From e1c2dbda23869b52f5dc2db719a11b7a3cb6c325 Mon Sep 17 00:00:00 2001 From: Guo Yixuan Date: Tue, 28 Aug 2012 03:05:07 +0000 Subject: [PATCH] Import boinc-app-seti_6.97~svn1409.orig.tar.gz [dgit import orig boinc-app-seti_6.97~svn1409.orig.tar.gz] --- AUTHORS | 31 + COPYING | 340 + COPYRIGHT | 37 + CheckResult | 288 + Graphics.Readme | 9 + Makefile.am | 44 + Makefile.incl | 56 + README | 57 + README_MAC | 1 + _autosetup | 137 + assimilator/Makefile.am | 34 + assimilator/sah_assimilate_handler.cpp | 760 + assimilator/sah_assimilate_handler.h | 7 + checkin_notes | 4134 +++++ client/Makefile.Readme | 27 + client/Makefile.am | 248 + client/Makefile.in.graphics | 151 + client/amd64fft8g.cpp | 123 + client/analyze.h | 70 + client/analyzeFuncs.cpp | 1284 ++ client/analyzeFuncs.h | 122 + client/analyzePoT.cpp | 641 + client/analyzePoT.h | 89 + client/analyzeReport.cpp | 447 + client/analyzeReport.h | 105 + client/app_icon.h | 2152 +++ client/autocorr.cpp | 166 + client/autocorr.h | 34 + client/better_banner.jpg | Bin 0 -> 9068 bytes client/chirpfft.cpp | 270 + client/chirpfft.h | 58 + client/collect2_line_linux.csh | 6 + client/collect2_line_solaris.csh | 6 + client/fft8g.cpp | 1107 ++ client/fft8g.h | 15 + client/gaussfit.cpp | 516 + client/gaussfit.h | 62 + client/gdata.cpp | 97 + client/gdata.h | 157 + client/graphics_main.cpp | 51 + client/lcgamm.cpp | 163 + client/lcgamm.h | 33 + client/main.cpp | 281 + client/malloc_a.cpp | 138 + client/malloc_a.h | 34 + client/progress.cpp | 189 + client/progress.h | 44 + client/pulsefind.cpp | 1393 ++ client/pulsefind.h | 85 + client/s_util.cpp | 236 + client/s_util.h | 155 + client/sah_gfx.cpp | 840 + client/sah_gfx.h | 70 + client/sah_gfx_base.cpp | 367 + client/sah_gfx_base.h | 100 + client/sah_gfx_main.cpp | 67 + client/sah_gfx_main.h | 43 + client/sah_version.cpp | 32 + client/sah_version.h | 31 + client/seti.cpp | 932 ++ client/seti.h | 262 + client/seti_header.cpp | 299 + client/seti_header.h | 132 + client/sincos.h | 102 + client/spike.cpp | 163 + client/spike.h | 34 + .../test_workunits/reference_result_unit.sah | 569 + client/test_workunits/reference_work_unit.sah | 5669 +++++++ client/timecvt.cpp | 172 + client/timecvt.h | 87 + client/vector/analyzeFuncs_altivec.cpp | 1662 ++ client/vector/analyzeFuncs_avx.cpp | 1358 ++ client/vector/analyzeFuncs_fpu.cpp | 333 + client/vector/analyzeFuncs_mmx.cpp | 107 + client/vector/analyzeFuncs_sse.cpp | 3167 ++++ client/vector/analyzeFuncs_sse2.cpp | 329 + client/vector/analyzeFuncs_sse3.cpp | 329 + client/vector/analyzeFuncs_vector.cpp | 1326 ++ client/vector/analyzeFuncs_vector.h | 297 + client/vector/analyzeFuncs_x86_64.cpp | 187 + client/vector/asmlib.h | 16 + client/vector/asmlib.zip | Bin 0 -> 30585 bytes client/vector/asmlibe.a | Bin 0 -> 7382 bytes client/vector/asmlibm.lib | Bin 0 -> 5612 bytes client/vector/avxcheck.asm | 36 + client/vector/hires_timer.cpp | 302 + client/vector/hires_timer.h | 98 + client/vector/sighandler.h | 189 + client/vector/x86_float4.cpp | 77 + client/vector/x86_float4.h | 266 + client/vector/x86_ops.h | 201 + client/win-sah_config.h | 473 + .../DevCpp_MinGW4_4plus/seti_boinc4_4plus.dev | 1299 ++ .../DevCpp_MinGW4_4plus/seti_boinc4_4plus.ico | Bin 0 -> 4710 bytes client/win_build/Logo2.bmp | Bin 0 -> 243414 bytes client/win_build/Logo2.jpg | Bin 0 -> 16198 bytes client/win_build/SAHjpeg.dev | 2119 +++ client/win_build/SETI_app.ico | Bin 0 -> 4710 bytes client/win_build/VS2008/boincglut.vcproj | 202 + client/win_build/VS2008/glut.vcproj | 455 + client/win_build/VS2008/image_libs.vcproj | 317 + client/win_build/VS2008/jpeglib.vcproj | 571 + client/win_build/VS2008/seti_boinc.sln | 124 + client/win_build/VS2008/seti_boinc.vcproj | 758 + client/win_build/VS2008/seti_graphics.vcproj | 457 + client/win_build/VS2008/setiboincdb.vcproj | 351 + client/win_build/boincglut.vcproj | 202 + client/win_build/fftw3.h | 332 + client/win_build/glut.vcproj | 458 + client/win_build/image_libs.vcproj | 320 + client/win_build/jpeglib.vcproj | 574 + client/win_build/libfftw3f.def | 635 + client/win_build/p004_640.jpg | Bin 0 -> 73960 bytes client/win_build/sah.ppm | Bin 0 -> 196623 bytes client/win_build/seti_boinc.dev | 2119 +++ client/win_build/seti_boinc.dsp | 686 + client/win_build/seti_boinc.dsw | 29 + client/win_build/seti_boinc.sln | 124 + client/win_build/seti_boinc.vcproj | 785 + client/win_build/seti_boinc_gcc3.dev | 2119 +++ client/win_build/seti_boinc_private.h | 23 + client/win_build/seti_boinc_private.rc | 42 + client/win_build/seti_graphics.dev | 2149 +++ client/win_build/seti_graphics.vcproj | 462 + client/win_build/seti_graphics_v3.dev | 2149 +++ client/win_build/setiboincdb.vcproj | 354 + client/worker.cpp | 175 + client/worker.h | 40 + compile | 99 + config.guess | 1465 ++ config.sub | 1569 ++ configure.ac | 500 + configure.ac.public | 141 + db/Makefile.in | 74 + db/app_config.cpp | 76 + db/app_config.h | 33 + db/db_table.h | 594 + db/find_references.awk | 59 + db/migrate_test.cpp | 125 + db/row_cache.h | 122 + db/schema_master.cpp | 13433 ++++++++++++++++ db/schema_master.h | 1242 ++ db/schema_master.sql | 854 + db/schema_to_class.awk | 742 + db/schema_to_class.in | 34 + db/sqlapi.h | 138 + db/sqlblob.cpp | 76 + db/sqlblob.h | 283 + db/sqldefs.h | 47 + db/sqlifx.ec | 1270 ++ db/sqlint8.cpp | 39 + db/sqlint8.h | 161 + db/sqlrow.cpp | 366 + db/sqlrow.h | 123 + db/tools/Makefile.in | 54 + db/tools/analysis_configs.xml | 49 + db/tools/insert_analysis_config.cpp | 61 + db/tools/insert_receiver_config.cpp | 43 + db/tools/insert_rfi_zones.cpp | 61 + db/tools/insert_s4_receivers.cpp | 54 + db/tools/insert_science_config.cpp | 62 + db/tools/insert_splitter_config.cpp | 43 + db/tools/print_s4_receivers.cpp | 26 + db/tools/recorder_configs.sql | 3 + db/tools/rfi_zones_to_xml.pro | 23 + db/tools/s4_receivers.xml | 357 + db/tools/science_configs.xml | 48 + db/tools/settings.sql | 6 + db/tools/splitter_configs.xml | 11 + db/track_mem.h | 39 + db/xml_util.cpp | 838 + db/xml_util.h | 1049 ++ depcomp | 464 + export-tarball | 107 + glut/Roman.stroke | 604 + glut/glut.h | 600 + glut/glut_roman.c | 2451 +++ glut/glut_stroke.c | 42 + glut/glut_swidth.c | 58 + glut/glutbitmap.h | 30 + glut/glutint.h | 24 + glut/glutstroke.h | 42 + glut/glutwin32.h | 18 + glut/stroke.h | 134 + glut/win32_glx.c | 255 + glut/win32_glx.h | 58 + glut/win32_util.c | 84 + glut/win32_x11.c | 401 + glut/win32_x11.h | 319 + hosts.make | 2 + image_libs/bmplib.cpp | 188 + image_libs/bmplib.h | 57 + image_libs/tgalib.cpp | 239 + image_libs/tgalib.h | 22 + install-sh | 251 + ltmain.sh | 6496 ++++++++ m4/acx_pthread.m4 | 199 + m4/ax_c_float_words_bigendian.m4 | 56 + m4/ax_check_gl.m4 | 82 + m4/ax_check_glu.m4 | 58 + m4/ax_check_glut.m4 | 72 + m4/ax_lang_compiler_ms.m4 | 14 + m4/boinc_platform.m4 | 69 + m4/check_ssl.m4 | 45 + m4/libcurl.m4 | 230 + m4/libtool.m4 | 6163 +++++++ m4/optimizations.m4 | 113 + m4/sah_asmlib.m4 | 62 + m4/sah_avx.m4 | 51 + m4/sah_check_boinc.m4 | 62 + m4/sah_check_healpix.m4 | 52 + m4/sah_check_ipp.m4 | 39 + m4/sah_check_jpeglib.m4 | 24 + m4/sah_check_lib.m4 | 503 + m4/sah_check_math_functions.m4 | 10 + m4/sah_find_s4path.m4 | 32 + m4/sah_find_setilib.m4 | 33 + m4/sah_grx.m4 | 27 + m4/sah_header_stdcxx.m4 | 71 + m4/sah_informix.m4 | 47 + m4/sah_largefile_breaks_cxx.m4 | 27 + m4/sah_libext.m4 | 33 + m4/sah_libsearch.m4 | 34 + m4/sah_links.m4 | 36 + m4/sah_make_dll.m4 | 14 + m4/sah_mysql.m4 | 30 + m4/sah_namespace.m4 | 92 + m4/sah_raw_ldflags.m4 | 5 + m4/sah_requires.m4 | 38 + m4/sah_select_bitness.m4 | 56 + m4/sah_staticize_ldflags.m4 | 41 + mac_build/HowToBuildSETI_XCode.rtf | 226 + mac_build/HowToTestSETI.txt | 29 + mac_build/buildfftw-3.1.1.sh | 97 + mac_build/config-i386.h | 610 + mac_build/config-ppc.h | 610 + mac_build/makeseticonfigs.sh | 102 + mac_build/sah_config.h | 125 + .../seti_boinc.xcodeproj/project.pbxproj | 1478 ++ missing | 336 + nightly-tarball | 37 + ops/bin/README | 22 + ops/bin/avg_file_create_dir | 21 + ops/bin/count_hard_links.csh | 3 + ops/bin/count_wugs_wus_by_tape.csh | 39 + ops/bin/data_flow.cfg | 98 + ops/bin/erase_data_drive | 101 + ops/bin/file_to_thumper | 79 + ops/bin/fill_xfer_to_hpss | 54 + ops/bin/make_hpss_script | 12 + ops/bin/make_xfer_script | 12 + ops/bin/run_jan.csh | 6 + ops/bin/seti_hsi.csh | 99 + ops/bin/xfer_to_hpss | 29 + setiathome.pbproj/project.pbxproj | 2497 +++ splitter/Makefile.am | 65 + splitter/angdist.cpp | 79 + splitter/angdist.h | 33 + splitter/cmap_interp.cpp | 40 + splitter/cmap_interp.h | 6 + splitter/coordcvt.cpp | 179 + splitter/coordcvt.h | 40 + splitter/db_fns.cpp | 199 + splitter/db_fns.h | 48 + splitter/dotransform.cpp | 218 + splitter/dotransform.h | 56 + splitter/encode.cpp | 93 + splitter/encode.h | 39 + splitter/fftw.h | 413 + splitter/four1.cpp | 88 + splitter/four1.h | 31 + splitter/hr_min_sec.cpp | 131 + splitter/hr_min_sec.h | 106 + splitter/libfftw.a | Bin 0 -> 248164 bytes splitter/makebufs.cpp | 139 + splitter/makebufs.h | 38 + splitter/mb_angdist.cpp | 88 + splitter/mb_angdist.h | 36 + splitter/mb_dotransform.cpp | 259 + splitter/mb_dotransform.h | 59 + splitter/mb_message.cpp | 73 + splitter/mb_polyphase.cpp | 150 + splitter/mb_splitter.cpp | 957 ++ splitter/mb_splitter.h | 144 + splitter/mb_splittypes.h | 114 + splitter/mb_validrun.cpp | 147 + splitter/mb_validrun.h | 35 + splitter/mb_wufiles.cpp | 678 + splitter/mb_wufiles.h | 46 + splitter/message.cpp | 65 + splitter/message.h | 40 + splitter/polyphase.cpp | 149 + splitter/polyphase.h | 26 + splitter/randomdata.cpp | 77 + splitter/readheader.cpp | 225 + splitter/readheader.h | 42 + splitter/readtape.cpp | 333 + splitter/readtape.h | 85 + splitter/splitparms.h | 145 + splitter/splitter.cpp | 717 + splitter/splitter.h | 132 + splitter/splittypes.h | 111 + splitter/squarewave.cpp | 75 + splitter/tools/disksplitter | 121 + splitter/tools/sah_splitter.sh | 150 + splitter/uttolst.h | 2 + splitter/validrun.cpp | 181 + splitter/validrun.h | 33 + splitter/writeheader.cpp | 105 + splitter/writeheader.h | 39 + splitter/wufiles.cpp | 679 + splitter/wufiles.h | 39 + splitter_old/Makefile.in | 92 + splitter_old/angdist.cpp | 79 + splitter_old/angdist.h | 36 + splitter_old/coordcvt.cpp | 173 + splitter_old/coordcvt.h | 43 + splitter_old/db_fns.cpp | 193 + splitter_old/db_fns.h | 51 + splitter_old/dotransform.cpp | 218 + splitter_old/dotransform.h | 59 + splitter_old/encode.cpp | 88 + splitter_old/encode.h | 42 + splitter_old/fftw.h | 413 + splitter_old/four1.cpp | 88 + splitter_old/four1.h | 34 + splitter_old/hr_min_sec.cpp | 131 + splitter_old/hr_min_sec.h | 109 + splitter_old/libfftw.a | Bin 0 -> 248165 bytes splitter_old/makebufs.cpp | 127 + splitter_old/makebufs.h | 41 + splitter_old/message.cpp | 52 + splitter_old/message.h | 30 + splitter_old/polyphase.cpp | 149 + splitter_old/polyphase.h | 26 + splitter_old/randomdata.cpp | 77 + splitter_old/readheader.cpp | 218 + splitter_old/readheader.h | 45 + splitter_old/readtape.cpp | 319 + splitter_old/readtape.h | 85 + splitter_old/splitparms.h | 148 + splitter_old/splitter.cpp | 682 + splitter_old/splitter.h | 122 + splitter_old/splittypes.h | 114 + splitter_old/squarewave.cpp | 75 + splitter_old/tools/disksplitter | 121 + splitter_old/tools/sah_splitter.sh | 150 + splitter_old/uttolst.h | 2 + splitter_old/validrun.cpp | 165 + splitter_old/validrun.h | 36 + splitter_old/writeheader.cpp | 105 + splitter_old/writeheader.h | 42 + splitter_old/wufiles.cpp | 530 + splitter_old/wufiles.h | 42 + tools/Makefile.am | 50 + tools/fakedata.cpp | 431 + tools/workunit_resample.cpp | 142 + trim_sources | 53 + validate/Makefile.in | 68 + validate/sah_boinc_db.cpp | 57 + validate/sah_boinc_db.h | 4 + validate/sah_result.cpp | 296 + validate/sah_result.h | 70 + validate/sah_validate.cpp | 596 + vector_lib/3dnow.h | 303 + vector_lib/Makefile | 9 + vector_lib/generics.h | 612 + vector_lib/mmx.h | 1100 ++ vector_lib/ps.cpp | 23 + vector_lib/simd.h | 376 + vector_lib/sse.h | 364 + vector_lib/t1.cpp | 59 + vector_lib/vis.h | 1080 ++ win_build/win_version.h | 5 + 374 files changed, 131972 insertions(+) create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 COPYRIGHT create mode 100755 CheckResult create mode 100644 Graphics.Readme create mode 100644 Makefile.am create mode 100644 Makefile.incl create mode 100644 README create mode 100644 README_MAC create mode 100755 _autosetup create mode 100644 assimilator/Makefile.am create mode 100644 assimilator/sah_assimilate_handler.cpp create mode 100644 assimilator/sah_assimilate_handler.h create mode 100644 checkin_notes create mode 100644 client/Makefile.Readme create mode 100644 client/Makefile.am create mode 100644 client/Makefile.in.graphics create mode 100644 client/amd64fft8g.cpp create mode 100644 client/analyze.h create mode 100644 client/analyzeFuncs.cpp create mode 100644 client/analyzeFuncs.h create mode 100644 client/analyzePoT.cpp create mode 100644 client/analyzePoT.h create mode 100644 client/analyzeReport.cpp create mode 100644 client/analyzeReport.h create mode 100644 client/app_icon.h create mode 100644 client/autocorr.cpp create mode 100644 client/autocorr.h create mode 100644 client/better_banner.jpg create mode 100644 client/chirpfft.cpp create mode 100644 client/chirpfft.h create mode 100755 client/collect2_line_linux.csh create mode 100644 client/collect2_line_solaris.csh create mode 100644 client/fft8g.cpp create mode 100644 client/fft8g.h create mode 100644 client/gaussfit.cpp create mode 100644 client/gaussfit.h create mode 100644 client/gdata.cpp create mode 100644 client/gdata.h create mode 100644 client/graphics_main.cpp create mode 100644 client/lcgamm.cpp create mode 100644 client/lcgamm.h create mode 100644 client/main.cpp create mode 100644 client/malloc_a.cpp create mode 100644 client/malloc_a.h create mode 100644 client/progress.cpp create mode 100644 client/progress.h create mode 100644 client/pulsefind.cpp create mode 100644 client/pulsefind.h create mode 100644 client/s_util.cpp create mode 100644 client/s_util.h create mode 100644 client/sah_gfx.cpp create mode 100644 client/sah_gfx.h create mode 100644 client/sah_gfx_base.cpp create mode 100644 client/sah_gfx_base.h create mode 100644 client/sah_gfx_main.cpp create mode 100644 client/sah_gfx_main.h create mode 100644 client/sah_version.cpp create mode 100644 client/sah_version.h create mode 100644 client/seti.cpp create mode 100644 client/seti.h create mode 100644 client/seti_header.cpp create mode 100644 client/seti_header.h create mode 100644 client/sincos.h create mode 100644 client/spike.cpp create mode 100644 client/spike.h create mode 100644 client/test_workunits/reference_result_unit.sah create mode 100644 client/test_workunits/reference_work_unit.sah create mode 100644 client/timecvt.cpp create mode 100644 client/timecvt.h create mode 100644 client/vector/analyzeFuncs_altivec.cpp create mode 100644 client/vector/analyzeFuncs_avx.cpp create mode 100644 client/vector/analyzeFuncs_fpu.cpp create mode 100644 client/vector/analyzeFuncs_mmx.cpp create mode 100644 client/vector/analyzeFuncs_sse.cpp create mode 100644 client/vector/analyzeFuncs_sse2.cpp create mode 100644 client/vector/analyzeFuncs_sse3.cpp create mode 100644 client/vector/analyzeFuncs_vector.cpp create mode 100644 client/vector/analyzeFuncs_vector.h create mode 100644 client/vector/analyzeFuncs_x86_64.cpp create mode 100644 client/vector/asmlib.h create mode 100644 client/vector/asmlib.zip create mode 100644 client/vector/asmlibe.a create mode 100644 client/vector/asmlibm.lib create mode 100644 client/vector/avxcheck.asm create mode 100644 client/vector/hires_timer.cpp create mode 100644 client/vector/hires_timer.h create mode 100644 client/vector/sighandler.h create mode 100644 client/vector/x86_float4.cpp create mode 100644 client/vector/x86_float4.h create mode 100644 client/vector/x86_ops.h create mode 100644 client/win-sah_config.h create mode 100644 client/win_build/DevCpp_MinGW4_4plus/seti_boinc4_4plus.dev create mode 100644 client/win_build/DevCpp_MinGW4_4plus/seti_boinc4_4plus.ico create mode 100644 client/win_build/Logo2.bmp create mode 100644 client/win_build/Logo2.jpg create mode 100755 client/win_build/SAHjpeg.dev create mode 100644 client/win_build/SETI_app.ico create mode 100644 client/win_build/VS2008/boincglut.vcproj create mode 100644 client/win_build/VS2008/glut.vcproj create mode 100644 client/win_build/VS2008/image_libs.vcproj create mode 100644 client/win_build/VS2008/jpeglib.vcproj create mode 100644 client/win_build/VS2008/seti_boinc.sln create mode 100644 client/win_build/VS2008/seti_boinc.vcproj create mode 100644 client/win_build/VS2008/seti_graphics.vcproj create mode 100644 client/win_build/VS2008/setiboincdb.vcproj create mode 100755 client/win_build/boincglut.vcproj create mode 100644 client/win_build/fftw3.h create mode 100755 client/win_build/glut.vcproj create mode 100755 client/win_build/image_libs.vcproj create mode 100755 client/win_build/jpeglib.vcproj create mode 100644 client/win_build/libfftw3f.def create mode 100644 client/win_build/p004_640.jpg create mode 100644 client/win_build/sah.ppm create mode 100644 client/win_build/seti_boinc.dev create mode 100755 client/win_build/seti_boinc.dsp create mode 100644 client/win_build/seti_boinc.dsw create mode 100755 client/win_build/seti_boinc.sln create mode 100755 client/win_build/seti_boinc.vcproj create mode 100644 client/win_build/seti_boinc_gcc3.dev create mode 100644 client/win_build/seti_boinc_private.h create mode 100644 client/win_build/seti_boinc_private.rc create mode 100644 client/win_build/seti_graphics.dev create mode 100644 client/win_build/seti_graphics.vcproj create mode 100644 client/win_build/seti_graphics_v3.dev create mode 100755 client/win_build/setiboincdb.vcproj create mode 100644 client/worker.cpp create mode 100644 client/worker.h create mode 100755 compile create mode 100755 config.guess create mode 100755 config.sub create mode 100644 configure.ac create mode 100644 configure.ac.public create mode 100644 db/Makefile.in create mode 100644 db/app_config.cpp create mode 100644 db/app_config.h create mode 100644 db/db_table.h create mode 100644 db/find_references.awk create mode 100644 db/migrate_test.cpp create mode 100644 db/row_cache.h create mode 100644 db/schema_master.cpp create mode 100644 db/schema_master.h create mode 100644 db/schema_master.sql create mode 100644 db/schema_to_class.awk create mode 100755 db/schema_to_class.in create mode 100644 db/sqlapi.h create mode 100644 db/sqlblob.cpp create mode 100644 db/sqlblob.h create mode 100644 db/sqldefs.h create mode 100644 db/sqlifx.ec create mode 100644 db/sqlint8.cpp create mode 100644 db/sqlint8.h create mode 100644 db/sqlrow.cpp create mode 100644 db/sqlrow.h create mode 100644 db/tools/Makefile.in create mode 100644 db/tools/analysis_configs.xml create mode 100644 db/tools/insert_analysis_config.cpp create mode 100644 db/tools/insert_receiver_config.cpp create mode 100644 db/tools/insert_rfi_zones.cpp create mode 100644 db/tools/insert_s4_receivers.cpp create mode 100644 db/tools/insert_science_config.cpp create mode 100644 db/tools/insert_splitter_config.cpp create mode 100644 db/tools/print_s4_receivers.cpp create mode 100644 db/tools/recorder_configs.sql create mode 100644 db/tools/rfi_zones_to_xml.pro create mode 100644 db/tools/s4_receivers.xml create mode 100644 db/tools/science_configs.xml create mode 100644 db/tools/settings.sql create mode 100644 db/tools/splitter_configs.xml create mode 100644 db/track_mem.h create mode 100644 db/xml_util.cpp create mode 100644 db/xml_util.h create mode 100755 depcomp create mode 100755 export-tarball create mode 100644 glut/Roman.stroke create mode 100644 glut/glut.h create mode 100644 glut/glut_roman.c create mode 100644 glut/glut_stroke.c create mode 100644 glut/glut_swidth.c create mode 100644 glut/glutbitmap.h create mode 100644 glut/glutint.h create mode 100644 glut/glutstroke.h create mode 100644 glut/glutwin32.h create mode 100644 glut/stroke.h create mode 100644 glut/win32_glx.c create mode 100644 glut/win32_glx.h create mode 100644 glut/win32_util.c create mode 100644 glut/win32_x11.c create mode 100644 glut/win32_x11.h create mode 100644 hosts.make create mode 100644 image_libs/bmplib.cpp create mode 100644 image_libs/bmplib.h create mode 100644 image_libs/tgalib.cpp create mode 100644 image_libs/tgalib.h create mode 100644 install-sh create mode 100644 ltmain.sh create mode 100644 m4/acx_pthread.m4 create mode 100644 m4/ax_c_float_words_bigendian.m4 create mode 100644 m4/ax_check_gl.m4 create mode 100644 m4/ax_check_glu.m4 create mode 100644 m4/ax_check_glut.m4 create mode 100644 m4/ax_lang_compiler_ms.m4 create mode 100644 m4/boinc_platform.m4 create mode 100644 m4/check_ssl.m4 create mode 100644 m4/libcurl.m4 create mode 100644 m4/libtool.m4 create mode 100644 m4/optimizations.m4 create mode 100644 m4/sah_asmlib.m4 create mode 100644 m4/sah_avx.m4 create mode 100644 m4/sah_check_boinc.m4 create mode 100644 m4/sah_check_healpix.m4 create mode 100644 m4/sah_check_ipp.m4 create mode 100644 m4/sah_check_jpeglib.m4 create mode 100644 m4/sah_check_lib.m4 create mode 100644 m4/sah_check_math_functions.m4 create mode 100644 m4/sah_find_s4path.m4 create mode 100644 m4/sah_find_setilib.m4 create mode 100644 m4/sah_grx.m4 create mode 100644 m4/sah_header_stdcxx.m4 create mode 100644 m4/sah_informix.m4 create mode 100644 m4/sah_largefile_breaks_cxx.m4 create mode 100644 m4/sah_libext.m4 create mode 100644 m4/sah_libsearch.m4 create mode 100644 m4/sah_links.m4 create mode 100644 m4/sah_make_dll.m4 create mode 100644 m4/sah_mysql.m4 create mode 100644 m4/sah_namespace.m4 create mode 100644 m4/sah_raw_ldflags.m4 create mode 100644 m4/sah_requires.m4 create mode 100644 m4/sah_select_bitness.m4 create mode 100644 m4/sah_staticize_ldflags.m4 create mode 100644 mac_build/HowToBuildSETI_XCode.rtf create mode 100644 mac_build/HowToTestSETI.txt create mode 100644 mac_build/buildfftw-3.1.1.sh create mode 100644 mac_build/config-i386.h create mode 100644 mac_build/config-ppc.h create mode 100644 mac_build/makeseticonfigs.sh create mode 100644 mac_build/sah_config.h create mode 100644 mac_build/seti_boinc.xcodeproj/project.pbxproj create mode 100755 missing create mode 100755 nightly-tarball create mode 100644 ops/bin/README create mode 100755 ops/bin/avg_file_create_dir create mode 100755 ops/bin/count_hard_links.csh create mode 100755 ops/bin/count_wugs_wus_by_tape.csh create mode 100755 ops/bin/data_flow.cfg create mode 100755 ops/bin/erase_data_drive create mode 100755 ops/bin/file_to_thumper create mode 100755 ops/bin/fill_xfer_to_hpss create mode 100755 ops/bin/make_hpss_script create mode 100755 ops/bin/make_xfer_script create mode 100755 ops/bin/run_jan.csh create mode 100755 ops/bin/seti_hsi.csh create mode 100755 ops/bin/xfer_to_hpss create mode 100644 setiathome.pbproj/project.pbxproj create mode 100644 splitter/Makefile.am create mode 100644 splitter/angdist.cpp create mode 100644 splitter/angdist.h create mode 100644 splitter/cmap_interp.cpp create mode 100644 splitter/cmap_interp.h create mode 100644 splitter/coordcvt.cpp create mode 100644 splitter/coordcvt.h create mode 100644 splitter/db_fns.cpp create mode 100644 splitter/db_fns.h create mode 100644 splitter/dotransform.cpp create mode 100644 splitter/dotransform.h create mode 100644 splitter/encode.cpp create mode 100644 splitter/encode.h create mode 100644 splitter/fftw.h create mode 100644 splitter/four1.cpp create mode 100644 splitter/four1.h create mode 100644 splitter/hr_min_sec.cpp create mode 100644 splitter/hr_min_sec.h create mode 100644 splitter/libfftw.a create mode 100644 splitter/makebufs.cpp create mode 100644 splitter/makebufs.h create mode 100644 splitter/mb_angdist.cpp create mode 100644 splitter/mb_angdist.h create mode 100644 splitter/mb_dotransform.cpp create mode 100644 splitter/mb_dotransform.h create mode 100644 splitter/mb_message.cpp create mode 100644 splitter/mb_polyphase.cpp create mode 100644 splitter/mb_splitter.cpp create mode 100644 splitter/mb_splitter.h create mode 100644 splitter/mb_splittypes.h create mode 100644 splitter/mb_validrun.cpp create mode 100644 splitter/mb_validrun.h create mode 100644 splitter/mb_wufiles.cpp create mode 100644 splitter/mb_wufiles.h create mode 100644 splitter/message.cpp create mode 100644 splitter/message.h create mode 100644 splitter/polyphase.cpp create mode 100644 splitter/polyphase.h create mode 100644 splitter/randomdata.cpp create mode 100644 splitter/readheader.cpp create mode 100644 splitter/readheader.h create mode 100644 splitter/readtape.cpp create mode 100644 splitter/readtape.h create mode 100644 splitter/splitparms.h create mode 100644 splitter/splitter.cpp create mode 100644 splitter/splitter.h create mode 100644 splitter/splittypes.h create mode 100644 splitter/squarewave.cpp create mode 100755 splitter/tools/disksplitter create mode 100755 splitter/tools/sah_splitter.sh create mode 100644 splitter/uttolst.h create mode 100644 splitter/validrun.cpp create mode 100644 splitter/validrun.h create mode 100644 splitter/writeheader.cpp create mode 100644 splitter/writeheader.h create mode 100644 splitter/wufiles.cpp create mode 100644 splitter/wufiles.h create mode 100644 splitter_old/Makefile.in create mode 100644 splitter_old/angdist.cpp create mode 100644 splitter_old/angdist.h create mode 100644 splitter_old/coordcvt.cpp create mode 100644 splitter_old/coordcvt.h create mode 100644 splitter_old/db_fns.cpp create mode 100644 splitter_old/db_fns.h create mode 100644 splitter_old/dotransform.cpp create mode 100644 splitter_old/dotransform.h create mode 100644 splitter_old/encode.cpp create mode 100644 splitter_old/encode.h create mode 100644 splitter_old/fftw.h create mode 100644 splitter_old/four1.cpp create mode 100644 splitter_old/four1.h create mode 100644 splitter_old/hr_min_sec.cpp create mode 100644 splitter_old/hr_min_sec.h create mode 100644 splitter_old/libfftw.a create mode 100644 splitter_old/makebufs.cpp create mode 100644 splitter_old/makebufs.h create mode 100644 splitter_old/message.cpp create mode 100644 splitter_old/message.h create mode 100644 splitter_old/polyphase.cpp create mode 100644 splitter_old/polyphase.h create mode 100644 splitter_old/randomdata.cpp create mode 100644 splitter_old/readheader.cpp create mode 100644 splitter_old/readheader.h create mode 100644 splitter_old/readtape.cpp create mode 100644 splitter_old/readtape.h create mode 100644 splitter_old/splitparms.h create mode 100644 splitter_old/splitter.cpp create mode 100644 splitter_old/splitter.h create mode 100644 splitter_old/splittypes.h create mode 100644 splitter_old/squarewave.cpp create mode 100755 splitter_old/tools/disksplitter create mode 100755 splitter_old/tools/sah_splitter.sh create mode 100644 splitter_old/uttolst.h create mode 100644 splitter_old/validrun.cpp create mode 100644 splitter_old/validrun.h create mode 100644 splitter_old/writeheader.cpp create mode 100644 splitter_old/writeheader.h create mode 100644 splitter_old/wufiles.cpp create mode 100644 splitter_old/wufiles.h create mode 100644 tools/Makefile.am create mode 100755 tools/fakedata.cpp create mode 100644 tools/workunit_resample.cpp create mode 100755 trim_sources create mode 100644 validate/Makefile.in create mode 100644 validate/sah_boinc_db.cpp create mode 100644 validate/sah_boinc_db.h create mode 100644 validate/sah_result.cpp create mode 100644 validate/sah_result.h create mode 100644 validate/sah_validate.cpp create mode 100644 vector_lib/3dnow.h create mode 100644 vector_lib/Makefile create mode 100644 vector_lib/generics.h create mode 100644 vector_lib/mmx.h create mode 100644 vector_lib/ps.cpp create mode 100644 vector_lib/simd.h create mode 100644 vector_lib/sse.h create mode 100644 vector_lib/t1.cpp create mode 100644 vector_lib/vis.h create mode 100644 win_build/win_version.h diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..1fafa15 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,31 @@ + +Authors of SETI@home: +Eric J. Korpela +Jeff Cobb +Matt Lebofsky +David Anderson +Charlie Fenton +Rom Walton +Tetsuji Rai +Eric Heien +Hiram Clawson +Alex Kan +Ben Herndon +Josef Segur +Simon Zadra +Jason Groothuis +Raistmer + +Authors of FFTW (reachable at fftw at fftw.org): +Matteo Frigo +Stevenj G. Johnson +Stefan Kral wrote genfft-k7/*.ml* + +Authors of fft8g.[cpp,h] +Takuya Ooura +Eric J. Korpela +Jeff Cobb + +Author of ASMLIB +Agner Fog + diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..d60c31a --- /dev/null +++ b/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/COPYRIGHT b/COPYRIGHT new file mode 100644 index 0000000..3029670 --- /dev/null +++ b/COPYRIGHT @@ -0,0 +1,37 @@ +// Copyright (c) 1999-2011 Regents of the University of California +// +// FFTW: Copyright (c) 2003,2006 Matteo Frigo +// Copyright (c) 2003,2006 Massachusets Institute of Technology +// +// fft8g.[cpp,h]: Copyright (c) 1995-2001 Takya Ooura +// +// ASMLIB: Copyright (c) 2004 Agner Fog + +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) any later +// version. + +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with this program; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions +// as an alternative to FFTW and distribute a linked executable and +// source code. You must obey the GNU General Public License in all +// respects for all of the code used other than the FFT library itself. +// Any modification required to support these libraries must be distributed +// under the terms of this license. If you modify this program, you may extend +// this exception to your version of the program, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. Please be aware that FFTW and ASMLIB are not covered by +// this exception, therefore you may not use FFTW and ASMLIB in any derivative +// work so modified without permission of the authors of those packages. + diff --git a/CheckResult b/CheckResult new file mode 100755 index 0000000..7cf8165 --- /dev/null +++ b/CheckResult @@ -0,0 +1,288 @@ +#!/bin/sh +# +# CheckResult - produce an html page with client test results +# +# Usage: CheckResult [more outfile.sah files] > check.html +# must supply at least one argument, the name of +# an outfile.sah to check. More than one file can +# be supplied to check. Each file will produce a table +# in the resulting html output. Place the output of this +# script into a file and read with a browser. +# +# KNOWN PROBLEM: Some clients output numbers in the form of: +# 1.803966e+000 instead of 1.803966e+00 +# This will cause a compare error. A work-around on +# such platforms is to edit the reference outfile and +# change all the +0x to +00x and -0x to -00x +# +# ASSUMED: outfile.sah_version_2.0 is available here in ./ +# +# Set the reference file location if different in your setup: + +Reference="./outfile.sah_version_2.0" + +# What kind of awk do you need ? I note Solaris needs to use nawk, +# and others need to use simply awk. Please set this to what you +# need to have for an awk. +AWK=nawk + +# trap signals and exit cleanly + +trap "CleanExit" 1 2 3 15 + +########################################################################### +# subroutines +########################################################################### +Usage() { + echo "Usage: [more outfile.sah files] > check.html" + echo "\t - name of outfile.sah to check" + echo "\t[more outfile.sah files] - can check more than one" + echo "\t reference file is assumed to be:" + echo "\t ${Reference}" +} + +########################################################################### +# There are no /tmps file to remove at this time. If some are +# developed in the future, clean them up here. +# +CleanExit() { + exit 0 +} # caught signal + +########################################################################### +Header() { +cat << _EOF_ + + SETI@home ${Reference} delta report SETI clients + + +_EOF_ +} # Header() + +########################################################################### +TableStart() { +cat << _EOF_ +
+ + + + + + + + + + + + +_EOF_ +} # TableStart() + +########################################################################### +TableEnd(){ +cat << _EOF_ +
+ SETI@home delta report for ${TITLE} +
+`date` - `date -u` +
+
When OK:
(actual delta) + (allowed delta)
When Bad:
(actual + measurement) (reference measurement)
power delta peak delta mean delta chisqr delta others ?
+_EOF_ +} # TableEnd() + +########################################################################### +Tailer(){ +cat << _EOF_ +
+The deltas are computed: <reference value> - <test value>
+power delta - the difference between power= on the spike: lines
+peak delta - the difference between peak= on the gaussian: lines
+mean delta - the difference between mean= on the gaussian: lines
+chisqr delta - the difference between chisqr= on the gaussian: lines
+others ? - indication if other fields on any line have differences
+
+
+ SETI@home STATS home page
+ SETI@home home page +
+
+
This page last updated: `date` - `date -u`
+ +_EOF_ +} # Tailer() +########################################################################### +########################################################################### +# start of main program + +# (It might be better to make the reference file be the first +# argument ?) + +if [ ! -f "${Reference}" ]; then { + echo "Reference outfile does not exist. Looking for:" + echo "\t${Reference}" + CleanExit +} fi + +if [ "$#" -lt 1 ]; then { + Usage + CleanExit +} fi + +Header # start the html file + +# For each file on the command line, generate a table + +for Test in $* +do + +TITLE="${Test}" + +#echo "

Checking file: ${Test}

" + +echo "
"
+if [ ! -f "${Test}" ]; then {
+	echo "\nERROR: specified file does not exist:"
+	echo "\t${Test}"
+} fi
+
+# first, see if there are the same number of lines in the outfiles
+
+TestWC=`cat ${Test} | wc -l`
+RefWC=`cat ${Reference} | wc -l`
+
+if [ "${TestWC}" -ne "${RefWC}" ]; then {
+	echo "ERROR: the two files do not have the same number of lines"
+	echo "'wc ${Test} ${Reference}'"
+	wc ${Test} ${Reference}
+} fi
+
+echo "
" + +TableStart + +# Processing is to read line by line from the reference file and +# the test file to check. Parse out all the numbers on +# the lines, and compare all numbers. Assuming format +# of output as it is currently in version 1.1 -> 1.3 +# (this works even with the new v1.10, v2.0 format, although +# it is not checking the pow= value) + +$AWK ' +function check_error(reference,measured,tolerance) { + diff=reference-measured + errbar=reference*tolerance + if ( errbar < 0 ) { abserrbar = - errbar } else { abserrbar = errbar } + if ( diff < 0 ) { absdiff = - diff } else { absdiff = diff } + if ( (absdiff < .0000001) ) { +printf "
0.0 (%.3e)
", reference + } else if ( (absdiff - abserrbar) > 0 ) { +printf " %.6e (!= %.6e) ", measured, reference + } else { +printf "
%.3e (%.3e)
", absdiff, abserrbar + } +} +function ogh(LineIn) { + n=split(LineIn, a, " ") + split(a[2], b, "="); ncfft=b[2] + split(a[3], b, "="); cr=b[2] + split(a[4], b, "="); fl=b[2] +} +function spike(LineIn) { + n=split(LineIn, a, " ") + split(a[2], b, "="); power=b[2] + split(a[3], b, "="); ra=b[2] + dec=a[5] + time=a[7] + split(a[8], b, "="); freq=b[2] + split(a[9], b, "="); fft_len=b[2] + split(a[10], b, "="); chirp_rate=b[2] +} +function gaussian(LineIn) { + n=split(LineIn, a, " ") + split(a[2], b, "="); peak=b[2] + split(a[3], b, "="); mean=b[2] + split(a[4], b, "="); ra=b[2] + dec=a[6] + time=a[8] + split(a[9], b, "="); freq=b[2] + split(a[10], b, "="); sigma=b[2] + split(a[11], b, "="); chisqr=b[2] + split(a[12], b, "="); fft_len=b[2] + split(a[13], b, "="); chirprate=b[2] +} +BEGIN { + Fname0="'${Reference}'" + Fname1="'${Test}'" + while ( (getline LineIn < Fname0) > 0 ) { + if ( match(LineIn, "^ end of file on %s\n", Fname1 + } else { + if ( match(LineIn, "^ yes \n" +} + } else if ( match(LineIn, "^ yes \n" +} + } else if ( match(LineIn, "^spike:") ) { + spike(LineIn) +power1=power; ra1=ra; dec1=dec; time1=time; freq1=freq; fft_len1=fft_len; + chirp_rate1=chirp_rate; + printf " " + check_error(power0, power1, .001) + printf "" +if ( (ra1 != ra0) || (dec1 != dec0) || (time1 != time0) || (freq1 != freq0) || (fft_len1 != fft_len0) ) { + printf" yes \n" +} else { +printf "\n" +} + } else if ( match(LineIn, "^gaussian:") ) { + gaussian(LineIn) +peak1=peak; mean1=mean; gra1=ra; gdec1=dec; gtime1=time; gfreq1=freq; +sigma1=sigma; chisqr1=chisqr; fft_len1=fft_len; chirprate1=chirprate; + printf "" + check_error(peak0, peak1, .001) + check_error(mean0, mean1, .001) + check_error(chisqr0, chisqr1, .001) + printf "\n" +if ( (gra1 != gra0) || (gdec1 != gdec0) || (gtime1 != gtime0) || (gfreq1 != gfreq0) || (sigma1 != sigma0) || (fft_len1 != fft_len0) || (chirprate1 != chirprate0) ) { + printf" \n" +} else { +printf "\n" +} + } + } + } + close Fname0 + close Fname1 +} +' +TableEnd + +done + +Tailer # Finished with the html file + +CleanExit diff --git a/Graphics.Readme b/Graphics.Readme new file mode 100644 index 0000000..2df9001 --- /dev/null +++ b/Graphics.Readme @@ -0,0 +1,9 @@ +This document will describe how to install seti with graphics. + +Make sure that boinc has been installed with graphics enabled. Follow +the instructions Makefile.Readme in seti_boinc/client to make sure +that Makefile.in.graphics will work with your system. Rename +Makefile.in.graphics as Makefile.in. From the seti_boinc/ directory +run configure (or ./configure), then make. The executable will then be +xseti[version and system info] and your app_info.xml file should +reflect that name. \ No newline at end of file diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..3b01331 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,44 @@ +# $Id: Makefile.am,v 1.2.2.1 2005/10/26 18:23:03 korpela Exp $ +# +# + +AUTOMAKE_OPTIONS = foreign + +## make sure rebuilding uses the right aclocal-switches +ACLOCAL_AMFLAGS = -I m4 + +if ENABLE_CLIENT + CLIENT_SUBDIRS = client +if ENABLE_TESTS + CLIENT_SUBDIRS +=tools +endif +endif + +if ENABLE_SERVER + SERVER_SUBDIRS = splitter assimilator validate +endif + +if USE_MY_IMAGELIBS + IMDIR = image_libs +endif + +if USE_MY_GLUT + GLUTDIR = glut +endif + + +SUBDIRS = $(JPEGDIR) $(IMDIR) $(GLUTDIR) $(CLIENT_SUBDIRS) $(SERVER_SUBDIRS) + +dist-hook: + rm -rf `find $(distdir) -name .backup -prune -o -name '*~' -o -name CVS` + +client-bin: + cd client && make client-bin client-bin-gz + +EXTRA_DIST = \ + db \ + tools \ + client/win_build \ + client/test_workunits \ + INSTALL + diff --git a/Makefile.incl b/Makefile.incl new file mode 100644 index 0000000..b5a5220 --- /dev/null +++ b/Makefile.incl @@ -0,0 +1,56 @@ +# $Id: Makefile.incl,v 1.2.2.6 2007/02/13 23:16:11 korpela Exp $ +# +# + +@SET_MAKE@ + +AM_LIBS = @LIBS@ +AM_LDFLAGS = @LDFLAGS@ +AM_CPPFLAGS = @CFLAGS@ @PICFLAGS@ @DEFS@ +AM_CFLAGS = $(AM_CPPFLAGS) +AM_CXXFLAGS = $(AM_CPPFLAGS) + +BOINCDIR = @BOINCDIR@ + +EXEEXT = @EXEEXT@ +OBJEXT = @OBJEXT@ +LIBEXT = @LIBEXT@ +DLLEXT = @DLLEXT@ +DOTEXEEXT = @DOTEXEEXT@ +LINK_DLL = @LINK_DLL@ + +LIBTOOL = @LIBTOOL@ + +MYSQL_LIBS = @MYSQL_LIBS@ +MYSQL_CFLAGS = @MYSQL_CFLAGS@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_LIBS = @PTHREAD_LIBS@ +INFORMIXDIR = @INFORMIXDIR@ +INFORMIX_LIBS = @INFORMIX_LIBS@ +INFORMIX_CFLAGS = @INFORMIX_CFLAGS@ +APP_LIBS = @ASMLIB_LIBS@ @APP_LIBS@ +APP_LDFLAGS = @ASMLIB_LDFLAGS@ @APP_LDFLAGS@ +APP_CFLAGS = @ASMLIB_CFLAGS@ @APP_CFLAGS@ +GRAPHICS_CFLAGS = @GRAPHICS_CFLAGS@ +DEFS = @DEFS@ +GRAPHICS_LIBS = @GRAPHICS_LIBS@ +SETILIBDIR = @SETILIBDIR@ +HEALPIX = @HEALPIX@ + +SUFFIXES = .cpp .c .@OBJEXT@ .@DLLEXT@ .@LIBEXT@ @DOTEXEEXT@ + +VERSION_MAJOR = @MAJOR_VERSION@ +VERSION_MINOR = @MINOR_VERSION@ + +BOINC_CFLAGS= @BOINC_CFLAGS@ + +BOINC_PLATFORM = @boinc_platform@ + +LDSTATIC = @LDSTATIC@ + +DEBUG_PROG = setiathome-$(VERSION_MAJOR).$(VERSION_MINOR).$(BOINC_PLATFORM).debug$(DOTEXEEXT) +DEBUG_NATIVESO = setiathome-$(VERSION_MAJOR).$(VERSION_MINOR).$(BOINC_PLATFORM).debug.$(DLLEXT) +CLIENT_PROG = setiathome-$(VERSION_MAJOR).$(VERSION_MINOR).$(BOINC_PLATFORM)$(DOTEXEEXT) +CLIENT_NATIVESO = setiathome-$(VERSION_MAJOR).$(VERSION_MINOR).$(BOINC_PLATFORM).$(DLLEXT) + + diff --git a/README b/README new file mode 100644 index 0000000..5587d03 --- /dev/null +++ b/README @@ -0,0 +1,57 @@ +setiathome(1) User Commands Version 6.90 - Feb 2011 + +NAME + seti_boinc - the SETI@home client program + +SYNOPSIS + seti_boinc [options] + +DESCRIPTION + seti_boinc is the boinc version of the SETI@home client. + It runs under the BOINC client which downloads radio telescope data + from a network server, analyzes the data looking for signals of + extraterrestrial origin, and uploads results to the server, + repeating this cycle indefinitely. + See http://setiathome.berkeley.edu for more information. + +FILES + In order to use seti_boinc to analyze data from the seti@home project + you must first download the BOINC client software which is avalable + through the setiathome web page http://setiathome.berkeley.edu/ + If used on a supported host platform, the BOINC client will automatically + download the most recent versions of the seti@home client software. + + If you are compiling for an unsupported host platform, you may need to use + the boinc anonymous platform mechanism described at + http://boinc.berkeley.edu/anonymous_platform.php + + The program generates several files with .sah extension + in the directory from which it's run. + These should not be modified. + + +OPTIONS + -nographics + Do not show graphics while running. + + -version + Show software version + +SEE ALSO: + There is much more information to be found about the operation + of the client at the following WEB sites: + http://setiathome.berkeley.edu/ + http://boinc.berkeley.edu/ + with discussions of add-on programs and scripts to control + the BOINC client in various situations. + + The most recent version of the seti_boinc source code can be found at + http://setiathome.berkeley.edu/ + + The most recent version of the official FFTW library can be found at + http://www.fftw.org/. A version containing any modifications made for + SETI@home can be found at http://setiathome.berkeley.edu/ + If you are unable to find it there, please contact Eric Korpela + . + + diff --git a/README_MAC b/README_MAC new file mode 100644 index 0000000..e7d3064 --- /dev/null +++ b/README_MAC @@ -0,0 +1 @@ +./configure --enable-fast-math -C --with-apple-opengl-framework --with-boinc-platform=powerpc-apple-darwin --without-x --disable-dynamic-graphics --with-my-libjpeg --with-my-jpeglib diff --git a/_autosetup b/_autosetup new file mode 100755 index 0000000..1a39bde --- /dev/null +++ b/_autosetup @@ -0,0 +1,137 @@ +#!/bin/sh + +## $Id: _autosetup,v 1.2.2.3 2007/08/07 21:42:31 mattl Exp $ + +## ---------- some portability checks/adjustments [stolen from configure] ---------- +## 'echo -n' is not portable.. +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac +##---------- + +## ---------------------------------------------------------------------- +## Check that given command $1 has version >= $2.$3 +## return 0 if ok, 1 too old or not found (-> shell conventions). +## ---------------------------------------------------------------------- +check_version() +{ + dir=`pwd` + cd /tmp + foundit= + ## get current version of $1 + desired=$2 + echo $ECHO_N "Checking version of '$1' >= $desired... $ECHO_C" + name=$1 + fullpath=`type $name | awk '{ print $(NF) }'`; + if [ -x "$fullpath" ]; then + foundit=yes; + fi + + if [ "$foundit" != yes ]; then + echo "Didn't find application"; + version=0 + success=no + else + cmdline="$fullpath --version"; + if version=`($cmdline 2>/dev/null)` 2>/dev/null; then + echo >/dev/null + else + version="0"; + fi + if [ -n "${version}" ]; then + version=`echo $version | awk '{ for (i=1;i<=NF;i++) { split($i,j,"."); m=j[1]"."j[2] ; if (m ~ /[0-9]+\.[0-9]+/) { print m ; break; } } }'` + if [ -z "$version" ]; then version=0; fi + success=`echo "$version" "$desired" | awk '{ if ($1 >= $2) { print "yes";} else {print "no";}} '` + else + version=0 + success=no + fi + fi + cd $dir + + if [ $success = "yes" ] ; then + echo "succeeded. ($version)" + return 0; + else + echo "failed. ($version)" + return 1; + fi +} ## check_version() + + + ## -------------------------------------------------------------------------------- + ## 'MAIN' starts here + ## -------------------------------------------------------------------------------- + echo "Bootstrapping configure script and makefiles:" + + ## ---------- first check santity of the installed versions of the build-system + ## in case there's GNU drop-in tools available, set these + + ## some sorry systems don't have proper GNU-make... + if check_version make 3.79; then + echo >/dev/null + else + if check_version gmake 3.79; then + have_gmake=yes; + else + echo "Couldn't find a new-enough version of GNU 'make', please install one!"; + exit 1; + fi + fi + + ## FreeBSD's m4 seems to be broken? Download a fresh one + if check_version m4 1.4; then + echo >/dev/null + else + ## solaris m4 works fine + if test -f /usr/ccs/bin/m4 -o "`uname -s`" = "FreeBSD" + then + echo >/dev/null + else + echo "Couldn't find a new-enough version of 'm4', please install one!"; + exit 1; + fi + # build_lsc_aux "m4-1.4.1" + fi + + if check_version pkg-config 0.15; then + echo >/dev/null + else + echo "Couldn't find a new-enough version of 'pkg-config', please install one!"; + exit 1; + # build_lsc_aux "pkgconfig-0.15.0" + fi + + if check_version autoconf 2.58; then + echo >/dev/null + else + echo "Couldn't find a new-enough version of 'autoconf', please install one!"; + echo "If you have a newer version, set the environment-variable 'AUTOCONF' to its path"; + exit 1; + # build_lsc_aux "autoconf-2.59" + fi + if check_version automake 1.08; then + echo >/dev/null + else + echo "Couldn't find a new-enough version of 'automake', please install one!"; + echo "If you have a newer version, set the environment-variable 'AUTOMAKE' to its path"; + exit 1; + # build_lsc_aux "automake-1.8.5" + fi + + ## ---------- ok, now run aclocal, automake, autohead and autoconf + cmdline="aclocal -I m4 && autoheader && automake && autoconf"; +echo "$cmdline" +if eval $cmdline; then + echo "Done, now run ./configure" + echo " ./configure -C to enable caching" + echo " ./configure --enable-maintainer-mode to enable maintainer depedencies" + exit 0 +else + echo "Something failed .... please check error-message and re-run when fixed." + echo "exiting..." + exit 1 +fi diff --git a/assimilator/Makefile.am b/assimilator/Makefile.am new file mode 100644 index 0000000..1020537 --- /dev/null +++ b/assimilator/Makefile.am @@ -0,0 +1,34 @@ +## $Id: Makefile.am,v 1.2.2.6 2007/08/09 23:37:34 jeffc Exp $ +include $(top_srcdir)/Makefile.incl + +AM_CFLAGS = @CFLAGS@ @DEFS@ -DTEXT_UI -DNDEBUG @PTHREAD_CFLAGS@ +AM_CXXFLAGS = $(AM_CFLAGS) + +AM_LDFLAGS += -Xlinker -R -Xlinker $(INFORMIXDIR)/lib:$(INFORMIXDIR)/lib/esql:$(LD_LIBRARY_PATH) @LDFLAGS@ -static + +CLIBS = @LIBS@ + +BOINC_INC = -I$(BOINCDIR) -I$(BOINCDIR)/api -I$(BOINCDIR)/lib -I$(BOINCDIR)/sched -I$(BOINCDIR)/db +BOINC_LIBS = -L$(BOINCDIR)/sched -lsched @MYSQL_LIBS@ @PTHREAD_LIBS@ -L$(BOINCDIR)/lib -lboinc -L$(SSLDIR) -lcrypto -lssl +HEALPIX_INC = -I$(HEALPIX)/include +HEALPIX_LIBS = -L$(HEALPIX)/lib -lchealpix -lhealpix_cxx -lcxxsupport + +#bin_PROGRAMS = sah_assimilator +noinst_PROGRAMS = sah_assimilator + +sah_assimilator_SOURCES = \ + $(BOINCDIR)/sched/assimilator.cpp \ + $(BOINCDIR)/sched/validate_util.cpp \ + sah_assimilate_handler.cpp \ + ../client/timecvt.cpp \ + ../db/schema_master.cpp \ + ../db/sqlifx.cpp \ + ../db/sqlrow.cpp \ + ../db/sqlblob.cpp \ + ../db/xml_util.cpp \ + ../db/app_config.cpp + +sah_assimilator_CFLAGS = $(AM_CFLAGS) $(BOINC_INC) $(HEALPIX_INC) $(SETILIB_CFLAGS) $(MYSQL_CFLAGS) $(INFORMIX_CFLAGS) -I.. -I../db $(PTHREAD_CFLAGS) -I../client -I../validate +sah_assimilator_CXXFLAGS = $(AM_CXXFLAGS) $(BOINC_INC) $(SETILIB_CFLAGS) $(HEALPIX_INC) $(MYSQL_CFLAGS) $(INFORMIX_CFLAGS) -I.. -I../db $(PTHREAD_CFLAGS) -I../client -I../validate +sah_assimilator_LDADD = $(PTHREAD_CFLAGS) $(BOINC_LIBS) $(SETILIB_LIBS) $(MYSQL_LIBS) $(INFORMIX_LIBS) $(CLIBS) $(HEALPIX_LIBS) + diff --git a/assimilator/sah_assimilate_handler.cpp b/assimilator/sah_assimilate_handler.cpp new file mode 100644 index 0000000..386a0ac --- /dev/null +++ b/assimilator/sah_assimilate_handler.cpp @@ -0,0 +1,760 @@ +#include "sah_config.h" + +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "boinc_db.h" +#include "sched_config.h" +#include "sah_assimilate_handler.h" +#include "sched_util.h" +#include "sched_msgs.h" +#include "parse.h" +#include "sched_util.h" +#include "util.h" +#include "validate_util.h" +#include "filesys.h" + +#include "setilib.h" + +#include "timecvt.h" +#include "db_table.h" +#include "schema_master.h" +#include "app_config.h" +#include "sqlint8.h" +#include "sah_result.h" + +// the boinc assimilator makes these available +extern SCHED_CONFIG config; +extern bool noinsert; + +const double D2R = 0.017453292; +const int fpix_res = 10; // Hz + +const float bad_fp_val_marker = -91.0; + +struct timespec nanotime; + +//inline long round(double x) {return long(floor(x + 0.5f));} + +int populate_seti_result( + result& sah_result, + RESULT& boinc_canonical_result, + WORKUNIT& b_wu, + long long & seti_wu_id +); +template int insert_signals( T& signal, + char * signal_name, + char * wu_name, + sqlint8_t sah_result_id, + std::ifstream& result_file, + receiver_config& receiver_cfg, + int appid, + int max_signals_allowed, + bool check_rfi, + list& hotpix); +template int pre_process(T& signal, receiver_config& receiver_cfg, sqlint8_t sah_result_id, char * wu_name, bool check_rfi); +template int check_values(T& signal, sqlint8_t sah_result_id, char * wu_name); +int get_science_configs(WORKUNIT& boinc_wu, long long seti_wu_id, receiver_config& receiver_cfg, analysis_config& analysis_cfg); +int parse_settings_id(WORKUNIT& boinc_wu); +int get_configs_old_method(WORKUNIT& boinc_wu, long long seti_wu_id, receiver_config& receiver_cfg, analysis_config& analysis_cfg); +long long new_wu_id(long long old_wu_id); + + +// assimilate_handler() is called by BOINC code and is passed the canonical +// result for a workunit. assimilate_handler() reads the referenced result +// file and inserts the result and its signals into the master science DB. +// BOINC also passes the workunit (as it appears in the BOINC DB) and a vector +// containing all results (including the canonical one) for that workunit. +// We use the workunit to determine if there is an error condition. +int assimilate_handler( + WORKUNIT& boinc_wu, vector& boinc_results, RESULT& boinc_canonical_result +) { + int retval=0; + int spike_count=0, spike_inserted_count=0, gaussian_count=0, gaussian_inserted_count=0, pulse_count=0, pulse_inserted_count=0, triplet_count=0, triplet_inserted_count=0, autocorr_count=0, autocorr_inserted_count=0; + static receiver_config receiver_cfg; + static analysis_config analysis_cfg; + workunit s_wu; + workunit_grp s_wu_grp; + result sah_result; + spike sah_spike; + autocorr sah_autocorr; + gaussian sah_gaussian; + pulse sah_pulse; + triplet sah_triplet; + char filename[256]; + char * path; + std::string path_str; + long sah_result_id; + sqlint8_t sah_spike_id, sah_autocorr_id, sah_gaussian_id, sah_pulse_id, sah_triplet_id; + static bool first_time = true; + int sql_error_code; + long long seti_wu_id; + time_t now; + int hotpix_update_count; + int hotpix_insert_count; + + APP_CONFIG sah_config; + + hotpix hotpix; + list qpixlist; // will be a unique list of qpixes for + // updating the hotpix table + list::iterator qpix_i; + + nanotime.tv_sec = 0; + nanotime.tv_nsec = 1000000; + + + // app specific configuration + if (first_time) { + first_time = false; + receiver_cfg.id = 0; + analysis_cfg.id = 0; + retval = sah_config.parse_file(".."); + if (retval) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, + "First entrance to handler : can't parse config file. Exiting.\n" + ); + return(retval); + } else { + retval = db_change(sah_config.scidb_name); + if (!retval) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, + "First entrance to handler : could not open science DB %s. Exiting.\n", + sah_config.scidb_name + ); + return(retval); + } else { + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL, + "First entrance to handler : using science DB %s\n", + sah_config.scidb_name + ); + } + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL, + "Will%s check signals for rfi\n", + sah_config.assim_check_rfi ? "" : " not" + ); + } + // Sometimes we want to perform all assimilation functions + // *except* insertion into the science master DB. + if (noinsert) { + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL, + "[%s] assimilator is in noinsert mode.\n", + boinc_wu.name + ); + } + } else { +/* + retval = db_change(sah_config.scidb_name); + if (!retval) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, + "First entrance to handler : could not open science DB %s. Exiting.\n", + sah_config.scidb_name + ); + return(retval); + } else { + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL, + "First entrance to handler : using science DB %s\n", + sah_config.scidb_name + ); + } +*/ + } + if (noinsert) return 0; // Note that this will result in the WU being marked as assimilated - + // we will not see it again. + + // translate seti wuid for thos wus that changed ids during the DB merge + seti_wu_id = new_wu_id((long long)boinc_wu.opaque); + log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG, + "[%s] old seti WU id is : %lld new seti WU id is : %lld\n", + boinc_wu.name, (long long)boinc_wu.opaque, seti_wu_id + ); + + if (boinc_wu.canonical_resultid) { + log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG, + "[%s] Canonical result is %d. SETI workunit ID is %lld.\n", + boinc_wu.name, boinc_wu.canonical_resultid, seti_wu_id + ); + } else { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, + "[%s] No canonical result\n", boinc_wu.name + ); + } + + if (!boinc_wu.canonical_resultid) { + return 0; // Note that this will result in the WU being marked as assimilated - + // we will not see it again. No canonical result means that + // too many results were returned with no concensus. + + } + + // Obtain and check the full path to the boinc result file. + retval = get_output_file_path(boinc_canonical_result, path_str); + if (retval) { + if (retval == ERR_XML_PARSE) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, + "[%s] Cannot extract filename from canonical result %ld.\n", + boinc_wu.name, boinc_wu.canonical_resultid); + return(retval); + } else { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, + "[%s] unknown error from get_output_file_path() for result %ld.\n", + boinc_wu.name, boinc_wu.canonical_resultid); + return(retval); + } + } else { + path = (char *)path_str.c_str(); + if (!boinc_file_exists(path)) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, + "[%s] Output file %s does not exist for result %ld.\n", + boinc_wu.name, path, boinc_wu.canonical_resultid); + return(-1); + } else { + log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG, + "[%s] Result %ld : using upload file %s\n", + boinc_wu.name, boinc_wu.canonical_resultid, path); + } + } + + // Open it. + std::ifstream result_file(path, ios_base::in); + if (!result_file.is_open()) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, + "[%s] open error for result file %s : errno %d\n", + boinc_wu.name, path, errno + ); + return -1; + } + + retval = get_science_configs(boinc_wu, seti_wu_id, receiver_cfg, analysis_cfg); + if (retval) { + if (retval == 100) { + return (0); + } else { + return (-1); + } + } + log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG, + "[%s] Result %ld : using receiver_cfg %d and analysis_cfg %d\n", + boinc_wu.name, boinc_wu.canonical_resultid, receiver_cfg.id, analysis_cfg.id); + + // Insert a sah result + retval = populate_seti_result(sah_result, boinc_canonical_result, boinc_wu, seti_wu_id); + sah_result_id = sah_result.insert(); + if (sah_result_id) { + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL, + "[%s] Inserted result. Boinc result id is %d. Sah result id is %lld.\n", + boinc_wu.name, boinc_canonical_result.id, + (long long)sah_result_id + ); + } else { + if (sql_last_error_code() == -239 || sql_last_error_code() == -268) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, + "[%s] Could not insert duplicate result. SQLCODE is %ld. SQLMSG is %s.\n", + boinc_wu.name, sql_last_error_code(), sql_error_message() + ); + return 0; // non-fatal - we will never see this result again + } else { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, + "[%s] Could not insert result. SQLCODE is %ld. SQLMSG is %s.\n", + boinc_wu.name, sql_last_error_code(), sql_error_message() + ); + return -1; // fatal - non-dup error + } + } + + // Insert all sah signals in turn + insert_signals( sah_spike, + "spike", + boinc_wu.name, + sah_result_id, + result_file, + receiver_cfg, + boinc_canonical_result.appid, + analysis_cfg.max_spikes, + sah_config.assim_check_rfi, + qpixlist); + + insert_signals( sah_autocorr, + "autocorr", + boinc_wu.name, + sah_result_id, + result_file, + receiver_cfg, + boinc_canonical_result.appid, + analysis_cfg.max_autocorr, + sah_config.assim_check_rfi, + qpixlist); + + insert_signals( sah_gaussian, + "gaussian", + boinc_wu.name, + sah_result_id, + result_file, + receiver_cfg, + boinc_canonical_result.appid, + analysis_cfg.max_gaussians, + sah_config.assim_check_rfi, + qpixlist); + + insert_signals( sah_pulse, + "pulse", + boinc_wu.name, + sah_result_id, + result_file, + receiver_cfg, + boinc_canonical_result.appid, + analysis_cfg.max_pulses, + sah_config.assim_check_rfi, + qpixlist); + + insert_signals( sah_triplet, + "triplet", + boinc_wu.name, + sah_result_id, + result_file, + receiver_cfg, + boinc_canonical_result.appid, + analysis_cfg.max_triplets, + sah_config.assim_check_rfi, + qpixlist); + + // update last hit time to now for each qpix hit + qpixlist.unique(); + hotpix_update_count = 0; + hotpix_insert_count = 0; + qpix_set_hotpix(qpixlist, hotpix_update_count, hotpix_insert_count); +//#define DEBUG_NEIGHBORS +#ifdef DEBUG_NEIGHBORS + for(qpix_i = qpixlist.begin(); qpix_i != qpixlist.end(); qpix_i++) fprintf(stderr, "%ld\n", *qpix_i); +#endif + qpixlist.clear(); + log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG, + "[%s] Updated %d rows and inserted %d rows in the hotpix table\n", + boinc_wu.name, hotpix_update_count, hotpix_insert_count + ); + + return 0; // the successful assimilation of one WU +} + + +template +int insert_signals( T& signal, + char * signal_name, + char * wu_name, + sqlint8_t sah_result_id, + std::ifstream& result_file, + receiver_config& receiver_cfg, + int appid, + int max_signals_allowed, + bool check_rfi, + list& qpixlist) { + + int signal_count=0, signal_inserted_count=0, retval=0, qpix; + sqlint8_t signal_id=0; + + result_file.clear(); + result_file.seekg(0); + while (!result_file.eof()) { + result_file >> signal; + if (!result_file.eof()) { + signal_count++; + signal.result_id = sah_result_id; // fill in any additional signal fields + if (appid == 2) signal.reserved = 1; // temporary for enhanced rollout + if (max_signals_allowed == 0 || signal_count <= max_signals_allowed) { + if (!(signal.rfi_found = check_values(signal, sah_result_id, wu_name))) { + // preprocess only if we have good values + retval = pre_process(signal, receiver_cfg, sah_result_id, wu_name, check_rfi); + qpixlist.push_back(npix2qpix((long long)signal.q_pix)); + } + signal_id = signal.insert(); + if (signal_id) { + log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG, + "[%s] Inserted %s %"INT8_FMT" for sah result %"INT8_FMT"\n", + wu_name, signal_name, INT8_PRINT_CAST(signal_id), INT8_PRINT_CAST(sah_result_id) + ); + signal_inserted_count++; + } else { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, + "[%s] Could not insert %s for sah result %"INT8_FMT". SQLCODE is %d. q_pix is %"INT8_FMT" ra is %lf decl is %lf .\n", + wu_name, signal_name, sah_result_id, sql_last_error_code(), signal.q_pix, signal.ra, signal.decl + ); +#if 0 + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, + "[%s] Could not insert %s for sah result %ld. SQLCODE is %d. SQLMSG is %s q_pix is %"INT8_FMT".\n", + wu_name, signal_name, sah_result_id, sql_last_error_code(), sql_error_message(), signal.q_pix + ); +#endif + return -1; + } + } + } + } + + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL, + "[%s] Inserted %d out of %d %s(s) for sah result %"INT8_FMT" \n", + wu_name, signal_inserted_count, signal_count, signal_name, INT8_PRINT_CAST(sah_result_id) + ); + +} + + +int populate_seti_result( + result& s_result, RESULT& b_result, WORKUNIT& b_wu, long long & seti_wu_id +) { + + // from boinc result + s_result.boinc_result = b_result.id; + s_result.received = time_t_to_jd((time_t) b_result.received_time); + s_result.wuid = seti_wu_id; + s_result.hostid = b_result.hostid; + s_result.versionid = b_result.app_version_num; + s_result.return_code = b_result.exit_status; + if ((int)b_result.opaque & RESULT_FLAG_OVERFLOW) s_result.overflow = 1; + + // from boinc WU + s_result.reserved = b_wu.error_mask; + + return(0); + +} + +template +int pre_process(T& signal, receiver_config& receiver_cfg, sqlint8_t sah_result_id, char * wu_name, bool check_rfi) { + + //long q_pix; + + // barycenter reference frame - note that we pass epoch of the + // day coordinates as seti_dop_FreqAtBaryCenter() does precession. + // We should change this but such a change will involve several + // projects. + signal.barycentric_freq = seti_dop_FreqAtBaryCenter(signal.detection_freq, + signal.time, + signal.ra, + signal.decl, + stdepoch, + (telescope_id)receiver_cfg.s4_id + ); + + // precess in place + eod2stdepoch(signal.time, signal.ra, signal.decl, stdepoch); + + // cubic pixel number with precessed coords plus course frequency + signal.q_pix = co_radeclfreq2npix(signal.ra, signal.decl, signal.barycentric_freq); + + //co_radecl2pix(signal.ra, signal.decl, q_pix); + // move the sky portion to the high order 4 bytes + // and add in freq portion (will land in the low order 4 bytes). + //signal.q_pix = q_pix; + //signal.q_pix = (signal.q_pix << 32) + ((unsigned long)round(signal.barycentric_freq / fpix_res)); + + // send the signal through the rfi checker if configured to do so + if(check_rfi) { + if (is_rfi(signal)) { + log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG, + "[%s] Signal for result %"INT8_FMT" flagged as RFI\n", + wu_name, sah_result_id + ); + } else { + log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG, + "[%s] Signal for result %"INT8_FMT" flagged as RFI CLEAN\n", + wu_name, sah_result_id + ); + } + } + + return 0; +} + +template +int check_values(T& signal, sqlint8_t sah_result_id, char * wu_name) { + + int retval=0; + + // check for ranges and NaN's + + if(signal.ra < 0 || signal.ra >= 24 || signal.ra != signal.ra) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, + "[%s] Signal for result %"INT8_FMT" has out of range RA : %lf\n", + wu_name, sah_result_id, signal.ra + ); + signal.ra = bad_fp_val_marker; + retval = 1; + } + if(signal.decl < -90 || signal.decl > 90 || signal.decl != signal.decl) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, + "[%s] Signal for result %"INT8_FMT" has out of range declination : %lf\n", + wu_name, sah_result_id, signal.decl + ); + signal.decl = bad_fp_val_marker; + retval = 1; + } + // time range is from 1990 to 2050 + if(signal.time < 2447892.5 || signal.time > 2469807.5 || signal.time != signal.time) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, + "[%s] Signal for result %"INT8_FMT" has out of range time : %lf\n", + wu_name, sah_result_id, signal.time + ); + signal.time = bad_fp_val_marker; + retval = 1; + } + if(signal.freq < 0 || signal.freq != signal.freq) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, + "[%s] Signal for result %"INT8_FMT" has out of range frequency : %lf\n", + wu_name, sah_result_id, signal.freq + ); + signal.freq = bad_fp_val_marker; + retval = 1; + } + + return(retval); +} + +int get_science_configs(WORKUNIT& boinc_wu, long long seti_wu_id, receiver_config& receiver_cfg, analysis_config& analysis_cfg) { + + int settings_id, retval=0; + static int first_time=1, current_settings_id=0, current_analysis_config_id=0, current_receiver_config_id=0; + settings settings; + +#if 1 + settings_id = parse_settings_id(boinc_wu); + if (settings_id) { + log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG, + "[%s] Name string contains settings id %ld\n", + boinc_wu.name, settings_id + ); + } else { + log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG, + "[%s] Name string contains no settings id\n", + boinc_wu.name + ); + } +#endif + +#if 0 + // temp hack + if (first_time) { + retval = get_configs_old_method(boinc_wu, seti_wu_id, receiver_cfg, analysis_cfg); + if (!retval) first_time = 0; + } + return (retval); + // end temp hack +#endif + + // can be removed after all WUs have settings (no settings would then be a fatal error) + if (!settings_id) { + get_configs_old_method(boinc_wu, seti_wu_id, receiver_cfg, analysis_cfg); + return(0); + } + // end can be removed after all WUs have settings + + if (settings_id == current_settings_id) { + return (0); + } else { + current_settings_id = settings_id; + + // get settings row + if (settings.fetch(settings_id)) { + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL, + "[%s] Obtained science master DB row for settings table id %ld\n", + boinc_wu.name, settings.id + ); + } else { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, + "[%s] Could not obtain science master DB row for settings table id %ld. SQLCODE is %d\n", + boinc_wu.name, settings_id, sql_last_error_code() + ); + return(-1); + } + + // get analysis config row + if (settings.analysis_cfg.id != current_analysis_config_id) { + if (analysis_cfg.fetch(settings.analysis_cfg.id)) { + current_analysis_config_id = analysis_cfg.id; + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL, + "[%s] Obtained science master DB row for analysis_config table id %ld\n", + boinc_wu.name, analysis_cfg.id + ); + } else { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, + "[%s] Could not obtain science master DB row for analysis_config table id %ld. SQLCODE is %d\n", + boinc_wu.name, settings.analysis_cfg.id, sql_last_error_code() + ); + return(-1); + } + } + + // get receiver config row + if (settings.receiver_cfg.id != current_receiver_config_id) { + if (receiver_cfg.fetch(settings.receiver_cfg.id)) { + current_receiver_config_id = receiver_cfg.id; + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL, + "[%s] Obtained science master DB row for receiver_config table id %ld\n", + boinc_wu.name, receiver_cfg.id + ); + } else { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, + "[%s] Could not obtain science master DB row for receiver_config table id %ld. SQLCODE is %d\n", + boinc_wu.name, settings.receiver_cfg.id, sql_last_error_code() + ); + return(-1); + } + } + + return(0); + + } +} + + +int parse_settings_id(WORKUNIT& boinc_wu) { + + int i=0, j=0, num_tokens=1, pos=0, len=0; + const int max_tokens=7, max_token_len=128, settings_token=4; + char tokens[max_tokens][max_token_len]; + + len = strlen(boinc_wu.name); + + // parse the dot delimited WU name into its + // constituent tokens + for (pos=0, i=0, j=0; + pos < len && i < max_tokens; + pos++) { + if (boinc_wu.name[pos] == '.') { + // terminate this token + tokens[i][j] = '\0'; + j = 0; + i++; + num_tokens++; + continue; + } + if (j >= max_token_len) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, + "[%s] Token too long during name parsing.\n", + boinc_wu.name + ); + exit(1); + } else { + // continue this token + tokens[i][j] = boinc_wu.name[pos]; + j++; + } + } + + if (i >= max_tokens) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, + "[%s] Too many tokens during name parsing.\n", + boinc_wu.name + ); + exit(1); + } else { + tokens[i][j] = '\0'; // terminate the final token + num_tokens++; + } + + if (i >= settings_token-1) { // does name cointain settings? + return(atoi(tokens[settings_token])); // yes - return it + } else { + return(0); + } +} + + +int get_configs_old_method(WORKUNIT& boinc_wu, long long seti_wu_id, receiver_config& receiver_cfg, analysis_config& analysis_cfg) { + + workunit s_wu; + workunit_grp s_wu_grp; + int sql_error_code; + + // workunit + if (s_wu.fetch(seti_wu_id)) { + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL, + "[%s] Obtained science master DB row for wu %lld [%s]\n", + boinc_wu.name, seti_wu_id, s_wu.name + ); + } else { + sql_error_code = sql_last_error_code(); + if (sql_error_code == 100) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, + "[%s] Science master DB row for wuid %lld does not exit. Marking as assimilated.\n", + boinc_wu.name, seti_wu_id + ); + return sql_error_code; + } else { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, + "[%s] Could not obtain science master DB row for wuid %lld. SQLCODE is %d\n", + boinc_wu.name, seti_wu_id, sql_error_code + ); + return -1; + } + } + + // workunit_grp + if (s_wu_grp.fetch(s_wu.group_info.id)) { + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL, + "[%s] Obtained science master DB row for wugid %ld\n", + boinc_wu.name, s_wu_grp.id + ); + } else { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, + "[%s] Could not obtain science master DB row for wugid %ld. SQLCODE is %d\n", + boinc_wu.name, s_wu.group_info.id, sql_last_error_code() + ); + return -1; + } + + // receiver_config - get it if it has changed + if (receiver_cfg.id != s_wu_grp.receiver_cfg.id) { + if (receiver_cfg.fetch(s_wu_grp.receiver_cfg.id)) { + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL, + "[%s] Obtained science master DB row for receiver table id %ld [%s]\n", + boinc_wu.name, receiver_cfg.id, receiver_cfg.name + ); + } else { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, + "[%s] Could not obtain science master DB row for receiver table id %ld. SQLCODE is %d\n", + boinc_wu.name, s_wu_grp.receiver_cfg.id, sql_last_error_code() + ); + return -1; + } + } + + // analysis_config - get it if it has changed + if (analysis_cfg.id != s_wu_grp.analysis_cfg.id) { + if (analysis_cfg.fetch(s_wu_grp.analysis_cfg.id)) { + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL, + "[%s] Obtained science master DB row for analysis table id %ld.\n", + boinc_wu.name, analysis_cfg.id + ); + } else { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, + "[%s] Could not obtain science master DB row for analysis table id %ld. SQLCODE is %d\n", + boinc_wu.name, s_wu_grp.analysis_cfg.id, sql_last_error_code() + ); + return -1; + } + } + + return 0; +} + +long long new_wu_id(long long old_wu_id) { + + workunit seti_wu; + char buf[256]; + + sprintf(buf,"where sb_id=%lld", old_wu_id); + + if (!seti_wu.fetch(std::string(buf))) { + return (old_wu_id); + } else { + return (seti_wu.id); + } + +} diff --git a/assimilator/sah_assimilate_handler.h b/assimilator/sah_assimilate_handler.h new file mode 100644 index 0000000..94b00e4 --- /dev/null +++ b/assimilator/sah_assimilate_handler.h @@ -0,0 +1,7 @@ +#include +#include "boinc_db.h" + +#define PROJECTDIR ".." + +extern int assimilate_handler(WORKUNIT&, std::vector&, RESULT&); + diff --git a/checkin_notes b/checkin_notes new file mode 100644 index 0000000..1f78397 --- /dev/null +++ b/checkin_notes @@ -0,0 +1,4134 @@ +5/20/03 jeffc + This is a preliminary checkin for the project of including WU + analysis parameters in the WU header. It also includes a routine + to read binary data WUs. + + In the end, all analysis parameters will have a default compile + time value which can be supersede by values contained in the WU header. + There will be no command line analysis parameters. + + For this checkin, I added the following variables + to the SETI_WORKUNIT_INFO (swi) structure. + + spike_sigma_thresh; + gaussian_chi_sq_thresh; + gaussian_power_thresh; + gaussian_peak_power_thresh; + beam_width; + num_fft_lengths; + analysis_fft_lengths[MAX_NUM_FFTS]; + chirp_resolution; + num_chirp_ranges; + ChirpFftTable_t chirp_fft_table[MAX_CFFT_PARAMS]; + + These replaced various standalone global variables and constants. + Values for all of these variables are to be included in the WU header. + + Because of all the moving of cfft parameters to swi, chirpfft_tab was removed from + the makefile. This prompted to removal of the params assignment in common_init() + and the necessity of passing the chirp resolution down to where it was needed - + InitChirpStep(). + + I added the following array sizers: + #define MAX_NUM_FFTS 64 + #define MAX_CFFT_PARAMS 2 + + I added code to seti_parse_wu_header() to parse the new header values. + + I added the following fields to PoTInfo_t. + GaussChiSqThresh; + GaussPowerThresh; + GaussPeakPowerThresh; + + In the output routines for each signal type, I added the temporary line: + outfile.flush(); + until a outfile flushing is added to the boinc code. + + The following existing members of swi were changed from float to double and associated + scanf()'s were changed to reflect this: + start_ra + start_dec + end_ra + end_dec + angle_range + + There were some places where we were using strlen where sizeof should have + been used in seti_parse_wu_header(). I fixed these. + + Added new routine read_bin_data() to read binary data. + + Testing. I dumped the generated chirpfft table and it matches the one + generated by the current client. I let the boinc app complete a WU + and the reported signals were correct within tolerances. The reading + of binary data WUs has *not* been tested. + + Still to do (among other things): + - make swi a global structure with compile time initialization. + - swi will include substructures for: + receiver parameters + recorder parameters + splitter parameters + analysis parameters + - create a new source file, seti_parse.C that will contain + routines for parsing complex seti variables like the + above parameter lists. + - there are still a number of single precision floats + in the code. These should all be changed to doubles. + - XML-ize the signal lines in outfile. + - do away with command line options that are redundant with + WU header items. + - add bounding tags to coordinate list in the WU header. + - add bounding tags for the different parameter groups (splitter, + analysis, etc) in the WU header. + - it might be a good idea to not have the limits imposed by + MAX_NUM_FFTS and MAX_CFFT_PARAMS. Instead, we could + have analysis_fft_lengths and chirp_fft_table be pointers + to areas that we realloc as we parse the WU header. + - remove outfile.flush() from the signal outut routines. + + changed sources: + analyzeFuncs.C + analyzeReport.C,h + worker.C + chirpfft.C,h + seti_header.C,h + analyzePoT.C,h + gaussfit.C + unix_main.C + analyze.h + s_util.C,h + +5/21/03 jeffc + Removed the include of hosts.make from Makefile and hardcoded: + + BOINCDIR = /disks/milkyway/a/users/anderson/boinc_cvs/boinc + +7/16/03 korpela + Basic workunit parsing now functioning. Maybe + + Makefile.in + Makefile + seti_header.C + unix_main.C + workunit.sah + db/Makefile.server + db/db_table.h + db/schema_master.sql + db/schema_to_class.awk + +7/21/03 jeffc + CFFT table generation now uses the new header classes. Note that while + the CFFT table still follows the same order in regard to chirp rates, + the order of FFT lengths at a given chirp rate is reversed from that + of the current release client. This should not matter. + + Also pulled out some debug printf()'s. + + chirpfft.C,h + worker.C + analyzeFuncs.C + analyzePoT.C + seti.C + +7/22/03 korpela + schema_master.[Ch] now compile in server mode. + Also make mods to schema, and started a new database (sah2@master_tcp) for + test purposes. + + db/Makefile.server + db/schema_master.sql + db/db_table.h + db/schema_to_class.awk + +7/24/03 korpela + Made changes to fix printing and allow real database access. + + db/Makefile.server + db/schema_to_class.awk + db/sqlinf.ec + db/sqlinf.h + db/db_table.h + +7/24/03 korpela + Moved the SQLROW class to a separate file so it could be used in the client. + Added indentation to the database XML printing to give a more structured feel. + deleted db_sah.* and db_informix.* + + db/Makefile.client + db/Makefile.server + db/db_table.h + db/schema_to_class.awk + db/sqlinf.ec + db/sqlinf.h + db/sqlrow.cpp [New] + db/sqlrow.h [New] + db/db_informix.cpp [Removed] + db/db_informix.ec [Removed] + db/db_informix.h [Removed] + db/db_sah.cpp [Removed] + db/db_sah.h [Removed] + +8/13/03 jeffc + Integrated Eric K's signal classes into the signal INFO structures (SPIKE_INFO + etc). These structures (now classes) contain a signal proper (Eric's class) + plus ancillary data needed for "best of" tracking and graphics. The handling + of the INFO objects required some code reoriganization to not be confusing. + + Signal INFO objects are print_xml()'ed to the state file at checkpoint time. + + Best of signal objects are print_xml()'ed to the outfile upon exit from the + main analysis loop. + + This is a preliminary checkin. More testing needs to be done. There is a known + seg fault with an overloaded assignment operator (for class gaussian at least). + Some debug code and comments need to be pulled out. + + gaussfit.C + unix_main.C + spike.C,h [New] + seti.C + worker.C + analyzeReport.C,h + analyzeFuncs.C + gdata.h + + +8/14/03 jeffc + Removed the hard coded path to the boinc api includes. + + unix_main.C + worker.C + + Removed or commented out various unused variables. + + analyzeReport.C + gaussfit.C + spike.C + seti.C + seti_header.C + +8/15/03 korpela + Added "std_fixes.h", "win_config.h" and "config.h" to db directory + "std_fixes.h" should contain any routines missing from the std:: namespace on + various platforms, ifdefed by defines found in "config.h" and "win_config.h" + Renamed "sqlinf.h" to "sqlapi.h", "sqlinf.cpp" to "sqlifx.cpp" + Misc changes for compiling under windows. + +2003/08/21 quarl + Added standalone-mode run-time option (-standalone, available only in + TEST_VERSION) + + unix_main.C + + +8/28/2003 jeffc + Some (not very clean) mods to fix unix compilation. There was + a dependency of ~/bin/astyle which I removed by removing the indent + logic from schema_to_class.in. db/schema_to_class was not being made + executable, even though this was specified in configure.ac. I specified + it in db/Makefile.in (twice, ugly) instead and this works. + + db/schema_to_class.in + db/Makefile.in + +9/3/03 jeffc + The ANALYSIS_STATE struct was being intialized *after* the parsing + of the state file. We now initialize, then parse. + + worker.cpp + +9/4/03 jeffc testing notes + I ran the client on the reference WU. The results matched well with + the reference result on triplets ans spikes. The reference result contains + 1 pulse and the new result contains no pulses. The reference result contains + 2 gaussians and the new result contains 1 gaussian that did not match well + with either of the reference gaussians. The 2 reference gaussians are + really one gaussian detected twice over a shot time period. + + I realized that the WU specified the new (correct) BW - 0.083 degrees. + I reran the client with the old 0.1 degree BW and the gaussian + matched much better and I got a pulse but it did not match well. + + new gaussian new gaussian reference gaussian + bw = 0.083 bw = 0.1 bw = 0.1 + peak power 2.1929943561554 2.271505355835 2.476470e+00 + mean power 0.6764104962348 0.635128259658 6.407137e-01 + ra 14.868992642608 14.87093261104 14.871 + dec 28.5 28.56 28.56 + time 2451606.8586998 2451606.858738 2451606.85874 + freq 1418917595.1423 1418922359.339 1418922359.34 + chirp rate 6.3884830474854 -21.7681655883 -2.176817e+01 + sigma 3.5038092136383 5.086092948913 4.129033e+00 + chisq 8.4692783355713 8.749799728393 8.323806e+00 + max power 5.0800476074219 5.173916816711 5.173924e+00 + + + new pulse new pulse reference pulse + bw = 0.083 bw = 0.1 bw = 0.1 + power NO PULSE 0.3064200878 1.605851e+00 + mean 0.0019431554 1.964450e-03 + period 0.042048022 1.078955e-01 + ra 14.9086410 14.892 + dec 28.58 28.57 + time 2451606.859504 2451606.85916 + freq 1418919677.7275 1418922119.13 + fft len 32 32 + chirp rate 0 0 + snr 6.004581928253 6.854417e+00 + thresh 5.9453372955 6.675629e+00 + len_prof 12 32 + + I added the reference result and the reference result to CVS. + + checkin_notes + reference_work_unit.sah + old_format_reference_result.sah + + I added a final outfile.flush() and that fixed the problem whereby we + were getting a truncated result. + + analyzeFuncs.cpp + +David Sept 12 2003 + - Moved SPIKE_INFO etc. from gdata.h to seti.h + Principle: everything relating to graphics should be surrounded by + #ifdef BOINC_APP_GRAPHICS + - Changed gdata from pointer to struct + - Defined new structs G_SPIKE_INFO etc. for graphics-related + signal info, to avoid template/constructor problems in graphics code + - Changed BOOLEAN to bool everywhere + + Graphics now work in a rudimentary way. + + Changes most files. New file: gdata.cpp + +Eric K 13 Sep 03 + -Moved client into client directory and modified makefiles + accordingly. + +Eric K 15 Sep 03 + -Moved win_build into client directory and modified seti_boinc.dsp + accordingly. + +Jeff 17 Sep 03 + No code changes. This is the branch point for the beta. The tag is: + + setiathome-4.xx_all_platforms_beta + + for both seti_boinc and boinc. They both make on solaris without serious + error and the resulting seti client links without error with the resulting + boinc libs. I ran the seti solaris 2.7 client on the reference WU and + it produces a reasonable looking result file. The science content has + not yet been fully validated but that is OK. "Best of" signals in the + result looks good. Checkpoint and restart work. + +Eric K. 22 Sep 03 + + Checked in several mods to the setiathome-4 beta branch and the main branch + required to get the splitter working properly under boinc. + + config.h.in + configure + configure.ac + db/db_table.h + db/sqlrow.cpp + db/tools/Makefile + db/tools/Makefile.in + db/tools/analysis_configs.xml + db/tools/insert_analysis_config.cpp + db/tools/insert_s4_receivers.cpp + db/tools/insert_splitter_config.cpp + db/tools/print_s4_receivers.cpp + db/tools/recorder_configs.sql + db/tools/splitter_configs.xml + splitter/Makefile.in + splitter/splitparms.h + splitter/splitter.cpp + splitter/splitter.h + splitter/wufiles.cpp + win_build/seti_boinc.dsp + +Jeff 24 Sep 03 + We now pass a tag to the XML print routine for the printing + of the best signals. + + client/ + analyzeFuncs.cpp + +Eric K 09/25/03 + Binary types in db tables are now of class sqlblob + + Makefile.in + client/Makefile.in + client/analyzeReport.cpp + client/seti.h + db/db_table.h + db/schema_master.cpp + db/schema_master.h + db/schema_master.sql + db/schema_to_class.awk + db/sqlblob.cpp + db/sqlblob.h + db/tools/Makefile + db/tools/Makefile.in + +Eric K 09/28/03 + Added operator =() to all db_table<> children. + Changed db_*::operator =() to call the child = operators. + + db/db_table.h + db/schema_to_class.awk + db/schema_master.h + db/schema_master.cpp + +Jeff 9/29/03 + Boolean standalone now initialized to false. + + If we have no WU to read (fopen() failed) in read_wu_state(), we set retval + to FOPEN_FAILED and return. This is certainly good to do and prevents + seg faults due to empty SWI's. But we need to also check SWI data before + using it. + + client/main.cpp + client/worker.cpp + +David Sept 30 2003 + - include graphics-related stuff only if BOINC_APP_GRAPHICS is defined + + main.cpp + +David Oct 2 2003 + - read_wu_state(): if there's no input file, return an error + - got rid of windows .exe + + client/ + worker.cpp + client/win_build/Debug + seti_boinc.exe (removed) + +Eric K. Oct 2 2003 + - moved xml_indent() from sqlrow.cpp, sqlrow.h to boinc/lib/xml_util.[Ch] + + db/sqlrow.cpp + db/sqlrow.h + +David Oct 4 2003 + - Reorganized graphics code to facilitate graphical variation + Factored user prefs into GRAPHICS_PREFS + Combined all graphics-related stuff into SAH_GRAPHICS + This inherits from GDATA, GRAPHICS_PREFS etc. + so that its member functions (all render-related code) + can access data without qualification. + + There are three top-level graphics "styles": + Classic: 3D version of original graphics + Panels: text is on rotating panels + Headsup: text is 2D in corners of screen + Each of these styles has numerous user-configurable settings. + + Not everything is working yet but the code is in better shape. + + client/ + analyzeFuncs.cpp + gdata.cpp,h + main.cpp + sah_gfx.cpp,h + win_build/ + seti_boinc.dsp + +David Oct 6 2003 + - Implement rotating-panels display for SETI@home + - Factor out generation of text in display + + client/ + analyzeFuncs.cpp + sah_gfx.cpp,h + win_build/ + seti_boinc.dsp + p004_640.jpg (new, just a sample background image) + +David Oct 7 2003 + NOTE: there are three different structs for each signal type. E.g.: + class gaussian (in schema_master.h) + has PoT array in unsigned chars + struct GAUSS_INFO (in seti.h) + contains "gaussian" as an element. + Also has score, bin, and the PoT array in floats + G_GAUSS_INFO (in gdata.h) + Has the minimal set of info needed to display a Gaussian. + A few fields from GAUSS_INFO, plus an "is_best" flag, + and a "dirty" flag (has this been displayed yet?) + Has a "copy" member function for copying from a GAUSS_INFO + + The variable best_gauss (of type GAUSS_INFO) etc. (in analyzeReport.cpp) + stores the best Gaussian found so far (zero power if none) + Stored and read from the state file. + The variable SAH_GRAPHICS::gi (of type G_GAUSS_INFO) + stores the Gaussian currently being displayed (zero power if none) + + Normally SAH_GRAPHICS::gi is copied from best_gauss, + and its is_best flag is true. + However, during analyze_pot(), SAH_GRAPHICS::gi is just the + most recent Gaussian computed, and is_best is false. + + - Set the "dirty" flag of SAH_GRAPHIC's signals whenever copy to them + (i.e. don't need to do this separately) + - Remove "is_best" field of GAUSS_INFO etc. + - Copy PoT arrays using a for loop, not a memcpy() + - In graphics code: factor out the decision about which signal to display + into a separate function (choose_signal_to_display()). + Display a dirty signal if there is one, + otherwise rotate among those that are actually there. + + client/ + analyzeReport.cpp + gaussfit.cpp + gdata.cpp,h + sah_gfx.cpp,h + seti.h +David Oct 7 2003 + - show CPU time in Classic-style graphics + - improve code factoring in Classic-style graphics + - add "present" flag to TEXTURE_DESC + - fix function names + + client/ + gdata.h + sah_gfx.cpp + win_build/seti_boinc.dsp + +Oliver Oct 8 2003 + - draws logos and user icons + - fixed headsup display + + client/ + sah_gfx.cpp + win_build/seti_boinc.dsp + +David Oct 8 2003 + - Use new texture-drawing interface + + sah_gfx.cpp,h + +Jeff Oct 9 2003 + Fixed bug in calls to ::parse_xml(). The string passed to these + routines must include the outer signal tags (eg . + + client/ + seti.cpp + +Jeff Oct 10 2003 + Checkpoint triplet PoTs. + + client/ + seti.cpp + +David Oct 10 2003 + - The functions that copy signals to the graphics structure now + have a "best_of" flag + - The functions that copy signals to the graphics structure now + check whether what they're copying is the same as what's already there; + if so they don't set the "dirty" flag + (otherwise the copy of the best-of signals after each PoT analysis + disrupt the 5-second cycle of signals) + - Fixed the code that implements 5-second cycle of signals + (it was doing integer arithmetic on a huge double, yielding negative results) + - Alpha of pillars is one (opaque) + - made a STARFIELD class + - changed GRAPH_2D to RIBBON_GRAPH + - Added support for tick marks in RIBBON_GRAPH + - tested parsing of XML preferences. + Preferred way of changing graphics is to edit app_init.xml + + client/ + AnalyzeFuncs.cpp + AnalyzeReport.cpp + gdata.cpp,h + sah_gfx.cpp,h + win_build/ + init_data.xml + +Jeff Oct 10 2003 + - Fixed bug that was preventing the choosing of the first best + spike (a legitimate spike score can be < 0). + + client/ + spike.cpp + +Oliver Oct 10 2003 + - Updated panel display, moved camera to origen + + client/ + sah_gfx.c,h + +David Oct 14 2003 + - changed angle param from "rate" to "period" + - put complete set of graphics prefs in init_data.xml + - updated graphics prefs code to use same set of parameters and names + as the Web code (astropulse/html/project_specific_prefs.inc) + - removed cruft + + + client/ + main.cpp + sah_gfx.cpp,h + seti.cpp + win_builc/init_data.xml + +Oliver Oct 14 2003 + - fixed stars, moved camera back to original location + + client/ + sah_gfx.cpp + +Oliver Oct 16 2003 + - more improvements on star generation + - fixed resize via. applying a universal glScale + + client/ + sah_gfx.cpp,H + +Jeff Oct 16 2003 + - tested, debugged and added documentation to the validator + and assimilator. + - Built production executables and installed them in the + "astropulse" beta test. + - Added the informix lib paths to the boinc master cron + program. This is needed for the assimilator. + - Note that at this point server side executables (and all + parts that make them up) have to be built on koloth (the + production host). This is because koloth has a different + gcc (and libs) than our other machines. Our standard gcc + is v 3.0.4 (bundled with libstdc++.so.3) while on koloth + we have gcc 3.3 (bundled with libstdc++.so.5). Running on + koloth after building elsewhere gives: + fatal: libstdc++.so.3: open failed: No such file or directory + - Note that various Makefile.in's specify the mysql library as + being /usr/local/mysql. But for koloth it needs to be + /usr/local/mysql_32bit. Linking against /usr/local/mysql + on koloth (a 64 bit mysql) gives + ld: warning: file /usr/local/mysql/lib/libmysqlclient.a(libmysql.o): + wrong ELF class: ELFCLASS64 + There will be a sysadmin fix for this to make /usr/local/mysql + correct on all hosts. + + code: + assimilator/ + sah_assimilate_handler.cpp,h + validate/ + sah_boinc_db.cpp,h + sah_result.cpp,h + sah_validate.cpp + + systems: + koloth:~boincadm/projects/ + AstroPulse_Beta/ + config.xml + cron/ + cron-boinc + +David 16 Oct 2003 + - Factored out the part of graphics that is common to both SETI@home and Astropulse + (SAH_GRAPHICS_BASE, in sah_gfx_base.cpp) + This will make it easier to maintain consistent graphics and preferences + between the two apps + + client/ + sah_gfx.cpp,h + sah_gfx_base.cpp,h (new!) + win_build/seti_boinc.dsp + +Jeff 17 Oct 2003 + - Best triplet PoT starting tag now has encoding type and length. + - Flush the results file (outfile) only at checkpoint time and workunit + completion time. + - Cleared out various old comments and debug lines. + + client/ + analyzeFuncs.cpp + analyzeReport.cpp + seti.cpp + +Oliver 17 Oct 2003 + - Fixed panel size + client/ + sah_gfx.cpp + +Jeff 17 Oct 2003 + - Checkpoint the gaussian display power threshold. This used + to be set to zero at program start/restart and then get bumped + to a higher value with the first gaussian (but then get set + back to zero on the next restart). Thus, if the best gaussian + in the WU was in fact below tha higher thershold, the same + WU could yield different best gassians depending on restart + history. This would have interfered with redundacy based + validation. + + client/ + analyzeReport.cpp + gaussfit.cpp + seti.cpp + seti.h + +Jeff 18 Oct 2003 + - Code cleanup. Removed some long commented out code and unneeded + header files. + + client/ + analyzeReport.cpp,h + gaussfit.cpp + seti.cpp,h + spike.cpp + +David 20 Oct 2003 + - Don't use len_prof as pulse PoT length; use PULSE_POT_LEN + + client/ + gdata.cpp,h + sah_gfx.cpp + +Jeff 22 Oct 2003 + - Specify app version as 2.00. + - Use new xml_util routines to output the triplet PoTs to the + state file as comma separated values. The min and max PoTs + are now printed to the state file as 2 separate PoTs. + + configure.ac + client/ + seti.cpp + +David 23 Oct 2003 + - fixed bug where an MFILE::printf() was overrunning its static buffer. + (use MFILE::write() instead; also upped buffer size to 20K) + client/ + seti.cpp + + +Oliver 24 Oct 2003 + - updated so that it will pass the name of the axis labels in when graph is created + + client/ + analyzeFuncs.cpp + sah_gfx.cpp + sah_gfx_base.cpp,h + +David 25 Oct 2003 + - split the graphics initialization into two parts: + 1) worker thread, which sets up the data structure + shared between worker and graphics + 2) graphics thread, which does OpenGL calls (must be in graphics thread). + This fixes a race condition where sometimes the worker thread + would access the shared data structure before it was initialized. + - check for logos present before drawing. + Fixes bug with white boxes drawn in place of logos + + client/ + main.cpp + sah_gfx.cpp + sah_gfx_base.cpp,h + +Jeff 27 Oct 2003 + - use match_tag() rather than parse_str() to find the triplet PoT's + in the state file. + - bump version to 2.01. + + configure.ac + client/ + seti.cpp + +Eric K. 27 Oct 2003 + - tried to fix the indentation problem by storing and recovering the + xml_indent_level at the beginning and end of write_state_file() + + client/ + seti.cpp + +Jeff 27 Oct 2003 + - renamed output file to result.sah + + client/ + s_util.h + +David 28 Oct 2003 + - call boinc_resolve_filename() for input, output files + + client/ + worker.cpp + +Jeff 29 Oct 2003 + - bumped version to 2.03 + + configure.ac + +Oliver 29 Oct 2003 + - fixed scaled logos + + client/ + sah_gfx_base.cpp + +Jeff 29 Oct 2003 + - gather up the entire triplet PoT from the state file before + sending it off to the XML parser. + - bump version to 2.04 + + client/ + seti.cpp + configure.ac + +Jeff 30 Oct 2003 + - simplified the coding and raised the buffer size to 8K in + parse_state_file(). + + client/ + seti.cpp + +David 31 Oct 2003 + - reorganized graphics to accommodate new BOINC mechanism + for adaptation to changing user preferences. + SAH_GRAPHICS now includes graphics objects rather than pointers, + since the may need to be init()ed repeatedly. + The code organization is described in a block comment + at the top of sah_gfx.cpp + - in panel display, panel colors are 1/3 and 2/3 points of hue range + + client/ + analyzeFuncs.cpp + main.cpp + sah_gfx.cpp,h + sah_gfx_base.cpp,h + win_build/ + seti_boinc.dsp + +David 1 Nov 2003 + - more "graphics follow prefs" changes + + client/ + sah_gfx.cpp + sah_gfx_base.cpp + +David 4 Nov 2003 + - removed old code (reduce_output() etc.) that output the + top N signals globally + - removed *_start() and *_end() functions from source files. + These are relics of an old and failed code-checksum scheme + - use string instead of char[256] a few places + + client/ + analyzePot.cpp + analyzeReport.cpp + gasdev.cpp + gaussfit.cpp + malloc_a.cpp + pulsefind.cpp + ran1.cpp + seti.cpp + seti_header.cpp + worker.cpp + +David 4 Nov 2003 + - released version 2.05 in beta test + +Jeff 5 Nov 2003 + - beta released setiathome_2.06_sparc-sun-solaris2.7. Looks like + setiathome_2.06_windows_intelx86 was released yesterday. + +David 6 Nov 2003 + - track BOINC API changes + + client/ + sah_gfx.cpp + win_build/ + seti_boinc.dsp + +David 6 Nov 2003 + - release windows version 2.07 + +Jeff 17 Nov 2003 + + - Added the GNU GPL to files in client/, db/ (except db/tools/), m4/, + and some top level files. Removed some obsolete files. + + client/ + * added GPL except... + fft8g.cpp added ooura license + *.{cpp,h} removed CVS/RCS log lines + gasdev.cpp removed + ran1.cpp removed + nr.h removed + lcgamm_test.cpp removed + Makefile.in removed references to nr stuff + db/* added GPL (but not to files in tools/) + m4/* added GPL + + + - I also created a public release distribution that includes everything + needed to build the client side application. We should automate this. + For reference, the distro contains no CVS directories and does contain: + COPYING + config.guess + config.h.in + config.sub + configure + configure.ac + install-sh + Makefile.in + aclocal.m4 + config.h + client/* + *except* : + win_build/ + Logo2.bmp + Logo2.jpg + p004_640.jpg + db/* + *except*: + tools + m4/* + + + +Karl 2003-11-21 + - recompiled with BOINC api bug fix. + - 2.08 client release (non-Windows only) + +David 25 Nov 2003 + - change to + - restored missing }; + - removed deleted files from .dsp file + + client/ + analyzeFuncs.cpp + analyzeReport.cpp + spike.cpp + sah_gfx_base.h,cpp + win_build/ + seti_boinc.dsp + +Jeff 27 Nov 2003 + - New release - bumbed version to 2.10 + + configure.ac + +Jeff 01 Dec 2003 + - Added debug code and fixed path bugs in validator and assimilator. + The production validator should be working at this point. + + validator/ + sah_boinc_db.cpp + sah_boinc_db.o + assimlator/ + sah_assimilate_handler.cpp + +Karl 2003-12-02 + - created script to trim sources of files we don't want to + distribute. (it's a badass 'find' line) + - created nightly tarball script. + + trim-sources (added) + nightly-tarball (added) + +Jeff 03 Dec 2003 + - released a statically linked version of the app for linux. Bumped + version to 2.11 + + configure.ac + +Jeff 08 Dec 2003 + - We have the same gcc version problem with solaris that we do with + linux whereby if the version number of libstdc++.so on the run + machine is different than that on the build machine, the loader + fails. However, on solaris you cannot just say gcc -static as there + are dynamic only versions of some needed libs, namely libdl and + libaio. I tried to use the -Xlinker gcc option which theoretically + should allow us to specify the link (collect2) line in precise + detail. But -lstdc++ kept showing up twice with one occurrence + being outside my -Xlinker -B -Xlinker static directive. So I + hand crafted a collect2 line and placed it in a file - collect2_line. + Sourcing this file produces an executable that will load and run + across gcc versions (and solaris versions for that matter). I + don't like it but it works. + + client/ + collect2_line (new file) + +Jeff 09 Dec 2003 + - Released version 2.12 for solaris 7, with a statically linked + stdc++. + + configure.ac + client/ + collect2_line + +Eric K. 13 Dec 2003 + - Changed from error return to exception based error handling. + - The seti_error class is defined in s_util.[h,cpp] + - Not yet tested under Windows... + + client/ + analyzeFuncs.cpp + analyzePoT.cpp + analyzeReport.cpp + chirpfft.cpp + gaussfit.cpp + main.cpp + pulsefind.cpp + s_util.cpp + s_util.h + seti.cpp + seti_header.cpp + spike.cpp + worker.cpp + +12/16/03 jeffc + - The SETI_WU_HEADER was declared gloabally as "seti_wu_header" + but was passed around by reference, usually under the name + "swi". This passing around was historical and had become + confusing and needless. This change is the first of 2 steps + to have all code access the global SETI_WU_HEADER as "swi". + I removed the passing of the entire swi from all function + calls that had it. Still to do is to remove the passing of + individual fields of swi. + + client/ + analyzeFuncs.cpp,h + analyzePoT.cpp,h + analyzeReport.cpp + chirpfft.cpp,h + gaussfit.cpp + seti.cpp,h + seti_header.cpp,h + spike.cpp + worker.cpp + +12/16/03 jeffc + - The assimlator to insert into the science DB. + + assimilate/ + sah_assimilate_handler.cpp + +Jeff 18 Dec 2003 + - Commented out the catch "(boinc_error e) {}" in main.cpp. Windows compiles + were failing on it. + - Removed the second parameter, "wu", from the cnvt_fftlen_hz() call in + in sah_gfx.cpp. The prototype of cnvt_fftlen_hz() has changed and + wu was wrong (and unused) anyway. + + client/ + main.cpp + sah_gfx.cpp + +Jeff 19 Dec 2003 + - New windows release - setiathome_2.13_windows_intelx86. + This was built on machine "bart", winXP, VC6. + - Note that with this release I started archiving both release + and debug builds (with symbol table files) in apps_release_sets/ + in the project directory. The contents fo this windows release + is: + apps_release_sets/setiathome_2.13_windows_intelx86/release/ + setiathome_2.13_windows_intelx86 + vc60.idb + apps_release_sets/setiathome_2.13_windows_intelx86/debug/ + setiathome_2.13_windows_intelx86.exe + setiathome_2.13_windows_intelx86.pdb + vc60.idb + vc60.pdb + +Jeff 22 Dec 2003 + - New windows release - setiathome_2.14_windows_intelx86. + This is the debug build associated with release 2.13. + +David 23 Dec 2003 + - fixed bug in seti_parse_data(): + "catch" clause was freeing a pointer that wasn't always assigned + + client/ + seti.cpp + +Jeff 26 Dec 2003 + - Made sure that we always initialize retval to 0. + + client/ + analyzeFuncs.cpp + analyzeReport.cpp + seti.cpp + worker.cpp + +Jeff 26 Dec 2003 + - Added boinc/lib/filesys.C,h to windows VC++ project. + - Bumped version to 2.17. + - Released windows app 2.17 (debug version). + + client/ + configure.ac + client/win_build/ + seti_boinc.dsp + +Eric (via Jeff) 26 Dec 2003 + - Implement copy and assignment constructors for SPIKE_INFO. + + client/ + seti.h + spike.cpp + analyzePoT.cpp + +Jeff 28 Dec 2003 + - Make sure that retval is checked after calls to MFILE::printf. + + client/ + analyzeFuncs.cpp + seti.cpp + +Jeff 28 Dec 2003 + - release windows app 2.18 + +Jeff 29 Dec 2003 + - release solaris app 2.18 (semi-static build) + + configure.ac (bump version) + configure + +Jeff 30 Dec 2003 + - release linux app 2.18 (static build). + The build was done on host shaggy. There is some malfunctioning of autoconf/configure + such that I had to hand code -DHAVE_ATOLL and -DHAVE_DIRENT_H into client/Makefile and + VERSION_MAJOR VERSION_MINOR into config.h. + +Jeff 5 Jan 2004 + - Commented out the generation of reconfigure code in the top level Makefile. + + Makefile.in + +Jeff 5 Jan 2004 + - Removed depricated code used in processing old style (nonXML) WU headers. + - Removed depricated code used in processing command line science params (science + tuning is now done in the WU header). + - Overloaded the seti_parse_wu_header() and seti_write_wu_header() functions. One version + of each makes use on the global SETI_WU_INFO structure and one version of each + takes a SETI_WU_INFO reference as a parameter. + - Moved the global SETI_WU_INFO from seti.cpp to seti_header.cpp so that the splitter + could see it. Linking the splitter to seti.o produced a number of unresolved + symbols. We should probably put all global objects in some file called global.cpp. + - Added a CC= line to the splitter's Makefile.in and removed some test programs. + + client/ + main.cpp + seti.cpp + seti_header.cpp,h + splitter/ + Makefile.in + +Jeff 9 Jan 2004 + - The splitter places the seti WU ID into the boinc WU opaque field. Now + the assimlator reads that ID from the boinc WU opaque field and places + it into the seti result wuid field, providing a reference from result + to workunit. + + assimlator/ + sah_assimilate_handler.cpp + +Jeff 13 Jan 2004 + - A many line set of changes to have the code use the analysis + configuration parameters in the WU header rather than those in analyze.h. + Specifically: + - Removed all analysis paramters from analyze.h. For reference, + these were: + #define BOX_CAR_LENGTH 8192 + #define POINTS_IN_CHUNK 32768 + #define SPIKES_TO_REPORT 1 + #define SIGMA_THRESH 22 + #define THRESH_IN_MEAN 3 + #define THRESH_IN_TRUEMEAN 3.2f + #define CHI_SQ_THRESH 8.8f + #define PULSE_MAX 40960 + #define PULSE_MIN 16 + #define PULSE_FFT_MAX 8192 + #define PULSE_THRESH 17.0 + #define PULSE_DISPLAY_THRESH 0.5f + #define TRIPLET_MAX 131072 + #define TRIPLET_MIN 16 + #define TRIPLET_THRESH 7.75 + #define OVERLAP_FACTOR 0.5 + #define PULSE_BEAMS 1.0 + #define GAUSS_POT_LEN 64 + #define PULSE_POT_LEN 256 + #define TRIPLET_POT_LEN 256 + #define POT_LEN 64 + #define T_OFFSET 1 + #define MIN_SLEW 0.0021f + #define MAX_SLEW 0.0105f + #define BEAM_WIDTH 0.1 + #define GAUSS_SIGMA 6.78 + #define GAUSS_SIGMA_SQ 45.9684 + - In all places where analyze.h paramters where used, + switched to the corresponding swi.analysis_cfg field. + - Many of the PoTInfo fields had been initialized at compile + time with analyze.h values. PoTInfo is now initialized at + compile time with zeros and and with swi.analysis_cfg values + at run time in ComputePoTInfo(). + - The signal info objects (SPIKE_INFO, etc) used to be globally + instantiated at compile time in analyzeReport.cpp. These + are now global pointers (in analyzeReport.cpp). They + are instantiated via reset_high_scores() at run time. reset_high_scores() + first deletes the signal info objects if they exist and then + (re)new's them into existance. + This change was needed because PoT array sizing within these objects + is now a run time function. + - All '.' notation to get to signal info fields had to be changed + to "->" throughout the code. + - Moved the signal info method code from seti.h (where it was inline) + to seti.cpp (where it is not). + + client/ + analyze.h + analyzeFuncs.cpp,h + analyzePoT.cpp + analyzeReport.cpp,h + gaussfit.cpp + pulsefind.cpp + seti.cpp,h + seti_header.cpp + spike.cpp,h + +Jeff 14 Jan 2004 + - added the following #defines back, in gdata.h this time. + There are graphics only global signal info structures whose + PoT arrays are sized at compile time. Making these dynamic + would probably mean instantiating them via new in main.cpp + right before the call to sah_graphics.worker_thread_init() + or in sah_graphics.worker_thread_init() itself. Note that + at this point, graphics initialing happens *before* we + read in the WU and the included analysis config info. That + would have to change. + #define GAUSS_POT_LEN 64 + #define PULSE_POT_LEN 256 + #define TRIPLET_POT_LEN 256 + + client/ + gdata.h + + +Jeff 14 Jan 2004 + - Added 2 new fields to analysis_config table: + pulse_beams smallfloat + max_signals integer + These fields have been added to analysis_config table in + the sah2@master_tcp database but have not yet been given values. + + db/ + schema_master.sql + schema_master.h + schema_master.cpp + +Jeff 15 Jan 2004 + - Changed to pointer syntax for _INFO structs in the + G__INFO copy constructors. + + client/ + gaussfit.cpp + spike.cpp + analyzeReport.cpp + gdata.cpp,h + +Jeff 15 Jan 2004 + - Added new row (id = 4) to table analysis_config in the backend + DB. Changed: + bsmooth_chunk_size from 32767 to 32768 + pulse_beams from NULL to 1.0 (new field) + max_signals from NULL to 30 (new field) + + max_signals may need to be adjusted. + + db/tools/ + analysis_configs.xml + +Jeff 15 jan 2004 + - Added stackwalker source to the client win_build directory. + This code was copied over from the boinc source tree. + + client/ + win_build/ + Stackwalker.cpp,h + +David 15 Jan 2004 + - validator: if can't get output file, mark the result as invalid. + This deals with situations where (usually because of a BOINC bug) + there is no output file, and infinite retrying won't help. + + validate/ + sah_boinc_db.cpp + sah_validate.cpp + +David 19 Jan 2004 + - call initGL() in SAH_GRAPHICS_BASE::graphics_thread_init() + (moved from windows_opengl.C, to remove OpenGL dependency) + - add win_util.h to project + + client/ + sah_gfx_base.cpp + win_build/ + seti_boinc.dsp + +Jeff 20 Jan 2004 + - fixed a bug in the G_PULSE_INFO copy constructor where the pulse proper + pot was being assigned rather than pot_max. + - removed references to GAUSS_INFO.pot as it was not being used anywhere. + This was the floating point pot outside of the gaussian proper. + + client/ + gdata.cpp + seti.cpp,h + +Jeff 21 Jan 2004 + - removed a redundant call to reset_high_scores() in parse_state_file(). The + call in seti_init_state() suffices. + - removed the call to report_init() in seti_analyze and replaced its functionality + with a call to new function reload_graphics_state() in parse_state_file(). + - removed unneeded calls to boinc_time_to_checkpoint() in seti_analyze(). + + client/ + analyzeFuncs.cpp + analyzeReport.cpp,h + seti.cpp + +Jeff 22 Jan 2004 + - app release 2.19. Cvs tagged as app_release_2_19. + + client/ + configure + configure.ac + +Jeff 22 Jan 2004 + - removed depricated and commented out code. + + client/ + analyzeFuncs.cpp + analyzePoT.cpp + analyzeReport.cpp + main.cpp + seti.cpp + seti_header.cpp + spike.cpp + +Jeff 26 Jan 2004 + - changed all calls to match_tag() to xml_match_tag(). + - (via Eric) implemented assignment and copy constructors for TRIPLET_INFO. + - moved call to seti_init_state() to after the call to seti_parse_wu(). + This is was necessary because seti_init_state() needs configuration + data contained in the WU header. This may fix a number of access + violations and seg faults. + + client/ + analyzeReport.cpp + seti.cpp,h + seti_header.cpp + worker.cpp + +Jeff 28 Jan 2004 + - Fixed a bug in the copy constructor for PULSE_INFO + - Got stackwalker working (Rom Walton did this). + - got rid of the dependency on the windows debug runtime (Rom). + - Bumped version to 2.21 for release. + - Cvs tagged as app_release_2_21. + + client/ + main.cpp + seti.cpp + configure.ac + configure + win_build/ + seti_boinc.vcproj + +Jeff 30 Jan 2004 + - Invoke stackwalker in stack trace mode only. It was crashing with + with an access violation during memory allocation tracing. (Rom Walton) + - Made progress more linear by treating pulse finding as it should be - + an (n^2)log(n) operation. + - Update global progress upon each return from find_pulse. This happens + several times for reach frequency bin, ie much more often than before. + - CVS tagged source as app_release_2_22 and released as version 2.22 on + the windows platform. + + configure.ac + configure + client/ + main.cpp (Rom) + analyzeFuncs.cpp + analyzePoT.cpp + progress.cpp,h (new files) + Makefile.in + win_build/ + seti_boinc.vcproj (added new files) + +Jeff 01 Feb 2004 + - Changed the pulse finding progress scale factor from 1/1e6 to 1/.65e6. + - Removed commented out code. + + client/ + progress.cpp + analyzeFuncs.cpp + analyzePoT.cpp + +Jeff 02 Feb 2004 + - Progress clean up. + + client/ + analyzePoT.cpp + progress.cpp + +Rom 02 Feb 2004 + - Hooked up to diagnostics library + - Replaced ANSI C assert with BOINCASSERT + + client/ + analyzePot.cpp + analyzeReport.cpp + lcgamm.cpp + main.cpp + spike.cpp + client/winbuild + seti_boinc.vcproj + +Rom 03 Feb 2004 + - Modified stackwalker so it attemps to use the dbghelp.dll that is included + with BOINC before using the search path. + + client/winbuild + stackwalker.cpp + +Jeff 03 Feb 2004 + - Moved progress related globals from analyzeFuncs.cpp,h to progress.cpp,h. + - Changed some floats to doubles to get rid of compile warnings. + + client/ + analyzeFuncs.cpp,h + analyzePoT.cpp + progress.cpp,h + seti.cpp + worker.cpp + +Jeff 04 Feb 2004 + - Windows release. - CVS tagged source as app_release_2_23. + +Rom 05 Feb 2004 + - Remove stackwalker from the project as it has been moved to the boinc project + api folder + - updated project files to new locations + + client/win_build/ + seti_boinc.vcproj + stackwalker.h + stackwalker.cpp + +Rom 06 Feb 2004 + - Removed boincdiag.cpp, h from project files. + + client/win_build/ + seti_boinc.vcproj + +Jeff 08 Feb 2004 + - Impelmented overflow detection. Upon reaching a maximum signal + count the app will throw a RESULT_OVERFLOW exception on the + next attempt to write a signal. Max_signals is an anlaysis + config parameter. It is not yet being provided in the WU headeer + so the app has it hard coded with the value 30. The current + signal count is saved to and read from the state file. + - PoTInfo.PulseBeams now gets its value from an analysis config + paramter. It is not yet being provided in the WU headeer + so the app has it hard coded with the value 1.0. + - Renamed write_state_file() to checkpoint() as this routine + is doing more than writing to the state file. + - Routine checkpoint() now has a paramter to tell it to force + the checkpoint without a call to boinc_time_to_checkpoint(). + + client/ + analyzeFuncs.cpp + analyzePoT.cpp + analyzeReport.cpp,h + main.cpp + s_util.cpp,h + seti.cpp,h + seti_header.cpp + +Jeff 11 Feb 2004 + - kludge fix to the pulse display PoT assert failures. If we see + a value over 255, we set it to 255. + - change all match_tag() calls to xml_match_tag() calls in the db/ + code. + - bumped version to 2.24. + - Windows release. - CVS tagged source as app_release_2_23. + + client/ + analyzeReport.cpp + win_build/ + seti_boinc.vcproj + db/ + schema_master.cpp + schema_to_class.awk + configure + configure.ac + +Jeff 12 Feb 2004 + - max_signals and PoTInfo.PulseBeams both now get their values + from the analysis_cfg in the swi. + - make sure that the work areas are freed before exiting GenChirpFftPairs(). + + client/ + seti_header.cpp + chirpfft.cpp + +Rom 19 Feb 2004 + - Attempt to track down error 128 by specifying GLU32.DLL, GLUT32.DLL, + OPENGL32.DLL, and OLE32.DLL (Debug Build Only) as Delay-Load DLL's. + This causes an exception to be thrown if the DLL isn't found instead + of the OS poping up a dialog the user has to deal with. + + client/win_build/ + seti_boinc.vcproj + +Jeff Feb 19 2004 + - CVS tagged as seti_boinc_app_release_2_25. + +Rom 19 Feb 2004 + - When throwing exceptions, make the exception contain line and file + information. + + client/ + analyzeFuncs.cpp + analyzePoT.cpp + analyzeReport.cpp + chirpfft.cpp + gaussfit.cpp + main.cpp + pulsefind.cpp + s_util.cpp, h + seti.cpp + seti_header.cpp + spike.cpp + worker.cpp + +Rom 19 Feb 2004 + - Revert one try/catch block back to the orginal int type instead of what I + converted it to so it'll actually execute the cleanup code for DATA_SUN_BINARY + encodings. + + client/ + seti.cpp + +Rom 23 Feb 2004 + - Sample exception in main. + + client/ + main.cpp + +Jeff Feb 25 2004 + - CVS tagged as seti_boinc_app_release_2_26. This tag is a little late but + the sources should be little if any changed. + +Rom 06 Mar 2004 + - Include file overhaul on the Windows platform. This fixes the build breaks introduced + by the changes to the BOINC include file structure on the Windows platform + + I pretty much touched all the source and header files. This checkin should not have any + effect on any platform other than Windows. + +Rom 08 Mar 2004 + - Fix build breaks on Solaris/Linux + + Lib/ + sah_gfx.cpp + sah_gfx_base.cpp + +Eric 08 Mar 2004 + - Fixed pulse reported POT for + len_prof>analysis_config.pulse_pot_max. + pulse.len_prof is now set to zero and the pi.pot is .clear()ed. + - changed match_tag in db_table.h to xml_match_tag to fix parsing problem + + client/ + analyzeReport.h + analyzeReport.cpp + db/ + db_table.h + +Jeff 09 Mar 2004 + - Bumped to version 2.27. + - CVS tagged as seti_boinc_app_release_2_27. + + configure.ac + configure + +Rom 09 Mar 2004 + - Reduce user confusion by marking the results_overflow exception as an informational + message instead of an error. + + client/ + main.cpp + +Rom 13 Mar 2004 + - Updated time_sources script so that the image libraries could be included in the nightly drops. + +Jeff Mar 15 2004 + - CVS tagged boinc and seti_boinc as boinc_app_release_2_28. + +Jeff Mar 18 2004 + - Validator overflow code. + + validate/ + sah_validate.cpp + +Jeff Mar 19 2004 + - Result file now has bounding tags. + + client/ + worker.cpp + analyzeFuncs.cpp + + BTW, here is how to build the mac osx client/app in such a way that you + can specify the build name: + configure --build powerpc-apple-darwin + +Jeff Mar 22 2004 + - Improved debug logging in the validator. + + validate/ + sah_validate.cpp + +Rom Mar 22 2004 + - Force the memory allocation functions to include file and line information for each + allocation. + - Turn on the memory leak detection report for Windows built binaries + - replaced malloc_a/calloc_a/free_a with their Windows CRT equivs. This only applies to + Windows when being compiled as Debug. + - Fixed a couple of bugs where the copy constructors and assignment operators were only + coping a fraction of what they intended to copy + + client/ + analyzeFuncs.cpp + analyzePoT.cpp + analyzeReport.cpp + main.cpp + malloc_a.h + pulsefind.cpp + seti.cpp + stdafx.h + client/win_build/ + seti_boinc.vcproj + +Rom Mar 22 2004 + - Attempt to force load glut32.dll in a specific location, if it fails catch the SEH exception + and just disable grapgics. + + client/ + sah_gfx_base.cpp + stdafx.h + +Rom Mar 23 2004 + - client applications don't really need to dump leak detection information + for public consumption. So remark it out for public release. + - Tag for a 2.29 release. + +Rom Mar 23 2004 + - Unify all diagnostics functionality under the same banner, SETI_BOINC, + BOINC_CLI, BOINC_GUI, upper_case now all initialize the BOINC Diagnostics + Library which sets up stdout and stderr redirection, heap corruption + detection, stackwalker for Windows, and stackalker fo *nix can be pluged + in and be automatically used by all applications. + - Taskbase#1131 -- closed + - Taskbase#1132 -- closed + + client/ + analyzeReport.cpp + lcgamm.cpp + main.cpp + stdafx.h + client/winbuild/ + seti_boinc.vcproj + +Jeff Mar 24 2004 + - Fixed nightly tarball generation so that autoconf,configure,make + will result in a successful build. + + trim_sources added awk line to trim configure.ac + configure.ac made sure lines to be trimmed are clear + of autoconf special characters + +Rom Mar 25 2004 + - I have made SETI_BOINC Glut Free, Basically copied font code from glut + and put it into the glut folder. + - Removed Glut libraries + - Removed Delay Load technologies + + client/win_build + seti_boinc.vcproj + client/win_build/glut + + glut/ + + +Rom Mar 25 2004 + - Fix up project file so it'll build on a clean platform. + + client/win_build + seti_boinc.vcproj + +Jeff Mar 26 2004 + - Release tags. Sources were tagged as seti_boinc_release_2_30 and then, + after some build problems were fixed, were tagged as seti_boinc_release_2_30a. + The build from this latter tag was what was released as app version 2.30. + +Jeff Mar 26 2004 + - Removed parseOutfile from the project. + +Rom Mar 26 2004 + - Fix a minor bug where after the screen saver shutdown BOINC would fire-up + a new SAH Window + - Tag for a 2.31 release. + + client/win_build + seti_boinc.vcproj + +Rom Mar 30 2004 + - Include the glut folder in the nightly tarball + + / + trim_sources + +Jeff Mar 31 2004 + - Nightly tarball generation now runs autoconf to produce a configure script + stripped of the trimmed directories. + + trim_sources + +David Mar 31 2004 + - handle mouse events, and offer a simple interface where + dragging rotates the 3D objects + + client/ + sah_gfx.cpp + sah_gfx_base.cpp,h + +Jeff April 2 2004 + - Kludge fix for the access violations we see in csv encoding. In the + checkpoint routine I check len_prof of the best_pulse and if it is + zero we do not write that pulse to the state file. + + - tagged as seti_boinc_app_release_2_32 and released to alpha. + + client/ + seti.cpp + +Jeff April 8 2004 + - Have splitter give full path to result template on read error. + - Correct configure defined PROJECTDIR + + / + aclocal.m4 + configure + splitter/ + splitter.cpp + +Jeff April 12 2004 + - tagged with: + seti_boinc_app_release_3_00 + +David April 12 2004 + - when get OVERFLOW exception we need to call boinc_finish(), + else the core client won't regard the result as done + + client/ + main.cpp + +David April 14 2004 + - include "mfile.h" + + client/ + analyzeReport.h + +Rom April 20 2004 + - Turn on tracing of CRT warnings by default since the CRT considers + heap corruption a warning offense instead of an error. + + client/ + main.cpp + +David April 22 2004 + - change all fopen()s to boinc_fopen(). + This is necessary to avoid EINTR failures on Unix, + and locking-related failures on Windows + + client/ + chirpfft.cpp + seti.cpp + worker.cpp + +Jeff April 30 2004 + - Fixed bug where a call to encode() lacked a parameter. + + db/ + sqlblob.h + +Jeff May 13 2004 + - Overflow results are now marked thusly in the SAH master science DB. + Boinc result.opaque is used to pass the overflow flag from the + validator to the assimilator. + - Fixed bug that resulted in the following assimilator error message: + Too many open SQL statements (> 20) for sql operations + The fix (via Eric) was to do an sql_close(fd) before each return(false) + in sql_run(). + + validate/ + sah_validate.cpp + sah_result.h + assimilator/ + sah_assimilate_handler.cpp + db/ + sqlifx.ec + +David May 15 2004 + - Some changes to reflect the new STARFIELD handling + (which is done entirely in 2D). + Call app_init_camera() in SAH_GFX_BASE::render(), + instead of just once at the beginning. + Since this is where viewpoint distance is handled, + we no longer have to do it in the mouse handler. + - add glFlush() to SAH_GFX_BASE::render() + + client/ + sah_gfx.cpp + sah_gfx_base.cpp,h + win_build/init_data.xml + +Jeff May 18 2004 + - corrected printf format for logging seti WU ID as contained in the + boinc:result.opaque field. + + assimilate/ + sah_assimilate_handler.cpp + +Jeff May 18 2004 + - Testing notes. I followed WU 11se03aa.9564.4544.428382.126 through the + system (seti side DB, boinc side DB, files) and found that the following + (at least) are working properly: + - seti workunit_grp points to tape + - seti wu points to workunit_grp + - seti result points to seti wu + - seti result points to boinc result + - the data description in the workunit_grp (DB) looks OK and appears + properly in the wu file + - the following all look good in the seti DB and appear properly + in the wu file: + - receiver_config + - recorder_config + - splitter_config + - analysis_config + *except* that the xml field in the wu file receiver_config + section has the string "apos" improperly embedded (task 1275). + - the workunit_header's in the wu file and result file are identical + *except* that the wu name in the result file is incomplete (task + 1274). + - the 1 reported pulse signal also appears as the best pulse in the + result file and is inserted properly in the DB. + - the 1 triplet signal also appears as the best triplet in the + result file and is inserted properly in the DB. + - the 7 spikes are inserted properly in the DB and the highest + power spike appears as the best spike. + - there was no gaussian in this wu. + +Jeff May 18 2004 + - Place app version number and received time as julian day into the result + record in the seti master DB. + + assimilate/ + sah_assimilate_handler.cpp + + +Jeff May 21 2004 + - Targeted heap checking. Placed the following code: + #ifdef _WIN32 + BOINCASSERT(_CrtCheckMemory()); + #endif + at the beginning and end of the following functions: + find_pulse() + ReportPulseEvent() + ReportTripletEvent() + checkpoint() + parse_state_file() + and at the beginning and end of all PULSE_INFO and TRIPLET_INFO + contructors and destructors. + + - use time_t_to_jd() to calculate julian day in the assimilator. + + + client/ + pulsefind.cpp + analyzeReport.cpp + seti.cpp + + assimilate/ + sah_assimilate_handler.cpp + Makefile.in + +Jeff May 25 2004 + - Obtain analysis configuration table for result pre-proccessing + (eg barycentric frequency calculation). + - Pre-processing stub routines. + - Check the new noinsert flag (command line parameter). + + assimilate/ + sah_assimilate_handler.cpp + +Rom May 25 2004 + - tagged with: + seti_boinc_app_release_3_07 + +Rom May 26 2004 + - updated config.guess based of David's checkin in BOINC + - Update config.guess so we don't have to add the --build command to + each execution of ./configure for the Macs + + / + config.guess + +David May 27 2004 + - resize(), graphics_thread_init(): do OpenGL stuff ourselves + + client/ + sah_gfx_base.cpp + +David May 27 2004 + - change logo-rendering code to use (0,1)x(0,1) + coord system instead of bizarre 3x4 stuff + + client/ + sah_gfx.cpp + sah_gfx_base.cpp,h + +Jeff june 2 2004 + - Upped minimum quorum from 2 to 3. + + splitter/ + wufiles.cpp + +David June 2 2004 + - changed default graphics prefs + + client/ + sah_gfx_base.cpp + +David June 8 2004 + - change boinc_resolve_filename() calls + + client/ + seti.cpp + worker.cpp + +David June 11 2004 + - moved xml_util* here from BOINC + + db/ + xml_util.C,h (new) + +David June 11 2004 + - added xml_util.C,h to Windows project file + + Note: doesn't build on Windows. + Indecipherable error messages involving std::XXX stuff + + client/win_build/ + init_data.xml + seti_boinc.vcproj + db/ + xml_util.C + +Rom June 12 2004 + - Cleanup build errors on Windows + + client/ + chirpfft.cpp + s_util.cpp + sah_gfx.cpp + sah_gfx_base.cpp + stdafx.cpp + timecvt.cpp + client/win_build/ + seti_boinc.vcproj + db/ + schema_master.cpp + schema_to_class.awk + sqlrow.cpp + xml_util.C, .h + +Jeff June 15 2004 + - Check for memory allocation failures in signal info constructors. + - Cleanup build errors on *nix. + + client/ + seti.cpp + db/ + Makefile.in + +Jeff (for Eric) June 15 2004 + - New routine, db_change(). + + db/ + schema_to_class.awk + schema_master.cpp + schema_master.h + +Rom June 15 2004 + - Tag for 3.08 release, all platforms + seti_boinc_app_release_3_08 + +Jeff June 15 2004 + - Strip leading zero from minor version. + + configure.ac + +David 15 June 2004 + - added rule for .C files + + client/Makefile.in + +Jeff 16 June 2004 + - Modifications to allow the same splitter executable to run under + different projects, say beta and public. The mods are: + + - The backend sciece DB name was hard coded in splitter.cpp and + is now a required command line parameter (-scidb=). We are using + the new db_change() routine to attach to the desired DB. + - The project directory was hard coded in config.h (PROJECTDIR) + and is now a required command line parameter (-projectdir=). + - the download directory was hard coded in splitparms.h as + WU_DIR. This was changed to WU_SUBDIR which equates to + "download" and concatenated to the projectdir to get the + fully qualified download directory. + + splitter/ + splitter.cpp,h + splitparms.h + makebufs.cpp + wufiles.cpp + +Rom 16 June 2004 + - Fix awk script so it'll coreectly deal with stdafx.h + + db/ + schema_master.cpp + schema_to_class.awk + +David 16 June 2004 + - include miofile.C in project + + client/win_build/ + seti_boinc.vcproj + +Jeff 17 June 2004 + - Change xml_util.C to xml_util.cpp. + + db/ + xml_util.C deleted + xml_util.cpp added + Makefile.in + +Jeff 18 June 2004 + - Splitter now reads the science DB name from an application config file. + This config file and the parsing of it is modeled on the boinc + config file. It is called sah_config.xml and resides in the project + directory. + + - Routine db_change() now dies nothing is the requested DB is already + open. + + db/ + app_config.cpp,h new files + schema_to_class.awk + schema_master.h + Makefile.in + + splitter/ + splitter.cpp + wufiles.cpp + +Jeff 20 June 2004 + - Assimilator now reads the science DB name from an application config file. + - Added pre_process stubs to assimilator (will be used for reference frame + correction etc). + + assimilator/ + sah_assimilate_handler.cpp,h + Makefile.in + +Jeff 21 June 2004 + - Changed fpops numbers on the splitter (these numbers appear in the WU. + db_wu.rsc_fpops_est from 3.9e+12 to 2.79248e+13 + db_wu.rsc_fpops_bound from 6.4e+13 to 4.46797e+14 + Keeping the ratio of bound to estimated at 16/1. + + splitter/ + wufiles.cpp + +Karl 2004-06-24 + + OpenBSD compile fixes from Daniel Hartmeier + + client/ + worker.cpp + db/ + xml_util.h + +Eric K 30 June 2004 + - Removed "using" directives from header files. "using" + directives should not be used in header files for the following reasons. + - A "using namespace" directive cannot be revoked for any source file + including the header. It forces the use of the namespace regardless of + the consequences. + - Dropping the namespace qualifier on STL templates ambiguates the + resolution of template functions. (How many C libraries or headers + have you seen that define the function min()?) + - Reducing typing is not a good reason to drop namespace qualifiers any + more than it would be a good idea to "#define p printf" + - Namespaces exist for a reason. + - It's acceptable to have "using" directive in a source file, since it + won't affect other files. It's better to have "using std::string;" + directives than "using namespace std;" for hopefully obvious reasons. + +Eric K 1 July 2004 + - changed the sql type of pot in gauss in triplet from char[64] to byte + - added a print_raw() method to the sqlblob class + - changed the gaussian null chisqr threshold to 2.075 to increase the number + of gaussians found. + client/gaussfit.cpp + db/schema_master.cpp + db/schema_master.sql + db/schema_to_class.awk + db/sqlblob.h + db/sqlifx.ec + db/sqlrow.cpp + db/sqlrow.h + db/tools/analysis_configs.xml + +David 7 June 2004 + - compile fixes, and use new BOINC API + + client/ + main.cpp + sah_gfx_base.cpp + +Jeff 9 July 2004 + - Splitter uses new prototype to create_work() in order to specify + the fully qualified path to the result template file. + - Because the query to count unsent results takes a long time, we + only perform the query every once every 100 times into + wait_for_db_wus_ondisk(). All other calls to this routine return + immediately, indicating a need for work. Further, while in the + wait for work loop, we perform the query only every 10 minutes. + - For Eric - the FOPS estimates have bben increased by a factor + of 6 (previous code checkin). + + splitter/ + splitter.cpp,h + wufiles.cpp + +Jeff 12 July 2004 + - db_change() will do nothing but return db_is_open if the requested + database is already open. + + db/ + schema_to_class.awk + +Jeff 12 July 2004 + - as a matter of policy, application handlers called by boinc programs + (ie the validator and assimilator) should handle error returns from boinc + functions themselves rather than return the error up to boinc code. + This change is for the assimilator to issue a message and then exit + if it cannot parse the project config file or if it cannot connect + the the project (boinc) DB. + + ssimilator/ + sah_assimilate_handler.cpp + +Jeff 15 July 2004 + - At Rom's request, backed out Eric's fops estimation changes + (see entry of 9 July 2004). + + splitter/ + wufiles.cpp + +Rom July 15 2004 + - Tag for 4.00 release, all platforms + seti_boinc_app_release_4_00 + +David July 19 2004 + - Win build: changed output filename to 4.00 + + client/win_build/ + seti_boinc.vcproj + + +Noaa 30 July 2004 + + - changed headers for sah_gfx_base.cpp + - different Makefile.in (ie Makefile.in.graphics) that can be + put in place of Makefile.in before configure to configure for + graphics, may need to be changed slightly depending on user, + description in Makefile.Readme + + client/ + sah_gfx_base.cpp + Makefile.in.graphics (new) + Makefile.Readme + +David 3 Aug 2004 + - BOINC API change + + client/ + main.cpp + +Noaa 5 August 2004 + + - changed lglut to lboincglut in Makefile.in.graphics + - changed Makefile.Readme to reflect that + - added a Graphics.Readme to explain how to install w/graphics + + / + Graphics.Readme + + client/ + Makefile.in.graphics + Makefile.Readme + +Noaa 6 August 2004 + + - Minor change to Makefile.Readme + - change of sah_gfx_base.cpp headers + + client/ + Makefile.Readme + sah_gfx_base.cpp + + +Jeff 12 Aug 2004 + - use hierarchical uldl directory structures (see boinc checkin notes). + - call perror() when splitter cannot fork(). + + assimilator/ + sah_assimilate_handler.cpp + validate/ + sah_boinc_db.cpp + splitter/ + splitter.cpp + wufiles.cpp + +Jeff 13 Aug 2004 + - bumbed the WU ondisk threshold from 20k to 50k. + - fixed a bad call to create_work(). The prototype had changed. + + splitter/ + splitparms.h + wufiles.cpp + +Jeff 24 Aug 2004 + - officially renamed the splitter executable to sah_splitter + + splitter/ + Makefile.in + +Jeff 25 Aug 2004 + - tell dir_hier_path() to create download subdirs as needed. + + splitter/ + wufiles.cpp + +David 30 Aug 2004 + - created html/ directory + + html/ (new) + project.inc + +Jeff 09 Sep 2004 + - Change to the validator to handle the case where one or more of the result files + for a WU's result set are missing. Before this change this state would result + in this WU and it's results never getting looked at again. No science, no + credit. + + This is coordinated seti_boinc / boinc change. This note is repeated in + the boinc checkin_notes. + + seti_boinc changes: + - get_result_file(), if it cannot read the result file, tries to read the + directory where the result file should be. If it can read the directory, + it returns ERR_FOPEN, as before. If it cannot read the directory, it + resturns ERR_OPENDIR. ERR_OPENDIR in this context signals a possibly + transient problem. Upon a successful result read, it sets sah_result.have_result + (a new data member as of this change) to true. + - check_set(), upon return from get_result_file() : + - sets result.validate_state to VALIDATE_STATE_ERROR (a new state + as of this change) and retval to zero if there is a nonzero + retval from check_set() and it is not ERR_OPENDIR. It then + continues. + - otherwise just continues. + check_set() then determines if any IO errors brought the result count + below wu.min_quorum. If not, it continues. Otherwise it returns. + In all subsequent logic any results for which sah_result.have_result == false + are skipped. Note that the result and the sah_result vectors are associated. + + validate/ + sah_result.h + sah_validate.cpp + sah_boinc_db.cpp + + boinc changes: + - new validate state VALIDATE_STATE_ERROR. + - in the enumeration for check_set(), we now include a clause to check for + VALIDATE_STATE_INIT in order to ignore results set to VALIDATE_STATE_ERROR. + This enumeration query now matches that for check_pair(). + Note that the only possible retvals from check_set() are now zero or + ERR_OPENDIR. + Note that logic to retry possibly transient errors still needs to be done. + Also left to be done is a transitioner change to subtract the number of + results in state VALIDATE_STATE_ERROR from the count of active results. + The latter change is needed to stimulate the production of additional results + for the affected WU. + + sched/ + validator.C + db/ + boinc_db.h + +Jeff 09 Sep 2004 + - Some changes to the validator mods of today. Validator logic now matches the + updated validator documentation on the boinc website. + + validate/ + sah_validate.cpp + +Jeff 19 Sep 2004 + - Some time ago a bug was fixed that reduced the amount of time it takes + to do pulse searching but the progress unit computation remained tuned + to the bug. This resulted in an overestimation of the percentage of + total processing time spent in pulse searcing. We do the most intensive + pulse searching at the start of a WU so what the user sees is an early + and false jump in percentage done. This change is just a retuning of + PulseProgressUnits(). I changed: + return(PulsePoTLen * PulsePoTLen * log(PulsePoTLen) * FftLen / 0.65e6); + to: + return(PulsePoTLen * PulsePoTLen * log(PulsePoTLen) * FftLen / 2.65e6); + + client/ + progress.cpp + +David 29 Sept 2004 + - fixed "heads-up" graphics display + + client/ + sah_gfx.cpp + +David 11 Oct 2004 + - accommodate change to BOINC graphics API + Moved exception-catchers from main() to worker() + - renamed SAH_GRAPHICS_BASE::worker_thread_init() to data_struct_init() + (since this is now called by graphics thread, not worker) + + client/ + main.cpp + sah_gfx.cpp,h + sah_gfx_base.cpp,h + worker.cpp,h + win_build/ + seti_boinc.vcproj + +Lana 13 Oct 2004 + - cleanup validator code to correspond to the boinc API + requirements for handling error conditions + + validate/ + sah_validate.cpp + +David 13 Oct 2004 + - compile fixes + + client/ + sah_gfx_base.cpp,h + +David 26 Oct 2004 + - track change to BOINC API + + client/ + main.cpp + +Rom 26 Oct 2004 + - Tag for 4.06 release, all platforms + seti_boinc_app_release_4_06 + +Eric 28 Oct 2004 + - Added support for threaded clients + - Fixed problem with retrieving insert ids related to ifx_getserial8() + - Fixed problem in xml_util.h when compiling on LLP64 platforms + + aclocal.m4 + config.h.in + configure.ac + configure + m4/ + acx_pthread.m4 + assimilator/ + Makefile.in + client/ + Makefile.in + db/ + sqlifx.ec + xml_util.h + db/tools/ + Makefile.in + splitter/ + Makefile.in + validate/ + Makefile.in + +Rom 29 Oct 2004 + - Tag for 4.07 release, all platforms + seti_boinc_app_release_4_07 + +David 31 Oct 2004 + - add config line to get rt library (sched_get_priority_min) on Solaris + + configure.ac + +Jeff 10 Nov 2004 + - Started using the "best_" signals in a result for validation. We had always + meant to do this in order to provide robust validation for results with + no signals exceeding threshold. Plus, the way the validator is written, + zero signal results arriving after the initial WU validation would always + recieve zero credit (at least one signal was expected). + + - Siganls counts now appear in the log (DEBUG level). + + validate/ + sah_result.{h,cpp} + sah_validate.cpp + +David 12 Nov 2004 + - move code to parse BOINC init file from + data_struct_init() to graphics_thread_init(); + fixes bug where user name and team didn't show + - Win compile fixes + + client/ + sah_gfx_base.cpp + win_build/ + seti_boinc.vcproj + +David 17 Nov 2004 + - use regular GLUT library + + client/ + Makefile.in.graphics + +Eric K. 18 Nov 2004 + - increased memory resource bound to 64M to prevent core client + from killing application when running with graphics enabled. + - Fixed base64 and base85 decoders in xml_util.h + - Altered BLOB printing so a minimum of 1 byte will always be inserted. + This fixes a problem with the new informix SDK. + + db/ + xml_util.h + schema_to_class.awk + schema_master.cpp + schema_master.h + splitter/ + wufiles.cpp + + - addendum (jeffc) : The BLOB fix here does indeed fix the problem + whereby some 5% of pulse inserts failed. Spike and triplet + inserts still fail at a rate of less than 1% in each case. The + cause of this is as yet unknown. The first public project SAH + result ID processed since today's fix was put in place was + 2969946. + +Jeff 18 Nov 2004 + - Added better error checking around inserts into the science DB. + + assimilator/ + sah_assimilate_handler.cpp + +Jeff 19 Nov 2004 + - Return from handler if result insert fails. + + assimilator/ + sah_assimilate_handler.cpp + +Jeff 19 Nov 2004 + - added the following fields to analysis_config table (all initialized + to zero): + max_spikes + max_gaussians + max_pulses + max_triplets + + db/ + schema_master.sql + schema_master.cpp + schema_master.h + tools/ + analysis_configs.xml + + with a recompile of the splitter and assimilator. + +Jeff 23 Nov 2004 + - bumped MAX_WUS_ONDISK back up to 500000. + + splitter/ + splitparams.h + +Rom 23 Nov 2004 + - Tag for 4.09 release, all platforms + seti_boinc_app_release_4_09 + +Jeff 29 Nov 2004 + - Master science DB fetches to obtain analysis config. This is used to + find max allowable inserts for any given signal type. + + assimilator/ + sah_assimilate_handler.cpp + +Jeff 30 Nov 2004 + - Final step in the "limit spike insertions to 8" project. Stopped + splitters, made a new analysis_config row (id=4), updated settings + to make analysis_cfg=4, and restarted splitters. The max(id)'s + of the following tables prior to splitter restart were: + seti master DB (sah2) workunit_grp : 22423 + seti master DB (sah2) workunit : 5736259 + boinc DB (SETI_BOINC) workunit : 5279254 + + db/tools/ + analysis_configs.xml + +Jeff 02 Dec 2004 + - Removed 2 files. uttolst.cpp contained a buggy routine, + tm_UtToLst() which did not handle multiple 24 hour wraps in the + calculation of LMST. This bug is what led to some RA's being >= 24. + Eric fixed this with an fmod() call in the new LMST routine, jd_to_lmst(), + contained in source file coordcvt.cpp. The only program to use code + from uttolst.cpp is testcoord, a program that Eric used to test + jd_to_lmst(). jd_to_lmst() has been fully tested and in production + for quite some time (over a year). + + splitter/ + Makefile.in + uttolst.cpp removed + testcoord.cpp removed + +Jeff 03 Dec 2004 + - Added the start of a public app build and test page. Needs work. + + html/ + sah_source_code.php + +Jeff 03 Dec 2004 + - added code (commented out for now) for precessing and reference frame + correcting signals. + + assimilator/ + sah_assimilate_handler.cpp + +Jeff 07 Dec 2004 + - Finished source code / build instruction page for the web site. + - Placed a reference result in the test WU directory. + - Removed the old style reference result. + + html/ + sah_participate.php + sah_source_code.php + client/ + test_workunits/ + old_format_reference_result.sah (removed) + reference_result.sah + + +Rom 07 Dec 2004 + - Cleanup from header file changes + + client/ + lcgamm.cpp + main.cpp + sah_gfx.cpp + sah_gfx_base.cpp + client/win/ + seti_boinc.vcproj + image_libs/ + bmplib.cpp + +Jeff 08 Dec 2004 + - Corrected tolerances in the validator so that they match this policy: + ra 0.00066 hours absolute + dec 0.01 degrees absolute + time .000011574 days absolute + frequency 0.01 Hz absolute + chirp_rate 0.01 Hz/s absolute + powers 1% relative + chisqrs 1% relative + triplet period 0.01 second absolute + pulse period 0.1% relative + pulse threshold 1% relative + pulse snr 1% relative + + Diffs: + was: if (abs_diff(ra, s.ra) > .15) return false; // .01 deg + is: if (abs_diff(ra, s.ra) > .00066) return false; // .01 deg + + case SIGNAL_TYPE_PULSE: + was: if (abs_diff(period, s.period) > .01) return false; // .01 sec + is: if (rel_diff(period, s.period) > .01) return false; // 1% + + + case SIGNAL_TYPE_TRIPLET: + was: if (rel_diff(period, s.period) > .01) return false; // 1% + is: if (abs_diff(period, s.period) > .01) return false; // .01 sec + + max(id) for result in the master science DB (sah2) prior to this change + (assimilator was allowed to drain): 4345521 + + validate/ + sah_result.cpp + +David 10 Dec 2004 + - Fixed Windows compile. + Added ../../../boinc/win_build to the include path + to pick up config.h + + client/win_build/ + init_data.xml + libboincapi.vcproj + seti_boinc.vcproj + setiboincdb.vcproj + +Jeff 16 Dec 2004 + - Record the app exit value in the master result record. Max(id) in + the master DB result table before this change was 4873677. + + assimilator/ + sah_assimilate_handler.cpp + +Jeff 17 Dec 2004 + - Record the boinc WU_ERROR state in the master result record. Max(id) in + the master DB result table before this change was 4923923. + + This is being recorded in the result.reserved field. This field needs + to be renamed. + + assimilator/ + sah_assimilate_handler.cpp + +Jeff 17 Dec 2004 + - Fixed link problem in the client directory. We now need to link to the boinc_api + as well as the boinc lib. + + client/ + Makefile.in + +Jeff 21 Dec 2004 + - Brought the assimilate handler into compliance with the new prototype. It now returns + a non zero retval on any error and zero on success. All errors are potentially recoverable. + + assimilator/ + sah_assimilate_handler.cpp + +Eric K 23 Dec 2004 + - First step in getting a universal graphical/non-graphical application. + - Added a -nographics command line option to turn off graphics. + - Graphics calls are now wrapped in "if (!nographics)" + - Added a client_stage variable which contains the initialization state of + the graphics (PREGRX,GRXINIT,POSTINIT). If a fatal error occurs, this + allows the client to guess at whether the failure was graphics related. + - Added an atexit handler which restarts the application in nographics + mode if exit is called in stage GRXINIT. + - If found, seti_boinc uses the native libjpeg. + + aclocal.m4 + config.h.in + configure + configure.ac + client/ + Makefile.in + analyzeFuncs.cpp + analyzePoT.cpp + analyzeReport.cpp + gaussfit.cpp + main.cpp + s_util.[h,cpp] + seti.[h,cpp] + spike.[h,cpp] + worker.[h,cpp] + +Jeffc 23 Dec 2004 + - Started the add of setilib to the configuration. + + configure.ac + aclocal.m4 + config.h.in + configure + m4/ + sah_check_setilib.m4 + assimilate/ + Makefile.in + +David 25 Dec 2004 + - compile fix for windows + - commented out sleep(10) in worker + + client/ + worker.cpp + win_build/ + libboinc.vcproj + +David 25 Dec 2004 + - more compile fixes for Windows, which mysteriously didn't + compile the debug version correctly + + added ../../../boinc/win_build to the include search path for all projects, + and removed boinc/api/win and boinc/client/win (these don't exist) + + Removed the forced include of ../config.h (this file doesn't exist) + + Note: on Windows, as far as I know, + "config.h" refers to the file boinc/win_build/config.h + + client/ + worker.cpp + win_build/ + libboinc.vcproj + libboincapi.vcproj + seti_boinc.sln + seti_boinc.vcproj + setiboincdb.vcproj + +Jeff 27 Dec 2004 + - More values are now read from sah_config.xml. Current values: + sah2@master_tcp + 500000 + 2 WAS 3 + 3 + 5 + 10 WAS 7 + 5 + - max WU IDs before this change went online: + SETI_BOINC DB : 7084313 + sah2 (science master) DB : 7545411 + + splitter/ + splitter.cpp + wufiles.cpp + db/ + app_config.cpp + app_config.h + +David 29 Dec 2004 + - Got the windows client to compile. + Added a file win_build/win_version.h that defines + MAJOR_VERSION and MINOR_VERSION. + Currently these are in configure.ac, + but I don't see how to convey these values to a file + included in the Windows compile. + If there's a better way feel free to undo this change + + client/ + version.cpp + win_build/ + seti_boinc.vcproj + win_build/ + win_version.h (new) +Jeff 4 Jan 2005 + - Rather than call dir_hier_path() directly, call boinc routine get_output_file_path() + to get path to result files. This automatically gives us the new path hash algorithm. + (see boinc checkin notes on 1/1/2005). + + Max result ID in the master science DB prior to the assimilator change was 5993798. + + validate/ + Makefile.in + sah_boinc_db.cpp + assimilator/ + Makefile.in + sah_assimilate_handler.cpp +Jeff 4 Jan 2005 + - Added calls to setilib routines to precess RA and declination to J2000. At this point, + this is only done for spikes and the results of the calculations are printed to the + log only - we are not actually updating the spike coords. After making sure the precession + is correct, we can start updating all signals. + + Max result ID in the master science DB prior to this change was 6005078. + + assimilator/ + sah_assimilate_handler.cpp + +Jeff 11 Jan 2005 + - Calculate barycentric frequency for all signals (not updating yet). + + validate/ + sah_assimilate_handler.cpp + +David 8 Feb 2005 + Various changes to get the Win version to compile, + hopefully with graphics working: + + - removed SAH_GRAPHICS_BASE_INTERFACE class. + The new idea is to have a SAH_GRAPHICS object, + which in the shared-library case lives in the shared library. + The main program has a pointer to this object, + but calls only its data-modification functions, + so it doesn't need to link with OpenGL or GLUT. + - Moved render() from SAH_GRAPHICS_BASE to SAH_GRAPHICS. + This eliminates the need for virtual functions. + - added reduce.C, md5*.C to project files + + client/ + sah_gfx.cpp,h + sah_gfx_base.cpp,h + seti.h + worker.cpp + win_build/ + libboinc.vcproj + libboincapi.vcproj +Eric 8 Feb 2005 + - Removed the db directory from the Makefile.am build list + - Added SETILIBDIR and INFORMIXDIR to Makefile.incl + - Changed references to /bin/false in configure.ac to remove path + - Changes to make the unix client compatible with davids changes above: + - worker thread needs access to + SAH_GRAPHICS_BASE::get_generate_buffer() and + SAH_GRAPHICS_BASE::generate_done(), so added #ifdefs to make + them visible to the executable during build + - Reordered db/db_table.h to re-fix undefined symbols + + Makefile.am + Makefile.in + Makefile.incl + configure.ac + configure + client/ + Makefile.am + Makefile.in + sah_gfx.[h,cpp] + sah_gfx_base.[h,cpp] + db/ + db_table.h + +Eric 10 Feb 2005 + - Removed aclocal.m4 and configure because they are generated by + _autosetup. + - Simplified the folding algorithm bases on code send by Ben Herndon. + On superscalar processors this can also be a speedup. On SPARC, + it's a 0.24% slowdown, not enough that we should stick with the + more complex original code. + - Changed the automake file to remove references to "installing" + seti_boinc into /usr/local/bin + - Fixes to get the windows client running. + - Added check for _int32 and int32_t to configure.ac + - Now that sah_graphics is dynamically allocated, a lot of our + graphics structures weren't getting initialized properly. I've + written default constructors for: G_GAUSS_INFO, G_TRIPLET_INFO, + G_PULSE_INFO, GDATA, SAH_GRAPHICS_BASE, SAH_GRAPHICS, SETI_WU_INFO, + GRAPH_BUFFER, and GRAPHICS_PREFS. + - Added ltmain.sh, depcomp and win_build/* to the nightly tarball. + - Changed trim_sources to use _autosetup instead of autoconf. + + aclocal.m4 (removed) + configure (removed) + trim_sources + configure.ac + config.h.in + client/ + pulsefind.cpp + Makefile.am + worker.cpp + sah_gfx.[h,cpp] + sah_gfx_base.[h,cpp] + seti_header.cpp + gdata.h + jpeglib/ + jpeglib.h + +Jeff 14 Feb 2005 + - put libboinc at the end of the lib list (functions in other + libs use symbols defined in libboinc) + - change some assimilator messages to DEBUG level. + + assimlator/ + Makefile.am + sah_assimilate_handler.cpp + validate/ + Makefile.am + +Eric K. 15 Feb 2005 + - fixed missing definition of dir_hier_path() in wufiles.cpp + - reordered initializations in constructors to get rid of + warning messages + - modified configure script to set CXXFLAGS to equal CFLAGS if + CXXFLAGS is not defined + - The client was trying to look up the graphics library symbol + "x11_glut_is_initialized" rather than "xwin_glut_is_initialized" + + configure.ac + client/ + gdata.h + sah_gfx_base.cpp + worker.cpp + splitter/ + wufiles.cpp + +Eric K. 16 Feb 2005 + - Fixed broken nightly tarball + + trim_sources + +Eric K. 16 Feb 2005 + -Rather than rechirping the original data every 1000 chirp + steps, we now rechirp the original data every step. This + will make results more repeatable when restarting work units. + It may also allow floating point rather than double precision + trig functions. + -The savedWUData in analysis_state used to be the raw data from + the file. As of now it is the baseline smoothed data floating + point data (unchirpped). + + client/ + seti.h + seti.cpp + analyzeFuncs.cpp + + + + - Fixed broken nightly tarball + +Eric K. 10 Mar 2005 + -To better support systems with concurrent calculation of sin() + and cos() I've added a sincos() and sincosf() function for + systems without these intrinsics. + -Modified analyzeFuncs and fft8g to use sincosf(). + -Fixed bug that prevented baseline smoothing on chirp 0 data. + -Modified configure to check for sinf(),cosf(),sincos() and sincosf() + + configure.ac + config.h.in + client/ + fft8g.cpp + sincos.h + analyzeFuncs.cpp + +Jeff 11 Mar 2005 + - Templated the science pre_processing function. Max(id) for result in the + master science DB before putting this change online was 9289454. + + assimilator/ + sah_assimilate_handler.cpp + +Charlie 11 Mar 2005 + - Add support for building Mac SETI@home application using XCODE IDE on Macintosh. + + mac_build/ + HowToBuildBOINC_XCode.rtf + seti_boinc.xcode.zip + +Jeff 16 Mar 2005 + - We now do values checking on signals and do not pass a signal on to + preprocessing is there is a critical value out of range (ra, decl, + time, freq at this point). We so however attemp to insert such a + signal into the master DB, with the value 1 placed in rfi_found. + + Max(id) for result in the master science DB before putting this + change online was 9826217. + + It came to light during testing this change that the occasional + insert failures that we see are for signals with wildly bad + values (NaNs ?). + + assimilator/ + sah_assimilate_handler.cpp + +Jeff 17 Mar 2005 + - Began inserting signals with pre-processed values: + - precession of coordinates from EOD to J2000. This uses + the serendip precession code. + This was tested by comparing assimilator precession results + to those obtained by the online FUSE precession calculator: + http://fuse.pha.jhu.edu/cgi-bin/precess_tool + There was agreement to under an arcsecond. This was also + tested under RA wrap conditions. Here are 2 examples: + obs RA obs decl sah precession obs time precession by fuse calc sah-fuse diff in arcsec + RA decl RA decl RA decl RA decl + 17.018570 18.127011 17.014893 18.134086 2453368.151255 17.014886 18.13411 0.378 -0.0864 + 0.001608 28.397810 23.997351 28.37006 2453365.416415 23.997336 28.36997 0.81 0.324 + + - calculation of the signal's barycentric frequency. + This also uses serendip code. Frequency shifts were within + the expected range (max ~= 142KHz) but no independent tests were done. + + - calculation of the cubic pixel number. This was tested by + reversing the qpix calculation and comparing the resulting + RA/Decl with the the original. There was agreement to a max + deviation of ~1.3 arcminutes which is OK because the qpix reversal + gives you the pixel center coordinates which is a max of ~1.3 arcmin + arcminutes from the pixel edge (given nside=2048). Most diviations + on reversal were smaller than this. + + Max(id) for result in the master science DB before putting this + change online was 9927205. + + assimilator/ + sah_assimilate_handler.cpp + +Jeff 21 Mar 2005 + - Better debugging output during WU file path resolution. + + assimilator/ + sah_assimilate_handler.cpp + +Rom 23 Mar 2005 + - Fix the release build of the S@H app on Windows + + client/ + version.cpp + client/win_build/ + seti_boinc.vcproj + + +Eric 12 Apr 2005 + - Fix bug in database code. The informix interface was expecting blobs to + be presented in hex format rather than raw binary. So informix interface + was attempting to translate the code to binary. In addition there was a + bug in the translating code such that only characters 'a'-'f' and 'A'-'F' + were being translated. The result was that most of the blob data were + reassigned blob[i]=(blob[2*i]*16+blob[2*i+1])&0xff. + - For better debugging, I changed the sqlifx.ec chk_status() macro (which + included a RETURN!!! Yuck!) into a boolean function. + - Since the informix SQLCODE variable (and the identical sqlca.sqlcode) + aren't available to the debugger, I replaced accesses to this variable + with calls to sql_error_code(). + - Since when errors were detected, sql_close() was being called which + cleared the error code. We've added a function sql_last_error_code() to + return the last non-zero error code and sql_reset_error_code() to reset + the last non-zero error code. There's still some work to do as far as + returning proper error status to the calling environment + - Changed the database name in the schema to sah2@sci_master_tcp to match + move to new db server/ + + db/ + schema_master.[cpp,h,sql] + schema_to_class.awk + sqlapi.h + sqlblob.h + sqlifx.ec + +Jeff 27 Apr 2005 + - Many changes to the informix related code in db/ in order to get the + science master DB migration code to work and to fix a bug that + was preventing the proper insertion of PoT's (both gaussian and + pulse). Eric L essentially rewrote sqlifx.ec. Note that to + allow DB insertions with ID's the symbol KEEP_ID must be defined + at compile time. + + - also some mods to the config insert tools in order to add some + new configs. + + db/ + db_table.h + schema_master.cpp + schema_to_class.awk + sqlapi.h + sqlblob.h + sqlifx.ec + sqlrow.cpp + sqlrow.h + + tools/ + Makefile.in + insert_analysis_config.cpp + insert_s4_receivers.cpp + insert_splitter_config.cpp + settings.sql + splitter_configs.xml + +Jeff 01 May 2005 + - recompiled the validater to pick up the credit fix referenced: + Bruce 29 April 2005 + and started it in the public project. Here is the start line of sah_validate1: + 2005-05-01 13:37:32 [normal ] Starting validator + + +Jeff 02 May 2005 + + - Assimilator changes: + - If there is no canonical result for a WU, return 0. This will cause + the boinc assimilator to mark the WU as assimilated and it will then + have it's file's and it's DB record(s) deleted. No canonical result + means that too many results were returned with no concensus. + - use sql_last_error_code() rather than sql_error_code(), as the latter + always returns 0. + - I a result insert get an informix error -239, return 0. This will cause + the boinc assimilator to mark the WU as assimilated and it will then + have it's file's and it's DB record(s) deleted. A -239 (uniqueness + violation, in this case on sah result field boinc_result) means that + we have already inserted the canonical result for this WU. This + should "never" happen but maybe with aome odd stop/start combo it does. + - If the bad value check detects a bad value in a signal, replace this + bad value with a recognizable marker. This is in addition to flagging + the signal in the rfi_found field. This value replacement is needed + because some bad values cannot be interted into the DB. The marker + value is -91.0. This is an impossible value for ra, decl, time, and freq. + - Max(id) for result in the master science DB before this change went online + was 13364296. + + + assimilator/ + sah_assimilate_handler.cpp + +Charlie 05 May 2005 +Mac: Modify projects and rebuild with OS 10.3.0 compatibility SDK. +Update build instructions. Check in XCode project. + mac_build/ + HowToBuildBOINC_XCode.rtf + seti_boinc.xcode + boinc.pbproj/ + project.pbxproj (add) + +Eric K. 18 May 2005 + - Changed includes of C headers to includes of C++ headers. (i.e. we now + include rather than ) + - Modified malloc_a() to use native aligned allocation routines if + available. + - Removed explicit use of _aligned_malloc on _WIN32 platforms since + malloc_a() will use _aligned_malloc(). + - Defined type sah_complex which is compatible with the FFTW complex + data type. Complex arrays that used to be defined a float arrays are + now of type sah_complex. Code accessing these arrays has been modified + where necessary. + - Added mods to allow the function prototypes in sincos.h to work if these + functions are present, but not in the system header. + - Modified the method by which the chirp table is computed. The goal is + to have the drift be less than 1 bin over the duration of interest + to the analysis. In the case of gaussians that duration is 2 beam + crossings. In the case of pulses it's one beam crossing. In the + case of spikes it's one fft length. This should pick up 1.5 dB in + sensitivity to gaussians, pulses and triplets. We could pick up another + 0.25 dB with another doubling of this duration, but I think we've reached + diminishing returns. + - Replaced repeated allocations of WorkData in the main loop with one + allocation prior to loop entry + - Made main processing loop compatible with FFTW. The configure script + now detects the FFTW library and header files and if both are available + USE_FFTW is defined in "config.h". This define determines which FFT is + used. + + + config.guess + config.sub + ltmain.sh + Makefile + Makefile.incl + configure.ac + client/ + Makefile.am + analyzeFuncs.[cpp,h] + malloc_a.[cpp,h] + fft8g.[cpp,h] + chirpfft.cpp + lcgamm.cpp + analyzePoT.cpp + s_util.[cpp,h] + main.cpp + progress.cpp + pulsefind.cpp + seti.[cpp,h] + analyzeReport.cpp + sincos.h + test_workunits/ + reference_work_unit.sah + +Rom 26 June 2005 + - Update Windows project files to use the FFTW library and optimize for SSE + + client/ + win-config.h + client/win_build/ + seti_boinc.vcproj + +Jeff 26 July 2005 + - Added a sky_map table to the db schema. This will be the primary table used + to control the near time persistency checker. + - Split a while() loop into 2 lines because otherwise gdb would not allow a + break to be set inside the loop (Eric change). + + db/ + schema_master.sql + schema_master.[cpp,h] + sqlifx.ec + +Jeff 09 Sept 2005 + - added a couple of libs to the splitter makefile that the new boinc crypto + code needs. + + splitter/ + Makefile.in + +Jeff 05 Oct 2005 + - Removed old/new hash boolean from call to dir_hier_path(). + + splitter/ + wufiles.cpp + +Jeff 28 Oct 2005 + - Fixed memory leak in the validator. + - Sync with changes in the BOINC SCHED_MSG_LOG definition. + + validate/ + sah_validate.cpp + sah_boinc_db.cpp + + +Jeff 1/9/2006 Jeff + Splitter related changes. + - account for new command_line parm in create_work() - we just pass NULL. + - changed all instances of safe_strncpy() to strlcpy(). + - change the app config file name to sah_enhanced_config.xml. + - added settings ID WU name. + + splitter/ + readtape.cpp + wufiles.cpp + db/ + app_config.cpp + +Jeff 1/11/2006 + - More safe_strncpy -> strlcpy(). + + client/ + timecvt.cpp + +Jeff 1/19/2006 + - added field sb_id to tape, workunit_grp, workunit, and result. These + fields were required for the DB merge. We can drop thme after a while. + + - app config file name back to sah_config.xml. This should be a command line item. + + db/ + app_config.cpp + schema_master.cpp + schema_master.h + schema_master.sql + +Jeff 1/23/2006 + - The assimilator now uses the settings ID that is embedded in the wu/result name + to get to the analysis_config and receiver_config tables. If the settings ID + has not changed from one result to the next (normally true until the enhanced client + gets released) then we do no DB accessing. This replaces the logic whereby + we were reading the wu and wug for each result. + - Both the enhanced and old splitter were previously modified to embed the settings ID + into the wu/result names. + + assimilator/ + sah_assimilate_handler.cpp + +Jeff 1/24/2006 + - Templated signal insertion. There were several other small code changes secondary + to this. + - if (appid == 2) signal.reserved = 1. This is temporary for enhanced rollout plus + DB correction. The correction code needs to know is the signals were returned + by an enhanced app or not. + + This sah2:result.max(id) before this change went on was 1615350419. + + assimilator/ + sah_assimilate_handler.cpp + + +Jeff 2/7/2006 + - Changed the type of q_pix in all 4 signal table schemas from integer to int8. + - The assimilator now inserts signals with "n_pix", a 64 bit integer. It + contains "q_pix" in the high order 32 bits and frequency with a resoltion of 10 Hz + in the low order 32 bits. All floating point numbers are cast (ie floored) to + integers in this processed. + + Note: the max IDs before this change were: + spike 1017689548 + gaussian 116885361 + pulse 173469464 + triplet 125669326 + + -------------------- Testing notes (all tests look good) ------------------ + + Here is a new spike. + + id 1017690489 + result_id 1619052602 + peak_power 24.45193290000 + mean_power 1.000000000000 + time 2453342.626688 + ra 2.944765570000 + decl 26.35156250000 + q_pix 3601673817190043 + freq 1421050038.263 + detection_freq 1421049936.330 + barycentric_freq 1421103637.391 + fft_len 131072 + chirp_rate -1.38084543000 + rfi_checked 0 + rfi_found 0 + reserved 0 + + n_pix q_pix freq + ---------------- ----------- ----------- + 3601673817190043 = 00 0C CB B4 08 78 6E 9B + + + 00 0C CB B4 = 838580.00 + which translates to RA 2.9443359 and Decl 26.3392294 + from DB 2.9447656 26.3515625 + --------- ---------- + 37 arcsec diff 44 arcsec diff + + 08 78 6E 9B = 142110363 + 1421103637.391/10 = 142110363 + --------- + 0 Hz diff + + Here is a new gaussian: + + id 116899622 + result_id 1619068124 + peak_power 1.717239500000 + mean_power 0.458329827 + time 2452982.120403 + ra 14.84703540000 + decl 18.09752270000 + q_pix 38639321233114672 + freq 1419769999.385 + detection_freq 1419770480.211 + barycentric_freq 1419689449.058 + fft_len 16384 + chirp_rate 11.23900990000 + rfi_checked 0 + rfi_found 0 + reserved 0 + sigma 6.227958200000 + chisqr 1.342639920000 + null_chisqr 2.142316580000 + score 0.00 + max_power 4.632330890000 + pot + + n_pix q_pix freq + ----------------- ----------- ----------- + 38639321233114672 = 00 89 46 42 08 76 46 30 + + 00 89 46 42 = 8996418 + which translates to RA 14.8461914 18.0921908 + from DB 14.8470354 18.0975227 + ---------- ---------- + 73 arcsec diff 19 arcsec diff + + 08 76 46 30 = 141968944 + 1419689449.058/10 = 141968944 + --------- + 0 Hz diff + + + Here is a new triplet: + + id 125678570 + result_id 1619068730 + peak_power 10.59097860000 + mean_power 0.00197354145 + time 2453358.223775 + ra 18.05746840000 + decl 20.87687870000 + q_pix 142995601912863989 + freq 1419248962.402 + detection_freq 1419248962.402 + barycentric_freq 1419256216.076 + fft_len 32 + chirp_rate 0.00 + rfi_checked 0 + rfi_found 0 + reserved 0 + period 0.919142425 + + + n_pix q_pix freq + ------------------ ----------- ----------- + 142995601912863989 = 01 fc 05 be 08 75 9c f5 + + 01 FC 05 BE = 33293758 + which translates to RA 18.0571289 Decl 20.8620894 + from DB 18.0574684 20.8768787 + ---------- ---------- + 29 arcsec diff 53 arcsec diff + + 08 75 9C F5 = 141925621 + 1419256216/10 = 141925621 + --------- + 0 Hz diff + + Here is a new pulse: + + id 173470235 + result_id 1619053031 + peak_power 0.919080853 + mean_power 0.00388364005 + time 2453357.914301 + ra 10.59253220000 + decl 18.10714530000 + q_pix 121561945579447491 + freq 1420880737.305 + detection_freq 1420880737.305 + barycentric_freq 1420750751.969 + fft_len 64 + chirp_rate 0.00 + rfi_checked 0 + rfi_found 0 + reserved 0 + period 0.293273598 + snr 7.352646830000 + thresh 7.250113490000 + score 0.00 + len_prof 44 + pot + + n_pix q_pix freq + ------------------ ----------- ----------- + 121561945579447491 = 01 AF DF F2 08 77 E4 C3 + + + 01 AF DF F2 = 28303346.00 + which translates to RA 10.5922852 Decl 18.0921908 + from DB 10.5925322 Decl 18.1071453 + ---------- ---------- + 21 arcsec diff 54 arcsec diff + + + 08 77 E4 C3 = 142075075 + 1420750751.969/10 = 142075075 + --------- + 0 Hz diff + + +2/23/2006 Jeff + - Changed the frequency to fpix conversion from a cast-to-long to + a round function: + inline long round(double x) {return long(floor(x + 0.5f));} + Casts from floating point to integers are always equivalent + to either (int)floor() or (int)ceil(), depending on the rounding + mode of the platform. + + This sah2:result.max(id) before this change went on was 1623225559. + + assimilator/ + sah_assimilate_handler.cpp + + I then thought there was a problem and fell back on this change. + The old assimilator went back on after result id 1623229153. + + I confirmed that there was in fact no problem and the new assimilator + went back on on 2/24/06 after result id 1623492910. + + Testing notes: + + Here is a new spike: + + id 1024551102 + result_id 1623225782 + peak_power 24.31553840000 + mean_power 1.000000000000 + time 2451858.467759 + ra 21.35094640000 + decl 18.07765010000 + q_pix 55794923851997434 + freq 1420622880.906 + detection_freq 1420621698.453 + barycentric_freq 1420741058.565 + fft_len 131072 + chirp_rate -19.5776901000 + rfi_checked 0 + rfi_found 0 + reserved 0 + + n_pix q_pix freq + ------------------ ----------- ----------- + 55794923851997434 00 C6 39 30 08 77 E0 FA + + 00 C6 39 30 = 12990768 + which translates to RA 21.3515625 Decl 18.0725708 + 21.3509464 18.0776501 + ---------- ---------- + 53 arcsec diff 18 arcsec diff + + + + 0877E0FA = 142074106 + round(1420741058.565/10) = 142074106 + --------- + 0 Hz diff + + Here is a new pulse: + + id 176938950 + result_id 1623229140 + peak_power 0.229531646 + mean_power 0.00195498206 + time 2451802.752266 + ra 1.953974720000 + decl 19.68553160000 + q_pix 2934081280477886 + freq 1420283508.301 + detection_freq 1420283508.301 + barycentric_freq 1420192624.394 + fft_len 32 + chirp_rate 0.00 + rfi_checked 0 + rfi_found 0 + reserved 0 + period 0.0233727992 + snr 5.806743140000 + thresh 5.665772440000 + score 0.00 + len_prof 7 + pot + + + n_pix q_pix freq + ------------------ ----------- ----------- + 2934081280477886 00 0A 6C 88 08 77 0A BE + + + 000A6C88 = 683144 + which translates to RA 1.9541016 Decl 19.6889732 + 1.95397472 Decl 19.6855316 + ---------- ---------- + 11 arcsec diff 12 arcsec diff + + + + 08770ABE = 142019262 + round(1420192624.394/10) = 142019262 + --------- + 0 Hz diff + + + Here is a new gaussian: + + id 120516510 + result_id 1623489856 + peak_power 3.313514950000 + mean_power 0.580334067 + time 2451925.666315 + ra 7.090055470000 + decl 8.357689860000 + q_pix 98579528333729636 + freq 1418915066.719 + detection_freq 1418912570.889 + barycentric_freq 1418934757.328 + fft_len 16384 + chirp_rate -35.8465271000 + rfi_checked 0 + rfi_found 0 + reserved 0 + sigma 3.568017480000 + chisqr 1.412076230000 + null_chisqr 2.102728610000 + score 0.00 + max_power 8.865511890000 + pot + + + n_pix q_pix freq + ------------------ ----------- ----------- + 98579528333729636 01 5E 39 8F 08 75 1F 64 + + 015E398F = 22952335 + which translates to RA 7.0898438 Decl 8.3666866 + 7.09005547 Decl 8.35768986 + ---------- ---------- + 18 arcsec diff 32 arcsec diff + + + 08751F64 = 141893476 + round(1418934757.328/10) = 141893476 + --------- + 0 Hz diff + +3/24/06 Jeff + Validator result overflow checking no longer uses an internal buffer. + stderr_out is checked in place. + + validate/ + sah_validate.cpp + +3/30/06 David + Added gutil_text.C to windows project + +5/4/06 Charlie + - Mac: Fix glut.h to be compatible with Mac's OpenGL framework. + - Create combined config.h file for Intel and PowerPC Macs. + - Create shell script to build fftw-3.1.1 library as universal + binary (PowerPC and Intel). + - Update seti_boinc XCode project to build both PowerPC and + Intel versions of SETI@home Enhanced application for Macintosh. + + glut/ + glut.h + mac_build/ + config.h + buildfftw-3.1.1.sh + seti_boinc.xcodeproj/ + project.pbxproj + +5/5/06 Charlie + - Mac: Fix fftw-3.1.1 build script to work on PowerPC as well as + Intel Macs. + + mac_build/ + buildfftw-3.1.1.sh + +5/8/06 Charlie + - Mac: Add icon to SETI@home enhanced. + + client/ + app_icon.h (added) + main.cpp + mac_build/ + seti_boinc.xcodeproj/ + project.pbxproj + +5/9/06 Charlie + - Mac: Fix crash bug on systems 10.3.0 through 10.3.8 due to + undefined sinf, cosf, atanf functions in dynamic linked + library usr/lib/libSystem.B.dylib. The fix is to not #define + HAVE_SINF, HAVE_COSF and HAVE_ATANF in config.h file for + PowerPC builds. + - Update Mac version to 5.13 + + mac_build/ + config.h + +5/15/06 Eric + - Version to 5.15 + - Embedded calls to boinc_worker_timer() in main loop + +6/14/06 Eric + - Version to 5.17 + - Removed calls to boinc_worker_timer() from main loop. + - Added support for transposing the PoT array on large memory machines. + This can improve performance, since caching is better for the transposed + PoT. Initial code by Alex Kan. + - Added several variations of transpose functions. Depending upon the size + and associativity of the machine cache, one may outperform the rest. + - Fixed some boinc compile problems (changes to the boinc_app_mouse_move(), + etc prototypes) + - added files in "client/vector" to the Dev-C++ and VCC projects. + - added high resolution timer class (vector/hires_timer.*) for function + timing. + - added timing code for on the fly function testing and switching. This + currently supporst BaseLineSmooth(), GetPowerSpectrum(), ChirpData(), and + Transpose(). Support for pulse, triplet and Gaussian finding will come + later. Functions can be added to the tests by adding them to the arrays + in analyzeFuncs_vector.cpp. + + client/ + analyzeFuncs.[cpp,h] + analyzePot.[cpp,h] + analyzeReport.[cpp,h] + sah_gfx.cpp + sah_gfx_base.cpp + win-config.h + seti.h + pulsefind.cpp + chirpfft.cpp + s_util.h + vector/ + analyzeFuncs_vector.[cpp,h] + hires_timer.[cpp,h] + analyzeFuncs_altivec.cpp + win_build/ + *.dev + *.vcproj + win_build/ + win_version.h + m4/ + optimizations.m4 + configure.ac + +7/20/06 Charlie + - Mac: Update seti_boinc XCode project for added source files and to link + with universal binary versions of BOINC libraries as built by + current BOINC XCode project (but seti_boinc project still builds + separate PPC and Intel applications.) + + mac_build/ + seti_boinc.xcodeproj/ + project.pbxproj + +8/1/06 Charlie + - Mac: Update seti_boinc XCode project for Altivec support. + + mac_build/ + seti_boinc.xcodeproj/ + project.pbxproj + +8/2/06 Charlie + - Mac: Create a new mac-specific config.h file which #includes either + config-i386.h or config-ppc.h; include instructions for generating + these files. Tthis is much easier than trying to merge them into + one combined file with "#ifdef i386" etc. + - #undef'ed HAVE_ATANF, HAVE_COSF and HAVE_SINF because this generates + much smaller code + - Create a new shell script makeseticonfigs.sh to automatically create + config-i386.h and config-ppc.h. + + mac_build/ + config.h + config-i386.h (new) + config-ppc.h (new) + makeseticonfigs.sh (new) + seti_boinc.xcodeproj/ + project.pbxproj + +8/3/06 Charlie + - Mac: Allow HAVE_ATANF, HAVE_COSF and HAVE_SINF for Intel to match + earlier versions. + + mac_build/ + config.h + +8/28/06 Charlie + - Mac: Incresae stack size by 8MB for Intel Macs only. This seems to + take care of the remaining screensaver graphics crashes. + + client/ + main.cpp + +9/19/06 Charlie + - Mac: Incresae stack size by another 8MB for Intel Macs only for a + total of 24MB. There were still a few occasional crashes with + 16MB stack. Tripling the original stack allocation is consistent + with my observation that memory sizes for most applications on + Intel Macs seem to be about three times that on PowerPC Macs. + + client/ + main.cpp + +1/29/07 Charlie + - Mac: Set Maximum stack size to system limit, for compatibvility with + future versions of core client (rlp.rlim_cur = rlp.rlim_max). The + core client will do this after fork() and before execv(). NOTE: if + the OS has set rlim_max to RLIM_INFINITY, that value is -1. So + adding a fixed amount (like 16MB) to -1 would actually reduce the + limit instead of increasing it. This change avoids that problem. + + client/ + main.cpp + +3/16/07 Jeffc + - some setilib related name changes. No logic change. + + assimilator/ + sah_assimilate_handler.cpp + +4/23/07 jeffc + - Upon recompile of the assimilator for bruno (i686-linux), + it aborted with: + *** stack smashing detected *** + This turned out to be an undersized char array in routine + sql_insert_id(). I increased it from 21 bytes to 256 bytes. + Still not too safe... + + sah:result.max(id) before this change was 1691705161. + + db/ + sqlifx.ec + +5/2/07 jeffc + - Assimilator changes: + - Functions radecl2pix(), pix2radecl(), and eod2stdepoch() were moved + to setilib. + - The code to pack ra, decl, and freq into signal.q_pix was put in setilib + function co_radeclfreq2npix(). + - Lots of little code and build cleanups. + + sah:result.max(id) before this change was 1694234121. + + assimilator/ + Makefile.am + sah_assimilate_handler.cpp + +5/31/07 korpela + - Increased version number to 5.20 !!! THIS IS NOT YET A WORKING BUILD. I + WILL TAG IT WHEN IT WORKS !!! + - Lots of changes by Joe Segur to implement optimized algorithms. + - Current build finds extra triplets. Tracking that down now. + - This might not build on Visual Studio. + + Significant changes are: + +1. Modified Pulse finding. This includes both algorithmic improvements +effective on all systems, and the possibility of using vectorized +folding subroutines on systems with SIMD capability. Files: +pulsefind.cpp, h - primary changes +analyzeReport.cpp, h - minor supporting change +AKfoldSSE.cpp - new + +The algorithmic improvements include: + +- The sums produced in the folding subroutines are not divided by + the fold level, saving a small amount of time. +- The invert_lcgf() caching saves the display threshold value rather + than the report threshold, and also doesn't scale by fold level. + This allows a quick comparison where only for the approximately 1% + of cases where display threshold is reached does report threshold + need to be calculated and checked. +- Calculations of period values are kept in integer form and only + converted to floating point for reporting. +- The memcpy() of Pulse PoT arrays before the initial fold by 3, 4, + or 5 is removed. +- The sequence of folding operations for Pulse PoTs of length 511 + and shorter is cached. This reduces the 3 nested loops to a + single faster loop for most cases where the loop overhead was using + a significant fraction of the time for folding. +- The default folding subroutines are optimized for FPU and coded to + encourage efficient instruction scheduling by the compiler. + +In support of SIMD folding: + +- Outputs of the folding subroutines are written 16 byte aligned so + the next fold can use aligned loads. (This is also more cache-friendly + even when SIMD isn't available). +- Because SIMD routines are not very efficient for the shortest PoT + lengths, particularly those not divisible by 4, the choice of routine + for each length up to 31 is table-driven. (Again, this proved to also + be a help for the default FPU optimized routines). + +Overall, the algorithmic improvements approach a 10% improvement in +total crunch time, SIMD folding another 10%. + +2. Transpose changes and additions: + +- Transpose is only done for chirp/fft pairs for which Gaussian, Pulse, + or Triplet searching will be done. +- Changed testing from 512x2048 to 16Kx64 which is used much more. That + had very little effect on my Pentium-M with 1 MiB L2 cache, more on + my Willamette P4 with 256 KiB L2, and most on my Pentium-MMX with + 256 KiB very slow L2 on the motherboard. +- Added a non-prefetch version of v_vTranspose4. It's faster on my + Willamette P4 system than the original, though slightly slower on + my Pentium-M system. (I also did the same for the GetPowerSpectrum + routines with similar effect.) +- Added another vectorized 4x4 subtranspose which differs mainly in + using non-temporal writes, plus a variety of functions which use + it. One of those always measures fastest on my two systems with SIMD + capability, by a 30% or more margin. + +files: +analyzeFuncs.cpp, h +analyzeFuncs_sse.cpp, h +analyzeFuncs_vector.cpp, h + + +3. Chirping changes and additions: + +- Modified CalcTrigArray() so when going two or more ChirpRateInd steps + it only transits the two 16 MiB arrays once. +- Modified testing so the change from negative to positive chirp goes + two steps up. That provides a better overall speed approximation, + though it's only a rough match to the number of chirp indices which + are skipped in typical WUs. +- Modified testing to start at chirp index 27040 so the error check is + including the difficult angles of over 262144 which make single + float rounding produce fractional input to the SinCos approximation + with only 5 bits of precision. +- After testing, if TrigArray isn't chosen then InitTrigArray() is not + called again. +- Added SSE3, SSE2, and SSE1 versions derived from Alex Kan's sources. +- Added an FPU version patterned after the SIMD versions; quick rounding + and non-branching polynomial SinCos approximation. On my systems it's + quicker than TrigArray and of course it doesn't need the extra 32 MiB + array space. This one isn't yet in a lunatics.at release, but Simon + has built pretest versions so I'll find out soon if it's faster on + AMD systems. + +Note 1: The DevC++ builds do a good job of making main() align per the + default preferred_stack_boundary of 2^4, but not the worker thread. + To work around that so the SIMD chirping wouldn't crash I added a + hack near the beginning of worker() to force the stack pointer to + a multiple of 16 for GNUC builds. The calculations in those SIMD + routines are complex enough that there are register spills to + temporary stack variables, so the kind of aligned alloca() used in + analyzeFuncs_x86_64.cpp isn't adequate, I did try that. I suppose + adding enough additional aligned variables could make that approach + work, but I'm reluctant to modify those well-tested routines more + than strictly necessary. +Note 2: The "const" in float4 constant definitions seems to conflict + with the MinGW intrinsics. I'm not sure why, I thought the C style + cast to (void *) used in the *mmintrin.h files should work, so I + just removed "const" for now. + +files: +x86_float4.cpp, h - modified +analyzeFuncs.cpp, h - modified +analyzeFuncs_vector.cpp, h - modified +analyzeFuncs_sse.cpp - modified +analyzeFuncs_fpu.cpp - new +analyzeFuncs_sse2.cpp - new +analyzeFuncs_sse3.cpp - new + + +4. Miscellaneous: + +- In seti.cpp, h added save to and restore from state file of individual + signal counts, plus relocated the final report of those values there; + it's now called before both the normal exit in analyzeFuncs.cpp and + the overflow exit in worker.cpp. +- In analyzeFuncs.cpp added output of a CUSTOM_STRING (if defined) to + the beginning of stderr, and a restart indication with the progress + in percent. +- In worker.cpp replaced the try/catch for parsing the state file with + a check for existence of that file, same as in my 517STxx builds from + the "Builds for unexplained error test" NC forum thread. +- In analyzeFuncs_vector.cpp, h restructured the tables of functions to + test to a single table for each type, adding a field indicating what + CPU capabilities are required for the function. Also added a routine + to set a variable to the host capabilities; the testing routines + compare those and don't try unsupported routines. + +06/07/2007 Eric K. + - Version to 5.21 + - Fixed crash on non-SSE processors. + - More optimized code merging from Joe Segur + + "In analyzeFuncs.cpp I moved the call to ComputePoTInfo up before the +call to ChooseFunctions() because the folding test uses some of the +PoTInfo values both directly and indirectly. The 3 new arguments in +ChooseFunctions() are needed because the folding test accesses the +ChirpFftPairs array. + + client/ + analyzeFuncs.cpp + pulsefind.h + vector/ + AKfoldSSE.cpp (removed) + analyzeFuncs_sse.cpp + analyzeFuncs_vector.[cpp,h] + x86_float4.h + win_build/ + seti_boinc.dev + +7/20/07 jeffc + Added science table hotpix. + + db/ + schema_master.{sql,cpp,h} + +7/21/07 Charlie + - Mac: Changed files for new vector functions, changed config.h + to sah_config.h, version 5.23, etc. + + mac_build/ + config-i386.h + config-ppc.h + makeseticonfigs.sh + seti_boinc.xcodeproj/ + project.pbxproj + +7/24/07 Charlie + - Mac: Reconfigure XCode project for separate PowerPC and Intel + targets, to allow individual source files to have different + compiler flags for each architecture. + - Mac: Use auto-config to build new config-i386.h, config-ppc.h; add + changes to sah_config.h to override certain items in these files. + -Mac: Update build instructions. + + mac_build/ + config-i386.h + config-ppc.h + sah_config.h + seti_boinc.xcodeproj/ + project.pbxproj + HowToBuildSETI_XCode.rtf + +7/25/07 Charlie + - Mac: More tweaks to XCode project and sah_config.h. + + mac_build/ + sah_config.h + seti_boinc.xcodeproj/ + project.pbxproj + +7/25/07 jeffc + The assimilator now populates a new table - hotpix. Rows consist of + a qpix and the time of assimlation. For each result assimilated + a unique list of qpixes for the signal set is constructed. For each + of these qpixes a new row in hotpix will be inserted, unless there is + already a row for that qpix, in which case the time will be unpdated. + + Max ID for result in beta before this change was 379785. + + assimilator/ + Makefile.am + sah_assimilate_handler.cpp + +7/25/07 jeffc + Placed a uniqueness constraint on hotpix.id via a unique index. + + db/ + schema_master.{sql,h,cpp} + +8/16/07 Charlie + - Mac: Update build instructions to put updating the version number + in the proper section. + - Mac: define USING_XCODE in project settings. + - Mac: Add path to BOINC version.h in header search paths; adjust + analyzeFuncs.cpp to get the library version from version.h instead + of config.h if USING_XCODE. + - Mac: Don't include sah_config.h from command line in XCODE project. + - Mac: tweaks to sah_config.h to correctly get COMPILER_STRING with GCC + version number. + - Mac: Fix compile error in analyzeFuncs_vector.cpp: included header + file contains "#undef isnan". + + client/ + analyzeFuncs.cpp + vector/ + analyzeFuncs_vector.cpp + mac_build/ + sah_config.h + seti_boinc.xcodeproj/ + project.pbxproj + HowToBuildSETI_XCode.rtf + +8/16/07 jeffc + - splitter: repeat read of all config's for each WUG. Not doing this for + the analysis_config lead to gradual lowering of (at least) the triplet + threshold that resulted in WUs that got bogged down in triplet + finding (looking at every PoT bin) and WU overflows (again, triplets). + + splitter/ + mb_splitter.cpp + +Jeff 10 Sep 2007 + - The CVS repository is deprecated this date. We now use SVN. + +Eric K. 6 Dec 07 + - Checked in David's extensive changes for V6 Graphics + +Charlie 7 Dec 07 + - Mac: Update XCode project for V6 graphics (separate graphics application) + - Fix compile error on Mac (memset undefined in this context) + + client/ + gdata.h + mac_build/ + seti_boinc.xcodeproj/ + project.pbxproj + +Eric K. 17 Dec 07 + - Fixed problem with SAH_PACKAGE_STRING assignment. + - Modified seti_boinc.dev for V6 graphics build with DevC++ + - Added seti_graphics.dev for building V6 graphics display app. + + client/ + analyzeFuncs.cpp + sah_gfx.cpp + win-sah_config.h + win_build/ + seti_boinc.dev + seti_graphics.dev + +Charlie 18 Dec 07 + - Mac: Fix bugs in definition of COMPILER_STRING. + - Mac: Put version number definitions in mac_build/sahconfig.h + instead of in 2 places (config-i386.h and config-ppc.h). + - Mac: Change version number to 6.00. + - Mac: Fix bug in XCode project (ppc targets had Run Script phase + after build instead of before.) + + mac_build/ + config-i386.h + config-ppc.h + sah_config.h + seti_boinc.xcodeproj/ + project.pbxproJ + +Eric 20 Dec 2007 + - Added three new methods to the db tables. + bool authorize_delete(bool auth); + bool DELETE(sqlint8_t id); + bool DELETE(std::string where); + Before delete is called, the caller must call (using the same instance) + authorized_delete(true). This must be called prior to each call to + DELETE(). + - Added a xml_encoding_from_string() call to xml_util.h + + db/ + db_table.h + xml_util.h + +Eric 31 Jan 2008 + - Fixed problem with incorrect receiver name in graphics output for multibeam workunits. + - Added copyright notices to files that were missing them. + - Added #include to analyzeFuncs_fpu.cpp + - Changed sqlblob input processing + + client/ + seti.cpp + gdata.h + sah_gfx.cpp + sah_gfx_main.cpp + sah_gfx_main.h + vector/ + analyzeFuncs_fpu.cpp + win_build/ + seti_graphics.dev + seti_boinc_private.rc + db/ + schema_to_class.awk + schema_master.cpp + sqlblob.h + +Eric K Feb 19, 2008 + - First attempt at simplifying autoconf. May break some builds on some + platforms. + - fixed problem with SAH_CHECK_ASMLIB macro + + m4/ + sah_asmlib.m4 + configure.ac + Makefile.incl + Makefile.am + sah_config.h + client/ + sah_gfx.cpp + client/ + Makefile.am + +David 10 June 2008 + - Add mechanism so that main program doesn't update shmem + if no graphics app is running + + client/ + gdata.h + sah_gfx.cpp + sah_gfx_main.cpp,.h + +Rom 11 Aug 2010 + - WIN: Use BOINC defined library project files for Visual Studio. + + client/win_build/ + libboinc.vcproj (deleted) + libboincapi.vcproj (deleted) + libgraphics2.vcproj (deleted) + seti_boinc.sln + +Charlie 17 Aug 11 + - Mac: Clean up XCode project (remove redundant build rules.) + + mac_build/ + seti_boinc.xcodeproj/ + project.pbxproJ diff --git a/client/Makefile.Readme b/client/Makefile.Readme new file mode 100644 index 0000000..bf5aba2 --- /dev/null +++ b/client/Makefile.Readme @@ -0,0 +1,27 @@ +This readme will explain the differences between Makefile.in and Makefile.in.graphics, +as well as usage and possible changes to be made to be system compliant. + +To use Makefile.in.graphics just rename it Makefile.in and configure seti_boinc. The +changes between the original Makefile.in and Makefile.in.graphics are: + +CFLAGS: addition of -DBOINC_APP_GRAPHICS +BOINC_INC: addition of -I/usr/openwin/share/include (possibly extraneous) + addition of -I$(BOINCDIR)/boincglut/include + -I../jpeglib +CXX, CC: addition of -g debug option (not vital) +GUIOBJS: addition of all the files prexisting under OBJS, as well as + graphics_api, x_opengl, grahpics_data from ../../boinc/api and sah_gfx_base, sah_gfx, and gdata (all .$(OBJEXT)) +GUILIBS: addition of -lX11, -lXmu, -L$(BOINCDIR)/boincglut/lib/glut -lboincglut + -L../jpeglib -ljpeg + THE FOLLOWING ADDITION IS SYSTEM DEPENDENT: the location of the GL + and GLU libraries on the system (ie /usr/X11R6/lib in Linux, + -L/usr/openwin/lib/ on Solaris) followed by -lGL and -lGLU +all: change PROGS to GUIPROG (possible to have both? I couldn't figure out how) +GUIPROG: addition of main.$(OBJEXT) to dependencies + addition of main.$(OBJEXT), gutil.$(OBJEXT), reduce.$(OBJEXT), + $(LIBS), -lpthread to rule + +The only thing that should need to be changed is the location of the GL libraries +as mentioned, but it's possible that other changes should be made. + +- Noaa Avital \ No newline at end of file diff --git a/client/Makefile.am b/client/Makefile.am new file mode 100644 index 0000000..413909e --- /dev/null +++ b/client/Makefile.am @@ -0,0 +1,248 @@ +## $Id: Makefile.am,v 1.7.2.21 2007/08/01 00:15:31 korpela Exp $ + +include $(top_srcdir)/Makefile.incl + + +BOINC_LIBS = -L$(BOINCDIR)/api -L$(BOINCDIR)/api/.libs -lboinc_api -L$(BOINCDIR)/lib -L$(BOINCDIR)/lib/.libs -lboinc + +CLIENT_C_FLAGS = $(APP_CFLAGS) $(CFLAGS) \ + $(DEFS) \ + -DTEXT_UI -DNDEBUG -DCLIENT \ + -I$(top_srcdir)/db \ + $(BOINC_CFLAGS) \ + $(PTHREAD_CFLAGS) \ + $(ASMLIB_CFLAGS) +CLIENT_LD_FLAGS = $(PTHREAD_CFLAGS) $(LDFLAGS) $(APP_LDFLAGS) +CLIENT_LD_ADD = $(PTHREAD_LIBS) $(BOINC_LIBS) $(APP_LIBS) + + + +if ENABLE_GUI + CLIENT_BIN = $(CLIENT_PROG) $(CLIENT_NATIVE) $(DEBUG_NATIVE) $(DEBUG_PROG) + GUI_BIN = seti_graphics + GUI_C_FLAGS = $(CLIENT_C_FLAGS) $(GRAPHICS_CFLAGS) + GUI_LD_ADD = $(GRAPHICS_LIBS_RAW) + CLIENT_LD_FLAGS += $(LDSTATIC) + CLIENT_LD_ADD += -L$(BOINCDIR)/api -L$(BOINCDIR)/lib $(BOINC_LIBS) $(AM_LIBS) + SAH_GRX_SOURCES = sah_gfx_main.cpp +else +#no graphics + SAH_GRX_SOURCES = + CLIENT_LD_ADD += $(AM_LIBS) + CLIENT_BIN = $(CLIENT_PROG) $(DEBUG_PROG) +endif + +if X86_64 + CLIENT_C_FLAGS+=-msse2 -mfpmath=sse -DUSE_SSE -DUSE_SSE2 +endif + +all: client-bin + +client-bin: $(CLIENT_BIN) + +$(DEBUG_PROG): seti_boinc + @RM@ -f $(DEBUG_PROG) + @LN@ seti_boinc $(DEBUG_PROG) + +$(CLIENT_PROG): seti_boinc + @CP@ seti_boinc $(CLIENT_PROG) + @STRIP@ $(CLIENT_PROG) + + + +noinst_PROGRAMS = seti_boinc + +if ENABLE_TESTS +noinst_PROGRAMS += hires_timer_test + +hires_timer_test_SOURCES= vector/hires_timer.cpp +hires_timer_test_CXXFLAGS=-DTEST_TIMER $(CXXFLAGS) $(CLIENT_C_FLAGS) +hires_timer_test_LDFLAGS=$(CLIENT_LD_FLAGS) +hires_timer_test_LDADD=$(CLIENT_LD_ADD) +endif + +seti_boinc_SOURCES = \ + main.cpp \ + vector/analyzeFuncs_vector.cpp \ + vector/analyzeFuncs_fpu.cpp \ + vector/analyzeFuncs_sse.cpp \ + vector/analyzeFuncs_sse2.cpp \ + vector/analyzeFuncs_sse3.cpp \ + vector/analyzeFuncs_avx.cpp \ + vector/analyzeFuncs_x86_64.cpp \ + vector/analyzeFuncs_altivec.cpp \ + vector/x86_float4.cpp \ + vector/hires_timer.cpp \ + analyzeFuncs.cpp \ + analyzeReport.cpp \ + analyzePoT.cpp \ + pulsefind.cpp \ + gaussfit.cpp \ + lcgamm.cpp \ + malloc_a.cpp \ + seti.cpp \ + seti_header.cpp \ + timecvt.cpp \ + s_util.cpp \ + sah_version.cpp \ + worker.cpp \ + chirpfft.cpp \ + spike.cpp \ + autocorr.cpp \ + progress.cpp \ + fft8g.cpp \ + gdata.cpp \ + ../db/schema_master.cpp \ + ../db/sqlrow.cpp \ + ../db/sqlblob.cpp \ + ../db/xml_util.cpp \ + $(SAH_GRX_SOURCES) + +seti_boinc_CFLAGS = $(CLIENT_C_FLAGS) +seti_boinc_CXXFLAGS = $(CLIENT_C_FLAGS) +seti_boinc_LDFLAGS = $(CLIENT_LD_FLAGS) +seti_boinc_LDADD = $(CLIENT_LD_ADD) +seti_boinc_LINK = $(CXX) $(seti_boinc_CXXFLAGS) $(seti_boinc_LDFLAGS) -o $@ + +if I386 +# allow use of sse instructions on i[3456]86 +seti_boinc-analyzeFuncs_sse3.o: vector/analyzeFuncs_sse3.cpp + if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(seti_boinc_CXXFLAGS) $(CXXFLAGS) -DUSE_SSE -DUSE_SSE2 \ + -DUSE_SSE3 -D__SSE__ -D__SSE2__ -D__SSE3__ \ + -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -msse3 \ + -c -o $@ $<; then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ + else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +seti_boinc-analyzeFuncs_sse2.o: vector/analyzeFuncs_sse2.cpp + if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(seti_boinc_CXXFLAGS) $(CXXFLAGS) -DUSE_SSE -DUSE_SSE2 \ + -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -msse2 \ + -c -o $@ $<; then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ + else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +seti_boinc-analyzeFuncs_sse.o: vector/analyzeFuncs_sse.cpp + if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(seti_boinc_CXXFLAGS) $(CXXFLAGS) -DUSE_SSE \ + -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -msse \ + -c -o $@ $<; then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ + else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +seti_boinc-analyzeFuncs_x86_64.o: vector/analyzeFuncs_x86_64.cpp + if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(seti_boinc_CXXFLAGS) $(CXXFLAGS) -DUSE_SSE \ + -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -mfpmath=sse -msse2 \ + -c -o $@ $<; then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ + else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +seti_boinc-x86_float4.o: vector/x86_float4.cpp + if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(seti_boinc_CXXFLAGS) $(CXXFLAGS) -DUSE_SSE \ + -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -msse \ + -c -o $@ $<; then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ + else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +if AVX +seti_boinc-analyzeFuncs_avx.o: vector/analyzeFuncs_avx.cpp + if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(seti_boinc_CXXFLAGS) $(CXXFLAGS) -DUSE_SSE -DUSE_SSE2 \ + -DUSE_SSE3 -DUSE_AVX -D__SSE__ -D__SSE2__ -D__SSE3__ \ + -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -mavx \ + -c -o $@ $<; then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ + else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +seti_boinc-analyzeFuncs_vector.o: vector/analyzeFuncs_vector.cpp + if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(seti_boinc_CXXFLAGS) $(CXXFLAGS) -DUSE_SSE -DUSE_SSE2 \ + -DUSE_SSE3 -DUSE_3DNOW -DUSE_AVX \ + -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ + -c -o $@ $<; then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ + else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +else +seti_boinc-analyzeFuncs_vector.o: vector/analyzeFuncs_vector.cpp + if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(seti_boinc_CXXFLAGS) $(CXXFLAGS) -DUSE_SSE -DUSE_SSE2 \ + -DUSE_SSE3 -DUSE_3DNOW \ + -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ + -c -o $@ $<; then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ + else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +endif +endif + +if X86_64 +# allow use of sse instructions on i[3456]86 +seti_boinc-analyzeFuncs_sse3.o: vector/analyzeFuncs_sse3.cpp + if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(seti_boinc_CXXFLAGS) $(CXXFLAGS) -DUSE_SSE3 \ + -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -msse3 \ + -c -o $@ $<; then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ + else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +if AVX +seti_boinc-analyzeFuncs_avx.o: vector/analyzeFuncs_avx.cpp + if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(seti_boinc_CXXFLAGS) $(CXXFLAGS) -DUSE_SSE3 -DUSE_AVX \ + -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -mavx \ + -c -o $@ $<; then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ + else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +seti_boinc-analyzeFuncs_vector.o: vector/analyzeFuncs_vector.cpp + if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(seti_boinc_CXXFLAGS) $(CXXFLAGS) -DUSE_SSE3 -DUSE_3DNOW -DUSE_AVX \ + -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ + -c -o $@ $<; then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ + else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +else +seti_boinc-analyzeFuncs_vector.o: vector/analyzeFuncs_vector.cpp + if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(seti_boinc_CXXFLAGS) $(CXXFLAGS) -DUSE_SSE3 -DUSE_3DNOW \ + -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ + -c -o $@ $<; then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ + else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +endif +endif + +if PPC +# allow use of altivec instructions on PPC +seti_boinc-analyzeFuncs_altivec.o: vector/analyzeFuncs_altivec.cpp + if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(seti_boinc_CXXFLAGS) $(CXXFLAGS) -DUSE_ALTIVEC \ + -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -faltivec \ + -c -o $@ $<; then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ + else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +seti_boinc-analyzeFuncs_vector.o: vector/analyzeFuncs_vector.cpp + if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(seti_boinc_CXXFLAGS) $(CXXFLAGS) -DUSE_ALTIVEC \ + -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ + -c -o $@ $<; then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ + else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +endif + + +if LINUX +# too much optimization on main.cpp breaks the client for some reason +seti_boinc-main.o: main.cpp + if $(CXX) --include ../sah_config.h $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(DEFS) -DTEXT_UI -DNDEBUG -DCLIENT $(CLIENT_C_FLAGS) -I$(top_srcdir)/db $(BOINC_CFLAGS) $(PTHREAD_CFLAGS) -O2 -Wall -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +endif + + +if ENABLE_GUI +noinst_PROGRAMS += seti_graphics + +seti_graphics_SOURCES = \ + timecvt.cpp \ + sah_gfx.cpp \ + sah_gfx_base.cpp \ + graphics_main.cpp \ + sah_version.cpp + +seti_graphics_CFLAGS = $(GUI_C_FLAGS) +seti_graphics_CXXFLAGS = $(GUI_C_FLAGS) +seti_graphics_LDFLAGS = $(GUI_LD_FLAGS) + + + +seti_graphics_LDADD = $(GUI_LD_ADD) $(BOINC_LIBS) + +$(DEBUG_NATIVE): $(GUI_BUILD) + @RM@ -f $(DEBUG_NATIVE) + @LN@ sah_graphics $(DEBUG_NATIVE) + +$(CLIENT_NATIVE): $(DEBUG_NATIVE) + @RM@ -f $(CLIENT_NATIVE) + @CP@ $(DEBUG_NATIVE) $(CLIENT_NATIVE) + +endif + diff --git a/client/Makefile.in.graphics b/client/Makefile.in.graphics new file mode 100644 index 0000000..c31ead3 --- /dev/null +++ b/client/Makefile.in.graphics @@ -0,0 +1,151 @@ +# $Id: Makefile.in.graphics,v 1.4.2.1 2006/12/14 22:21:43 korpela Exp $ +# +# + +@SET_MAKE@ + +EXEEXT = @EXEEXT@ +OBJEXT = @OBJEXT@ +LIBEXT = @LIBEXT@ +DLLEXT = @DLLEXT@ +DOTEXEEXT = @DOTEXEEXT@ + + +SUFFIXES = .cpp .c .@OBJEXT@ .@DLLEXT@ .@LIBEXT@ @DOTEXEEXT@ + +VERSION_MAJOR = @MAJOR_VERSION@ +VERSION_MINOR = @MINOR_VERSION@ + +BOINCDIR = @BOINCDIR@ + +CC = @CC@ +CFLAGS = @CFLAGS@ @DEFS@ -DTEXT_UI -DNDEBUG -DCLIENT -DBOINC_APP_GRAPHICS + +CXX = @CXX@ +CXXFLAGS = $(CFLAGS) + +BOINC_INC= -I$(BOINCDIR)/api -I$(BOINCDIR)/lib -I$(BOINCDIR)/image_libs/ -I/usr/openwin/share/include/ -I../jpeglib + +.cpp.@OBJEXT@: + $(CXX) -g $(CXXFLAGS) $(BOINC_INC) -I.. -I../db -c -o $*.@OBJEXT@ $< + +.C.@OBJEXT@: + $(CXX) -g $(CXXFLAGS) $(BOINC_INC) -I.. -I../db -c -o $*.@OBJEXT@ $< + +.c.@OBJEXT@: + $(CC) -g $(CFLAGS) $(BOINC_INC) -I.. -I../db -c -o $*.@OBJEXT@ $< + +LDFLAGS = @LDFLAGS@ + +CLIBS = @LIBS@ + +SUFFIXES = .cpp .@OBJEXT@ +PROG = setiathome-$(VERSION_MAJOR).$(VERSION_MINOR).@host@$(DOTEXEEXT) +GUIPROG = xsetiathome-$(VERSION_MAJOR).$(VERSION_MINOR).@host@$(DOTEXEEXT) +PROGS = $(PROG) setiathome_test$(DOTEXEEXT) + +../aclocal.m4: ../m4/*.m4 + @CAT@ ../m4/*.m4 >../aclocal.m4 + +../configure: ../configure.ac ../aclocal.m4 ../sah_config.h.in + (cd ..; make sah_config.h) + +OBJS = \ + analyzeFuncs.$(OBJEXT) \ + analyzeReport.$(OBJEXT) \ + analyzePoT.$(OBJEXT) \ + pulsefind.$(OBJEXT) \ + gaussfit.$(OBJEXT) \ + lcgamm.$(OBJEXT) \ + malloc_a.$(OBJEXT) \ + seti.$(OBJEXT) \ + seti_header.$(OBJEXT) \ + timecvt.$(OBJEXT) \ + s_util.$(OBJEXT) \ + version.$(OBJEXT) \ + worker.$(OBJEXT) \ + chirpfft.$(OBJEXT) \ + spike.$(OBJEXT) \ + progress.$(OBJEXT) \ + ../db/schema_master_client.$(OBJEXT) \ + ../db/sqlrow_client.$(OBJEXT) \ + ../db/sqlblob.$(OBJEXT) \ + ../db/xml_util.$(OBJEXT) + +BOINC_OBJS = -L$(BOINCDIR)/lib -lboinc + +GUIOBJS = \ + analyzeFuncs.$(OBJEXT) \ + analyzeReport.$(OBJEXT) \ + analyzePoT.$(OBJEXT) \ + pulsefind.$(OBJEXT) \ + gaussfit.$(OBJEXT) \ + lcgamm.$(OBJEXT) \ + malloc_a.$(OBJEXT) \ + seti.$(OBJEXT) \ + seti_header.$(OBJEXT) \ + timecvt.$(OBJEXT) \ + s_util.$(OBJEXT) \ + version.$(OBJEXT) \ + worker.$(OBJEXT) \ + chirpfft.$(OBJEXT) \ + spike.$(OBJEXT) \ + progress.$(OBJEXT) \ + sah_gfx_base.$(OBJEXT) \ + sah_gfx.$(OBJEXT) \ + gdata.$(OBJEXT) \ + ../db/schema_master_client.$(OBJEXT) \ + ../db/sqlrow_client.$(OBJEXT) \ + ../db/sqlblob.$(OBJEXT) \ + ../db/xml_util.$(OBJEXT) + +GUILIBS = -lX11 -lXmu @GRXLIBS@ -L../jpeglib/ -ljpeg -L/usr/X11R6/lib -L/usr/openwin/lib/ -lGL -lGLU -lglut \ + -L../../boinc/api -lboinc_api -lboinc_graphics_api + +LIBS = -L. \ + -looura + +all: Makefile dependencies $(GUIPROG) + +clean: + rm -f *.$(OBJEXT) libooura.$(LIBEXT) $(PROGS) dependencies config.log config.cache + +OOURAOBS = fft8g.$(OBJEXT) + +libooura.$(LIBEXT): $(OOURAOBS) + @AR@ r libooura.$(LIBEXT) $(OOURAOBS) + @RANLIB@ libooura.$(LIBEXT) + +$(PROG): main.$(OBJEXT) libooura.$(LIBEXT) $(OBJS) + $(CXX) main.$(OBJEXT) $(OBJS) $(LIBS) $(CLIBS) -o $(PROG) $(BOINC_OBJS) + strip $(PROG) + +$(GUIPROG): main.$(OBJEXT) $(GUIOBJS) libooura.$(LIBEXT) + $(CXX) main.$(OBJEXT) ../../boinc/api/gutil.$(OBJEXT) ../../boinc/api/reduce.$(OBJEXT) $(GUIOBJS) $(GUILIBS) $(LIBS) $(CLIBS) -lpthread -o $(GUIPROG).debug $(BOINC_OBJS) + cp $(GUIPROG).debug $(GUIPROG) + strip $(GUIPROG) + +# The following is because version.$(OBJEXT) depends on +# VERSION_MAJOR and VERSION_MINOR, defined in the Makefile. +# Is there a cleaner way of doing this? +version.$(OBJEXT): version.cpp ../sah_config.h version.h + +main_test.$(OBJEXT): main.cpp + $(CXX) $(CXXFLAGS) $(BOINC_INC) -I.. -I../db -DTEST_VERSION -c -o main_test.$(OBJEXT) main.cpp + +setiathome_test$(DOTEXEEXT): main_test.$(OBJEXT) $(OBJS) libooura.$(LIBEXT) + $(CXX) main_test.$(OBJEXT) $(OBJS) $(LIBS) $(CLIBS) -o setiathome_test$(DOTEXEEXT) $(BOINC_OBJS) + +../db/sqlrow_client.$(OBJEXT): ../db/sqlrow.cpp ../db/sqlrow.h + (cd ../db; $(MAKE) sqlrow_client.$(OBJEXT)) + +../db/schema_master_client.$(OBJEXT): ../db/schema_master.cpp ../db/db_table.h + (cd ../db; $(MAKE) schema_master_client.$(OBJEXT)) + +../db/schema_master.cpp: ../db/schema_master.sql ../db/schema_to_class.awk + (cd ../db; $(MAKE) schema_master.cpp) + +dependencies: ../sah_config.h *.cpp Makefile + $(CXX) $(CXXFLAGS) -I.. -I/ -I../db $(BOINC_INC) -M *.cpp > dependencies + +include dependencies diff --git a/client/amd64fft8g.cpp b/client/amd64fft8g.cpp new file mode 100644 index 0000000..e1f2896 --- /dev/null +++ b/client/amd64fft8g.cpp @@ -0,0 +1,123 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +// AMD optimizations by Evandro Menezes + +#ifdef USE_AMD_OPT_CODE + +#include +#include + +static const int as [4] [4] = {{0, 0, INT_MIN, INT_MIN}, // {-, -, +, +} + {0, 0, 0, INT_MIN}, // {-, +, +, +} + {0, INT_MIN, 0, INT_MIN}, // {-, +, -, +} + {INT_MIN, 0, INT_MIN, 0}}; // {+, -, +, -} +static const __m128 mmpp = *(__m128 *) (as [0] + 0), + mppp = *(__m128 *) (as [1] + 0), + mpmp = *(__m128 *) (as [2] + 0), + pmpm = *(__m128 *) (as [3] + 0); + +void cftfsub(int n, float *a, float *w) +{ + void cft1st(int n, float *a, float *w); + void cftmdl(int n, int l, float *a, float *w); + int j, j1, j2, j3, l; + __m128 x10, x32, y10, y32, zz; + + zz = _mm_setzero_ps (); + + l = 2; + if (n >= 16) { + cft1st(n, a, w); + l = 16; + while ((l << 3) <= n) { + cftmdl(n, l, a, w); + l <<= 3; + } + } + if ((l << 1) < n) { + for (j = 0; j < l; j += 2) { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + // x0r = a[j] + a[j1]; + // x0i = a[j + 1] + a[j1 + 1]; + x10 = _mm_loadl_pi (zz, (__m64 *) (a + j)); + y10 = _mm_loadl_pi (zz, (__m64 *) (a + j1)); + // x1r = a[j] - a[j1]; + // x1i = a[j + 1] - a[j1 + 1]; + x10 = _mm_movelh_ps (x10, x10); + y10 = _mm_movelh_ps (y10, y10); + y10 = _mm_xor_ps (mmpp, y10); + x10 = _mm_add_ps (x10, y10); + // x2r = a[j2] + a[j3]; + // x2i = a[j2 + 1] + a[j3 + 1]; + x32 = _mm_loadl_pi (zz, (__m64 *) (a + j2)); + y32 = _mm_loadl_pi (zz, (__m64 *) (a + j3)); + // x3r = a[j2] - a[j3]; + // x3i = a[j2 + 1] - a[j3 + 1]; + x32 = _mm_movelh_ps (x32, x32); + y32 = _mm_movelh_ps (y32, y32); + y32 = _mm_xor_ps (mmpp, y32); + x32 = _mm_add_ps (x32, y32); + + // a[j] = x0r + x2r; + // a[j + 1] = x0i + x2i; + // a[j1] = x1r - x3i; + // a[j1 + 1] = x1i + x3r; + x32 = _mm_xor_ps (mppp, x32); + x32 = _mm_shuffle_ps (x32, x32, _MM_SHUFFLE (2, 3, 1, 0)); + y10 = _mm_add_ps (x10, x32); + _mm_storel_pi ((__m64 *) (a + j), y10); + _mm_storeh_pi ((__m64 *) (a + j1), y10); + // a[j2] = x0r - x2r; + // a[j2 + 1] = x0i - x2i; + // a[j3] = x1r + x3i; + // a[j3 + 1] = x1i - x3r; + y32 = _mm_sub_ps (x10, x32); + _mm_storel_pi ((__m64 *) (a + j2), y32); + _mm_storeh_pi ((__m64 *) (a + j3), y32); + } + } else if ((l << 1) == n) { + for (j = 0; j < l; j += 2) { + j1 = j + l; + // x0r = a[j] - a[j1]; + // x0i = a[j + 1] - a[j1 + 1]; + x10 = _mm_loadl_pi (zz, (__m64 *) (a + j)); + x32 = _mm_loadl_pi (zz, (__m64 *) (a + j1)); + y10 = _mm_sub_ps (x10, x32); + // a[j] += a[j1]; + // a[j + 1] += a[j1 + 1]; + y32 = _mm_add_ps (x10, x32); + _mm_storel_pi ((__m64 *) (a + j), y32); + // a[j1] = x0r; + // a[j1 + 1] = x0i; + _mm_storel_pi ((__m64 *) (a + j1), y10); + } + } +} +#endif // USE_AMD_OPT_CODE diff --git a/client/analyze.h b/client/analyze.h new file mode 100644 index 0000000..8b164e4 --- /dev/null +++ b/client/analyze.h @@ -0,0 +1,70 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +// This file contains compile time configuration parameters +// for the seti@home reference algorithm implementation. + +#ifndef _ANALYZE_ +#define _ANALYZE_ + +#define ISODD(a) (a)%2 != 0 ? true : false +#define IROUND(a) ( (int) ((a) + 0.5f) ) +#define LROUND(a) ( (long) ((a) + 0.5f) ) +#define SQUARE(a) ((a) * (a)) +typedef unsigned char BOOLEAN; + +#define SPIKE_SCORE_HIGH 40 // a high number (extremely unlikely in noise) +#define AUTOCORR_SCORE_HIGH 40 // a high number (extremely unlikely in noise) + +#define USE_PULSE +#define USE_TRIPLET + +extern int t_offset_start; +extern int t_offset_stop; +extern float SlewRate; + +extern float gauss_sigma; +extern float gauss_sigma_sq; + +#define NEG_LN_ONE_HALF 0.693 +#define EXP(a,b,c) exp(-(NEG_LN_ONE_HALF * SQUARE((float)(a) - (float)(b))) / (float)(c)) + +#endif + +// ========================================================================== + +// General Notes + +// Concerning the gaussian function macro EXP: +// The EXP macro defined here is used to generate the gaussian function +// f(x) = exp(-(C * x^2 / sigma^2)) in both fakedata and gaussfit. Sigma +// is in arbitrary units and simply gives the width of the gaussian. We +// give it a particular meaning by properly setting the value of the +// constant C. The meaning we give sigma here is that 2sigma is the +// half power beamwidth of the telescope. We solve for C when x = sigma +// and f(x) = 1/2. Thus we have f(x) = exp(-C). Taking the natural log +// of both sides gives us ln(1/2) = -C. And so C = -ln(1/2) = 0.693. diff --git a/client/analyzeFuncs.cpp b/client/analyzeFuncs.cpp new file mode 100644 index 0000000..08b39d4 --- /dev/null +++ b/client/analyzeFuncs.cpp @@ -0,0 +1,1284 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +// analyzeFuncs.C +// $Id: analyzeFuncs.cpp,v 1.34.2.44 2007/08/16 10:13:55 charlief Exp $ +// + +#define DO_SMOOTH + +#if defined(USING_XCODE) || defined(_WIN32) +#include "version.h" +const char *BOINC_PACKAGE_STRING="libboinc: "BOINC_VERSION_STRING; +#else +#include "config.h" +const char *BOINC_PACKAGE_STRING="libboinc: "PACKAGE_STRING; +#endif + +#undef PACKAGE_STRING +#undef PACKAGE +#undef PACKAGE_NAME +#undef PACKAGE_BUGREPORT +#undef PACKAGE_TARNAME +#undef PACKAGE_VERSION +#undef VERSION + +#include "sah_config.h" +const char *SAH_PACKAGE_STRING=CUSTOM_STRING; + +#include +#include +#include +#include +#ifdef HAVE_MEMORY_H +#include +#endif +#include + +#include "sincos.h" +#include "util.h" +#include "s_util.h" +#include "boinc_api.h" +#ifdef BOINC_APP_GRAPHICS +#include "sah_gfx_main.h" +#endif +#include "diagnostics.h" + +// In order to use IPP, set -DUSE_IPP and one of -DUSE_SSE3, -DUSE_SSE2, +// -DUSE_SSE or nothing(generic), IPP precedes FFTW, ooura // TMR +#if defined(USE_IPP) +#pragma message ("-----IPP-----") +#if defined(USE_SSE3) +#define T7 1 +#pragma message ("-----sse3-----") +#include +#elif defined(USE_SSE2) +#define W7 1 +#pragma message ("-----sse2-----") +#include +#elif defined(USE_SSE) +#define A6 1 +#pragma message ("-----sse-----") +#include +#else +#pragma message ("-----mmx-----") +#include +#endif // T7 +#include +#elif defined(USE_FFTWF) +#pragma message ("----FFTW----") +#include "fftw3.h" +#else +#pragma message ("----ooura----") +#include "fft8g.h" +#endif // USE_IPP + + +#include "seti.h" +#include "analyze.h" +#include "analyzeReport.h" +#include "gaussfit.h" +#include "spike.h" +#include "autocorr.h" +#include "malloc_a.h" +#include "analyzeFuncs.h" +#include "analyzePoT.h" +#include "chirpfft.h" +#include "worker.h" +#include "filesys.h" +#include "progress.h" + +BaseLineSmooth_func BaseLineSmooth=v_BaseLineSmooth; +GetPowerSpectrum_func GetPowerSpectrum=v_GetPowerSpectrum; +ChirpData_func ChirpData=v_ChirpData; +Transpose_func Transpose=v_Transpose4; + +#ifdef USE_IPP +static int MaxBufSize = 0; +static Ipp8u* FftBuf = NULL; +#endif // USE_IPP + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#define INVALID_CHIRP 2e+20 + +ChirpFftPair_t* ChirpFftPairs = NULL; + +double ProgressUnitSize; +double progress=0, remaining=1; + +// These are used to calculate chirped signals +// TrigStep contains trigonometric functions for MinChirpStep over time +// CurrentTrig contains current trigonometric fuctions +// Tetsuji "Maverick" Rai + +// Trigonometric arrays +SinCosArray* TrigStep = NULL; // trigonometric array of MinChirpStep +SinCosArray* CurrentTrig = NULL; // current chirprate trigonometric array +int CurrentChirpRateInd; // current chirprate index (absolute value) +double MinChirpStep=0.0; +bool use_transposed_pot; + +void InitTrigArray(int, double, int, double); +void FreeTrigArray(void); +void CalcTrigArray (int len, int ChirpRateInd); + +// The main analysis function. Args: +// state pointer to data, # of points, starting chirp/fftlen +// Must be called with unchirped data; +// this function modifies (chirps) the data in place +// swi parsed WU header + +//#define DEBUG +#ifdef DEBUG +int icfft; // for debug +#endif + +int seti_analyze (ANALYSIS_STATE& state) { + sah_complex* DataIn = state.savedWUData; + int NumDataPoints = state.npoints; + sah_complex* ChirpedData = NULL; + sah_complex* WorkData = NULL; + float* PowerSpectrum = NULL; + float* tPowerSpectrum; // Transposed power spectra if used. + float* AutoCorrelation = NULL; + + use_transposed_pot= (!notranspose_flag) && + ((app_init_data.host_info.m_nbytes != 0) && + (app_init_data.host_info.m_nbytes >= (double)(96*1024*1024))); + int num_cfft = 0; + float chirprate; + int last_chirp_ind = - 1 << 20, chirprateind; + + double progress_diff, progress_in_cfft, cputime0=0; + int retval=0; + + if (swi.analysis_cfg.credit_rate != 0) LOAD_STORE_ADJUSTMENT=swi.analysis_cfg.credit_rate; + +#ifndef DEBUG + int icfft; +#endif + int NumFfts, ifft, fftlen; + int CurrentSub; + int FftNum, need_transpose; + unsigned long bitfield=swi.analysis_cfg.analysis_fft_lengths; + unsigned long FftLen; + unsigned long ac_fft_len=swi.analysis_cfg.autocorr_fftlen; + +#ifdef USE_IPP + IppsFFTSpec_C_32fc* FftSpec[MAX_NUM_FFTS]; + int BufSize; + + ippStaticInit(); // initialization of IPP library +#elif defined(USE_FFTWF) + // plan space for fftw + fftwf_plan analysis_plans[MAX_NUM_FFTS]; + fftwf_plan autocorr_plan; +#else + // fields need by the ooura fft logic + int * BitRevTab[MAX_NUM_FFTS]; + float * CoeffTab[MAX_NUM_FFTS]; +#endif + + // Allocate data array and work area arrays. + ChirpedData = state.data; + PowerSpectrum = (float*) calloc_a(NumDataPoints, sizeof(float), MEM_ALIGN); + if (PowerSpectrum == NULL) SETIERROR(MALLOC_FAILED, "PowerSpectrum == NULL"); + if (use_transposed_pot) { + tPowerSpectrum = (float*) calloc_a(NumDataPoints, sizeof(float), MEM_ALIGN); + if (tPowerSpectrum == NULL) SETIERROR(MALLOC_FAILED, "tPowerSpectrum == NULL"); + } else { + tPowerSpectrum=PowerSpectrum; + } + AutoCorrelation = (float*)calloc_a(ac_fft_len, sizeof(float), MEM_ALIGN); + if (AutoCorrelation == NULL) SETIERROR(MALLOC_FAILED, "AutoCorrelation == NULL"); + + // boinc_worker_timer(); + FftNum=0; + FftLen=1; + + + +#ifdef USE_FFTWF + double sz; + FILE *wisdom; + if ((wisdom=boinc_fopen("wisdom.sah","r"))) { + char *wiz=(char *)calloc_a(1024,64,MEM_ALIGN); + int n=0; + while (wiz && n<64*1024 && !feof(wisdom)) { + n+=fread(wiz+n,1,80,wisdom); + } + fftwf_import_wisdom_from_string(wiz); + free_a(wiz); + fclose(wisdom); + } +#endif + + +#ifdef BOINC_APP_GRAPHICS + if (sah_graphics) strcpy(sah_graphics->status, "Generating FFT Coefficients"); +#endif + while (bitfield != 0) { + if (bitfield & 1) { + swi.analysis_fft_lengths[FftNum]=FftLen; +#ifdef USE_IPP + int order = 0; + for (int tmp = FftLen; !(tmp & 1); order++) tmp >>= 1; + if (ippsFFTInitAlloc_C_32fc(&FftSpec[FftNum], order, + IPP_FFT_NODIV_BY_ANY, ippAlgHintFast)) { + SETIERROR (MALLOC_FAILED, "ippsFFTInitAlloc failed"); + } +#elif !defined(USE_FFTWF) + // See docs in fft8g.C for sizing guidelines for BitRevTab and CoeffTab. + BitRevTab[FftNum] = (int*) calloc_a(3+(int)sqrt((float)swi.analysis_fft_lengths[FftNum]), sizeof(int), MEM_ALIGN); + if (BitRevTab[FftNum] == NULL) SETIERROR(MALLOC_FAILED, "BitRevTab[FftNum] == NULL"); + BitRevTab[FftNum][0] = 0; +#else + + + WorkData = (sah_complex *)malloc_a(FftLen * sizeof(sah_complex),MEM_ALIGN); + sah_complex *scratch=(sah_complex *)malloc_a(FftLen*sizeof(sah_complex),MEM_ALIGN); + if ((WorkData == NULL) || (scratch==NULL)) { + SETIERROR(MALLOC_FAILED, "WorkData == NULL || scratch == NULL"); + } + + // TODO: Deallocate these at the end of the function + analysis_plans[FftNum] = fftwf_plan_dft_1d(FftLen, scratch, WorkData, FFTW_BACKWARD, FFTW_MEASURE|FFTW_PRESERVE_INPUT); +#endif + FftNum++; +#ifdef USE_FFTWF + free_a(scratch); + free_a(WorkData); +#endif /* USE_FFTWF */ + + } + FftLen*=2; + bitfield>>=1; + } + +#ifdef USE_FFTWF + { + float *out= (float *)malloc_a(ac_fft_len*sizeof(float),MEM_ALIGN); + float *scratch=(float *)malloc_a(ac_fft_len*sizeof(float),MEM_ALIGN); + if ((WorkData == NULL) || (scratch==NULL)) { + SETIERROR(MALLOC_FAILED, "WorkData == NULL || scratch == NULL"); + } + autocorr_plan=fftwf_plan_r2r_1d(ac_fft_len, scratch, out, FFTW_REDFT10, FFTW_MEASURE|FFTW_PRESERVE_INPUT); + free_a(scratch); + free_a(out); + } + + wisdom=boinc_fopen("wisdom.sah","w"); + if (wisdom) { + char *wiz=fftwf_export_wisdom_to_string(); + if (wiz) { + fwrite(wiz,strlen(wiz),1,wisdom); + } + fclose(wisdom); + } +#endif + + if (!state.icfft) { +#ifdef CUSTOM_STRING + fprintf(stderr,"%s\n", CUSTOM_STRING); +#else + fprintf(stderr,"%s\n", SAH_PACKAGE_STRING); +#endif +#ifdef AVX_EMU + fprintf(stderr,"Emulating AVX\n"); +#endif + fprintf(stderr,"%s\n\n", BOINC_PACKAGE_STRING); + fprintf(stderr,"Work Unit Info:\n"); + fprintf(stderr,"...............\n"); + fprintf(stderr,"WU true angle range is : %f\n", swi.angle_range); + } else fprintf(stderr,"Restarted at %.2f percent.\n", progress*100); + fflush(stderr); + + swi.num_fft_lengths=FftNum; + // gernerate table of chirp/fft pairs (we may read table from file if testing) + if (cfft_file != NULL) + num_cfft = ReadCFftFile(&ChirpFftPairs, &MinChirpStep); + else + num_cfft = GenChirpFftPairs(&ChirpFftPairs, &MinChirpStep); + if (num_cfft == MALLOC_FAILED) { + SETIERROR(MALLOC_FAILED, "num_cfft == MALLOC_FAILED"); + } + + // Get together various values that we'll need to analyse power over time + ComputePoTInfo(num_cfft, NumDataPoints); + + // Initialize TrigArrays for testing if we have the memory.... + // If we can't tell how much memory we have, assume we have plenty. + if ((app_init_data.host_info.m_nbytes == 0) || + (app_init_data.host_info.m_nbytes >= (double)(64*1024*1024))) { + InitTrigArray (NumDataPoints, MinChirpStep, + TESTCHIRPIND, + swi.subband_sample_rate); + } + + boinc_install_signal_handlers(); +#ifdef BOINC_APP_GRAPHICS + if (sah_graphics) strcpy(sah_graphics->status, "Choosing optimal functions"); +#endif + // Choose the best analysis functions. + ChooseFunctions(&BaseLineSmooth, + &GetPowerSpectrum, + &ChirpData, + &Transpose, + ChirpFftPairs, + num_cfft, + swi.nsamples, + state.icfft == 0); + + if ((app_init_data.host_info.m_nbytes == 0) || + (app_init_data.host_info.m_nbytes >= (double)(64*1024*1024))) { + FreeTrigArray(); + // If we're using TrigArrays, reallocate & reinit + if ((ChirpData == v_ChirpData) || (ChirpData == fpu_opt_ChirpData)) { + InitTrigArray (NumDataPoints, MinChirpStep, + ChirpFftPairs[state.icfft].ChirpRateInd, + swi.subband_sample_rate); + } + } + +#ifdef USE_IPP + if (MaxBufSize) { + FftBuf = (Ipp8u*) malloc_a (MaxBufSize, MEM_ALIGN); + if (FftBuf == NULL) SETIERROR (MALLOC_FAILED, "FftBuf == NULL"); + } +#elif !defined(USE_FFTWF) + for (FftNum = 0; FftNum < swi.num_fft_lengths; FftNum++) { + CoeffTab[FftNum] = (float*) calloc_a(swi.analysis_fft_lengths[FftNum]/2, sizeof(float), MEM_ALIGN); + if (CoeffTab[FftNum] == NULL) SETIERROR(MALLOC_FAILED, "CoeffTab[FftNum] == NULL"); + } +#endif + + // Allocate WorkData array the size of the biggest FFT we'll do + // TODO: Deallocate this at the end of the function + WorkData = (sah_complex *)malloc_a(FftLen/2 * sizeof(sah_complex),MEM_ALIGN); + if (WorkData == NULL) { + SETIERROR(MALLOC_FAILED, "WorkData == NULL"); + } + + // Smooth Baseline + +#ifdef DO_SMOOTH +#ifdef BOINC_APP_GRAPHICS + if (sah_graphics) strcpy(sah_graphics->status, "Doing Baseline Smoothing"); +#endif + retval = BaseLineSmooth( + DataIn, NumDataPoints, swi.analysis_cfg.bsmooth_boxcar_length, + swi.analysis_cfg.bsmooth_chunk_size + ); + if (retval) SETIERROR(retval,"from BaseLineSmooth"); +#endif + + + // used to calculate percent done + //ProgressUnitSize = GetProgressUnitSize(NumDataPoints, num_cfft, swi); + ProgressUnitSize = GetProgressUnitSize(NumDataPoints, num_cfft); + //#define DUMP_CHIRP +#ifdef DUMP_CHIRP + // dump chirp/fft pairs and exit. + fprintf(stderr, "size = %d MinChirpStep = %f\n", num_cfft, MinChirpStep); + for (icfft = 0; icfft < num_cfft; icfft++) { + fprintf(stderr,"%6d %15.11f %6d %6d %d %d\n", + icfft, + ChirpFftPairs[icfft].ChirpRate, + ChirpFftPairs[icfft].ChirpRateInd, + ChirpFftPairs[icfft].FftLen, + ChirpFftPairs[icfft].GaussFit, + ChirpFftPairs[icfft].PulseFind + ); + } + fflush(stderr); + exit(0); +#endif + + + boinc_wu_cpu_time(cputime0); + reset_units(); + double chirp_units=0; + + // Loop through chirp/fft pairs - this is the top level analysis loop. + double last_ptime=0; + int rollovers=0; + double clock_max=0; + for (icfft = state.icfft; icfft < num_cfft; icfft++) { + fftlen = ChirpFftPairs[icfft].FftLen; + chirprate = ChirpFftPairs[icfft].ChirpRate; + chirprateind = ChirpFftPairs[icfft].ChirpRateInd; + // boinc_worker_timer(); +#ifdef DEBUG + double ptime=static_cast((unsigned)clock())/CLOCKS_PER_SEC+ + clock_max*rollovers; + clock_max=std::max(last_ptime-ptime,clock_max); + if (ptime((unsigned)clock())/CLOCKS_PER_SEC+ + clock_max*rollovers; + } + last_ptime=ptime; + + fprintf(stderr,"%f %f %f %f %f %f %f %f %f\n", + ptime, + progress, + ((double)icfft)/num_cfft, + analysis_state.FLOP_counter, + triplet_units, + pulse_units, + spike_units, + gauss_units, + chirp_units + ); + fflush(stderr); + + double cputime=0; + boinc_wu_cpu_time(cputime); + cputime-=cputime0; +#endif + + remaining=1.0-(double)icfft/num_cfft; + + if (chirprateind != last_chirp_ind) { +#ifdef BOINC_APP_GRAPHICS + if (sah_graphics) strcpy(sah_graphics->status, "Chirping data"); +#endif + + retval = ChirpData( + DataIn, + ChirpedData, + chirprateind, + chirprate, + NumDataPoints, + swi.subband_sample_rate + ); + + if (retval) SETIERROR(retval, "from ChirpData()"); + + progress += (double)(ProgressUnitSize * ChirpProgressUnits()); + chirp_units+=(double)(ProgressUnitSize * ChirpProgressUnits()); + progress = std::min(progress,1.0); + } + + // last_chirp = chirprate; + last_chirp_ind = chirprateind; + + // Process this FFT length. + // For a given FFT length (at a given chirp), we construct + // PowerSpectrum[] which is a "waterfall" array of power spectra, + // each fftlen long on the frequency axis and sample time long + // on the time axis. + // As we go along, we check each spectra for spikes. + + state.icfft = icfft; // update analysis state + + // Find index into FFT length table for the current + // FFT length. This will be the same index needed + // for ooura's coeffecient and bit reverse tables. + for (FftNum = 0; FftNum < swi.num_fft_lengths; FftNum++) { + if (swi.analysis_fft_lengths[FftNum] == fftlen) { + break; + } + } + +#ifdef BOINC_APP_GRAPHICS + if (sah_graphics) { + sah_graphics->fft_info.chirp_rate = chirprate; + sah_graphics->fft_info.fft_len = fftlen; + strcpy(sah_graphics->status, "Computing Fast Fourier Transform"); + } +#endif + + // If PoT freq bin is non-negative, we are into PoT analysis + // for this cfft pair and should not re-output an "ogh" line. + if (state.PoT_freq_bin == -1) { + retval = result_group_start(); + if (retval) SETIERROR(retval,"from result_group_start"); + } + + // Number of FFTs for this length + NumFfts = NumDataPoints / fftlen; + +#ifdef BOINC_APP_GRAPHICS + if (sah_graphics) { + rarray.init_data(fftlen, NumFfts); + } +#endif + for (ifft = 0; ifft < NumFfts; ifft++) { + // boinc_worker_timer(); + CurrentSub = fftlen * ifft; +#if !defined(USE_FFTWF) && !defined(USE_IPP) + // FFTW and IPP now use out of place transforms. + memcpy( + WorkData, + &ChirpedData[CurrentSub], + (int)(fftlen * sizeof(sah_complex)) + ); +#endif + + state.FLOP_counter+=5*(double)fftlen*log((double)fftlen)/log(2.0); +#ifdef USE_IPP + ippsFFTInv_CToC_32fc((Ipp32fc*)ChirpedData[CurrentSub], + (Ipp32fc*)WorkData, + FftSpec[FftNum], FftBuf); +#elif defined(USE_FFTWF) + fftwf_execute_dft(analysis_plans[FftNum], &ChirpedData[CurrentSub], WorkData); +#else + // replace time with freq - ooura FFT + cdft(fftlen*2, 1, WorkData, BitRevTab[FftNum], CoeffTab[FftNum]); +#endif + + // replace freq with power + state.FLOP_counter+=(double)fftlen; + GetPowerSpectrum( WorkData, + &PowerSpectrum[CurrentSub], + fftlen + ); + + if (fftlen==(long)ac_fft_len) { + state.FLOP_counter+=((double)fftlen)*5*log((double)fftlen)/log(2.0)+2*fftlen; +#if defined(USE_FFTWF) + fftwf_execute_r2r(autocorr_plan,&PowerSpectrum[CurrentSub],AutoCorrelation); +#else +#error Analysis needs to be modified for your FFT choice. +#endif + } + + // any ETIs ?! + // If PoT freq bin is non-negative, we are into PoT analysis + // for this cfft pair and need not redo spike and autocorr finding. + if (state.PoT_freq_bin == -1) { + state.FLOP_counter+=(double)fftlen; + retval = FindSpikes( + &PowerSpectrum[CurrentSub], + fftlen, + ifft, + swi + ); + progress += SpikeProgressUnits(fftlen)*ProgressUnitSize/NumFfts; + if (retval) SETIERROR(retval,"from FindSpikes"); + + + if (fftlen==ac_fft_len) { + retval = FindAutoCorrelation( + AutoCorrelation, + fftlen, + ifft, + swi + ); + if (retval) SETIERROR(retval,"from FindAutoCorrelation"); + } + } + + //progress = ((float)icfft)/num_cfft + ((float)ifft)/(NumFfts*num_cfft); + progress = std::min(progress,1.0); +#ifdef BOINC_APP_GRAPHICS + if (!nographics()) { + rarray.add_source_row(PowerSpectrum+fftlen*ifft); + sah_graphics->local_progress = (((float)ifft+1)/NumFfts); + } +#endif + remaining=1.0-(double)(icfft+1)/num_cfft; + fraction_done(progress,remaining); + // jeffc + //fprintf(stderr, "S fft len %d progress = %12.10f\n", fftlen, progress); + } // loop through chirped data array + +#ifdef BOINC_APP_GRAPHICS + if (!nographics()) { + memcpy(&sah_shmem->rarray_data, &rarray, sizeof(REDUCED_ARRAY_DATA)); + } +#endif + fraction_done(progress,remaining); + // jeffc + //fprintf(stderr, "Sdone fft len %d progress = %12.10f\n", fftlen, progress); + + // transpose PoT matrix to make memory accesses nicer + need_transpose = ChirpFftPairs[icfft].GaussFit || ChirpFftPairs[icfft].PulseFind; + if ( !need_transpose ) { + int tmpPulsePoTLen, tmpOverlap; + GetPulsePoTLen( NumFfts, &tmpPulsePoTLen, &tmpOverlap ); + if ( ! ( tmpPulsePoTLen > PoTInfo.TripletMax || tmpPulsePoTLen < PoTInfo.TripletMin ) ) + need_transpose = true; + } + + if (need_transpose && use_transposed_pot) { + Transpose(fftlen, NumFfts, (float *) PowerSpectrum, (float *)tPowerSpectrum); + } + // + // Analyze Power over Time. May return quickly if this FFT + // length and/or this WUs slew rate places the data block + // outside PoT analysis limits. + // Counting flops is done inside analyze_pot + retval = analyze_pot(tPowerSpectrum, NumDataPoints, ChirpFftPairs[icfft]); + if (retval) SETIERROR(retval,"from analyze_pot"); + +#ifdef BOINC_APP_GRAPHICS + // switch the display back to "best of" signals + // + if (!nographics()) { + sah_graphics->gi.copy(best_gauss, true); + sah_graphics->pi.copy(best_pulse, true); + sah_graphics->ti.copy(best_triplet, true); + } +#endif + // Force progress to 100% before calling result_group_end() to store + // 100% in state file so it will survive exit & relaunch + if (icfft == (num_cfft-1)) { + progress = 1; + remaining = 0; + fraction_done(progress,remaining); + } + retval = checkpoint(); + if (retval) SETIERROR(retval,"from checkpoint() in seti_analyse()"); + + } // loop over chirp/fftlen paris + + // Return the "best of" signals. This may include duplicates of + // already reported interesting signals. + if (best_spike->s.fft_len) { + retval = outfile.printf("%s", best_spike->s.print_xml(0,0,1,"best_spike").c_str()); + if (retval < 0) { + SETIERROR(WRITE_FAILED,"from outfile.printf (best spike) in seti_analyze()"); + } + } + + if (best_autocorr->a.fft_len) { + retval = outfile.printf("%s", best_autocorr->a.print_xml(0,0,1,"best_autocorr").c_str()); + if (retval < 0) { + SETIERROR(WRITE_FAILED,"from outfile.printf (best autocorr) in seti_analyze()"); + } + } + + if (best_gauss->g.fft_len || best_gauss->score) { + retval = outfile.printf("%s", best_gauss->g.print_xml(0,0,1,"best_gaussian").c_str()); + if (retval < 0) { + SETIERROR(WRITE_FAILED,"from outfile.printf (best gaussian) in seti_analyze()"); + } + } + if (best_pulse->p.fft_len) { + retval = outfile.printf("%s", best_pulse->p.print_xml(0,0,1,"best_pulse").c_str()); + if (retval < 0) { + SETIERROR(WRITE_FAILED,"from outfile.printf (best pulse) in seti_analyze()"); + } + } + if (best_triplet->t.fft_len) { + retval = outfile.printf("%s", best_triplet->t.print_xml(0,0,1,"best_triplet").c_str()); + if (retval < 0) { + SETIERROR(WRITE_FAILED,"from outfile.printf (best triplet) in seti_analyze()"); + } + } + +#ifdef BOINC_APP_GRAPHICS + if (sah_graphics) strcpy(sah_graphics->status, "Work unit done"); +#endif + final_report(); // flop and signal counts to stderr + retval = checkpoint(); // try a final checkpoint + + if (PowerSpectrum) free_a(PowerSpectrum); + if (use_transposed_pot) free_a(tPowerSpectrum); + +#ifdef USE_IPP + for (FftNum = 0; FftNum < swi.num_fft_lengths; FftNum++) { + if (FftSpec[FftNum]) ippsFFTFree_C_32fc (FftSpec[FftNum]); + } + if (FftBuf) free_a(FftBuf); + FftBuf = NULL; +#elif !defined(USE_FFTWF) + for (FftNum = 0; FftNum < swi.num_fft_lengths; FftNum++) { + if (BitRevTab[FftNum]) free_a(BitRevTab[FftNum]); + } + for (FftNum = 0; FftNum < swi.num_fft_lengths; FftNum++) { + if (CoeffTab[FftNum]) free_a(CoeffTab[FftNum]); + } +#endif + + if (WorkData) free_a(WorkData); + WorkData = NULL; + + if (ChirpFftPairs) free(ChirpFftPairs); + if ((app_init_data.host_info.m_nbytes == 0) || + (app_init_data.host_info.m_nbytes >= (double)(64*1024*1024))) { + FreeTrigArray(); + } + + // jeffc + //retval = outfile.flush(); + xml_indent(-2); + outfile.printf(""); + outfile.close(); + //if (retval) SETIERROR(WRITE_FAILED,"from outfile.fflush in seti_analyze()"); + + return retval; +} + + +int v_BaseLineSmooth( + sah_complex* DataIn, + int NumDataPoints, + int BoxCarLength, + int NumPointsInChunk +) { + + // We use a sliding boxcar method for baseline smoothing. Input data + // is the time domain. It is transformed (using a separate array) + // into the frequency domain. After baseline smoothing is done + // in the frequency domain, it is transformed back into the time domain. + + int h, i, j, k; + sah_complex* DataInChunk; + static sah_complex *DataOutChunk=0; + static float* PowerSpectrum=0; + float Total, LocalMean, ScaleFactor,recipNumPointsInChunk=1.0/NumPointsInChunk; + int NumTimeChunks, TimeChunk, Endpoint; + static int OldNumPointsInChunk = 0; +#ifdef USE_IPP + static IppsFFTSpec_C_32fc* FftSpec = NULL; +#elif defined(USE_FFTWF) + static fftwf_plan backward_transform, forward_transform; +#endif /* USE_FFTWF */ + +#ifndef USE_FFTWF + static int * BitRevTab = NULL; + static float * CoeffTab = NULL; +#endif /* USE_FFTWF */ + + NumTimeChunks = (int)(NumDataPoints * recipNumPointsInChunk); + + + // If we keep doing transforms that are the same length, don't reinitialize plans + if (NumPointsInChunk != OldNumPointsInChunk) { + if (OldNumPointsInChunk != 0) { + +#ifdef USE_IPP + if (FftSpec) ippsFFTFree_C_32fc (FftSpec); +#elif defined(USE_FFTWF) + if (backward_transform) free_a(backward_transform); + if (forward_transform) free_a(forward_transform); +#else + if (BitRevTab) free_a(BitRevTab); + if (CoeffTab) free_a(CoeffTab); +#endif + if (PowerSpectrum) free_a(PowerSpectrum); + if (DataOutChunk) free_a(DataOutChunk); + } + PowerSpectrum = (float*) calloc_a(NumPointsInChunk, sizeof(float), MEM_ALIGN); + if (PowerSpectrum == NULL) { + printf("Could not allocate Power Spectrum array in v_BaseLineSmooth()\n"); + exit(1); + } + // Do the transforms in the DataOutChunk, since DataInChunk won't + // necessarily be aligned correctly (and we won't get SIMD) + // TODO: automatically make DataInChunk aligned correctly so we + // don't need the memcpy. This may already be done if + // NumPointsInChunk*sizeof(sah_complex) is a multiple of MEM_ALIGN + DataOutChunk = (sah_complex *)malloc_a(NumPointsInChunk * sizeof(sah_complex),MEM_ALIGN); + OldNumPointsInChunk = NumPointsInChunk; + +#ifdef USE_IPP + int order = 0; + for (int tmp = NumPointsInChunk; !(tmp & 1); order++) tmp >>= 1; + ippsFFTInitAlloc_C_32fc (&FftSpec, order, IPP_FFT_NODIV_BY_ANY, + ippAlgHintAccurate); +#elif defined(USE_FFTWF) + sah_complex *scratch = (sah_complex *)malloc_a(NumPointsInChunk * sizeof(sah_complex),MEM_ALIGN); + + backward_transform = fftwf_plan_dft_1d(NumPointsInChunk, scratch, DataOutChunk, FFTW_BACKWARD, FFTW_MEASURE|FFTW_PRESERVE_INPUT); + forward_transform = fftwf_plan_dft_1d(NumPointsInChunk, DataOutChunk, DataOutChunk, FFTW_FORWARD, FFTW_MEASURE); + free_a(scratch); +#else + BitRevTab = (int*) calloc_a(3+(int)sqrt((float)NumPointsInChunk/2), sizeof(int), MEM_ALIGN); + if (BitRevTab == NULL) return MALLOC_FAILED; + + CoeffTab = (float*) calloc_a(NumPointsInChunk/2, sizeof(float), MEM_ALIGN); + if (CoeffTab == NULL) return MALLOC_FAILED; + // flag to tell cdft() to init it's work areas + // already done since we used calloc_a(); + // BitRevTab[0] = 0; +#endif + + } + + for (TimeChunk = 0; TimeChunk < NumTimeChunks; TimeChunk++) { +#ifdef BOINC_APP_GRAPHICS + if (sah_graphics) sah_graphics->local_progress = (((float)TimeChunk)/NumTimeChunks); +#endif + + DataInChunk = &(DataIn[TimeChunk*NumPointsInChunk]); +#ifndef USE_FFTWF + memcpy( DataOutChunk, DataInChunk, (int)(NumPointsInChunk*sizeof(sah_complex)) ); +#endif + + // transform to freq +#ifdef USE_IPP + ippsFFTInv_CToC_32fc ((Ipp32fc*)DataOutChunk, (Ipp32fc*)DataOutChunk, + FftSpec, NULL); +#elif !defined(USE_FFTWF) + cdft(NumPointsInChunk*2, 1, DataOutChunk, BitRevTab, CoeffTab); +#else + fftwf_execute_dft(backward_transform,DataInChunk,DataOutChunk); +#endif + + GetPowerSpectrum( + DataOutChunk, PowerSpectrum, NumPointsInChunk + ); + + // Begin: normalize in freq. domain via sliding boxcar + + Endpoint = NumPointsInChunk / 2; + + i = Endpoint; // start i at lowest negative freq; + // this is low point in first boxcar + j = i + BoxCarLength / 2; // start j midpoint in first boxcar + k = i + BoxCarLength; // start k at end of first boxcar; + // thus a boxcar is i----j----k + Total = 0; + for (h = i; h < k; h++) { // Get mean for first boxcar + Total += PowerSpectrum[h]; + } + LocalMean = Total / BoxCarLength; + ScaleFactor = (float)(1.0/sqrt(LocalMean * 0.5)); + + // normalize 1st half of 1st boxcar + for (h = i; h < j; h++) { + DataOutChunk[h][0] *= ScaleFactor; + DataOutChunk[h][1] *= ScaleFactor; + } + + for (; k != Endpoint; i++, j++, k++) { // sliding boxcar + if (k == NumPointsInChunk) { // take care of wrapping + k = 0; + } + if (j == NumPointsInChunk) { + j = 0; + } + if (i == NumPointsInChunk) { + i = 0; + } + + LocalMean = LocalMean + - PowerSpectrum[i] / BoxCarLength + + PowerSpectrum[k] / BoxCarLength; + ScaleFactor = (float)(1.0/sqrt(LocalMean * 0.5)); + + DataOutChunk[j][0] *= ScaleFactor; + DataOutChunk[j][1] *= ScaleFactor; + + } // End sliding boxcar + + // normalize final half of final boxcar + for (h = j; h < k; h++) { + DataOutChunk[h][0] *= ScaleFactor; + DataOutChunk[h][1] *= ScaleFactor; + } + + // End: normalize in freq. domain via sliding boxcar + + // transform back to time +#ifdef USE_IPP + ippsFFTFwd_CToC_32fc((Ipp32fc*)DataOutChunk, (Ipp32fc*)DataOutChunk, + FftSpec, NULL); +#elif !defined(USE_FFTWF) + cdft(NumPointsInChunk*2, -1, DataOutChunk, BitRevTab, CoeffTab); +#else + fftwf_execute(forward_transform); +#endif + analysis_state.FLOP_counter+=10.0*NumPointsInChunk*log((double)NumPointsInChunk)/log(2.0)+10.0*NumPointsInChunk; + // return powers to normal + for (i = 0; i < NumPointsInChunk; i++) { + DataInChunk[i][0] = DataOutChunk[i][0]*recipNumPointsInChunk; + DataInChunk[i][1] = DataOutChunk[i][1]*recipNumPointsInChunk; + } + } + + return 0; +} + + +int v_GetPowerSpectrum( + sah_complex* FreqData, + float* PowerSpectrum, + int NumDataPoints +) { + int i; + +#ifdef __INTEL_COMPILER +#pragma message ("---using ICC---") +#pragma vector aligned + __assume_aligned (FreqData, MEM_ALIGN); +#endif + analysis_state.FLOP_counter+=3.0*NumDataPoints; + for (i = 0; i < NumDataPoints; i++) { + PowerSpectrum[i] = FreqData[i][0] * FreqData[i][0] + + FreqData[i][1] * FreqData[i][1]; + } + return 0; +} + +// chirp_rate is in Hz per second + +#ifndef USE_INTEL_OPT_CODE +int v_ChirpData( + sah_complex* cx_DataArray, + sah_complex* cx_ChirpDataArray, + int chirp_rate_ind, + double chirp_rate, + int ul_NumDataPoints, + double sample_rate +) { + int i; + double recip_sample_rate=1.0/sample_rate; + +#ifdef DEBUG + fprintf(stderr, "icfft = %6d crate index = %6d\n", icfft, chirp_rate_ind); + fflush(stderr); +#endif + + if (chirp_rate_ind == 0) { + memcpy(cx_ChirpDataArray, + cx_DataArray, + (int)ul_NumDataPoints * sizeof(sah_complex) + ); // NOTE INT CAST + } else { + + // what we do depends on how much memory we have... + // If we have more than 64MB, we'll cache the chirp table. If not + // we'll calculate it each time. + bool CacheChirpCalc=((app_init_data.host_info.m_nbytes == 0) || + (app_init_data.host_info.m_nbytes >= (double)(64*1024*1024))); + + // calculate trigonometric array + // this function returns w/o doing nothing when sign of chirp_rate_ind + // reverses. so we have to take care of it. + + if (CacheChirpCalc) CalcTrigArray(ul_NumDataPoints, chirp_rate_ind); + + for (i = 0; i < ul_NumDataPoints; i++) { + float c, d, real, imag; + + if (CacheChirpCalc) { + c = CurrentTrig[i].Cos; + d = (chirp_rate_ind >0)? CurrentTrig[i].Sin : -CurrentTrig[i].Sin; + } else { + double dd,cc; + double time=static_cast(i)*recip_sample_rate; + // since ang is getting moded by 2pi, we calculate "ang mod 2pi" + // before the call to sincos() inorder to reduce roundoff error. + // (Bug submitted by Tetsuji "Maverick" Rai) + double ang = 0.5*chirp_rate*time*time; + ang -= floor(ang); + ang *= M_PI*2; + sincos(ang,&dd,&cc); + c=cc; + d=dd; + } + + // Sometimes chirping is done in place. + // We don't want to overwrite data prematurely. + real = cx_DataArray[i][0] * c - cx_DataArray[i][1] * d; + imag = cx_DataArray[i][0] * d + cx_DataArray[i][1] * c; + cx_ChirpDataArray[i][0] = real; + cx_ChirpDataArray[i][1] = imag; + } + analysis_state.FLOP_counter+=12.0*ul_NumDataPoints; + } + return 0; +} +#endif // USE_INTEL_OPT_CODE + + +// Trigonometric arrays functions +// These functions makes trigonometric arrays very quickly and +// will speed up v_ChirpData() +// by Tetsuji "Maverick" Rai + +// initialize TrigStep and CurrentTrig + +void InitTrigArray(int len, double ChirpStep, int InitChirpRateInd, + double SampleRate) { + int i; + double ang, Coef; + + TrigStep = (SinCosArray*) malloc_a (len * sizeof(SinCosArray), MEM_ALIGN); + if (TrigStep == NULL) SETIERROR(MALLOC_FAILED, "TrigStep == NULL"); + + CurrentTrig = (SinCosArray*) malloc_a (len * sizeof(SinCosArray), MEM_ALIGN); + if (CurrentTrig == NULL) SETIERROR(MALLOC_FAILED, "CurrentTrig == NULL"); + + // Make ChirpStep array + + Coef = ChirpStep / (SampleRate*SampleRate); + + for (i = 0; i < len; i++) { + // since ang is getting cast to a float, we calculate "ang mod 2pi" + // before the call to sincosf() inorder to reduce roundoff error. + // (Bug submitted by Tetsuji "Maverick" Rai) + // addition: now it's used as double float, but this bug fix + // is still preferable + ang = 0.5*(double)i*(double)i*Coef; + ang -= floor(ang); + ang *= 2*M_PI; + sincos(ang, &TrigStep[i].Sin, &TrigStep[i].Cos); + } + + // Set initial trigonometric array + + if ((CurrentChirpRateInd = abs(InitChirpRateInd)) != 0) { + Coef = CurrentChirpRateInd*ChirpStep / (SampleRate*SampleRate); + + for (i = 0; i < len; i++) { + ang = 0.5*(double)i*(double)i*Coef; + ang -= floor(ang); + ang *= 2*M_PI; + sincos(ang, &CurrentTrig[i].Sin, &CurrentTrig[i].Cos); + } + } else { + // if it starts from the beginning, it's quite simple + for (i = 0; i < len; i++) { + CurrentTrig[i].Sin = 0.; + CurrentTrig[i].Cos = 1.0; + } + } +} + + + +// calculate next CurrentTrig + +void CalcTrigArray (int len, int ChirpRateInd) { + double SinX, CosX, SinS, CosS; + int TempCRateInd = abs(ChirpRateInd); + int i, j; + // skip automatically when TempCRateInd == CurrentChirpRateInd + // (it happens when sign of chirprate reverses) + // Otherwise + // sin(x+step) = sin(x)*cos(step) + cos(x)*sin(step) + // cos(x+step) = cos(x)*cos(step) - sin(x)*sin(step) + + // In most cases index increases by 1, and in the later phase of a WU + // by 4 at most in reference WU, but it's 2-3 times faster than + // sincos() function on P4 with gcc or icc. When index increases by 1, + // this is about 10 times as fast as sincos() + + // JWS: Modified so when index increases by more than one, the two 16 MiB + // arrays are only loaded once. The index can increase by as much as 16. + // +#ifdef DEBUG + fprintf(stderr, " New ind = %6d (abs(%6d)) Previous = %6d\n", + ChirpRateInd, TempCRateInd, CurrentChirpRateInd); + fflush(stderr); +#endif + + switch ( TempCRateInd - CurrentChirpRateInd ) { + case 0: + return; // replaces "automatic skip" + case 1: + for ( j = 0; j < len; j++ ) { + SinX = CurrentTrig[j].Sin; + CosX = CurrentTrig[j].Cos; + SinS = TrigStep[j].Sin; + CosS = TrigStep[j].Cos; + + CurrentTrig[j].Sin = SinX * CosS + CosX * SinS; + CurrentTrig[j].Cos = CosX * CosS - SinX * SinS; + } + break; + case 2: // unroll once to avoid 50/50 inner loop + for ( j = 0; j < len; j++ ) { + double SinTmp, CosTmp; + + SinX = CurrentTrig[j].Sin; + CosX = CurrentTrig[j].Cos; + SinS = TrigStep[j].Sin; + CosS = TrigStep[j].Cos; + + SinTmp = SinX * CosS + CosX * SinS; + CosTmp = CosX * CosS - SinX * SinS; + + CurrentTrig[j].Sin = SinTmp * CosS + CosTmp * SinS; + CurrentTrig[j].Cos = CosTmp * CosS - SinTmp * SinS; + } + break; + default: // 3 or more + for ( j = 0; j < len; j++ ) { + for ( i = CurrentChirpRateInd; i < TempCRateInd; i++ ) { + SinX = CurrentTrig[j].Sin; + CosX = CurrentTrig[j].Cos; + SinS = TrigStep[j].Sin; + CosS = TrigStep[j].Cos; + + CurrentTrig[j].Sin = SinX * CosS + CosX * SinS; + CurrentTrig[j].Cos = CosX * CosS - SinX * SinS; + } + } + break; + } + CurrentChirpRateInd = TempCRateInd; +} + + +// free TrigStep and CurrentTrig + +void FreeTrigArray() { + if (TrigStep) free_a(TrigStep); + TrigStep = NULL; + + if (CurrentTrig) free_a(CurrentTrig); + CurrentTrig = NULL; +} + +template +inline void v_subTranspose(float *in, float *out, int xline, int yline) { + // Transpose an X by X subsection of a XLINE by YLINE matrix into the + // appropriate part of a YLINE by XLINE matrix. "IN" points to the first + // (lowest address) element of the input submatrix. "OUT" points to the + // first (lowest address) element of the output submatrix. + int i,j; + float *p; + register float tmp[x*x]; + for (j=0;j(in+j*x+i,out+y*i+j,x,y); + } + for (;i(in+j*x+i,out+y*i+j,x,y); + } + for (;i(in+j*x+i,out+y*i+j,x,y); + } + for (;i(in+j*x+i,out+y*i+j,x,y); + } + for (;i(in+j*x+i,out+y*i+j,x,y); + } + for (;i(in+j*x+i,out+y*i+j,x,y); + } + for (;i(in+j*x+i,out+y*i+j,x,y); + } + for (;i(in+j*x+i,out+y*i+j,x,y); + } + for (;i(in+j*x+i,out+y*i+j,x,y); + } + for (;i(in+j*x+i,out+y*i+j,x,y); + } + for (;i +#include +#include +#include + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef BOINC_APP_GRAPHICS +#include "sah_gfx_main.h" +#endif + +#include "util.h" +#include "malloc_a.h" +#include "analyze.h" +#include "seti.h" +#include "worker.h" +#include "analyzeFuncs.h" +#include "analyzePoT.h" +#include "analyzeReport.h" +#include "gaussfit.h" +#include "pulsefind.h" +#include "chirpfft.h" +#include "filesys.h" +#include "util.h" +#include "s_util.h" +#include "progress.h" + +//#define DEBUG_POT + +// Compile time inits. Command line parms of setiathome_test can +// change a number of these. +PoTInfo_t PoTInfo = {0}; + +int analyze_pot( + float *PowerSpectrum, + int NumDataPoints, + ChirpFftPair_t &cfft +) { + + + // This function analyses Power over Time for the current data block. + // The PoT array is created by taking an array of power spectra (a + // standard row-major 2D array) and extracting the PoT as column-major + // data. We essentialy turn the array on its side. + + int retval = 0, + i, + FftLength=cfft.FftLen, // Current FFT length + ThisPoT, // index of current PoT along the freq axis + PoTLen, // compliment of FFT length - determines time res + PulsePoTLen, // length of PoT segment passed to pulse finders + Overlap, // PoT segment overlap in bins + TOffset, // index into ThisPoT of current pulse segment + PulsePoTNum = 0, // the oridinal position of a pulse PoT w/in a full PoT + NumPulsePoTs = 0, // the number of pulse PoTs w/in a full PoT. This is + // constant regardless of FFT or PoT length and is + // determined by slew rate. + AdvanceBy; // the number of bins to advance for the next pulse PoT + + float ProgressAddFactor = 0.0, // sum of progress adds for ThisPoT + ProgressPerPulsePoT = 0.0; // for local progress display + + bool SkipGauss = false, + SkipPulse = false, + SkipTriplet = false, + TOffsetOK = true; + + static float *GaussPoT = NULL, + *PulsePoT = NULL; + +#ifdef DUMP_POWER_SPECTRA + + if (ul_FftLength == FFT_TO_DUMP) { + for (i=0;i PoTInfo.TripletMax || PulsePoTLen < PoTInfo.TripletMin) + SkipTriplet = true; + SkipGauss = !(cfft.GaussFit); + SkipPulse = !(cfft.PulseFind); + + if(!SkipPulse || !SkipTriplet) { + // NumPulsePoTs is the number of PoT segments that we pass to the pulse + // detectors per frequency bin. ProgressPerPulsePoT is the inverse of + // number of pulse detection segments in the entire data block, taking + // into account that we skip the first (DC) frequency bin. An assumption + // is made here that minimum pulse/triplet PoT length will always be + // greater than 1. Otherwise, AdvanceBy can become zero and a divide by + // zero can occur. The assumption is also made that FftLength is always + // greater than 1! + NumPulsePoTs = 1 + (PoTLen-PulsePoTLen)/AdvanceBy + ((PoTLen-PulsePoTLen)%AdvanceBy ? 1 : 0); + ProgressPerPulsePoT = (float)1 / ((FftLength - 1) * NumPulsePoTs); + } + +#ifdef DEBUG_POT + fprintf(stderr, "SlewRate = %f\n", PoTInfo.SlewRate); + fprintf(stderr, "PoTLen = %d\n", PoTLen); + fprintf(stderr, "MaxPoTLen = %d\n", PoTInfo.MaxPoTLen); + fprintf(stderr, "PoTDuration = %f\n", PoTInfo.WUDuration); + fprintf(stderr, "BeamRate = %f\n", PoTInfo.BeamRate); + fprintf(stderr, "PulsePoTLen = %d\n", PulsePoTLen); + fprintf(stderr, "Overlap = %d\n", Overlap); + fprintf(stderr, "AdvanceBy = %d\n", AdvanceBy); + fprintf(stderr, "min_slew = %f\n", PoTInfo.min_slew); + fprintf(stderr, "max_slew = %f\n", PoTInfo.max_slew); + fprintf(stderr, "PulseOverlapFactor = %f\n", PoTInfo.PulseOverlapFactor); + fprintf(stderr, "PulseBeams = %f\n", PoTInfo.PulseBeams); + fprintf(stderr, "PulseThresh = %f\n", PoTInfo.PulseThresh); + fprintf(stderr, "PulseMax = %d\n", PoTInfo.PulseMax); + fprintf(stderr, "PulseMin = %d\n", PoTInfo.PulseMin); + fprintf(stderr, "PulseFftMax = %d\n", PoTInfo.PulseFftMax); + fprintf(stderr, "TripletThresh = %f\n", PoTInfo.TripletThresh); + fprintf(stderr, "TripletMax = %d\n", PoTInfo.TripletMax); + fprintf(stderr, "TripletMin = %d\n", PoTInfo.TripletMin); +#endif + +#ifndef USE_PULSE + + SkipPulse = TRUE; +#endif +#ifndef USE_TRIPLET + + SkipTriplet = TRUE; +#endif + + // Get memory fot the PoT arrays. The PoT array for gausian analysis is + // of set size. The PoT array for pulse analysis is sized to cover + // PulseBeams beams, regardless of whether this violates either the + // triplet or pulse limits on array size. + if(!GaussPoT) { + GaussPoT = (float *)malloc_a(swi.analysis_cfg.gauss_pot_length * sizeof(float), MEM_ALIGN); + if(GaussPoT == NULL) { + SETIERROR(MALLOC_FAILED, "GaussPoT == NULL"); + } + } + if(!PulsePoT) { + PulsePoT = (float *)calloc_a(PoTInfo.MaxPoTLen+3, sizeof(float), MEM_ALIGN); + if(PulsePoT == NULL) { + SETIERROR(MALLOC_FAILED, "PulsePoT == NULL"); + } + } + + // Look for gaussians --------------------------------------------------- + if(!SkipGauss && (analysis_state.PoT_activity == POT_DOING_GAUSS || + analysis_state.PoT_activity == POT_INACTIVE)) { + +#ifdef BOINC_APP_GRAPHICS + if (sah_graphics) + strcpy(sah_graphics->status, "Searching for Gaussians"); +#endif + + // If we are back from being interrupted in the middle of gaussian PoT + // analysis, load state and continue. Otherwise start anew, skipping + // the DC (0) bin. + if(analysis_state.PoT_activity == POT_DOING_GAUSS) { + ThisPoT = analysis_state.PoT_freq_bin; + } else { + ThisPoT = 1; // skip the DC bin on start of new cfft pair + } + + // Initial display of local Progress / CPU time. Assumes that + // we start ThisPoT at 1 each time in! +#ifdef BOINC_APP_GRAPHICS + if (sah_graphics) + sah_graphics->local_progress = ((float)ThisPoT-1)/(FftLength-1); +#endif + + // loop through frequencies + for(; ThisPoT < FftLength; ThisPoT++) { + + // Create PowerOfTime array for gaussian fit + retval = GetFixedPoT( + PowerSpectrum, + NumDataPoints, + FftLength, + GaussPoT, + swi.analysis_cfg.gauss_pot_length, + ThisPoT + ); + if (retval) + continue; + + retval = GaussFit(GaussPoT, FftLength, ThisPoT); + if (retval) + SETIERROR(retval,"from GaussFit"); + + + + progress += ProgressUnitSize * GaussianProgressUnits() / (float)(FftLength - 1); + progress=std::min(progress,1.0); // prevent display of > 100% + fraction_done(progress,remaining); + + // At the end of each frequency bin we update progress and save state. +#ifdef BOINC_APP_GRAPHICS + if (!nographics()) { + sah_graphics->local_progress = ((float)ThisPoT)/(FftLength-1); + } +#endif + analysis_state.PoT_freq_bin = ThisPoT; + analysis_state.PoT_activity = POT_DOING_GAUSS; + retval = checkpoint(); + if (retval) + SETIERROR(retval,"from checkpoint()"); + + } // end loop through frequencies + + analysis_state.PoT_freq_bin = -1; + analysis_state.PoT_activity = POT_INACTIVE; + + } // end looking for gaussians + + + // Look for pulses ------------------------------------------------------- + if(!SkipPulse || !SkipTriplet) { + +#ifdef BOINC_APP_GRAPHICS + if (sah_graphics) { + strcpy(sah_graphics->status, "Searching for Pulses / Triplets"); + // init local progress for pulse search + sah_graphics->local_progress = 0; + } +#endif + + + // If we are back from being interrupted in the middle of pulse PoT + // analysis, load state and continue. Otherwise start anew, skipping + // the DC (0) bin. + if(analysis_state.PoT_activity == POT_DOING_PULSE) { + ThisPoT = analysis_state.PoT_freq_bin; + } else { + ThisPoT = 1; // skip the DC bin on start of new cfft pair + } + + PulsePoTNum = 0; + +#ifdef BOINC_APP_GRAPHICS + // Inital display of Local Progress + if (sah_graphics) { + sah_graphics->local_progress = (((ThisPoT-1) * NumPulsePoTs) + + PulsePoTNum) * + ProgressPerPulsePoT; + } +#endif + + // loop through frequencies + for(; ThisPoT < FftLength; ThisPoT++) { + + // loop through time for each frequency. PulsePoTNum is + // used only for progress calculation. + for(TOffset = 0, PulsePoTNum = 1, TOffsetOK = true; + TOffsetOK; + PulsePoTNum++, TOffset += AdvanceBy) { + + // Create PowerOfTime array for pulse detection. If there + // are not enough points left in this PoT, adjust TOffset + // to get the latest possible pulse PoT. + if(TOffset + PulsePoTLen >= PoTLen) { + TOffsetOK = false; + TOffset = PoTLen - PulsePoTLen; + } + if (use_transposed_pot) { + memcpy(PulsePoT, &PowerSpectrum[ThisPoT * PoTLen + TOffset], PulsePoTLen*sizeof(float)); + } else { + for(i = 0; i < PulsePoTLen; i++) { + PulsePoT[i] = PowerSpectrum[ThisPoT + (TOffset+i) * FftLength]; + } + } + + if(!SkipTriplet) { + retval = find_triplets(PulsePoT, + PulsePoTLen, + (float)PoTInfo.TripletThresh, + TOffset, + ThisPoT); + if (retval) + SETIERROR(retval,"from find_triplets()"); + } + + if(!SkipPulse) { + retval = find_pulse(PulsePoT, + PulsePoTLen, + (float)PoTInfo.PulseThresh, + TOffset, + ThisPoT + ); + if (retval) + SETIERROR(retval,"from find_pulse()"); + } + + // At the end of each pulse PoT we update progress. Progress + // will thus get updted several times per frequency bin. +#ifdef BOINC_APP_GRAPHICS + if (sah_graphics) + { + sah_graphics->local_progress = (((ThisPoT-1) * NumPulsePoTs) + + PulsePoTNum) * + ProgressPerPulsePoT; + } +#endif + if(!SkipTriplet) { + progress += (ProgressUnitSize * TripletProgressUnits()) / + (float)(FftLength - 1) / NumPulsePoTs; + } + if(!SkipPulse) { + progress += (ProgressUnitSize * PulseProgressUnits(PulsePoTLen, FftLength - 1)) / + (float)(FftLength - 1) / NumPulsePoTs; + + } + progress=std::min(progress,1.0); // prevent display of > 100% + fraction_done(progress,remaining); + + } // end loop through time for each frequency + + // At the end of each frequency bin we save state. + analysis_state.PoT_activity = POT_DOING_PULSE; + analysis_state.PoT_freq_bin = ThisPoT; + retval = checkpoint(); + if (retval) + SETIERROR(retval,"from checkpoint()"); + + } // end loop through frequencies + + analysis_state.PoT_freq_bin = -1; + analysis_state.PoT_activity = POT_INACTIVE; + + } // end looking for pulses + + + return (retval); // no error return point +} + +int GetFixedPoT( + float fp_PowerSpectrum[], + int ul_NumDataPoints, + int ul_FftLength, + float fp_PoT[], + int ul_PoTLen, + int ul_PoT +) { + + // This routine returns a PoT array of fixed length, regardless + // of the actual number of time bins in the current data block. + + int ul_PoT_i, + ul_PoTChunkSize, + ul_PoTChunk_i, + ul_PoTChunkLimit, + ul_NumSpectra, + ul_PoTsPerSpec, + ul_MidPoint, + ul_BaseSpec, + ul_SubPoT_i; + + float f_Factor, + f_BaseSpecPowerPerPoT = 0.0, + f_AftSpecPowerPerPoT = 0.0, + f_ForwardSpecPowerPerPoT = 0.0, + f_BaseWeight; + + ul_NumSpectra = ul_NumDataPoints / ul_FftLength; + ul_PoTChunkSize = ul_NumSpectra / ul_PoTLen; + + // Populate PoT + + // For setiathome_enhanced, the number of spectra is the same as the + // number of elements in a PoT array more times than not (16K FFT length). + // For an 0.426 angle range, there are 2.2104e10 cases where they're equal + // and 2.2082e10 cases where they're not. Copying directly rather than + // adding also means no FLOP_counter increment is needed. + if (ul_NumSpectra == ul_PoTLen) { + if (use_transposed_pot) { + memcpy(fp_PoT, &fp_PowerSpectrum[ul_PoT * ul_NumSpectra], + swi.analysis_cfg.gauss_pot_length * sizeof(float)); + } else { + for (ul_PoT_i = 0, ul_PoTChunk_i = 0; + ul_PoT_i < swi.analysis_cfg.gauss_pot_length; + ul_PoT_i++, ul_PoTChunk_i += ul_FftLength) { + fp_PoT[ul_PoT_i] = fp_PowerSpectrum[ul_PoT + ul_PoTChunk_i]; + } + } + // If the number of spectra is greater than the number + // of elements in a PoT array, we add sum adjacent spectra + // into PoT elements. + // ul_PoTChunkSize indicates how many time-wise + // power spectra bins are added together to make one PoT bin. + } else if (ul_NumSpectra > ul_PoTLen) { + ul_PoTChunk_i = 0; + for (ul_PoT_i = 0; ul_PoT_i < swi.analysis_cfg.gauss_pot_length; ul_PoT_i++) { + fp_PoT[ul_PoT_i] = 0.0; + ul_PoTChunkLimit = ul_PoTChunk_i + ul_PoTChunkSize; + + // Stuff chunk of power spectra bins into 1 PoT bin + if (use_transposed_pot) { + for (; ul_PoTChunk_i < ul_PoTChunkLimit; ul_PoTChunk_i++) { + fp_PoT[ul_PoT_i] += fp_PowerSpectrum[ul_PoT * ul_NumSpectra + ul_PoTChunk_i]; + } + } else { + for (; ul_PoTChunk_i < ul_PoTChunkLimit; ul_PoTChunk_i++) { + fp_PoT[ul_PoT_i] += fp_PowerSpectrum[ul_PoT + + ul_FftLength * ul_PoTChunk_i]; + } + } + } + analysis_state.FLOP_counter+=((double)ul_NumSpectra+swi.analysis_cfg.gauss_pot_length); + } else { + // If the number of spectra is less than the the number + // of elements in a PoT array, we smear the power in each + // spectrum over more than one PoT element. Further, we + // perform a linear interpolation to smooth the transition + // from one spectrum to the next. That is, we allow the + // spectra before or after our "base" spectrum to effect + // the powers that go into a given PoT bin. The closer + // in time that the PoT bin is to the "before" or "after" + // spectra, the more that PoT bin is effected by the + // neighboring spectrum. + // NOTE : This is all effectively turned off by not letting + // gaussfit() see data analyzed with an FFT length + // greater than GAUSS_POT_LEN. + + ul_PoTsPerSpec = ul_PoTLen / ul_NumSpectra; + // Number of PoT bins over which to smear 1 spectrum. + f_Factor = 1.0f / ul_PoTsPerSpec; + // For dividing up 1 spectrum's power pre-interpolation. + ul_MidPoint = ul_PoTsPerSpec / 2; + + for (ul_PoT_i = 0; ul_PoT_i < swi.analysis_cfg.gauss_pot_length; ul_PoT_i++) { + ul_BaseSpec = int(ul_PoT_i / ul_PoTsPerSpec); + // The spectrum bounding the current PoT bin. + ul_SubPoT_i = ul_PoT_i - ul_PoTsPerSpec * ul_BaseSpec; + // Relative to the start of the base spectrum. + // Powers pre-interpolation. + if (use_transposed_pot) { + f_BaseSpecPowerPerPoT = fp_PowerSpectrum[ul_PoT + * ul_NumSpectra + ul_BaseSpec] * f_Factor; + } else { + f_BaseSpecPowerPerPoT = fp_PowerSpectrum[ul_PoT + + ul_FftLength * ul_BaseSpec] * f_Factor; + } + if (ul_BaseSpec > 0) { + if (use_transposed_pot) { + f_AftSpecPowerPerPoT = fp_PowerSpectrum[ul_PoT + * ul_NumSpectra + (ul_BaseSpec-1)] * f_Factor; + } else { + f_AftSpecPowerPerPoT = fp_PowerSpectrum[ul_PoT + + ul_FftLength * (ul_BaseSpec-1)] * f_Factor; + } + } + if (ul_BaseSpec < ul_NumSpectra - 1) { + if (use_transposed_pot) { + f_ForwardSpecPowerPerPoT = fp_PowerSpectrum[ul_PoT + * ul_NumSpectra + (ul_BaseSpec+1)] * f_Factor; + } else { + f_ForwardSpecPowerPerPoT = fp_PowerSpectrum[ul_PoT + + ul_FftLength * (ul_BaseSpec+1)] * f_Factor; + } + } + + // Begin interpolation. + if (ul_SubPoT_i < ul_MidPoint) { + // Use the Aft spectrum if there is one. + // If not, use non-interpoated powers. + if (ul_BaseSpec == 0) { + fp_PoT[ul_PoT_i] = f_BaseSpecPowerPerPoT; + } else { + f_BaseWeight = (float)(ul_PoTsPerSpec - (ul_MidPoint - ul_SubPoT_i)) / ul_PoTsPerSpec; + fp_PoT[ul_PoT_i] = (f_BaseSpecPowerPerPoT * f_BaseWeight) + + (f_AftSpecPowerPerPoT * (1.0f - f_BaseWeight)); + } + } else { + // Use the Forward spectrum if there is one. + // If not, use non-interpoated powers. + if (ul_BaseSpec == ul_NumSpectra-1) { + fp_PoT[ul_PoT_i] = f_BaseSpecPowerPerPoT; + } else { + f_BaseWeight = (float)(ul_PoTsPerSpec - (ul_SubPoT_i - ul_MidPoint)) / ul_PoTsPerSpec; + fp_PoT[ul_PoT_i] = (f_BaseSpecPowerPerPoT * f_BaseWeight) + + (f_ForwardSpecPowerPerPoT * (1.0f - f_BaseWeight)); + } + } + } // end for ul_PoT_i < swi.analysis_cfg.gauss_pot_length + analysis_state.FLOP_counter+=(double)(9*swi.analysis_cfg.gauss_pot_length); + } + return 0; +} + +void ComputePoTInfo(int num_cfft, int NumDataPoints) { + + // Tis routine calculates various PoT values based on program constants + // and data contained in the current WU. + + // A note on "sigma", calculated here and used by the gaussian finder: + // The sigma calculated here is in units of PoT, ie, in bins of the + // Power Of Time arrays. Gaussian PoT arrays are of fixed length, given by + // GAUSS_POT_LEN. The basic definition of sigma here is that it is the + // amount of time it takes to cover 1/2 the half-power-beamwidth of the + // serendip feed. This is also a constant - BEAM_WIDTH - in units of + // degrees. We scan BEAM_WIDTH degrees at a given, but variable, slew rate. + + + double DegPerPotBin; // slew rate in degrees per PoT bin + int i, MinFftLen; + + // jeffc - is there really any need for these PoTInfo fields + // at this point? + PoTInfo.min_slew = swi.analysis_cfg.pot_min_slew; + PoTInfo.max_slew = swi.analysis_cfg.pot_max_slew; + PoTInfo.PulseOverlapFactor = swi.analysis_cfg.pot_overlap_factor; // ? + PoTInfo.PulseBeams = swi.analysis_cfg.pulse_beams; + PoTInfo.PulseThresh = swi.analysis_cfg.pulse_thresh; + PoTInfo.PulseMax = swi.analysis_cfg.pulse_max; + PoTInfo.PulseMin = swi.analysis_cfg.pulse_min; + PoTInfo.PulseFftMax = swi.analysis_cfg.pulse_fft_max; + PoTInfo.TripletThresh = swi.analysis_cfg.triplet_thresh; + PoTInfo.TripletMax = swi.analysis_cfg.triplet_max; + PoTInfo.TripletMin = swi.analysis_cfg.triplet_min; + PoTInfo.GaussChiSqThresh = swi.analysis_cfg.gauss_chi_sq_thresh; + PoTInfo.GaussPowerThresh = swi.analysis_cfg.gauss_power_thresh; + PoTInfo.GaussPeakPowerThresh = swi.analysis_cfg.gauss_peak_power_thresh; + + // Find the max fft length in the chirp/fft table + for(i = 1, MinFftLen = ChirpFftPairs[0].FftLen; i < num_cfft; i++) { + if(ChirpFftPairs[i].FftLen < MinFftLen) { + MinFftLen = ChirpFftPairs[i].FftLen; + } + } + + PoTInfo.MaxPoTLen = NumDataPoints / MinFftLen; + PoTInfo.WUDuration = (float)(swi.nsamples / swi.subband_sample_rate); + + // Here we calculate slew rate and slew related values. + // If there is no telescope movement, slew related values remain + // in their initialized state (zero). + if(swi.angle_range != 0.0) { + PoTInfo.SlewRate = (float)(swi.angle_range / PoTInfo.WUDuration); + PoTInfo.BeamRate = (float)(PoTInfo.SlewRate / swi.beam_width); + DegPerPotBin = swi.angle_range / swi.analysis_cfg.gauss_pot_length; + PoTInfo.GaussSigma = (float)((swi.beam_width/2.0f) / DegPerPotBin); + PoTInfo.GaussSigmaSq = PoTInfo.GaussSigma * PoTInfo.GaussSigma; + PoTInfo.GaussTOffsetStart = static_cast(floor(swi.analysis_cfg.pot_t_offset * PoTInfo.GaussSigma+0.5)); + PoTInfo.GaussTOffsetStop = swi.analysis_cfg.gauss_pot_length - PoTInfo.GaussTOffsetStart; + } +} + +void GetPulsePoTLen(long FullPoTLen, int * PulsePoTLen, int * PulseOverlap) { + + // This routine, given the time axis length of a WU in bins and data available + // in the PoTInfo struct, will calculate how many time bins to pass the pulse + // detectors for the given time axis length. Time axis length in seconds is + // is constant, while length in bins is inversely proportional to FFT length. + + // If slew rate is so low that, over the duration of the entire WU, + // we do not cover the number of beams passed to each call of the + // pulse finders then assume that we will be passing the entire PoT + // to the pulse finders. This also takes care of the case where slew + // rate is zero. Otherwise, calculate that portion of the PoT that + // we will be passing. + + // NOTE: the code calling this routine may be concerned with either pulse finding + // or triplet finding. There may be different max and/or min PoT length constraints + // between these 2 algorithms. Thus, this routine just returns the length that + // will contain PoTInfo.PulseBeams worth of data. It is up to the calling code + // to then apply any length constaints. + + double BinRate, // function of time resolution and slew rate + BinsPerBeam; // function of time res, slew rate, and beam width + + // jeffc - the following line in temporary. Pulse beams will go into the + // analysis config. + //PoTInfo.PulseBeams = 1.0; + + BinRate = FullPoTLen / PoTInfo.WUDuration; // in bins/second + + if(PoTInfo.BeamRate * PoTInfo.WUDuration < PoTInfo.PulseBeams) { + BinsPerBeam = (float)FullPoTLen; // slow slew - pass FullPoT + } else { + BinsPerBeam = BinRate / PoTInfo.BeamRate; // we will pass a portion of FullPoT + } + + *PulsePoTLen = IROUND(BinsPerBeam * PoTInfo.PulseBeams); // in bins + if(*PulsePoTLen > FullPoTLen) { + *PulsePoTLen = FullPoTLen; // pulse PoT longer than full PoT + } // ... so pass as much as we can + // ... ie the full PoT + + *PulseOverlap = IROUND(BinsPerBeam * PoTInfo.PulseOverlapFactor); // in bins + +#ifdef DEBUG_POT + + fprintf(stderr, "BinRate = %f\n", BinRate); + fprintf(stderr, "BinsPerBeam = %f\n", BinsPerBeam); +#endif + +} + diff --git a/client/analyzePoT.h b/client/analyzePoT.h new file mode 100644 index 0000000..a58d917 --- /dev/null +++ b/client/analyzePoT.h @@ -0,0 +1,89 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +// $Id: analyzePoT.h,v 1.5.2.2 2005/07/04 22:50:09 korpela Exp $ + +#include "chirpfft.h" +#define POT_INACTIVE 0 +#define POT_DOING_GAUSS 1 +#define POT_DOING_PULSE 2 + +extern double beam_width; + +typedef struct { + double WUDuration; // in seconds + double SlewRate; // degrees/second + double BeamRate; // beams/second + int MaxPoTLen; + + double GaussSigma; // in gaussian PoT bins + double GaussSigmaSq; // in gaussian PoT bins + int GaussTOffsetStart; // in gaussian PoT bins + int GaussTOffsetStop; // in gaussian PoT bins + double min_slew; + double max_slew; + double GaussChiSqThresh; // gaussian reporting thresh + double GaussPowerThresh; // PoT investigation thresh - in units + // of mean power across entire PoT + double GaussPeakPowerThresh; // gaussian investigation thresh - in + // units of mean power across PoT, + // exclusive of 2 sigma area on either + // side of gaussian peak + + double PulseOverlapFactor; // for both pulse and triplets + double PulseBeams; // for both pulse and triplets + + double PulseThresh; + int PulseMax; + int PulseMin; + int PulseFftMax; + + double TripletThresh; + int TripletMax; + int TripletMin; +} +PoTInfo_t; + +extern PoTInfo_t PoTInfo; + +int analyze_pot( + float * fp_PowerSpectrum, + int ul_NumDataPoints, + ChirpFftPair_t &cfft +); + +int GetFixedPoT( + float fp_PowerSpectrum[], + int ul_NumDataPoints, + int ul_FftLength, + float fp_PoT[], + int ul_PoTLen, + int ul_PoT +); + +void ComputePoTInfo(int num_cfft, int NumDataPoints); +void GetPulsePoTLen(long FullPoTLen, int * PulsePoTLen, int * PulseOverlap); diff --git a/client/analyzeReport.cpp b/client/analyzeReport.cpp new file mode 100644 index 0000000..a3c03e0 --- /dev/null +++ b/client/analyzeReport.cpp @@ -0,0 +1,447 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +// analyzeReport.C +// $Id: analyzeReport.cpp,v 1.40.2.9 2007/05/31 22:03:09 korpela Exp $ +// + +#include "sah_config.h" + +#include +#include +#include +#include +#include + +#include "diagnostics.h" +#include "util.h" +#include "s_util.h" +#ifdef BOINC_APP_GRAPHICS +#include "sah_gfx_main.h" +#endif + +#include "analyze.h" +#include "gaussfit.h" +#include "seti.h" +#include "chirpfft.h" +#include "analyzeReport.h" +#include "analyzePoT.h" + +#include "../db/schema_master.h" + +// outfile will be flushed at checkpoint time and just before +// normal program exit. +MFILE outfile; + +SPIKE_INFO * best_spike; +AUTOCORR_INFO * best_autocorr; +GAUSS_INFO * best_gauss; +PULSE_INFO * best_pulse; +TRIPLET_INFO * best_triplet; + +int signal_count = 0; +int spike_count = 0; +int autocorr_count = 0; +int pulse_count = 0; +int triplet_count = 0; +int gaussian_count = 0; + +void reload_graphics_state() { +#ifdef BOINC_APP_GRAPHICS + if (!nographics()) { + sah_graphics->si.copy(best_spike, true); + sah_graphics->ai.copy(best_autocorr, true); + sah_graphics->gi.copy(best_gauss, true); + sah_graphics->pi.copy(best_pulse, true); + sah_graphics->ti.copy(best_triplet, true); + } +#endif +} + +void reset_high_scores() { + if(best_spike) delete(best_spike); + if(best_autocorr) delete(best_autocorr); + if(best_gauss) delete(best_gauss); + if(best_pulse) delete(best_pulse); + if(best_triplet) delete(best_triplet); + + best_spike = new(SPIKE_INFO); + best_autocorr = new(AUTOCORR_INFO); + best_gauss = new(GAUSS_INFO); + best_gauss->score=-12; + best_pulse = new(PULSE_INFO); + best_triplet = new(TRIPLET_INFO); +} + +static double interpol(double x1,double y1,double x2,double y2, double x) { + double slope=(y2-y1)/(x2-x1); + return slope*(x-x1)+y1; +} + +void time_to_ra_dec(double time_jd, double *ra, double *dec) { + int i=0; + double raoffs=0; + + while ((i 12.0) { + raoffs=-24.0; + } + if ((swi.position_history[i].ra-swi.position_history[i+1].ra)> 12.0) { + raoffs=24.0; + } + + *ra=interpol( + swi.position_history[i].time, + swi.position_history[i].ra, + swi.position_history[i+1].time, + swi.position_history[i+1].ra+raoffs, + time_jd + ); + if (*ra<0) { + *ra+=24; + } else if (*ra>24) { + *ra-=24; + } + + *dec=interpol( + swi.position_history[i].time, + swi.position_history[i].dec, + swi.position_history[i+1].time, + swi.position_history[i+1].dec, + time_jd + ); +} + + +int result_spike(SPIKE_INFO &si) { + + int retval=0; + + if (signal_count >= swi.analysis_cfg.max_signals) { + SETIERROR(RESULT_OVERFLOW,"in result_spike"); + } + + retval = outfile.printf("%s", si.s.print_xml(0,0,1).c_str()); + + if (retval < 0) { + SETIERROR(WRITE_FAILED,"in result_spike"); + } else { + signal_count++; + spike_count++; + } + + return 0; +} + +int result_autocorr(AUTOCORR_INFO &ai) { + + int retval=0; + + if (signal_count >= swi.analysis_cfg.max_signals) { + SETIERROR(RESULT_OVERFLOW,"in result_autocorr"); + } + + retval = outfile.printf("%s", ai.a.print_xml(0,0,1).c_str()); + + if (retval < 0) { + SETIERROR(WRITE_FAILED,"in result_autocorr"); + } else { + signal_count++; + autocorr_count++; + } + + return 0; +} + +int result_gaussian(GAUSS_INFO &gi) { + + int retval=0; + + if (signal_count > swi.analysis_cfg.max_signals) { + SETIERROR(RESULT_OVERFLOW,"in result_gaussian"); + } + + retval = outfile.printf("%s", gi.g.print_xml(0,0,1).c_str()); + + if (retval >= 0) { + retval= outfile.printf("\n"); + } + + if (retval < 0) { + SETIERROR(WRITE_FAILED,"in result_gaussian"); + } else { + signal_count++; + gaussian_count++; + } + + return 0; +} + + +int ReportTripletEvent( + float Power, float MeanPower, float period, + float mid_time_bin, int start_time_bin, int freq_bin, + int pot_len,const float *PoT, int write_triplet +) { + TRIPLET_INFO ti; + triplet triplet; + int retval=0, i, j; + double step,norm,index; + double max_power=0; + static int * inv; + +// debug possible heap corruption -- jeffc +#ifdef _WIN32 +BOINCASSERT(_CrtCheckMemory()); +#endif + + if (!inv) inv = (int*)calloc_a(swi.analysis_cfg.triplet_pot_length, sizeof(int), MEM_ALIGN); + + // triplet info + ti.score=Power; + ti.t.peak_power=Power; + ti.t.mean_power=MeanPower; + ti.freq_bin=freq_bin; + ti.time_bin=mid_time_bin+start_time_bin+0.5f; + ti.t.chirp_rate=ChirpFftPairs[analysis_state.icfft].ChirpRate; + ti.t.fft_len=ChirpFftPairs[analysis_state.icfft].FftLen; + ti.bperiod=period; + ti.t.period=static_cast(period*static_cast(ti.t.fft_len)/swi.subband_sample_rate); + ti.t.freq=cnvt_bin_hz(freq_bin, ti.t.fft_len); + double t_offset=(static_cast(mid_time_bin)+start_time_bin+0.5) + *static_cast(ti.t.fft_len)/ + swi.subband_sample_rate; + ti.t.detection_freq=calc_detection_freq(ti.t.freq,ti.t.chirp_rate,t_offset); + ti.t.time=swi.time_recorded+t_offset/86400.0; + time_to_ra_dec(ti.t.time, &ti.t.ra, &ti.t.decl); + + // Populate the min and max PoT arrays. These are only used + // for graphics. + memset(ti.pot_min,0xff,swi.analysis_cfg.triplet_pot_length*sizeof(int)); + memset(ti.pot_max,0,swi.analysis_cfg.triplet_pot_length*sizeof(int)); + step=static_cast(pot_len)/swi.analysis_cfg.triplet_pot_length; + ti.scale=static_cast(1.0/step); + index=0; + for (i=0;imax_power) max_power=PoT[i]; + } + norm=255.0/max_power; + float mtb = mid_time_bin; + if (pot_len > swi.analysis_cfg.triplet_pot_length) { + ti.tpotind0_0 = ti.tpotind0_1 = static_cast(((mtb-period)*swi.analysis_cfg.triplet_pot_length)/pot_len); + ti.tpotind1_0 = ti.tpotind1_1 = static_cast(((mtb)*swi.analysis_cfg.triplet_pot_length)/pot_len); + ti.tpotind2_0 = ti.tpotind2_1 = static_cast(((mtb+period)*swi.analysis_cfg.triplet_pot_length)/pot_len); + for (j=0; j(floor(PoT[j]*norm)); + } + if ((PoT[j]*norm)>ti.pot_max[i]) { + ti.pot_max[i]=static_cast(floor(PoT[j]*norm)); + } + } + } else { + memset(inv, -1, sizeof(inv)); + for (i=0;i(floor(PoT[j]*norm)); + } + if ((PoT[j]*norm)>ti.pot_max[i]) { + ti.pot_max[i]=static_cast(floor(PoT[j]*norm)); + } + } + ti.tpotind0_0 = inv[static_cast(mtb-period)]; + ti.tpotind0_1 = inv[static_cast(mtb-period+1)]; + ti.tpotind1_0 = (inv[static_cast(mtb)]+inv[static_cast(mtb+1)])/2; + ti.tpotind1_1 = (inv[static_cast(mtb+1)]+inv[static_cast(mtb+2)])/2; + ti.tpotind2_0 = inv[static_cast(mtb+period)]; + if (mtb+period+1 >= pot_len) ti.tpotind2_1 = swi.analysis_cfg.triplet_pot_length-1; + else ti.tpotind2_1 = inv[static_cast(mtb+period+1)]; + } + + // Update sah_graphics triplet info regardless of whether it is the + // best thus far. If a triplet has made it this far, display it. +#ifdef BOINC_APP_GRAPHICS + if (!nographics()) sah_graphics->ti.copy(&ti); +#endif + + // best thus far ? + if (ti.score>best_triplet->score) { + *best_triplet=ti; + } + + + if (write_triplet) { + + if (signal_count > swi.analysis_cfg.max_signals) { + SETIERROR(RESULT_OVERFLOW,"in ReportTripletEvent"); + } + + retval = outfile.printf("%s", ti.t.print_xml(0,0,1).c_str()); + + if (retval < 0) { + SETIERROR(WRITE_FAILED,"in ReportTripletEvent"); + } else { + signal_count++; + triplet_count++; + } + + } + +// debug possible heap corruption -- jeffc +#ifdef _WIN32 +BOINCASSERT(_CrtCheckMemory()); +#endif + + return(retval); +} + +int ReportPulseEvent(float PulsePower,float MeanPower, float period, + int time_bin,int freq_bin, float snr, float thresh, float *folded_pot, + int scale, int write_pulse) { + PULSE_INFO pi; + pulse pulse; + int retval=0, i, len_prof=static_cast(floor(period)); + float step,norm,index,MinPower=PulsePower*MeanPower*scale; + +// debug possible heap corruption -- jeffc +#ifdef _WIN32 +BOINCASSERT(_CrtCheckMemory()); +#endif + + // pulse info + pi.score=snr/thresh; + pi.p.peak_power=PulsePower-1; + pi.p.mean_power=MeanPower; + pi.p.fft_len=ChirpFftPairs[analysis_state.icfft].FftLen; + pi.p.chirp_rate=ChirpFftPairs[analysis_state.icfft].ChirpRate; + pi.p.period=static_cast(period*static_cast(pi.p.fft_len)/swi.subband_sample_rate); + pi.p.snr = snr; + pi.p.thresh = thresh; + pi.p.len_prof = len_prof; + pi.freq_bin=freq_bin; + pi.time_bin=time_bin; + pi.p.freq=cnvt_bin_hz(freq_bin, pi.p.fft_len); + double t_offset=(static_cast(time_bin)+0.5) + *static_cast(pi.p.fft_len)/ + swi.subband_sample_rate; + pi.p.detection_freq=calc_detection_freq(pi.p.freq,pi.p.chirp_rate,t_offset); + pi.p.time=swi.time_recorded+t_offset/86400.0; + time_to_ra_dec(pi.p.time, &pi.p.ra, &pi.p.decl); + + for (i=0;i(len_prof)/swi.analysis_cfg.pulse_pot_length; + index=0; + for (i=0;i((folded_pot[static_cast(floor(index))+j]-MinPower)*norm); + if (pot= 256) pi.pot_min[i] = 255; // kludge until we fix the assert failures + BOINCASSERT(pi.pot_min[i] < 256); + if (pot>pi.pot_max[i]) + pi.pot_max[i]=pot; + if (pi.pot_max[i] >= 256) pi.pot_max[i] = 255; // kludge until we fix the assert failures + BOINCASSERT(pi.pot_max[i] < 256); + } + index+=step; + } + } +#endif + + // Populate the result PoT if the folded PoT will fit. + if (pi.p.len_prof < swi.analysis_cfg.pulse_pot_length) { + pi.p.pot.resize(len_prof); + for (i=0;ipi.copy(&pi); +#endif + + // best thus far ? + if (pi.score>best_pulse->score) { + *best_pulse=pi; + } + + if (write_pulse) { + + if (signal_count > swi.analysis_cfg.max_signals) { + SETIERROR(RESULT_OVERFLOW,"in ReportPulseEvent"); + } + + //for (i=0;i= 0) { + outfile.printf("\n"); + } + + if (retval < 0) { + SETIERROR(WRITE_FAILED,"in ReportPulseEvent"); + } else { + signal_count++; + pulse_count++; + } + + } + +// debug possible heap corruption -- jeffc +#ifdef _WIN32 +BOINCASSERT(_CrtCheckMemory()); +#endif + + + return(retval); +} + diff --git a/client/analyzeReport.h b/client/analyzeReport.h new file mode 100644 index 0000000..0340107 --- /dev/null +++ b/client/analyzeReport.h @@ -0,0 +1,105 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +// Title : analyzeReport.h +// $Id: analyzeReport.h,v 1.8.2.3 2007/05/31 22:03:09 korpela Exp $ + +#include + +#include "seti.h" +#include "boinc_api.h" +#include "mfile.h" + +int ReportEvents( + float * fp_PowerSpectrum, + int ul_NumDataPoints, + int us_FFT, + double spike_sigma_thresh + ); + +int ReportGaussEvent( + int ul_TOffset, + float f_PeakPower, + float f_TrueMean, + float f_SumSq, + int ul_PoT, + float sigma, + float f_PoTMaxPower, + float fp_PoT[] + ); + +int ReportPulseEvent( + float PulsePower, + float MeanPower, + float PulsePeriod, + int time_bin, + int freq_bin, + float snr, + float thresh, + float *foldedPOT, + int scale, + int write + ); + +int ReportTripletEvent( + float PulsePower, + float MeanPower, + float PulsePeriod, + float mid_time_bin, + int start_time_bin, + int freq_bin, + int pot_len, + const float *PoT, + int write + ); + +int result_spike(SPIKE_INFO &si); + +int result_autocorr(AUTOCORR_INFO &ai); + +int result_gaussian(GAUSS_INFO &gi); + +void time_to_ra_dec(double time_jd, double *ra, double *dec); + +extern void reset_high_scores(); + +//extern void report_init(); +extern void reload_graphics_state(); + +extern SPIKE_INFO * best_spike; +extern AUTOCORR_INFO * best_autocorr; +extern GAUSS_INFO * best_gauss; +extern PULSE_INFO * best_pulse; +extern TRIPLET_INFO * best_triplet; +extern MFILE outfile; + +extern int signal_count; +extern int autocorr_count; +extern int spike_count; +extern int pulse_count; +extern int gaussian_count; +extern int triplet_count; diff --git a/client/app_icon.h b/client/app_icon.h new file mode 100644 index 0000000..384686e --- /dev/null +++ b/client/app_icon.h @@ -0,0 +1,2152 @@ +char MacAppIconData[] = { + 0X69,0X63,0X6E,0X73,0X00,0X00,0X86,0X53,0X69,0X63,0X73,0X23,0X00,0X00,0X00,0X48, + 0X02,0X00,0X05,0X00,0X08,0X80,0X15,0X40,0XED,0XB8,0X80,0X08,0XC0,0X18,0X6F,0XB0, + 0X3F,0XE0,0X1F,0XC0,0X0F,0X80,0X1F,0XC0,0X38,0XE0,0X17,0X40,0X2F,0XA0,0X7F,0XF0, + 0X02,0X00,0X07,0X00,0X0F,0X80,0X1F,0XC0,0XFF,0XF8,0XFF,0XF8,0XFF,0XF8,0X7F,0XF0, + 0X3F,0XE0,0X1F,0XC0,0X0F,0X80,0X1F,0XC0,0X3F,0XE0,0X1F,0XC0,0X3F,0XE0,0X7F,0XF0, + 0X69,0X63,0X73,0X34,0X00,0X00,0X00,0X88,0X00,0X00,0X00,0XF0,0X00,0X00,0X00,0X00, + 0X00,0X00,0X0F,0X1F,0X00,0X00,0X00,0X00,0X00,0X00,0XF1,0X11,0XF0,0X00,0X00,0X00, + 0X00,0X0F,0X1F,0X1F,0X1F,0X00,0X00,0X00,0XFF,0XF1,0XFF,0X1F,0XF1,0XFF,0XF0,0X00, + 0XF1,0X11,0X11,0X11,0X11,0X11,0XF0,0X00,0XF9,0X81,0X81,0X81,0X81,0X89,0XF0,0X00, + 0X0F,0X98,0X88,0X88,0X88,0X9F,0X00,0X00,0X00,0XF9,0X89,0X99,0X89,0XF0,0X00,0X00, + 0X00,0X0F,0XF9,0X99,0XFF,0X00,0X00,0X00,0X00,0X00,0XF9,0XF9,0XF0,0X00,0X00,0X00, + 0X00,0X0F,0XF9,0X99,0XFF,0X00,0X00,0X00,0X00,0XFF,0X98,0X88,0X9F,0XF0,0X00,0X00, + 0X00,0X0F,0X89,0XF9,0X8F,0X00,0X00,0X00,0X00,0XF8,0XFF,0X9F,0XF8,0XF0,0X00,0X00, + 0X0F,0XFF,0XFF,0XFF,0XFF,0XFF,0X00,0X00,0X69,0X63,0X73,0X38,0X00,0X00,0X01,0X08, + 0X00,0X00,0X00,0X00,0X00,0X00,0XFF,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00, + 0X00,0X00,0X00,0X00,0X00,0XFF,0X28,0XFF,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00, + 0X00,0X00,0X00,0X00,0XFF,0X28,0X28,0X28,0XFF,0X00,0X00,0X00,0X00,0X00,0X00,0X00, + 0X00,0X00,0X00,0XFF,0X71,0XFF,0X28,0XFF,0X71,0XFF,0X00,0X00,0X00,0X00,0X00,0X00, + 0XFF,0XFF,0XFF,0X71,0XFF,0XFF,0X28,0XFF,0XFF,0X71,0XFF,0XFF,0XFF,0X00,0X00,0X00, + 0XFF,0X28,0X28,0X28,0X28,0X28,0X28,0X28,0X28,0X28,0X28,0X28,0XFF,0X00,0X00,0X00, + 0XFF,0XE8,0X9B,0X71,0X9B,0X71,0X9B,0X71,0X9B,0X71,0X9B,0XE8,0XFF,0X00,0X00,0X00, + 0X00,0XFF,0XE6,0X9B,0XE4,0XE4,0XE4,0XE4,0XE4,0X9B,0XE6,0XFF,0X00,0X00,0X00,0X00, + 0X00,0X00,0XFF,0XE8,0XE4,0XE6,0XE6,0XE6,0XE4,0XE8,0XFF,0X00,0X00,0X00,0X00,0X00, + 0X00,0X00,0X00,0XFF,0XE9,0XE8,0XE8,0XE8,0XE9,0XFF,0X00,0X00,0X00,0X00,0X00,0X00, + 0X00,0X00,0X00,0X00,0XFF,0XE8,0XFF,0XE8,0XFF,0X00,0X00,0X00,0X00,0X00,0X00,0X00, + 0X00,0X00,0X00,0XFF,0XE9,0XE6,0XE6,0XE6,0XE9,0XFF,0X00,0X00,0X00,0X00,0X00,0X00, + 0X00,0X00,0XFF,0XE9,0XE6,0X9B,0X9B,0X9B,0XE6,0XE9,0XFF,0X00,0X00,0X00,0X00,0X00, + 0X00,0X00,0X00,0XFF,0X9B,0XE6,0XFF,0XE6,0X9B,0XFF,0X00,0X00,0X00,0X00,0X00,0X00, + 0X00,0X00,0XFF,0X9B,0XFF,0XFF,0XE6,0XFF,0XFF,0X9B,0XFF,0X00,0X00,0X00,0X00,0X00, + 0X00,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X00,0X00,0X00,0X00, + 0X49,0X43,0X4E,0X23,0X00,0X00,0X01,0X08,0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X00,0X01, + 0XBF,0XFE,0XFF,0XFD,0XBF,0XFC,0X7F,0XFD,0XBF,0X7A,0XBF,0XF5,0XBF,0XF6,0XDF,0XFD, + 0XBF,0XEE,0XEF,0XFD,0XBF,0XDE,0XF7,0XFD,0XB8,0X00,0X00,0X3D,0XB8,0X00,0X00,0X3D, + 0XBC,0XAA,0XAA,0X7D,0XBD,0X55,0X55,0X7D,0XBE,0XFF,0XFE,0XFD,0XBF,0X7F,0XFD,0XFD, + 0XBF,0X9F,0XF3,0XFD,0XBF,0XE0,0X0F,0XFD,0XBE,0XF7,0XDF,0X7D,0XBF,0XF0,0X1F,0XFD, + 0XBF,0XFA,0XBF,0XFD,0XBF,0XF9,0X3F,0XFD,0XBF,0XF0,0X1F,0XFD,0XBF,0XF0,0X1F,0XFD, + 0XBF,0XED,0X6F,0XFD,0XBF,0XDE,0XF7,0XFD,0X80,0X00,0X00,0X01,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XE6,0X8B,0X03,0XFF,0XDD,0XDF,0XE7,0XF7,0XEC,0XDB,0XEF,0XE7,0XF5,0XDB,0XFF, + 0XC0,0XCE,0XDB,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X69,0X63,0X6C,0X34,0X00,0X00,0X02,0X08, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFC,0XCC,0XCC,0XCC,0XCC,0XCC,0XCC,0XCD,0XDD,0XDD,0XDD,0XDD,0XDD,0XDD,0XDD,0XEF, + 0XFC,0X66,0X66,0X66,0X66,0X66,0X66,0X60,0X66,0X66,0X66,0X66,0X66,0X66,0X66,0XEF, + 0XFC,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X11,0X1F,0XFF,0XFE,0XFF,0XFF,0XFF,0XFF,0XEF, + 0XFC,0X66,0X66,0X66,0XC6,0X66,0X61,0X91,0X91,0X66,0X66,0X66,0X66,0X66,0XC6,0XEF, + 0XFC,0XFF,0XFF,0XFF,0XFF,0XFF,0X19,0XF1,0XF9,0X1F,0XFF,0XFF,0XFF,0XFF,0XFF,0XEF, + 0XFC,0X6E,0X66,0X66,0X66,0X61,0X9F,0XF1,0XFF,0X91,0X66,0X66,0X66,0X66,0XF6,0XEF, + 0XFC,0XFF,0XFF,0XFF,0XFF,0X19,0XFF,0XF1,0XFF,0XF9,0X1F,0XFF,0XFF,0XFF,0XFF,0XEF, + 0XFC,0X66,0X61,0X11,0X11,0X11,0X11,0X11,0X11,0X11,0X11,0X11,0X11,0X66,0X66,0XEF, + 0XFC,0XFF,0XF1,0X88,0X88,0X88,0X88,0X88,0X88,0X88,0X88,0X88,0X81,0XFF,0XFF,0XEF, + 0XFC,0X66,0X69,0X18,0X98,0X98,0X98,0X98,0X98,0X98,0X98,0X98,0X89,0X66,0X66,0XEF, + 0XFC,0XFF,0XFF,0X89,0X89,0X89,0X89,0X89,0X89,0X89,0X89,0X89,0X8F,0XFF,0XFF,0XEF, + 0XFC,0X66,0X66,0X61,0X88,0X88,0X88,0X88,0X88,0X88,0X88,0X81,0X66,0X66,0X66,0XEF, + 0XFC,0XFF,0XFF,0XFF,0X89,0X99,0X99,0X99,0X99,0X99,0X99,0X8F,0XFF,0XFF,0XFF,0XEF, + 0XFC,0X66,0X66,0X66,0X68,0X99,0X99,0X99,0X99,0X99,0X98,0X66,0X66,0X66,0X66,0XEF, + 0XFD,0XFF,0XFF,0XFF,0XFF,0XF9,0X99,0X99,0X99,0X99,0XFF,0XFF,0XFF,0XFF,0XFF,0XEF, + 0XFD,0X66,0X66,0X6C,0X66,0X66,0X9F,0XFF,0XFF,0X96,0X66,0X66,0XC6,0X66,0X66,0XEF, + 0XFD,0XFF,0XFF,0XFF,0XFF,0XFF,0X99,0X99,0X99,0X9F,0XFF,0XFF,0XFF,0XFF,0XFF,0XEF, + 0XFD,0X66,0X66,0X66,0X66,0X66,0X69,0XF9,0XF9,0X66,0X66,0X66,0X66,0X66,0X66,0XEF, + 0XFD,0XFF,0XFF,0XFF,0XFF,0XFF,0XF9,0X9F,0X99,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XEF, + 0XFD,0X66,0XE6,0X66,0X66,0X66,0X99,0X99,0X99,0X96,0X66,0X66,0X66,0X6E,0X66,0XEF, + 0XFD,0XFF,0XFF,0XFF,0XFF,0XFF,0X89,0XFF,0XF9,0X8F,0XFF,0XFF,0XFF,0XFF,0XFF,0XEF, + 0XFD,0X66,0X66,0X66,0X66,0X68,0X9F,0X8F,0X8F,0X98,0X66,0X66,0X66,0X66,0X66,0XEF, + 0XFD,0XFF,0XFF,0XFF,0XFF,0X89,0XFF,0XF8,0XFF,0XF9,0X8F,0XFF,0XFF,0XFF,0XFF,0XEF, + 0XFE,0XEE,0XEE,0XEE,0XEE,0XEE,0XEE,0XEE,0XEE,0XEE,0XEE,0XEE,0XEE,0XEE,0XEE,0XEF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0X91,0X1F,0X91,0XF1,0X11,0XF1,0XF9,0X81,0X11,0X11,0X9F, + 0XFF,0XFF,0X9F,0XFF,0XFF,0X1F,0XFF,0X1F,0XFF,0X1F,0XF9,0XFF,0XFF,0XF1,0X19,0XFF, + 0XFF,0XF9,0X1F,0XFF,0XFF,0X91,0X9F,0X11,0XFF,0X1F,0XF1,0XFF,0XFF,0XF1,0X9F,0XFF, + 0XFF,0X91,0X1F,0XFF,0XFF,0XFF,0X1F,0X1F,0XFF,0X1F,0XF1,0XFF,0XFF,0XF9,0XFF,0XFF, + 0XF9,0X11,0X11,0X18,0X9F,0X11,0X9F,0X91,0XFF,0X1F,0XF1,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0X69,0X63,0X6C,0X38,0X00,0X00,0X04,0X08,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X2B,0X2B,0X2B,0X2B,0X2B,0XF7,0XF7, + 0XF7,0XF7,0XF7,0XF8,0XF8,0XF8,0XF8,0X56,0X56,0X56,0X56,0XF9,0XF9,0XF9,0XF9,0XFA, + 0XFA,0XFA,0XFA,0X81,0X81,0X81,0XAC,0XFF,0XFF,0X2B,0XD3,0XF1,0XF1,0XF1,0XF1,0XF1, + 0XF1,0XF1,0XF1,0XF1,0XF1,0XF1,0XF1,0X00,0XF1,0XF1,0XF1,0XF1,0XF1,0XF1,0XF1,0XF1, + 0XF1,0XF1,0XF1,0XF1,0XF1,0XD3,0XFD,0XFF,0XFF,0X2B,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X28,0X71,0X28,0XFF,0XFF,0XFF,0XFF,0XFC,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFD,0XFF,0XFF,0X2B,0XD3,0XF1,0XF1,0XF1,0XF1,0XF1, + 0XF8,0XF1,0XF1,0XF1,0XF1,0X71,0XE6,0X71,0XE6,0X71,0XF1,0XF1,0XF1,0XF1,0XF1,0XF1, + 0XF1,0XF1,0XF1,0XF1,0XF8,0XD3,0XFD,0XFF,0XFF,0X2B,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0X28,0XE6,0XFF,0X71,0XFF,0XE6,0X28,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFD,0XFF,0XFF,0XF7,0XD3,0XFC,0XF1,0XF1,0XF1,0XF1, + 0XF1,0XF1,0XF1,0X71,0XE6,0XFF,0XFF,0X71,0XFF,0XFF,0XE6,0X71,0XF1,0XF1,0XF1,0XF1, + 0XF1,0XF1,0XF1,0XF1,0XF1,0XD3,0XFD,0XFF,0XFF,0XF7,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0X71,0XE6,0XFF,0XFF,0XFF,0X71,0XFF,0XFF,0XFF,0XE6,0X71,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFD,0XFF,0XFF,0XF7,0XD3,0XF1,0XF1,0X28,0X28,0X28, + 0X28,0X28,0X28,0X28,0X28,0X28,0X28,0X28,0X28,0X28,0X28,0X28,0X28,0X28,0X28,0X28, + 0X28,0X28,0XF1,0XF1,0XF1,0XD3,0XFD,0XFF,0XFF,0XF7,0XFF,0XFF,0XFF,0X71,0X9B,0X9B, + 0X9B,0X9B,0X9B,0X9B,0X9B,0X9B,0X9B,0X9B,0X9B,0X9B,0X9B,0X9B,0X9B,0X9B,0X9B,0X9B, + 0X9B,0X71,0XFF,0XFF,0XFF,0XFF,0XFD,0XFF,0XFF,0XF7,0XD3,0XF1,0XF1,0XE8,0X71,0X9B, + 0XE6,0X9B,0XE6,0X9B,0XE6,0X9B,0XE6,0X9B,0XE6,0X9B,0XE6,0X9B,0XE6,0X9B,0XE6,0X9B, + 0X9B,0XE8,0XF1,0XF1,0XF1,0XD3,0XFD,0XFF,0XFF,0XF8,0XFF,0XFF,0XFF,0XFF,0X9B,0XE6, + 0XE4,0XE6,0XE4,0XE6,0XE4,0XE6,0XE4,0XE6,0XE4,0XE6,0XE4,0XE6,0XE4,0XE6,0XE4,0XE6, + 0X9B,0XFF,0XFF,0XFF,0XFF,0XFF,0XFD,0XFF,0XFF,0XF8,0XD3,0XF1,0XF1,0XF1,0XF1,0X71, + 0XE4,0XE4,0XE4,0XE4,0XE4,0XE4,0XE4,0XE4,0XE4,0XE4,0XE4,0XE4,0XE4,0XE4,0XE4,0X71, + 0XF1,0XF1,0XF1,0XF1,0XF1,0XD3,0XFD,0XFF,0XFF,0XF8,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0X9B,0XE6,0XE6,0XE6,0XE6,0XE6,0XE6,0XE6,0XE6,0XE6,0XE6,0XE6,0XE6,0XE6,0X9B,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFD,0XFF,0XFF,0XF8,0XD3,0XF1,0XF1,0XF1,0XF1,0XF1, + 0XF1,0XE4,0XE6,0XE6,0XE6,0XE6,0XE6,0XE6,0XE6,0XE6,0XE6,0XE6,0XE6,0XE4,0XF1,0XF1, + 0XF1,0XF1,0XF1,0XF1,0XF1,0XD3,0XFD,0XFF,0XFF,0X56,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XE9,0XE6,0XE8,0XE8,0XE8,0XE8,0XE8,0XE8,0XE8,0XE6,0XE9,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFD,0XFF,0XFF,0X56,0XD3,0XF1,0XF1,0XF1,0XF1,0XF8, + 0XF1,0XF1,0XF1,0XF1,0XE6,0XE9,0XE9,0XE9,0XE9,0XE9,0XE6,0XF1,0XF1,0XF1,0XF1,0XF1, + 0XF8,0XF1,0XF1,0XF1,0XF1,0XD3,0XFD,0XFF,0XFF,0X56,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XE6,0XE6,0XE6,0XE6,0XE6,0XE6,0XE6,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFD,0XFF,0XFF,0X56,0XD3,0XF1,0XF1,0XF1,0XF1,0XF1, + 0XF1,0XF1,0XF1,0XF1,0XF1,0XE6,0XE9,0XE7,0XE9,0XE6,0XF1,0XF1,0XF1,0XF1,0XF1,0XF1, + 0XF1,0XF1,0XF1,0XF1,0XF1,0XD3,0XFD,0XFF,0XFF,0XF9,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XE6,0XE7,0XE9,0XE7,0XE6,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFD,0XFF,0XFF,0XF9,0XD3,0XF1,0XFC,0XF1,0XF1,0XF1, + 0XF1,0XF1,0XF1,0XF1,0XE6,0XE6,0XE6,0XE6,0XE6,0XE6,0XE6,0XF1,0XF1,0XF1,0XF1,0XF1, + 0XF1,0XF1,0XF1,0XFC,0XF1,0XD3,0XFD,0XFF,0XFF,0XF9,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0X9B,0XE6,0XFF,0XFF,0XFF,0XE6,0X9B,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFD,0XFF,0XFF,0XF9,0XD3,0XF1,0XF1,0XF1,0XF1,0XF1, + 0XF1,0XF1,0XF1,0X9B,0XE6,0XFF,0X9B,0XFF,0X9B,0XFF,0XE6,0X9B,0XF1,0XF1,0XF1,0XF1, + 0XF1,0XF1,0XF1,0XF1,0XF1,0XD3,0XFD,0XFF,0XFF,0XFA,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0X9B,0XE6,0XFF,0XFF,0XFF,0X9B,0XFF,0XFF,0XFF,0XE6,0X9B,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFD,0XFF,0XFF,0XAC,0XFD,0XFD,0XFD,0XFD,0XFD,0XFD, + 0XFD,0XFD,0XFD,0XFD,0XFD,0XFD,0XFD,0XFD,0XFD,0XFD,0XFD,0XFD,0XFD,0XFD,0XFD,0XFD, + 0XFD,0XFD,0XFD,0XFD,0XFD,0XFD,0XFD,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XE5,0X71,0X71,0XFF,0XE5,0X71,0XFF,0X71,0X71,0X71,0XFF,0X71,0XE8,0XE6, + 0XE4,0X71,0X4C,0X4C,0X27,0X02,0XE8,0XFF,0XFF,0XFF,0XFF,0XFF,0XE8,0XFF,0XFF,0XFF, + 0XFF,0XFF,0X71,0XFF,0XFF,0XFF,0X71,0XFF,0XFF,0XFF,0X71,0XFF,0XFF,0XE8,0XFF,0XFF, + 0XFF,0XFF,0XFF,0X4C,0X27,0XE8,0XFF,0XFF,0XFF,0XFF,0XFF,0XE8,0X4C,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XE7,0X71,0XE7,0XFF,0X71,0X71,0XFF,0XFF,0X71,0XFF,0XFF,0X71,0XFF,0XFF, + 0XFF,0XFF,0XFF,0X4C,0XE8,0XFF,0XFF,0XFF,0XFF,0XFF,0XE8,0X27,0X4C,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0X71,0XFF,0X71,0XFF,0XFF,0XFF,0X71,0XFF,0XFF,0X71,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XE8,0XFF,0XFF,0XFF,0XFF,0XFF,0XE8,0X02,0X27,0X4C,0X4C,0X71,0XE4, + 0XE6,0XFF,0X71,0X71,0XE5,0XFF,0XE5,0X71,0XFF,0XFF,0X71,0XFF,0XFF,0X71,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X69,0X74,0X33,0X32,0X00,0X00,0X3D,0X53, + 0X00,0X00,0X00,0X00,0XFF,0X00,0XFF,0X00,0XFC,0X00,0X02,0XE9,0XE2,0XCE,0XF1,0XC3, + 0X02,0XB4,0X8E,0X69,0X83,0X00,0X02,0XE2,0XDD,0XC6,0XF1,0XB4,0X02,0X9B,0X6C,0X4D, + 0X83,0X00,0X02,0XCE,0XC6,0XA8,0XF1,0X91,0X02,0X75,0X55,0X37,0X83,0X00,0X02,0XC3, + 0XB4,0X91,0XF1,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XF1,0X00, + 0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XF1,0X00,0X02,0X67,0X48,0X30, + 0X83,0X00,0X02,0XC3,0XB4,0X91,0XB4,0X00,0X01,0XFF,0XFF,0XB8,0X00,0X02,0X67,0X48, + 0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XB2,0X00,0X00,0X2A,0X81,0XFF,0X00,0X2A,0XA9, + 0X00,0X00,0X02,0X89,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XB1, + 0X00,0X01,0X38,0XEE,0X81,0XFF,0X01,0XEE,0X38,0XA8,0X00,0X03,0X04,0X07,0X04,0X03, + 0X86,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X9C,0X00,0X80,0X01, + 0X8E,0X00,0X02,0X38,0XEE,0XF6,0X81,0XFF,0X02,0XF6,0XEE,0X38,0XA5,0X00,0X05,0X02, + 0X12,0X1C,0X24,0X17,0X08,0X86,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4, + 0X91,0X9C,0X00,0X03,0X0B,0X25,0X22,0X09,0X8C,0X00,0X03,0X37,0XE9,0XF1,0XF8,0X81, + 0XFA,0X03,0XF8,0XF1,0XE9,0X37,0XA3,0X00,0X07,0X03,0X0D,0X3B,0X6B,0X7A,0X57,0X1F, + 0X05,0X85,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X9B,0X00,0X05, + 0X05,0X33,0X93,0X8C,0X30,0X02,0X8A,0X00,0X04,0X36,0XE4,0XEB,0XF2,0XEF,0X81,0XF4, + 0X04,0XEF,0XF2,0XEB,0XE4,0X36,0XA2,0X00,0X08,0X07,0X23,0X6D,0XB7,0XC8,0X9B,0X43, + 0X0B,0X02,0X84,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X9B,0X00, + 0X05,0X05,0X4F,0XC1,0XB9,0X49,0X05,0X89,0X00,0X05,0X34,0XDC,0XE4,0XEA,0XE7,0X76, + 0X81,0XEC,0X05,0X76,0XE7,0XEA,0XE4,0XDC,0X34,0XA1,0X00,0X07,0X07,0X2B,0X82,0XCA, + 0XD9,0XB0,0X53,0X11,0X85,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91, + 0X9B,0X00,0X05,0X01,0X20,0X5A,0X56,0X1A,0X03,0X88,0X00,0X06,0X32,0XD5,0XDC,0XE2, + 0XE0,0X72,0X00,0X81,0XE4,0X06,0X00,0X72,0XE0,0XE2,0XDC,0XD5,0X32,0XA0,0X00,0X07, + 0X02,0X1D,0X60,0XA3,0XB5,0X89,0X39,0X0A,0X85,0X00,0X02,0X67,0X48,0X30,0X83,0X00, + 0X02,0XC3,0XB4,0X91,0X9C,0X00,0X02,0X07,0X06,0X08,0X89,0X00,0X07,0X30,0XCC,0XD3, + 0XD9,0XD7,0X6D,0X00,0X00,0X81,0XDB,0X07,0X00,0X00,0X6D,0XD7,0XD9,0XD3,0XCC,0X30, + 0X9F,0X00,0X07,0X01,0X0C,0X26,0X4D,0X58,0X3D,0X15,0X02,0X85,0X00,0X02,0X67,0X48, + 0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XAA,0X00,0X05,0X2E,0XC4,0XCB,0XD0,0XCE,0X69, + 0X80,0X00,0X81,0XD2,0X80,0X00,0X05,0X69,0XCE,0XD0,0XCB,0XC4,0X2E,0X9F,0X00,0X05, + 0X01,0X06,0X10,0X12,0X0B,0X03,0X86,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3, + 0XB4,0X91,0XA9,0X00,0X05,0X2C,0XBB,0XC1,0XC6,0XC4,0X64,0X81,0X00,0X81,0XC8,0X81, + 0X00,0X05,0X64,0XC4,0XC6,0XC1,0XBB,0X2C,0X9F,0X00,0X03,0X07,0X01,0X02,0X04,0X87, + 0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XA8,0X00,0X05,0X2A,0XB2, + 0XB8,0XBE,0XBB,0X5F,0X82,0X00,0X81,0XBF,0X82,0X00,0X05,0X5F,0XBB,0XBE,0XB8,0XB2, + 0X2A,0XAC,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XA7,0X00,0X05, + 0X28,0XAA,0XB0,0XB5,0XB2,0X5B,0X83,0X00,0X81,0XB6,0X83,0X00,0X05,0X5B,0XB2,0XB5, + 0XB0,0XAA,0X28,0XAB,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XA6, + 0X00,0X05,0X26,0XA1,0XA7,0XAC,0XAA,0X54,0X84,0X00,0X81,0XAD,0X84,0X00,0X05,0X54, + 0XAA,0XAC,0XA7,0XA1,0X26,0XAA,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4, + 0X91,0X81,0X00,0X05,0X01,0X01,0X07,0X04,0X04,0X01,0X9B,0X00,0X05,0X24,0X99,0X9E, + 0XA3,0XA1,0X50,0X85,0X00,0X81,0XA4,0X85,0X00,0X05,0X50,0XA1,0XA3,0X9E,0X99,0X24, + 0XA9,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X80,0X00,0X07,0X01, + 0X06,0X12,0X21,0X1E,0X11,0X04,0X01,0X99,0X00,0X05,0X22,0X91,0X96,0X9A,0X98,0X4B, + 0X86,0X00,0X81,0X9B,0X86,0X00,0X05,0X4B,0X98,0X9A,0X96,0X91,0X22,0XA8,0X00,0X02, + 0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X80,0X00,0X07,0X04,0X15,0X3B,0X5A, + 0X55,0X32,0X10,0X02,0X98,0X00,0X05,0X20,0X88,0X8D,0X91,0X8F,0X47,0X87,0X00,0X81, + 0X92,0X87,0X00,0X05,0X47,0X8F,0X91,0X8D,0X88,0X20,0XA7,0X00,0X02,0X67,0X48,0X30, + 0X83,0X00,0X02,0XC3,0XB4,0X91,0X80,0X00,0X08,0X08,0X26,0X63,0X88,0X81,0X4F,0X1A, + 0X03,0X01,0X96,0X00,0X05,0X1E,0X7F,0X83,0X87,0X85,0X42,0X88,0X00,0X81,0X88,0X88, + 0X00,0X05,0X42,0X85,0X87,0X83,0X7F,0X1E,0XA6,0X00,0X02,0X67,0X48,0X30,0X83,0X00, + 0X0D,0XC3,0XB4,0X91,0X00,0X00,0X01,0X07,0X29,0X65,0X8B,0X83,0X51,0X1B,0X04,0X96, + 0X00,0X05,0X1C,0X77,0X7B,0X7E,0X7D,0X3E,0X89,0X00,0X81,0X7F,0X89,0X00,0X05,0X3E, + 0X7D,0X7E,0X7B,0X77,0X1C,0XA5,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4, + 0X91,0X80,0X00,0X07,0X04,0X1A,0X43,0X61,0X59,0X33,0X10,0X04,0X95,0X00,0X05,0X1A, + 0X6E,0X72,0X75,0X74,0X39,0X8A,0X00,0X81,0X76,0X8A,0X00,0X05,0X39,0X74,0X75,0X72, + 0X6E,0X1A,0XA4,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X80,0X00, + 0X07,0X01,0X08,0X18,0X25,0X22,0X12,0X04,0X01,0X94,0X00,0X05,0X18,0X67,0X6A,0X6D, + 0X6C,0X35,0X8B,0X00,0X81,0X6E,0X8B,0X00,0X05,0X35,0X6C,0X6D,0X6A,0X67,0X18,0XA3, + 0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X81,0X00,0X05,0X01,0X05, + 0X06,0X07,0X02,0X01,0X94,0X00,0X05,0X16,0X5F,0X62,0X65,0X64,0X32,0X8C,0X00,0X81, + 0X66,0X8C,0X00,0X05,0X32,0X64,0X65,0X62,0X5F,0X16,0XA2,0X00,0X02,0X67,0X48,0X30, + 0X83,0X00,0X02,0XC3,0XB4,0X91,0X82,0X00,0X00,0X01,0X97,0X00,0X05,0X15,0X5A,0X5D, + 0X5F,0X5E,0X2F,0X8D,0X00,0X81,0X60,0X8D,0X00,0X05,0X2F,0X5E,0X5F,0X5D,0X5A,0X15, + 0XA1,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X89,0X00,0XD6,0XFF, + 0X8C,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X89,0X00,0X00,0XCB, + 0XD4,0XCC,0X00,0XCB,0X8C,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91, + 0X89,0X00,0X02,0XC5,0XCC,0XB8,0XD0,0XB7,0X02,0XB8,0XCC,0XC5,0X8C,0X00,0X02,0X67, + 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X89,0X00,0X02,0XB4,0XC8,0X9E,0XD0,0X99, + 0X02,0X9E,0XC8,0XB4,0X8C,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91, + 0X89,0X00,0X02,0X9E,0XC4,0X88,0XD0,0X79,0X02,0X88,0XC4,0X9E,0X8C,0X00,0X02,0X67, + 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X89,0X00,0X02,0X82,0XBF,0X7B,0XD0,0X5B, + 0X02,0X7B,0XBF,0X82,0X8C,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91, + 0X89,0X00,0X02,0X65,0XBA,0X75,0XD0,0X3A,0X02,0X75,0XBA,0X65,0X8C,0X00,0X02,0X67, + 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X89,0X00,0X02,0X44,0XB4,0X7A,0XD0,0X1B, + 0X02,0X7A,0XB4,0X44,0X8C,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91, + 0X89,0X00,0X03,0X21,0XAB,0X8D,0X06,0X81,0X04,0X00,0X02,0X84,0X04,0X00,0X02,0X84, + 0X04,0X00,0X02,0X84,0X04,0X00,0X02,0X84,0X04,0X00,0X02,0X84,0X04,0X00,0X02,0X84, + 0X04,0X00,0X02,0X84,0X04,0X00,0X02,0X84,0X04,0X00,0X02,0X84,0X04,0X00,0X02,0X81, + 0X04,0X03,0X06,0X8D,0XAB,0X21,0X8C,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3, + 0XB4,0X91,0X8A,0X00,0X02,0X7E,0XA6,0X28,0XCE,0X00,0X02,0X28,0XA6,0X7E,0X8D,0X00, + 0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X8A,0X00,0X02,0X52,0X9F,0X4D, + 0XCE,0X00,0X02,0X4D,0X9F,0X52,0X8D,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3, + 0XB4,0X91,0X8A,0X00,0X03,0X28,0X97,0X70,0X01,0XCC,0X00,0X03,0X01,0X70,0X97,0X28, + 0X8D,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X8B,0X00,0X02,0X65, + 0X91,0X1A,0XCC,0X00,0X02,0X1A,0X91,0X65,0X8E,0X00,0X02,0X67,0X48,0X30,0X83,0X00, + 0X02,0XC3,0XB4,0X91,0X8B,0X00,0X02,0X36,0X89,0X3F,0XCC,0X00,0X02,0X3F,0X89,0X36, + 0X8E,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X8B,0X00,0X03,0X0A, + 0X60,0X78,0X13,0XCA,0X00,0X03,0X22,0X78,0X60,0X0A,0X8E,0X00,0X02,0X67,0X48,0X30, + 0X83,0X00,0X02,0XC3,0XB4,0X91,0X8C,0X00,0X02,0X31,0X7B,0X4A,0XCA,0X00,0X02,0X4A, + 0X7B,0X31,0X8F,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X8C,0X00, + 0X03,0X05,0X4D,0X6D,0X1E,0XC8,0X00,0X03,0X1E,0X6D,0X4D,0X05,0X8F,0X00,0X02,0X67, + 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X8D,0X00,0X03,0X1F,0X61,0X47,0X09,0XC6, + 0X00,0X03,0X09,0X47,0X61,0X1F,0X90,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3, + 0XB4,0X91,0X8E,0X00,0X02,0X32,0X66,0X34,0XC6,0X00,0X02,0X34,0X66,0X32,0X91,0X00, + 0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X8E,0X00,0X03,0X07,0X3D,0X58, + 0X22,0XC4,0X00,0X03,0X22,0X58,0X3D,0X07,0X91,0X00,0X02,0X67,0X48,0X30,0X83,0X00, + 0X02,0XC3,0XB4,0X91,0X8F,0X00,0X03,0X12,0X44,0X47,0X15,0XC2,0X00,0X03,0X15,0X47, + 0X44,0X12,0X92,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X90,0X00, + 0X03,0X18,0X44,0X39,0X0D,0XC0,0X00,0X03,0X0D,0X39,0X44,0X18,0X93,0X00,0X02,0X67, + 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X91,0X00,0X03,0X1A,0X40,0X30,0X0A,0XBE, + 0X00,0X03,0X0A,0X30,0X40,0X1A,0X94,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3, + 0XB4,0X91,0X92,0X00,0X03,0X19,0X3A,0X2A,0X09,0XBC,0X00,0X03,0X09,0X2A,0X3A,0X19, + 0X95,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X93,0X00,0X03,0X14, + 0X30,0X27,0X0B,0XBA,0X00,0X03,0X0B,0X27,0X30,0X14,0X96,0X00,0X02,0X67,0X48,0X30, + 0X83,0X00,0X02,0XC3,0XB4,0X91,0X94,0X00,0X03,0X0F,0X27,0X25,0X0D,0XB8,0X00,0X03, + 0X0D,0X25,0X27,0X0F,0X97,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91, + 0X95,0X00,0X03,0X08,0X1C,0X25,0X11,0XB6,0X00,0X03,0X11,0X25,0X1C,0X08,0X98,0X00, + 0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X96,0X00,0X04,0X02,0X12,0X20, + 0X14,0X04,0XB2,0X00,0X04,0X04,0X14,0X20,0X12,0X02,0X99,0X00,0X02,0X67,0X48,0X30, + 0X83,0X00,0X02,0XC3,0XB4,0X91,0X98,0X00,0X03,0X09,0X15,0X10,0X03,0XB0,0X00,0X03, + 0X03,0X10,0X15,0X09,0X9B,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91, + 0X99,0X00,0X04,0X02,0X0A,0X11,0X08,0X01,0XAC,0X00,0X09,0X01,0X08,0X11,0X0A,0X02, + 0X00,0X01,0X00,0X00,0X01,0X97,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4, + 0X91,0X9B,0X00,0X04,0X03,0X09,0X0D,0X09,0X03,0XA8,0X00,0X07,0X03,0X09,0X0D,0X09, + 0X03,0X01,0X00,0X00,0X81,0X01,0X97,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3, + 0XB4,0X91,0X9D,0X00,0X04,0X02,0X06,0X09,0X07,0X02,0XA4,0X00,0X11,0X02,0X07,0X09, + 0X06,0X02,0X00,0X01,0X01,0X00,0X03,0X02,0X02,0X01,0X01,0X03,0X01,0X00,0X01,0X93, + 0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X9F,0X00,0X04,0X01,0X03, + 0X04,0X05,0X03,0XA0,0X00,0X13,0X03,0X05,0X04,0X03,0X01,0X01,0X00,0X00,0X02,0X02, + 0X03,0X03,0X06,0X05,0X05,0X04,0X03,0X01,0X01,0X02,0X93,0X00,0X02,0X67,0X48,0X30, + 0X83,0X00,0X02,0XC3,0XB4,0X91,0XA2,0X00,0X00,0X01,0X80,0X02,0X00,0X01,0X9A,0X00, + 0X00,0X01,0X80,0X02,0X00,0X01,0X81,0X00,0X05,0X01,0X01,0X03,0X03,0X06,0X08,0X80, + 0X09,0X06,0X07,0X05,0X03,0X02,0X01,0X02,0X01,0X91,0X00,0X02,0X67,0X48,0X30,0X83, + 0X00,0X02,0XC3,0XB4,0X91,0XCC,0X00,0X10,0X01,0X02,0X03,0X06,0X09,0X0C,0X0F,0X11, + 0X11,0X0F,0X0C,0X0B,0X06,0X04,0X01,0X00,0X01,0X91,0X00,0X02,0X67,0X48,0X30,0X83, + 0X00,0X02,0XC3,0XB4,0X91,0XAA,0X00,0X03,0X01,0X02,0X01,0X02,0X81,0X01,0X84,0X00, + 0X81,0X01,0X03,0X02,0X01,0X02,0X01,0X86,0X00,0X12,0X01,0X01,0X02,0X02,0X04,0X09, + 0X0E,0X13,0X1D,0X21,0X22,0X1C,0X18,0X10,0X0B,0X08,0X03,0X02,0X01,0X91,0X00,0X02, + 0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XCB,0X00,0X11,0X01,0X03,0X03,0X08, + 0X0D,0X14,0X1F,0X36,0X47,0X51,0X40,0X2B,0X19,0X0F,0X09,0X05,0X00,0X02,0X91,0X00, + 0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XCC,0X00,0X11,0X02,0X06,0X0A, + 0X12,0X1C,0X39,0X66,0X96,0XA3,0X83,0X4B,0X27,0X15,0X0E,0X09,0X03,0X01,0X01,0X90, + 0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XCA,0X00,0X13,0X01,0X01, + 0X03,0X06,0X0C,0X14,0X25,0X4A,0X97,0XD1,0XDD,0XBC,0X6E,0X34,0X1E,0X0F,0X09,0X05, + 0X02,0X02,0X90,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XCC,0X00, + 0X11,0X03,0X07,0X0E,0X18,0X29,0X56,0XA4,0XDD,0XE8,0XCB,0X7B,0X38,0X1F,0X11,0X09, + 0X05,0X03,0X02,0X90,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XCA, + 0X00,0X13,0X02,0X02,0X03,0X06,0X0D,0X15,0X25,0X49,0X86,0XBE,0XCB,0XA9,0X66,0X32, + 0X1A,0X12,0X09,0X04,0X03,0X01,0X90,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3, + 0XB4,0X91,0XCB,0X00,0X11,0X02,0X01,0X07,0X0B,0X14,0X1F,0X33,0X52,0X74,0X7D,0X64, + 0X40,0X25,0X1A,0X0F,0X09,0X03,0X01,0X91,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02, + 0XC3,0XB4,0X91,0X86,0X00,0X0E,0X01,0X00,0X00,0X01,0X00,0X02,0X01,0X01,0X02,0X01, + 0X02,0X02,0X01,0X01,0X02,0X80,0X01,0XB0,0X00,0X12,0X01,0X02,0X04,0X09,0X0F,0X18, + 0X21,0X2E,0X3B,0X3E,0X36,0X2A,0X1D,0X14,0X0C,0X07,0X03,0X00,0X02,0X90,0X00,0X02, + 0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X84,0X00,0X03,0X01,0X01,0X00,0X03, + 0X80,0X02,0X04,0X01,0X00,0X00,0X01,0X02,0X80,0X00,0X03,0X01,0X01,0X02,0X01,0XB1, + 0X00,0X12,0X01,0X02,0X03,0X06,0X0B,0X11,0X17,0X22,0X23,0X24,0X26,0X1B,0X14,0X0F, + 0X08,0X05,0X03,0X02,0X01,0X90,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4, + 0X91,0X83,0X00,0X10,0X01,0X01,0X02,0X03,0X03,0X04,0X03,0X03,0X04,0X03,0X00,0X02, + 0X01,0X00,0X00,0X01,0X01,0XB3,0X00,0X11,0X01,0X02,0X01,0X02,0X05,0X07,0X0B,0X0F, + 0X14,0X16,0X15,0X15,0X11,0X0E,0X09,0X06,0X03,0X02,0X92,0X00,0X02,0X67,0X48,0X30, + 0X83,0X00,0X02,0XC3,0XB4,0X91,0X81,0X00,0X05,0X01,0X01,0X02,0X03,0X04,0X07,0X80, + 0X08,0X03,0X07,0X05,0X04,0X02,0X80,0X01,0X80,0X00,0X00,0X01,0XB4,0X00,0X0E,0X02, + 0X01,0X01,0X04,0X06,0X08,0X0C,0X0D,0X0C,0X0C,0X09,0X07,0X04,0X04,0X03,0X93,0X00, + 0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X81,0X00,0X0E,0X03,0X01,0X04, + 0X07,0X0B,0X0D,0X0E,0X10,0X10,0X0D,0X0B,0X07,0X04,0X03,0X01,0XBA,0X00,0X04,0X02, + 0X01,0X03,0X04,0X05,0X80,0X06,0X05,0X07,0X06,0X03,0X03,0X01,0X01,0X86,0X00,0X00, + 0X01,0X89,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X81,0X00,0X10, + 0X01,0X04,0X07,0X0B,0X0F,0X16,0X18,0X1A,0X19,0X16,0X12,0X0E,0X08,0X05,0X03,0X00, + 0X01,0XBB,0X00,0X01,0X02,0X02,0X83,0X03,0X00,0X02,0X87,0X00,0X05,0X01,0X05,0X06, + 0X07,0X04,0X01,0X85,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X17,0XC3,0XB4,0X91,0X00, + 0X00,0X01,0X02,0X02,0X05,0X08,0X10,0X16,0X1F,0X25,0X28,0X25,0X22,0X1B,0X14,0X0B, + 0X08,0X05,0X02,0X01,0XBB,0X00,0X0A,0X01,0X02,0X01,0X02,0X01,0X01,0X00,0X01,0X00, + 0X01,0X01,0X84,0X00,0X07,0X01,0X03,0X0E,0X21,0X27,0X1A,0X09,0X02,0X84,0X00,0X02, + 0X67,0X48,0X30,0X83,0X00,0X17,0XC3,0XB4,0X91,0X00,0X00,0X01,0X00,0X04,0X06,0X0D, + 0X16,0X1F,0X29,0X33,0X37,0X34,0X2D,0X24,0X1A,0X10,0X09,0X06,0X03,0X01,0XBC,0X00, + 0X01,0X01,0X01,0X81,0X00,0X01,0X02,0X01,0X86,0X00,0X08,0X01,0X0E,0X30,0X5B,0X68, + 0X49,0X1B,0X05,0X03,0X83,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X16,0XC3,0XB4,0X91, + 0X00,0X01,0X01,0X02,0X04,0X08,0X11,0X1A,0X28,0X3B,0X6F,0X8C,0X5A,0X39,0X2B,0X20, + 0X14,0X0C,0X06,0X03,0XBD,0X00,0X00,0X01,0X8D,0X00,0X08,0X04,0X19,0X51,0X89,0X95, + 0X75,0X30,0X0A,0X01,0X83,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X17,0XC3,0XB4,0X91, + 0X00,0X00,0X01,0X03,0X06,0X09,0X12,0X1D,0X2D,0X5D,0XC3,0XE6,0X99,0X40,0X2F,0X23, + 0X17,0X0C,0X06,0X04,0X01,0X93,0X00,0X02,0X03,0X0E,0X05,0X93,0X00,0X02,0X04,0X0E, + 0X03,0X9B,0X00,0X08,0X04,0X1B,0X56,0X8D,0X99,0X7A,0X36,0X08,0X03,0X83,0X00,0X02, + 0X67,0X48,0X30,0X83,0X00,0X03,0XC3,0XB4,0X91,0X00,0X80,0X01,0X10,0X05,0X0A,0X11, + 0X1B,0X2A,0X5C,0XC1,0XE4,0X96,0X3F,0X30,0X22,0X16,0X0D,0X07,0X03,0X01,0X92,0X00, + 0X03,0X08,0X22,0X0B,0X04,0X93,0X00,0X03,0X0E,0X0E,0X22,0X09,0X99,0X00,0X08,0X01, + 0X03,0X0F,0X39,0X66,0X72,0X53,0X20,0X07,0X84,0X00,0X02,0X67,0X48,0X30,0X83,0X00, + 0X02,0XC3,0XB4,0X91,0X81,0X00,0X10,0X04,0X08,0X10,0X1A,0X25,0X3B,0X6C,0X89,0X57, + 0X38,0X2A,0X1F,0X13,0X0B,0X06,0X03,0X01,0X91,0X00,0X05,0X0D,0X39,0X12,0X07,0X3B, + 0X0E,0X91,0X00,0X05,0X1A,0X38,0X07,0X10,0X39,0X0E,0X99,0X00,0X06,0X01,0X04,0X12, + 0X28,0X2F,0X20,0X0A,0X85,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X16,0XC3,0XB4,0X91, + 0X00,0X00,0X01,0X02,0X03,0X07,0X0C,0X13,0X1D,0X28,0X30,0X34,0X30,0X2C,0X23,0X18, + 0X11,0X09,0X05,0X01,0X91,0X00,0X07,0X12,0X51,0X1A,0X00,0X00,0X14,0X54,0X14,0X8F, + 0X00,0X07,0X24,0X4F,0X0A,0X00,0X00,0X17,0X51,0X14,0X9A,0X00,0X04,0X03,0X07,0X0A, + 0X05,0X04,0X85,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X81,0X00, + 0X0E,0X03,0X05,0X0A,0X10,0X16,0X1D,0X22,0X25,0X24,0X20,0X1A,0X13,0X0B,0X08,0X03, + 0X91,0X00,0X02,0X16,0X65,0X21,0X81,0X00,0X02,0X19,0X69,0X19,0X8D,0X00,0X02,0X2E, + 0X63,0X0D,0X81,0X00,0X02,0X1D,0X65,0X19,0X9B,0X00,0X00,0X01,0X87,0X00,0X02,0X67, + 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X81,0X00,0X10,0X02,0X03,0X05,0X09,0X0E, + 0X11,0X16,0X19,0X18,0X15,0X10,0X0C,0X07,0X04,0X02,0X01,0X01,0X8E,0X00,0X02,0X1C, + 0X7D,0X29,0X83,0X00,0X02,0X1E,0X82,0X1E,0X8B,0X00,0X02,0X38,0X7A,0X0F,0X83,0X00, + 0X02,0X24,0X7D,0X1E,0XA5,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91, + 0X81,0X00,0X0E,0X01,0X01,0X04,0X05,0X07,0X0B,0X0D,0X0D,0X0E,0X0C,0X09,0X07,0X05, + 0X03,0X02,0X8F,0X00,0X02,0X21,0X93,0X30,0X85,0X00,0X02,0X24,0X9A,0X24,0X89,0X00, + 0X02,0X42,0X8E,0X12,0X85,0X00,0X02,0X2A,0X93,0X24,0XA4,0X00,0X02,0X67,0X48,0X30, + 0X83,0X00,0X02,0XC3,0XB4,0X91,0X81,0X00,0X0F,0X02,0X02,0X01,0X03,0X04,0X07,0X07, + 0X09,0X09,0X06,0X06,0X04,0X03,0X02,0X02,0X01,0X8D,0X00,0X02,0X26,0XA7,0X36,0X87, + 0X00,0X02,0X2A,0XAE,0X2A,0X87,0X00,0X02,0X4B,0XA1,0X15,0X87,0X00,0X02,0X30,0XAB, + 0X2A,0XA3,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X83,0X00,0X80, + 0X01,0X80,0X04,0X80,0X03,0X02,0X02,0X00,0X02,0X8E,0X00,0X02,0X29,0XB6,0X3B,0X89, + 0X00,0X02,0X2D,0XBD,0X2D,0X85,0X00,0X02,0X52,0XAE,0X16,0X89,0X00,0X02,0X34,0XBA, + 0X2D,0XA2,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X83,0X00,0X01, + 0X02,0X00,0X80,0X01,0X05,0X02,0X02,0X01,0X00,0X00,0X01,0X8E,0X00,0X02,0X29,0XB6, + 0X3B,0X8B,0X00,0X02,0X2D,0XBD,0X2D,0X83,0X00,0X02,0X52,0XAE,0X16,0X8B,0X00,0X02, + 0X34,0XBA,0X2D,0XA1,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X83, + 0X00,0X00,0X01,0X84,0X00,0X00,0X01,0X8F,0X00,0X02,0X29,0XB6,0X3B,0X8D,0X00,0X02, + 0X2D,0XBD,0X2D,0X81,0X00,0X02,0X52,0XAE,0X16,0X8D,0X00,0X02,0X34,0XBA,0X2D,0XA0, + 0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X9D,0X00,0X02,0X29,0XB6, + 0X3B,0X8F,0X00,0X07,0X2D,0XBD,0X2D,0X00,0X00,0X52,0XAE,0X16,0X8F,0X00,0X02,0X34, + 0XBA,0X2D,0X9F,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X9D,0X00, + 0X01,0X94,0X3B,0X91,0X00,0X05,0X2D,0X61,0X00,0X0F,0XA7,0X16,0X91,0X00,0X02,0X34, + 0XAA,0X04,0X9E,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XB4,0X9B,0X75,0XCE,0X67, + 0X00,0X69,0X9F,0X67,0X02,0X59,0X3F,0X30,0X83,0X00,0X02,0X8E,0X6C,0X55,0XAA,0X48, + 0X04,0X47,0X46,0X46,0X47,0X47,0XBF,0X48,0X02,0X3F,0X30,0X30,0X83,0X00,0X02,0X69, + 0X4D,0X37,0XA9,0X30,0X06,0X2F,0X2A,0X25,0X22,0X26,0X2B,0X2F,0XC1,0X30,0XFF,0X00, + 0XFF,0X00,0XFF,0X00,0XA2,0X00,0X02,0X06,0X22,0X2F,0X81,0X4A,0X01,0X36,0X0C,0X83, + 0X00,0X01,0X09,0X16,0X83,0X1B,0X82,0X00,0X8A,0X1B,0X83,0X00,0X80,0X4A,0X83,0X00, + 0X16,0X06,0X0F,0X19,0X24,0X2E,0X38,0X43,0X4D,0X56,0X5C,0X5C,0X5F,0X63,0X68,0X6D, + 0X73,0X78,0X7D,0X82,0X88,0X8D,0X92,0X96,0X81,0X99,0X00,0X46,0XA7,0X00,0X02,0X06, + 0X2F,0X5F,0X84,0X66,0X00,0X26,0X82,0X00,0X02,0X12,0X41,0X5F,0X83,0X66,0X82,0X00, + 0X8A,0X66,0X83,0X00,0X80,0X66,0X83,0X00,0X16,0X0A,0X19,0X2A,0X3C,0X4D,0X5D,0X6F, + 0X80,0X8F,0X99,0X99,0X9E,0XA5,0XAD,0XB6,0XBF,0XC8,0XD0,0XD9,0XE2,0XEB,0XF3,0XFA, + 0X80,0XFF,0X01,0XA7,0X05,0XA6,0X00,0X01,0X06,0X52,0X80,0X66,0X01,0X4A,0X37,0X80, + 0X2F,0X01,0X3D,0X28,0X81,0X00,0X02,0X08,0X40,0X5D,0X84,0X66,0X82,0X00,0X8A,0X66, + 0X83,0X00,0X80,0X66,0X83,0X00,0X1A,0X0A,0X19,0X2A,0X3C,0X4D,0X5D,0X6F,0X80,0X8F, + 0X99,0X99,0X9E,0XA5,0XAD,0XB6,0XBF,0XC8,0XD0,0XD9,0XE2,0XEB,0XF3,0XFA,0XFF,0XFF, + 0XA7,0X05,0XA7,0X00,0X04,0X44,0X66,0X66,0X44,0X06,0X88,0X00,0X04,0X16,0X5D,0X66, + 0X60,0X06,0X8C,0X00,0X02,0X4A,0X66,0X66,0X91,0X00,0X19,0X0A,0X19,0X2A,0X3C,0X4D, + 0X5D,0X6F,0X80,0X8F,0X99,0X99,0X9E,0XA5,0XAD,0XB6,0XBF,0XC8,0XD0,0XD9,0XE2,0XEB, + 0XF3,0XFA,0XFF,0XA7,0X05,0XA7,0X00,0X03,0X0D,0X66,0X66,0X4A,0X8A,0X00,0X03,0X1A, + 0X65,0X66,0X39,0X8D,0X00,0X02,0X4A,0X66,0X66,0X91,0X00,0X18,0X0A,0X19,0X2A,0X3C, + 0X4D,0X5D,0X6F,0X80,0X8F,0X99,0X99,0X9E,0XA5,0XAD,0XB6,0XBF,0XC8,0XD0,0XD9,0XE2, + 0XEB,0XF3,0XFA,0XA7,0X05,0XA8,0X00,0X03,0X2F,0X66,0X66,0X22,0X8A,0X00,0X03,0X1B, + 0X66,0X66,0X2F,0X8D,0X00,0X02,0X4A,0X66,0X66,0X91,0X00,0X17,0X0A,0X19,0X2A,0X3C, + 0X4D,0X5D,0X6F,0X80,0X8F,0X99,0X99,0X9E,0XA5,0XAD,0XB6,0XBF,0XC8,0XD0,0XD9,0XE2, + 0XEB,0XF3,0XA4,0X05,0XA9,0X00,0X03,0X2F,0X66,0X66,0X1B,0X8A,0X00,0X03,0X1B,0X66, + 0X66,0X2F,0X8D,0X00,0X02,0X4A,0X66,0X66,0X88,0X00,0X02,0X37,0X4A,0X4A,0X83,0X00, + 0X16,0X02,0X05,0X08,0X0C,0X10,0X13,0X16,0X1A,0X1D,0X1F,0X1F,0X37,0XA5,0XAD,0XB6, + 0XBF,0XC8,0XD0,0XD9,0XE2,0XEB,0X9F,0X05,0X98,0X00,0X01,0X03,0X09,0X8D,0X00,0X03, + 0X28,0X66,0X66,0X3D,0X8A,0X00,0X03,0X1B,0X66,0X66,0X2F,0X8D,0X00,0X02,0X4A,0X66, + 0X66,0X88,0X00,0X02,0X4A,0X66,0X66,0X8E,0X00,0X0A,0X1D,0XA5,0XAD,0XB6,0XBF,0XC8, + 0XD0,0XD9,0XE2,0X9A,0X05,0X98,0X00,0X02,0X03,0X6C,0X1D,0X8D,0X00,0X00,0X0D,0X80, + 0X66,0X00,0X2F,0X89,0X00,0X03,0X1B,0X66,0X66,0X2F,0X8D,0X00,0X02,0X4A,0X66,0X66, + 0X88,0X00,0X02,0X4A,0X66,0X66,0X8E,0X00,0X09,0X1D,0XA5,0XAD,0XB6,0XBF,0XC8,0XD0, + 0XD9,0X94,0X05,0X98,0X00,0X03,0X04,0X71,0XA5,0X1D,0X8E,0X00,0X00,0X37,0X80,0X66, + 0X01,0X4A,0X1B,0X87,0X00,0X03,0X1B,0X66,0X66,0X2F,0X8D,0X00,0X02,0X4A,0X66,0X66, + 0X88,0X00,0X02,0X4A,0X66,0X66,0X8E,0X00,0X08,0X1D,0XA5,0XAD,0XB6,0XBF,0XC8,0XD0, + 0X8E,0X04,0X98,0X00,0X04,0X04,0X77,0XAD,0XA5,0X1D,0X8F,0X00,0X00,0X3D,0X81,0X66, + 0X01,0X4A,0X1B,0X85,0X00,0X03,0X1B,0X66,0X66,0X59,0X83,0X4A,0X87,0X00,0X02,0X4A, + 0X66,0X66,0X88,0X00,0X02,0X4A,0X66,0X66,0X8E,0X00,0X07,0X1D,0XA5,0XAD,0XB6,0XBF, + 0XC8,0X88,0X04,0X98,0X00,0X05,0X04,0X7D,0XB6,0XAD,0XA5,0X1D,0X90,0X00,0X01,0X28, + 0X5F,0X81,0X66,0X01,0X3D,0X06,0X83,0X00,0X00,0X1B,0X86,0X66,0X87,0X00,0X02,0X4A, + 0X66,0X66,0X88,0X00,0X02,0X4A,0X66,0X66,0X8E,0X00,0X06,0X1D,0XA5,0XAD,0XB6,0XBF, + 0X83,0X04,0X98,0X00,0X06,0X04,0X83,0XBF,0XB6,0XAD,0XA5,0X1D,0X91,0X00,0X02,0X06, + 0X2F,0X5F,0X80,0X66,0X01,0X5F,0X13,0X82,0X00,0X03,0X1B,0X66,0X66,0X4A,0X83,0X2F, + 0X87,0X00,0X02,0X4A,0X66,0X66,0X88,0X00,0X02,0X4A,0X66,0X66,0X8E,0X00,0X05,0X1D, + 0XA5,0XAD,0XB6,0X7D,0X04,0X98,0X00,0X07,0X04,0X88,0XC8,0XBF,0XB6,0XAD,0XA5,0X1D, + 0X93,0X00,0X06,0X06,0X2F,0X5F,0X66,0X66,0X5F,0X06,0X81,0X00,0X03,0X1B,0X66,0X66, + 0X2F,0X8D,0X00,0X02,0X4A,0X66,0X66,0X88,0X00,0X02,0X4A,0X66,0X66,0X8E,0X00,0X04, + 0X1D,0XA5,0XAD,0X77,0X04,0X98,0X00,0X08,0X04,0X8E,0XD0,0XC8,0XBF,0XB6,0XAD,0XA5, + 0X1D,0X95,0X00,0X04,0X0D,0X52,0X66,0X66,0X3D,0X81,0X00,0X03,0X1B,0X66,0X66,0X2F, + 0X8D,0X00,0X02,0X4A,0X66,0X66,0X88,0X00,0X02,0X4A,0X66,0X66,0X8E,0X00,0X03,0X1D, + 0XA5,0X71,0X04,0X98,0X00,0X09,0X05,0X94,0XD9,0XD0,0XC8,0XBF,0XB6,0XAD,0XA5,0X1D, + 0X96,0X00,0X03,0X0D,0X66,0X66,0X59,0X81,0X00,0X03,0X1B,0X66,0X66,0X2F,0X8D,0X00, + 0X02,0X4A,0X66,0X66,0X88,0X00,0X02,0X4A,0X66,0X66,0X8E,0X00,0X02,0X1D,0X6C,0X03, + 0X98,0X00,0X0A,0X05,0X9A,0XE2,0XD9,0XD0,0XC8,0XBF,0XB6,0XAD,0XA5,0X1D,0X97,0X00, + 0X02,0X52,0X66,0X66,0X81,0X00,0X03,0X1B,0X66,0X66,0X2F,0X8D,0X00,0X02,0X4A,0X66, + 0X66,0X88,0X00,0X02,0X4A,0X66,0X66,0X8E,0X00,0X01,0X09,0X03,0X98,0X00,0X16,0X05, + 0X9F,0XEB,0XE2,0XD9,0XD0,0XC8,0XBF,0XB6,0XAD,0XA5,0X37,0X1F,0X1F,0X1D,0X1A,0X16, + 0X13,0X10,0X0C,0X08,0X05,0X02,0X8C,0X00,0X02,0X4A,0X66,0X66,0X81,0X00,0X03,0X1B, + 0X66,0X66,0X2F,0X8D,0X00,0X02,0X4A,0X66,0X66,0X88,0X00,0X02,0X4A,0X66,0X66,0XAA, + 0X00,0X17,0X05,0XA4,0XF3,0XEB,0XE2,0XD9,0XD0,0XC8,0XBF,0XB6,0XAD,0XA5,0X9E,0X99, + 0X99,0X8F,0X80,0X6F,0X5D,0X4D,0X3C,0X2A,0X19,0X0A,0X8B,0X00,0X03,0X06,0X66,0X66, + 0X44,0X81,0X00,0X03,0X1B,0X66,0X66,0X2F,0X8D,0X00,0X02,0X4A,0X66,0X66,0X88,0X00, + 0X02,0X4A,0X66,0X66,0XA9,0X00,0X18,0X05,0XA7,0XFA,0XF3,0XEB,0XE2,0XD9,0XD0,0XC8, + 0XBF,0XB6,0XAD,0XA5,0X9E,0X99,0X99,0X8F,0X80,0X6F,0X5D,0X4D,0X3C,0X2A,0X19,0X0A, + 0X8A,0X00,0X04,0X06,0X52,0X66,0X66,0X1B,0X81,0X00,0X03,0X1A,0X65,0X66,0X44,0X8D, + 0X00,0X02,0X4A,0X66,0X66,0X88,0X00,0X02,0X4A,0X66,0X66,0XA8,0X00,0X19,0X05,0XA7, + 0XFF,0XFA,0XF3,0XEB,0XE2,0XD9,0XD0,0XC8,0XBF,0XB6,0XAD,0XA5,0X9E,0X99,0X99,0X8F, + 0X80,0X6F,0X5D,0X4D,0X3C,0X2A,0X19,0X0A,0X82,0X00,0X00,0X1B,0X81,0X00,0X06,0X13, + 0X22,0X37,0X5F,0X66,0X66,0X36,0X82,0X00,0X04,0X11,0X5A,0X66,0X66,0X24,0X82,0X1B, + 0X87,0X00,0X02,0X4A,0X66,0X66,0X88,0X00,0X02,0X4A,0X66,0X66,0XA7,0X00,0X1A,0X05, + 0XA7,0XFF,0XFF,0XFA,0XF3,0XEB,0XE2,0XD9,0XD0,0XC8,0XBF,0XB6,0XAD,0XA5,0X9E,0X99, + 0X99,0X8F,0X80,0X6F,0X5D,0X4D,0X3C,0X2A,0X19,0X0A,0X82,0X00,0X86,0X66,0X01,0X5F, + 0X2F,0X83,0X00,0X02,0X04,0X3A,0X5A,0X84,0X66,0X87,0X00,0X02,0X4A,0X66,0X66,0X88, + 0X00,0X02,0X4A,0X66,0X66,0XA6,0X00,0X01,0X05,0XA7,0X80,0XFF,0X16,0XFA,0XF3,0XEB, + 0XE2,0XD9,0XD0,0XC8,0XBF,0XB6,0XAD,0XA5,0X9E,0X99,0X99,0X8F,0X80,0X6F,0X5D,0X4D, + 0X3C,0X2A,0X19,0X0A,0X82,0X00,0X00,0X5F,0X83,0X66,0X02,0X52,0X2F,0X06,0X85,0X00, + 0X02,0X10,0X40,0X5F,0X83,0X66,0X87,0X00,0X02,0X4A,0X66,0X66,0X88,0X00,0X02,0X4A, + 0X66,0X66,0XA6,0X00,0X00,0X46,0X81,0X99,0X16,0X96,0X92,0X8D,0X88,0X82,0X7D,0X78, + 0X73,0X6D,0X68,0X63,0X5F,0X5C,0X5C,0X56,0X4D,0X43,0X38,0X2E,0X24,0X19,0X0F,0X06, + 0X83,0X00,0X00,0X13,0X80,0X1B,0X00,0X13,0XFF,0X00,0XFF,0X00,0XCF,0X00,0XFF,0X00, + 0XFF,0X00,0XFC,0X00,0X02,0XE9,0XE2,0XCE,0XF1,0XC3,0X02,0XB4,0X8E,0X69,0X83,0X00, + 0X02,0XE2,0XDD,0XC6,0XF1,0XB4,0X02,0X9B,0X6C,0X4D,0X83,0X00,0X02,0XCE,0XC6,0XA8, + 0XF1,0X91,0X02,0X75,0X55,0X37,0X83,0X00,0X02,0XC3,0XB4,0X91,0XF1,0X00,0X02,0X67, + 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XF1,0X00,0X02,0X67,0X48,0X30,0X83,0X00, + 0X02,0XC3,0XB4,0X91,0XF1,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91, + 0XB4,0X00,0X01,0XFF,0XFF,0XB8,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4, + 0X91,0XB2,0X00,0X00,0X2A,0X81,0XFF,0X00,0X2A,0XA9,0X00,0X00,0X02,0X89,0X00,0X02, + 0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XB1,0X00,0X01,0X38,0XEE,0X81,0XFF, + 0X01,0XEE,0X38,0XA8,0X00,0X03,0X04,0X07,0X04,0X03,0X86,0X00,0X02,0X67,0X48,0X30, + 0X83,0X00,0X02,0XC3,0XB4,0X91,0X9C,0X00,0X80,0X01,0X8E,0X00,0X02,0X38,0XEE,0XF6, + 0X81,0XFF,0X02,0XF6,0XEE,0X38,0XA5,0X00,0X05,0X02,0X12,0X1C,0X24,0X17,0X08,0X86, + 0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X9C,0X00,0X03,0X0B,0X25, + 0X22,0X09,0X8C,0X00,0X03,0X38,0XED,0XF5,0XFC,0X81,0XFE,0X03,0XFC,0XF5,0XED,0X38, + 0XA3,0X00,0X07,0X03,0X0D,0X3B,0X6B,0X7A,0X57,0X1F,0X05,0X85,0X00,0X02,0X67,0X48, + 0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X9B,0X00,0X05,0X05,0X33,0X93,0X8C,0X30,0X02, + 0X8A,0X00,0X04,0X37,0XEB,0XF3,0XFA,0XF7,0X81,0XFC,0X04,0XF7,0XFA,0XF3,0XEB,0X37, + 0XA2,0X00,0X08,0X07,0X23,0X6D,0XB7,0XC8,0X9B,0X43,0X0B,0X02,0X84,0X00,0X02,0X67, + 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X9B,0X00,0X05,0X05,0X4F,0XC1,0XB9,0X49, + 0X05,0X89,0X00,0X05,0X37,0XE9,0XF1,0XF8,0XF5,0X7D,0X81,0XFA,0X05,0X7D,0XF5,0XF8, + 0XF1,0XE9,0X37,0XA1,0X00,0X07,0X07,0X2B,0X82,0XCA,0XD9,0XB0,0X53,0X11,0X85,0X00, + 0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X9B,0X00,0X05,0X01,0X20,0X5A, + 0X56,0X1A,0X03,0X88,0X00,0X06,0X36,0XE7,0XEE,0XF5,0XF2,0X7B,0X00,0X81,0XF7,0X06, + 0X00,0X7B,0XF2,0XF5,0XEE,0XE7,0X36,0XA0,0X00,0X07,0X02,0X1D,0X60,0XA3,0XB5,0X89, + 0X39,0X0A,0X85,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X9C,0X00, + 0X02,0X07,0X06,0X08,0X89,0X00,0X07,0X36,0XE5,0XEC,0XF3,0XF0,0X7A,0X00,0X00,0X81, + 0XF5,0X07,0X00,0X00,0X7A,0XF0,0XF3,0XEC,0XE5,0X36,0X9F,0X00,0X07,0X01,0X0C,0X26, + 0X4D,0X58,0X3D,0X15,0X02,0X85,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4, + 0X91,0XAA,0X00,0X05,0X35,0XE2,0XE9,0XF0,0XED,0X79,0X80,0X00,0X81,0XF2,0X80,0X00, + 0X05,0X79,0XED,0XF0,0XE9,0XE2,0X35,0X9F,0X00,0X05,0X01,0X06,0X10,0X12,0X0B,0X03, + 0X86,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XA9,0X00,0X05,0X34, + 0XDF,0XE7,0XED,0XEA,0X77,0X81,0X00,0X81,0XEF,0X81,0X00,0X05,0X77,0XEA,0XED,0XE7, + 0XDF,0X34,0X9F,0X00,0X03,0X07,0X01,0X02,0X04,0X87,0X00,0X02,0X67,0X48,0X30,0X83, + 0X00,0X02,0XC3,0XB4,0X91,0XA8,0X00,0X05,0X34,0XDD,0XE5,0XEB,0XE8,0X76,0X82,0X00, + 0X81,0XED,0X82,0X00,0X05,0X76,0XE8,0XEB,0XE5,0XDD,0X34,0XAC,0X00,0X02,0X67,0X48, + 0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XA7,0X00,0X05,0X33,0XDA,0XE2,0XE8,0XE5,0X75, + 0X83,0X00,0X81,0XEA,0X83,0X00,0X05,0X75,0XE5,0XE8,0XE2,0XDA,0X33,0XAB,0X00,0X02, + 0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XA6,0X00,0X05,0X33,0XD9,0XE0,0XE6, + 0XE3,0X71,0X84,0X00,0X81,0XE8,0X84,0X00,0X05,0X71,0XE3,0XE6,0XE0,0XD9,0X33,0XAA, + 0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X81,0X00,0X05,0X01,0X01, + 0X07,0X04,0X04,0X01,0X9B,0X00,0X05,0X32,0XD6,0XDD,0XE3,0XE1,0X6F,0X85,0X00,0X81, + 0XE5,0X85,0X00,0X05,0X6F,0XE1,0XE3,0XDD,0XD6,0X32,0XA9,0X00,0X02,0X67,0X48,0X30, + 0X83,0X00,0X02,0XC3,0XB4,0X91,0X80,0X00,0X07,0X01,0X06,0X12,0X21,0X1E,0X11,0X04, + 0X01,0X99,0X00,0X05,0X32,0XD3,0XDA,0XE0,0XDE,0X6E,0X86,0X00,0X81,0XE2,0X86,0X00, + 0X05,0X6E,0XDE,0XE0,0XDA,0XD3,0X32,0XA8,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02, + 0XC3,0XB4,0X91,0X80,0X00,0X07,0X04,0X15,0X3B,0X5A,0X55,0X32,0X10,0X02,0X98,0X00, + 0X05,0X31,0XD1,0XD8,0XDE,0XDC,0X6D,0X87,0X00,0X81,0XE0,0X87,0X00,0X05,0X6D,0XDC, + 0XDE,0XD8,0XD1,0X31,0XA7,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91, + 0X80,0X00,0X08,0X08,0X26,0X63,0X88,0X81,0X4F,0X1A,0X03,0X01,0X96,0X00,0X05,0X31, + 0XCE,0XD5,0XDB,0XD9,0X6B,0X88,0X00,0X81,0XDD,0X88,0X00,0X05,0X6B,0XD9,0XDB,0XD5, + 0XCE,0X31,0XA6,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X0D,0XC3,0XB4,0X91,0X00,0X00, + 0X01,0X07,0X29,0X65,0X8B,0X83,0X51,0X1B,0X04,0X96,0X00,0X05,0X30,0XCB,0XD2,0XD8, + 0XD6,0X6A,0X89,0X00,0X81,0XDA,0X89,0X00,0X05,0X6A,0XD6,0XD8,0XD2,0XCB,0X30,0XA5, + 0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X80,0X00,0X07,0X04,0X1A, + 0X43,0X61,0X59,0X33,0X10,0X04,0X95,0X00,0X05,0X2F,0XCA,0XD0,0XD6,0XD4,0X69,0X8A, + 0X00,0X81,0XD8,0X8A,0X00,0X05,0X69,0XD4,0XD6,0XD0,0XCA,0X2F,0XA4,0X00,0X02,0X67, + 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X80,0X00,0X07,0X01,0X08,0X18,0X25,0X22, + 0X12,0X04,0X01,0X94,0X00,0X05,0X2F,0XC7,0XCD,0XD3,0XD1,0X68,0X8B,0X00,0X81,0XD5, + 0X8B,0X00,0X05,0X68,0XD1,0XD3,0XCD,0XC7,0X2F,0XA3,0X00,0X02,0X67,0X48,0X30,0X83, + 0X00,0X02,0XC3,0XB4,0X91,0X81,0X00,0X05,0X01,0X05,0X06,0X07,0X02,0X01,0X94,0X00, + 0X05,0X2E,0XC5,0XCC,0XD1,0XCF,0X67,0X8C,0X00,0X81,0XD3,0X8C,0X00,0X05,0X67,0XCF, + 0XD1,0XCC,0XC5,0X2E,0XA2,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91, + 0X82,0X00,0X00,0X01,0X97,0X00,0X05,0X2E,0XC3,0XCA,0XCF,0XCD,0X66,0X8D,0X00,0X81, + 0XD1,0X8D,0X00,0X05,0X66,0XCD,0XCF,0XCA,0XC3,0X2E,0XA1,0X00,0X02,0X67,0X48,0X30, + 0X83,0X00,0X02,0XC3,0XB4,0X91,0X89,0X00,0XD6,0XFF,0X8C,0X00,0X02,0X67,0X48,0X30, + 0X83,0X00,0X02,0XC3,0XB4,0X91,0X89,0X00,0X00,0XFE,0XD4,0XFF,0X00,0XFE,0X8C,0X00, + 0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X89,0X00,0X01,0XF6,0XFF,0XD2, + 0XF6,0X01,0XFF,0XF6,0X8C,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91, + 0X89,0X00,0X02,0XE2,0XFC,0XEC,0XD0,0XEA,0X02,0XEC,0XFC,0XE2,0X8C,0X00,0X02,0X67, + 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X89,0X00,0X02,0XC7,0XF8,0XE1,0XD0,0XDC, + 0X02,0XE1,0XF8,0XC7,0X8C,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91, + 0X89,0X00,0X02,0XA6,0XF3,0XDB,0XD0,0XD0,0X02,0XDB,0XF3,0XA6,0X8C,0X00,0X02,0X67, + 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X89,0X00,0X02,0X81,0XEE,0XD8,0XD0,0XC5, + 0X02,0XD8,0XEE,0X81,0X8C,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91, + 0X89,0X00,0X02,0X58,0XE9,0XD7,0XD0,0XB9,0X02,0XD7,0XE9,0X58,0X8C,0X00,0X02,0X67, + 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X89,0X00,0X03,0X2C,0XE0,0XD9,0XAE,0X81, + 0XAD,0X00,0X97,0X84,0XAD,0X00,0X97,0X84,0XAD,0X00,0X97,0X84,0XAD,0X00,0X97,0X84, + 0XAD,0X00,0X97,0X84,0XAD,0X00,0X97,0X84,0XAD,0X00,0X97,0X84,0XAD,0X00,0X97,0X84, + 0XAD,0X00,0X97,0X84,0XAD,0X00,0X97,0X81,0XAD,0X03,0XAE,0XD9,0XE0,0X2C,0X8C,0X00, + 0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X8A,0X00,0X02,0XA8,0XDD,0XB4, + 0X80,0XA7,0X02,0X94,0X63,0X94,0X82,0XA7,0X02,0X94,0X63,0X94,0X82,0XA7,0X02,0X94, + 0X63,0X94,0X82,0XA7,0X02,0X94,0X63,0X94,0X82,0XA7,0X02,0X94,0X63,0X94,0X82,0XA7, + 0X02,0X94,0X63,0X94,0X82,0XA7,0X02,0X94,0X63,0X94,0X82,0XA7,0X02,0X94,0X63,0X94, + 0X82,0XA7,0X02,0X94,0X63,0X94,0X82,0XA7,0X02,0X94,0X63,0X94,0X80,0XA7,0X02,0XB4, + 0XDD,0XA8,0X8D,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X8A,0X00, + 0X05,0X6F,0XD6,0XBC,0XA3,0XA3,0X93,0X80,0X61,0X00,0X93,0X80,0XA3,0X00,0X93,0X80, + 0X61,0X00,0X93,0X80,0XA3,0X00,0X93,0X80,0X61,0X00,0X93,0X80,0XA3,0X00,0X93,0X80, + 0X61,0X00,0X93,0X80,0XA3,0X00,0X93,0X80,0X61,0X00,0X93,0X80,0XA3,0X00,0X93,0X80, + 0X61,0X00,0X93,0X80,0XA3,0X00,0X93,0X80,0X61,0X00,0X93,0X80,0XA3,0X00,0X93,0X80, + 0X61,0X00,0X93,0X80,0XA3,0X00,0X93,0X80,0X61,0X00,0X93,0X80,0XA3,0X00,0X93,0X80, + 0X61,0X05,0X93,0XA3,0XA3,0XBC,0XD6,0X6F,0X8D,0X00,0X02,0X67,0X48,0X30,0X83,0X00, + 0X02,0XC3,0XB4,0X91,0X8A,0X00,0X56,0X36,0XCD,0XC2,0X9E,0X91,0X5F,0X5F,0X91,0X5F, + 0X5F,0X91,0X9E,0X91,0X5F,0X5F,0X91,0X5F,0X5F,0X91,0X9E,0X91,0X5F,0X5F,0X91,0X5F, + 0X5F,0X91,0X9E,0X91,0X5F,0X5F,0X91,0X5F,0X5F,0X91,0X9E,0X91,0X5F,0X5F,0X91,0X5F, + 0X5F,0X91,0X9E,0X91,0X5F,0X5F,0X91,0X5F,0X5F,0X91,0X9E,0X91,0X5F,0X5F,0X91,0X5F, + 0X5F,0X91,0X9E,0X91,0X5F,0X5F,0X91,0X5F,0X5F,0X91,0X9E,0X91,0X5F,0X5F,0X91,0X5F, + 0X5F,0X91,0X9E,0X91,0X5F,0X5F,0X91,0X5F,0X5F,0X91,0X9E,0XC2,0XCD,0X36,0X8D,0X00, + 0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X8B,0X00,0X54,0X8C,0XC9,0X9B, + 0X5D,0X5D,0X8F,0X9A,0X8F,0X5D,0X5D,0X8F,0X5D,0X5D,0X8F,0X9A,0X8F,0X5D,0X5D,0X8F, + 0X5D,0X5D,0X8F,0X9A,0X8F,0X5D,0X5D,0X8F,0X5D,0X5D,0X8F,0X9A,0X8F,0X5D,0X5D,0X8F, + 0X5D,0X5D,0X8F,0X9A,0X8F,0X5D,0X5D,0X8F,0X5D,0X5D,0X8F,0X9A,0X8F,0X5D,0X5D,0X8F, + 0X5D,0X5D,0X8F,0X9A,0X8F,0X5D,0X5D,0X8F,0X5D,0X5D,0X8F,0X9A,0X8F,0X5D,0X5D,0X8F, + 0X5D,0X5D,0X8F,0X9A,0X8F,0X5D,0X5D,0X8F,0X5D,0X5D,0X8F,0X9A,0X8F,0X5D,0X5D,0X9B, + 0XC9,0X8C,0X8E,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X8B,0X00, + 0X08,0X4C,0XC2,0X93,0X5B,0X8D,0X95,0X91,0X95,0X8D,0X80,0X5B,0X04,0X8D,0X95,0X91, + 0X95,0X8D,0X80,0X5B,0X04,0X8D,0X95,0X91,0X95,0X8D,0X80,0X5B,0X04,0X8D,0X95,0X91, + 0X95,0X8D,0X80,0X5B,0X04,0X8D,0X95,0X91,0X95,0X8D,0X80,0X5B,0X04,0X8D,0X95,0X91, + 0X95,0X8D,0X80,0X5B,0X04,0X8D,0X95,0X91,0X95,0X8D,0X80,0X5B,0X04,0X8D,0X95,0X91, + 0X95,0X8D,0X80,0X5B,0X04,0X8D,0X95,0X91,0X95,0X8D,0X80,0X5B,0X08,0X8D,0X95,0X91, + 0X95,0X8D,0X5B,0X93,0XC2,0X4C,0X8E,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3, + 0XB4,0X91,0X8B,0X00,0X54,0X0F,0X8B,0XB8,0X93,0X91,0X8E,0X75,0X8E,0X91,0X8C,0X5A, + 0X8C,0X91,0X8E,0X75,0X8E,0X91,0X8C,0X5A,0X8C,0X91,0X8E,0X75,0X8E,0X91,0X8C,0X5A, + 0X8C,0X91,0X8E,0X75,0X8E,0X91,0X8C,0X5A,0X8C,0X91,0X8E,0X75,0X8E,0X91,0X8C,0X5A, + 0X8C,0X91,0X8E,0X75,0X8E,0X91,0X8C,0X5A,0X8C,0X91,0X8E,0X75,0X8E,0X91,0X8C,0X5A, + 0X8C,0X91,0X8E,0X75,0X8E,0X91,0X8C,0X5A,0X8C,0X91,0X8E,0X75,0X8E,0X91,0X8C,0X5A, + 0X8C,0X91,0X8E,0X75,0X8E,0X91,0X9C,0XB8,0X8B,0X0F,0X8E,0X00,0X02,0X67,0X48,0X30, + 0X83,0X00,0X02,0XC3,0XB4,0X91,0X8C,0X00,0X03,0X47,0XB4,0XA4,0X8B,0X80,0X72,0X00, + 0X8B,0X80,0X8C,0X00,0X8B,0X80,0X72,0X00,0X8B,0X80,0X8C,0X00,0X8B,0X80,0X72,0X00, + 0X8B,0X80,0X8C,0X00,0X8B,0X80,0X72,0X00,0X8B,0X80,0X8C,0X00,0X8B,0X80,0X72,0X00, + 0X8B,0X80,0X8C,0X00,0X8B,0X80,0X72,0X00,0X8B,0X80,0X8C,0X00,0X8B,0X80,0X72,0X00, + 0X8B,0X80,0X8C,0X00,0X8B,0X80,0X72,0X00,0X8B,0X80,0X8C,0X00,0X8B,0X80,0X72,0X00, + 0X8B,0X80,0X8C,0X00,0X8B,0X80,0X72,0X03,0X8B,0XA4,0XB4,0X47,0X8F,0X00,0X02,0X67, + 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X8C,0X00,0X07,0X08,0X75,0XAC,0X81,0X6F, + 0X88,0X6F,0X6F,0X80,0X88,0X04,0X6F,0X6F,0X88,0X6F,0X6F,0X80,0X88,0X04,0X6F,0X6F, + 0X88,0X6F,0X6F,0X80,0X88,0X04,0X6F,0X6F,0X88,0X6F,0X6F,0X80,0X88,0X04,0X6F,0X6F, + 0X88,0X6F,0X6F,0X80,0X88,0X04,0X6F,0X6F,0X88,0X6F,0X6F,0X80,0X88,0X04,0X6F,0X6F, + 0X88,0X6F,0X6F,0X80,0X88,0X04,0X6F,0X6F,0X88,0X6F,0X6F,0X80,0X88,0X04,0X6F,0X6F, + 0X88,0X6F,0X6F,0X80,0X88,0X07,0X6F,0X6F,0X88,0X6F,0X81,0XAC,0X75,0X08,0X8F,0X00, + 0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X8D,0X00,0X50,0X30,0X96,0X94, + 0X87,0X83,0X85,0X6B,0X6B,0X85,0X6B,0X6B,0X85,0X83,0X85,0X6B,0X6B,0X85,0X6B,0X6B, + 0X85,0X83,0X85,0X6B,0X6B,0X85,0X6B,0X6B,0X85,0X83,0X85,0X6B,0X6B,0X85,0X6B,0X6B, + 0X85,0X83,0X85,0X6B,0X6B,0X85,0X6B,0X6B,0X85,0X83,0X85,0X6B,0X6B,0X85,0X6B,0X6B, + 0X85,0X83,0X85,0X6B,0X6B,0X85,0X6B,0X6B,0X85,0X83,0X85,0X6B,0X6B,0X85,0X6B,0X6B, + 0X85,0X83,0X85,0X6B,0X6B,0X85,0X6B,0X6B,0X85,0X83,0X87,0X94,0X96,0X30,0X90,0X00, + 0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X8E,0X00,0X05,0X4F,0XA2,0X90, + 0X7E,0X7E,0X81,0X80,0X68,0X00,0X81,0X80,0X7E,0X00,0X81,0X80,0X68,0X00,0X81,0X80, + 0X7E,0X00,0X81,0X80,0X68,0X00,0X81,0X80,0X7E,0X00,0X81,0X80,0X68,0X00,0X81,0X80, + 0X7E,0X00,0X81,0X80,0X68,0X00,0X81,0X80,0X7E,0X00,0X81,0X80,0X68,0X00,0X81,0X80, + 0X7E,0X00,0X81,0X80,0X68,0X00,0X81,0X80,0X7E,0X00,0X81,0X80,0X68,0X00,0X81,0X80, + 0X7E,0X00,0X81,0X80,0X68,0X05,0X81,0X7E,0X7E,0X90,0XA2,0X4F,0X91,0X00,0X02,0X67, + 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X8E,0X00,0X08,0X0C,0X64,0X99,0X86,0X7A, + 0X7A,0X7E,0X65,0X7E,0X82,0X7A,0X02,0X7E,0X65,0X7E,0X82,0X7A,0X02,0X7E,0X65,0X7E, + 0X82,0X7A,0X02,0X7E,0X65,0X7E,0X82,0X7A,0X02,0X7E,0X65,0X7E,0X82,0X7A,0X02,0X7E, + 0X65,0X7E,0X82,0X7A,0X02,0X7E,0X65,0X7E,0X82,0X7A,0X02,0X7E,0X65,0X7E,0X82,0X7A, + 0X08,0X7E,0X65,0X7E,0X7A,0X7A,0X86,0X99,0X64,0X0C,0X91,0X00,0X02,0X67,0X48,0X30, + 0X83,0X00,0X02,0XC3,0XB4,0X91,0X8F,0X00,0X03,0X1F,0X71,0X8E,0X7D,0XC2,0X75,0X03, + 0X7D,0X8E,0X71,0X1F,0X92,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91, + 0X90,0X00,0X03,0X2B,0X77,0X86,0X75,0XC0,0X70,0X03,0X75,0X86,0X77,0X2B,0X93,0X00, + 0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X91,0X00,0X03,0X30,0X76,0X7E, + 0X6F,0XBE,0X6B,0X03,0X6F,0X7E,0X76,0X30,0X94,0X00,0X02,0X67,0X48,0X30,0X83,0X00, + 0X02,0XC3,0XB4,0X91,0X92,0X00,0X03,0X30,0X6F,0X77,0X6A,0XBC,0X66,0X03,0X6A,0X77, + 0X6F,0X30,0X95,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X93,0X00, + 0X03,0X2A,0X64,0X71,0X66,0XBA,0X61,0X03,0X66,0X71,0X64,0X2A,0X96,0X00,0X02,0X67, + 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X94,0X00,0X03,0X21,0X56,0X6D,0X62,0XB8, + 0X5C,0X03,0X62,0X6D,0X56,0X21,0X97,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3, + 0XB4,0X91,0X95,0X00,0X03,0X15,0X44,0X69,0X5F,0XB6,0X57,0X03,0X5F,0X69,0X44,0X15, + 0X98,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X96,0X00,0X04,0X06, + 0X30,0X5A,0X5D,0X54,0XB2,0X52,0X04,0X54,0X5D,0X5A,0X30,0X06,0X99,0X00,0X02,0X67, + 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X98,0X00,0X03,0X1B,0X41,0X50,0X3F,0XB0, + 0X35,0X03,0X3F,0X50,0X41,0X1B,0X9B,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3, + 0XB4,0X91,0X99,0X00,0X04,0X06,0X27,0X47,0X46,0X3A,0XAC,0X35,0X09,0X3A,0X46,0X47, + 0X27,0X06,0X00,0X01,0X00,0X00,0X01,0X97,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02, + 0XC3,0XB4,0X91,0X9B,0X00,0X04,0X0E,0X2B,0X48,0X4E,0X49,0XA8,0X47,0X07,0X49,0X4E, + 0X48,0X2B,0X0E,0X01,0X00,0X00,0X81,0X01,0X97,0X00,0X02,0X67,0X48,0X30,0X83,0X00, + 0X02,0XC3,0XB4,0X91,0X9D,0X00,0X04,0X0E,0X28,0X42,0X4A,0X46,0XA4,0X44,0X11,0X46, + 0X4A,0X42,0X28,0X0E,0X00,0X01,0X01,0X00,0X03,0X02,0X02,0X01,0X01,0X03,0X01,0X00, + 0X01,0X93,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X9F,0X00,0X04, + 0X08,0X1E,0X35,0X46,0X46,0XA0,0X44,0X13,0X46,0X46,0X35,0X1E,0X08,0X01,0X00,0X00, + 0X02,0X02,0X03,0X03,0X06,0X05,0X05,0X04,0X03,0X01,0X01,0X02,0X93,0X00,0X02,0X67, + 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XA2,0X00,0X04,0X10,0X21,0X37,0X43,0X45, + 0X9A,0X44,0X04,0X45,0X43,0X37,0X21,0X10,0X81,0X00,0X05,0X01,0X01,0X03,0X03,0X06, + 0X08,0X80,0X09,0X06,0X07,0X05,0X03,0X02,0X01,0X02,0X01,0X91,0X00,0X02,0X67,0X48, + 0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XA5,0X00,0X04,0X0B,0X1A,0X56,0X4B,0X45,0X94, + 0X44,0X04,0X45,0X4B,0X56,0X1A,0X0B,0X83,0X00,0X10,0X01,0X02,0X03,0X06,0X09,0X0C, + 0X0F,0X11,0X11,0X0F,0X0C,0X0B,0X06,0X04,0X01,0X00,0X01,0X91,0X00,0X02,0X67,0X48, + 0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XA7,0X00,0X0A,0X77,0X77,0X5A,0X57,0X52,0X4E, + 0X4B,0X48,0X47,0X45,0X45,0X82,0X44,0X0C,0X45,0X47,0X45,0X45,0X47,0X48,0X4B,0X4E, + 0X52,0X57,0X5A,0X77,0X77,0X83,0X00,0X12,0X01,0X01,0X02,0X02,0X04,0X09,0X0E,0X13, + 0X1D,0X21,0X22,0X1C,0X18,0X10,0X0B,0X08,0X03,0X02,0X01,0X91,0X00,0X02,0X67,0X48, + 0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XA7,0X00,0X01,0X77,0X77,0X96,0X54,0X01,0X77, + 0X77,0X84,0X00,0X11,0X01,0X03,0X03,0X08,0X0D,0X14,0X1F,0X36,0X47,0X51,0X40,0X2B, + 0X19,0X0F,0X09,0X05,0X00,0X02,0X91,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3, + 0XB4,0X91,0XA7,0X00,0X01,0X77,0X77,0X96,0X4D,0X01,0X77,0X77,0X85,0X00,0X11,0X02, + 0X06,0X0A,0X12,0X1C,0X39,0X66,0X96,0XA3,0X83,0X4B,0X27,0X15,0X0E,0X09,0X03,0X01, + 0X01,0X90,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XA7,0X00,0X01, + 0X77,0X77,0X96,0X45,0X01,0X77,0X77,0X83,0X00,0X13,0X01,0X01,0X03,0X06,0X0C,0X14, + 0X25,0X4A,0X97,0XD1,0XDD,0XBC,0X6E,0X34,0X1E,0X0F,0X09,0X05,0X02,0X02,0X90,0X00, + 0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XA7,0X00,0X01,0X77,0X77,0X96, + 0X3D,0X01,0X77,0X77,0X85,0X00,0X11,0X03,0X07,0X0E,0X18,0X29,0X56,0XA4,0XDD,0XE8, + 0XCB,0X7B,0X38,0X1F,0X11,0X09,0X05,0X03,0X02,0X90,0X00,0X02,0X67,0X48,0X30,0X83, + 0X00,0X02,0XC3,0XB4,0X91,0XA7,0X00,0X01,0X77,0X77,0X96,0X35,0X01,0X77,0X77,0X83, + 0X00,0X13,0X02,0X02,0X03,0X06,0X0D,0X15,0X25,0X49,0X86,0XBE,0XCB,0XA9,0X66,0X32, + 0X1A,0X12,0X09,0X04,0X03,0X01,0X90,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3, + 0XB4,0X91,0XA7,0X00,0X9A,0X77,0X84,0X00,0X11,0X02,0X01,0X07,0X0B,0X14,0X1F,0X33, + 0X52,0X74,0X7D,0X64,0X40,0X25,0X1A,0X0F,0X09,0X03,0X01,0X91,0X00,0X02,0X67,0X48, + 0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X86,0X00,0X0E,0X01,0X00,0X00,0X01,0X00,0X02, + 0X01,0X01,0X02,0X01,0X02,0X02,0X01,0X01,0X02,0X80,0X01,0X8C,0X00,0X9A,0X77,0X84, + 0X00,0X12,0X01,0X02,0X04,0X09,0X0F,0X18,0X21,0X2E,0X3B,0X3E,0X36,0X2A,0X1D,0X14, + 0X0C,0X07,0X03,0X00,0X02,0X90,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4, + 0X91,0X84,0X00,0X03,0X01,0X01,0X00,0X03,0X80,0X02,0X04,0X01,0X00,0X00,0X01,0X02, + 0X80,0X00,0X03,0X01,0X01,0X02,0X01,0X92,0X00,0X90,0X39,0X89,0X00,0X12,0X01,0X02, + 0X03,0X06,0X0B,0X11,0X17,0X22,0X23,0X24,0X26,0X1B,0X14,0X0F,0X08,0X05,0X03,0X02, + 0X01,0X90,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X83,0X00,0X10, + 0X01,0X01,0X02,0X03,0X03,0X04,0X03,0X03,0X04,0X03,0X00,0X02,0X01,0X00,0X00,0X01, + 0X01,0X95,0X00,0X90,0X39,0X88,0X00,0X11,0X01,0X02,0X01,0X02,0X05,0X07,0X0B,0X0F, + 0X14,0X16,0X15,0X15,0X11,0X0E,0X09,0X06,0X03,0X02,0X92,0X00,0X02,0X67,0X48,0X30, + 0X83,0X00,0X02,0XC3,0XB4,0X91,0X81,0X00,0X05,0X01,0X01,0X02,0X03,0X04,0X07,0X80, + 0X08,0X03,0X07,0X05,0X04,0X02,0X80,0X01,0X80,0X00,0X00,0X01,0X94,0X00,0X83,0X39, + 0X07,0X27,0X16,0X09,0X01,0X01,0X09,0X16,0X27,0X82,0X39,0X8A,0X00,0X0E,0X02,0X01, + 0X01,0X04,0X06,0X08,0X0C,0X0D,0X0C,0X0C,0X09,0X07,0X04,0X04,0X03,0X93,0X00,0X02, + 0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X81,0X00,0X0E,0X03,0X01,0X04,0X07, + 0X0B,0X0D,0X0E,0X10,0X10,0X0D,0X0B,0X07,0X04,0X03,0X01,0X99,0X00,0X81,0X39,0X02, + 0X34,0X1A,0X01,0X83,0X00,0X02,0X01,0X1A,0X34,0X80,0X39,0X8B,0X00,0X04,0X02,0X01, + 0X03,0X04,0X05,0X80,0X06,0X05,0X07,0X06,0X03,0X03,0X01,0X01,0X86,0X00,0X00,0X01, + 0X89,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X81,0X00,0X10,0X01, + 0X04,0X07,0X0B,0X0F,0X16,0X18,0X1A,0X19,0X16,0X12,0X0E,0X08,0X05,0X03,0X00,0X01, + 0X97,0X00,0X81,0X39,0X00,0X1A,0X87,0X00,0X00,0X1A,0X80,0X39,0X00,0X0D,0X8D,0X00, + 0X01,0X02,0X02,0X83,0X03,0X00,0X02,0X87,0X00,0X05,0X01,0X05,0X06,0X07,0X04,0X01, + 0X85,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X17,0XC3,0XB4,0X91,0X00,0X00,0X01,0X02, + 0X02,0X05,0X08,0X10,0X16,0X1F,0X25,0X28,0X25,0X22,0X1B,0X14,0X0B,0X08,0X05,0X02, + 0X01,0X96,0X00,0X00,0X0D,0X80,0X39,0X01,0X27,0X01,0X87,0X00,0X05,0X01,0X27,0X39, + 0X39,0X35,0X0D,0X8C,0X00,0X0A,0X01,0X02,0X01,0X02,0X01,0X01,0X00,0X01,0X00,0X01, + 0X01,0X84,0X00,0X07,0X01,0X03,0X0E,0X21,0X27,0X1A,0X09,0X02,0X84,0X00,0X02,0X67, + 0X48,0X30,0X83,0X00,0X17,0XC3,0XB4,0X91,0X00,0X00,0X01,0X00,0X04,0X06,0X0D,0X16, + 0X1F,0X29,0X33,0X37,0X34,0X2D,0X24,0X1A,0X10,0X09,0X06,0X03,0X01,0X95,0X00,0X01, + 0X0E,0X3C,0X80,0X40,0X00,0X19,0X89,0X00,0X05,0X19,0X40,0X40,0X3E,0X3C,0X0E,0X8C, + 0X00,0X01,0X01,0X01,0X81,0X00,0X01,0X02,0X01,0X86,0X00,0X08,0X01,0X0E,0X30,0X5B, + 0X68,0X49,0X1B,0X05,0X03,0X83,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X16,0XC3,0XB4, + 0X91,0X00,0X01,0X01,0X02,0X04,0X08,0X11,0X1A,0X28,0X3B,0X6F,0X8C,0X5A,0X39,0X2B, + 0X20,0X14,0X0C,0X06,0X03,0X95,0X00,0X02,0X10,0X44,0X46,0X80,0X49,0X00,0X0B,0X89, + 0X00,0X06,0X0B,0X49,0X49,0X48,0X46,0X44,0X10,0X8B,0X00,0X00,0X01,0X8D,0X00,0X08, + 0X04,0X19,0X51,0X89,0X95,0X75,0X30,0X0A,0X01,0X83,0X00,0X02,0X67,0X48,0X30,0X83, + 0X00,0X17,0XC3,0XB4,0X91,0X00,0X00,0X01,0X03,0X06,0X09,0X12,0X1D,0X2D,0X5D,0XC3, + 0XE6,0X99,0X40,0X2F,0X23,0X17,0X0C,0X06,0X04,0X01,0X93,0X00,0X03,0X16,0X5A,0X58, + 0X53,0X80,0X54,0X00,0X02,0X89,0X00,0X07,0X02,0X54,0X52,0X52,0X53,0X57,0X5A,0X16, + 0X9B,0X00,0X08,0X04,0X1B,0X56,0X8D,0X99,0X7A,0X36,0X08,0X03,0X83,0X00,0X02,0X67, + 0X48,0X30,0X83,0X00,0X03,0XC3,0XB4,0X91,0X00,0X80,0X01,0X10,0X05,0X0A,0X11,0X1B, + 0X2A,0X5C,0XC1,0XE4,0X96,0X3F,0X30,0X22,0X16,0X0D,0X07,0X03,0X01,0X92,0X00,0X07, + 0X1E,0X75,0X68,0X62,0X5F,0X5F,0X5E,0X5F,0X8B,0X12,0X81,0X5F,0X03,0X6A,0X6A,0X75, + 0X1F,0X99,0X00,0X08,0X01,0X03,0X0F,0X39,0X66,0X72,0X53,0X20,0X07,0X84,0X00,0X02, + 0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X81,0X00,0X10,0X04,0X08,0X10,0X1A, + 0X25,0X3B,0X6C,0X89,0X57,0X38,0X2A,0X1F,0X13,0X0B,0X06,0X03,0X01,0X91,0X00,0X09, + 0X26,0X8F,0X77,0X70,0X96,0X74,0X64,0X62,0X63,0X1E,0X8A,0X1D,0X08,0X67,0X64,0X64, + 0X7C,0X94,0X70,0X75,0X8F,0X27,0X99,0X00,0X06,0X01,0X04,0X12,0X28,0X2F,0X20,0X0A, + 0X85,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X16,0XC3,0XB4,0X91,0X00,0X00,0X01,0X02, + 0X03,0X07,0X0C,0X13,0X1D,0X28,0X30,0X34,0X30,0X2C,0X23,0X18,0X11,0X09,0X05,0X01, + 0X91,0X00,0X09,0X2F,0XA7,0X83,0X74,0X74,0X82,0XAD,0X7F,0X6D,0X6C,0X8B,0X2A,0X09, + 0X6B,0X6D,0X8A,0XAA,0X7B,0X74,0X74,0X81,0XA7,0X30,0X9A,0X00,0X04,0X03,0X07,0X0A, + 0X05,0X04,0X85,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X81,0X00, + 0X0E,0X03,0X05,0X0A,0X10,0X16,0X1D,0X22,0X25,0X24,0X20,0X1A,0X13,0X0B,0X08,0X03, + 0X91,0X00,0X0C,0X35,0XBB,0X91,0X80,0X7E,0X3F,0X40,0X8E,0XC1,0X8C,0X78,0X37,0X3B, + 0X87,0X34,0X0C,0X41,0X41,0X75,0X99,0XBE,0X86,0X40,0X3F,0X7E,0X80,0X8E,0XBB,0X38, + 0X9B,0X00,0X00,0X01,0X87,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91, + 0X81,0X00,0X10,0X02,0X03,0X05,0X09,0X0E,0X11,0X16,0X19,0X18,0X15,0X10,0X0C,0X07, + 0X04,0X02,0X01,0X01,0X8E,0X00,0X0D,0X3E,0XCF,0X9F,0X8B,0X89,0X44,0X00,0X00,0X46, + 0X9B,0XD5,0X99,0X83,0X1C,0X87,0X00,0X0D,0X1C,0X83,0XA8,0XD1,0X92,0X46,0X00,0X00, + 0X44,0X89,0X8B,0X9C,0XCF,0X40,0XA5,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3, + 0XB4,0X91,0X81,0X00,0X0E,0X01,0X01,0X04,0X05,0X07,0X0B,0X0D,0X0D,0X0E,0X0C,0X09, + 0X07,0X05,0X03,0X02,0X8F,0X00,0X05,0X45,0XDF,0XAC,0X96,0X94,0X49,0X81,0X00,0X05, + 0X4B,0XA7,0XE5,0XA5,0X8D,0X21,0X85,0X00,0X05,0X21,0X8D,0XB5,0XDF,0X9E,0X4B,0X81, + 0X00,0X05,0X49,0X94,0X96,0XA9,0XDF,0X48,0XA4,0X00,0X02,0X67,0X48,0X30,0X83,0X00, + 0X02,0XC3,0XB4,0X91,0X81,0X00,0X0F,0X02,0X02,0X01,0X03,0X04,0X07,0X07,0X09,0X09, + 0X06,0X06,0X04,0X03,0X02,0X02,0X01,0X8D,0X00,0X05,0X4C,0XEC,0XB5,0X9F,0X9D,0X4E, + 0X83,0X00,0X05,0X4E,0XB1,0XF1,0XAF,0X95,0X23,0X83,0X00,0X05,0X23,0X95,0XBF,0XEB, + 0XA7,0X4E,0X83,0X00,0X05,0X4E,0X9D,0X9F,0XB2,0XEE,0X50,0XA3,0X00,0X02,0X67,0X48, + 0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X83,0X00,0X80,0X01,0X80,0X04,0X80,0X03,0X02, + 0X02,0X00,0X02,0X8E,0X00,0X05,0X51,0XF4,0XBC,0XA6,0XA4,0X51,0X85,0X00,0X05,0X51, + 0XB8,0XF8,0XB6,0X9C,0X25,0X81,0X00,0X05,0X25,0X9C,0XC7,0XF2,0XAE,0X51,0X85,0X00, + 0X05,0X51,0XA4,0XA6,0XB9,0XF6,0X55,0XA2,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02, + 0XC3,0XB4,0X91,0X83,0X00,0X01,0X02,0X00,0X80,0X01,0X05,0X02,0X02,0X01,0X00,0X00, + 0X01,0X8E,0X00,0X05,0X51,0XF4,0XBC,0XA6,0XA4,0X51,0X87,0X00,0X0D,0X51,0XB8,0XF8, + 0XB6,0X9C,0X25,0X00,0X00,0X25,0X9C,0XC7,0XF2,0XAE,0X51,0X87,0X00,0X05,0X51,0XA4, + 0XA6,0XB9,0XF6,0X55,0XA1,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91, + 0X83,0X00,0X00,0X01,0X84,0X00,0X00,0X01,0X8F,0X00,0X05,0X51,0XF4,0XBC,0XA6,0XA4, + 0X51,0X89,0X00,0X0B,0X51,0XB8,0XF8,0XB6,0X9C,0X25,0X25,0X9C,0XC7,0XF2,0XAE,0X51, + 0X89,0X00,0X05,0X51,0XA4,0XA6,0XB9,0XF6,0X55,0XA0,0X00,0X02,0X67,0X48,0X30,0X83, + 0X00,0X02,0XC3,0XB4,0X91,0X9D,0X00,0X05,0X51,0XF4,0XBC,0XA6,0XA4,0X51,0X8B,0X00, + 0X09,0X51,0XB8,0XF8,0XB6,0X9E,0X9E,0XC7,0XF2,0XAE,0X51,0X8B,0X00,0X05,0X51,0XA4, + 0XA6,0XB9,0XF6,0X55,0X9F,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91, + 0X9C,0X00,0X05,0X25,0XE4,0XBC,0XA6,0XA4,0X51,0X8D,0X00,0X07,0X51,0XB8,0XD0,0XA6, + 0XAD,0XEF,0XAE,0X51,0X8D,0X00,0X05,0X51,0XA4,0XA6,0XB9,0XEF,0X29,0X9E,0X00,0X02, + 0X67,0X48,0X30,0X83,0X00,0X02,0XB4,0X9B,0X75,0XCE,0X67,0X00,0X6A,0X9F,0X67,0X02, + 0X59,0X3F,0X30,0X83,0X00,0X02,0X8E,0X6C,0X55,0XAA,0X48,0X04,0X47,0X46,0X46,0X47, + 0X47,0XBF,0X48,0X02,0X3F,0X30,0X30,0X83,0X00,0X02,0X69,0X4D,0X37,0XA9,0X30,0X06, + 0X2F,0X2A,0X25,0X22,0X26,0X2B,0X2F,0XC1,0X30,0XFF,0X00,0XFF,0X00,0XFF,0X00,0XA2, + 0X00,0X02,0X10,0X55,0X75,0X81,0XBA,0X01,0X88,0X1E,0X82,0X00,0X03,0X01,0X17,0X38, + 0X43,0X82,0X44,0X82,0X00,0X8A,0X44,0X83,0X00,0X80,0XBA,0X83,0X00,0X08,0X0A,0X19, + 0X2A,0X3C,0X4D,0X5D,0X6F,0X80,0X8F,0X8F,0X99,0X00,0X46,0XA7,0X00,0X02,0X10,0X75, + 0XEE,0X84,0XFF,0X00,0X60,0X81,0X00,0X03,0X01,0X2E,0XA3,0XEF,0X83,0XFF,0X82,0X00, + 0X8A,0XFF,0X83,0X00,0X80,0XFF,0X83,0X00,0X08,0X11,0X2A,0X46,0X64,0X80,0X9B,0XB9, + 0XD5,0XEE,0X8E,0XFF,0X01,0XA7,0X05,0XA6,0X00,0X01,0X10,0XCE,0X80,0XFF,0X01,0XBA, + 0X89,0X80,0X75,0X01,0X99,0X63,0X81,0X00,0X02,0X14,0X9F,0XE8,0X84,0XFF,0X82,0X00, + 0X8A,0XFF,0X83,0X00,0X80,0XFF,0X83,0X00,0X08,0X11,0X2A,0X46,0X64,0X80,0X9B,0XB9, + 0XD5,0XEE,0X8D,0XFF,0X01,0XA7,0X05,0XA7,0X00,0X04,0XAA,0XFF,0XFF,0XAA,0X10,0X88, + 0X00,0X04,0X36,0XE8,0XFF,0XF0,0X10,0X8C,0X00,0X02,0XBA,0XFF,0XFF,0X91,0X00,0X08, + 0X11,0X2A,0X46,0X64,0X80,0X9B,0XB9,0XD5,0XEE,0X8C,0XFF,0X01,0XA7,0X05,0XA7,0X00, + 0X03,0X20,0XFF,0XFF,0XBA,0X8A,0X00,0X03,0X42,0XFD,0XFF,0X8E,0X8D,0X00,0X02,0XBA, + 0XFF,0XFF,0X91,0X00,0X08,0X11,0X2A,0X46,0X64,0X80,0X9B,0XB9,0XD5,0XEE,0X8B,0XFF, + 0X01,0XA7,0X05,0XA8,0X00,0X03,0X75,0XFF,0XFF,0X55,0X8A,0X00,0X03,0X44,0XFF,0XFF, + 0X75,0X8D,0X00,0X02,0XBA,0XFF,0XFF,0X91,0X00,0X08,0X11,0X2A,0X46,0X64,0X80,0X9B, + 0XB9,0XD5,0XEE,0X8A,0XFF,0X01,0XA7,0X05,0XA9,0X00,0X03,0X75,0XFF,0XFF,0X44,0X8A, + 0X00,0X03,0X44,0XFF,0XFF,0X75,0X8D,0X00,0X02,0XBA,0XFF,0XFF,0X88,0X00,0X02,0X89, + 0XBA,0XBA,0X83,0X00,0X0B,0X03,0X08,0X0E,0X14,0X1A,0X1F,0X25,0X2B,0X30,0X33,0X33, + 0X58,0X86,0XFF,0X01,0XA7,0X05,0X98,0X00,0X01,0X05,0X0E,0X8D,0X00,0X03,0X65,0XFF, + 0XFF,0X99,0X8A,0X00,0X03,0X44,0XFF,0XFF,0X75,0X8D,0X00,0X02,0XBA,0XFF,0XFF,0X88, + 0X00,0X02,0XBA,0XFF,0XFF,0X8E,0X00,0X00,0X2E,0X85,0XFF,0X01,0XA7,0X05,0X98,0X00, + 0X02,0X05,0XA7,0X2E,0X8D,0X00,0X00,0X20,0X80,0XFF,0X00,0X75,0X89,0X00,0X03,0X44, + 0XFF,0XFF,0X75,0X8D,0X00,0X02,0XBA,0XFF,0XFF,0X88,0X00,0X02,0XBA,0XFF,0XFF,0X8E, + 0X00,0X00,0X2E,0X84,0XFF,0X01,0XA7,0X05,0X98,0X00,0X03,0X05,0XA7,0XFF,0X2E,0X8E, + 0X00,0X00,0X89,0X80,0XFF,0X01,0XBA,0X44,0X87,0X00,0X03,0X44,0XFF,0XFF,0X75,0X8D, + 0X00,0X02,0XBA,0XFF,0XFF,0X88,0X00,0X02,0XBA,0XFF,0XFF,0X8E,0X00,0X00,0X2E,0X83, + 0XFF,0X01,0XA7,0X05,0X98,0X00,0X04,0X05,0XA7,0XFF,0XFF,0X2E,0X8F,0X00,0X00,0X99, + 0X81,0XFF,0X01,0XBA,0X44,0X85,0X00,0X03,0X44,0XFF,0XFF,0XDE,0X83,0XBA,0X87,0X00, + 0X02,0XBA,0XFF,0XFF,0X88,0X00,0X02,0XBA,0XFF,0XFF,0X8E,0X00,0X00,0X2E,0X82,0XFF, + 0X01,0XA7,0X05,0X98,0X00,0X01,0X05,0XA7,0X80,0XFF,0X00,0X2E,0X90,0X00,0X01,0X65, + 0XEE,0X81,0XFF,0X01,0X99,0X10,0X83,0X00,0X00,0X44,0X86,0XFF,0X87,0X00,0X02,0XBA, + 0XFF,0XFF,0X88,0X00,0X02,0XBA,0XFF,0XFF,0X8E,0X00,0X00,0X2E,0X81,0XFF,0X01,0XA7, + 0X05,0X98,0X00,0X01,0X05,0XA7,0X81,0XFF,0X00,0X2E,0X91,0X00,0X02,0X10,0X75,0XEE, + 0X80,0XFF,0X01,0XEE,0X30,0X82,0X00,0X03,0X44,0XFF,0XFF,0XBA,0X83,0X75,0X87,0X00, + 0X02,0XBA,0XFF,0XFF,0X88,0X00,0X02,0XBA,0XFF,0XFF,0X8E,0X00,0X00,0X2E,0X80,0XFF, + 0X01,0XA7,0X05,0X98,0X00,0X01,0X05,0XA7,0X82,0XFF,0X00,0X2E,0X93,0X00,0X06,0X10, + 0X75,0XEE,0XFF,0XFF,0XEE,0X10,0X81,0X00,0X03,0X44,0XFF,0XFF,0X75,0X8D,0X00,0X02, + 0XBA,0XFF,0XFF,0X88,0X00,0X02,0XBA,0XFF,0XFF,0X8E,0X00,0X04,0X2E,0XFF,0XFF,0XA7, + 0X05,0X98,0X00,0X01,0X05,0XA7,0X83,0XFF,0X00,0X2E,0X95,0X00,0X04,0X20,0XCE,0XFF, + 0XFF,0X99,0X81,0X00,0X03,0X44,0XFF,0XFF,0X75,0X8D,0X00,0X02,0XBA,0XFF,0XFF,0X88, + 0X00,0X02,0XBA,0XFF,0XFF,0X8E,0X00,0X03,0X2E,0XFF,0XA7,0X05,0X98,0X00,0X01,0X05, + 0XA7,0X84,0XFF,0X00,0X2E,0X96,0X00,0X03,0X20,0XFF,0XFF,0XDE,0X81,0X00,0X03,0X44, + 0XFF,0XFF,0X75,0X8D,0X00,0X02,0XBA,0XFF,0XFF,0X88,0X00,0X02,0XBA,0XFF,0XFF,0X8E, + 0X00,0X02,0X2E,0XA7,0X05,0X98,0X00,0X01,0X05,0XA7,0X85,0XFF,0X00,0X2E,0X97,0X00, + 0X02,0XCE,0XFF,0XFF,0X81,0X00,0X03,0X44,0XFF,0XFF,0X75,0X8D,0X00,0X02,0XBA,0XFF, + 0XFF,0X88,0X00,0X02,0XBA,0XFF,0XFF,0X8E,0X00,0X01,0X0E,0X05,0X98,0X00,0X01,0X05, + 0XA7,0X86,0XFF,0X0B,0X58,0X33,0X33,0X30,0X2B,0X25,0X1F,0X1A,0X14,0X0E,0X08,0X03, + 0X8C,0X00,0X02,0XBA,0XFF,0XFF,0X81,0X00,0X03,0X44,0XFF,0XFF,0X75,0X8D,0X00,0X02, + 0XBA,0XFF,0XFF,0X88,0X00,0X02,0XBA,0XFF,0XFF,0XAA,0X00,0X01,0X05,0XA7,0X8A,0XFF, + 0X08,0XEE,0XD5,0XB9,0X9B,0X80,0X64,0X46,0X2A,0X11,0X8B,0X00,0X03,0X10,0XFF,0XFF, + 0XAA,0X81,0X00,0X03,0X44,0XFF,0XFF,0X75,0X8D,0X00,0X02,0XBA,0XFF,0XFF,0X88,0X00, + 0X02,0XBA,0XFF,0XFF,0XA9,0X00,0X01,0X05,0XA7,0X8B,0XFF,0X08,0XEE,0XD5,0XB9,0X9B, + 0X80,0X64,0X46,0X2A,0X11,0X8A,0X00,0X04,0X10,0XCE,0XFF,0XFF,0X44,0X81,0X00,0X03, + 0X40,0XFC,0XFF,0XA9,0X8D,0X00,0X02,0XBA,0XFF,0XFF,0X88,0X00,0X02,0XBA,0XFF,0XFF, + 0XA8,0X00,0X01,0X05,0XA7,0X8C,0XFF,0X08,0XEE,0XD5,0XB9,0X9B,0X80,0X64,0X46,0X2A, + 0X11,0X82,0X00,0X00,0X44,0X81,0X00,0X06,0X30,0X55,0X89,0XEE,0XFF,0XFF,0X88,0X82, + 0X00,0X04,0X2A,0XE2,0XFE,0XFF,0X5B,0X82,0X44,0X87,0X00,0X02,0XBA,0XFF,0XFF,0X88, + 0X00,0X02,0XBA,0XFF,0XFF,0XA7,0X00,0X01,0X05,0XA7,0X8D,0XFF,0X08,0XEE,0XD5,0XB9, + 0X9B,0X80,0X64,0X46,0X2A,0X11,0X82,0X00,0X86,0XFF,0X01,0XEE,0X75,0X83,0X00,0X02, + 0X0A,0X91,0XE2,0X84,0XFF,0X87,0X00,0X02,0XBA,0XFF,0XFF,0X88,0X00,0X02,0XBA,0XFF, + 0XFF,0XA6,0X00,0X01,0X05,0XA7,0X8E,0XFF,0X08,0XEE,0XD5,0XB9,0X9B,0X80,0X64,0X46, + 0X2A,0X11,0X82,0X00,0X00,0XEE,0X83,0XFF,0X02,0XCE,0X75,0X10,0X84,0X00,0X04,0X01, + 0X28,0X9F,0XEE,0XFE,0X82,0XFF,0X87,0X00,0X02,0XBA,0XFF,0XFF,0X88,0X00,0X02,0XBA, + 0XFF,0XFF,0XA6,0X00,0X00,0X46,0X8F,0X99,0X08,0X8F,0X80,0X6F,0X5D,0X4D,0X3C,0X2A, + 0X19,0X0A,0X83,0X00,0X00,0X30,0X80,0X44,0X00,0X30,0XFF,0X00,0XFF,0X00,0XCF,0X00, + 0XFF,0X00,0XFF,0X00,0XFC,0X00,0X02,0XE9,0XE2,0XCE,0XF1,0XC3,0X02,0XB4,0X8E,0X69, + 0X83,0X00,0X02,0XE2,0XDD,0XC6,0XF1,0XB4,0X02,0X9B,0X6C,0X4D,0X83,0X00,0X02,0XCE, + 0XC6,0XA8,0XF1,0X91,0X02,0X75,0X55,0X37,0X83,0X00,0X0E,0XC3,0XB4,0X91,0XBF,0XB7, + 0XAD,0XA3,0X9A,0X91,0X87,0X7E,0X74,0X6A,0X62,0X5A,0XCC,0X55,0X80,0X56,0X0F,0X58, + 0X5A,0X5E,0X62,0X68,0X6F,0X76,0X7D,0X84,0X8B,0X91,0X97,0X9C,0X9F,0XA1,0XA2,0X82, + 0XA3,0X03,0XA4,0X67,0X48,0X30,0X83,0X00,0X0E,0XC3,0XB4,0X91,0XBF,0XB7,0XAD,0XA3, + 0X9A,0X91,0X87,0X7E,0X74,0X6A,0X62,0X5A,0XCB,0X55,0X12,0X56,0X55,0X57,0X58,0X5C, + 0X60,0X65,0X6B,0X72,0X79,0X81,0X88,0X8E,0X93,0X98,0X9C,0X9F,0XA1,0XA2,0X83,0XA3, + 0X03,0XA4,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XF1,0X00,0X02,0X67,0X48, + 0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XB4,0X00,0X01,0XCC,0XCC,0XB8,0X00,0X02,0X67, + 0X48,0X30,0X83,0X00,0X0E,0XC3,0XB4,0X91,0XBF,0XB7,0XAD,0XA3,0X9A,0X91,0X87,0X7E, + 0X74,0X6A,0X62,0X5A,0XA6,0X55,0X00,0X69,0X81,0XCC,0X00,0X69,0X97,0X55,0X80,0X56, + 0X11,0X58,0X5A,0X5D,0X61,0X67,0X6E,0X75,0X7D,0X85,0X8B,0X91,0X96,0X9A,0X9C,0X9E, + 0XA1,0XA1,0XA2,0X85,0XA3,0X04,0XA4,0XA4,0X67,0X48,0X30,0X83,0X00,0X0E,0XC3,0XB4, + 0X91,0XBF,0XB7,0XAD,0XA3,0X9A,0X91,0X87,0X7E,0X74,0X6A,0X62,0X5A,0XA5,0X55,0X01, + 0X6F,0XC4,0X81,0XCC,0X01,0XC4,0X6F,0X95,0X55,0X16,0X56,0X56,0X57,0X59,0X5B,0X5F, + 0X64,0X6A,0X71,0X79,0X80,0X87,0X8E,0X93,0X98,0X9B,0X9D,0X9F,0XA1,0XA2,0XA5,0XA3, + 0XA4,0X85,0XA3,0X03,0XA4,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X9C,0X00, + 0X80,0X01,0X8E,0X00,0X02,0X2D,0XBE,0XC5,0X81,0XCC,0X02,0XC5,0XBE,0X2D,0XA5,0X00, + 0X05,0X02,0X12,0X1C,0X24,0X17,0X08,0X86,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02, + 0XC3,0XB4,0X91,0X9C,0X00,0X03,0X0B,0X25,0X22,0X09,0X8C,0X00,0X03,0X2C,0XBA,0XC0, + 0XC5,0X81,0XC7,0X03,0XC5,0XC0,0XBA,0X2C,0XA3,0X00,0X07,0X03,0X0D,0X3B,0X6B,0X7A, + 0X57,0X1F,0X05,0X85,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X0E,0XC3,0XB4,0X91,0XBF, + 0XB7,0XAD,0XA3,0X9A,0X91,0X87,0X7E,0X74,0X6A,0X62,0X5A,0X8F,0X55,0X05,0X58,0X77, + 0XB7,0XB2,0X75,0X56,0X8A,0X55,0X04,0X6C,0XB9,0XBC,0XBF,0XBE,0X81,0XC0,0X05,0XBE, + 0XBF,0XBC,0XB9,0X6C,0X56,0X88,0X55,0X01,0X56,0X55,0X80,0X56,0X26,0X57,0X58,0X59, + 0X5B,0X5E,0X62,0X67,0X6D,0X74,0X7C,0X83,0X8A,0X90,0X95,0X99,0X9C,0X9E,0XA0,0XA1, + 0XA2,0XA5,0XB0,0XCA,0XE5,0XEB,0XDB,0XBA,0XA6,0XA2,0XA1,0XA1,0XA0,0X9F,0X9F,0X9E, + 0X9D,0X67,0X48,0X30,0X83,0X00,0X0E,0XC3,0XB4,0X91,0XBF,0XB7,0XAD,0XA3,0X9A,0X91, + 0X87,0X7E,0X74,0X6A,0X62,0X5A,0X8F,0X55,0X05,0X58,0X8A,0XD6,0XD0,0X86,0X58,0X89, + 0X55,0X05,0X6B,0XB1,0XB5,0XB7,0XB6,0X86,0X81,0XB8,0X07,0X86,0XB6,0XB7,0XB5,0XB1, + 0X6C,0X56,0X56,0X81,0X57,0X82,0X56,0X2B,0X57,0X56,0X57,0X58,0X58,0X5A,0X5C,0X5E, + 0X62,0X66,0X6B,0X71,0X78,0X7F,0X86,0X8D,0X92,0X97,0X9B,0X9D,0X9F,0XA0,0XA1,0XA2, + 0XA2,0XA6,0XB3,0XD2,0XEC,0XF1,0XE2,0XC0,0XA7,0XA0,0X9F,0X9E,0X9D,0X9C,0X9B,0X9A, + 0X9A,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X9B,0X00,0X05,0X01,0X20,0X5A, + 0X56,0X1A,0X03,0X88,0X00,0X06,0X26,0XA2,0XA8,0XAD,0XAB,0X57,0X00,0X81,0XAE,0X06, + 0X00,0X57,0XAB,0XAD,0XA8,0XA2,0X26,0XA0,0X00,0X07,0X02,0X1D,0X60,0XA3,0XB5,0X89, + 0X39,0X0A,0X85,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X9C,0X00, + 0X02,0X07,0X06,0X08,0X89,0X00,0X07,0X24,0X99,0X9E,0XA3,0XA1,0X52,0X00,0X00,0X81, + 0XA4,0X07,0X00,0X00,0X52,0XA1,0XA3,0X9E,0X99,0X24,0X9F,0X00,0X07,0X01,0X0C,0X26, + 0X4D,0X58,0X3D,0X15,0X02,0X85,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X0E,0XC3,0XB4, + 0X91,0XBF,0XB7,0XAD,0XA3,0X9A,0X91,0X87,0X7E,0X74,0X6A,0X62,0X5A,0X9E,0X55,0X05, + 0X64,0X95,0X98,0X99,0X99,0X77,0X80,0X55,0X81,0X9A,0X0A,0X5D,0X5F,0X62,0X7F,0X99, + 0X9A,0X98,0X97,0X75,0X6B,0X6B,0X83,0X6A,0X13,0X6B,0X6C,0X6D,0X70,0X72,0X76,0X79, + 0X7E,0X83,0X88,0X8C,0X91,0X95,0X99,0X9C,0X9E,0XA0,0XA1,0XA2,0XA2,0X84,0XA3,0X10, + 0XA5,0XA8,0XA8,0XA3,0X9E,0X9A,0X97,0X94,0X90,0X8E,0X8D,0X90,0X95,0X9D,0X67,0X48, + 0X30,0X83,0X00,0X0E,0XC3,0XB4,0X91,0XBF,0XB7,0XAD,0XA3,0X9A,0X91,0X87,0X7E,0X74, + 0X6A,0X62,0X5A,0X9D,0X55,0X09,0X62,0X8B,0X8D,0X8F,0X8E,0X72,0X55,0X56,0X56,0X57, + 0X81,0X8F,0X09,0X64,0X68,0X6B,0X6F,0X80,0X8E,0X8F,0X8E,0X8D,0X7C,0X80,0X77,0X81, + 0X76,0X12,0X77,0X78,0X7A,0X7C,0X7F,0X82,0X86,0X8A,0X8D,0X91,0X95,0X98,0X9B,0X9D, + 0X9F,0XA0,0XA1,0XA2,0XA2,0X85,0XA3,0X10,0XA5,0XA1,0XA1,0XA0,0X9B,0X97,0X93,0X8E, + 0X8B,0X8A,0X8B,0X90,0X9A,0XA3,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XA8, + 0X00,0X05,0X1D,0X7C,0X80,0X84,0X82,0X42,0X82,0X00,0X81,0X85,0X82,0X00,0X05,0X42, + 0X82,0X84,0X80,0X7C,0X1D,0XAC,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4, + 0X91,0XA7,0X00,0X05,0X1B,0X73,0X77,0X7A,0X79,0X3D,0X83,0X00,0X81,0X7B,0X83,0X00, + 0X05,0X3D,0X79,0X7A,0X77,0X73,0X1B,0XAB,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X0E, + 0XC3,0XB4,0X91,0XBF,0XB7,0XAD,0XA3,0X9A,0X91,0X87,0X7E,0X74,0X6A,0X62,0X5A,0X9A, + 0X55,0X0C,0X5B,0X70,0X71,0X72,0X71,0X63,0X55,0X56,0X57,0X58,0X5D,0X61,0X68,0X81, + 0X72,0X0C,0X86,0X8B,0X8F,0X92,0X94,0X96,0X97,0X85,0X73,0X72,0X73,0X75,0X90,0X81, + 0X97,0X0D,0X98,0X98,0X99,0X9A,0X9B,0X9C,0X9D,0X9E,0X9F,0XA0,0XA1,0XA1,0XA2,0XA2, + 0X89,0XA3,0X11,0XA2,0XA1,0X9F,0X9C,0X98,0X92,0X8C,0X85,0X82,0X82,0X87,0X91,0X9E, + 0XAB,0XB7,0X67,0X48,0X30,0X83,0X00,0X0E,0XC3,0XB4,0X91,0XBF,0XB7,0XAD,0XA3,0X9A, + 0X91,0X89,0X7F,0X75,0X6A,0X62,0X5A,0X99,0X55,0X0D,0X59,0X67,0X67,0X68,0X68,0X5E, + 0X55,0X55,0X56,0X58,0X5C,0X61,0X68,0X71,0X81,0X68,0X0D,0X91,0X94,0X97,0X99,0X9B, + 0X9C,0X9C,0X9D,0X83,0X69,0X68,0X6A,0X6C,0X91,0X82,0X9D,0X06,0X9E,0X9E,0X9F,0XA0, + 0XA0,0XA1,0XA1,0X80,0XA2,0X8B,0XA3,0X11,0XA2,0XA1,0X9F,0X9B,0X96,0X8F,0X88,0X82, + 0X7F,0X81,0X88,0X93,0XA1,0XAF,0XBB,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91, + 0X80,0X00,0X07,0X01,0X06,0X12,0X21,0X1E,0X11,0X04,0X01,0X99,0X00,0X05,0X15,0X58, + 0X5B,0X5D,0X5C,0X2E,0X86,0X00,0X81,0X5E,0X86,0X00,0X05,0X2E,0X5C,0X5D,0X5B,0X58, + 0X15,0XA8,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X80,0X00,0X07, + 0X04,0X15,0X3B,0X5A,0X55,0X32,0X10,0X02,0X98,0X00,0X05,0X12,0X4E,0X51,0X53,0X52, + 0X29,0X87,0X00,0X81,0X54,0X87,0X00,0X05,0X29,0X52,0X53,0X51,0X4E,0X12,0XA7,0X00, + 0X02,0X67,0X48,0X30,0X83,0X00,0X0E,0XC3,0XB4,0X91,0XBF,0XB7,0XAD,0XA4,0XA1,0XA7, + 0XAD,0XA8,0X92,0X75,0X63,0X5B,0X96,0X55,0X01,0X52,0X4A,0X80,0X49,0X00,0X4F,0X81, + 0X55,0X06,0X56,0X5A,0X60,0X69,0X74,0X7F,0X8A,0X81,0X49,0X04,0XA0,0XA1,0XA1,0XA2, + 0XA2,0X83,0XA3,0X05,0X77,0X4B,0X4A,0X4C,0X4F,0X8F,0X8A,0XA3,0X84,0XA2,0X83,0XA3, + 0X11,0XA2,0XA0,0X9D,0X97,0X90,0X88,0X80,0X7C,0X7B,0X82,0X8D,0X9A,0XA8,0XB5,0XBE, + 0X67,0X48,0X30,0X83,0X00,0X0E,0XC3,0XB4,0X91,0XBF,0XB7,0XAD,0XA4,0XA1,0XA8,0XAE, + 0XA9,0X93,0X76,0X64,0X5A,0X95,0X55,0X05,0X50,0X40,0X40,0X3F,0X3F,0X4A,0X81,0X55, + 0X07,0X56,0X58,0X5C,0X63,0X6E,0X79,0X85,0X8F,0X81,0X3F,0X80,0XA2,0X86,0XA3,0X05, + 0X72,0X41,0X40,0X43,0X46,0X8D,0X86,0XA3,0X81,0XA2,0X82,0XA1,0X81,0XA2,0X14,0XA3, + 0XA3,0XA2,0XA2,0X9F,0X9C,0X96,0X8F,0X86,0X7F,0X7B,0X7B,0X82,0X8E,0X9B,0XA9,0XB6, + 0XBF,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X80,0X00,0X07,0X04,0X1A,0X43, + 0X61,0X59,0X33,0X10,0X04,0X95,0X00,0X05,0X0C,0X31,0X33,0X35,0X34,0X1A,0X8A,0X00, + 0X81,0X35,0X8A,0X00,0X05,0X1A,0X34,0X35,0X33,0X31,0X0C,0XA4,0X00,0X02,0X67,0X48, + 0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X80,0X00,0X07,0X01,0X08,0X18,0X25,0X22,0X12, + 0X04,0X01,0X94,0X00,0X05,0X09,0X28,0X29,0X2B,0X2A,0X15,0X8B,0X00,0X81,0X2B,0X8B, + 0X00,0X05,0X15,0X2A,0X2B,0X29,0X28,0X09,0XA3,0X00,0X02,0X67,0X48,0X30,0X83,0X00, + 0X0E,0XC3,0XB4,0X91,0XBF,0XB7,0XAD,0XA3,0X9A,0X92,0X89,0X80,0X75,0X6A,0X62,0X5A, + 0X92,0X55,0X05,0X4A,0X26,0X25,0X23,0X24,0X3D,0X82,0X55,0X09,0X56,0X56,0X58,0X5D, + 0X64,0X6F,0X7C,0X87,0X92,0X99,0X81,0X23,0X8C,0XA3,0X10,0X65,0X26,0X24,0X28,0X2C, + 0X87,0XA3,0XA3,0XA2,0XA2,0XA1,0X9F,0X9E,0X9C,0X9A,0X97,0X95,0X80,0X94,0X19,0X96, + 0X98,0X9A,0X9C,0X9E,0XA0,0XA1,0XA1,0XA0,0X9D,0X99,0X92,0X8A,0X81,0X7A,0X78,0X7B, + 0X84,0X91,0X9D,0XAA,0XB6,0XBF,0X67,0X48,0X30,0X83,0X00,0X0E,0XC3,0XB4,0X91,0XBF, + 0XB7,0XAD,0XA3,0X9A,0X91,0X87,0X7E,0X74,0X6A,0X62,0X5A,0X91,0X55,0X05,0X48,0X20, + 0X1E,0X1C,0X1D,0X39,0X84,0X55,0X08,0X56,0X5A,0X60,0X69,0X74,0X80,0X8B,0X95,0X9B, + 0X81,0X1C,0X8D,0XA3,0X2C,0X61,0X1F,0X1D,0X21,0X25,0X85,0XA2,0XA2,0XA1,0X9F,0X9D, + 0X9A,0X97,0X93,0X90,0X8D,0X8B,0X8A,0X8B,0X8D,0X90,0X94,0X97,0X9B,0X9D,0X9F,0X9F, + 0X9E,0X9C,0X97,0X90,0X88,0X7F,0X78,0X77,0X7B,0X85,0X91,0X9E,0XAB,0XB6,0XBF,0X67, + 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X89,0X00,0XD6,0XFF,0X8C,0X00,0X02,0X67, + 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X89,0X00,0XD6,0X33,0X8C,0X00,0X02,0X67, + 0X48,0X30,0X83,0X00,0X10,0XC3,0XB4,0X91,0XBF,0XB7,0XAD,0XA3,0X9A,0X91,0X87,0X7E, + 0X74,0X6A,0X62,0X5A,0X34,0X33,0XD2,0X2E,0X13,0X33,0X36,0X90,0X8E,0X89,0X82,0X7B, + 0X75,0X73,0X75,0X7D,0X88,0X94,0XA0,0XAC,0XB7,0XBF,0X67,0X48,0X30,0X83,0X00,0X11, + 0XC3,0XB4,0X91,0XBF,0XB7,0XAD,0XA3,0X9A,0X91,0X87,0X7E,0X74,0X6A,0X62,0X5A,0X36, + 0X32,0X27,0XD0,0X26,0X14,0X27,0X32,0X3B,0X86,0X85,0X80,0X7A,0X75,0X71,0X71,0X76, + 0X7E,0X89,0X95,0XA0,0XAC,0XB7,0XBF,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91, + 0X89,0X00,0X02,0X27,0X31,0X22,0XD0,0X1E,0X02,0X22,0X31,0X27,0X8C,0X00,0X02,0X67, + 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X89,0X00,0X02,0X21,0X30,0X1F,0XD0,0X17, + 0X02,0X1F,0X30,0X21,0X8C,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X11,0XC3,0XB4,0X91, + 0XBF,0XB7,0XAD,0XA3,0X9A,0X91,0X87,0X7E,0X74,0X6A,0X62,0X5A,0X40,0X2E,0X1D,0XD0, + 0X0F,0X14,0X1D,0X2E,0X47,0X64,0X64,0X62,0X62,0X64,0X67,0X6F,0X78,0X82,0X8D,0X98, + 0XA2,0XAD,0XB7,0XBF,0X67,0X48,0X30,0X83,0X00,0X11,0XC3,0XB4,0X91,0XBF,0XB7,0XAD, + 0XA3,0X9A,0X91,0X87,0X7E,0X74,0X6A,0X62,0X5A,0X46,0X2D,0X1F,0XD0,0X07,0X14,0X1F, + 0X2D,0X4A,0X5D,0X5D,0X5C,0X5D,0X62,0X67,0X6F,0X7A,0X83,0X8E,0X99,0XA2,0XAD,0XB7, + 0XBF,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X89,0X00,0X02,0X08,0X2A,0X23, + 0X82,0X01,0X00,0X00,0X84,0X01,0X00,0X00,0X84,0X01,0X00,0X00,0X84,0X01,0X00,0X00, + 0X84,0X01,0X00,0X00,0X84,0X01,0X00,0X00,0X84,0X01,0X00,0X00,0X84,0X01,0X00,0X00, + 0X84,0X01,0X00,0X00,0X84,0X01,0X00,0X00,0X82,0X01,0X02,0X23,0X2A,0X08,0X8C,0X00, + 0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X8A,0X00,0X02,0X20,0X2A,0X0A, + 0XCE,0X00,0X02,0X0A,0X2A,0X20,0X8D,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X12,0XC3, + 0XB4,0X91,0XBF,0XB7,0XAD,0XA3,0X9A,0X91,0X87,0X7E,0X74,0X6A,0X62,0X5A,0X55,0X3E, + 0X28,0X13,0XCE,0X00,0X02,0X13,0X28,0X3E,0X81,0X55,0X0E,0X59,0X61,0X69,0X73,0X7D, + 0X86,0X90,0X9A,0XA3,0XAD,0XB7,0XBF,0X67,0X48,0X30,0X83,0X00,0X12,0XC3,0XB4,0X91, + 0XBF,0XB7,0XAD,0XA3,0X9A,0X91,0X87,0X7E,0X74,0X6A,0X62,0X5A,0X55,0X49,0X26,0X1C, + 0XCE,0X00,0X02,0X1C,0X26,0X49,0X81,0X55,0X0E,0X5A,0X62,0X69,0X73,0X7E,0X87,0X91, + 0X9A,0XA3,0XAD,0XB7,0XBF,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X8B,0X00, + 0X02,0X19,0X24,0X06,0XCC,0X00,0X02,0X06,0X24,0X19,0X8E,0X00,0X02,0X67,0X48,0X30, + 0X83,0X00,0X02,0XC3,0XB4,0X91,0X8B,0X00,0X02,0X0D,0X22,0X10,0XCC,0X00,0X02,0X10, + 0X22,0X0D,0X8E,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X14,0XC3,0XB4,0X91,0XBF,0XB7, + 0XAD,0XA3,0X9A,0X91,0X87,0X7E,0X74,0X6A,0X62,0X5A,0X55,0X55,0X51,0X2E,0X1D,0X04, + 0XCA,0X00,0X03,0X08,0X1D,0X2E,0X51,0X82,0X55,0X0E,0X5A,0X62,0X6A,0X74,0X7E,0X87, + 0X91,0X9A,0XA3,0XAD,0XB7,0XBF,0X67,0X48,0X30,0X83,0X00,0X0E,0XC3,0XB4,0X91,0XBF, + 0XB7,0XAD,0XA3,0X9A,0X91,0X87,0X7E,0X74,0X6A,0X62,0X5A,0X80,0X55,0X02,0X40,0X1F, + 0X13,0XCA,0X00,0X02,0X13,0X1F,0X40,0X83,0X55,0X0E,0X5A,0X62,0X6A,0X74,0X7E,0X87, + 0X91,0X9A,0XA3,0XAD,0XB7,0XBF,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X8C, + 0X00,0X03,0X01,0X13,0X1C,0X08,0XC8,0X00,0X03,0X08,0X1C,0X13,0X01,0X8F,0X00,0X02, + 0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X8D,0X00,0X03,0X08,0X18,0X11,0X02, + 0XC6,0X00,0X03,0X02,0X11,0X18,0X08,0X90,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X0E, + 0XC3,0XB4,0X91,0XBF,0XB7,0XAD,0XA3,0X9A,0X91,0X87,0X7E,0X74,0X6A,0X62,0X5A,0X82, + 0X55,0X02,0X39,0X1A,0X0D,0XC6,0X00,0X02,0X0D,0X1A,0X38,0X85,0X55,0X0E,0X5A,0X62, + 0X6A,0X74,0X7E,0X87,0X91,0X9A,0XA3,0XAD,0XB7,0XBF,0X67,0X48,0X30,0X83,0X00,0X0E, + 0XC3,0XB4,0X91,0XBF,0XB7,0XAD,0XA3,0X9A,0X91,0X87,0X7E,0X74,0X6A,0X62,0X5A,0X82, + 0X55,0X03,0X52,0X30,0X16,0X09,0XC4,0X00,0X03,0X09,0X16,0X2E,0X50,0X85,0X55,0X0E, + 0X5A,0X62,0X6A,0X74,0X7E,0X87,0X91,0X9A,0XA3,0XAD,0XB7,0XBF,0X67,0X48,0X30,0X83, + 0X00,0X02,0XC3,0XB4,0X91,0X8F,0X00,0X03,0X05,0X11,0X11,0X05,0XC2,0X00,0X03,0X05, + 0X11,0X11,0X05,0X92,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X90, + 0X00,0X03,0X06,0X11,0X0E,0X03,0XC0,0X00,0X03,0X03,0X0E,0X11,0X06,0X93,0X00,0X02, + 0X67,0X48,0X30,0X83,0X00,0X0E,0XC3,0XB4,0X91,0XBD,0XB4,0XAA,0XA0,0X96,0X8E,0X85, + 0X7D,0X73,0X69,0X61,0X59,0X80,0X55,0X08,0X56,0X58,0X5E,0X64,0X6E,0X55,0X22,0X0C, + 0X03,0XBE,0X00,0X03,0X03,0X0C,0X1C,0X3E,0X88,0X55,0X0E,0X5A,0X62,0X6A,0X74,0X7E, + 0X87,0X91,0X9A,0XA3,0XAD,0XB7,0XBF,0X67,0X48,0X30,0X83,0X00,0X1B,0XC3,0XB4,0X91, + 0XB8,0XAF,0XA6,0X9B,0X94,0X8B,0X82,0X7A,0X71,0X68,0X61,0X59,0X56,0X55,0X56,0X58, + 0X5C,0X62,0X6A,0X75,0X80,0X5E,0X23,0X0B,0X02,0XBC,0X00,0X03,0X02,0X0B,0X1A,0X3C, + 0X89,0X55,0X0E,0X5A,0X62,0X6A,0X74,0X7E,0X87,0X91,0X9A,0XA3,0XAD,0XB7,0XBF,0X67, + 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X93,0X00,0X03,0X05,0X0C,0X0A,0X03,0XBA, + 0X00,0X03,0X03,0X0A,0X0C,0X05,0X96,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3, + 0XB4,0X91,0X94,0X00,0X03,0X04,0X0A,0X09,0X03,0XB8,0X00,0X03,0X03,0X09,0X0A,0X04, + 0X97,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X1E,0XC3,0XB4,0X91,0XA1,0X9A,0X92,0X8C, + 0X86,0X81,0X7B,0X76,0X70,0X69,0X64,0X5F,0X5D,0X5F,0X62,0X68,0X6F,0X78,0X82,0X8B, + 0X93,0X99,0X9D,0XA0,0X85,0X44,0X09,0X04,0XB6,0X00,0X03,0X04,0X09,0X27,0X47,0X8C, + 0X55,0X0E,0X5A,0X62,0X6A,0X74,0X7E,0X87,0X91,0X9A,0XA3,0XAD,0XB7,0XBF,0X67,0X48, + 0X30,0X83,0X00,0X20,0XC3,0XB4,0X91,0X9A,0X96,0X90,0X8B,0X87,0X83,0X7F,0X7A,0X75, + 0X6E,0X6A,0X66,0X64,0X67,0X6B,0X72,0X79,0X82,0X8A,0X92,0X97,0X9C,0X9F,0XA1,0XA2, + 0X9B,0X5B,0X1A,0X05,0X01,0XB2,0X00,0X04,0X01,0X05,0X11,0X31,0X51,0X8D,0X55,0X0E, + 0X5A,0X62,0X6A,0X74,0X7E,0X87,0X91,0X9A,0XA3,0XAD,0XB7,0XBF,0X67,0X48,0X30,0X83, + 0X00,0X02,0XC3,0XB4,0X91,0X98,0X00,0X03,0X02,0X05,0X04,0X01,0XB0,0X00,0X03,0X01, + 0X04,0X05,0X02,0X9B,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X9A, + 0X00,0X02,0X03,0X05,0X02,0XAE,0X00,0X08,0X02,0X05,0X03,0X00,0X00,0X01,0X00,0X00, + 0X01,0X97,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X19,0XC3,0XB4,0X91,0X9D,0X9D,0X9B, + 0X9B,0X9A,0X98,0X96,0X93,0X90,0X8D,0X8A,0X88,0X87,0X89,0X8C,0X90,0X94,0X98,0X9B, + 0X9E,0XA0,0XA1,0XA2,0X84,0XA3,0X04,0X8A,0X53,0X18,0X02,0X01,0XA8,0X00,0X07,0X01, + 0X02,0X0E,0X2D,0X48,0X56,0X55,0X55,0X81,0X56,0X8B,0X55,0X0E,0X5A,0X62,0X6A,0X74, + 0X7E,0X87,0X91,0X9A,0XA3,0XAD,0XB7,0XBF,0X67,0X48,0X30,0X83,0X00,0X18,0XC3,0XB4, + 0X91,0XA1,0XA0,0XA0,0X9F,0X9E,0X9D,0X9C,0X9A,0X98,0X96,0X93,0X92,0X92,0X93,0X95, + 0X97,0X9A,0X9C,0X9E,0XA0,0XA1,0XA2,0X87,0XA3,0X04,0X87,0X54,0X1C,0X02,0X01,0XA4, + 0X00,0X09,0X01,0X02,0X10,0X2C,0X47,0X55,0X56,0X56,0X55,0X57,0X81,0X56,0X03,0X57, + 0X56,0X55,0X56,0X87,0X55,0X0E,0X5A,0X62,0X6A,0X74,0X7E,0X87,0X91,0X9A,0XA3,0XAD, + 0XB7,0XBF,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XA0,0X00,0X81,0X01,0XA0, + 0X00,0X81,0X01,0X0F,0X00,0X01,0X00,0X00,0X02,0X02,0X03,0X03,0X06,0X05,0X05,0X04, + 0X03,0X01,0X01,0X02,0X93,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91, + 0XA4,0X00,0X01,0X01,0X01,0X9C,0X00,0X01,0X01,0X01,0X83,0X00,0X05,0X01,0X01,0X03, + 0X03,0X06,0X08,0X80,0X09,0X06,0X07,0X05,0X03,0X02,0X01,0X02,0X01,0X91,0X00,0X02, + 0X67,0X48,0X30,0X83,0X00,0X04,0XC3,0XB4,0X91,0XA4,0XA4,0X81,0XA3,0X80,0XA2,0X80, + 0XA1,0X00,0XA0,0X80,0XA1,0X80,0XA2,0X92,0XA3,0X01,0X88,0X66,0X9A,0X00,0X01,0X35, + 0X47,0X83,0X55,0X10,0X56,0X56,0X57,0X59,0X5B,0X5D,0X5F,0X60,0X60,0X5F,0X5D,0X5C, + 0X59,0X58,0X56,0X55,0X56,0X85,0X55,0X0E,0X5A,0X62,0X6A,0X74,0X7E,0X87,0X91,0X9A, + 0XA3,0XAD,0XB7,0XBF,0X67,0X48,0X30,0X83,0X00,0X03,0XC3,0XB4,0X91,0XA4,0X86,0XA3, + 0X83,0XA2,0X97,0XA3,0X82,0X00,0X01,0X01,0X01,0X8C,0X00,0X01,0X01,0X01,0X82,0X00, + 0X83,0X55,0X81,0X56,0X0E,0X58,0X5B,0X5E,0X62,0X68,0X6B,0X6C,0X68,0X65,0X60,0X5C, + 0X5A,0X57,0X56,0X56,0X85,0X55,0X0E,0X5A,0X62,0X6A,0X74,0X7E,0X87,0X91,0X9A,0XA3, + 0XAD,0XB7,0XBF,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XCB,0X00,0X11,0X01, + 0X03,0X03,0X08,0X0D,0X14,0X1F,0X36,0X47,0X51,0X40,0X2B,0X19,0X0F,0X09,0X05,0X00, + 0X02,0X91,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XCC,0X00,0X11, + 0X02,0X06,0X0A,0X12,0X1C,0X39,0X66,0X96,0XA3,0X83,0X4B,0X27,0X15,0X0E,0X09,0X03, + 0X01,0X01,0X90,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X9F,0XA3, + 0X80,0XA2,0X01,0XA1,0XA1,0X80,0XA0,0X9A,0X00,0X83,0X55,0X13,0X56,0X56,0X57,0X59, + 0X5D,0X62,0X6E,0X86,0XBA,0XE0,0XE8,0XD2,0X9E,0X78,0X69,0X5F,0X5B,0X58,0X56,0X56, + 0X84,0X55,0X0E,0X5A,0X62,0X6A,0X74,0X7E,0X87,0X91,0X9A,0XA3,0XAD,0XB7,0XBF,0X67, + 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X9C,0XA3,0X80,0XA2,0X07,0XA1,0XA0,0XA0, + 0X9F,0X9E,0X9E,0X9D,0X9D,0X9A,0X00,0X85,0X55,0X11,0X57,0X5A,0X5E,0X65,0X70,0X8E, + 0XC2,0XE8,0XF0,0XDC,0XA7,0X7A,0X6A,0X60,0X5B,0X58,0X57,0X56,0X84,0X55,0X0E,0X5A, + 0X62,0X6A,0X74,0X7E,0X87,0X91,0X9A,0XA3,0XAD,0XB7,0XBF,0X67,0X48,0X30,0X83,0X00, + 0X02,0XC3,0XB4,0X91,0XCA,0X00,0X13,0X02,0X02,0X03,0X06,0X0D,0X15,0X25,0X49,0X86, + 0XBE,0XCB,0XA9,0X66,0X32,0X1A,0X12,0X09,0X04,0X03,0X01,0X90,0X00,0X02,0X67,0X48, + 0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0XCB,0X00,0X11,0X02,0X01,0X07,0X0B,0X14,0X1F, + 0X33,0X52,0X74,0X7D,0X64,0X40,0X25,0X1A,0X0F,0X09,0X03,0X01,0X91,0X00,0X02,0X67, + 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X8B,0XA3,0X1B,0XA4,0XA3,0XA3,0XA4,0XA3, + 0XA4,0XA4,0XA3,0XA3,0XA4,0XA3,0XA3,0XA2,0XA2,0XA1,0XA0,0X9E,0X9D,0X9B,0X98,0X95, + 0X92,0X8F,0X8B,0X89,0X86,0X85,0X83,0X9A,0X00,0X84,0X55,0X12,0X56,0X56,0X58,0X5B, + 0X5F,0X65,0X6B,0X74,0X7C,0X7E,0X79,0X71,0X68,0X62,0X5D,0X5A,0X57,0X55,0X56,0X84, + 0X55,0X0E,0X5A,0X62,0X6A,0X74,0X7E,0X87,0X91,0X9A,0XA3,0XAD,0XB7,0XBF,0X67,0X48, + 0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X87,0XA3,0X81,0XA4,0X81,0XA3,0X00,0XA4,0X82, + 0XA3,0X11,0XA4,0XA2,0XA2,0XA1,0X9F,0X9D,0X9B,0X98,0X95,0X91,0X8D,0X88,0X84,0X80, + 0X7D,0X7A,0X78,0X77,0X80,0X76,0X01,0X75,0X74,0X90,0X00,0X89,0X55,0X12,0X56,0X56, + 0X57,0X59,0X5C,0X60,0X64,0X6C,0X6C,0X6D,0X6E,0X67,0X62,0X5F,0X5A,0X58,0X57,0X56, + 0X56,0X84,0X55,0X0E,0X5A,0X62,0X6A,0X74,0X7E,0X87,0X91,0X9A,0XA3,0XAD,0XB7,0XBF, + 0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X83,0X00,0X10,0X01,0X01,0X02,0X03, + 0X03,0X04,0X03,0X03,0X04,0X03,0X00,0X02,0X01,0X00,0X00,0X01,0X01,0XB3,0X00,0X11, + 0X01,0X02,0X01,0X02,0X05,0X07,0X0B,0X0F,0X14,0X16,0X15,0X15,0X11,0X0E,0X09,0X06, + 0X03,0X02,0X92,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X81,0X00, + 0X05,0X01,0X01,0X02,0X03,0X04,0X07,0X80,0X08,0X03,0X07,0X05,0X04,0X02,0X80,0X01, + 0X80,0X00,0X00,0X01,0XB4,0X00,0X0E,0X02,0X01,0X01,0X04,0X06,0X08,0X0C,0X0D,0X0C, + 0X0C,0X09,0X07,0X04,0X04,0X03,0X93,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3, + 0XB4,0X91,0X81,0XA3,0X0D,0XA4,0XA3,0XA4,0XA6,0XA7,0XA8,0XA8,0XA9,0XA9,0XA8,0XA7, + 0XA6,0XA4,0XA4,0X82,0XA3,0X14,0XA2,0XA1,0X9F,0X9D,0X99,0X94,0X8D,0X86,0X7F,0X78, + 0X71,0X6B,0X66,0X62,0X5F,0X5D,0X5C,0X5B,0X5A,0X59,0X5A,0X80,0X59,0X90,0X00,0X8B, + 0X55,0X04,0X56,0X56,0X57,0X58,0X58,0X80,0X59,0X05,0X5A,0X59,0X57,0X57,0X56,0X56, + 0X87,0X55,0X0E,0X5A,0X62,0X6A,0X74,0X7E,0X87,0X91,0X9A,0XA3,0XAD,0XB7,0XBF,0X67, + 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X82,0XA3,0X04,0XA4,0XA6,0XA7,0XA8,0XAB, + 0X80,0XAC,0X05,0XAB,0XA9,0XA8,0XA6,0XA5,0XA4,0X80,0XA3,0X10,0XA2,0XA2,0XA0,0X9E, + 0X9A,0X95,0X8E,0X86,0X7D,0X75,0X6D,0X67,0X61,0X5E,0X5B,0X59,0X58,0X80,0X57,0X82, + 0X56,0X90,0X00,0X00,0X42,0X8D,0X55,0X01,0X56,0X56,0X83,0X57,0X00,0X56,0X88,0X55, + 0X0F,0X58,0X5D,0X65,0X6C,0X75,0X7E,0X87,0X91,0X9A,0XA3,0XAD,0XB7,0XBF,0X67,0X48, + 0X30,0X83,0X00,0X17,0XC3,0XB4,0X91,0X00,0X00,0X01,0X02,0X02,0X05,0X08,0X10,0X16, + 0X1F,0X25,0X28,0X25,0X22,0X1B,0X14,0X0B,0X08,0X05,0X02,0X01,0XBB,0X00,0X0A,0X01, + 0X02,0X01,0X02,0X01,0X01,0X00,0X01,0X00,0X01,0X01,0X84,0X00,0X07,0X01,0X03,0X0E, + 0X21,0X27,0X1A,0X09,0X02,0X84,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X17,0XC3,0XB4, + 0X91,0X00,0X00,0X01,0X00,0X04,0X06,0X0D,0X16,0X1F,0X29,0X33,0X37,0X34,0X2D,0X24, + 0X1A,0X10,0X09,0X06,0X03,0X01,0XBC,0X00,0X01,0X01,0X01,0X81,0X00,0X01,0X02,0X01, + 0X86,0X00,0X08,0X01,0X0E,0X30,0X5B,0X68,0X49,0X1B,0X05,0X03,0X83,0X00,0X02,0X67, + 0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X80,0XA3,0X1F,0XA4,0XA4,0XA6,0XA9,0XAC, + 0XB1,0XB8,0XCB,0XD6,0XC3,0XB8,0XB3,0XAF,0XAA,0XA7,0XA5,0XA4,0XA3,0XA2,0XA1,0X9E, + 0X9B,0X95,0X8D,0X83,0X78,0X6D,0X64,0X5D,0X59,0X57,0X56,0X86,0X55,0X02,0X42,0X06, + 0X03,0X91,0X00,0X02,0X03,0X06,0X42,0X8B,0X55,0X00,0X56,0X8D,0X55,0X11,0X57,0X63, + 0X81,0XA1,0XA9,0X9D,0X86,0X81,0X87,0X91,0X9A,0XA3,0XAD,0XB7,0XBF,0X67,0X48,0X30, + 0X83,0X00,0X02,0XC3,0XB4,0X91,0X80,0XA3,0X1F,0XA4,0XA5,0XA6,0XA9,0XAD,0XB3,0XC5, + 0XE9,0XF6,0XDA,0XBA,0XB4,0XB0,0XAB,0XA7,0XA5,0XA4,0XA2,0XA2,0XA0,0X9D,0X98,0X91, + 0X87,0X7C,0X71,0X67,0X5F,0X5A,0X57,0X55,0X56,0X85,0X55,0X02,0X42,0X09,0X01,0X93, + 0X00,0X02,0X01,0X09,0X42,0X9B,0X55,0X11,0X57,0X64,0X84,0XA3,0XAB,0X9F,0X89,0X81, + 0X88,0X91,0X9A,0XA3,0XAD,0XB7,0XBF,0X67,0X48,0X30,0X83,0X00,0X03,0XC3,0XB4,0X91, + 0X00,0X80,0X01,0X10,0X05,0X0A,0X11,0X1B,0X2A,0X5C,0XC1,0XE4,0X96,0X3F,0X30,0X22, + 0X16,0X0D,0X07,0X03,0X01,0X92,0X00,0X03,0X02,0X09,0X03,0X01,0X93,0X00,0X03,0X04, + 0X04,0X09,0X02,0X99,0X00,0X08,0X01,0X03,0X0F,0X39,0X66,0X72,0X53,0X20,0X07,0X84, + 0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X81,0X00,0X10,0X04,0X08, + 0X10,0X1A,0X25,0X3B,0X6C,0X89,0X57,0X38,0X2A,0X1F,0X13,0X0B,0X06,0X03,0X01,0X91, + 0X00,0X05,0X03,0X0E,0X05,0X02,0X0F,0X04,0X91,0X00,0X05,0X06,0X0E,0X02,0X04,0X0E, + 0X04,0X99,0X00,0X06,0X01,0X04,0X12,0X28,0X2F,0X20,0X0A,0X85,0X00,0X02,0X67,0X48, + 0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X80,0XA3,0X1C,0XA4,0XA4,0XA6,0XA7,0XAA,0XAD, + 0XB1,0XB4,0XB6,0XB4,0XB3,0XB0,0XAC,0XA9,0XA6,0XA5,0XA2,0XA1,0X9F,0X9C,0X96,0X8E, + 0X83,0X77,0X6B,0X61,0X5B,0X57,0X56,0X85,0X55,0X07,0X41,0X18,0X09,0X00,0X00,0X05, + 0X15,0X05,0X8F,0X00,0X07,0X09,0X14,0X02,0X00,0X00,0X08,0X18,0X41,0X9A,0X55,0X0F, + 0X57,0X5E,0X67,0X6C,0X75,0X7E,0X87,0X91,0X9A,0XA3,0XAD,0XB7,0XBF,0X67,0X48,0X30, + 0X83,0X00,0X02,0XC3,0XB4,0X91,0X81,0XA3,0X1A,0XA4,0XA5,0XA7,0XA9,0XAB,0XAD,0XAF, + 0XB0,0XB0,0XAF,0XAC,0XAA,0XA7,0XA6,0XA4,0XA2,0XA1,0X9E,0X9A,0X93,0X8A,0X7E,0X72, + 0X67,0X5E,0X59,0X56,0X85,0X55,0X02,0X40,0X1C,0X0B,0X81,0X00,0X02,0X06,0X1A,0X06, + 0X8D,0X00,0X02,0X0B,0X19,0X03,0X81,0X00,0X02,0X0A,0X1C,0X40,0X9A,0X55,0X0E,0X5A, + 0X63,0X6A,0X74,0X7E,0X87,0X91,0X9A,0XA3,0XAD,0XB7,0XBF,0X67,0X48,0X30,0X83,0X00, + 0X02,0XC3,0XB4,0X91,0X81,0X00,0X10,0X02,0X03,0X05,0X09,0X0E,0X11,0X16,0X19,0X18, + 0X15,0X10,0X0C,0X07,0X04,0X02,0X01,0X01,0X8E,0X00,0X02,0X07,0X1F,0X0A,0X83,0X00, + 0X02,0X08,0X20,0X08,0X8B,0X00,0X02,0X0E,0X1F,0X04,0X83,0X00,0X02,0X09,0X1F,0X08, + 0XA5,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X81,0X00,0X0E,0X01, + 0X01,0X04,0X05,0X07,0X0B,0X0D,0X0D,0X0E,0X0C,0X09,0X07,0X05,0X03,0X02,0X8F,0X00, + 0X02,0X08,0X25,0X0C,0X85,0X00,0X02,0X09,0X26,0X09,0X89,0X00,0X02,0X11,0X23,0X05, + 0X85,0X00,0X02,0X0B,0X25,0X09,0XA4,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3, + 0XB4,0X91,0X81,0XA3,0X04,0XA4,0XA4,0XA3,0XA4,0XA4,0X81,0XA6,0X01,0XA5,0XA5,0X80, + 0XA4,0X0C,0XA3,0XA1,0X9E,0X9A,0X93,0X89,0X7E,0X71,0X66,0X5D,0X59,0X56,0X56,0X82, + 0X55,0X02,0X3F,0X2B,0X10,0X87,0X00,0X02,0X0A,0X2B,0X0A,0X87,0X00,0X02,0X13,0X28, + 0X05,0X87,0X00,0X02,0X0E,0X2C,0X3F,0X97,0X55,0X0E,0X5A,0X62,0X6A,0X74,0X7E,0X87, + 0X91,0X9A,0XA3,0XAD,0XB7,0XBF,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X86, + 0XA3,0X84,0XA4,0X0C,0XA3,0XA4,0XA2,0XA0,0X9D,0X98,0X90,0X86,0X79,0X6D,0X63,0X5C, + 0X57,0X83,0X55,0X02,0X3F,0X2E,0X11,0X89,0X00,0X02,0X0B,0X2F,0X0B,0X85,0X00,0X02, + 0X14,0X2C,0X06,0X89,0X00,0X02,0X0F,0X2F,0X3F,0X96,0X55,0X0E,0X5A,0X62,0X6A,0X74, + 0X7E,0X87,0X91,0X9A,0XA3,0XAD,0XB7,0XBF,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4, + 0X91,0X83,0X00,0X01,0X02,0X00,0X80,0X01,0X05,0X02,0X02,0X01,0X00,0X00,0X01,0X8E, + 0X00,0X02,0X0A,0X2D,0X0F,0X8B,0X00,0X02,0X0B,0X2F,0X0B,0X83,0X00,0X02,0X14,0X2C, + 0X06,0X8B,0X00,0X02,0X0D,0X2E,0X0B,0XA1,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02, + 0XC3,0XB4,0X91,0X83,0X00,0X00,0X01,0X84,0X00,0X00,0X01,0X8F,0X00,0X02,0X0A,0X2D, + 0X0F,0X8D,0X00,0X02,0X0B,0X2F,0X0B,0X81,0X00,0X02,0X14,0X2C,0X06,0X8D,0X00,0X02, + 0X0D,0X2E,0X0B,0XA0,0X00,0X02,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X8E, + 0XA3,0X0A,0XA2,0XA0,0X9D,0X98,0X91,0X86,0X7A,0X6E,0X63,0X5C,0X57,0X81,0X55,0X02, + 0X3F,0X2E,0X11,0X8F,0X00,0X07,0X0B,0X2F,0X0B,0X00,0X00,0X14,0X2C,0X06,0X8F,0X00, + 0X02,0X0F,0X2F,0X3F,0X93,0X55,0X0E,0X5A,0X62,0X6A,0X74,0X7E,0X87,0X91,0X9A,0XA3, + 0XAD,0XB7,0XBF,0X67,0X48,0X30,0X83,0X00,0X02,0XC3,0XB4,0X91,0X8E,0XA3,0X0A,0XA2, + 0XA0,0X9C,0X97,0X8E,0X83,0X77,0X6A,0X61,0X5A,0X56,0X80,0X55,0X05,0X42,0X27,0X11, + 0X00,0X00,0X09,0X8D,0X11,0X07,0X09,0X0B,0X18,0X00,0X04,0X2A,0X06,0X09,0X8D,0X11, + 0X05,0X09,0X00,0X01,0X0F,0X2C,0X42,0X92,0X55,0X0E,0X5A,0X62,0X6A,0X74,0X7E,0X87, + 0X91,0X9A,0XA3,0XAD,0XB7,0XBF,0X67,0X48,0X30,0X83,0X00,0X02,0XB4,0X9B,0X75,0XCE, + 0X67,0X00,0X66,0X9F,0X67,0X02,0X59,0X3F,0X30,0X83,0X00,0X02,0X8E,0X6C,0X55,0XAA, + 0X48,0X04,0X47,0X46,0X46,0X47,0X47,0XBF,0X48,0X02,0X3F,0X30,0X30,0X83,0X00,0X02, + 0X69,0X4D,0X37,0XA9,0X30,0X06,0X2F,0X2A,0X25,0X22,0X26,0X2B,0X2F,0XC1,0X30,0XFF, + 0X00,0XFF,0X00,0XFF,0X00,0XDA,0X00,0X16,0X02,0X05,0X08,0X0C,0X0F,0X13,0X16,0X1A, + 0X1D,0X1F,0X1F,0X22,0X26,0X2B,0X30,0X35,0X3B,0X40,0X45,0X4A,0X50,0X55,0X59,0X81, + 0X5C,0X00,0X2A,0XE1,0X00,0X16,0X03,0X08,0X0E,0X14,0X1A,0X1F,0X25,0X2B,0X30,0X33, + 0X33,0X38,0X3F,0X47,0X50,0X59,0X62,0X6A,0X73,0X7C,0X85,0X8D,0X94,0X80,0X99,0X01, + 0X64,0X03,0XE1,0X00,0X1A,0X03,0X08,0X0E,0X14,0X1A,0X1F,0X25,0X2B,0X30,0X33,0X33, + 0X38,0X3F,0X47,0X50,0X59,0X62,0X6A,0X73,0X7C,0X85,0X8D,0X94,0X99,0X99,0X64,0X03, + 0XE2,0X00,0X19,0X03,0X08,0X0E,0X14,0X1A,0X1F,0X25,0X2B,0X30,0X33,0X33,0X38,0X3F, + 0X47,0X50,0X59,0X62,0X6A,0X73,0X7C,0X85,0X8D,0X94,0X99,0X64,0X03,0XE3,0X00,0X18, + 0X03,0X08,0X0E,0X14,0X1A,0X1F,0X25,0X2B,0X30,0X33,0X33,0X38,0X3F,0X47,0X50,0X59, + 0X62,0X6A,0X73,0X7C,0X85,0X8D,0X94,0X64,0X03,0XE4,0X00,0X17,0X03,0X08,0X0E,0X14, + 0X1A,0X1F,0X25,0X2B,0X30,0X33,0X33,0X38,0X3F,0X47,0X50,0X59,0X62,0X6A,0X73,0X7C, + 0X85,0X8D,0X61,0X03,0XE5,0X00,0X07,0X01,0X02,0X03,0X04,0X05,0X06,0X07,0X09,0X80, + 0X0A,0X0B,0X13,0X3F,0X47,0X50,0X59,0X62,0X6A,0X73,0X7C,0X85,0X5C,0X03,0X98,0X00, + 0X01,0X01,0X03,0XD4,0X00,0X0A,0X0A,0X3F,0X47,0X50,0X59,0X62,0X6A,0X73,0X7C,0X57, + 0X03,0X98,0X00,0X02,0X01,0X29,0X0A,0XD4,0X00,0X09,0X0A,0X3F,0X47,0X50,0X59,0X62, + 0X6A,0X73,0X51,0X03,0X98,0X00,0X03,0X02,0X2E,0X3F,0X0A,0XD4,0X00,0X08,0X0A,0X3F, + 0X47,0X50,0X59,0X62,0X6A,0X4B,0X02,0X98,0X00,0X04,0X02,0X34,0X47,0X3F,0X0A,0XD4, + 0X00,0X07,0X0A,0X3F,0X47,0X50,0X59,0X62,0X45,0X02,0X98,0X00,0X05,0X02,0X3A,0X50, + 0X47,0X3F,0X0A,0XD4,0X00,0X06,0X0A,0X3F,0X47,0X50,0X59,0X40,0X02,0X98,0X00,0X06, + 0X02,0X40,0X59,0X50,0X47,0X3F,0X0A,0XD4,0X00,0X05,0X0A,0X3F,0X47,0X50,0X3A,0X02, + 0X98,0X00,0X07,0X02,0X45,0X62,0X59,0X50,0X47,0X3F,0X0A,0XD4,0X00,0X04,0X0A,0X3F, + 0X47,0X34,0X02,0X98,0X00,0X08,0X02,0X4B,0X6A,0X62,0X59,0X50,0X47,0X3F,0X0A,0XD4, + 0X00,0X03,0X0A,0X3F,0X2E,0X02,0X98,0X00,0X09,0X03,0X51,0X73,0X6A,0X62,0X59,0X50, + 0X47,0X3F,0X0A,0XD4,0X00,0X02,0X0A,0X29,0X01,0X98,0X00,0X0A,0X03,0X57,0X7C,0X73, + 0X6A,0X62,0X59,0X50,0X47,0X3F,0X0A,0XD4,0X00,0X01,0X03,0X01,0X98,0X00,0X0B,0X03, + 0X5C,0X85,0X7C,0X73,0X6A,0X62,0X59,0X50,0X47,0X3F,0X13,0X80,0X0A,0X07,0X09,0X07, + 0X06,0X05,0X04,0X03,0X02,0X01,0XE5,0X00,0X17,0X03,0X61,0X8D,0X85,0X7C,0X73,0X6A, + 0X62,0X59,0X50,0X47,0X3F,0X38,0X33,0X33,0X30,0X2B,0X25,0X1F,0X1A,0X14,0X0E,0X08, + 0X03,0XE4,0X00,0X18,0X03,0X64,0X94,0X8D,0X85,0X7C,0X73,0X6A,0X62,0X59,0X50,0X47, + 0X3F,0X38,0X33,0X33,0X30,0X2B,0X25,0X1F,0X1A,0X14,0X0E,0X08,0X03,0XE3,0X00,0X19, + 0X03,0X64,0X99,0X94,0X8D,0X85,0X7C,0X73,0X6A,0X62,0X59,0X50,0X47,0X3F,0X38,0X33, + 0X33,0X30,0X2B,0X25,0X1F,0X1A,0X14,0X0E,0X08,0X03,0XE2,0X00,0X1A,0X03,0X64,0X99, + 0X99,0X94,0X8D,0X85,0X7C,0X73,0X6A,0X62,0X59,0X50,0X47,0X3F,0X38,0X33,0X33,0X30, + 0X2B,0X25,0X1F,0X1A,0X14,0X0E,0X08,0X03,0XE1,0X00,0X01,0X03,0X64,0X80,0X99,0X16, + 0X94,0X8D,0X85,0X7C,0X73,0X6A,0X62,0X59,0X50,0X47,0X3F,0X38,0X33,0X33,0X30,0X2B, + 0X25,0X1F,0X1A,0X14,0X0E,0X08,0X03,0XE1,0X00,0X00,0X2A,0X81,0X5C,0X16,0X59,0X55, + 0X50,0X4A,0X45,0X40,0X3B,0X35,0X30,0X2B,0X26,0X22,0X1F,0X1F,0X1D,0X1A,0X16,0X13, + 0X0F,0X0C,0X08,0X05,0X02,0XFF,0X00,0XFF,0X00,0XDA,0X00,0X74,0X38,0X6D,0X6B,0X00, + 0X00,0X40,0X08,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF, + 0XFF,0XFF,0XFF +}; diff --git a/client/autocorr.cpp b/client/autocorr.cpp new file mode 100644 index 0000000..68ec470 --- /dev/null +++ b/client/autocorr.cpp @@ -0,0 +1,166 @@ +// Copyright 2011 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + + +#include "sah_config.h" + +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOINC_APP_GRAPHICS +#include "graphics2.h" +#endif + +#include "util.h" +#include "s_util.h" +#include "analyze.h" +#include "gaussfit.h" +#include "seti.h" +#include "chirpfft.h" +#include "analyzeReport.h" +#include "analyzePoT.h" +#ifdef BOINC_APP_GRAPHICS +#include "sah_gfx_main.h" +#endif + +#include "../db/schema_master.h" + +#define UNSTDMAX(a,b) (((a) > (b)) ? (a) : (b)) +#define UNSTDMIN(a,b) (((a) < (b)) ? (a) : (b)) + +unsigned int pow2a(unsigned int num) +{ + unsigned int n = num > 0 ? num - 1 : 0; + n |= n >> 1; + n |= n >> 2; + n |= n >> 4; + n |= n >> 8; + n |= n >> 16; + n++; + + return n >> 1; +} + +int FindAutoCorrelation( + float * AutoCorrelation, + int ul_NumDataPoints, + int fft_num, + SETI_WU_INFO& swi +) { + // Because positive and negative delays are the same + // we only have to look at half the points + int i, j, k, m, retval, blksize; + float temp; + float total, MeanPower, partial; + AUTOCORR_INFO ai; + + i = j = k = m = 0; + total = 0.0f; + + int len = ul_NumDataPoints/2; + blksize = UNSTDMAX(4, UNSTDMIN(pow2a((unsigned int) sqrt((float) (len / 32)) * 32), 512)); + + for(int b = 0; b < len/blksize; b++) { + partial = 0.0f; + for(i = 0; i < blksize; i++) { + AutoCorrelation[b*blksize+i]*=AutoCorrelation[b*blksize+i]; + partial += AutoCorrelation[b*blksize+i]; + } + total += partial; + } + MeanPower = total / ul_NumDataPoints; + + // Here we extract the autocorrs_to_report highest power events, + // outputing them as we go. + // Index usage: + // i : walk power spectrum us_NumToReport times + // j : walks power spectrum for each i + // k : marks current high power candidate while j walks on + // m : marks the current tail of the high power hit "list" + + + for (i = 0; i < swi.analysis_cfg.autocorr_per_spectrum; i++) { + + temp = 0.0; + + // Walk the array, looking for the first/next highest power. + // Start j at 1, in order to skip the DC (ie 0) bin. + // NOTE: this is a simple scan for high powers. Nice and fast + // for a very low i. If i is substantial, this code should be + // replaced with an index (q)sort. + for (j = 1; j < ul_NumDataPoints/2; j++) { + + if (AutoCorrelation[j] > temp) { + if (AutoCorrelation[j] < AutoCorrelation[m] || m == 0) { + temp = AutoCorrelation[j]; + k = j; + } + } + } // temp now = first/next highest power and k = it's bin number + + m = k; // save the "lowest" highest. + + // autocorr info + ai.a.peak_power = temp/MeanPower; + ai.a.mean_power = 1.0; + ai.bin = k; + ai.fft_ind = fft_num; + ai.a.chirp_rate = ChirpFftPairs[analysis_state.icfft].ChirpRate; + ai.a.fft_len = ChirpFftPairs[analysis_state.icfft].FftLen; + ai.a.delay = ((float)ai.bin)/swi.subband_sample_rate; + ai.a.freq = swi.subband_center; + double t_offset=((double)ai.fft_ind+0.5)*(double)ai.a.fft_len/ + swi.subband_sample_rate; + ai.a.detection_freq=calc_detection_freq(ai.a.freq,ai.a.chirp_rate,t_offset); + ai.a.time = swi.time_recorded + t_offset / 86400.0; + time_to_ra_dec(ai.a.time, &ai.a.ra, &ai.a.decl); + + // Score used for "best of" and graphics. + ai.score = ai.a.peak_power / AUTOCORR_SCORE_HIGH; + ai.score = ai.score > 0.0 ? log10(ai.score) : -12.0; + // if best_autocorr.s.fft_len == 0, there is not yet a first autocorr + if (ai.score > best_autocorr->score || best_autocorr->a.fft_len == 0) { + *best_autocorr = ai; +#ifdef BOINC_APP_GRAPHICS + if (!nographics()) sah_graphics->ai.copy(&ai); +#endif + } + + // Report a signal if it excceeds threshold. + if (ai.a.peak_power > (swi.analysis_cfg.autocorr_thresh)) { + retval = result_autocorr(ai); + if (retval) SETIERROR(retval,"from result_autocorr()"); + } + } + return 0; +} + diff --git a/client/autocorr.h b/client/autocorr.h new file mode 100644 index 0000000..9f63287 --- /dev/null +++ b/client/autocorr.h @@ -0,0 +1,34 @@ +// Copyright 2011 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +int FindAutoCorrelation( + float * AutoCorrelation, + int ul_NumDataPoints, + int fft_num, + SETI_WU_INFO& swi +); + diff --git a/client/better_banner.jpg b/client/better_banner.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a293b80aeb9be58243841c4993768c6e119b8394 GIT binary patch literal 9068 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 literal 0 HcmV?d00001 diff --git a/client/chirpfft.cpp b/client/chirpfft.cpp new file mode 100644 index 0000000..4546eec --- /dev/null +++ b/client/chirpfft.cpp @@ -0,0 +1,270 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#include "sah_config.h" + +#include +#include +#include +#include + +#include "diagnostics.h" +#include "util.h" +#include "s_util.h" +#ifdef BOINC_APP_GRAPHICS +#include "sah_gfx_main.h" +#endif + + + +#include "seti_header.h" +#include "seti.h" +#include "util.h" +#include "filesys.h" +#include "s_util.h" +#include "analyze.h" +#include "worker.h" +#include "chirpfft.h" + +sh_sint8_t num_gaussian_searches; +sh_sint8_t num_pulse_searches; +sh_sint8_t num_triplet_searches; + +char * cfft_file = NULL; + +size_t GenChirpFftPairs( + ChirpFftPair_t ** ChirpFftPairs, + double * MinChirpStep +) { + + long i, j, max_fft_len; + double CRate; + double ChirpRes = swi.analysis_cfg.chirp_resolution; + double NumSamples = swi.nsamples; + double WUDuration = (double)(swi.nsamples/swi.subband_sample_rate); + double SlewRate=static_cast(swi.angle_range)/WUDuration; + long MaxGaussFFTLen=swi.nsamples/swi.analysis_cfg.gauss_pot_length; + + double BeamsPerWU = std::max(swi.true_angle_range/swi.beam_width,1.0); + long MinPulseFFTLen=(long)ceil(swi.nsamples/(swi.analysis_cfg.pulse_max*BeamsPerWU*swi.analysis_cfg.pulse_beams)); + long MaxPulseFFTLen= + std::min((unsigned long)(swi.nsamples/(swi.analysis_cfg.pulse_min*swi.analysis_cfg.pulse_beams*BeamsPerWU)), + (unsigned long)swi.analysis_cfg.pulse_fft_max); + long NumLimits = (long)swi.analysis_cfg.chirps.size(); + double * ChirpSteps ; + ChirpFftPair_t tmp; + std::map ChirpFftMap; + + // An arrays associated with the FFT length array. + ChirpSteps = (double *)calloc(swi.num_fft_lengths, sizeof(double)); + + // Each FFT length has a (different) associated chirp step. + CalcChirpSteps(ChirpSteps, MinChirpStep); + + // Lets simplify the logic for doing chirps by using the STL map + // container for sorting. + max_fft_len=swi.analysis_fft_lengths[swi.num_fft_lengths-1]; + for (i=0; i= swi.analysis_cfg.pot_min_slew) && + (SlewRate <= swi.analysis_cfg.pot_max_slew)); + tmp.PulseFind=0; + while (CRate <= swi.analysis_cfg.chirps[i].chirp_limit) { + // Pulse find on alternate chirp rates when fitting Gaussians + if ((SlewRate >= swi.analysis_cfg.pot_min_slew) && + (SlewRate <= swi.analysis_cfg.pot_max_slew)) { + tmp.PulseFind=!(tmp.PulseFind) && tmp.GaussFit + && (tmp.FftLen<=MaxPulseFFTLen) + && (tmp.FftLen>=MinPulseFFTLen); + // else pulse find when our FFT liength is in range... + } else { + tmp.PulseFind=(tmp.FftLen<=MaxPulseFFTLen) + && (tmp.FftLen>=MinPulseFFTLen); + } + // Force all chirp rates to be a multiple of the minimum step. + tmp.ChirpRate= + (tmp.ChirpRateInd=(int32_t)floor(CRate/(*MinChirpStep)+0.5)) + *(*MinChirpStep); + // Generate keys specifying the order of the chirps + // chirp_rate,sign,fft_length order... + sh_sint8_t key=static_cast(floor(CRate/(*MinChirpStep)+0.5))*2; + key*=max_fft_len*2; + key+=tmp.FftLen; + // Insert the positive chirp overwriting any existing with this + // key value; + ChirpFftMap[key]=tmp; + //fprintf(stderr,"%f %d %f\n",CRate,tmp.ChirpRateInd,tmp.ChirpRate); + //fflush(stderr); + // Now the negative chirps for non-zero chirp; + if (CRate != 0.0) { + tmp.ChirpRate*=-1; + tmp.ChirpRateInd*=-1; + key+=max_fft_len*2; // flip the bit representing the sign in the + // key + ChirpFftMap[key]=tmp; + } + CRate+=ChirpSteps[j]; + } // end while loop through chirp rates + } // end if + } // end for loop through fft lenngths + } // end for loop through cfft parameter table + + + // Copy our ordereds CFFT map into a more standard array + *ChirpFftPairs = (ChirpFftPair_t *)calloc(ChirpFftMap.size(),sizeof(ChirpFftPair_t)); + std::map::const_iterator p; + i=0; + for (p=ChirpFftMap.begin();p!=ChirpFftMap.end();p++) { + num_gaussian_searches+=(p->second.GaussFit*(p->second.FftLen-1)); + num_pulse_searches+=(sh_sint8_t)(p->second.PulseFind*(p->second.FftLen-1)*(NumSamples/p->second.FftLen)*log((double)NumSamples/p->second.FftLen)/log(2.0)); + num_triplet_searches+=(sh_sint8_t)(p->second.PulseFind*(p->second.FftLen-1)*(NumSamples/p->second.FftLen)*(NumSamples/p->second.FftLen)); + (*ChirpFftPairs)[i++]=p->second; + } + /* + fprintf( + stderr,"NumCfft=%d\n NumGauss="SINT8_FMT"\n NumPulse="SINT8_FMT"\n NumTriplet="SINT8_FMT"\n", + static_cast(ChirpFftMap.size()), + SINT8_FMT_CAST(num_gaussian_searches), + SINT8_FMT_CAST(num_pulse_searches), + SINT8_FMT_CAST(num_triplet_searches) + ); + */ + fflush(stderr); + + if (ChirpSteps) free (ChirpSteps); + return(ChirpFftMap.size()); +} + + +void CalcChirpSteps(double* ChirpSteps, double* MinChirpStep) { + + double ChirpRes = swi.analysis_cfg.chirp_resolution; + double NumSamples = swi.nsamples; + double WUDuration = (double)(swi.nsamples/swi.subband_sample_rate); + + + int i; + double SecondsInAnalysis; + double SlewRate=static_cast(swi.angle_range)/WUDuration; + long FftLen; + long MaxGaussFFTLen=swi.nsamples/swi.analysis_cfg.gauss_pot_length; + double BeamsPerWU = std::max(swi.true_angle_range/swi.beam_width,1.0); + long MinPulseFFTLen=(long)ceil(swi.nsamples/(swi.analysis_cfg.pulse_max*BeamsPerWU*swi.analysis_cfg.pulse_beams)); + long MaxPulseFFTLen= + std::min((unsigned long)(swi.nsamples/(swi.analysis_cfg.pulse_min*swi.analysis_cfg.pulse_beams*BeamsPerWU)), + (unsigned long)swi.analysis_cfg.pulse_fft_max); + long MaxTripletFFTLen=swi.nsamples/swi.analysis_cfg.triplet_min; + double SecondsInBeam = WUDuration/swi.true_angle_range*swi.beam_width; + + // For each FFT length, calculate the corresponding chirp + // step (in Hz/s), given the chirp resolution (in FFT bins). + // Keep track of the minimum chirp step. + + // The goal here is to have the drift be less than 1 bin over the + // duration of interest to the analysis. In the case of gaussians + // that duration is 2 beam crossings. In the case of pulses it's + // one beam crossing. In the case of spikes it's one fft length. + *MinChirpStep = 0.0; + for(i = 0; i < swi.num_fft_lengths; i++) { + FftLen = swi.analysis_fft_lengths[i]; + double SecondsInFFT = WUDuration / (NumSamples / FftLen); + // Are we going to do Gaussians? + if ((FftLen <= MaxGaussFFTLen) && + (SlewRate >= swi.analysis_cfg.pot_min_slew) && + (SlewRate <= swi.analysis_cfg.pot_max_slew)) { + SecondsInAnalysis = SecondsInBeam*2; + // In not, are we going to do pulses or triplets? + } else if ((FftLen<=MaxPulseFFTLen) && (FftLen<= MaxTripletFFTLen)) { + // Look for pulses over one beam crossing or one beam crossing + // at the pot_min_slew, whichever is lower. + SecondsInAnalysis = std::min(SecondsInBeam,swi.beam_width/swi.analysis_cfg.pot_min_slew); + } else { + SecondsInAnalysis = SecondsInFFT; + } + ChirpSteps[i] = ChirpRes / (SecondsInAnalysis * SecondsInFFT); + //fprintf(stderr,"%d %f\n",i,ChirpSteps[i]); + //fflush(stderr); + if(ChirpSteps[i] < *MinChirpStep || *MinChirpStep == 0.0) { + *MinChirpStep = ChirpSteps[i]; + } + } +} + + +bool VeryClose(double a, double b, double CloseEnough) { + + double Diff; + + Diff = fabs(a - b); + + if(Diff > CloseEnough) + return(false); + else + return(true); +} + + +int ReadCFftFile(ChirpFftPair_t ** ChirpFftPairs, double * MinChirpStep) { + + // ChirpFftSet_t ChirpFftSet; + ChirpFftPair_t * ChirpFftPair; + int NumChirpFftPairs; + FILE * cfftfp; + double ChirpRate; + int FftLen; + + NumChirpFftPairs = 0; + + cfftfp = boinc_fopen(cfft_file, "r"); + + ChirpFftPair = (ChirpFftPair_t*) calloc(1,sizeof(ChirpFftPair_t)); + + while(fscanf(cfftfp, "%lf %d", &ChirpRate, &FftLen) == 2) { + ChirpFftPair = (ChirpFftPair_t *)realloc( + (void *)ChirpFftPair, sizeof(ChirpFftPair_t)*(NumChirpFftPairs+1)); + if (ChirpFftPair == NULL) SETIERROR(MALLOC_FAILED, "ChirpFftPair == NULL"); + ChirpFftPair[NumChirpFftPairs].ChirpRate = ChirpRate; + ChirpFftPair[NumChirpFftPairs].FftLen = FftLen; + NumChirpFftPairs++; + } + + *ChirpFftPairs = ChirpFftPair; + *MinChirpStep = (float) TEST_MIN_CHIRP_STEP; + + fclose(cfftfp); + + return(NumChirpFftPairs); +} + diff --git a/client/chirpfft.h b/client/chirpfft.h new file mode 100644 index 0000000..693b91a --- /dev/null +++ b/client/chirpfft.h @@ -0,0 +1,58 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +#ifndef SAH_CHIRPFFT_H +#define SAH_CHIRPFFT_H + +#define TEST_MIN_CHIRP_STEP 0.002776 // chirps .5 bins with 128K point FFT + +// Variable (usually an array of such +// variables) to hold chirp/fft pairs. +typedef struct { + double ChirpRate; + int ChirpRateInd; // chirprate index (= ChirpRate / MinChirpStep) + int FftLen; + int GaussFit; + int PulseFind; +} +ChirpFftPair_t; + +size_t GenChirpFftPairs( + ChirpFftPair_t ** ChirpFftPairs, + double * MinChirpStep +); + +extern ChirpFftPair_t * ChirpFftPairs; +extern char * cfft_file; + +void CalcChirpSteps(double* ChirpSteps, double* MinChirpStep); + +bool VeryClose(double a, double b, double CloseEnough); + +int ReadCFftFile(ChirpFftPair_t ** ChirpFftPairs, double * MinChirpStep); + +#endif diff --git a/client/collect2_line_linux.csh b/client/collect2_line_linux.csh new file mode 100755 index 0000000..a0530e8 --- /dev/null +++ b/client/collect2_line_linux.csh @@ -0,0 +1,6 @@ +#! /bin/csh + +# Run this with the desired version number as the only operand. Ex: +# collect2_line 2.27 + +/usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.2.2/collect2 -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o setiathome_$1_i686-pc-linux-gnu /usr/lib/crt1.o /usr/lib/crti.o /usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.2.2/crtbegin.o -L. -L../../boinc/lib -L/usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.2.2 -L/usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.2.2/../../.. main.o analyzeFuncs.o analyzeReport.o analyzePoT.o pulsefind.o gaussfit.o lcgamm.o malloc_a.o seti.o seti_header.o timecvt.o s_util.o version.o worker.o chirpfft.o spike.o progress.o ../db/schema_master_client.o ../db/sqlrow_client.o ../db/sqlblob.o ../db/xml_util.o -looura -Bstatic -lstdc++ -Bdynamic -lz -lnsl -ldl -lboinc -Bstatic -lstdc++ -Bdynamic -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.2.2/crtend.o /usr/lib/crtn.o diff --git a/client/collect2_line_solaris.csh b/client/collect2_line_solaris.csh new file mode 100644 index 0000000..a2ff246 --- /dev/null +++ b/client/collect2_line_solaris.csh @@ -0,0 +1,6 @@ +#! /bin/csh + +# Run this with the desired version number as the only operand. Ex: +# collect2_line 2.27 + +/usr/local/gcc/bin/../lib/gcc-lib/sparc-sun-solaris2.7/3.0.4/collect2 -V -Y P,/usr/ccs/lib:/usr/lib -Qy -o setiathome_${1}_sparc-sun-solaris2.7 /usr/local/gcc/bin/../lib/gcc-lib/sparc-sun-solaris2.7/3.0.4/crt1.o /usr/local/gcc/bin/../lib/gcc-lib/sparc-sun-solaris2.7/3.0.4/crti.o /usr/ccs/lib/values-Xa.o /usr/local/gcc/bin/../lib/gcc-lib/sparc-sun-solaris2.7/3.0.4/crtbegin.o -L. -L../../boinc/lib -L/usr/local/gcc/bin/../lib/gcc-lib/sparc-sun-solaris2.7/3.0.4 -L/usr/local/gcc/bin/../lib/gcc-lib -L/usr/local/gcc-3.0.4/lib/gcc-lib/sparc-sun-solaris2.7/3.0.4 -L/usr/ccs/bin -L/usr/ccs/lib -L/usr/local/gcc/bin/../lib/gcc-lib/sparc-sun-solaris2.7/3.0.4/../../.. -L/usr/local/gcc-3.0.4/lib/gcc-lib/sparc-sun-solaris2.7/3.0.4/../../.. main.o analyzeFuncs.o analyzeReport.o analyzePoT.o pulsefind.o gaussfit.o lcgamm.o malloc_a.o seti.o seti_header.o timecvt.o s_util.o version.o worker.o chirpfft.o spike.o progress.o ../db/schema_master_client.o ../db/sqlrow_client.o ../db/sqlblob.o ../db/xml_util.o -looura -B static -lstdc++ -B dynamic -lz -lsocket -lnsl -lelf -ldl -laio -lboinc -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/local/gcc/bin/../lib/gcc-lib/sparc-sun-solaris2.7/3.0.4/crtend.o /usr/local/gcc/bin/../lib/gcc-lib/sparc-sun-solaris2.7/3.0.4/crtn.o diff --git a/client/fft8g.cpp b/client/fft8g.cpp new file mode 100644 index 0000000..1ed485b --- /dev/null +++ b/client/fft8g.cpp @@ -0,0 +1,1107 @@ +// This code is from the General Purpose FFT (Fast Fourier/Cosine/Sine Transform) Package. +// Copyright Takuya OOURA, 1996-2001 +// (Email: ooura@kurims.kyoto-u.ac.jp or ooura@mmm.t.u-tokyo.ac.jp) +// +// You may use, copy, modify and distribute this code for any purpose +// (include commercial use) and without fee. Please refer to this package +// when you modify this code. + +// $Id: fft8g.cpp,v 1.4.2.3 2006/12/14 22:21:45 korpela Exp $ +/* +NOTE ON USE BY SETI@HOME : All floating point objects were changed + from double precision to single precision. + The function prototypes below were placed + in file fft8g.h. + Also, the following unused transforms were + removed from the source: + rdft: Real Discrete Fourier Transform + ddct: Discrete Cosine Transform + ddst: Discrete Sine Transform + dfct: Cosine Transform of RDFT (Real Symmetric DFT) + dfst: Sine Transform of RDFT (Real Anti-symmetric DFT) + + Modified to use sincosf/sinf/cosf/atanf. Implementations of these are + in sincos.h for machines without + + +Fast Fourier/Cosine/Sine Transform + dimension :one + data length :power of 2 + decimation :frequency + radix :8, 4, 2 + data :inplace + table :use +functions + cdft: Complex Discrete Fourier Transform +function prototypes + void cdft(int, int, float *, int *, float *); + void rdft(int, int, float *, int *, float *); + void ddct(int, int, float *, int *, float *); + void ddst(int, int, float *, int *, float *); + void dfct(int, float *, float *, int *, float *); + void dfst(int, float *, float *, int *, float *); + + +-------- Complex DFT (Discrete Fourier Transform) -------- + [definition] + + X[k] = sum_j=0^n-1 x[j]*exp(2*pi*i*j*k/n), 0<=k + X[k] = sum_j=0^n-1 x[j]*exp(-2*pi*i*j*k/n), 0<=k + ip[0] = 0; // first time only + cdft(2*n, 1, a, ip, w); + + ip[0] = 0; // first time only + cdft(2*n, -1, a, ip, w); + [parameters] + 2*n :data length (int) + n >= 1, n = power of 2 + a[0...2*n-1] :input/output data (float *) + input data + a[2*j] = Re(x[j]), + a[2*j+1] = Im(x[j]), 0<=j= 2+sqrt(n) + strictly, + length of ip >= + 2+(1<<(int)(log(n+0.5)/log(2))/2). + ip[0],ip[1] are pointers of the cos/sin table. + w[0...n/2-1] :cos/sin table (float *) + w[],ip[] are initialized if ip[0] == 0. + [remark] + Inverse of + cdft(2*n, -1, a, ip, w); + is + cdft(2*n, 1, a, ip, w); + for (j = 0; j <= 2 * n - 1; j++) { + a[j] *= 1.0 / n; + } + . + + +Appendix : + The cos/sin table is recalculated when the larger table required. + w[] and ip[] are compatible with all routines. +*/ + +#include "sah_config.h" +#include "sincos.h" +#include "s_util.h" + +void fft8g_start() {} + + +void cdft(int n, int isgn, sah_complex *aa, int *ip, float *w) { + void makewt(int nw, int *ip, float *w); + void bitrv2(int n, int *ip, float *a); + void bitrv2conj(int n, int *ip, float *a); + void cftfsub(int n, float *a, float *w); + void cftbsub(int n, float *a, float *w); + + float *a=(float *)aa; + + if (n > (ip[0] << 2)) { + makewt(n >> 2, ip, w); + } + if (n > 4) { + if (isgn >= 0) { + bitrv2(n, ip + 2, a); + cftfsub(n, a, w); + } else { + bitrv2conj(n, ip + 2, a); + cftbsub(n, a, w); + } + } else if (n == 4) { + cftfsub(n, a, w); + } +} + + +/* -------- initializing routines -------- */ + + +#include + +void makewt(int nw, int *ip, float *w) { + void bitrv2(int n, int *ip, float *a); + int j, nwh; + float delta, x, y; + + ip[0] = nw; + ip[1] = 1; + if (nw > 2) { + nwh = nw >> 1; + delta = atanf(1.0) / nwh; + w[0] = 1; + w[1] = 0; + w[nwh] = cosf(delta * nwh); + w[nwh + 1] = w[nwh]; + if (nwh > 2) { + for (j = 2; j < nwh; j += 2) { + sincosf(delta*j,&y,&x); + w[j] = x; + w[j + 1] = y; + w[nw - j] = y; + w[nw - j + 1] = x; + } + for (j = nwh - 2; j >= 2; j -= 2) { + x = w[2 * j]; + y = w[2 * j + 1]; + w[nwh + j] = x; + w[nwh + j + 1] = y; + } + bitrv2(nw, ip + 2, w); + } + } +} + + +void makect(int nc, int *ip, float *c) { + int j, nch; + float delta; + + ip[1] = nc; + if (nc > 1) { + nch = nc >> 1; + delta = atanf(1.0f) / nch; + c[0] = cosf(delta * nch); + c[nch] = (0.5f * c[0]); + for (j = 1; j < nch; j++) { + sincosf(delta*j,c+nc-j,c+j); + c[j]*=0.5f; + c[nc-j]*=0.5f; + } + } +} + + +/* -------- child routines -------- */ + + +void bitrv2(int n, int *ip, float *a) { + int j, j1, k, k1, l, m, m2; + float xr, xi, yr, yi; + + ip[0] = 0; + l = n; + m = 1; + while ((m << 3) < l) { + l >>= 1; + for (j = 0; j < m; j++) { + ip[m + j] = ip[j] + l; + } + m <<= 1; + } + m2 = 2 * m; + if ((m << 3) == l) { + for (k = 0; k < m; k++) { + for (j = 0; j < k; j++) { + j1 = 2 * j + ip[k]; + k1 = 2 * k + ip[j]; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += m2; + k1 += 2 * m2; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += m2; + k1 -= m2; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += m2; + k1 += 2 * m2; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + } + j1 = 2 * k + m2 + ip[k]; + k1 = j1 + m2; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + } + } else { + for (k = 1; k < m; k++) { + for (j = 0; j < k; j++) { + j1 = 2 * j + ip[k]; + k1 = 2 * k + ip[j]; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += m2; + k1 += m2; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + } + } + } +} + + +void bitrv2conj(int n, int *ip, float *a) { + int j, j1, k, k1, l, m, m2; + float xr, xi, yr, yi; + + ip[0] = 0; + l = n; + m = 1; + while ((m << 3) < l) { + l >>= 1; + for (j = 0; j < m; j++) { + ip[m + j] = ip[j] + l; + } + m <<= 1; + } + m2 = 2 * m; + if ((m << 3) == l) { + for (k = 0; k < m; k++) { + for (j = 0; j < k; j++) { + j1 = 2 * j + ip[k]; + k1 = 2 * k + ip[j]; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += m2; + k1 += 2 * m2; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += m2; + k1 -= m2; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += m2; + k1 += 2 * m2; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + } + k1 = 2 * k + ip[k]; + a[k1 + 1] = -a[k1 + 1]; + j1 = k1 + m2; + k1 = j1 + m2; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + k1 += m2; + a[k1 + 1] = -a[k1 + 1]; + } + } else { + a[1] = -a[1]; + a[m2 + 1] = -a[m2 + 1]; + for (k = 1; k < m; k++) { + for (j = 0; j < k; j++) { + j1 = 2 * j + ip[k]; + k1 = 2 * k + ip[j]; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += m2; + k1 += m2; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + } + k1 = 2 * k + ip[k]; + a[k1 + 1] = -a[k1 + 1]; + a[k1 + m2 + 1] = -a[k1 + m2 + 1]; + } + } +} + + +void cftfsub(int n, float *a, float *w) { + void cft1st(int n, float *a, float *w); + void cftmdl(int n, int l, float *a, float *w); + int j, j1, j2, j3, l; + float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + + l = 2; + if (n >= 16) { + cft1st(n, a, w); + l = 16; + while ((l << 3) <= n) { + cftmdl(n, l, a, w); + l <<= 3; + } + } + if ((l << 1) < n) { + for (j = 0; j < l; j += 2) { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + x0r = a[j] + a[j1]; + x0i = a[j + 1] + a[j1 + 1]; + x1r = a[j] - a[j1]; + x1i = a[j + 1] - a[j1 + 1]; + x2r = a[j2] + a[j3]; + x2i = a[j2 + 1] + a[j3 + 1]; + x3r = a[j2] - a[j3]; + x3i = a[j2 + 1] - a[j3 + 1]; + a[j] = x0r + x2r; + a[j + 1] = x0i + x2i; + a[j2] = x0r - x2r; + a[j2 + 1] = x0i - x2i; + a[j1] = x1r - x3i; + a[j1 + 1] = x1i + x3r; + a[j3] = x1r + x3i; + a[j3 + 1] = x1i - x3r; + } + } else if ((l << 1) == n) { + for (j = 0; j < l; j += 2) { + j1 = j + l; + x0r = a[j] - a[j1]; + x0i = a[j + 1] - a[j1 + 1]; + a[j] += a[j1]; + a[j + 1] += a[j1 + 1]; + a[j1] = x0r; + a[j1 + 1] = x0i; + } + } +} + + +void cftbsub(int n, float *a, float *w) { + void cft1st(int n, float *a, float *w); + void cftmdl(int n, int l, float *a, float *w); + int j, j1, j2, j3, j4, j5, j6, j7, l; + float wn4r, x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, + y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, + y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i; + + l = 2; + if (n > 16) { + cft1st(n, a, w); + l = 16; + while ((l << 3) < n) { + cftmdl(n, l, a, w); + l <<= 3; + } + } + if ((l << 2) < n) { + wn4r = w[2]; + for (j = 0; j < l; j += 2) { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + j4 = j3 + l; + j5 = j4 + l; + j6 = j5 + l; + j7 = j6 + l; + x0r = a[j] + a[j1]; + x0i = -a[j + 1] - a[j1 + 1]; + x1r = a[j] - a[j1]; + x1i = -a[j + 1] + a[j1 + 1]; + x2r = a[j2] + a[j3]; + x2i = a[j2 + 1] + a[j3 + 1]; + x3r = a[j2] - a[j3]; + x3i = a[j2 + 1] - a[j3 + 1]; + y0r = x0r + x2r; + y0i = x0i - x2i; + y2r = x0r - x2r; + y2i = x0i + x2i; + y1r = x1r - x3i; + y1i = x1i - x3r; + y3r = x1r + x3i; + y3i = x1i + x3r; + x0r = a[j4] + a[j5]; + x0i = a[j4 + 1] + a[j5 + 1]; + x1r = a[j4] - a[j5]; + x1i = a[j4 + 1] - a[j5 + 1]; + x2r = a[j6] + a[j7]; + x2i = a[j6 + 1] + a[j7 + 1]; + x3r = a[j6] - a[j7]; + x3i = a[j6 + 1] - a[j7 + 1]; + y4r = x0r + x2r; + y4i = x0i + x2i; + y6r = x0r - x2r; + y6i = x0i - x2i; + x0r = x1r - x3i; + x0i = x1i + x3r; + x2r = x1r + x3i; + x2i = x1i - x3r; + y5r = wn4r * (x0r - x0i); + y5i = wn4r * (x0r + x0i); + y7r = wn4r * (x2r - x2i); + y7i = wn4r * (x2r + x2i); + a[j1] = y1r + y5r; + a[j1 + 1] = y1i - y5i; + a[j5] = y1r - y5r; + a[j5 + 1] = y1i + y5i; + a[j3] = y3r - y7i; + a[j3 + 1] = y3i - y7r; + a[j7] = y3r + y7i; + a[j7 + 1] = y3i + y7r; + a[j] = y0r + y4r; + a[j + 1] = y0i - y4i; + a[j4] = y0r - y4r; + a[j4 + 1] = y0i + y4i; + a[j2] = y2r - y6i; + a[j2 + 1] = y2i - y6r; + a[j6] = y2r + y6i; + a[j6 + 1] = y2i + y6r; + } + } else if ((l << 2) == n) { + for (j = 0; j < l; j += 2) { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + x0r = a[j] + a[j1]; + x0i = -a[j + 1] - a[j1 + 1]; + x1r = a[j] - a[j1]; + x1i = -a[j + 1] + a[j1 + 1]; + x2r = a[j2] + a[j3]; + x2i = a[j2 + 1] + a[j3 + 1]; + x3r = a[j2] - a[j3]; + x3i = a[j2 + 1] - a[j3 + 1]; + a[j] = x0r + x2r; + a[j + 1] = x0i - x2i; + a[j2] = x0r - x2r; + a[j2 + 1] = x0i + x2i; + a[j1] = x1r - x3i; + a[j1 + 1] = x1i - x3r; + a[j3] = x1r + x3i; + a[j3 + 1] = x1i + x3r; + } + } else { + for (j = 0; j < l; j += 2) { + j1 = j + l; + x0r = a[j] - a[j1]; + x0i = -a[j + 1] + a[j1 + 1]; + a[j] += a[j1]; + a[j + 1] = -a[j + 1] - a[j1 + 1]; + a[j1] = x0r; + a[j1 + 1] = x0i; + } + } +} + + +void cft1st(int n, float *a, float *w) { + int j, k1; + float wn4r, wtmp, wk1r, wk1i, wk2r, wk2i, wk3r, wk3i, + wk4r, wk4i, wk5r, wk5i, wk6r, wk6i, wk7r, wk7i; + float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, + y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, + y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i; + + wn4r = w[2]; + x0r = a[0] + a[2]; + x0i = a[1] + a[3]; + x1r = a[0] - a[2]; + x1i = a[1] - a[3]; + x2r = a[4] + a[6]; + x2i = a[5] + a[7]; + x3r = a[4] - a[6]; + x3i = a[5] - a[7]; + y0r = x0r + x2r; + y0i = x0i + x2i; + y2r = x0r - x2r; + y2i = x0i - x2i; + y1r = x1r - x3i; + y1i = x1i + x3r; + y3r = x1r + x3i; + y3i = x1i - x3r; + x0r = a[8] + a[10]; + x0i = a[9] + a[11]; + x1r = a[8] - a[10]; + x1i = a[9] - a[11]; + x2r = a[12] + a[14]; + x2i = a[13] + a[15]; + x3r = a[12] - a[14]; + x3i = a[13] - a[15]; + y4r = x0r + x2r; + y4i = x0i + x2i; + y6r = x0r - x2r; + y6i = x0i - x2i; + x0r = x1r - x3i; + x0i = x1i + x3r; + x2r = x1r + x3i; + x2i = x1i - x3r; + y5r = wn4r * (x0r - x0i); + y5i = wn4r * (x0r + x0i); + y7r = wn4r * (x2r - x2i); + y7i = wn4r * (x2r + x2i); + a[2] = y1r + y5r; + a[3] = y1i + y5i; + a[10] = y1r - y5r; + a[11] = y1i - y5i; + a[6] = y3r - y7i; + a[7] = y3i + y7r; + a[14] = y3r + y7i; + a[15] = y3i - y7r; + a[0] = y0r + y4r; + a[1] = y0i + y4i; + a[8] = y0r - y4r; + a[9] = y0i - y4i; + a[4] = y2r - y6i; + a[5] = y2i + y6r; + a[12] = y2r + y6i; + a[13] = y2i - y6r; + if (n > 16) { + wk1r = w[4]; + wk1i = w[5]; + x0r = a[16] + a[18]; + x0i = a[17] + a[19]; + x1r = a[16] - a[18]; + x1i = a[17] - a[19]; + x2r = a[20] + a[22]; + x2i = a[21] + a[23]; + x3r = a[20] - a[22]; + x3i = a[21] - a[23]; + y0r = x0r + x2r; + y0i = x0i + x2i; + y2r = x0r - x2r; + y2i = x0i - x2i; + y1r = x1r - x3i; + y1i = x1i + x3r; + y3r = x1r + x3i; + y3i = x1i - x3r; + x0r = a[24] + a[26]; + x0i = a[25] + a[27]; + x1r = a[24] - a[26]; + x1i = a[25] - a[27]; + x2r = a[28] + a[30]; + x2i = a[29] + a[31]; + x3r = a[28] - a[30]; + x3i = a[29] - a[31]; + y4r = x0r + x2r; + y4i = x0i + x2i; + y6r = x0r - x2r; + y6i = x0i - x2i; + x0r = x1r - x3i; + x0i = x1i + x3r; + x2r = x1r + x3i; + x2i = x3r - x1i; + y5r = wk1i * x0r - wk1r * x0i; + y5i = wk1i * x0i + wk1r * x0r; + y7r = wk1r * x2r + wk1i * x2i; + y7i = wk1r * x2i - wk1i * x2r; + x0r = wk1r * y1r - wk1i * y1i; + x0i = wk1r * y1i + wk1i * y1r; + a[18] = x0r + y5r; + a[19] = x0i + y5i; + a[26] = y5i - x0i; + a[27] = x0r - y5r; + x0r = wk1i * y3r - wk1r * y3i; + x0i = wk1i * y3i + wk1r * y3r; + a[22] = x0r - y7r; + a[23] = x0i + y7i; + a[30] = y7i - x0i; + a[31] = x0r + y7r; + a[16] = y0r + y4r; + a[17] = y0i + y4i; + a[24] = y4i - y0i; + a[25] = y0r - y4r; + x0r = y2r - y6i; + x0i = y2i + y6r; + a[20] = wn4r * (x0r - x0i); + a[21] = wn4r * (x0i + x0r); + x0r = y6r - y2i; + x0i = y2r + y6i; + a[28] = wn4r * (x0r - x0i); + a[29] = wn4r * (x0i + x0r); + k1 = 4; + for (j = 32; j < n; j += 16) { + k1 += 4; + wk1r = w[k1]; + wk1i = w[k1 + 1]; + wk2r = w[k1 + 2]; + wk2i = w[k1 + 3]; + wtmp = 2 * wk2i; + wk3r = wk1r - wtmp * wk1i; + wk3i = wtmp * wk1r - wk1i; + wk4r = 1 - wtmp * wk2i; + wk4i = wtmp * wk2r; + wtmp = 2 * wk4i; + wk5r = wk3r - wtmp * wk1i; + wk5i = wtmp * wk1r - wk3i; + wk6r = wk2r - wtmp * wk2i; + wk6i = wtmp * wk2r - wk2i; + wk7r = wk1r - wtmp * wk3i; + wk7i = wtmp * wk3r - wk1i; + x0r = a[j] + a[j + 2]; + x0i = a[j + 1] + a[j + 3]; + x1r = a[j] - a[j + 2]; + x1i = a[j + 1] - a[j + 3]; + x2r = a[j + 4] + a[j + 6]; + x2i = a[j + 5] + a[j + 7]; + x3r = a[j + 4] - a[j + 6]; + x3i = a[j + 5] - a[j + 7]; + y0r = x0r + x2r; + y0i = x0i + x2i; + y2r = x0r - x2r; + y2i = x0i - x2i; + y1r = x1r - x3i; + y1i = x1i + x3r; + y3r = x1r + x3i; + y3i = x1i - x3r; + x0r = a[j + 8] + a[j + 10]; + x0i = a[j + 9] + a[j + 11]; + x1r = a[j + 8] - a[j + 10]; + x1i = a[j + 9] - a[j + 11]; + x2r = a[j + 12] + a[j + 14]; + x2i = a[j + 13] + a[j + 15]; + x3r = a[j + 12] - a[j + 14]; + x3i = a[j + 13] - a[j + 15]; + y4r = x0r + x2r; + y4i = x0i + x2i; + y6r = x0r - x2r; + y6i = x0i - x2i; + x0r = x1r - x3i; + x0i = x1i + x3r; + x2r = x1r + x3i; + x2i = x1i - x3r; + y5r = wn4r * (x0r - x0i); + y5i = wn4r * (x0r + x0i); + y7r = wn4r * (x2r - x2i); + y7i = wn4r * (x2r + x2i); + x0r = y1r + y5r; + x0i = y1i + y5i; + a[j + 2] = wk1r * x0r - wk1i * x0i; + a[j + 3] = wk1r * x0i + wk1i * x0r; + x0r = y1r - y5r; + x0i = y1i - y5i; + a[j + 10] = wk5r * x0r - wk5i * x0i; + a[j + 11] = wk5r * x0i + wk5i * x0r; + x0r = y3r - y7i; + x0i = y3i + y7r; + a[j + 6] = wk3r * x0r - wk3i * x0i; + a[j + 7] = wk3r * x0i + wk3i * x0r; + x0r = y3r + y7i; + x0i = y3i - y7r; + a[j + 14] = wk7r * x0r - wk7i * x0i; + a[j + 15] = wk7r * x0i + wk7i * x0r; + a[j] = y0r + y4r; + a[j + 1] = y0i + y4i; + x0r = y0r - y4r; + x0i = y0i - y4i; + a[j + 8] = wk4r * x0r - wk4i * x0i; + a[j + 9] = wk4r * x0i + wk4i * x0r; + x0r = y2r - y6i; + x0i = y2i + y6r; + a[j + 4] = wk2r * x0r - wk2i * x0i; + a[j + 5] = wk2r * x0i + wk2i * x0r; + x0r = y2r + y6i; + x0i = y2i - y6r; + a[j + 12] = wk6r * x0r - wk6i * x0i; + a[j + 13] = wk6r * x0i + wk6i * x0r; + } + } +} + + +void cftmdl(int n, int l, float *a, float *w) { + int j, j1, j2, j3, j4, j5, j6, j7, k, k1, m; + float wn4r, wtmp, wk1r, wk1i, wk2r, wk2i, wk3r, wk3i, + wk4r, wk4i, wk5r, wk5i, wk6r, wk6i, wk7r, wk7i; + float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, + y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, + y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i; + + m = l << 3; + wn4r = w[2]; + for (j = 0; j < l; j += 2) { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + j4 = j3 + l; + j5 = j4 + l; + j6 = j5 + l; + j7 = j6 + l; + x0r = a[j] + a[j1]; + x0i = a[j + 1] + a[j1 + 1]; + x1r = a[j] - a[j1]; + x1i = a[j + 1] - a[j1 + 1]; + x2r = a[j2] + a[j3]; + x2i = a[j2 + 1] + a[j3 + 1]; + x3r = a[j2] - a[j3]; + x3i = a[j2 + 1] - a[j3 + 1]; + y0r = x0r + x2r; + y0i = x0i + x2i; + y2r = x0r - x2r; + y2i = x0i - x2i; + y1r = x1r - x3i; + y1i = x1i + x3r; + y3r = x1r + x3i; + y3i = x1i - x3r; + x0r = a[j4] + a[j5]; + x0i = a[j4 + 1] + a[j5 + 1]; + x1r = a[j4] - a[j5]; + x1i = a[j4 + 1] - a[j5 + 1]; + x2r = a[j6] + a[j7]; + x2i = a[j6 + 1] + a[j7 + 1]; + x3r = a[j6] - a[j7]; + x3i = a[j6 + 1] - a[j7 + 1]; + y4r = x0r + x2r; + y4i = x0i + x2i; + y6r = x0r - x2r; + y6i = x0i - x2i; + x0r = x1r - x3i; + x0i = x1i + x3r; + x2r = x1r + x3i; + x2i = x1i - x3r; + y5r = wn4r * (x0r - x0i); + y5i = wn4r * (x0r + x0i); + y7r = wn4r * (x2r - x2i); + y7i = wn4r * (x2r + x2i); + a[j1] = y1r + y5r; + a[j1 + 1] = y1i + y5i; + a[j5] = y1r - y5r; + a[j5 + 1] = y1i - y5i; + a[j3] = y3r - y7i; + a[j3 + 1] = y3i + y7r; + a[j7] = y3r + y7i; + a[j7 + 1] = y3i - y7r; + a[j] = y0r + y4r; + a[j + 1] = y0i + y4i; + a[j4] = y0r - y4r; + a[j4 + 1] = y0i - y4i; + a[j2] = y2r - y6i; + a[j2 + 1] = y2i + y6r; + a[j6] = y2r + y6i; + a[j6 + 1] = y2i - y6r; + } + if (m < n) { + wk1r = w[4]; + wk1i = w[5]; + for (j = m; j < l + m; j += 2) { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + j4 = j3 + l; + j5 = j4 + l; + j6 = j5 + l; + j7 = j6 + l; + x0r = a[j] + a[j1]; + x0i = a[j + 1] + a[j1 + 1]; + x1r = a[j] - a[j1]; + x1i = a[j + 1] - a[j1 + 1]; + x2r = a[j2] + a[j3]; + x2i = a[j2 + 1] + a[j3 + 1]; + x3r = a[j2] - a[j3]; + x3i = a[j2 + 1] - a[j3 + 1]; + y0r = x0r + x2r; + y0i = x0i + x2i; + y2r = x0r - x2r; + y2i = x0i - x2i; + y1r = x1r - x3i; + y1i = x1i + x3r; + y3r = x1r + x3i; + y3i = x1i - x3r; + x0r = a[j4] + a[j5]; + x0i = a[j4 + 1] + a[j5 + 1]; + x1r = a[j4] - a[j5]; + x1i = a[j4 + 1] - a[j5 + 1]; + x2r = a[j6] + a[j7]; + x2i = a[j6 + 1] + a[j7 + 1]; + x3r = a[j6] - a[j7]; + x3i = a[j6 + 1] - a[j7 + 1]; + y4r = x0r + x2r; + y4i = x0i + x2i; + y6r = x0r - x2r; + y6i = x0i - x2i; + x0r = x1r - x3i; + x0i = x1i + x3r; + x2r = x1r + x3i; + x2i = x3r - x1i; + y5r = wk1i * x0r - wk1r * x0i; + y5i = wk1i * x0i + wk1r * x0r; + y7r = wk1r * x2r + wk1i * x2i; + y7i = wk1r * x2i - wk1i * x2r; + x0r = wk1r * y1r - wk1i * y1i; + x0i = wk1r * y1i + wk1i * y1r; + a[j1] = x0r + y5r; + a[j1 + 1] = x0i + y5i; + a[j5] = y5i - x0i; + a[j5 + 1] = x0r - y5r; + x0r = wk1i * y3r - wk1r * y3i; + x0i = wk1i * y3i + wk1r * y3r; + a[j3] = x0r - y7r; + a[j3 + 1] = x0i + y7i; + a[j7] = y7i - x0i; + a[j7 + 1] = x0r + y7r; + a[j] = y0r + y4r; + a[j + 1] = y0i + y4i; + a[j4] = y4i - y0i; + a[j4 + 1] = y0r - y4r; + x0r = y2r - y6i; + x0i = y2i + y6r; + a[j2] = wn4r * (x0r - x0i); + a[j2 + 1] = wn4r * (x0i + x0r); + x0r = y6r - y2i; + x0i = y2r + y6i; + a[j6] = wn4r * (x0r - x0i); + a[j6 + 1] = wn4r * (x0i + x0r); + } + k1 = 4; + for (k = 2 * m; k < n; k += m) { + k1 += 4; + wk1r = w[k1]; + wk1i = w[k1 + 1]; + wk2r = w[k1 + 2]; + wk2i = w[k1 + 3]; + wtmp = 2 * wk2i; + wk3r = wk1r - wtmp * wk1i; + wk3i = wtmp * wk1r - wk1i; + wk4r = 1 - wtmp * wk2i; + wk4i = wtmp * wk2r; + wtmp = 2 * wk4i; + wk5r = wk3r - wtmp * wk1i; + wk5i = wtmp * wk1r - wk3i; + wk6r = wk2r - wtmp * wk2i; + wk6i = wtmp * wk2r - wk2i; + wk7r = wk1r - wtmp * wk3i; + wk7i = wtmp * wk3r - wk1i; + for (j = k; j < l + k; j += 2) { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + j4 = j3 + l; + j5 = j4 + l; + j6 = j5 + l; + j7 = j6 + l; + x0r = a[j] + a[j1]; + x0i = a[j + 1] + a[j1 + 1]; + x1r = a[j] - a[j1]; + x1i = a[j + 1] - a[j1 + 1]; + x2r = a[j2] + a[j3]; + x2i = a[j2 + 1] + a[j3 + 1]; + x3r = a[j2] - a[j3]; + x3i = a[j2 + 1] - a[j3 + 1]; + y0r = x0r + x2r; + y0i = x0i + x2i; + y2r = x0r - x2r; + y2i = x0i - x2i; + y1r = x1r - x3i; + y1i = x1i + x3r; + y3r = x1r + x3i; + y3i = x1i - x3r; + x0r = a[j4] + a[j5]; + x0i = a[j4 + 1] + a[j5 + 1]; + x1r = a[j4] - a[j5]; + x1i = a[j4 + 1] - a[j5 + 1]; + x2r = a[j6] + a[j7]; + x2i = a[j6 + 1] + a[j7 + 1]; + x3r = a[j6] - a[j7]; + x3i = a[j6 + 1] - a[j7 + 1]; + y4r = x0r + x2r; + y4i = x0i + x2i; + y6r = x0r - x2r; + y6i = x0i - x2i; + x0r = x1r - x3i; + x0i = x1i + x3r; + x2r = x1r + x3i; + x2i = x1i - x3r; + y5r = wn4r * (x0r - x0i); + y5i = wn4r * (x0r + x0i); + y7r = wn4r * (x2r - x2i); + y7i = wn4r * (x2r + x2i); + x0r = y1r + y5r; + x0i = y1i + y5i; + a[j1] = wk1r * x0r - wk1i * x0i; + a[j1 + 1] = wk1r * x0i + wk1i * x0r; + x0r = y1r - y5r; + x0i = y1i - y5i; + a[j5] = wk5r * x0r - wk5i * x0i; + a[j5 + 1] = wk5r * x0i + wk5i * x0r; + x0r = y3r - y7i; + x0i = y3i + y7r; + a[j3] = wk3r * x0r - wk3i * x0i; + a[j3 + 1] = wk3r * x0i + wk3i * x0r; + x0r = y3r + y7i; + x0i = y3i - y7r; + a[j7] = wk7r * x0r - wk7i * x0i; + a[j7 + 1] = wk7r * x0i + wk7i * x0r; + a[j] = y0r + y4r; + a[j + 1] = y0i + y4i; + x0r = y0r - y4r; + x0i = y0i - y4i; + a[j4] = wk4r * x0r - wk4i * x0i; + a[j4 + 1] = wk4r * x0i + wk4i * x0r; + x0r = y2r - y6i; + x0i = y2i + y6r; + a[j2] = wk2r * x0r - wk2i * x0i; + a[j2 + 1] = wk2r * x0i + wk2i * x0r; + x0r = y2r + y6i; + x0i = y2i - y6r; + a[j6] = wk6r * x0r - wk6i * x0i; + a[j6 + 1] = wk6r * x0i + wk6i * x0r; + } + } + } +} + + +void rftfsub(int n, float *a, int nc, float *c) { + int j, k, kk, ks, m; + float wkr, wki, xr, xi, yr, yi; + + m = n >> 1; + ks = 2 * nc / m; + kk = 0; + for (j = 2; j < m; j += 2) { + k = n - j; + kk += ks; + wkr = static_cast(0.5 - c[nc - kk]); + wki = c[kk]; + xr = a[j] - a[k]; + xi = a[j + 1] + a[k + 1]; + yr = wkr * xr - wki * xi; + yi = wkr * xi + wki * xr; + a[j] -= yr; + a[j + 1] -= yi; + a[k] += yr; + a[k + 1] -= yi; + } +} + + +void rftbsub(int n, float *a, int nc, float *c) { + int j, k, kk, ks, m; + float wkr, wki, xr, xi, yr, yi; + + a[1] = -a[1]; + m = n >> 1; + ks = 2 * nc / m; + kk = 0; + for (j = 2; j < m; j += 2) { + k = n - j; + kk += ks; + wkr = 0.5f - c[nc - kk]; + wki = c[kk]; + xr = a[j] - a[k]; + xi = a[j + 1] + a[k + 1]; + yr = wkr * xr + wki * xi; + yi = wkr * xi - wki * xr; + a[j] -= yr; + a[j + 1] = yi - a[j + 1]; + a[k] += yr; + a[k + 1] = yi - a[k + 1]; + } + a[m + 1] = -a[m + 1]; +} + + +void dctsub(int n, float *a, int nc, float *c) { + int j, k, kk, ks, m; + float wkr, wki, xr; + + m = n >> 1; + ks = nc / n; + kk = 0; + for (j = 1; j < m; j++) { + k = n - j; + kk += ks; + wkr = c[kk] - c[nc - kk]; + wki = c[kk] + c[nc - kk]; + xr = wki * a[j] - wkr * a[k]; + a[j] = wkr * a[j] + wki * a[k]; + a[k] = xr; + } + a[m] *= c[0]; +} + + +void dstsub(int n, float *a, int nc, float *c) { + int j, k, kk, ks, m; + float wkr, wki, xr; + + m = n >> 1; + ks = nc / n; + kk = 0; + for (j = 1; j < m; j++) { + k = n - j; + kk += ks; + wkr = c[kk] - c[nc - kk]; + wki = c[kk] + c[nc - kk]; + xr = wki * a[k] - wkr * a[j]; + a[k] = wkr * a[k] + wki * a[j]; + a[j] = xr; + } + a[m] *= c[0]; +} + + +void fft8g_end() {} diff --git a/client/fft8g.h b/client/fft8g.h new file mode 100644 index 0000000..11ef259 --- /dev/null +++ b/client/fft8g.h @@ -0,0 +1,15 @@ +// This code is from the General Purpose FFT (Fast Fourier/Cosine/Sine Transform) Package. +// Copyright Takuya OOURA, 1996-2001 +// (Email: ooura@kurims.kyoto-u.ac.jp or ooura@mmm.t.u-tokyo.ac.jp) +// +// You may use, copy, modify and distribute this code for any purpose +// (include commercial use) and without fee. Please refer to this package +// when you modify this code. + +// $Id: fft8g.h,v 1.3.2.1 2005/05/19 00:42:30 korpela Exp $ +void cdft(int, int, sah_complex *, int *, float *); +void rdft(int, int, float *, int *, float *); +void ddct(int, int, float *, int *, float *); +void ddst(int, int, float *, int *, float *); +void dfct(int, float *, float *, int *, float *); +void dfst(int, float *, float *, int *, float *); diff --git a/client/gaussfit.cpp b/client/gaussfit.cpp new file mode 100644 index 0000000..d7eb598 --- /dev/null +++ b/client/gaussfit.cpp @@ -0,0 +1,516 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +// gaussfit.C +// $Id: gaussfit.cpp,v 1.21.2.12 2007/08/10 00:38:48 korpela Exp $ +// + +// The purpose of gaussian fitting is to find signals that rise and +// fall in power over time at a rate consistent with the beam +// pattern of the telescope. + +#include "sah_config.h" + +#include +#include + +#include + +// debug stuff +#define DEBUG_POT +//#define DUMP_POWER_SPECTRA +//#define DUMP_GAUSSIAN +#define POT_TO_DUMP 32 +#define TOFF_TO_DUMP 15 +#define FFT_TO_DUMP 131072 +int gul_PoT; +int gul_Fftl; +// end debug stuff + +#ifdef BOINC_APP_GRAPHICS +#include "sah_gfx_main.h" +#endif + +//#include "util.h" +#include "s_util.h" +#include "analyze.h" +#include "seti.h" +#include "worker.h" +#include "analyzeFuncs.h" +#include "analyzeReport.h" +#include "analyzePoT.h" +#include "lcgamm.h" +#include "gaussfit.h" +#include "chirpfft.h" + +bool dump_pot = false; +//float gauss_display_power_thresh = 0; + +float f_GetPeak( + float fp_PoT[], + int ul_TOffset, + int ul_HalfSumLength, + float f_MeanPower, + float f_PeakScaleFactor, + float f_weight[] +) { + // Peak power is calculated as the weighted + // sum of all powers within ul_HalfSumLength + // of the assumed gaussian peak. + // The weights are given by the gaussian function itself. + // BUG WATCH : for the f_PeakScaleFactor to work, + // ul_HalfSumLength *must* be set to sigma. + + int i; + float f_sum; + + f_sum = 0.0; + + // Find a weighted sum + for (i = ul_TOffset - ul_HalfSumLength; i <= ul_TOffset + ul_HalfSumLength; i++) { + f_sum += (fp_PoT[i] - f_MeanPower) * f_weight[abs(i-ul_TOffset)]; + } + + analysis_state.FLOP_counter+=6.0*ul_HalfSumLength; + return(f_sum * f_PeakScaleFactor); +} + +float f_GetChiSq( + float fp_PoT[], + int ul_PowerLen, + int ul_TOffset, + float f_PeakPower, + float f_MeanPower, + float f_weight[], + float *xsq_null=0 +) { + // We calculate our assumed gaussian powers + // on the fly as we try to fit them to the + // actual powers at each point along the PoT. + + int i; + float f_ChiSq=0,f_null_hyp=0, f_PredictedPower, f_tot_weight=0; + double rebin=swi.nsamples/ChirpFftPairs[analysis_state.icfft].FftLen + /ul_PowerLen; + + for (i = 0; i < ul_PowerLen; i++) { + f_PredictedPower = f_MeanPower + + f_PeakPower * f_weight[abs(i-ul_TOffset)] ; + f_tot_weight+=f_weight[abs(i-ul_TOffset)]; +#ifdef DUMP_GAUSSIAN + if ((gul_PoT == POT_TO_DUMP && ul_TOffset == TOFF_TO_DUMP) && + gul_Fftl == FFT_TO_DUMP) { + fprintf(stdout, "%f\n", f_PredictedPower); + } +#endif + // ChiSq in this realm is: + // sum[0:i]( (observed power - expected power)^2 / expected variance ) + // The power of a signal is: + // power = (noise + signal)^2 = noise^2 + signal^2 + 2*noise*signal + // With mean power normalization, noise becomes 1, leaving: + // power = signal^2 +or- 2*signal + 1 + f_PredictedPower/=f_MeanPower; + double signal=f_PredictedPower; + double noise=(2.0*sqrt(std::max(f_PredictedPower,1.0f)-1)+1); + + f_ChiSq += + (static_cast(rebin*SQUARE(fp_PoT[i]/f_MeanPower - signal)/noise)); + f_null_hyp+= + (static_cast(rebin*SQUARE(fp_PoT[i]/f_MeanPower-1)/noise)); + } + + analysis_state.FLOP_counter+=20.0*ul_PowerLen+5; + f_ChiSq/=ul_PowerLen; + f_null_hyp/=ul_PowerLen; + +#ifdef DUMP_GAUSSIAN + if (gul_PoT == POT_TO_DUMP + && ul_TOffset == TOFF_TO_DUMP + && gul_Fftl == FFT_TO_DUMP + ) { + for (i = 0; i < ul_PowerLen; i++) { + fprintf(stdout, "%f\n", fp_PoT[i]); + } + } +#endif + if (xsq_null) *xsq_null=f_null_hyp; + return f_ChiSq; +} + + +float f_GetTrueMean( + float fp_PoT[], + int ul_PowerLen, + float f_TotalPower, + int ul_TOffset, + int ul_ExcludeLen +) { + // TrueMean is the mean power of the data set minus all power + // out to ExcludeLen from our current TOffset. + int i, i_start, i_lim; + float f_ExcludePower = 0; + + // take care that we do not add to exclude power beyond PoT bounds! + i_start = std::max(ul_TOffset - ul_ExcludeLen, 0); + i_lim = std::min(ul_TOffset + ul_ExcludeLen + 1, swi.analysis_cfg.gauss_pot_length); + for (i = i_start; i < i_lim; i++) { + f_ExcludePower += fp_PoT[i]; + } + + analysis_state.FLOP_counter+=(double)(i_lim-i_start+5); + return((f_TotalPower - f_ExcludePower) / (ul_PowerLen - (i - i_start))); +} + + +float f_GetPeakScaleFactor(float f_sigma) { + // The PeakScaleFactor is calculated such that when used in f_GetPeak(), + // the actual peak power can be extracted from a weighted sum. + // This sum (see f_GetPeak()), is calculated as : + // sum = SUM[x from -sigma to +sigma] of (gaussian weights * our data) + // The gaussian weights are e^(-x^2 / sigma^2). + // Our data is A(e^(-x^2 / sigma^2)), where 'A' is the peak power. + // Through algebraic manipulation, we have: + // A = sum * (1 / SUM[x from -sigma to +sigma] of (e^(-x^2 / sigma^2))^2. + // The factor by which we multiply the sum is the PeakScaleFactor. + // It is completely determined by sigma. + + int i, i_s = static_cast(floor(f_sigma+0.5)); + float f_sigma_sq = f_sigma*f_sigma; + float f_sum = 0.0; + + for (i = -i_s; i <= i_s; i++) { + f_sum += static_cast(EXP(i, 0, f_sigma_sq)); + } + + analysis_state.FLOP_counter+=(13.0*f_sigma+3); + return(1 / f_sum); +} + + +int ChooseGaussEvent( + int ifft, + float PeakPower, + float TrueMean, + float ChiSq, + float null_ChiSq, + int bin, + float sigma, + float PoTMaxPower, + float fp_PoT[] +) { + + GAUSS_INFO gi; + float scale_factor; + bool report, chisqOK=(ChiSq <= swi.analysis_cfg.gauss_chi_sq_thresh); + + // gaussian info + gi.bin = bin; + gi.fft_ind = ifft; + gi.g.chirp_rate = ChirpFftPairs[analysis_state.icfft].ChirpRate; + gi.g.fft_len = ChirpFftPairs[analysis_state.icfft].FftLen; + gi.g.sigma = sigma; + gi.g.peak_power = PeakPower; + gi.g.mean_power = TrueMean; + gi.g.chisqr = ChiSq; + gi.g.null_chisqr = null_ChiSq; + gi.g.freq = cnvt_bin_hz(bin, gi.g.fft_len); + double t_offset=(((double)gi.fft_ind+0.5)/swi.analysis_cfg.gauss_pot_length)* + PoTInfo.WUDuration; + gi.g.detection_freq =calc_detection_freq(gi.g.freq,gi.g.chirp_rate,t_offset); + gi.g.time = swi.time_recorded+t_offset/86400.0; + gi.g.max_power = PoTMaxPower; + gi.score = -13.0; + time_to_ra_dec(gi.g.time, &gi.g.ra, &gi.g.decl); + + // Scale PoT down to 256 16 bit ints. + //for (i=0; i(gi.g.max_power) / 255.0f; + if (gi.g.pot.size() != static_cast(swi.analysis_cfg.gauss_pot_length)) { + gi.g.pot.set_size(swi.analysis_cfg.gauss_pot_length); + } + float_to_uchar(fp_PoT, &(gi.g.pot[0]), swi.analysis_cfg.gauss_pot_length, scale_factor); + + if (!swi.analysis_cfg.gauss_null_chi_sq_thresh) + swi.analysis_cfg.gauss_null_chi_sq_thresh=1.890; + // Gauss score used for "best of" and graphics. + // This score is now set to be based upon the probability that a signal + // would occur due to noise and the probability that it is shaped like + // a Gaussian (normalized to 0 at thresholds). Thanks to Tetsuji for + // making me think about this. The Gaussian has 62 degrees of freedom and + // the null hypothesis has 63 degrees of freedom when gauss_pot_length=64; + //JWS: Calculate invariant terms once, ala Alex Kan and Przemyslaw Zych + static float gauss_bins = static_cast(swi.analysis_cfg.gauss_pot_length); + static float gauss_dof = gauss_bins - 2.0f; + static float null_dof = gauss_bins - 1.0f; + static double score_offset = ( + lcgf(0.5*null_dof, swi.analysis_cfg.gauss_null_chi_sq_thresh*0.5*gauss_bins) + -lcgf(0.5*gauss_dof, swi.analysis_cfg.gauss_chi_sq_thresh*0.5*gauss_bins) + ); +//R: same optimization as for GPU build: if there is reportable Gaussian already - +//R: skip score calculation for all except new reportable Gaussians + // Final thresholding first. + report = chisqOK + && (gi.g.peak_power >= gi.g.mean_power * swi.analysis_cfg.gauss_peak_power_thresh) + && (gi.g.null_chisqr >= swi.analysis_cfg.gauss_null_chi_sq_thresh); + if (gaussian_count==0||report) { + gi.score = score_offset + +lcgf(0.5*gauss_dof,std::max(gi.g.chisqr*0.5*gauss_bins,0.5*gauss_dof+1)) + -lcgf(0.5*null_dof,std::max(gi.g.null_chisqr*0.5*gauss_bins,0.5*null_dof+1)); + } + // Only include "real" Gaussians (those meeting the chisqr threshold) + // in the best Gaussian display. + if (gi.score > best_gauss->score && chisqOK) { + *best_gauss = gi; + } + // Update gdata gauss info regardless of whether it is the + // best thus far or even passes the final threshold. If + // a gaussian has made it this far, display it. +#ifdef BOINC_APP_GRAPHICS + if (!nographics()) sah_graphics->gi.copy(&gi); +#endif + + + analysis_state.FLOP_counter+=24.0; + // Final reporting. + if (report) { + return result_gaussian(gi); + } + return 0; +} + + +int GaussFit( + float * fp_PoT, + int ul_FftLength, + int ul_PoT +) { + int i, retval; + BOOLEAN b_IsAPeak; + float f_NormMaxPower; + float f_null_hyp; + + int ul_TOffset; + int iSigma = static_cast(floor(PoTInfo.GaussSigma+0.5)); + float f_GroupSum, f_GroupMax; + int i_f, iPeakLoc; + + float f_TotalPower, + f_MeanPower, + f_TrueMean, + f_ChiSq, + f_PeakPower; + + // For setiathome the Sigma and Gaussian PoT length don't change during + // a run of the application, so these frequently used values can be + // precalculated and kept. + static float f_PeakScaleFactor; + static float *f_weight; + + if (!f_weight) { + f_PeakScaleFactor = f_GetPeakScaleFactor(static_cast(PoTInfo.GaussSigma)); + f_weight = reinterpret_cast(malloc(PoTInfo.GaussTOffsetStop*sizeof(float))); + if (!f_weight) SETIERROR(MALLOC_FAILED, "!f_weight"); + for (i = 0; i < PoTInfo.GaussTOffsetStop; i++) { + f_weight[i] = static_cast(EXP(i, 0, PoTInfo.GaussSigmaSq)); + } + } + // Find mean over power-of-time array + f_TotalPower = 0; + for (i = 0; i < swi.analysis_cfg.gauss_pot_length; i++) { + f_TotalPower += fp_PoT[i]; + } + f_MeanPower = f_TotalPower / swi.analysis_cfg.gauss_pot_length; + + // Normalize power-of-time and check for the existence + // of at least 1 peak. + b_IsAPeak = false; + double r_MeanPower=1.0/f_MeanPower; + for (i = 0; i < swi.analysis_cfg.gauss_pot_length; i++) { + fp_PoT[i] *= r_MeanPower; + if (fp_PoT[i] > PoTInfo.GaussPowerThresh) b_IsAPeak = true; + } + analysis_state.FLOP_counter+=3.0*swi.analysis_cfg.gauss_pot_length+2; + + if (!b_IsAPeak) { + //printf("no peak\n"); + return 0; // no peak - bail on this PoT + } + + // Recalculate Total Power across normalized array. + // Given that powers are positive, f_TotalPower will + // end up being == swi.analysis_cfg.gauss_pot_length. + f_TotalPower = 0; + f_NormMaxPower = 0; + // Also locate group with the highest sum for use in second bailout check. + f_GroupSum = 0; + f_GroupMax = 0; + for (i = 0, i_f = -iSigma; i < swi.analysis_cfg.gauss_pot_length; i++, i_f++) { + f_TotalPower += fp_PoT[i]; + if(fp_PoT[i] > f_NormMaxPower) f_NormMaxPower = fp_PoT[i]; + f_GroupSum += fp_PoT[i] - ((i_f < 0) ? 0.0f : fp_PoT[i_f]); + if (f_GroupSum > f_GroupMax) { + f_GroupMax = f_GroupSum; + iPeakLoc = i - iSigma/2; + } + } + + // Check at the group peak location whether data may contain Gaussians + // (but only after the first hurry-up Gaussian has been set for graphics) + + if (best_gauss->display_power_thresh != 0) { + iPeakLoc = std::max(PoTInfo.GaussTOffsetStart, + (std::min(PoTInfo.GaussTOffsetStop - 1, iPeakLoc))); + + f_TrueMean = f_GetTrueMean( + fp_PoT, + swi.analysis_cfg.gauss_pot_length, + f_TotalPower, + iPeakLoc, + 2 * iSigma + ); + + f_PeakPower = f_GetPeak( + fp_PoT, + iPeakLoc, + iSigma, + f_TrueMean, + f_PeakScaleFactor, + f_weight + ); + + analysis_state.FLOP_counter+=5.0*swi.analysis_cfg.gauss_pot_length+5; + + if (f_PeakPower < f_TrueMean*best_gauss->display_power_thresh*0.5f) { + return 0; // not even a weak peak at max group - bail on this PoT + } + } + + + // slide dynamic gaussian across the Power Of Time array + for (ul_TOffset = PoTInfo.GaussTOffsetStart; + ul_TOffset < PoTInfo.GaussTOffsetStop; + ul_TOffset++ + ) { + + // TrueMean is the mean power of the data set minus all power + // out to 2 sigma from our current TOffset. + f_TrueMean = f_GetTrueMean( + fp_PoT, + swi.analysis_cfg.gauss_pot_length, + f_TotalPower, + ul_TOffset, + 2 * iSigma + ); + + f_PeakPower = f_GetPeak( + fp_PoT, + ul_TOffset, + iSigma, + f_TrueMean, + f_PeakScaleFactor, + f_weight + ); + + // worth looking at ? + if (f_PeakPower < f_TrueMean*best_gauss->display_power_thresh) { + continue; + } + + // bump up the display threshold to its final value. + // We could bump it up only to the gaussian just found, + // but that would cause a lot of time waste + // computing chisq etc. + if (best_gauss->display_power_thresh == 0) { + best_gauss->display_power_thresh = PoTInfo.GaussPeakPowerThresh/3; + } + +#ifdef TEXT_UI + if(dump_pot) { + printf("Found good peak at this PoT element.... truemean is %f, power is %f\n", f_TrueMean, f_PeakPower); + } +#endif + +#ifdef DUMP_GAUSSIAN + gul_PoT = ul_PoT; + gul_Fftl = ul_FftLength; +#endif + + // look at it - try to fit + f_ChiSq = f_GetChiSq( + fp_PoT, + swi.analysis_cfg.gauss_pot_length, + ul_TOffset, + f_PeakPower, + f_TrueMean, + f_weight, + &f_null_hyp + ); + +#ifdef TEXT_UI + if(dump_pot) { + printf("Checking ChiSqr for PoT dump....\n"); + if(f_ChiSq <= swi.analysis_cfg.gauss_chi_sq_thresh) { + int dump_i; + printf( + "POT %d %f %f %f %f %d ", + ul_TOffset, + f_PeakPower, + f_TrueMean, + PoTInfo.GaussSigmaSq, + f_ChiSq, + ul_PoT + ); + for (dump_i = 0; dump_i < swi.analysis_cfg.gauss_pot_length; dump_i++) { + printf("%f ", fp_PoT[dump_i]); + } + printf("\n"); + } else { + printf("ChiSqr is %f, not good enough.\n", f_ChiSq); + } + } +#endif + + retval = ChooseGaussEvent( + ul_TOffset, + f_PeakPower, + f_TrueMean, + f_ChiSq, + f_null_hyp, + ul_PoT, + static_cast(PoTInfo.GaussSigma), + f_NormMaxPower, + fp_PoT + ); + if (retval) SETIERROR(retval,"from ChooseGaussEvent"); + + } // End of sliding gaussian + + return 0; + +} // End of gaussfit() + + diff --git a/client/gaussfit.h b/client/gaussfit.h new file mode 100644 index 0000000..db96e31 --- /dev/null +++ b/client/gaussfit.h @@ -0,0 +1,62 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +// Title : gaussfit.h +// $Id: gaussfit.h,v 1.3.2.2 2006/06/22 23:53:57 korpela Exp $ + +extern int GaussFit( + float * fp_PoT, + int ul_FftLength, + int ul_PoT + ); + +extern float f_GetPeak( + float fp_PoT[], + int ul_TOffset, + int ul_HalfSumLength, + float f_MeanPower, + float f_PeakScaleFactor, + float f_weight[] +); + +int ChooseGaussEvent( + int ifft, + float PeakPower, + float TrueMean, + float ChiSq, + float null_ChiSq, + int bin, + float sigma, + float PoTMaxPower, + float fp_PoT[] +); + +float f_GetPeakScaleFactor(float f_sigma); + +extern void gauss_display_init(); + +extern bool dump_pot; diff --git a/client/gdata.cpp b/client/gdata.cpp new file mode 100644 index 0000000..467cb31 --- /dev/null +++ b/client/gdata.cpp @@ -0,0 +1,97 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +#include "sah_config.h" +#include + +#include "seti.h" + +#include "gdata.h" + +// in each case, see if the signal being copied is the same +// as what's already there, and return if so. +// This prevents the dirty flag from being set spuriously +// + +void G_TRIPLET_INFO::copy(TRIPLET_INFO * ti, bool ib) { + int i; + if (peak_power==ti->t.peak_power && period==ti->t.period) return; + peak_power = ti->t.peak_power; + period = ti->t.period; + tpotind0_0 = ti->tpotind0_0; + tpotind0_1 = ti->tpotind0_1; + tpotind1_0 = ti->tpotind1_0; + tpotind1_1 = ti->tpotind1_1; + tpotind2_0 = ti->tpotind2_0; + tpotind2_1 = ti->tpotind2_1; + for (i=0; ipot_max[i]; + } + for (i=0; ipot_min[i]; + } + dirty = true; + is_best = ib; +} + +void G_PULSE_INFO::copy(PULSE_INFO * pi, bool ib) { + int i; + if (score==pi->score && peak_power==pi->p.peak_power) return; + peak_power = pi->p.peak_power; + period = pi->p.period; + score = pi->score; + for (i=0; ipot_max[i]; + } + //for (i=0; ipot_min[i]; + //} + dirty = true; + is_best = ib; +} + +void G_GAUSS_INFO::copy(GAUSS_INFO * gi, bool ib) { + size_t i; + if (score==gi->score && chisqr==gi->g.chisqr) return; + score = gi->score; + peak_power = gi->g.peak_power; + mean_power = gi->g.mean_power; + chisqr = gi->g.chisqr; + sigma = gi->g.sigma; + fft_ind = gi->fft_ind; + for (i=0; ig.pot.size(),static_cast(GAUSS_POT_LEN)); i++) { + pot[i] = gi->g.pot[i]; + } + dirty = true; + is_best = ib; +} + +void G_SPIKE_INFO::copy(SPIKE_INFO * si, bool ib) { +} + +void G_AUTOCORR_INFO::copy(AUTOCORR_INFO * si, bool ib) { +} diff --git a/client/gdata.h b/client/gdata.h new file mode 100644 index 0000000..8e7536b --- /dev/null +++ b/client/gdata.h @@ -0,0 +1,157 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +// $Id: gdata.h,v 1.16.2.5 2007/05/31 22:03:10 korpela Exp $ + +// GDATA is a collection of information generated by the worker thread +// that might be useful for graphics. +// It does not contain any user preference info, +// or anything related to a particular style of graphics. + +#ifndef _GDATA_ +#define _GDATA_ + +#include "sah_version.h" +#include "reduce.h" +#ifndef AP_CLIENT +#include "analyze.h" +#include + +struct GAUSS_INFO; +struct SPIKE_INFO; +struct AUTOCORR_INFO; +struct TRIPLET_INFO; +struct PULSE_INFO; + +// Power of time array sizes for graphics routines only. +#define GAUSS_POT_LEN 64 +#define PULSE_POT_LEN 256 +#define TRIPLET_POT_LEN 256 + +struct FFT_INFO { + double chirp_rate; + int fft_len; +}; + + +struct G_AUTOCORR_INFO { + void copy(AUTOCORR_INFO *, bool is_best=false); +}; + +struct G_SPIKE_INFO { + void copy(SPIKE_INFO *, bool is_best=false); +}; + +struct G_GAUSS_INFO { + double score; + bool is_best; // true if best score so far + bool dirty; // true if we haven't displayed this yet + double peak_power; + double mean_power; + double chisqr; + double sigma; + int fft_ind; // assigned in ReportGaussEvent() + float pot[GAUSS_POT_LEN]; + void copy(GAUSS_INFO *, bool is_best=false); + G_GAUSS_INFO() : score(0), is_best(false), dirty(false), peak_power(0), mean_power(0), chisqr(0), sigma(0), fft_ind(0) + { memset(pot,0,sizeof(pot)); }; +}; + +struct G_TRIPLET_INFO { + double peak_power; + double period; + bool is_best; + bool dirty; + int tpotind0_0; // index into pot_min/pot_max arrays + int tpotind0_1; // of start/end of first element of triplet + int tpotind1_0; // second element + int tpotind1_1; + int tpotind2_0; // and third element + int tpotind2_1; + unsigned int pot_min[TRIPLET_POT_LEN]; // Scaled 0-255 for display + unsigned int pot_max[TRIPLET_POT_LEN]; // Scaled 0-255 for display + void copy(TRIPLET_INFO *, bool is_best=false); + G_TRIPLET_INFO() : peak_power(0), period(0), is_best(false), dirty(false), tpotind0_0(0), tpotind0_1(0), + tpotind1_0(0), tpotind1_1(0), tpotind2_0(0), tpotind2_1(0) + { memset(pot_min,0,sizeof(pot_min)); memset(pot_max,0,sizeof(pot_max)); } +}; + +struct G_PULSE_INFO { + bool is_best; + bool dirty; + double peak_power; + double period; + double score; + unsigned int pot_max[PULSE_POT_LEN]; // Scaled 0-255 for display + void copy(PULSE_INFO *, bool is_best=false); + G_PULSE_INFO() : is_best(false), dirty(false), peak_power(0), period(0), score(0) + { memset(pot_max,0,sizeof(pot_max)); } +}; + +#endif + +struct G_SETI_WU_INFO { + char receiver_name[255]; + int s4_id; + double time_recorded; + double subband_base; + double start_ra, start_dec; + double subband_sample_rate; +}; + +struct GDATA { + int ready; + int version_major; + int version_minor; + double local_progress; + double progress; + double cpu_time; + volatile int countdown; + // the graphics app sets this to 5 every second, + // and the main app decrements it every second. + // So if it's zero, it means no graphics app is running + char status[80]; + +#ifndef AP_CLIENT + G_SETI_WU_INFO wu; + FFT_INFO fft_info; + G_SPIKE_INFO si; + G_AUTOCORR_INFO ai; + G_GAUSS_INFO gi; + G_TRIPLET_INFO ti; + G_PULSE_INFO pi; +#endif +}; + +// SAH_SHMEM is the shared-memory structure + +struct SAH_SHMEM { + GDATA gdata; + REDUCED_ARRAY_DATA rarray_data; +}; + +#endif diff --git a/client/graphics_main.cpp b/client/graphics_main.cpp new file mode 100644 index 0000000..ee82238 --- /dev/null +++ b/client/graphics_main.cpp @@ -0,0 +1,51 @@ +// Berkeley Open Infrastructure for Network Computing +// http://boinc.berkeley.edu +// Copyright (C) 2005 University of California +// +// This is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; +// either version 2.1 of the License, or (at your option) any later version. +// +// This software is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU Lesser General Public License for more details. +// +// To view the GNU Lesser General Public License visit +// http://www.gnu.org/copyleft/lesser.html +// or write to the Free Software Foundation, Inc., +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +// Example graphics application, paired with uc2.C +// This demonstrates: +// - using shared memory to communicate with the worker app +// - reading XML preferences by which users can customize graphics +// (in this case, select colors) +// - handle mouse input (in this case, to zoom and rotate) +// - draw text and 3D objects using OpenGL + +#ifdef _WIN32 +#include "boinc_win.h" +#else +#include +#include +#endif + +#include "boinc_api.h" +#include "graphics2.h" +#include "diagnostics.h" +#include "sah_gfx.h" + +SAH_GRAPHICS sah_graphics; +APP_INIT_DATA sah_aid; + +int main(int argc, char** argv) { + boinc_init_graphics_diagnostics(BOINC_DIAG_DEFAULTS); + boinc_parse_init_data_file(); + boinc_get_init_data(sah_aid); + if (sah_aid.project_preferences) { + sah_graphics.parse_project_prefs(sah_aid.project_preferences); + } + boinc_graphics_loop(argc, argv); +} diff --git a/client/lcgamm.cpp b/client/lcgamm.cpp new file mode 100644 index 0000000..791a977 --- /dev/null +++ b/client/lcgamm.cpp @@ -0,0 +1,163 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +/* + * $Id: lcgamm.cpp,v 1.9.2.11 2007/05/31 22:03:10 korpela Exp $ + */ +#include "sah_config.h" + +#if defined(_WIN32) && !defined(__MINGW32__) +#include +#endif + +#include +#include +#include +#include +#include +#include // delete me! + +#include "diagnostics.h" + +#define ITMAX 10000 // Needs to be a few times the sqrt of the max. input to lcgf +#define FP_EPS 1.0e-35 + +/* Log of the complete gamma function */ +static double gammln(double a) { + + double x,y,tmp,ser; + static double cof[6]={76.18009172947146,-86.50532032941677, + 24.01409824083091,-1.231739572450155, + 0.1208650973866179e-2,-0.5395239384953e-5}; + int j; + + y=x=a; + tmp=x+5.5; + tmp -= (x+0.5)*log(tmp); + ser=1.000000000190015; + for (j=0;j<=5;j++) ser += cof[j]/++y; + return (double)(-tmp+log(2.5066282746310005*ser/x)); +} + +/* Log of the compliment of the incomplete gamma function + * log(1-P(a,x)) valid only for (a+1)::epsilon(); + const double FPMIN=std::numeric_limits::min()/EPS; + double an,b,c,d,del,h,gln=gammln(a); + + // assert(x>=(a+1)); + BOINCASSERT(x>=(a+1)); + b=x+1.0-a; + c=1.0f/FPMIN; + d=1.0/b; + h=d; + for (i=1;i<=ITMAX;i++) { + an = -i*(i-a); + b += 2.0; + d=an*d+b; + if (fabs(d)=0); + + rts=0.5f*(xh+xl); + dxold=(float)fabs(xh-xl); + dx=dxold; + f=lcgf(a,rts)-y; + df=dlcgf(a,rts); + for (j=1;j<=ITMAX;j++) { + if ((((rts-xh)*df-f)*((rts-xl)*df-f) >= 0.0) + || (fabs(2.0*f)>fabs(dxold*df))) { + dxold=dx; + dx=0.5f*(xh-xl); + rts=xl+dx; + if ((xl==rts) || (xh==rts)) return rts; + } else { + dxold=dx; + dx=f/df; + temp=rts; + rts-=dx; + if (temp==rts) return rts; + } + f=lcgf(a,rts)-y; + df=dlcgf(a,rts); + if (fabs(f) +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#include +#include +#endif + + +#include "diagnostics.h" +#include "util.h" +#include "s_util.h" +#include "boinc_api.h" +#ifdef BOINC_APP_GRAPHICS +#include "sah_gfx_main.h" +#include "graphics2.h" +#endif + +#ifdef BOINC_APP_GRAPHICS + +#endif + +#include "util.h" +#include "s_util.h" +#include "str_util.h" +#include "str_replace.h" +#include "analyze.h" +#include "analyzeFuncs.h" +#include "analyzePoT.h" +#include "worker.h" +#include "sah_version.h" +#include "chirpfft.h" +#include "gaussfit.h" + +#ifdef __APPLE_CC__ +#include "app_icon.h" +#include +#endif + + +static int g_argc; +static char **g_argv; + +void usage() { + printf( + "options:\n" +#ifdef BOINC_APP_GRAPHICS + " -nographics run without graphics\n" + " -notranspose do not transpose data for pulse and gaussian searches\n" + " -default_functions use the safe unoptimized default functions\n" + " -standalone (implies -nographics)\n" +#else + " -standalone\n" +#endif + " -version show version info\n" + " -verbose print running status\n" + ); +} + +void print_error(int e) { + char* p; + + p = error_string(e); + fprintf(stderr,"%s\n",p); +} + +void print_version() { + printf( + "SETI@home client.\n" + "Version: %d.%02d\n", + gmajor_version, gminor_version + ); + printf( + "\nSETI@home is sponsored by individual donors around the world.\n" + "If you'd like to contribute to the project,\n" + "please visit the SETI@home web site at\n" + "http://setiathome.ssl.berkeley.edu.\n" + "The project is also sponsored by the Planetary Society,\n" + "the University of California, Sun Microsystems, Paramount Pictures,\n" + "Fujifilm Computer Products, Informix, Engineering Design Team Inc,\n" + "The Santa Cruz Operation (SCO), Intel, Quantum Corporation,\n" + "and the SETI Institute.\n\n" + "SETI@home was developed by David Gedye (Founder),\n" + "David Anderson (Director), Dan Werthimer (Chief Scientist),\n" + "Hiram Clawson, Jeff Cobb, Charlie Fenton,\n" + "Eric Heien, Eric Korpela, Matt Lebofsky,\n" + "Tetsuji 'Maverick' Rai and Rom Walton\n" + ); +} + +extern double sigma_thresh; +extern double f_PowerThresh; +extern double f_PeakPowerThresh; +extern double chi_sq_thresh; +bool notranspose_flag=false; +bool default_functions_flag=false; + +int run_stage; + + +typedef seti_error boinc_error; + +//void atexit_handler(void) { +// if (run_stage == GRXINIT) { +// fprintf(stderr,"Staring in non-graphical mode"); +// fflush(stderr); +// fclose(stderr); +// g_argv[g_argc]="-nographics"; +// execv(g_argv[0],g_argv); +// SETIERROR(UNHANDLED_SIGNAL, "from atexit_handler()"); +// } +//} + +extern APP_INIT_DATA app_init_data; + +int main(int argc, char** argv) { + int retval = 0, i; + FORCE_FRAME_POINTER; + run_stage=PREGRX; + g_argc=argc; + + if (!(g_argv=(char **)calloc(argc+2,sizeof(char *)))) { + exit(MALLOC_FAILED); + } + + + setbuf(stdout, 0); + + bool standalone = false; + g_argv[0]=argv[0]; + + for (i=1; i(e)); + } + return 0; +} + +#ifdef _WIN32 + + +// +// Function: WinMain +// +// Purpose: Application entry point, used instead of main so that on Win9x platforms +// windows do not appear for each instance executing on the system. +// +// Date: 01/29/04 +// +int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR Args, int WinMode) { + LPSTR command_line; + char* argv[100]; + int argc, retval; + + command_line = GetCommandLine(); + argc = parse_command_line(command_line,argv); + retval = main(argc, argv); + + return retval; +} + + +#endif diff --git a/client/malloc_a.cpp b/client/malloc_a.cpp new file mode 100644 index 0000000..937f58f --- /dev/null +++ b/client/malloc_a.cpp @@ -0,0 +1,138 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +// $Id: malloc_a.cpp,v 1.6.2.5 2007/05/31 22:03:10 korpela Exp $ +#include "sah_config.h" + +#include +#include +#ifdef HAVE_MEMORY_H +#include +#endif +#ifdef HAVE_MALLOC_H +#include +#endif + +//JWS: fftwf_malloc() is inadequate for AVX, XOP, and future SIMD > 128 bit +//#ifdef USE_FFTWF +//#include +//#endif + +#include "malloc_a.h" + +// for processor portability (e.g. 32/64/etc, bit processors) +typedef size_t PointerArith; + +// malloc_a and free_a are used to allocate one memory block + +// Allocates memory on N-byte boundary +// +// When fftwf is used, we use fftwf_malloc and ignore the alignment setting, +// since this guarantees proper alignment for SIMD types. +// +// On WIN32, we use _aligned_malloc() +// +// Where memalign() is available, we use it. +// +// If none of the above, we use our own algorithm. +// +// Layout in memory of the pointers and buffer: +// +// +-- malloc'd memory pointer +// | +// | +-- save malloc'd memory pointer here for use with free_a() +// V V +// +--------+---+------------------- ... +// | unused |ptr| aligned buffer +// +--------+---+------------------- ... +// ^ +// | +// +-- aligned memory pointer returned from malloc_a() +// +// +// +void *malloc_a(size_t size, size_t alignment) { +//#if defined(USE_FFTWF) +// return fftwf_malloc(size); +//#elif defined(HAVE__ALIGNED_MALLOC) +#if defined(HAVE__ALIGNED_MALLOC) + return _aligned_malloc(size,alignment); +#elif defined(HAVE_MEMALIGN) + return memalign(alignment,size); +#else + PointerArith byteAlignment; + void *pmem; + void *palignedMem; + void **pp; + + // ensure byteAlignment is positive (if alignment is 0, make it 1) + if (alignment < 1) { + alignment = 1; + } + byteAlignment = alignment - 1; + + pmem = (void *) malloc(size + byteAlignment + sizeof(void *)); // allocate memory + if (pmem == NULL) return NULL; + + // align memory on N byte boundary + palignedMem = (void *) (((PointerArith) pmem + byteAlignment + sizeof(void *)) & ~(byteAlignment)); + + pp = (void **) palignedMem; + pp[-1] = pmem; // store original address + + return(palignedMem); // return aligned memory +#endif +} + +//Frees memory that was allocated with malloc_a +void free_a(void *palignedMem) { +//#if defined(USE_FFTWF) +// fftwf_free(palignedMem); +//#elif defined(HAVE__ALIGNED_FREE) +#if defined(HAVE__ALIGNED_FREE) + _aligned_free(palignedMem); +#elif defined(HAVE_MEMALIGN) + free(palignedMem); +#else + void **pp; + + if (palignedMem == NULL) return; + + pp = (void **) palignedMem; + + //pp[-1] pts to original address of malloc'd memory + free(pp[-1]); +#endif +} + +void *calloc_a(size_t size, size_t nitems, size_t alignment) { + void* p = malloc_a(size*nitems, alignment); + if (p) + memset(p, 0, size*nitems); + return p; +} + diff --git a/client/malloc_a.h b/client/malloc_a.h new file mode 100644 index 0000000..aadde97 --- /dev/null +++ b/client/malloc_a.h @@ -0,0 +1,34 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +// $Id: malloc_a.h,v 1.5.2.2 2005/06/26 19:55:43 korpela Exp $ +// memory alignment multiple for large arrays +#define MEM_ALIGN 64 + +void* malloc_a(size_t size, size_t alignment); +void* calloc_a(size_t size, size_t nitems, size_t alignment); +void free_a(void *palignedMem); diff --git a/client/progress.cpp b/client/progress.cpp new file mode 100644 index 0000000..55a184b --- /dev/null +++ b/client/progress.cpp @@ -0,0 +1,189 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +// progress.C + +#include "sah_config.h" + +#include +#include +#include +#include + +#include "diagnostics.h" +#include "util.h" +#include "s_util.h" +#ifdef BOINC_APP_GRAPHICS +#include "sah_gfx_main.h" +#endif + + +#include "progress.h" +#include "analyzePoT.h" +#include "seti.h" +#include "chirpfft.h" + +double NormalizedToSpike = 0.0; + +double triplet_units; +double pulse_units; +double spike_units; +double gauss_units; + + +// fraction_done sets the boinc_fraction_done() with a smooth transition +// from using "progress" to "remaining" to determine the fraction done. +// The speed of the transition is determine by PROG_POWER. 6 means that +// "remaining" is the dominant term for about the final 1/6th of the run. +#define PROG_POWER 6 +void fraction_done(double progress,double remaining) { + double prog2=1.0-remaining; + progress=std::min(progress,1.0); + double prog=progress*(1.0-pow(prog2,PROG_POWER))+prog2*pow(prog2,PROG_POWER); + boinc_fraction_done(prog); +} + + +void reset_units() { + triplet_units=0; + pulse_units=0; + spike_units=0; + gauss_units=0; +} + +float GetProgressUnitSize(int NumDataPoints, int num_cfft) { + + // A ProgressUnit is defined as the computation time of a + // detection algorithm on the entire data block at a + // given chirpfft pair. + + // Spike detection takes place for every FFT length and at + // any slew rate. PoT detctors, on the other hand, may opt + // to not execute if slew rate and/or FFT length limits are + // not met. + + + int i, ThisPoTLen, ThisPulsePoTLen, DummyOverlap; + + double NumProgressUnits; + double LastChirpRate = 0.0f; + + double TotalSpikeProgressUnits = 0.0; + double TotalGaussianProgressUnits = 0.0; + double TotalPulseProgressUnits = 0.0; + double TotalTripletProgressUnits = 0.0; + double TotalChirpProgressUnits = 0.0; + NumProgressUnits = 0.0; + + for (i = 0; i < num_cfft; i++) { + + // FFTs and spike finding + TotalSpikeProgressUnits += SpikeProgressUnits(ChirpFftPairs[i].FftLen); + + // Chirping + if(ChirpFftPairs[i].ChirpRate != LastChirpRate) { + TotalChirpProgressUnits += ChirpProgressUnits(); + LastChirpRate = ChirpFftPairs[i].ChirpRate; + } + + ThisPoTLen = NumDataPoints / ChirpFftPairs[i].FftLen; + + // Gaussians.... + if (ChirpFftPairs[i].GaussFit) { + TotalGaussianProgressUnits += GaussianProgressUnits(); + } + + // Pulses and Triplets.... + GetPulsePoTLen(ThisPoTLen, &ThisPulsePoTLen, &DummyOverlap); +#ifdef USE_PULSE + if(ChirpFftPairs[i].PulseFind) + TotalPulseProgressUnits += PulseProgressUnits(ThisPulsePoTLen, ChirpFftPairs[i].FftLen - 1); +#endif +#ifdef USE_TRIPLET + if(ThisPulsePoTLen >= PoTInfo.TripletMin && ThisPulsePoTLen <= PoTInfo.TripletMax) + TotalTripletProgressUnits += TripletProgressUnits(); +#endif + + } + + NumProgressUnits = TotalChirpProgressUnits + + TotalSpikeProgressUnits + + TotalGaussianProgressUnits + + TotalPulseProgressUnits + + TotalTripletProgressUnits; + +/* + fprintf(stderr, "%f ChirpProgressUnits (%f\%)\n", TotalChirpProgressUnits, TotalChirpProgressUnits/NumProgressUnits); + fprintf(stderr, "%f SpikeProgressUnits (%f\%)\n", TotalSpikeProgressUnits, TotalSpikeProgressUnits/NumProgressUnits); + fprintf(stderr, "%f GaussianProgressUnits (%f\%)\n", TotalGaussianProgressUnits, TotalGaussianProgressUnits/NumProgressUnits); + fprintf(stderr, "%f TripletProgressUnits (%f\%)\n", TotalTripletProgressUnits, TotalTripletProgressUnits/NumProgressUnits); + fprintf(stderr, "%f PulseProgressUnits (%f\%)\n", TotalPulseProgressUnits, TotalPulseProgressUnits/NumProgressUnits); + fprintf(stderr, "%f NumProgressUnits\n", NumProgressUnits); +*/ + + // Add a fudge factor of 0.01% to make sure we do not hit 100% done too soon + return(1.0f/(float)(NumProgressUnits + NumProgressUnits * 0.0001)); +} + + + // Algorithm specific functions that return the number of progress + // units for the entire data block for some chirp/fft pair. All other + // algorithms are normalized to fft/spike finding, which is said + // to take 1.0 progress units. + + // If progress us updated at finer intervals than the computation + // on the entire data block, care must be taken to divide the + // return value by the number of such intervals in a data block. + // Eg, if you update for each FFT bin, divide the number of units + // by FFT length. + +double SpikeProgressUnits(int FftLen) { + spike_units+=(1.0+log((double)FftLen)/11.783); + return (1.0+log((double)FftLen)/11.783); +} + +double GaussianProgressUnits() { + gauss_units+=(14.5*0.6); + return(14.5*0.6); +} + +// Pulse finding is an (n^2)log(n) computation. The final factor +// is a scaling factor and can be tuned. +double PulseProgressUnits(double PulsePoTLen, int FftLen) { + pulse_units+=(PulsePoTLen * PulsePoTLen * log(PulsePoTLen) * FftLen / 2.65e6/4); + return(PulsePoTLen * PulsePoTLen * log(PulsePoTLen) * FftLen / 2.65e6/4); +} + +double TripletProgressUnits() { + triplet_units+=0.1; + return(0.1); +} + +double ChirpProgressUnits() { + + return (2.0); +} diff --git a/client/progress.h b/client/progress.h new file mode 100644 index 0000000..2f2b84f --- /dev/null +++ b/client/progress.h @@ -0,0 +1,44 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +// progress.h + +float GetProgressUnitSize(int NumDataPoints, int num_cfft); +double SpikeProgressUnits(int FftLen); +double GaussianProgressUnits(); +double PulseProgressUnits(double PulsePoTLen, int FftLen); +double TripletProgressUnits(); +double ChirpProgressUnits(); + +void fraction_done(double progress,double remaining); + +extern double triplet_units; +extern double pulse_units; +extern double spike_units; +extern double gauss_units; + +void reset_units(); diff --git a/client/pulsefind.cpp b/client/pulsefind.cpp new file mode 100644 index 0000000..de62663 --- /dev/null +++ b/client/pulsefind.cpp @@ -0,0 +1,1393 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + + +/* + * $Id: pulsefind.cpp,v 1.16.2.16 2007/08/10 00:38:48 korpela Exp $ + * + */ + +#include "sah_config.h" + +#include +#include +#include +#include +#include +#include + +#include "diagnostics.h" +#include "util.h" +#include "s_util.h" +#include "boinc_api.h" +#ifdef BOINC_APP_GRAPHICS +#include "sah_gfx_main.h" +#endif + +#include "seti.h" +#include "seti_header.h" +#include "analyzePoT.h" +#include "analyzeReport.h" +#include "worker.h" +#include "malloc_a.h" +#include "lcgamm.h" +#include "pulsefind.h" + +//#define DEBUG_TRIPLET_VERBOSE +//#define DEBUG_PULSE_VERBOSE +//#define DEBUG_PULSE_BOUNDS + + +/********************** + * + * find_triplets - Analyzes the input signal for a triplet signal. + * + * Written by Eric Heien. + */ +int find_triplets( const float *power, int len_power, float triplet_thresh, int time_bin, int freq_bin ) { + static int *binsAboveThreshold; + int i,n,numBinsAboveThreshold=0,p,q; + float midpoint,mean_power=0,peak_power,period; + + if (!binsAboveThreshold) { + binsAboveThreshold=(int *)malloc_a(PoTInfo.TripletMax*sizeof(int),MEM_ALIGN); + if (!binsAboveThreshold) SETIERROR(MALLOC_FAILED, "!binsAboveThreshold"); + } + + /* Get all the bins that are above the threshold, and find the power array mean value */ +#ifdef DEBUG_TRIPLET_VERBOSE + fprintf(stderr, "In find_triplets()... PulsePotLen = %d triplet_thresh = %f TOffset = %d PoT = %d\n", len_power, triplet_thresh, time_bin, freq_bin); +#endif + + for( i=0;i= triplet_thresh ) { + binsAboveThreshold[numBinsAboveThreshold] = i; + numBinsAboveThreshold++; + } + } + analysis_state.FLOP_counter+=10.0+len_power; + + /* Check each bin combination for a triplet */ + if (numBinsAboveThreshold>2) { + for( i=0;i peak_power ) + peak_power = power[binsAboveThreshold[n]]; + + p = binsAboveThreshold[i]; + while( (power[p] >= triplet_thresh) && (p <= (static_cast(floor(midpoint)))) ) { /* Check if there is a pulse "off" in between init and midpoint */ + p++; + } + + q = static_cast(floor(midpoint))+1; + while( (power[q] >= triplet_thresh) && (q <= binsAboveThreshold[n])) { /* Check if there is a pulse "off" in between midpoint and end */ + q++; + } + + if( p >= static_cast(floor(midpoint)) || q >= binsAboveThreshold[n]) { + /* if this pulse doesn't have an "off" between all the three spikes, it's dropped */ + } else if( (midpoint - floor(midpoint)) > 0.1f ) { /* if it's spread among two bins */ + if( power[(int)midpoint] >= triplet_thresh ) { + if( power[(int)midpoint] > peak_power ) + peak_power = power[(int)midpoint]; + + ReportTripletEvent( peak_power/mean_power, mean_power, period, midpoint,time_bin, freq_bin, len_power, power, 1 ); + } + + if( power[(int)(midpoint+1.0f)] >= triplet_thresh ) { + if( power[(int)(midpoint+1.0f)] > peak_power ) + peak_power = power[(int)(midpoint+1.0f)]; + + ReportTripletEvent( peak_power/mean_power, mean_power, period, midpoint,time_bin, freq_bin, len_power, power, 1 ); + } + } else { /* otherwise just check the single midpoint bin */ + if( power[(int)midpoint] >= triplet_thresh ) { + if( power[(int)midpoint] > peak_power ) + peak_power = power[(int)midpoint]; + + ReportTripletEvent( peak_power/mean_power, mean_power, period, midpoint,time_bin, freq_bin, len_power, power, 1 ); + } + } + } + } + } + analysis_state.FLOP_counter+=(10.0*numBinsAboveThreshold*numBinsAboveThreshold); + return (0); +} + + + +/********************** + * + * Pulse finding + * + * + * Default folding subroutines, FPU optimized + * + */ +float sw_sum3_t31(float *ss[], struct PoTPlan *P) { + float sum1, sum2, tmax2, tmax1; + int i = P->di; + float *one = ss[0]; + float *two = ss[0]+P->tmp0; + float *three = ss[0]+P->tmp1; + tmax2 = tmax1 = float(0.0); + + if ( i & 1 ) { + i -= 1; + tmax1 = one[i] + two[i]; + tmax1 += three[i]; + P->dest[i] = tmax1; + } + switch (i) { + case 30: + sum1 = one[29] + two[29]; sum2 = one[28] + two[28]; + sum1 += three[29]; sum2 += three[28]; + P->dest[29] = sum1; P->dest[28] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 28: + sum1 = one[27] + two[27]; sum2 = one[26] + two[26]; + sum1 += three[27]; sum2 += three[26]; + P->dest[27] = sum1; P->dest[26] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 26: + sum1 = one[25] + two[25]; sum2 = one[24] + two[24]; + sum1 += three[25]; sum2 += three[24]; + P->dest[25] = sum1; P->dest[24] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 24: + sum1 = one[23] + two[23]; sum2 = one[22] + two[22]; + sum1 += three[23]; sum2 += three[22]; + P->dest[23] = sum1; P->dest[22] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 22: + sum1 = one[21] + two[21]; sum2 = one[20] + two[20]; + sum1 += three[21]; sum2 += three[20]; + P->dest[21] = sum1; P->dest[20] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 20: + sum1 = one[19] + two[19]; sum2 = one[18] + two[18]; + sum1 += three[19]; sum2 += three[18]; + P->dest[19] = sum1; P->dest[18] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 18: + sum1 = one[17] + two[17]; sum2 = one[16] + two[16]; + sum1 += three[17]; sum2 += three[16]; + P->dest[17] = sum1; P->dest[16] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 16: + sum1 = one[15] + two[15]; sum2 = one[14] + two[14]; + sum1 += three[15]; sum2 += three[14]; + P->dest[15] = sum1; P->dest[14] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 14: + sum1 = one[13] + two[13]; sum2 = one[12] + two[12]; + sum1 += three[13]; sum2 += three[12]; + P->dest[13] = sum1; P->dest[12] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 12: + sum1 = one[11] + two[11]; sum2 = one[10] + two[10]; + sum1 += three[11]; sum2 += three[10]; + P->dest[11] = sum1; P->dest[10] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 10: + sum1 = one[9] + two[9]; sum2 = one[8] + two[8]; + sum1 += three[9]; sum2 += three[8]; + P->dest[9] = sum1; P->dest[8] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 8: + sum1 = one[7] + two[7]; sum2 = one[6] + two[6]; + sum1 += three[7]; sum2 += three[6]; + P->dest[7] = sum1; P->dest[6] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 6: + sum1 = one[5] + two[5]; sum2 = one[4] + two[4]; + sum1 += three[5]; sum2 += three[4]; + P->dest[5] = sum1; P->dest[4] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 4: + sum1 = one[3] + two[3]; sum2 = one[2] + two[2]; + sum1 += three[3]; sum2 += three[2]; + P->dest[3] = sum1; P->dest[2] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 2: + sum1 = one[1] + two[1]; sum2 = one[0] + two[0]; + sum1 += three[1]; sum2 += three[0]; + P->dest[1] = sum1; P->dest[0] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + } + if (tmax1 > tmax2) return tmax1; + return tmax2; +} +// +// use for higher sum3 folds +// +float top_sum3(float *ss[], struct PoTPlan *P) { + float sum1, sum2, tmaxB, tmax; + int i; + float *one = ss[0]; + float *two = ss[0]+P->tmp0; + float *three = ss[0]+P->tmp1; + tmaxB = tmax = float(0.0); + + for (i = 0 ; i < P->di-21; i += 22) { + sum1 = one[i+0] + two[i+0]; sum2 = one[i+1] + two[i+1]; + sum1 += three[i+0]; sum2 += three[i+1]; + P->dest[i+0] = sum1; P->dest[i+1] = sum2; + if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; + + sum1 = one[i+2] + two[i+2]; sum2 = one[i+3] + two[i+3]; + sum1 += three[i+2]; sum2 += three[i+3]; + P->dest[i+2] = sum1; P->dest[i+3] = sum2; + if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; + + sum1 = one[i+4] + two[i+4]; sum2 = one[i+5] + two[i+5]; + sum1 += three[i+4]; sum2 += three[i+5]; + P->dest[i+4] = sum1; P->dest[i+5] = sum2; + if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; + + sum1 = one[i+6] + two[i+6]; sum2 = one[i+7] + two[i+7]; + sum1 += three[i+6]; sum2 += three[i+7]; + P->dest[i+6] = sum1; P->dest[i+7] = sum2; + if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; + + sum1 = one[i+8] + two[i+8]; sum2 = one[i+9] + two[i+9]; + sum1 += three[i+8]; sum2 += three[i+9]; + P->dest[i+8] = sum1; P->dest[i+9] = sum2; + if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; + + sum1 = one[i+10] + two[i+10]; sum2 = one[i+11] + two[i+11]; + sum1 += three[i+10]; sum2 += three[i+11]; + P->dest[i+10] = sum1; P->dest[i+11] = sum2; + if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; + + sum1 = one[i+12] + two[i+12]; sum2 = one[i+13] + two[i+13]; + sum1 += three[i+12]; sum2 += three[i+13]; + P->dest[i+12] = sum1; P->dest[i+13] = sum2; + if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; + + sum1 = one[i+14] + two[i+14]; sum2 = one[i+15] + two[i+15]; + sum1 += three[i+14]; sum2 += three[i+15]; + P->dest[i+14] = sum1; P->dest[i+15] = sum2; + if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; + + sum1 = one[i+16] + two[i+16]; sum2 = one[i+17] + two[i+17]; + sum1 += three[i+16]; sum2 += three[i+17]; + P->dest[i+16] = sum1; P->dest[i+17] = sum2; + if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; + + sum1 = one[i+18] + two[i+18]; sum2 = one[i+19] + two[i+19]; + sum1 += three[i+18]; sum2 += three[i+19]; + P->dest[i+18] = sum1; P->dest[i+19] = sum2; + if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; + + sum1 = one[i+20] + two[i+20]; sum2 = one[i+21] + two[i+21]; + sum1 += three[i+20]; sum2 += three[i+21]; + P->dest[i+20] = sum1; P->dest[i+21] = sum2; + if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; + } + for ( ; i < P->di; i++) { + sum1 = one[i] + two[i] + three[i]; + P->dest[i] = sum1; + if (sum1 > tmax) tmax = sum1; + } + if (tmax > tmaxB) return tmax; + return tmaxB; +} + +sum_func swi3tb[FOLDTBLEN] = { + sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, + sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, + sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, + sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, + sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, + sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, + sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, + sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, top_sum3 +}; +// +// +float sw_sum4_t31(float *ss[], struct PoTPlan *P) { + float sum1, sum2, tmax2, tmax1; + int i = P->di; + float *one = ss[0]; + float *two = ss[0]+P->tmp0; + float *three = ss[0]+P->tmp1; + float *four = ss[0]+P->tmp2; + tmax2 = tmax1 = float(0.0); + + if ( i & 1 ) { + i -= 1; + tmax1 = one[i] + two[i]; sum2 = three[i] + four[i]; + tmax1 += sum2; + P->dest[i] = tmax1; + } + switch (i) { + case 30: + sum1 = one[29] + two[29]; sum2 = one[28] + two[28]; + sum1 += three[29]; sum2 += three[28]; + sum1 += four[29]; sum2 += four[28]; + P->dest[29] = sum1; P->dest[28] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 28: + sum1 = one[27] + two[27]; sum2 = one[26] + two[26]; + sum1 += three[27]; sum2 += three[26]; + sum1 += four[27]; sum2 += four[26]; + P->dest[27] = sum1; P->dest[26] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 26: + sum1 = one[25] + two[25]; sum2 = one[24] + two[24]; + sum1 += three[25]; sum2 += three[24]; + sum1 += four[25]; sum2 += four[24]; + P->dest[25] = sum1; P->dest[24] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 24: + sum1 = one[23] + two[23]; sum2 = one[22] + two[22]; + sum1 += three[23]; sum2 += three[22]; + sum1 += four[23]; sum2 += four[22]; + P->dest[23] = sum1; P->dest[22] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 22: + sum1 = one[21] + two[21]; sum2 = one[20] + two[20]; + sum1 += three[21]; sum2 += three[20]; + sum1 += four[21]; sum2 += four[20]; + P->dest[21] = sum1; P->dest[20] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 20: + sum1 = one[19] + two[19]; sum2 = one[18] + two[18]; + sum1 += three[19]; sum2 += three[18]; + sum1 += four[19]; sum2 += four[18]; + P->dest[19] = sum1; P->dest[18] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 18: + sum1 = one[17] + two[17]; sum2 = one[16] + two[16]; + sum1 += three[17]; sum2 += three[16]; + sum1 += four[17]; sum2 += four[16]; + P->dest[17] = sum1; P->dest[16] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 16: + sum1 = one[15] + two[15]; sum2 = one[14] + two[14]; + sum1 += three[15]; sum2 += three[14]; + sum1 += four[15]; sum2 += four[14]; + P->dest[15] = sum1; P->dest[14] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 14: + sum1 = one[13] + two[13]; sum2 = one[12] + two[12]; + sum1 += three[13]; sum2 += three[12]; + sum1 += four[13]; sum2 += four[12]; + P->dest[13] = sum1; P->dest[12] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 12: + sum1 = one[11] + two[11]; sum2 = one[10] + two[10]; + sum1 += three[11]; sum2 += three[10]; + sum1 += four[11]; sum2 += four[10]; + P->dest[11] = sum1; P->dest[10] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 10: + sum1 = one[9] + two[9]; sum2 = one[8] + two[8]; + sum1 += three[9]; sum2 += three[8]; + sum1 += four[9]; sum2 += four[8]; + P->dest[9] = sum1; P->dest[8] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 8: + sum1 = one[7] + two[7]; sum2 = one[6] + two[6]; + sum1 += three[7]; sum2 += three[6]; + sum1 += four[7]; sum2 += four[6]; + P->dest[7] = sum1; P->dest[6] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 6: + sum1 = one[5] + two[5]; sum2 = one[4] + two[4]; + sum1 += three[5]; sum2 += three[4]; + sum1 += four[5]; sum2 += four[4]; + P->dest[5] = sum1; P->dest[4] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 4: + sum1 = one[3] + two[3]; sum2 = one[2] + two[2]; + sum1 += three[3]; sum2 += three[2]; + sum1 += four[3]; sum2 += four[2]; + P->dest[3] = sum1; P->dest[2] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 2: + sum1 = one[1] + two[1]; sum2 = one[0] + two[0]; + sum1 += three[1]; sum2 += three[0]; + sum1 += four[1]; sum2 += four[0]; + P->dest[1] = sum1; P->dest[0] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + } + if (tmax1 > tmax2) return tmax1; + return tmax2; +} +// +// use for higher sum4 folds +// +float top_sum4(float *ss[], struct PoTPlan *P) { + float sum1, sum2, tmaxB, tmax; + int i; + float *one = ss[0]; + float *two = ss[0]+P->tmp0; + float *three = ss[0]+P->tmp1; + float *four = ss[0]+P->tmp2; + tmaxB = tmax = float(0.0); + + for (i = 0 ; i < P->di-15; i += 16) { + sum1 = one[i+0] + two[i+0]; sum2 = one[i+1] + two[i+1]; + sum1 += three[i+0]; sum2 += three[i+1]; + sum1 += four[i+0]; sum2 += four[i+1]; + P->dest[i+0] = sum1; P->dest[i+1] = sum2; + if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; + + sum1 = one[i+2] + two[i+2]; sum2 = one[i+3] + two[i+3]; + sum1 += three[i+2]; sum2 += three[i+3]; + sum1 += four[i+2]; sum2 += four[i+3]; + P->dest[i+2] = sum1; P->dest[i+3] = sum2; + if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; + + sum1 = one[i+4] + two[i+4]; sum2 = one[i+5] + two[i+5]; + sum1 += three[i+4]; sum2 += three[i+5]; + sum1 += four[i+4]; sum2 += four[i+5]; + P->dest[i+4] = sum1; P->dest[i+5] = sum2; + if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; + + sum1 = one[i+6] + two[i+6]; sum2 = one[i+7] + two[i+7]; + sum1 += three[i+6]; sum2 += three[i+7]; + sum1 += four[i+6]; sum2 += four[i+7]; + P->dest[i+6] = sum1; P->dest[i+7] = sum2; + if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; + + sum1 = one[i+8] + two[i+8]; sum2 = one[i+9] + two[i+9]; + sum1 += three[i+8]; sum2 += three[i+9]; + sum1 += four[i+8]; sum2 += four[i+9]; + P->dest[i+8] = sum1; P->dest[i+9] = sum2; + if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; + + sum1 = one[i+10] + two[i+10]; sum2 = one[i+11] + two[i+11]; + sum1 += three[i+10]; sum2 += three[i+11]; + sum1 += four[i+10]; sum2 += four[i+11]; + P->dest[i+10] = sum1; P->dest[i+11] = sum2; + if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; + + sum1 = one[i+12] + two[i+12]; sum2 = one[i+13] + two[i+13]; + sum1 += three[i+12]; sum2 += three[i+13]; + sum1 += four[i+12]; sum2 += four[i+13]; + P->dest[i+12] = sum1; P->dest[i+13] = sum2; + if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; + + sum1 = one[i+14] + two[i+14]; sum2 = one[i+15] + two[i+15]; + sum1 += three[i+14]; sum2 += three[i+15]; + sum1 += four[i+14]; sum2 += four[i+15]; + P->dest[i+14] = sum1; P->dest[i+15] = sum2; + if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; + } + for ( ; i < P->di; i++) { + sum1 = (one[i] + two[i] ); sum2 = (three[i] + four[i] ); + sum1 += sum2; + P->dest[i] = sum1; + if (sum1 > tmax) tmax = sum1; + } + if (tmax > tmaxB) return tmax; + return tmaxB; +} +// +sum_func swi4tb[FOLDTBLEN] = { + sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, + sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, + sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, + sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, + sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, + sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, + sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, + sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, top_sum4 +}; +// +// +float sw_sum5_t31(float *ss[], struct PoTPlan *P) { + float sum1, sum2, tmax2, tmax1; + int i = P->di; + float *one = ss[0]; + float *two = ss[0]+P->tmp0; + float *three = ss[0]+P->tmp1; + float *four = ss[0]+P->tmp2; + float *five = ss[0]+P->tmp3; + tmax2 = tmax1 = float(0.0); + + if ( i & 1 ) { + i -= 1; + tmax1 = one[i] + two[i]; sum2 = three[i] + four[i]; + tmax1 += five[i]; + tmax1 += sum2; + P->dest[i] = tmax1; + } + switch (i) { + case 30: + sum1 = one[29] + two[29]; sum2 = one[28] + two[28]; + sum1 += three[29]; sum2 += three[28]; + sum1 += four[29]; sum2 += four[28]; + sum1 += five[29]; sum2 += five[28]; + P->dest[29] = sum1; P->dest[28] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 28: + sum1 = one[27] + two[27]; sum2 = one[26] + two[26]; + sum1 += three[27]; sum2 += three[26]; + sum1 += four[27]; sum2 += four[26]; + sum1 += five[27]; sum2 += five[26]; + P->dest[27] = sum1; P->dest[26] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 26: + sum1 = one[25] + two[25]; sum2 = one[24] + two[24]; + sum1 += three[25]; sum2 += three[24]; + sum1 += four[25]; sum2 += four[24]; + sum1 += five[25]; sum2 += five[24]; + P->dest[25] = sum1; P->dest[24] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 24: + sum1 = one[23] + two[23]; sum2 = one[22] + two[22]; + sum1 += three[23]; sum2 += three[22]; + sum1 += four[23]; sum2 += four[22]; + sum1 += five[23]; sum2 += five[22]; + P->dest[23] = sum1; P->dest[22] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 22: + sum1 = one[21] + two[21]; sum2 = one[20] + two[20]; + sum1 += three[21]; sum2 += three[20]; + sum1 += four[21]; sum2 += four[20]; + sum1 += five[21]; sum2 += five[20]; + P->dest[21] = sum1; P->dest[20] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 20: + sum1 = one[19] + two[19]; sum2 = one[18] + two[18]; + sum1 += three[19]; sum2 += three[18]; + sum1 += four[19]; sum2 += four[18]; + sum1 += five[19]; sum2 += five[18]; + P->dest[19] = sum1; P->dest[18] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 18: + sum1 = one[17] + two[17]; sum2 = one[16] + two[16]; + sum1 += three[17]; sum2 += three[16]; + sum1 += four[17]; sum2 += four[16]; + sum1 += five[17]; sum2 += five[16]; + P->dest[17] = sum1; P->dest[16] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 16: + sum1 = one[15] + two[15]; sum2 = one[14] + two[14]; + sum1 += three[15]; sum2 += three[14]; + sum1 += four[15]; sum2 += four[14]; + sum1 += five[15]; sum2 += five[14]; + P->dest[15] = sum1; P->dest[14] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 14: + sum1 = one[13] + two[13]; sum2 = one[12] + two[12]; + sum1 += three[13]; sum2 += three[12]; + sum1 += four[13]; sum2 += four[12]; + sum1 += five[13]; sum2 += five[12]; + P->dest[13] = sum1; P->dest[12] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 12: + sum1 = one[11] + two[11]; sum2 = one[10] + two[10]; + sum1 += three[11]; sum2 += three[10]; + sum1 += four[11]; sum2 += four[10]; + sum1 += five[11]; sum2 += five[10]; + P->dest[11] = sum1; P->dest[10] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 10: + sum1 = one[9] + two[9]; sum2 = one[8] + two[8]; + sum1 += three[9]; sum2 += three[8]; + sum1 += four[9]; sum2 += four[8]; + sum1 += five[9]; sum2 += five[8]; + P->dest[9] = sum1; P->dest[8] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 8: + sum1 = one[7] + two[7]; sum2 = one[6] + two[6]; + sum1 += three[7]; sum2 += three[6]; + sum1 += four[7]; sum2 += four[6]; + sum1 += five[7]; sum2 += five[6]; + P->dest[7] = sum1; P->dest[6] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 6: + sum1 = one[5] + two[5]; sum2 = one[4] + two[4]; + sum1 += three[5]; sum2 += three[4]; + sum1 += four[5]; sum2 += four[4]; + sum1 += five[5]; sum2 += five[4]; + P->dest[5] = sum1; P->dest[4] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 4: + sum1 = one[3] + two[3]; sum2 = one[2] + two[2]; + sum1 += three[3]; sum2 += three[2]; + sum1 += four[3]; sum2 += four[2]; + sum1 += five[3]; sum2 += five[2]; + P->dest[3] = sum1; P->dest[2] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 2: + sum1 = one[1] + two[1]; sum2 = one[0] + two[0]; + sum1 += three[1]; sum2 += three[0]; + sum1 += four[1]; sum2 += four[0]; + sum1 += five[1]; sum2 += five[0]; + P->dest[1] = sum1; P->dest[0] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + } + if (tmax1 > tmax2) return tmax1; + return tmax2; +} +// +// use for higher sum5 folds +// +float top_sum5(float *ss[], struct PoTPlan *P) { + float sum1, sum2, tmaxB, tmax; + int i; + float *one = ss[0]; + float *two = ss[0]+P->tmp0; + float *three = ss[0]+P->tmp1; + float *four = ss[0]+P->tmp2; + float *five = ss[0]+P->tmp3; + tmaxB = tmax = float(0.0); + + for (i = 0 ; i < P->di-15; i += 16) { + sum1 = one[i+0] + two[i+0]; sum2 = one[i+1] + two[i+1]; + sum1 += three[i+0]; sum2 += three[i+1]; + sum1 += four[i+0]; sum2 += four[i+1]; + sum1 += five[i+0]; sum2 += five[i+1]; + P->dest[i+0] = sum1; P->dest[i+1] = sum2; + if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; + + sum1 = one[i+2] + two[i+2]; sum2 = one[i+3] + two[i+3]; + sum1 += three[i+2]; sum2 += three[i+3]; + sum1 += four[i+2]; sum2 += four[i+3]; + sum1 += five[i+2]; sum2 += five[i+3]; + P->dest[i+2] = sum1; P->dest[i+3] = sum2; + if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; + + sum1 = one[i+4] + two[i+4]; sum2 = one[i+5] + two[i+5]; + sum1 += three[i+4]; sum2 += three[i+5]; + sum1 += four[i+4]; sum2 += four[i+5]; + sum1 += five[i+4]; sum2 += five[i+5]; + P->dest[i+4] = sum1; P->dest[i+5] = sum2; + if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; + + sum1 = one[i+6] + two[i+6]; sum2 = one[i+7] + two[i+7]; + sum1 += three[i+6]; sum2 += three[i+7]; + sum1 += four[i+6]; sum2 += four[i+7]; + sum1 += five[i+6]; sum2 += five[i+7]; + P->dest[i+6] = sum1; P->dest[i+7] = sum2; + if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; + + sum1 = one[i+8] + two[i+8]; sum2 = one[i+9] + two[i+9]; + sum1 += three[i+8]; sum2 += three[i+9]; + sum1 += four[i+8]; sum2 += four[i+9]; + sum1 += five[i+8]; sum2 += five[i+9]; + P->dest[i+8] = sum1; P->dest[i+9] = sum2; + if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; + + sum1 = one[i+10] + two[i+10]; sum2 = one[i+11] + two[i+11]; + sum1 += three[i+10]; sum2 += three[i+11]; + sum1 += four[i+10]; sum2 += four[i+11]; + sum1 += five[i+10]; sum2 += five[i+11]; + P->dest[i+10] = sum1; P->dest[i+11] = sum2; + if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; + + sum1 = one[i+12] + two[i+12]; sum2 = one[i+13] + two[i+13]; + sum1 += three[i+12]; sum2 += three[i+13]; + sum1 += four[i+12]; sum2 += four[i+13]; + sum1 += five[i+12]; sum2 += five[i+13]; + P->dest[i+12] = sum1; P->dest[i+13] = sum2; + if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; + + sum1 = one[i+14] + two[i+14]; sum2 = one[i+15] + two[i+15]; + sum1 += three[i+14]; sum2 += three[i+15]; + sum1 += four[i+14]; sum2 += four[i+15]; + sum1 += five[i+14]; sum2 += five[i+15]; + P->dest[i+14] = sum1; P->dest[i+15] = sum2; + if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; + } + for ( ; i < P->di; i++) { + sum1 = (one[i] + two[i] ); sum2 = (three[i] + four[i] ); + sum1 += five[i]; + sum1 += sum2; + P->dest[i] = sum1; + if (sum1 > tmax) tmax = sum1; + } + if (tmax > tmaxB) return tmax; + return tmaxB; +} +// +// +sum_func swi5tb[FOLDTBLEN] = { + sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, + sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, + sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, + sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, + sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, + sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, + sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, + sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, top_sum5 +}; +// +// +float sw_sum2_t31(float *ss[], struct PoTPlan *P) { + float sum1, sum2, tmax2, tmax1; + int i = P->di; + float *one = ss[1]+P->offset; + float *two = ss[1]+P->tmp0; + tmax2 = tmax1 = float(0.0); + + if ( i & 1 ) { + i -= 1; + tmax1 = one[i] + two[i]; + P->dest[i] = tmax1; + } + switch (i) { + case 30: + sum1 = one[29] + two[29]; sum2 = one[28] + two[28]; + P->dest[29] = sum1; P->dest[28] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 28: + sum1 = one[27] + two[27]; sum2 = one[26] + two[26]; + P->dest[27] = sum1; P->dest[26] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 26: + sum1 = one[25] + two[25]; sum2 = one[24] + two[24]; + P->dest[25] = sum1; P->dest[24] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 24: + sum1 = one[23] + two[23]; sum2 = one[22] + two[22]; + P->dest[23] = sum1; P->dest[22] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 22: + sum1 = one[21] + two[21]; sum2 = one[20] + two[20]; + P->dest[21] = sum1; P->dest[20] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 20: + sum1 = one[19] + two[19]; sum2 = one[18] + two[18]; + P->dest[19] = sum1; P->dest[18] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 18: + sum1 = one[17] + two[17]; sum2 = one[16] + two[16]; + P->dest[17] = sum1; P->dest[16] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 16: + sum1 = one[15] + two[15]; sum2 = one[14] + two[14]; + P->dest[15] = sum1; P->dest[14] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 14: + sum1 = one[13] + two[13]; sum2 = one[12] + two[12]; + P->dest[13] = sum1; P->dest[12] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 12: + sum1 = one[11] + two[11]; sum2 = one[10] + two[10]; + P->dest[11] = sum1; P->dest[10] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 10: + sum1 = one[9] + two[9]; sum2 = one[8] + two[8]; + P->dest[9] = sum1; P->dest[8] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 8: + sum1 = one[7] + two[7]; sum2 = one[6] + two[6]; + P->dest[7] = sum1; P->dest[6] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 6: + sum1 = one[5] + two[5]; sum2 = one[4] + two[4]; + P->dest[5] = sum1; P->dest[4] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 4: + sum1 = one[3] + two[3]; sum2 = one[2] + two[2]; + P->dest[3] = sum1; P->dest[2] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + case 2: + sum1 = one[1] + two[1]; sum2 = one[0] + two[0]; + P->dest[1] = sum1; P->dest[0] = sum2; + if (sum1 > tmax1) tmax1 = sum1; if (sum2 > tmax2) tmax2 = sum2; + } + if (tmax1 > tmax2) return tmax1; + return tmax2; +} +// +// use for higher sum2 folds +// +float top_sum2(float *ss[], struct PoTPlan *P) { + float sum1, sum2, tmaxB, tmax; + int i; + float *one = ss[1]+P->offset; + float *two = ss[1]+P->tmp0; + tmaxB = tmax = float(0.0); + + for (i = 0 ; i < P->di-21; i += 22) { + sum1 = one[i+0] + two[i+0]; sum2 = one[i+1] + two[i+1]; + P->dest[i+0] = sum1; P->dest[i+1] = sum2; + if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; + + sum1 = one[i+2] + two[i+2]; sum2 = one[i+3] + two[i+3]; + P->dest[i+2] = sum1; P->dest[i+3] = sum2; + if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; + + sum1 = one[i+4] + two[i+4]; sum2 = one[i+5] + two[i+5]; + P->dest[i+4] = sum1; P->dest[i+5] = sum2; + if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; + + sum1 = one[i+6] + two[i+6]; sum2 = one[i+7] + two[i+7]; + P->dest[i+6] = sum1; P->dest[i+7] = sum2; + if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; + + sum1 = one[i+8] + two[i+8]; sum2 = one[i+9] + two[i+9]; + P->dest[i+8] = sum1; P->dest[i+9] = sum2; + if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; + + sum1 = one[i+10] + two[i+10]; sum2 = one[i+11] + two[i+11]; + P->dest[i+10] = sum1; P->dest[i+11] = sum2; + if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; + + sum1 = one[i+12] + two[i+12]; sum2 = one[i+13] + two[i+13]; + P->dest[i+12] = sum1; P->dest[i+13] = sum2; + if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; + + sum1 = one[i+14] + two[i+14]; sum2 = one[i+15] + two[i+15]; + P->dest[i+14] = sum1; P->dest[i+15] = sum2; + if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; + + sum1 = one[i+16] + two[i+16]; sum2 = one[i+17] + two[i+17]; + P->dest[i+16] = sum1; P->dest[i+17] = sum2; + if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; + + sum1 = one[i+18] + two[i+18]; sum2 = one[i+19] + two[i+19]; + P->dest[i+18] = sum1; P->dest[i+19] = sum2; + if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; + + sum1 = one[i+20] + two[i+20]; sum2 = one[i+21] + two[i+21]; + P->dest[i+20] = sum1; P->dest[i+21] = sum2; + if (sum1 > tmax) tmax = sum1; if (sum2 > tmaxB) tmaxB = sum2; + } + for ( ; i < P->di; i++) { + sum1 = one[i] + two[i]; + P->dest[i] = sum1; + if (sum1 > tmax) tmax = sum1; + } + if (tmax > tmaxB) return tmax; + return tmaxB; +} + +sum_func swi2tb[FOLDTBLEN] = { + sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, + sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, + sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, + sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, + sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, + sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, + sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, + sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, top_sum2 +}; +// +// +FoldSet swifold = {swi3tb, swi4tb, swi5tb, swi2tb, swi2tb, "FPU opt"}; + +// Arrays from which folding subroutines will be chosen during execution. +// Other sets can be inserted to replace the defaults. +// + +sum_func sumsel3[FOLDTBLEN] = { + sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, + sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, + sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, + sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, + sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, + sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, + sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, + sw_sum3_t31, sw_sum3_t31, sw_sum3_t31, top_sum3 +}; +sum_func sumsel4[FOLDTBLEN] = { + sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, + sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, + sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, + sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, + sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, + sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, + sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, + sw_sum4_t31, sw_sum4_t31, sw_sum4_t31, top_sum4 +}; +sum_func sumsel5[FOLDTBLEN] = { + sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, + sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, + sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, + sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, + sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, + sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, + sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, + sw_sum5_t31, sw_sum5_t31, sw_sum5_t31, top_sum5 +}; +sum_func sumsel2[FOLDTBLEN] = { + sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, + sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, + sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, + sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, + sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, + sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, + sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, + sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, top_sum2 +}; +sum_func sumsel2AL[FOLDTBLEN] = { + sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, + sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, + sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, + sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, + sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, + sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, + sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, + sw_sum2_t31, sw_sum2_t31, sw_sum2_t31, top_sum2 +}; + +FoldSet Foldmain = {sumsel3, sumsel4, sumsel5, sumsel2, sumsel2AL, "opt FPU"}; + +/********************** + * + * Routine to copy fold subroutine tables. + * + */ +int CopyFoldSet(FoldSet *dst, FoldSet *src) { + int i, j3, j4, j5, j2, j2AL; + + j3 = j4 = j5 = j2 = j2AL = 0; + + for (i = 0; i < FOLDTBLEN; i++) { + + if (src->f3[i] != 0) { + dst->f3[i] = src->f3[i]; + j3 = i; + } else dst->f3[i] = src->f3[j3]; + + if (src->f4[i] != 0) { + dst->f4[i] = src->f4[i]; + j4 = i; + } else dst->f4[i] = src->f4[j4]; + + if (src->f5[i] != 0) { + dst->f5[i] = src->f5[i]; + j5 = i; + } else dst->f5[i] = src->f5[j5]; + + if (src->f2[i] != 0) { + dst->f2[i] = src->f2[i]; + j2 = i; + } else dst->f2[i] = src->f2[j2]; + + if (src->f2AL[i] != 0) { + dst->f2AL[i] = src->f2AL[i]; + j2AL = i; + } else dst->f2AL[i] = src->f2AL[j2AL]; + } + dst->name = src->name; + return 0; +} + +/********************** + * + * t_funct - Caching routine for calls to invert_lcgf, return cache value if present + * + * This version caches and returns the threshold factor for dis_thresh rather than cur_thresh. + * + * The threshold factor assumes folding subroutines which do NOT divide the sums by num_adds. + */ +float t_funct(int m, int n, int x) { + static struct tftab { + int n; + float y; + } + *t_funct_tab; + + float c_dis_thresh = (float)swi.analysis_cfg.pulse_display_thresh; + + if (!t_funct_tab) { + int tablen = (PoTInfo.PulseMax+2)/3 + + 3*(int)(log((float)PoTInfo.PulseMax)/log(2.0)-3) - 1; + t_funct_tab=(struct tftab *)malloc_a(tablen*sizeof(struct tftab),MEM_ALIGN); + if (!t_funct_tab) SETIERROR(MALLOC_FAILED, "!t_funct_tab"); + memset(t_funct_tab, 0, tablen*sizeof(struct tftab)); + } + if (t_funct_tab[x].n!=n) { + t_funct_tab[x].n=n; + t_funct_tab[x].y = (invert_lcgf((float)(-PoTInfo.PulseThresh - log((float)m)), + (float)n, (float)1e-4) - n) * c_dis_thresh + n; + } + return t_funct_tab[x].y; +} + +/********************** + * + * Preplanning routine called from find_pulse() + * + */ +int plan_PulsePoT(PoTPlan * PSeq, int PulsePotLen, float *div, int *dbinoffs) { + float period; + int ndivs; + int i, j, di, dbins, offset; + int num_adds_2; + long p; + unsigned long cperiod; + int num_adds; + register float tmp_max,t1; + int res=1; + int k = 0; // plan index + + for (i = 32, ndivs = 1; i <= PulsePotLen; ndivs++, i *= 2); + + int32_t thePotLen = PulsePotLen; + + // Periods from PulsePotLen/3 to PulsePotLen/4, and power of 2 fractions of. + // then (len/4 to len/5) and finally (len/5 to len/6) + // + int32_t firstP, lastP; + for(num_adds = 3; num_adds <= 5; num_adds++) { + int num_adds_minus1; + switch(num_adds) { + case 3: lastP = (thePotLen*2)/3; firstP = (thePotLen*1)/2; num_adds_minus1 = 2; break; + case 4: lastP = (thePotLen*3)/4; firstP = (thePotLen*3)/5; num_adds_minus1 = 3; break; + case 5: lastP = (thePotLen*4)/5; firstP = (thePotLen*4)/6; num_adds_minus1 = 4; break; + } + + for (p = lastP ; p > firstP ; p--) { + int tabofst = ndivs*3+2-num_adds; + PSeq[k].dest = div+dbinoffs[0]; // Output storage + PSeq[k].cperiod = cperiod = p*(C3X2TO14 / num_adds_minus1); + PSeq[k].tmp0 = (int)((cperiod+C3X2TO13)/C3X2TO14); + PSeq[k].tmp1 = (int)((cperiod*2+C3X2TO13)/C3X2TO14); + PSeq[k].di = di = (int)cperiod/C3X2TO14; + PSeq[k].na = num_adds; + PSeq[k].thresh = t_funct(di, num_adds, di+tabofst); + + switch(num_adds) { + case 3: + PSeq[k].fun_ptr = (di < FOLDTBLEN) ? sumsel3[di] : sumsel3[FOLDTBLEN-1]; + break; + case 4: + PSeq[k].tmp2 = (int)((cperiod*3+C3X2TO13)/C3X2TO14); + PSeq[k].fun_ptr = (di < FOLDTBLEN) ? sumsel4[di] : sumsel4[FOLDTBLEN-1]; + break; + case 5: + PSeq[k].tmp2 = (int)((cperiod*3+C3X2TO13)/C3X2TO14); + PSeq[k].tmp3 = (int)((cperiod*4+C3X2TO13)/C3X2TO14); + PSeq[k].fun_ptr = (di < FOLDTBLEN) ? sumsel5[di] : sumsel5[FOLDTBLEN-1]; + break; + } + + k++; // next plan + num_adds_2 = 2* num_adds; + + for (j = 1; j < ndivs ; j++) { + tabofst -= 3; + PSeq[k].offset = dbinoffs[j-1]; + PSeq[k].dest = div+dbinoffs[j]; + PSeq[k].cperiod = PSeq[k-1].cperiod/2; + PSeq[k].tmp0 = di & 1; + PSeq[k].di = di = PSeq[k].cperiod/C3X2TO14; + PSeq[k].tmp0 += di + PSeq[k].offset; //PSeq[k].offset + (PSeq[k].cperiod+C3X2TO13)/C3X2TO14 + if (PSeq[k].tmp0 & 3) PSeq[k].fun_ptr = (di < FOLDTBLEN) ? sumsel2[di] : sumsel2[FOLDTBLEN-1]; + else PSeq[k].fun_ptr = (di < FOLDTBLEN) ? sumsel2AL[di] : sumsel2AL[FOLDTBLEN-1]; + PSeq[k].na = num_adds_2; + PSeq[k].thresh = t_funct(di, num_adds_2, di+tabofst); + + k++; // next plan + num_adds_2 *=2; + } // for (j = 1; j < ndivs + } // for (p = lastP + } // for(num_adds = + PSeq[k].di = 0; // stop + return (k); +} + +/********************** + * + * find_pulse - uses a folding algorithm to find repeating pulses + * Initially folds by prime number then by powers of two. + * + * Initial code by Eric Korpela + * Major revisions and optimization by Ben Herndon + * Further revised by Joe Segur + * + */ +int find_pulse(const float * fp_PulsePot, int PulsePotLen, + float pulse_thresh, int TOffset, int FOffset) { + static float *div,*FoldedPOT; + static int *dbinoffs, PrevPPL, PrevPoTln; + static PoTPlan *PSeq; + static float rcfg_dis_thresh = 1.0f / (float)swi.analysis_cfg.pulse_display_thresh; + PoTPlan PTPln = {0} ; + float *SrcSel[2]; + float period; + int ndivs; + int i, j, di, maxs = 0; + int num_adds, num_adds_2; + long p; + float max=0,maxd=0,avg=0,maxp=0, snr=0, fthresh=0; + register float tmp_max,t1; + int res=1; + + // debug possible heap corruption -- jeffc +#ifdef _WIN32 + BOINCASSERT(_CrtCheckMemory()); +#endif + +#ifdef DEBUG_PULSE_VERBOSE + fprintf(stderr, "In find_pulse()... PulsePotLen = %d pulse_thresh = %f TOffset = %d PoT = %d\n", PulsePotLen, pulse_thresh, TOffset, FOffset); +#endif + + // boinc_worker_timer(); + + // Create internal arrays.... + if (!div) { + int n, maxdivs = 1; + for (i = 32; i <= PoTInfo.PulseMax; maxdivs++, i *= 2); + div=(float *)calloc_a(((PoTInfo.PulseMax*7/4)+maxdivs*MEM_ALIGN/sizeof(float)), sizeof(float), MEM_ALIGN); + FoldedPOT=(float *)malloc_a((PoTInfo.PulseMax+1)*sizeof(float)/3, MEM_ALIGN); + dbinoffs=(int *)malloc_a(maxdivs*sizeof(int), MEM_ALIGN); + for (i = 32, n = 1; i <= PPLANMAX; n++, i *= 2); + i = ((PPLANMAX*2)/3)-((PPLANMAX*2)/4); + i += ((PPLANMAX*3)/4)-((PPLANMAX*3)/5); + i += ((PPLANMAX*4)/5)-((PPLANMAX*4)/6); + i *= n; + PSeq = (PoTPlan *)malloc_a((i+1)*sizeof(PoTPlan), MEM_ALIGN); + if ((!div) || (!FoldedPOT) || (!dbinoffs) || (!PSeq)) + SETIERROR(MALLOC_FAILED, "(!div) || (!FoldedPOT) || (!dbinoffs) || (!PSeq)"); + if (t_funct(6,1000,0)<0) SETIERROR(MALLOC_FAILED, "t_funct(6,1000,0)<0");; + } + + SrcSel[0] = (float *)fp_PulsePot; // source of data for 3, 4, 5 folds + SrcSel[1] = div; // source of data for 2 folds + +/* Uncomment this block if res > 1 is ever actually used + + // Rebin to lower resolution if required + if (res <= 1) { + memcpy(div,fp_PulsePot,PulsePotLen*sizeof(float)); + } else { + for (j=0;jdis_thresh) { + // unscale for reporting + tmp_max /= PSeq[k].na; + cur_thresh = (dis_thresh / PSeq[k].na - avg) * rcfg_dis_thresh + avg; + + ReportPulseEvent(tmp_max/avg,avg,res*(float)PSeq[k].cperiod/(float)C3X2TO14, + TOffset+PulsePotLen/2,FOffset, + (tmp_max-avg)*(float)sqrt((float)PSeq[k].na)/avg, + (cur_thresh-avg)*(float)sqrt((float)PSeq[k].na)/avg, + PSeq[k].dest, PSeq[k].na, 0); + + if ((tmp_max>cur_thresh) && ((t1=tmp_max-cur_thresh)>maxd)) { + maxp = (float)PSeq[k].cperiod/(float)C3X2TO14; + maxd = t1; + maxs = PSeq[k].na; + max = tmp_max; + snr = (float)((tmp_max-avg)*sqrt((float)PSeq[k].na)/avg); + fthresh=(float)((cur_thresh-avg)*sqrt((float)PSeq[k].na)/avg); + memcpy(FoldedPOT, PSeq[k].dest, PSeq[k].di*sizeof(float)); + } + } + } // for ( k = + } + else { // If not plan, + + // Periods from PulsePotLen/3 to PulsePotLen/4, and power of 2 fractions of. + // then (len/4 to len/5) and finally (len/5 to len/6) + // + int32_t firstP, lastP; + for(num_adds = 3; num_adds <= 5; num_adds++) { + int num_adds_minus1; + switch(num_adds) { + case 3: lastP = (thePotLen*2)/3; firstP = (thePotLen*1)/2; num_adds_minus1 = 2; break; + case 4: lastP = (thePotLen*3)/4; firstP = (thePotLen*3)/5; num_adds_minus1 = 3; break; + case 5: lastP = (thePotLen*4)/5; firstP = (thePotLen*4)/6; num_adds_minus1 = 4; break; + } + + for (p = lastP ; p > firstP ; p--) { + float cur_thresh, dis_thresh; + int tabofst, mper, perdiv; + + tabofst = ndivs*3+2-num_adds; + mper = p * (12/num_adds_minus1); + perdiv = num_adds_minus1; + PTPln.tmp0 = (int)((mper + 6)/12); // round(period) + PTPln.tmp1 = (int)((mper * 2 + 6)/12); // round(period*2) + PTPln.di = (int)p/perdiv; // (int)period + PTPln.dest = div+dbinoffs[0]; // Output storage + dis_thresh = t_funct(PTPln.di, num_adds, PTPln.di+tabofst)*avg; + + switch(num_adds) { + case 3: + tmp_max = (PTPln.di < FOLDTBLEN) ? sumsel3[PTPln.di](SrcSel, &PTPln) : sumsel3[FOLDTBLEN-1](SrcSel, &PTPln); + break; + case 4: + PTPln.tmp2 = (int)((mper * 3 + 6)/12); // round(period*3) + tmp_max = (PTPln.di < FOLDTBLEN) ? sumsel4[PTPln.di](SrcSel, &PTPln) : sumsel4[FOLDTBLEN-1](SrcSel, &PTPln); + break; + case 5: + PTPln.tmp2 = (int)((mper * 3 + 6)/12); // round(period*3) + PTPln.tmp3 = (int)((mper * 4 + 6)/12); // round(period*4) + tmp_max = (PTPln.di < FOLDTBLEN) ? sumsel5[PTPln.di](SrcSel, &PTPln) : sumsel5[FOLDTBLEN-1](SrcSel, &PTPln); + break; + } + + if (tmp_max>dis_thresh) { + // unscale for reporting + tmp_max /= num_adds; + cur_thresh = (dis_thresh / num_adds - avg) * rcfg_dis_thresh + avg; + + ReportPulseEvent(tmp_max/avg,avg,((float)p)/(float)perdiv*res, + TOffset+PulsePotLen/2,FOffset, + (tmp_max-avg)*(float)sqrt((float)num_adds)/avg, + (cur_thresh-avg)*(float)sqrt((float)num_adds)/avg, + PTPln.dest, num_adds, 0); + + if ((tmp_max>cur_thresh) && ((t1=tmp_max-cur_thresh)>maxd)) { + maxp = (float)p/(float)perdiv; + maxd = t1; + maxs = num_adds; + max = tmp_max; + snr = (float)((tmp_max-avg)*sqrt((float)num_adds)/avg); + fthresh=(float)((cur_thresh-avg)*sqrt((float)num_adds)/avg); + memcpy(FoldedPOT, PTPln.dest, PTPln.di*sizeof(float)); + } + } + + num_adds_2 = 2* num_adds; + + for (j = 1; j < ndivs ; j++) { + PTPln.offset = dbinoffs[j-1]; + PTPln.dest = div+dbinoffs[j]; + perdiv *=2; + PTPln.tmp0 = PTPln.di & 1; + PTPln.di /= 2; + PTPln.tmp0 += PTPln.di + PTPln.offset; + tabofst -=3; + dis_thresh = t_funct(PTPln.di, num_adds_2, PTPln.di+tabofst) * avg; + + if (PTPln.tmp0 & 3) + tmp_max = (PTPln.di < FOLDTBLEN) ? sumsel2[PTPln.di](SrcSel, &PTPln) : sumsel2[FOLDTBLEN-1](SrcSel, &PTPln); + else + tmp_max = (PTPln.di < FOLDTBLEN) ? sumsel2AL[PTPln.di](SrcSel, &PTPln) : sumsel2AL[FOLDTBLEN-1](SrcSel, &PTPln); + + if (tmp_max>dis_thresh) { + // unscale for reporting + tmp_max /= num_adds_2; + cur_thresh = (dis_thresh / num_adds_2 - avg) * rcfg_dis_thresh + avg; + + ReportPulseEvent(tmp_max/avg,avg,((float)p)/(float)perdiv*res, + TOffset+PulsePotLen/2,FOffset, + (tmp_max-avg)*(float)sqrt((float)num_adds_2)/avg, + (cur_thresh-avg)*(float)sqrt((float)num_adds_2)/avg, + PTPln.dest, num_adds_2, 0); + + if ((tmp_max>cur_thresh) && ((t1=tmp_max-cur_thresh)>maxd)) { + maxp = (float)p/(float)perdiv; + maxd = t1; + maxs = num_adds_2; + max = tmp_max; + snr = (float)((tmp_max-avg)*sqrt((float)num_adds_2)/avg); + fthresh = (float)((cur_thresh-avg)*sqrt((float)num_adds_2)/avg); + memcpy(FoldedPOT, PTPln.dest, PTPln.di*sizeof(float)); + } + } + + num_adds_2 *=2; + } // for (j = 1; j < ndivs + } // for (p = lastP + } // for(num_adds = + } + + analysis_state.FLOP_counter+=(PulsePotLen*0.1818181818182+400.0)*PulsePotLen; + if (maxp!=0) + ReportPulseEvent(max/avg,avg,maxp*res,TOffset+PulsePotLen/2,FOffset, + snr, fthresh, FoldedPOT, maxs, 1); + + // debug possible heap corruption -- jeffc +#ifdef _WIN32 + BOINCASSERT(_CrtCheckMemory()); +#endif + + return 0; +} + diff --git a/client/pulsefind.h b/client/pulsefind.h new file mode 100644 index 0000000..6108493 --- /dev/null +++ b/client/pulsefind.h @@ -0,0 +1,85 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +// $Id: pulsefind.h,v 1.3.2.3 2007/06/08 03:09:45 korpela Exp $ + +// constants for integerized period in preplanning +#define C3X2TO14 0xC000 +#define C3X2TO13 0x6000 + +// constant for preplan limit +#define PPLANMAX 511 + +typedef float (*sum_func)( float *[], struct PoTPlan *); + +struct PoTPlan { + int di; // count 0 = done + float *dest; // (destination) + int tmp0; // Tmp0 [+offset for 2sum] + union {int tmp1; int offset; }; // Tmp1 for 3,4,5sum - source offset for 2sum + int tmp2; // Tmp2 + int tmp3; // Tmp3 + sum_func fun_ptr; // pointer to sum routine + unsigned long cperiod; // *0xC000 + float thresh; // invert_lcgf() + int na; // num_adds or num_adds_2 +}; + + +// std::max is SLOW +#define UNSTDMAX(a,b) (((a) > (b)) ? (a) : (b)) + +#define FOLDTBLEN 32 + +struct FoldSet { + sum_func *f3; // to table for fold by 3 + sum_func *f4; // to table for fold by 4 + sum_func *f5; // to table for fold by 5 + sum_func *f2; // to table for fold by 2 + sum_func *f2AL; // to table for fold by 2 needing tmp0 aligned + const char *name; // to string literal name of set +}; + + +// forward declare folding sets + +extern FoldSet AVXfold_a; // in analyzeFuncs_avx.cpp +extern FoldSet AVXfold_c; // in analyzeFuncs_avx.cpp +extern FoldSet sse_ben_fold; // in analyzeFuncs_sse.cpp +extern FoldSet BHSSEfold; // in analyzeFuncs_sse.cpp +extern FoldSet AKSSEfold; // in analyzeFuncs_sse.cpp +extern FoldSet AKavfold; // in analyzeFuncs_altivec.cpp +extern FoldSet swifold; // in Pulsefind - default set +extern FoldSet Foldmain; // in Pulsefind - used set + +// routines in pulsefind.cpp + +int find_triplets(const float * fp_PulsePot, int PulsePotLen, float triplet_thresh, int TOffset, int ul_PoT); + +int find_pulse(const float * fp_PulsePot, int PulsePotLen, float pulse_thresh, int TOffset, int ul_PoT); + +int CopyFoldSet(FoldSet *dst, FoldSet *src); diff --git a/client/s_util.cpp b/client/s_util.cpp new file mode 100644 index 0000000..44b5515 --- /dev/null +++ b/client/s_util.cpp @@ -0,0 +1,236 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +// util.C +// +// $Id: s_util.cpp,v 1.10.2.4 2006/12/14 22:21:47 korpela Exp $ +// + +#include "sah_config.h" + +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_SIGNAL_H +#include +#endif +#ifdef HAVE_SYS_SIGNAL_H +#include +#endif + +#include "timecvt.h" +#include "util.h" +#include "s_util.h" + +const char * const seti_error::message[]={ + "Success", + "Can't create file -- disk full?", + "Can't read from file", + "Can't write to file -- disk full?", + "Can't allocate memory", + "Can't open file", + "Bad workunit header", + "Garbled encoded workunit", + "Garbled binary workunit", + "result_overflow", + "Unhandled signal", + "atexit() failure", + "Vectorized functions unsupported", + "Floating point failure" +}; + +void seti_error::print() const { + std::cerr << "SETI@home error " << -value << " " ; + if ((value <= atexit_failure) && (value >=0)) { + std::cerr << message[value] ; + } else { + std::cerr << "Unknown error" ; + } + + std::cerr << std::endl << data << std::endl; + std::cerr << "File: " << file << std::endl; + std::cerr << "Line: " << line << std::endl; + std::cerr << std::endl; +} + +void strip_cr(char*p ) { + char* q = strchr(p, '\n'); + if (q) *q = 0; +} + +// Encode a range of bytes into printable chars, and write to file. +// Encodes 3 bytes into 4 chars. +// May read up to two bytes past end. + +void encode(unsigned char* bin, int nbytes, FILE* f) { + int count=0, offset=0, nleft; + unsigned char c0, c1, c2, c3; + for (nleft = nbytes; nleft > 0; nleft -= 3) { + c0 = bin[offset]&0x3f; // 6 + c1 = (bin[offset]>>6) | (bin[offset+1]<<2)&0x3f; // 2+4 + c2 = ((bin[offset+1]>>4)&0xf) | (bin[offset+2]<<4)&0x3f;// 4+2 + c3 = bin[offset+2]>>2; // 6 + c0 += 0x20; + c1 += 0x20; + c2 += 0x20; + c3 += 0x20; + fprintf(f, "%c%c%c%c", c0, c1, c2, c3); + offset += 3; + count += 4; + if (count == 64) { + count = 0; + fprintf(f, "\n"); + } + } + fprintf(f, "\n"); +} + +// Read from file, decode into bytes, put in array. +// May write up to two bytes past end of array. +int decode(unsigned char* bin, int nbytes, FILE* f) { + unsigned char buf[256], *p, c0, c1, c2; + int i, n, m, nleft = nbytes, offset=0; + int nbadlines = 0; + while (1) { + if (nleft <= 0) break; + p = (unsigned char*)fgets((char*)buf, 256, f); + if (!p) { + SETIERROR(BAD_DECODE, "file ended too soon"); + } + n = (int)strlen((char*)buf)-1; + if (n%4) { + nbadlines++; + if (nbadlines == 100) { + SETIERROR(BAD_DECODE, "too many bad lines - rejecting file"); + } + n = 64; + fprintf(stderr, "encoded line has bad length: %s\n", buf); + } + m = (n/4)*3; + if (m > nleft+2) { + //fprintf(stderr, "encoded line too long\n"); + //return BAD_DECODE; + n = ((nleft+2)/3)*4; + } + p = buf; + for (i=0; i>2 | p[2]<<4; // 4 + 4 + c2 = p[2]>>4 | p[3]<<2; // 2 + 6 + p += 4; + bin[offset++] = c0; + bin[offset++] = c1; + bin[offset++] = c2; + nleft -= 3; + } + } + return 0; +} + + +// Read from file, put in array. +int read_bin_data(unsigned char* bin, int nbytes, FILE* f) { + int i; + size_t n; + + for(i=0; i < nbytes; i += 256) { + n = fread((void *)(bin+i), 256, 1, f); + if (!n) { + SETIERROR(BAD_BIN_READ,"file ended too soon"); + } + } + return 0; +} + + +// see the doc on binary data representation + +void bits_to_floats(unsigned char* raw, sah_complex* data, int nsamples) { + int i, j, k=0; + unsigned char c; + + for (i=0; i>= 2; + } + } +} + +int float_to_uchar(float float_element[], unsigned char char_element[], + long num_elements, float scale_factor) { + long i, test_int; + + for(i = 0; i < num_elements; i++) { + test_int = ROUND(float_element[i]/scale_factor); + if(test_int >= 0 && test_int <= 255) + char_element[i] = (unsigned)test_int; + else + char_element[i] = test_int < 0 ? 0 : 255; + } + return 0; +} + +char* error_string(int e) { + char* p; + static char buf[256]; + + switch(e) { + case CANT_CREATE_FILE: + sprintf(buf, "Can't create file - disk full?"); + p = buf; + break; + case WRITE_FAILED: p = "Can't write to file - disk full?"; break; + case MALLOC_FAILED: p = "Can't allocate memory"; break; + case FOPEN_FAILED: + sprintf(buf, "Can't open file"); + p = buf; + break; + case BAD_HEADER: p = "Bad file header"; break; + case BAD_DECODE: p = "Can't decode data"; break; + + default: sprintf(buf, "Unknown error %d", e) ; return buf; + } + return p; +} + diff --git a/client/s_util.h b/client/s_util.h new file mode 100644 index 0000000..5e01665 --- /dev/null +++ b/client/s_util.h @@ -0,0 +1,155 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +// $Id: s_util.h,v 1.12.2.10 2006/09/07 00:26:51 korpela Exp $ +#ifndef _UTIL_H +#define _UTIL_H + +#include +#include +#include +#include "track_mem.h" + +typedef float sah_complex[2]; + +// The following is a complete list of #defines used in the code: +// TEXT_UI +// textual UI using printf, scanf +// NOTE: the above are not mutually exclusive +// _WIN32 +// windows environment. does not imply GUI +// _WIN_NT_98 +// Win NT or 98 environment +// TEST_VERSION +// include extra command-line options +// HAVE_* +// (POSIX only) presence or absence of functions, .h files +// as generated by configure script + +// client file names +#define OUTFILE_FILENAME "result.sah" +#define STATE_FILENAME "state.sah" +#define WU_FILENAME "work_unit.sah" +#define CFFT_FILENAME "cfft.sah" + +#define INF 0x7fffffff +#define ROUND(a) ((a) - (long)(a) > .5 ? (long)(a) + 1 : (long)(a)) + +#define TASK_SETI 2 + +class seti_error { + public: + typedef enum { + success=0, + cant_create_file, + read_failed, + write_failed, + malloc_failed, + fopen_failed, + bad_header, + bad_decode, + bad_bin_read, + result_overflow, + unhandled_signal, + atexit_failure, + unsupported_function, + floating_point_fail, + } errors; + static const char * const message[]; + seti_error(int e, const char *s=0) : value(-e), data(s) {}; + seti_error(int e, const char *f, int l, const char *s=0) : value(-e), file(f), line(l), data(s) {}; + seti_error(const seti_error &e) : value(e.value), file(e.file), line(e.line), data(e.data) {}; + operator int() const { return -value; }; + void print() const; + private: + int value; + std::string file; + int line; + std::string data; +}; + + + +// error codes +#define SUCCESS 0 +#define CANT_CREATE_FILE (-seti_error::cant_create_file) +#define READ_FAILED (-seti_error::read_failed) +#define WRITE_FAILED (-seti_error::write_failed) +#define MALLOC_FAILED (-seti_error::malloc_failed) +#define FOPEN_FAILED (-seti_error::fopen_failed) +#define BAD_HEADER (-seti_error::bad_header) +#define BAD_DECODE (-seti_error::bad_decode) +#define BAD_BIN_READ (-seti_error::bad_bin_read) +#define RESULT_OVERFLOW (-seti_error::result_overflow) +#define UNHANDLED_SIGNAL (-seti_error::unhandled_signal) +#define UNSUPPORTED_FUNCTION (-seti_error::unsupported_function) +#define FP_ERROR (-seti_error::floating_point_fail) +#define ATEXIT_FAILURE (-seti_error::atexit_failure) + +#ifdef HAVE_MALLOC_H +#include +#endif +#ifdef HAVE_MEMORY_H +#include +#endif +#ifdef HAVE_ALLOCA_H +#include +#endif + +// The MS & intel compilers don't allow alloca in try/catch blocks +#ifndef FORCE_FRAME_POINTER +#if ( defined(HAVE_ALLOCA) || defined(HAVE_ALLOCA_H) || defined(_WIN32) ) && !( defined(__INTEL_COMPILER) || defined (_MSC_VER) ) +#define FORCE_FRAME_POINTER alloca(16) +#else +#define FORCE_FRAME_POINTER (0) +#endif +#endif + + +// macro so we can get file and line info. +#define SETIERROR( err, errmsg ) do { \ + FORCE_FRAME_POINTER; \ + throw seti_error( err, __FILE__, __LINE__, errmsg ); \ +} while (0) + +#define CHECKPOINT_SKIPPED (0) + +//#include "seti_header.h" + +extern void strip_cr(char*p ); + +extern void encode(unsigned char* bin, int nbytes, FILE* f); +extern int decode(unsigned char* bin, int nbytes, FILE* f); +extern int read_bin_data(unsigned char* bin, int nbytes, FILE* f); +extern void bits_to_floats(unsigned char* raw, sah_complex *data, int nsamples); +extern int float_to_uchar( + float float_element[], unsigned char char_element[], + long num_elements, float scale_factor + ); +extern char* error_string(int); + +#endif diff --git a/client/sah_gfx.cpp b/client/sah_gfx.cpp new file mode 100644 index 0000000..8a48d79 --- /dev/null +++ b/client/sah_gfx.cpp @@ -0,0 +1,840 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +// Copyright 2003 Regents of the University of California + + +// Here's a summary of the various functions for initializing graphics +// and responding to user preferences changes: +// +// SAH_GRAPHICS::worker_thread_init() +// (called from worker thread once, at start) +// +// SAH_GRAPHICS_BASE::worker_thread_init +// set prefs to defaults +// parse_project_prefs() (from data already in mem) +// initialize graph buffers +// +// app_graphics_thread_init +// (called from SetMode when create window) +// +// SAH_GRAPHICS::graphics_thread_init() +// SAH_GRAPHICS_BASE::graphics_thread_init() +// init_camera() +// init_lights() +// app_resize(); +// setup_given_prefs() +// +// app_graphics_reread_prefs +// (called from event loop when get REREAD_PREFS msg +// and we have an open window) +// +// SAH_GRAPHICS::reread_prefs() +// SAH_GRAPHICS_BASE::reread_prefs() +// boinc_parse_init_data_file() +// boinc_get_init_data() +// parse_project_prefs() +// setup_given_prefs() +// +// SAH_GRAPHICS::setup_given_prefs() +// SAH_GRAPHICS_BASE::setup_given_prefs() +// init starfield +// init logos +// initialize graph, progress bar structures + +#include "sah_config.h" + +#ifdef _WIN32 +#include "boinc_win.h" +#include // Header File For The OpenGL32 Library +#include // Header File For The GLu32 Library +#if !defined(__MINGW32__) && !defined(_MSC_VER) + #include // Header File For The Glaux Library +#endif +#include +#endif + +#ifndef _WIN32 +#include +#include +#include +#include + +#ifdef __APPLE_CC__ +#include +#include +#include +#include +#include +#include +#include +#endif + +#ifdef HAVE_GL_H +#include "gl.h" +#elif defined(HAVE_GL_GL_H) +#include +#elif defined(HAVE_OPENGL_GL_H) +#include +#endif + +#ifdef HAVE_GLU_H +#include "glu.h" +#elif defined(HAVE_GL_GLU_H) +#include +#elif defined(HAVE_OPENGL_GLU_H) +#include +#endif + +#ifdef HAVE_GLUT_H +#include "glut.h" +#elif defined(HAVE_GL_GLUT_H) +#include +#elif defined(HAVE_OPENGL_GLUT_H) +#include +#elif defined(HAVE_GLUT_GLUT_H) +#include +#endif +#endif + +#include "util.h" +#include "str_util.h" +#include "str_replace.h" +#include "boinc_api.h" +#include "graphics2.h" +#include "gutil.h" +#include "timecvt.h" +#include "sah_gfx.h" + +bool mouse_down = false; +int mouse_x, mouse_y; + +static void ra_string(float x, char* p) { + int hr = (int) x; + float fmin = x-hr; + int min = (int)(fmin*60); + float fsec = fmin*60 - min; + int sec = (int)(fsec*60); + sprintf(p, "%2d hr %2d' %2d\" RA", hr, min, sec); +} + +static void dec_string(float x, char* p) { + int deg = (int) x; + float fmin = x-deg; + int min = (int)(fmin*60); + float fsec = fmin*60 - min; + int sec = (int)(fsec*60); + sprintf(p, "%s%d deg %2d' %2d\" Dec", (x<0?"-":"+"), deg, abs(min), abs(sec)); +} + +void SAH_GRAPHICS::init_text_panels() { + float pos[3], size[2]; + COLOR color; + double dtheta; + double char_height = 0.15; + double line_width = 2.0; + double line_spacing = 0.3; + double margin = 0.2; + color.a = graph_alpha; + double lum = .6; + double sat = .9; + + double hue = start_hue + hue_change*.33; + HLStoRGB(hue, lum, sat, color); + + pos[0] = -1; + pos[1] = -1; + pos[2] = -2; + size[0] = 4.9; + size[1] = 3.; + dtheta = .3; + text_panels[0].init( + pos, size, color, dtheta, char_height, line_width, line_spacing, margin + ); + + hue = start_hue + hue_change*.66; + if (hue > 1) hue -= 1; + if (hue < 1) hue += 1; + HLStoRGB(hue, lum, sat, color); + pos[0] = -3; + pos[1] = 0; + pos[2] = -1.8; + dtheta = -.6; + text_panels[1].init( + pos, size, color, dtheta, char_height, line_width, line_spacing, margin + ); +} + +void SAH_GRAPHICS::get_data_info_string(char* buf) { + char ra_buf[256], dec_buf[256]; + static const char *locations[]= { + "Arecibo 403MHz Line Feed", + "Arecibo 1.42GHz Flat Feed", + "Arecibo 1.42GHz Gregorian Feed", + "Unknown" + }; + int s4_id=3; + + if (gdata->ready) { + s4_id = gdata->wu.s4_id; + // starting after the 3rd receiver_cfg entry, the long form + // name appears in receiver_cfg->name + if (s4_id>2) { + if (strlen(gdata->wu.receiver_name)==0) { + locations[0]="SETI@home Multi-Beam"; + } else { + locations[0]=gdata->wu.receiver_name; + } + s4_id=0; + } + ra_string(gdata->wu.start_ra, ra_buf); + dec_string(gdata->wu.start_dec, dec_buf); + sprintf(buf, "From: %s, %s\n" + "Recorded on: %s\n" + "Recorded at: %s\n" + "Base frequency: %.9f GHz", + ra_buf, dec_buf, + short_jd_string(gdata->wu.time_recorded), + locations[s4_id], + gdata->wu.subband_base/1e9 + ); + } else { + strcpy( buf, "" ); + } +} + +void SAH_GRAPHICS::get_user_info_string(char* buf) { + sprintf( buf, + "Name: %s\n" + "Team: %s\n" + "Total credit: %.2f\n", + app_init_data.user_name, + app_init_data.team_name, + app_init_data.user_total_credit + ); +} + +void SAH_GRAPHICS::get_analysis_info_string(char* buf) { + if (gdata->ready) { + sprintf(buf, + "%s\n" + "Doppler drift rate %6.4f Hz/sec Resolution %5.3f Hz\n", + gdata->status, + gdata->fft_info.chirp_rate, gdata->wu.subband_sample_rate/gdata->fft_info.fft_len + ); + } else { + strcpy( buf, "" ); + } +} + +// decide what type of signal to display. +// If there's anything new (dirty) display it. +// Otherwise cycle through the types +// +int SAH_GRAPHICS::choose_signal_to_display(double time_of_day) { + int choices[3], nchoices; + + if (gdata->gi.dirty) { + gdata->gi.dirty = false; + return 0; + } else if (gdata->pi.dirty) { + gdata->pi.dirty = false; + return 1; + } else if (gdata->ti.dirty) { + gdata->ti.dirty = false; + return 2; + } else { + nchoices = 0; + if (gdata->gi.peak_power) { + choices[nchoices++] = 0; + } + if (gdata->pi.peak_power) { + choices[nchoices++] = 1; + } + if (gdata->ti.peak_power) { + choices[nchoices++] = 2; + } + if (nchoices == 0) return -1; + if (nchoices == 1) return choices[0]; + int i = (int)fmod(time_of_day/5., (double)nchoices); // rotate every 5 seconds + return choices[i]; + } +} + +void SAH_GRAPHICS::render_pillars(double time_of_day, double dt) { + int i; + float pos[3]; + double cur_cpu_time; + double max = 0, d; + float pulseData[PULSE_POT_LEN]; + float tripletData[TRIPLET_POT_LEN]; + float gaussFunc[GAUSS_POT_LEN]; + char buf[512],time_buf[256]; + const char *TitleText="SETI@home 7"; + + + int s4_id=3; + + if (gdata && gdata->ready) { + s4_id=gdata->wu.s4_id; + if (s4_id > 2) { + TitleText="SETI@home Version 7"; + } + } + + draw_pillars(); + + // draw User and Data text + // + mode_lines(); + + glColor3f(1., 1., 1.); // white text + pos[0] = 2; + pos[1] = 2.15; + pos[2] = 0; + draw_text_line(pos, 0.2, 2.0, "Data info"); + pos[0] = 1.2; + pos[1] -= 0.2; + + get_data_info_string(buf); + + draw_text(pos, 0.1, 1.0, 0.15, buf ); + pos[0] = 2; + pos[1] = .8; + draw_text_line(pos, 0.2, 2.0, "User info"); + pos[0] = 1.2; + pos[1] -= .2; + + get_user_info_string(buf); + draw_text(pos, 0.1, 1.0, 0.15, buf); + pos[0] = -2.75; + pos[1] = 2.15; + draw_text_line(pos, 0.2, 2.0, TitleText); + pos[0] = -3.5; + pos[1] = 1.9; + + get_analysis_info_string(buf); + draw_text(pos, 0.1, 1.0, 0.15, buf); + + // draw CPU time and progress bars + // + pos[1] = 0.3; + cur_cpu_time=gdata->cpu_time; + ndays_to_string(cur_cpu_time/SECONDS_PER_DAY, 0, time_buf ); + sprintf(buf, "Overall %.3f%% done CPU time: %s", floor(gdata->progress*100000)/1000, time_buf); + draw_text_line(pos, 0.1, 1.0, buf); + mode_unshaded(); + + inner_progress.draw(gdata->local_progress); + outer_progress.draw(gdata->progress); + + // draw current or best signal + // + + if (!gdata->ready) return; + glColor3f(1., 1., 1.); + mode_unshaded(); + + pos[0] = -3.5; + pos[1] = 1.6; + pos[2] = 0.; + + switch (choose_signal_to_display(time_of_day)) { + case 0: + if (gdata->gi.peak_power) { + sprintf( buf, "%sGaussian: power %5.2f, fit %5.3f, score %5.3f", + gdata->gi.is_best?"Best ":"New ", + gdata->gi.peak_power, gdata->gi.chisqr, gdata->gi.score ); + draw_text(pos, 0.1, 1.0, 0.15, buf); + + for (i=0;igi.pot[i] > max) max = gdata->gi.pot[i]; + } + for (i=0;igi.fft_ind)/gdata->gi.sigma; + gaussFunc[i] = (gdata->gi.mean_power + gdata->gi.peak_power*exp(-d*d*0.693))/max; + } + rnd_graph.draw(gdata->gi.pot, GAUSS_POT_LEN); + sin_graph.draw(gaussFunc, GAUSS_POT_LEN); + } + break; + case 1: + if (gdata->pi.peak_power) { + sprintf( buf, "%sPulse: power %5.2f, period %6.4f, score %5.2f", + gdata->pi.is_best?"Best ":"New ", + gdata->pi.peak_power, gdata->pi.period, gdata->pi.score ); + draw_text(pos, 0.1, 1.0, 0.15, buf); + + for (i=0;ipi.pot_max[i]/255.0; + } + rnd_graph.draw(pulseData, PULSE_POT_LEN); + } + break; + case 2: + if (gdata->ti.peak_power) { + sprintf( + buf, "%sTriplet: power %5.2f, period %6.4f", + gdata->ti.is_best?"Best ":"New ", + gdata->ti.peak_power, gdata->ti.period + ); + draw_text(pos, 0.1, 1.0, 0.15, buf); + for (i=0;iti.pot_max[i]/255.0; + } + rnd_graph.add_tick(gdata->ti.tpotind0_0, 0); + rnd_graph.add_tick(gdata->ti.tpotind1_0, 1); + rnd_graph.add_tick(gdata->ti.tpotind2_0, 2); + rnd_graph.draw(tripletData, TRIPLET_POT_LEN, true); + } + break; + } +} +extern float* white; +void SAH_GRAPHICS::render_headsup(double time_of_day, double dt) { + double cur_cpu_time; + COLOR color; + color.a = .7; + double lum = .5; + double sat = .5; + double hue = start_hue + hue_change/2.; + if (hue > 1) hue -= 1; + if (hue < 1) hue += 1; + HLStoRGB(hue, lum, sat, color); + + mode_ortho(); + GLfloat char_height = 0.015; + GLfloat line_width = 0.25; + GLfloat line_spacing = 0.03; + GLfloat margin = 0.2; + char buf[512], time_buf[256]; + + float pos[3] = {0, 0.7, 1.0}; + + mode_unshaded(); + + //float pos1[3] = {.03,.94,1.0}; + //float pos2[3] = {.97,.94,1.0}; + float pos1[3] = {0, .62, 1.0}; + float pos2[3] = {1, .71, 1.0}; + + get_analysis_info_string(buf); + draw_text(pos1, char_height, line_width, line_spacing, buf); + + get_user_info_string(buf); + get_data_info_string(time_buf); + strcat(buf, time_buf); + draw_text_right(pos2, char_height, line_width, line_spacing, buf); + + cur_cpu_time=gdata->cpu_time; + ndays_to_string(cur_cpu_time/SECONDS_PER_DAY, 0, time_buf ); + sprintf(buf, "Overall %.3f%% done CPU time: %s", floor(gdata->progress*100000)/1000, time_buf); + draw_text(pos, char_height, line_width, line_spacing, buf); + + outer_progress_2d.draw(gdata->progress); + glColor4f(1,1,1,1); + + if (gdata->ready) { + double max = 0, d; + float pulseData[PULSE_POT_LEN]; + float tripletData[TRIPLET_POT_LEN]; + float gaussFunc[GAUSS_POT_LEN]; + char buf[256]; + int choice; + int i; + + choice = choose_signal_to_display(time_of_day); + pos[1]=.47; + switch (choice) { + case 0: + if (gdata->gi.peak_power) { + sprintf( buf, "%sGaussian: power %5.2f, fit %5.3f, score %5.3f", + gdata->gi.is_best?"Best ":"", + gdata->gi.peak_power, gdata->gi.chisqr, gdata->gi.score ); + draw_text(pos, char_height, line_width, line_spacing, buf); + + for (i=0;igi.pot[i] > max) max = gdata->gi.pot[i]; + } + for (i=0;igi.fft_ind)/gdata->gi.sigma; + gaussFunc[i] = (gdata->gi.mean_power + gdata->gi.peak_power*exp(-d*d*0.693))/max; + } + sin_graph.draw(gaussFunc, GAUSS_POT_LEN); + rnd_graph.draw(gdata->gi.pot, GAUSS_POT_LEN); + } + break; + case 1: + if (gdata->pi.peak_power) { + sprintf( + buf, "%sPulse: power %5.2f, period %6.4f, score %5.2f", + gdata->pi.is_best?"Best ":"", + gdata->pi.peak_power, gdata->pi.period, gdata->pi.score + ); + draw_text(pos, char_height, line_width, line_spacing, buf); + + for (i=0;ipi.pot_max[i]/255.0; + } + rnd_graph.draw(pulseData, PULSE_POT_LEN); + } + break; + case 2: + if (gdata->ti.peak_power) { + sprintf( + buf, "Best Triplet: power %5.2f, period %6.4f", + gdata->ti.peak_power, gdata->ti.period + ); + draw_text(pos, char_height, line_width, line_spacing, buf); + for (i=0;iti.pot_max[i]/255.0; + } + rnd_graph.add_tick(gdata->ti.tpotind0_0, 1 ); + rnd_graph.add_tick(gdata->ti.tpotind1_0, 1 ); + rnd_graph.add_tick(gdata->ti.tpotind2_0, 1 ); + rnd_graph.draw(tripletData, TRIPLET_POT_LEN); + } + break; + } + } + + ortho_done(); +} + +void SAH_GRAPHICS::render_panels(double time_of_day, double dt) { + double cur_cpu_time; + char buf[512],time_buf[256]; + + float pos[3] = {0., 0., 0.}; + int i; + MOVING_TEXT_PANEL tp[2]; + + get_user_info_string(buf); + get_data_info_string(time_buf); + strcat(buf, time_buf); + text_panels[0].set_text(0, buf); + + get_analysis_info_string(buf); + text_panels[1].set_text(0, buf); + + cur_cpu_time=gdata->cpu_time; + ndays_to_string(cur_cpu_time/SECONDS_PER_DAY, 0, time_buf ); + sprintf(buf, "Overall %.3f%% done CPU time: %s", floor(gdata->progress*100000)/1000, time_buf); + text_panels[1].set_text(6, buf); + + text_panels[1].get_pos(8, pos); + pos[2]+=.01; + outer_progress_2d.set_pos(pos); + + pos[0] = 0.03; + pos[1] = 0.76; + pos[2] = 0; + + mode_unshaded(); + + outer_progress_2d.draw(gdata->progress); + glColor4f(1,1,1,1); + + if (gdata->ready) { + double max = 0, d; + float pulseData[PULSE_POT_LEN]; + float tripletData[TRIPLET_POT_LEN]; + //float pos[3] = {.03, .94-(2.*line_spacing), 0.}; + float gaussFunc[GAUSS_POT_LEN]; + char buf[256]; + int choice; + int i; + + choice = choose_signal_to_display(time_of_day); + strcpy(buf, ""); + switch (choice) { + case 0: + if (gdata->gi.peak_power) { + sprintf( buf, "%sGaussian: power %5.2f, fit %5.3f, score %5.3f", + gdata->gi.is_best?"Best ":"", + gdata->gi.peak_power, gdata->gi.chisqr, gdata->gi.score + ); + + for (i=0;igi.pot[i] > max) max = gdata->gi.pot[i]; + } + for (i=0;igi.fft_ind)/gdata->gi.sigma; + gaussFunc[i] = (gdata->gi.mean_power + gdata->gi.peak_power*exp(-d*d*0.693))/max; + } + + text_panels[1].get_pos(4, pos); + rnd_graph.set_pos(pos); + text_panels[1].get_pos(4, pos); + pos[2] -= -.01; + sin_graph.set_pos(pos); + sin_graph.draw(gaussFunc, GAUSS_POT_LEN); + rnd_graph.draw(gdata->gi.pot, GAUSS_POT_LEN); + } + break; + case 1: + if (gdata->pi.peak_power) { + sprintf( buf, "%sPulse: peak_power %5.2f, period %6.4f, score %5.2f", + gdata->pi.is_best?"Best ":"", + gdata->pi.peak_power, gdata->pi.period, gdata->pi.score + ); + + for (i=0;ipi.pot_max[i]/255.0; + } + + text_panels[1].get_pos(4, pos); + rnd_graph.set_pos(pos); + rnd_graph.draw(pulseData, PULSE_POT_LEN); + } + break; + case 2: + if (gdata->ti.peak_power) { + sprintf( + buf, "Best Triplet: power %5.2f, period %6.4f", + gdata->ti.peak_power, gdata->ti.period + ); + for (i=0;iti.pot_max[i]/255.0; + } + + text_panels[1].get_pos(4, pos); + rnd_graph.set_pos(pos); + + rnd_graph.add_tick(gdata->ti.tpotind0_0, 0); + rnd_graph.add_tick(gdata->ti.tpotind1_0, 1); + rnd_graph.add_tick(gdata->ti.tpotind2_0, 2); + rnd_graph.draw(tripletData, TRIPLET_POT_LEN); + } + break; + } + text_panels[1].set_text(5, buf); + } + for (i=0; i<2; i++) { + tp[i] = text_panels[i]; + } + + MOVING_TEXT_PANEL::sort(tp, 2); + for (i=0; i<2; i++) { + tp[i].draw(); + } + for (i=0; i<2; i++) { + text_panels[i].move(dt); + } + +} + +void app_graphics_render(int x, int y, double t) { + sah_graphics.render(x, y, t); +} + +void app_graphics_init() { + sah_graphics.graphics_thread_init(); +} + +void SAH_GRAPHICS::data_struct_init() { + SAH_GRAPHICS_BASE::data_struct_init(); +} + +// Name is misleading - this gets called each time the app switches mode +// +void SAH_GRAPHICS::graphics_thread_init() { + SAH_GRAPHICS_BASE::graphics_thread_init(); + setup_given_prefs(); +} + +void SAH_GRAPHICS::setup_given_prefs() { + float pos[3], size[3]; + float outer[] = {1.0, 0., 0.2, 0.4}; + float inner[] = {0.2, 0.0, 0.7, 0.9}; + + float red[] = {1., 0., 0., 1.}; + float green[] = {0., 1., 0., 1.}; + float white[] = {1., 1., 1., 1.}; + float reda[] = {1., 0, 0, .8}; + + pos[0] = -3.5; + pos[1] = 0.8; + pos[2] = -.4; + size[0] = 4.; + size[1] = .5; + size[2] = .4; + + SAH_GRAPHICS_BASE::setup_given_prefs(); + + switch (text_style) { + case TEXT_STYLE_PILLARS: + rnd_graph.init(pos, size, red, green); + pos[2] = -.2; + size[2] = .1; + sin_graph.init(pos, size, white, white); + pos[0] = -1.5; + pos[1] = 1.95; + pos[2] = 0; + inner_progress.init(pos, 1.0, 0.07, 0.05, outer, inner); + + pos[0] = -3.5; + pos[1] = 0.60; + pos[2] = 0; + outer_progress.init(pos, 4., 0.1, 0.08, outer,inner); + break; + case TEXT_STYLE_HEADSUP: + pos[0] = .03; + pos[1] = .5; + pos[2] = 1; + size[0] = .4; + size[1] = .08; + size[2] = 0; + rnd_graph.init(pos, size, reda, green); + size[2]=0; + pos[2]=0; + sin_graph.init(pos, size, white, white); + pos[0] = .03; + pos[1] = 0.67; + pos[2] = 0; + outer_progress_2d.init(pos,.4,.02,.015,outer,inner); + break; + case TEXT_STYLE_PANELS: + init_text_panels(); + size[0] = 3; + size[1] = .5; + size[2] = .1; + rnd_graph.init(pos, size, reda, green); + size[2]=.05; + sin_graph.init(pos, size, white, white); + pos[0] = .03; + pos[1] = .745; + pos[2] = 0; + outer[3]=.7; + outer_progress_2d.init(pos,3,.2,.15,outer,inner); + break; + } + + pos[0] = -3.50; + pos[1] = -2.50; + pos[2] = -2.00; + size[0] = 7.00; + size[1] = 2.00; + size[2] = 4.00; + rarray.init_display( + graph_style, pos, size, start_hue, hue_change, graph_alpha, + "Frequency (Hz)","Power","Time (sec)" + ); +} + +void app_graphics_resize(int w, int h) { + sah_graphics.resize(w, h); +} + +void boinc_app_mouse_move(int x, int y, int left, int middle, int right) { + if (left) { + sah_graphics.pitch_angle += (y-mouse_y)*.1; + sah_graphics.roll_angle += (x-mouse_x)*.1; + mouse_y = y; + mouse_x = x; + } else if (right) { + double d = (y-mouse_y); + sah_graphics.viewpoint_distance *= exp(d/100.); + mouse_y = y; + mouse_x = x; + } else { + mouse_down = false; + } +} + +void boinc_app_mouse_button(int x, int y, int which, int is_down) { + if (is_down) { + mouse_down = true; + mouse_x = x; + mouse_y = y; + } else { + mouse_down = false; + } +} + +void boinc_app_key_press(int, int) {} + +void boinc_app_key_release(int, int) {} + +static void app_init_camera(double dist) { + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective( + 45.0, // field of view in degree + 1.0, // aspect ratio + 1.0, // Z near clip + 1000.0 // Z far + ); + + set_viewpoint(dist); +} + +void SAH_GRAPHICS::render(int xs, int ys, double time_of_day) { + static double last_time=0; + double dt = 0; + + if (!sah_shmem) { + sah_shmem = (SAH_SHMEM*)boinc_graphics_get_shmem("setiathome"); + gdata = &(sah_shmem->gdata); + } + gdata->countdown = 5; + + if (last_time != 0) { + dt = time_of_day - last_time; + } + last_time = time_of_day; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + if (starfield_size) { + starfield.update_stars(dt); + } + + render_logos(); + app_init_camera(viewpoint_distance); + scale_screen(width, height); + + start_rotate(); + incr_rotate(dt); + + render_background(); + + switch (text_style) { + case TEXT_STYLE_PILLARS: + render_pillars(time_of_day, dt); + break; + case TEXT_STYLE_PANELS: + render_panels(time_of_day, dt); + break; + case TEXT_STYLE_HEADSUP: + render_headsup(time_of_day, dt); + break; + } + render_3d_graph(time_of_day); + end_rotate(); + glFlush(); +} diff --git a/client/sah_gfx.h b/client/sah_gfx.h new file mode 100644 index 0000000..9f7602a --- /dev/null +++ b/client/sah_gfx.h @@ -0,0 +1,70 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +#ifndef SAH_GFX_H +#define SAH_GFX_H + +#include "gdata.h" +#include "reduce.h" +#include "gutil.h" +#include "sah_gfx_base.h" + + +// SAH_GRAPHICS combines all the info needed to draw S@h graphics: +// - user preferences (GRAPHICS_PREFS) +// - generic project graphics (SAH_GRAPHICS_BASE) +// - data from the analysis (GDATA) +// - internal state +// Its member functions do the rendering +// +class SAH_GRAPHICS: public SAH_GRAPHICS_BASE { + PROGRESS inner_progress; + PROGRESS outer_progress; + PROGRESS_2D outer_progress_2d; // outer progress for 2D display + RIBBON_GRAPH rnd_graph; + RIBBON_GRAPH sin_graph; + MOVING_TEXT_PANEL text_panels[3]; + void render_pillars(double, double); + void render_panels(double, double); + void render_headsup(double, double); + void init_text_panels(); + void get_data_info_string(char*); + void get_user_info_string(char*); + void get_analysis_info_string(char*); + int choose_signal_to_display(double time_of_day); +public: + void render(int x, int y, double t); + void data_struct_init(); + void graphics_thread_init(); + void reread_prefs(); + void setup_given_prefs(); +}; + +extern SAH_GRAPHICS sah_graphics; + +#endif + diff --git a/client/sah_gfx_base.cpp b/client/sah_gfx_base.cpp new file mode 100644 index 0000000..bf920d1 --- /dev/null +++ b/client/sah_gfx_base.cpp @@ -0,0 +1,367 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +#include "sah_config.h" + +#ifdef _WIN32 +#include "boinc_win.h" +#include // Header File For The OpenGL32 Library +#include // Header File For The GLu32 Library +#if !defined(__MINGW32__) && !defined(_MSC_VER) + #include // Header File For The Glaux Library +#endif +#include +#endif + +#ifndef _WIN32 +#include +#include + +#ifdef __APPLE_CC__ +#include +#include +#include +#include +#include +#include +#include +#endif +#endif + +#ifdef HAVE_IEEEFP_H +#include +#endif + +#include "s_util.h" +#include "db/db_table.h" +#include "db/schema_master.h" +#include "boinc_gl.h" +#include "parse.h" +#include "graphics2.h" +#include "sah_gfx_base.h" +#include "gutil.h" +#include "reduce.h" +#include "graphics_data.h" +#include "filesys.h" + +#define PI2 (2*3.1415926) + +#define SETI_LOGO_FILENAME "seti_logo" +#define USER_LOGO_FILENAME "user_logo" +#define BACKGROUND_FILENAME "background" + +// maximum resolutions for power graph +#define MAX_GRAPH_RES_X 200 +#define MAX_GRAPH_RES_Y 100 + +extern bool mouse_down; + +using namespace std; + +// The following must agree with the strings in +// project_specific_prefs.inc +// + +void GRAPHICS_PREFS::parse_project_prefs(char *buf) { + std::string text; + + if (!buf) return; + if (parse_str(buf, "", text)) { + if (!strcmp(text.c_str(), "Pillars")) text_style = TEXT_STYLE_PILLARS; + if (!strcmp(text.c_str(), "Panels")) text_style = TEXT_STYLE_PANELS; + if (!strcmp(text.c_str(), "Heads-up")) text_style = TEXT_STYLE_HEADSUP; + } + + if (parse_str(buf, "", text)) { + if (!strcmp(text.c_str(), "Rectangles")) graph_style = GRAPH_STYLE_RECTANGLES; + if (!strcmp(text.c_str(), "Wireframe")) graph_style = GRAPH_STYLE_WIREFRAME; + if (!strcmp(text.c_str(), "Surface")) graph_style = GRAPH_STYLE_SURFACE; + if (!strcmp(text.c_str(), "Planes")) graph_style = GRAPH_STYLE_PLANES; + } + parse_double(buf, "", max_fps); + parse_double(buf, "", max_cpu); + parse_double(buf, "", grow_time); + parse_double(buf, "", hold_time); + parse_double(buf, "", graph_alpha); + parse_double(buf, "", roll_period); + parse_double(buf, "", roll_range); + parse_double(buf, "", pitch_period); + parse_double(buf, "", pitch_range); + parse_int(buf, "", starfield_size); + parse_double(buf, "", starfield_speed); + parse_double(buf, "", start_hue); + parse_double(buf, "", hue_change); +} + +void GRAPHICS_PREFS::defaults() { + text_style = TEXT_STYLE_PILLARS; + graph_style = GRAPH_STYLE_RECTANGLES; + max_fps = 20; + max_cpu = 30; + grow_time = 3; + hold_time = 2; + graph_alpha = 0.7; + + pitch_period = 10; + pitch_range = 20; + roll_period = 30; + roll_range = 30; + starfield_size = 2000; + starfield_speed = 400.0f; + + start_hue = 0.2; + hue_change = 0.7; +} + +SAH_GRAPHICS_BASE::SAH_GRAPHICS_BASE() : + GRAPHICS_PREFS(), + //GDATA(), + roll_angle(0),roll_phase(0), + pitch_angle(0),pitch_phase(0),starfield(),seti_logo_texture(), + user_logo_texture(), background_texture(),viewpoint_distance(1.0) +{ + data_struct_init(); +} + +void SAH_GRAPHICS_BASE::start_rotate() { + if (roll_period == 0 && pitch_period == 0) return; + glPushMatrix(); + if (pitch_period) { + glRotated(pitch_angle + pitch_range*sin(pitch_phase), 1., 0., 0); + } + if (roll_period) { + glRotated(roll_angle + roll_range*sin(roll_phase), 0., 1., 0); + } +} + +void SAH_GRAPHICS_BASE::incr_rotate(double dt) { + if (mouse_down) return; + pitch_phase += PI2*(dt/pitch_period); + if (pitch_phase > PI2) pitch_phase -= PI2; + roll_phase += PI2*(dt/roll_period); + if (roll_phase > PI2) roll_phase -= PI2; +} + +void SAH_GRAPHICS_BASE::end_rotate() { + if (roll_period == 0 && pitch_period == 0) return; + glPopMatrix(); +} + +// A note on our coordinates: +// X should be between -4 and 4 +// Y should be between -3 and 3 +// Z should be centered around zero (graph is -2 to +2) + +void SAH_GRAPHICS_BASE::draw_pillars() { + float pos[3]; + GLfloat violet[] = {0.6, 0.3, .8, 1.0}; + GLfloat white[] = {1.0, 1.0, 1.0, 1.0}; + COLOR color; + double lum = .5; + double sat = .5; + double hue = start_hue + hue_change/2.; + if (hue > 1) hue -= 1; + if (hue < 1) hue += 1; + HLStoRGB(hue, lum, sat, color); + color.a = 1.0; + GLfloat graphColor[4] = {color.r,color.g,color.b,color.a}; + + pos[0] = pos[1] = pos[2] = 0; + mode_shaded(graphColor); + pos[0] = -3.50; pos[1] = 0; + drawCylinder(false, pos, 7.00, .10); + drawSphere(pos, .10); + pos[0] = 3.5; drawSphere(pos, .1); + + pos[0] = -3.50; pos[1] = 2.50; + drawCylinder(false, pos, 7.00, .10); + drawSphere(pos, .10); + pos[0] = 3.5; drawSphere(pos, .1); + + pos[0] = 1.00; pos[1] = 1.25; + drawCylinder(false, pos, 2.50, .10); + pos[0] = 3.5; drawSphere(pos, .1); + + pos[0] = 1.00; pos[1] = 0; + drawCylinder(true, pos, 2.50, .10); +} + +void set_viewpoint(double dist) { + double x, y, z; + x = 0; + y = 3.0*dist; + z = 11.0*dist; + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + gluLookAt( + x, y, z, // eye position + 0,-.8,0, // where we're looking + 0.0, 1.0, 0. // up is in positive Y direction + ); + +} + + +static void initlights() { + GLfloat ambient[] = {1., 1., 1., 1.0}; + GLfloat position[] = {-13.0, 6.0, 20.0, 1.0}; + GLfloat dir[] = {-1, -.5, -3, 1.0}; + glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); + glLightfv(GL_LIGHT0, GL_POSITION, position); + glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, dir); +} + +void SAH_GRAPHICS_BASE::render_logos() { + float pos[3] = {.03, .03, 0}; + float size[3] = {.5, .14, 0}; + bool any = seti_logo_texture.present || user_logo_texture.present; + + if (any) { + mode_ortho(); + mode_unshaded(); + } + + //draw texture justified at bottom left relative to coords + if (seti_logo_texture.present) { + seti_logo_texture.draw(pos, size, ALIGN_BOTTOM, ALIGN_BOTTOM); + } + + float pos2[3] = {.7, .03, 0}; + float size2[3] = {.27, .3, 0}; + //draw texture justified at bottom right relative to coords + if (user_logo_texture.present) { + user_logo_texture.draw(pos2, size2, ALIGN_TOP, ALIGN_BOTTOM); + } + if (any) { + ortho_done(); + } +} + +void SAH_GRAPHICS_BASE::render_background() { + float pos[3], size[3]; + // draw image behind graph, if any + // + if (background_texture.present) { + mode_texture(); + pos[0] = -3; pos[1] = -3; pos[2] = -2; + size[0] = 6; size[1] = 6; size[2] = 0; + background_texture.draw(pos, size, ALIGN_CENTER, ALIGN_CENTER); + } +} + +void SAH_GRAPHICS_BASE::render_3d_graph(double time_of_day) { + double elapsed_time,frac_done; + + if (rarray.start_time == 0) { + rarray.start_time = time_of_day; + } + elapsed_time = time_of_day - rarray.start_time; + if (elapsed_time >= grow_time) { + frac_done = 1.0; + } else { + frac_done = elapsed_time/grow_time; + } + rarray.draw_axes(); + rarray.draw_labels(); + + rarray.draw_part(frac_done); + if (elapsed_time >= grow_time + hold_time) { + memcpy(&rarray, &sah_shmem->rarray_data, sizeof(REDUCED_ARRAY_DATA)); + rarray.start_time = time_of_day; + rarray.new_array(); + } +} + + +// this sets up the shared data structures, +// don't make any OpenGL calls from here +// This is called before BOINC initialization, +// so don't do any BOINC-related stuff +// +void SAH_GRAPHICS_BASE::data_struct_init() { + defaults(); + srand(time(NULL)); +} + +// this is called from the graphics thread; +// it does OpenGL initialization. +// This is always called after init_worker_thread(), +// so the graphics prefs are in place. +// +void SAH_GRAPHICS_BASE::graphics_thread_init() { + boinc_get_init_data(app_init_data); + parse_project_prefs(app_init_data.project_preferences); + + glShadeModel(GL_SMOOTH); // Enable Smooth Shading + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Black Background + glClearDepth(1.0f); // Depth Buffer Setup + glEnable(GL_DEPTH_TEST); // Enables Depth Testing + glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations + initlights(); + + int viewport[4]; + get_viewport(viewport); + int w = viewport[2]; + int h = viewport[3]; + resize(w,h); +} + +void SAH_GRAPHICS_BASE::resize(int w, int h) { + //float fontsize = (w/35.0f>14) ? 14 : w/35.0f; + //int weight = (700>w*35.0f/24.0f) ? 700 : w*35.0f/24.0f; + //listBase=MyCreateFont("Ariel",fontsize,weight); + height=h; + width=w; + glViewport(0, 0, w, h); +} + +void SAH_GRAPHICS_BASE::setup_given_prefs() { + char filename[256]; + + boinc_max_fps = max_fps; + boinc_max_gfx_cpu_frac = max_cpu/100.; + if (starfield_size) { + starfield.build_stars(starfield_size, starfield_speed); + } + seti_logo_texture.present = false; + user_logo_texture.present = false; + background_texture.present = false; + + double fsize=0; + boinc_resolve_filename(SETI_LOGO_FILENAME, filename, sizeof(filename)); + if (!file_size(filename,fsize) && (fsize>4096)) { + seti_logo_texture.load_image_file(filename); + } else { + fprintf(stderr,"Warning: unable to load JPEG file. File size=%d\n",(int)fsize); + seti_logo_texture.present=false; + } + boinc_resolve_filename(USER_LOGO_FILENAME, filename, sizeof(filename)); + user_logo_texture.load_image_file(filename); + boinc_resolve_filename(BACKGROUND_FILENAME, filename, sizeof(filename)); + background_texture.load_image_file(filename); +} diff --git a/client/sah_gfx_base.h b/client/sah_gfx_base.h new file mode 100644 index 0000000..487dd36 --- /dev/null +++ b/client/sah_gfx_base.h @@ -0,0 +1,100 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +#include +#include "boinc_api.h" + +#include "gutil.h" +#include "gdata.h" +#include "graphics_data.h" + +#include "reduce.h" + +typedef enum { + TEXT_STYLE_PILLARS, // panels delimited by cylinders + TEXT_STYLE_PANELS, // rotating panels + TEXT_STYLE_HEADSUP // 2D text in corners +} TEXT_STYLE; + +// User's graphics-related per-project preferences for SETI@home +// +struct GRAPHICS_PREFS { + TEXT_STYLE text_style; + GRAPH_STYLE graph_style; + double max_fps; // max frames per second + double max_cpu; // max pct of CPU + double graph_alpha; + double pitch_period; + double pitch_range; // degrees + double roll_period; + double roll_range; + int starfield_size; + double starfield_speed; + double start_hue, hue_change; // determine graph colors + double grow_time; + double hold_time; + + void parse_project_prefs(char*); + void defaults(); + GRAPHICS_PREFS() { defaults(); }; +}; + +class SAH_GRAPHICS_BASE: /* public GDATA, */ public GRAPHICS_PREFS { +public: + double roll_angle; + double roll_phase; + double pitch_angle; + double pitch_phase; + STARFIELD starfield; + TEXTURE_DESC seti_logo_texture; + TEXTURE_DESC user_logo_texture; + TEXTURE_DESC background_texture; + APP_INIT_DATA app_init_data; + double viewpoint_distance; + int width, height; + REDUCED_ARRAY_RENDER rarray; + SAH_SHMEM* sah_shmem; + GDATA* gdata; + + SAH_GRAPHICS_BASE(); + void data_struct_init(); + void graphics_thread_init(); + void reread_prefs(); + void setup_given_prefs(); + + void resize(int, int); + void start_rotate(); + void incr_rotate(double dt); + void end_rotate(); + void draw_pillars(); + void render_logos(); + void render_background(); + void render_3d_graph(double time_of_day); +}; + +extern void set_viewpoint(double); +extern bool nographics(); diff --git a/client/sah_gfx_main.cpp b/client/sah_gfx_main.cpp new file mode 100644 index 0000000..0abe756 --- /dev/null +++ b/client/sah_gfx_main.cpp @@ -0,0 +1,67 @@ + +// Copyright 2007 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +#include "sah_gfx_main.h" +#include "boinc_api.h" +#include "graphics2.h" + +extern double progress; +SAH_SHMEM* sah_shmem; +REDUCED_ARRAY_GEN rarray; +GDATA* sah_graphics; +bool nographics_flag = false; + +void update_shmem() { + if (sah_graphics->countdown > 0) { + sah_graphics->countdown--; + } + boinc_wu_cpu_time(sah_graphics->cpu_time); + sah_graphics->progress=progress; +} + +void sah_graphics_init(APP_INIT_DATA& app_init_data) { + if (nographics_flag) return; + if ((app_init_data.host_info.m_nbytes != 0) && + (app_init_data.host_info.m_nbytes <= (double)(48*1024*1024)) + ) { + fprintf(stderr,"Low memory machine... Disabling graphics.\n"); + fprintf(stderr,"%f <= %f\n",app_init_data.host_info.m_nbytes,(double)48*1024*1024); + nographics_flag = true; + return; + } + sah_shmem = (SAH_SHMEM*)boinc_graphics_make_shmem("setiathome", sizeof(SAH_SHMEM)); + if (!sah_shmem) { + sah_shmem=(SAH_SHMEM*)boinc_graphics_get_shmem("setiathome"); + } + if (!sah_shmem) { + nographics_flag = true; + return; + } + sah_graphics = &(sah_shmem->gdata); + boinc_register_timer_callback(update_shmem); +} diff --git a/client/sah_gfx_main.h b/client/sah_gfx_main.h new file mode 100644 index 0000000..30eb172 --- /dev/null +++ b/client/sah_gfx_main.h @@ -0,0 +1,43 @@ +// Copyright 2007 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +#include +#include "gdata.h" +#include "boinc_api.h" + +extern SAH_SHMEM* sah_shmem; +extern REDUCED_ARRAY_GEN rarray; +extern GDATA* sah_graphics; +extern bool nographics_flag; + +inline bool nographics() { + if (nographics_flag) return true; + if (!sah_graphics) return true; + if (!sah_graphics->countdown) return true; + return false; +} +extern void sah_graphics_init(APP_INIT_DATA&); diff --git a/client/sah_version.cpp b/client/sah_version.cpp new file mode 100644 index 0000000..deca954 --- /dev/null +++ b/client/sah_version.cpp @@ -0,0 +1,32 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +// $Id: sah_version.cpp,v 1.1.2.1 2007/05/31 22:08:12 korpela Exp $ +#include "sah_config.h" +int gmajor_version = VERSION_MAJOR; +int gminor_version = VERSION_MINOR; + diff --git a/client/sah_version.h b/client/sah_version.h new file mode 100644 index 0000000..8ee221b --- /dev/null +++ b/client/sah_version.h @@ -0,0 +1,31 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +//$Id: sah_version.h,v 1.1.2.1 2007/05/31 22:08:12 korpela Exp $ +extern int gmajor_version; +extern int gminor_version; + diff --git a/client/seti.cpp b/client/seti.cpp new file mode 100644 index 0000000..50ac77f --- /dev/null +++ b/client/seti.cpp @@ -0,0 +1,932 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +// seti.C +// $Id: seti.cpp,v 1.60.2.19 2007/08/10 00:38:49 korpela Exp $ +// +// SETI-specific logic for reading/writing checkpoint files +// and parsing WU files. +// +// Files: +// state.txt +// the last chirp rate / FFT len finished, if any +// outfile.txt +// The append-only result file +// +// What finally gets sent back as the result file is: +// - the generic result header, with the final CPU time filled in +// - the SETI-specific part of the WU header +// - the contents of outfile.txt + +#include "sah_config.h" + +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#include +#include + +#ifdef BOINC_APP_GRAPHICS +#include "sah_gfx_main.h" +#endif + +#ifdef HAVE_IEEEFP_H +#include +#endif + +#include "boinc_api.h" +#include "str_util.h" +#include "str_replace.h" + +#include "diagnostics.h" +#include "parse.h" +#include "filesys.h" +#include "s_util.h" +#include "seti_header.h" +#include "analyze.h" +#include "analyzeFuncs.h" +#include "analyzeReport.h" +#include "analyzePoT.h" +#include "malloc_a.h" +#include "chirpfft.h" +#include "worker.h" + +#include "seti.h" + +#define DATA_ASCII 1 +#define DATA_ENCODED 2 +#define DATA_SUN_BINARY 3 + +APP_INIT_DATA app_init_data; + +ANALYSIS_STATE analysis_state; +static int wrote_header; +double LOAD_STORE_ADJUSTMENT=2.85; +double SETUP_FLOPS=1.42e+10/2.85; + +SPIKE_INFO::SPIKE_INFO() : track_mem("SPIKE_INFO"),s(), score(0), bin(0), fft_ind(0) {} + +SPIKE_INFO::~SPIKE_INFO() {} + +SPIKE_INFO::SPIKE_INFO(const SPIKE_INFO &si) : track_mem("SPIKE_INFO"), +s(si.s), score(si.score), bin(si.bin), fft_ind(si.fft_ind) {} + +SPIKE_INFO &SPIKE_INFO::operator =(const SPIKE_INFO &si) { + if (&si != this) { + s=si.s; + score=si.score; + bin=si.bin; + fft_ind=si.fft_ind; + } + return *this; +} + +AUTOCORR_INFO::AUTOCORR_INFO() : track_mem("AUTOCORR_INFO"),a(), score(0), bin(0), fft_ind(0) {} + +AUTOCORR_INFO::~AUTOCORR_INFO() {} + +AUTOCORR_INFO::AUTOCORR_INFO(const AUTOCORR_INFO &ai) : track_mem("AUTOCORR_INFO"), +a(ai.a), score(ai.score), bin(ai.bin), fft_ind(ai.fft_ind) {} + +AUTOCORR_INFO &AUTOCORR_INFO::operator =(const AUTOCORR_INFO &ai) { + if (&ai != this) { + a=ai.a; + score=ai.score; + bin=ai.bin; + fft_ind=ai.fft_ind; + } + return *this; +} + + +GAUSS_INFO::GAUSS_INFO() : track_mem("GAUSS_INFO"), +g(), score(0), display_power_thresh(0), bin(0), fft_ind(0) { +} + +GAUSS_INFO::~GAUSS_INFO() {} + +GAUSS_INFO::GAUSS_INFO(const GAUSS_INFO &gi) : track_mem("GAUSS_INFO"), +g(gi.g), score(gi.score), bin(gi.bin), fft_ind(gi.fft_ind) { +} + +GAUSS_INFO &GAUSS_INFO::operator =(const GAUSS_INFO &gi) { + if (&gi != this) { + g=gi.g; + score=gi.score; + bin=gi.bin; + fft_ind=gi.fft_ind; + } + return *this; +} + +PULSE_INFO::PULSE_INFO() : track_mem("PULSE_INFO"), p(), score(0), freq_bin(0), time_bin(0) { + +// debug possible heap corruption -- jeffc +#ifdef _WIN32 +BOINCASSERT(_CrtCheckMemory()); +#endif + + pot_min = (unsigned int *)calloc_a(swi.analysis_cfg.pulse_pot_length, sizeof(unsigned int), MEM_ALIGN); + if (pot_min == NULL) SETIERROR(MALLOC_FAILED, "new PULSE_INFO pot_min == NULL"); + pot_max = (unsigned int *)calloc_a(swi.analysis_cfg.pulse_pot_length, sizeof(unsigned int), MEM_ALIGN); + if (pot_max == NULL) SETIERROR(MALLOC_FAILED, "new PULSE_INFO pot_max == NULL"); + +// debug possible heap corruption -- jeffc +#ifdef _WIN32 +BOINCASSERT(_CrtCheckMemory()); +#endif + +} + + +PULSE_INFO::~PULSE_INFO() { +// debug possible heap corruption -- jeffc +#ifdef _WIN32 +BOINCASSERT(_CrtCheckMemory()); +#endif + + free_a(pot_min); + free_a(pot_max); + +// debug possible heap corruption -- jeffc +#ifdef _WIN32 +BOINCASSERT(_CrtCheckMemory()); +#endif + +} + + +PULSE_INFO::PULSE_INFO(const PULSE_INFO &pi) : track_mem("PULSE_INFO"), +p(pi.p), score(pi.score), freq_bin(pi.freq_bin), time_bin(pi.time_bin) { + +// debug possible heap corruption -- jeffc +#ifdef _WIN32 +BOINCASSERT(_CrtCheckMemory()); +#endif + + pot_min = (unsigned int *)calloc_a(swi.analysis_cfg.pulse_pot_length, sizeof(unsigned int), MEM_ALIGN); + if (pot_min == NULL) SETIERROR(MALLOC_FAILED, "copied PULSE_INFO pot_min == NULL"); + pot_max = (unsigned int *)calloc_a(swi.analysis_cfg.pulse_pot_length, sizeof(unsigned int), MEM_ALIGN); + if (pot_max == NULL) SETIERROR(MALLOC_FAILED, "copied PULSE_INFO pot_max == NULL"); + + memcpy(pot_min,pi.pot_min,(swi.analysis_cfg.pulse_pot_length * sizeof(unsigned int))); + memcpy(pot_max,pi.pot_max,(swi.analysis_cfg.pulse_pot_length * sizeof(unsigned int))); + +// debug possible heap corruption -- jeffc +#ifdef _WIN32 +BOINCASSERT(_CrtCheckMemory()); +#endif + +} + +PULSE_INFO &PULSE_INFO::operator =(const PULSE_INFO &pi) { + +// debug possible heap corruption -- jeffc +#ifdef _WIN32 +BOINCASSERT(_CrtCheckMemory()); +#endif + + if (&pi != this) { + p=pi.p; + score=pi.score; + freq_bin=pi.freq_bin; + time_bin=pi.time_bin; + + memcpy(pot_min,pi.pot_min,(swi.analysis_cfg.pulse_pot_length * sizeof(unsigned int))); + memcpy(pot_max,pi.pot_max,(swi.analysis_cfg.pulse_pot_length * sizeof(unsigned int))); + } + +// debug possible heap corruption -- jeffc +#ifdef _WIN32 +BOINCASSERT(_CrtCheckMemory()); +#endif + + return *this; +} + +TRIPLET_INFO::TRIPLET_INFO() : track_mem("TRIPLET_INFO"), +t(), score(0), bperiod(0), freq_bin(0), tpotind0_0(0), tpotind0_1(0), +tpotind1_0(0), tpotind1_1(0), tpotind2_0(0), tpotind2_1(0), time_bin(0), +scale(0) { + +// debug possible heap corruption -- jeffc +#ifdef _WIN32 +BOINCASSERT(_CrtCheckMemory()); +#endif + + pot_min = (unsigned int *)calloc_a(swi.analysis_cfg.triplet_pot_length, sizeof(unsigned int), MEM_ALIGN); + if (pot_min == NULL) SETIERROR(MALLOC_FAILED, "new TRIPLET_INFO pot_min == NULL"); + pot_max = (unsigned int *)calloc_a(swi.analysis_cfg.triplet_pot_length, sizeof(unsigned int), MEM_ALIGN); + if (pot_max == NULL) SETIERROR(MALLOC_FAILED, "new TRIPLET_INFO pot_max == NULL"); + +// debug possible heap corruption -- jeffc +#ifdef _WIN32 +BOINCASSERT(_CrtCheckMemory()); +#endif + +} + +TRIPLET_INFO::TRIPLET_INFO(const TRIPLET_INFO &ti) : track_mem("TRIPLET_INFO"), t(ti.t), score(ti.score), + + bperiod(ti.bperiod), freq_bin(ti.freq_bin), + tpotind0_0(ti.tpotind0_0), tpotind0_1(ti.tpotind0_1), + tpotind1_0(ti.tpotind1_0), tpotind1_1(ti.tpotind1_1), + tpotind2_0(ti.tpotind2_0), tpotind2_1(ti.tpotind2_1), + time_bin(ti.time_bin), scale(ti.scale) + +{ + +// debug possible heap corruption -- jeffc +#ifdef _WIN32 +BOINCASSERT(_CrtCheckMemory()); +#endif + + pot_min = (unsigned int *)calloc_a(swi.analysis_cfg.triplet_pot_length, sizeof(unsigned int), MEM_ALIGN); + if (pot_min == NULL) SETIERROR(MALLOC_FAILED, "copied TRIPLET_INFO pot_min == NULL"); + pot_max = (unsigned int *)calloc_a(swi.analysis_cfg.triplet_pot_length, sizeof(unsigned int), MEM_ALIGN); + if (pot_max == NULL) SETIERROR(MALLOC_FAILED, "copied TRIPLET_INFO pot_max == NULL"); + memcpy(pot_min,ti.pot_min,(swi.analysis_cfg.triplet_pot_length * sizeof(unsigned int))); + memcpy(pot_max,ti.pot_max,(swi.analysis_cfg.triplet_pot_length * sizeof(unsigned int))); + +// debug possible heap corruption -- jeffc +#ifdef _WIN32 +BOINCASSERT(_CrtCheckMemory()); +#endif + +} + +TRIPLET_INFO &TRIPLET_INFO::operator =(const TRIPLET_INFO &ti) { + +// debug possible heap corruption -- jeffc +#ifdef _WIN32 +BOINCASSERT(_CrtCheckMemory()); +#endif + + if (&ti != this) { + t=ti.t; + score=ti.score; + bperiod=ti.bperiod; + freq_bin=ti.freq_bin; + tpotind0_0=ti.tpotind0_0; + tpotind0_1=ti.tpotind0_1; + tpotind1_0=ti.tpotind1_0; + tpotind1_1=ti.tpotind1_1; + tpotind2_0=ti.tpotind2_0; + tpotind2_1=ti.tpotind2_1; + time_bin=ti.time_bin; + + memcpy(pot_min,ti.pot_min,(swi.analysis_cfg.triplet_pot_length * sizeof(unsigned int))); + memcpy(pot_max,ti.pot_max,(swi.analysis_cfg.triplet_pot_length * sizeof(unsigned int))); + } + +// debug possible heap corruption -- jeffc +#ifdef _WIN32 +BOINCASSERT(_CrtCheckMemory()); +#endif + + return *this; +} + + +TRIPLET_INFO::~TRIPLET_INFO() { + +// debug possible heap corruption -- jeffc +#ifdef _WIN32 +BOINCASSERT(_CrtCheckMemory()); +#endif + + free_a(pot_min); + free_a(pot_max); + +// debug possible heap corruption -- jeffc +#ifdef _WIN32 +BOINCASSERT(_CrtCheckMemory()); +#endif + +} + + +// Do SETI-specific initialization for a work unit. +// - prepare outfile for appending +// - reset scores +int seti_init_state() { + analysis_state.icfft= 0; + analysis_state.PoT_freq_bin = -1; + analysis_state.PoT_activity = POT_INACTIVE; + progress = 0.0; + reset_high_scores(); + std::string path; + + boinc_resolve_filename_s(OUTFILE_FILENAME, path); + if (outfile.open(path.c_str(), "ab")) SETIERROR(CANT_CREATE_FILE," in seti_init_state()"); + + return 0; +} + +// This gets called at the start of each chirp/fft pair. +int result_group_start() { + wrote_header = 0; + return 0; +} + +// This gets called prior to writing an entry in the output file. +// Write the chirp/fft parameters if not done already. + +int result_group_write_header() { + if (wrote_header) return 0; + wrote_header = 1; + int retval = outfile.printf( "\n", + analysis_state.icfft, + ChirpFftPairs[analysis_state.icfft].ChirpRate, + ChirpFftPairs[analysis_state.icfft].FftLen + ); + if (retval < 0) SETIERROR(WRITE_FAILED,"in result_group_write_header()"); + return 0; +} + + +// this gets called at the end of each chirp/fft pair +// Rewrite the state file, +// and write an end-of-group record to log file +// if anything was written for this group. +int result_group_end() { + int retval=0; + + if (wrote_header) { + retval = outfile.printf( "\n", + analysis_state.icfft, + ChirpFftPairs[analysis_state.icfft].ChirpRate, + ChirpFftPairs[analysis_state.icfft].FftLen); + if (retval < 0) SETIERROR(WRITE_FAILED,"in result_group_end"); + } + + return 0; +} + +int checkpoint(BOOLEAN force_checkpoint) { + + int retval=0, i, l=xml_indent_level; + xml_indent_level=0; + MFILE state_file; + char buf[2048]; + std::string enc_field, str; + + // The user may have set preferences for a long time between + // checkpoints to reduce disk access. + if (!force_checkpoint) { + if (!boinc_time_to_checkpoint()) return CHECKPOINT_SKIPPED; + } + + fflush(stderr); + +// debug possible heap corruption -- jeffc +#ifdef _WIN32 +BOINCASSERT(_CrtCheckMemory()); +#endif + + if (state_file.open(STATE_FILENAME, "wb")) SETIERROR(CANT_CREATE_FILE,"in checkpoint()"); + retval = state_file.printf( + "%d\n" + "%e\n" + "%d\n" + "%.8f\n" + "%d\n" + "%d\n" + "%d\n" + "%f\n" + "%d\n" + "%d\n" + "%d\n" + "%d\n" + "%d\n", + analysis_state.icfft, + ChirpFftPairs[analysis_state.icfft].ChirpRate, + ChirpFftPairs[analysis_state.icfft].FftLen, + std::min(progress,0.9999999), + analysis_state.PoT_freq_bin, + analysis_state.PoT_activity, + signal_count, + analysis_state.FLOP_counter, + spike_count, + autocorr_count, + pulse_count, + gaussian_count, + triplet_count + ); + if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); + + // checkpoint the best spike thus far (if any) + if(best_spike->s.fft_len) { + retval = state_file.printf("\n"); + if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); + // the spike proper + str = best_spike->s.print_xml(0,0,1); + retval = (int)state_file.write(str.c_str(), str.size(), 1); + // ancillary data + retval = state_file.printf( + "%f\n" + "%d\n" + "%d\n", + best_spike->score, + best_spike->bin, + best_spike->fft_ind); + if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); + retval = state_file.printf("\n"); + if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); + } + + // checkpoint the best autocorr thus far (if any) + if(best_autocorr->a.fft_len) { + retval = state_file.printf("\n"); + if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); + // the autocorr proper + str = best_autocorr->a.print_xml(0,0,1); + retval = (int)state_file.write(str.c_str(), str.size(), 1); + // ancillary data + retval = state_file.printf( + "%f\n" + "%d\n" + "%d\n", + best_autocorr->score, + best_autocorr->bin, + best_autocorr->fft_ind); + if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); + retval = state_file.printf("\n"); + if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); + } + + // checkpoint the best gaussian thus far (if any) + if(best_gauss->g.fft_len || best_gauss->score) { + retval = state_file.printf("\n"); + if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); + // the gaussian proper + str = best_gauss->g.print_xml(0,0,1); + retval = (int)state_file.write(str.c_str(), str.size(), 1); + // ancillary data + retval = state_file.printf( + "%f\n" + "%f\n" + "%d\n" + "%d\n", + best_gauss->score, + best_gauss->display_power_thresh, + best_gauss->bin, + best_gauss->fft_ind); + if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); + retval = state_file.printf("\n"); + if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); + } + + // checkpoint the best pulse thus far (if any) + // The check for len_prof is a kludge. + if(best_pulse->p.fft_len) { + retval = state_file.printf("\n"); + if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); + // the pulse proper + str = best_pulse->p.print_xml(0,0,1); + retval = (int)state_file.write(str.c_str(), str.size(), 1); + // ancillary data + retval = state_file.printf( + "%f\n" + "%d\n" + "%d\n", + best_pulse->score, + best_pulse->freq_bin, + best_pulse->time_bin); + if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); + retval = state_file.printf("\n"); + if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); + } + + // checkpoint the best triplet thus far (if any) + if(best_triplet->t.fft_len) { + retval = state_file.printf("\n"); + if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); + // the triplet proper + str = best_triplet->t.print_xml(0,0,1); + retval = (int)state_file.write(str.c_str(), str.size(), 1); + + // ancillary data + retval = state_file.printf( + "%f\n" + "%f\n" + "%d\n" + "%d\n" + "%d\n" + "%d\n" + "%d\n" + "%d\n" + "%d\n" + "%f\n" + "%f\n", + best_triplet->score, + best_triplet->bperiod, + best_triplet->tpotind0_0, + best_triplet->tpotind0_1, + best_triplet->tpotind1_0, + best_triplet->tpotind1_1, + best_triplet->tpotind2_0, + best_triplet->tpotind2_1, + best_triplet->freq_bin, + best_triplet->time_bin, + best_triplet->scale); + if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); + + // convert min PoT to chars, encode, and print + for (i=0; ipot_min[i]; + } + enc_field=xml_encode_string(buf, swi.analysis_cfg.triplet_pot_length, _x_csv); + retval = state_file.printf( + "", + enc_field.size(), xml_encoding_names[_x_csv] + ); + if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); + state_file.write(enc_field.c_str(), enc_field.size(), 1); + retval = state_file.printf("\n"); + if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); + + // convert max PoT to chars, encode, and print + for (i=0; ipot_max[i]; + } + enc_field=xml_encode_string(buf, swi.analysis_cfg.triplet_pot_length, _x_csv); + state_file.printf( + "", + enc_field.size(), xml_encoding_names[_x_csv] + ); + if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); + state_file.write(enc_field.c_str(), enc_field.size(), 1); + retval = state_file.printf("\n"); + if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); + retval = state_file.printf("\n"); + if (retval < 0) SETIERROR(WRITE_FAILED,"in checkpoint()"); + } + + // The result (outfile) and state mfiles are now synchronized. + // Flush them both. + retval = outfile.flush(); + if (retval) SETIERROR(WRITE_FAILED,"in checkpoint()"); + retval = state_file.flush(); + if (retval) SETIERROR(WRITE_FAILED,"in checkpoint()"); + retval = state_file.close(); + if (retval) SETIERROR(WRITE_FAILED,"in checkpoint()"); + boinc_checkpoint_completed(); + xml_indent_level=l; + +// debug possible heap corruption -- jeffc +#ifdef _WIN32 +BOINCASSERT(_CrtCheckMemory()); +#endif + + return 0; +} + +// Read the state file and set analysis_state accordingly. +// Note: The state of analysis is saved in two places: +// 1) at the end of processing the data for any given +// chirp/fft pair. In this case, the icfft index +// needs to be set for the *next* chirp/fft pair. +// If analysis was in this state when saved, +// PoT_freq_bin will have been set to -1. +// 2) at the end of PoT processing for any given +// frequency bin (for any given chirp/fft pair). +// This is indicated by PoT_freq_bin containing +// something other than -1. It will contain the +// frequency bin just completed. In this case, we +// are *not* finished processing for the current +// chirp/fft pair and we do not increment icfft to +// the next pair. We do however increment PoT_freq_bin +// to the next frequency bin. +// +int parse_state_file(ANALYSIS_STATE& as) { + static char buf[8192]; + int ncfft, fl, PoT_freq_bin, PoT_activity; + double cr=0,flops=0; + FILE* state_file; + +// debug possible heap corruption -- jeffc +#ifdef _WIN32 +BOINCASSERT(_CrtCheckMemory()); +#endif + + ncfft = -1; + progress = 0.0; + PoT_freq_bin = -1; + PoT_activity = POT_INACTIVE; + state_file = boinc_fopen(STATE_FILENAME, "rb"); + if (!state_file) SETIERROR(FOPEN_FAILED,"in parse_state_file()"); + + // main parsing loop + while (fgets(buf, sizeof(buf), state_file)) { + if (parse_int(buf, "", ncfft)) continue; + else if (parse_double(buf, "", cr)) continue; + else if (parse_int(buf, "", fl)) continue; + else if (parse_double(buf, "", progress)) continue; + else if (parse_int(buf, "", PoT_freq_bin)) continue; + else if (parse_int(buf, "", PoT_activity)) continue; + else if (parse_int(buf, "", signal_count)) continue; + else if (parse_double(buf, "", flops)) continue; + else if (parse_int(buf, "", spike_count)) continue; + else if (parse_int(buf, "", autocorr_count)) continue; + else if (parse_int(buf, "", pulse_count)) continue; + else if (parse_int(buf, "", gaussian_count)) continue; + else if (parse_int(buf, "", triplet_count)) continue; + // best spike + else if (xml_match_tag(buf, "")) { + while (fgets(buf, sizeof(buf), state_file)) { + if (xml_match_tag(buf, "")) break; + // spike proper + else if (xml_match_tag(buf, "")) { + char *p = buf + strlen(buf); + while(fgets(p, sizeof(buf)-(int)strlen(buf), state_file)) { + if (xml_match_tag(buf, "")) break; + p += strlen(p); + } + best_spike->s.parse_xml(buf); + } + // ancillary data + else if (parse_double(buf, "", best_spike->score)) continue; + else if (parse_int(buf, "", best_spike->bin)) continue; + else if (parse_int(buf, "", best_spike->fft_ind)) continue; + } // end while in best_spike + } // end if in best_spike + + // best autocorr + else if (xml_match_tag(buf, "")) { + while (fgets(buf, sizeof(buf), state_file)) { + if (xml_match_tag(buf, "")) break; + // autocorr proper + else if (xml_match_tag(buf, "")) { + char *p = buf + strlen(buf); + while(fgets(p, sizeof(buf)-(int)strlen(buf), state_file)) { + if (xml_match_tag(buf, "")) break; + p += strlen(p); + } + best_autocorr->a.parse_xml(buf); + } + // ancillary data + else if (parse_double(buf, "", best_autocorr->score)) continue; + else if (parse_int(buf, "", best_autocorr->bin)) continue; + else if (parse_int(buf, "", best_autocorr->fft_ind)) continue; + } // end while in best_autocorr + } // end if in best_autocorr + + // best gaussian.. + else if (xml_match_tag(buf, "")) { + while (fgets(buf, sizeof(buf), state_file)) { + if (xml_match_tag(buf, "")) break; + // gaussian proper + else if (xml_match_tag(buf, "")) { + char *p = buf + strlen(buf); + while(fgets(p, sizeof(buf)-(int)strlen(buf), state_file)) { + if (xml_match_tag(buf, "")) break; + p += strlen(p); + } + best_gauss->g.parse_xml(buf); + } + // ancillary data + else if (parse_double(buf, "", best_gauss->score)) continue; + else if (parse_double(buf, "", + best_gauss->display_power_thresh)) continue; + else if (parse_int(buf, "", best_gauss->bin)) continue ; + else if (parse_int(buf, "", best_gauss->fft_ind)) continue; + } // end while in best_gaissian + } // end if in best_gaussian + + // best pulse + else if (xml_match_tag(buf, "")) { + while (fgets(buf, sizeof(buf), state_file)) { + if (xml_match_tag(buf, "")) break; + // pulse proper + else if (xml_match_tag(buf, "")) { + char *p = buf + strlen(buf); + while(fgets(p, sizeof(buf)-(int)strlen(buf), state_file)) { + if (xml_match_tag(buf, "")) break; + p += strlen(p); + } + best_pulse->p.parse_xml(buf); + } + // ancillary data + else if (parse_double(buf, "", best_pulse->score)) continue; + else if (parse_int(buf, "", best_pulse->freq_bin)) continue; + else if (parse_int(buf, "", best_pulse->time_bin)) continue; + } // end while in best_pulse + } // end if in best_pulse + + // best triplet + else if (xml_match_tag(buf, "")) { + while (fgets(buf, sizeof(buf), state_file)) { + if (xml_match_tag(buf, "")) break; + // triplet proper + else if (xml_match_tag(buf, "")) { + char *p = buf + strlen(buf); + while(fgets(p, sizeof(buf)-(int)strlen(buf), state_file)) { + if (xml_match_tag(buf, "")) break; + p += strlen(p); + } + best_triplet->t.parse_xml(buf); + } + // ancillary data + else if (parse_double(buf, "", best_triplet->score)) continue; + else if (parse_double(buf, "", best_triplet->bperiod)) continue; + else if (parse_int(buf, "", best_triplet->tpotind0_0)) continue; + else if (parse_int(buf, "", best_triplet->tpotind0_1)) continue; + else if (parse_int(buf, "", best_triplet->tpotind1_0)) continue; + else if (parse_int(buf, "", best_triplet->tpotind1_1)) continue; + else if (parse_int(buf, "", best_triplet->tpotind2_0)) continue; + else if (parse_int(buf, "", best_triplet->tpotind2_1)) continue; + else if (parse_int(buf, "", best_triplet->freq_bin)) continue; + else if (parse_double(buf, "", best_triplet->time_bin)) continue; + else if (parse_double(buf, "", best_triplet->scale)) continue; + else if (xml_match_tag(buf, " pot_min( + xml_decode_field(buf,"bt_pot_min") + ); + int i; + for (i=0; ipot_min[i] = pot_min[i]; + } + } // end Min PoT + else if (xml_match_tag(buf, " pot_max( + xml_decode_field(buf,"bt_pot_max") + ); + int i; + for (i=0; ipot_max[i] = pot_max[i]; + } + } // end Max PoT + } // end while in best_triplet + } // end if in best_triplet + + } // end main parsing loop + + fclose(state_file); + + analysis_state.FLOP_counter=flops; + reload_graphics_state(); // so we can draw best_of signals + + // Adjust for restart - go 1 step beyond the checkpoint. + as.PoT_activity = PoT_activity; + if(PoT_freq_bin == -1) { + as.icfft = ncfft+1; + as.PoT_freq_bin = PoT_freq_bin; + } else { + as.icfft = ncfft; + as.PoT_freq_bin = PoT_freq_bin+1; + } + +// debug possible heap corruption -- jeffc +#ifdef _WIN32 +BOINCASSERT(_CrtCheckMemory()); +#endif + + return 0; +} + +// On entry, analysis_state.data points to malloced data +// and outfile is not open. +// On exit, these are freed and closed +int seti_do_work() { + int retval=0; + + retval = seti_analyze(analysis_state); + free_a(analysis_state.data); + analysis_state.data = 0; + + if( swi.data_type == DATA_ENCODED ) { + free_a(analysis_state.savedWUData); + analysis_state.savedWUData = 0; + } + + return retval; +} + +// on success, swi.data points to malloced data. +int seti_parse_data(FILE* f, ANALYSIS_STATE& state) { + unsigned long nbytes, nsamples,samples_per_byte; + sah_complex *data; + unsigned long i; + char *p, buf[256]; + sah_complex *bin_data=0; + int retval=0; + FORCE_FRAME_POINTER; + + nsamples = swi.nsamples; + samples_per_byte=(8/swi.bits_per_sample); + data = (sah_complex *)malloc_a(nsamples*sizeof(sah_complex), MEM_ALIGN); + bin_data = (sah_complex *)malloc_a(nsamples*sizeof(sah_complex), MEM_ALIGN); + if (!data) SETIERROR(MALLOC_FAILED, "!data"); + if (!bin_data) SETIERROR(MALLOC_FAILED, "!bin_data"); + + switch(swi.data_type) { + case DATA_ASCII: + for (i=0; i datav( + xml_decode_field(tmpbuf,"data") + ); + + memcpy(bin_data,&(datav[0]),datav.size()); + if (datav.size() < nbytes) throw BAD_DECODE; + } catch (int i) { + retval=i; + if (data) free_a(data); + if (bin_data) free_a(bin_data); + SETIERROR(i,"in seti_parse_data()"); + } + bits_to_floats((unsigned char *)bin_data, data, nsamples); + memcpy(bin_data,data,nsamples*sizeof(sah_complex)); + state.savedWUData = bin_data; + break; + } + state.npoints = nsamples; + state.data = data; + +#ifdef BOINC_APP_GRAPHICS + if (sah_graphics) { + strlcpy(sah_graphics->wu.receiver_name,swi.receiver_cfg.name,255); + sah_graphics->wu.s4_id = swi.receiver_cfg.s4_id; + sah_graphics->wu.time_recorded = swi.time_recorded; + sah_graphics->wu.subband_base = swi.subband_base; + sah_graphics->wu.start_ra = swi.start_ra; + sah_graphics->wu.start_dec = swi.start_dec; + sah_graphics->wu.subband_sample_rate = swi.subband_sample_rate; + sah_graphics->ready = true; + } +#endif + + return 0; +} + +int seti_parse_wu(FILE* f, ANALYSIS_STATE& state) { + int retval=0; + retval = seti_parse_wu_header(f); + if (retval) SETIERROR(retval,"from seti_parse_wu_header()"); + return seti_parse_data(f, state); +} + +void final_report() { + fprintf(stderr,"\nFlopcounter: %f\n\n", analysis_state.FLOP_counter); + fprintf(stderr,"Spike count: %d\n", spike_count); + fprintf(stderr,"Autocorr count: %d\n", autocorr_count); + fprintf(stderr,"Pulse count: %d\n", pulse_count); + fprintf(stderr,"Triplet count: %d\n", triplet_count); + fprintf(stderr,"Gaussian count: %d\n", gaussian_count); + fflush(stderr); +} diff --git a/client/seti.h b/client/seti.h new file mode 100644 index 0000000..d49717b --- /dev/null +++ b/client/seti.h @@ -0,0 +1,262 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +// $Id: seti.h,v 1.19.2.27 2007/08/10 00:38:49 korpela Exp $ +#ifndef _SETI_H +#define _SETI_H + +#ifdef _WIN32 +#include "boinc_win.h" +#endif +#include +#include "boinc_api.h" + +extern APP_INIT_DATA app_init_data; + +#include "analyze.h" +#ifndef AP_CLIENT +#include "seti_header.h" +#endif +#include "malloc_a.h" + +// Define 64 bit integer types. +#ifdef HAVE_INTTYPES_H +// Most gnu platforms +#include +typedef int64_t sh_sint8_t; +typedef uint64_t sh_uint8_t; + +#ifdef PRId64 +// If print formats are defined +#define SINT8_FMT "%"PRId64 +#define SINT8_FMT_CAST(x) (x) +#define UINT8_FMT "%"PRIu64 +#define UINT8_FMT_CAST(x) (x) +#else +// play it safe. It'll work through 49 bits at least. +#define SINT8_FMT "%20.0f" +#define SINT8_FMT_CAST(x) static_cast(x) +#define UINT8_FMT "%20.0f" +#define UINT8_FMT_CAST(x) static_cast(x) +#endif + +#elif SIZEOF_LONG_INT >= 8 +// other L64 +typedef long sh_sint8_t; +typedef unsigned long sh_uint8_t; +#define SINT8_FMT "%ld" +#define SINT8_FMT_CAST(x) (x) +#define UINT8_FMT "%lu" +#define UINT8_FMT_CAST(x) (x) + +#elif defined(LLONG_MAX) || defined(HAVE_LONG_LONG) +// systems with long long, but no inttypes.h +typedef long long sh_sint8_t; +typedef unsigned long long sh_uint8_t; +// again play it safe +#define SINT8_FMT "%20.0f" +#define SINT8_FMT_CAST(x) static_cast(x) +#define UINT8_FMT "%20.0f" +#define UINT8_FMT_CAST(x) static_cast(x) + +#elif defined(HAVE__INT64) || \ + (defined(_INTEGRAL_MAX_BITS) && (_INTEGRAL_MAX_BITS >= 64)) +// Probably, but not necessarily MSC. +typedef _int64 sh_sint8_t; +typedef unsigned _int64 sh_uint8_t; +#ifdef _MSC_VER +// leave it to microsoft to be different. +#define SINT8_FMT "%I64d" +#define SINT8_FMT_CAST(x) (x) +#define UINT8_FMT "%I64u" +#define UINT8_FMT_CAST(x) (x) +#else +#define SINT8_FMT "%20.0f" +#define SINT8_FMT_CAST(x) static_cast(x) +#define UINT8_FMT "%20.0f" +#define UINT8_FMT_CAST(x) static_cast(x) +#endif + +#elif defined(HAVE_LONG_DOUBLE) +typedef long double sh_sint8_t; +typedef long double sh_uint8_t; +#define SINT8_FMT "%20.0lf" +#define SINT8_FMT_CAST(x) (x) +#define UINT8_FMT "%20.0lf" +#define UINT8_FMT_CAST(x) (x) + +#else +typedef double sh_sint8_t; +typedef double sh_uint8_t; +#define SINT8_FMT "%20.0f" +#define SINT8_FMT_CAST(x) static_cast(x) +#define UINT8_FMT "%20.0f" +#define UINT8_FMT_CAST(x) static_cast(x) + +#endif // HAVE_INTTYPES_H + +// make a consistent int32_t +#ifndef HAVE_INT32_T +#ifdef HAVE__INT32 +typedef _int32 int32_t; +#else +typedef long int32_t; +#endif +#endif + + +#ifdef HAVE_MALLOC_H +#include +#endif +#ifdef HAVE_MEMORY_H +#include +#endif +#ifdef HAVE_ALLOCA_H +#include +#endif + +// Adjustement to flops counter to make FLOPS include floating point loads and +// stores. +extern double LOAD_STORE_ADJUSTMENT; +extern double SETUP_FLOPS; + + +typedef float sah_complex[2]; + +struct ANALYSIS_STATE { + sah_complex *data; + sah_complex *savedWUData; // Save the original WU data + int npoints; + int icfft; + int PoT_freq_bin; // where we are in PoT analysis for this icfft + // ... will be -1 if no PoT analysis in progress + int PoT_activity; + int doing_pulse; + double FLOP_counter; +}; + +extern bool notranspose_flag; +extern bool default_functions_flag; +extern bool verbose; +extern int seti_init_state(); +extern int seti_do_work(); +extern int result_group_start(); +extern int result_group_write_header(); +extern int result_group_end(); +extern int checkpoint(BOOLEAN force_checkpoint=0); +extern int seti_parse_wu(FILE*, ANALYSIS_STATE&); +extern int parse_state_file(ANALYSIS_STATE& as); +extern void final_report(); + +extern ANALYSIS_STATE analysis_state; +#ifndef AP_CLIENT +extern SETI_WU_INFO swi; +#endif + +#ifdef BOINC_APP_GRAPHICS +#include "reduce.h" +#include "graphics2.h" +#endif + +#ifndef AP_CLIENT +struct SPIKE_INFO : public track_mem { +public : + SPIKE_INFO(); + ~SPIKE_INFO(); + SPIKE_INFO(const SPIKE_INFO &si); + SPIKE_INFO &operator =(const SPIKE_INFO &si); + spike s; + double score; // calc in ReportEvents() + int bin; // assigned in ReportEvents() + int fft_ind; // assigned in ReportEvents() +}; + +struct AUTOCORR_INFO : public track_mem { +public : + AUTOCORR_INFO(); + ~AUTOCORR_INFO(); + AUTOCORR_INFO(const AUTOCORR_INFO &si); + AUTOCORR_INFO &operator =(const AUTOCORR_INFO &si); + autocorr a; + double score; // calc in ReportEvents() + int bin; // assigned in ReportEvents() + int fft_ind; // assigned in ReportEvents() +}; + +struct GAUSS_INFO : public track_mem { +public : + GAUSS_INFO(); + ~GAUSS_INFO(); + GAUSS_INFO(const GAUSS_INFO &gi); + GAUSS_INFO &operator =(const GAUSS_INFO &gi); + gaussian g; + double score; // calc in ReportGaussEvent() + double display_power_thresh; // calc in gaussfit() + int bin; // assigned in ReportGaussEvent() + int fft_ind; // assigned in ReportGaussEvent() + //float * pot; +}; + +struct PULSE_INFO : public track_mem { +public : + PULSE_INFO(); + ~PULSE_INFO(); + PULSE_INFO(const PULSE_INFO &pi); + PULSE_INFO &operator =(const PULSE_INFO &pi); + pulse p; + double score; // calc in ReportPulseEvent() + int freq_bin; // assigned in ReportPulseEvent() + int time_bin; // assigned in ReportPulseEvent() + unsigned int * pot_min; // Scaled 0-255 for display + unsigned int * pot_max; // Scaled 0-255 for display +}; + +struct TRIPLET_INFO : public track_mem { +public : + TRIPLET_INFO(); + ~TRIPLET_INFO(); + TRIPLET_INFO(const TRIPLET_INFO &ti); + TRIPLET_INFO &operator =(const TRIPLET_INFO &ti); + triplet t; + double score; // assigned in ReportTripletEvent() + double bperiod; // probably deprecated - remove sometime + int freq_bin; // assigned in ReportTripletEvent() + // ticks below assigned in ReportTripletEvent() + int tpotind0_0; // index into pot_min/pot_max arrays + int tpotind0_1; // of start/end of first element of triplet + int tpotind1_0; // second element + int tpotind1_1; + int tpotind2_0; // and third element + int tpotind2_1; + double time_bin; // calc in ReportTripletEvent() + double scale; // Scale from PoT bins to TRIPLET_POT_LEN + unsigned int * pot_min; // Scaled 0-255 for display + unsigned int * pot_max; // Scaled 0-255 for display +}; +#endif + +#endif diff --git a/client/seti_header.cpp b/client/seti_header.cpp new file mode 100644 index 0000000..ccfeed2 --- /dev/null +++ b/client/seti_header.cpp @@ -0,0 +1,299 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +/* + * + * $Id: seti_header.cpp,v 1.22.2.6 2007/05/31 22:03:11 korpela Exp $ + * + */ + +#include "sah_config.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "diagnostics.h" +#include "util.h" +#include "s_util.h" + +#ifdef HAVE_IEEEFP_H +#include +#endif + +#include "seti.h" +#include "analyze.h" +#include "timecvt.h" +#include "parse.h" +#include "../db/db_table.h" +#include "../db/schema_master.h" +#include "seti_header.h" +#include "analyzePoT.h" +#include "analyzeReport.h" +#include "chirpfft.h" + +// Write a SETI work unit header to a file + +char *receivers[]={"invalid","synthetic","ao1420"}; +char *datatypes[]={"invalid","ascii","encoded","sun_binary"}; + +SETI_WU_INFO::SETI_WU_INFO(const workunit &w) : + track_mem("SETI_WU_INFO"), + data_class(0), + start_ra(w.group_info->data_desc.start_ra), + start_dec(w.group_info->data_desc.start_dec), + end_ra(w.group_info->data_desc.end_ra), + end_dec(w.group_info->data_desc.end_dec), + true_angle_range(w.group_info->data_desc.true_angle_range), + time_recorded(w.group_info->data_desc.time_recorded_jd), + subband_center(w.subband_desc.center), + subband_base(w.subband_desc.base), + subband_sample_rate(w.subband_desc.sample_rate), + fft_len(w.group_info->splitter_cfg->fft_len), + ifft_len(w.group_info->splitter_cfg->ifft_len), + subband_number(w.subband_desc.number), + receiver_cfg(w.group_info->receiver_cfg), + nsamples(w.group_info->data_desc.nsamples), + bits_per_sample(w.group_info->recorder_cfg->bits_per_sample), + position_history(w.group_info->data_desc.coords.begin()), + num_positions(w.group_info->data_desc.coords.size()), + analysis_cfg(w.group_info->analysis_cfg), + beam_width(w.group_info->receiver_cfg->beam_width), +wu(&w) { + if (!strcmp(w.group_info->splitter_cfg->data_type,"ascii")) data_type = DATA_ASCII; + else if (!strcmp(w.group_info->splitter_cfg->data_type,"encoded")) data_type = DATA_ENCODED; + else if (!strcmp(w.group_info->splitter_cfg->data_type,"sun_binary")) data_type = DATA_SUN_BINARY; + splitter_version=(int)floor(w.group_info->splitter_cfg->version)*0x100; + splitter_version+=(int)((w.group_info->splitter_cfg->version)*0x100) && 0xff; + angle_range=true_angle_range; + sprintf(tape_version,"%8.2f",w.group_info->recorder_cfg->version); +} + +SETI_WU_INFO::SETI_WU_INFO() : + track_mem("SETI_WU_INFO"), + data_class(0), + start_ra(0), + start_dec(0), + end_ra(0), + end_dec(0), + true_angle_range(0), + time_recorded(0), + subband_center(0), + subband_base(0), + subband_sample_rate(0), + fft_len(0), + ifft_len(0), + subband_number(0), + nsamples(0), + bits_per_sample(0), + position_history(), + num_positions(0), + beam_width(0) +{ + data_type = DATA_ASCII; + splitter_version=0; + angle_range=0; + tape_version[0]=0; +} +SETI_WU_INFO::SETI_WU_INFO(const SETI_WU_INFO &s) : + track_mem("SETI_WU_INFO"), + data_type(s.data_type), + data_class(s.data_class), + splitter_version(s.splitter_version), + start_ra(s.start_ra), + start_dec(s.start_dec), + end_ra(s.end_ra), + end_dec(s.end_dec), + angle_range(s.true_angle_range), + true_angle_range(s.true_angle_range), + time_recorded(s.time_recorded), + subband_center(s.subband_center), + subband_base(s.subband_base), + subband_sample_rate(s.subband_sample_rate), + fft_len(s.fft_len), + ifft_len(s.ifft_len), + subband_number(s.subband_number), + receiver_cfg(s.receiver_cfg), + nsamples(s.nsamples), + bits_per_sample(s.bits_per_sample), + position_history(s.position_history), + num_positions(s.num_positions), + analysis_cfg(s.analysis_cfg), + beam_width(s.beam_width), +wu(s.wu) { + strcpy(tape_version,s.tape_version); +} + +int seti_write_wu_header(FILE *file, int output_xml) { + + fprintf(file,"%s",swi.wu->print_xml().c_str()); + return 0; +} + +int seti_write_wu_header(FILE *file, int output_xml, SETI_WU_INFO &swi) { + + fprintf(file,"%s",swi.wu->print_xml().c_str()); + return 0; +} + +SETI_WU_INFO swi; + +static workunit *wu; + +int seti_parse_wu_header(FILE* f) { + char buf[256]; + int found=0; + + std::string buffer(""); + buffer.reserve(10*1024); + + swi.data_type=0; + + // Allow old style headers to be parsed correctly. + // jeffc - need this? + //swi.fft_len=2048; + //swi.ifft_len=8; + + do { + fgets(buf, 256, f); + } while (!feof(f) && !xml_match_tag(buf,"= 0) { + return (int)(nbins*freq/sample_rate); + } else { + return (int)(nbins/2-(freq/sample_rate)); + } +} + +float cnvt_fftind_time(int fft_ind, int fft_len) { + return (float)(fft_ind*(fft_len/swi.subband_sample_rate)); +} + +float cnvt_gauss_offset_time(int offset) { + float dur = (float)(swi.nsamples/swi.subband_sample_rate); + return (float)(offset*dur/swi.analysis_cfg.gauss_pot_length); +} + +// need to properly handle frequency rollover when calculating detection +// frequency +double calc_detection_freq(double freq, double chirp_rate, double t_offset) { + double fft_ratio=1.0/swi.wu->group_info->splitter_cfg->ifft_len; + double lowerlim=swi.subband_base-0.5*swi.subband_sample_rate*fft_ratio; + double upperlim=lowerlim+swi.subband_sample_rate; + double detection_freq=freq+chirp_rate*t_offset; + while (detection_freq < lowerlim) detection_freq+=swi.subband_sample_rate; + while (detection_freq > upperlim) detection_freq-=swi.subband_sample_rate; + return detection_freq; +} diff --git a/client/seti_header.h b/client/seti_header.h new file mode 100644 index 0000000..6b82c05 --- /dev/null +++ b/client/seti_header.h @@ -0,0 +1,132 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +/* + * + * $Id: seti_header.h,v 1.7.2.5 2007/05/31 22:03:11 korpela Exp $ + * + */ + +#ifndef SETI_HEADER_H +#define SETI_HEADER_H + +#ifndef _WIN32 +#include +#include +#endif + +#include "timecvt.h" +#include "db/db_table.h" +#include "db/schema_master.h" +#undef USE_MYSQL + +#define SRC_SYNTHETIC 1 +#define SRC_ARECIBO_1420 2 +#define NUM_SRCS 3 + +#define DATA_ASCII 1 +#define DATA_ENCODED 2 +#define DATA_SUN_BINARY 3 + +#define MAX_SCOPE_STRINGS 32 +#define MAX_NUM_FFTS 64 +#define MAX_CFFT_PARAMS 2 + +// Variables of type ChirpFftTable_t (usually an array of such +// variables) indicate a range of chirp rates and the FFT +// lenghts (spectral resolutions) that we wish to process within +// said chirp range. +typedef struct { + double MaxChirpRate; + // Upper bound for this range. + // Lower bound is MaxChirpRate of the previous + // ChirpFftTable_t element. Lower bound + // of first ChirpFftTable_t element is assumed to be zero. + unsigned char DoFft[MAX_NUM_FFTS]; // Boolean - do this FFT length while in + // this chirp range +} +ChirpFftTable_t; + + +struct SCOPE_STRING : public track_mem { + TIME st; + double alt, az; + double ra, dec; + SCOPE_STRING() : track_mem("SCOPE_STRING") {} +}; + +struct SETI_WU_INFO : public track_mem { + int data_type; + int data_class; + int splitter_version; + double start_ra; // 0 .. 24 + double start_dec; // -90 .. 90 + double end_ra; + double end_dec; + double angle_range; // in degrees (only for 0.1 degree beam) + double true_angle_range; // in degrees + double time_recorded; // in Julian form + double subband_center; // Hz This parameter is deprecated in favor of + // subband_base + double subband_base; // center freq of bin 0. + double subband_sample_rate; + int fft_len; + int ifft_len; + int subband_number; + receiver_config receiver_cfg; + unsigned long nsamples; + unsigned int bits_per_sample; + std::vector::const_iterator position_history; + size_t num_positions; // number_of_positions in history array + char tape_version[16]; + analysis_config analysis_cfg; + int num_fft_lengths; + int analysis_fft_lengths[32]; + double beam_width; + ChirpFftTable_t chirp_fft_table[MAX_CFFT_PARAMS]; + const workunit *wu; + SETI_WU_INFO(); + SETI_WU_INFO(const workunit &w); + SETI_WU_INFO(const SETI_WU_INFO &s); +}; + +extern int seti_write_wu_header(FILE*, int); +extern int seti_write_wu_header(FILE*, int, SETI_WU_INFO swi); +extern int seti_parse_wu_header(FILE*); +extern int seti_parse_wu_header(FILE*, SETI_WU_INFO &swi); + +extern float cnvt_fftlen_hz(int); +extern double cnvt_bin_hz(int, int); +extern double cnvt_bin_hz_offset(int, int); +extern float cnvt_fftind_time(int, int); +extern float cnvt_gauss_offset_time(int offset); +extern int cnvt_hz_bin(float freq, float sample_rate, int nbins); +extern double calc_detection_freq(double freq, double chirp_rate, double + t_offset); + +#endif + diff --git a/client/sincos.h b/client/sincos.h new file mode 100644 index 0000000..161f840 --- /dev/null +++ b/client/sincos.h @@ -0,0 +1,102 @@ +// Copyright 2005 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +// seti.C +// $Id: sincos.h,v 1.2.2.2 2005/06/26 19:55:47 korpela Exp $ +// + + +/* Implement the sincos[f] function on machines that don't have it */ +#ifndef _SINCOS_H_ +#define _SINCOS_H_ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* These are outside of the #ifndefs because on some machines sinf and cosf */ +/* are in libstdc++, but are not defined in the system header . */ +void sincos(double angle, double *s, double *c); +void sincosf(float angle, float *s, float *c); +float sinf(float angle); +float cosf(float angle); +float atanf(float angle); + +#ifndef HAVE_SINCOSF +inline void sincosf(float angle, float *s, float *c) { +/* do we have sincos? If so use it since it's likely to */ +/* be faster than separate computation */ +#ifdef HAVE_SINCOS + float sd,cd; + sincos(angle,&sd,&cd); + *s=(float)sd; + *c=(float)cd; +/* if we don't have sincos, how about sinf and cosf? */ +#elif defined(HAVE_SINF) && defined(HAVE_COSF) + *s=sinf(angle); + *c=cosf(angle); +/* as a last resort, compute the old fashioned way */ +#else + *s=(float)sin(angle); + *c=(float)cos(angle); +#endif +} +#endif + +#ifndef HAVE_SINCOS +inline void sincos(double angle, double *s, double *c) { +/* this is the obvious implementation. Is there a */ +/* better trickier way? */ + *s=sin(angle); + *c=cos(angle); +} +#endif + +#ifndef HAVE_SINF +inline float sinf(float angle) { + return (float)sin(angle); +} +#endif + +#ifndef HAVE_COSF +inline float cosf(float angle) { + return (float)cos(angle); +} +#endif + +#ifndef HAVE_ATANF +inline float atanf(float angle) { + return (float)atan(angle); +} +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/client/spike.cpp b/client/spike.cpp new file mode 100644 index 0000000..4555a66 --- /dev/null +++ b/client/spike.cpp @@ -0,0 +1,163 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + + +#include "sah_config.h" + +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOINC_APP_GRAPHICS +#include "graphics2.h" +#endif + +#include "util.h" +#include "s_util.h" +#include "analyze.h" +#include "gaussfit.h" +#include "seti.h" +#include "chirpfft.h" +#include "analyzeReport.h" +#include "analyzePoT.h" +#ifdef BOINC_APP_GRAPHICS +#include "sah_gfx_main.h" +#endif + +#include "../db/schema_master.h" + +#define UNSTDMAX(a,b) (((a) > (b)) ? (a) : (b)) +#define UNSTDMIN(a,b) (((a) < (b)) ? (a) : (b)) + +unsigned int pow2(unsigned int num) +{ + unsigned int n = num > 0 ? num - 1 : 0; + n |= n >> 1; + n |= n >> 2; + n |= n >> 4; + n |= n >> 8; + n |= n >> 16; + n++; + + return n >> 1; +} + +int FindSpikes( + float * fp_PowerSpectrum, + int ul_NumDataPoints, + int fft_num, + SETI_WU_INFO& swi +) { + //int i, j, k, m, bin, retval; + int i, j, k, m, retval, blksize; + float temp, partial; + //float total, MeanPower, spike_score; + float total, MeanPower; + SPIKE_INFO si; + + i = j = k = m = 0; + total = 0.0f; + blksize = UNSTDMAX(8, UNSTDMIN(pow2((unsigned int) sqrt((float) (ul_NumDataPoints / 32)) * 32), 512)); + + for(int b = 0; b < ul_NumDataPoints/blksize; b++) { + partial = 0.0f; + for(i = 0; i < blksize; i++) { + partial += fp_PowerSpectrum[b*blksize+i]; + } + total += partial; + } + MeanPower = total / ul_NumDataPoints; + + // Here we extract the spikes_to_report highest power events, + // outputing them as we go. + // Index usage: + // i : walk power spectrum us_NumToReport times + // j : walks power spectrum for each i + // k : marks current high power candidate while j walks on + // m : marks the current tail of the high power hit "list" + + + for (i = 0; i < swi.analysis_cfg.spikes_per_spectrum; i++) { + + temp = 0.0; + + // Walk the array, looking for the first/next highest power. + // Start j at 1, in order to skip the DC (ie 0) bin. + // NOTE: this is a simple scan for high powers. Nice and fast + // for a very low i. If i is substantial, this code should be + // replaced with an index (q)sort. Do *not* sort the power + // spectrum itself in place - it's used elsewhere. + for (j = 1; j < ul_NumDataPoints; j++) { + + if (fp_PowerSpectrum[j] > temp) { + if (fp_PowerSpectrum[j] < fp_PowerSpectrum[m] || m == 0) { + temp = fp_PowerSpectrum[j]; + k = j; + } + } + } // temp now = first/next highest power and k = it's bin number + + m = k; // save the "lowest" highest. + + // spike info + si.s.peak_power = temp/MeanPower; + si.s.mean_power = 1.0; + si.bin = k; + si.fft_ind = fft_num; + si.s.chirp_rate = ChirpFftPairs[analysis_state.icfft].ChirpRate; + si.s.fft_len = ChirpFftPairs[analysis_state.icfft].FftLen; + si.s.freq = cnvt_bin_hz(si.bin, si.s.fft_len); + double t_offset=((double)si.fft_ind+0.5)*(double)si.s.fft_len/ + swi.subband_sample_rate; + si.s.detection_freq=calc_detection_freq(si.s.freq,si.s.chirp_rate,t_offset); + si.s.time = swi.time_recorded + t_offset / 86400.0; + time_to_ra_dec(si.s.time, &si.s.ra, &si.s.decl); + + // Score used for "best of" and graphics. + si.score = si.s.peak_power / SPIKE_SCORE_HIGH; + si.score = si.score > 0.0 ? log10(si.score) : -12.0; + // if best_spike.s.fft_len == 0, there is not yet a first spike + if (si.score > best_spike->score || best_spike->s.fft_len == 0) { + *best_spike = si; +#ifdef BOINC_APP_GRAPHICS + if (!nographics()) sah_graphics->si.copy(&si); +#endif + } + + // Report a signal if it excceeds threshold. + if (si.s.peak_power > (swi.analysis_cfg.spike_thresh)) { + retval = result_spike(si); + if (retval) SETIERROR(retval,"from result_spike()"); + } + } + return 0; +} + diff --git a/client/spike.h b/client/spike.h new file mode 100644 index 0000000..a4bc31e --- /dev/null +++ b/client/spike.h @@ -0,0 +1,34 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +int FindSpikes( + float * fp_PowerSpectrum, + int ul_NumDataPoints, + int fft_num, + SETI_WU_INFO& swi +); + diff --git a/client/test_workunits/reference_result_unit.sah b/client/test_workunits/reference_result_unit.sah new file mode 100644 index 0000000..14cf58c --- /dev/null +++ b/client/test_workunits/reference_result_unit.sah @@ -0,0 +1,569 @@ + + + reference.wu + + + + 0 + 0 + 0 + 0 + 0 + 0 + + reference_group + + 14.853 + 28.55 + 14.911 + 28.58 + 0.775 + Fri Mar 3 08:36:01 2000 + 2451606.85836 + 1048576 + + + + 14.853 + 28.55 + + + + 14.856 + 28.56 + + + + 14.858 + 28.56 + + + + 14.861 + 28.56 + + + + 14.864 + 28.56 + + + + 14.867 + 28.56 + + + + 14.869 + 28.56 + + + + 14.872 + 28.56 + + + + 14.875 + 28.56 + + + + 14.878 + 28.57 + + + + 14.881 + 28.57 + + + + 14.883 + 28.57 + + + + 14.886 + 28.57 + + + + 14.889 + 28.57 + + + + 14.892 + 28.57 + + + + 14.895 + 28.57 + + + + 14.897 + 28.57 + + + + 14.9 + 28.57 + + + + 14.903 + 28.58 + + + + 14.906 + 28.58 + + + + 14.909 + 28.58 + + + + 14.911 + 28.58 + + + + + 1 + ao_1420 + 0.1 + 1420 + 18.3538056 + -66.7552222 + 497 + 168 + 0 + + 7.4,5.4,-49.1,-1091,0,0,0,0,0,0,0,0,0 + + + -5146.7,66.1,14.3,317.7,0,0,0,0,0,0,0,0,0 + + 0 + 0 + 0 + + + sah_recorder + 2 + 2500000 + 0 + 1.4 + + + 0.17 + encoded + 2048 + 8 + fft + welsh + 0 + 0 + + + + 22 + 1 + 17.8 + 1 + 131072 + 2.1 + 1.42 + 3 + 3.2 + 64 + 20 + 0.5 + 40960 + 16 + 8192 + 256 + 8.5 + 131072 + 16 + 256 + 0.5 + 1 + 0.0021 + 0.0105 + 0.333 + 262136 + 8192 + 32768 + + + 20 + 262136 + + + 50 + 65528 + + + 1 + 30 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + 0 + + + 145 +
1418920288.09
+ 1418916015.62 + 9765.62 +
+0 +
+ + 22.395510432656 + 1 + + 14.909502836654 + 28.58 + 0 + 1418919354.6705 + 1418919461.2933 + 0 + 131072 + 1.0592016409052 + 0 + 0 + 0 + + + 22.535019975152 + 1 + + 14.909502836654 + 28.58 + 0 + 1418919354.298 + 1418919461.2929 + 0 + 131072 + 1.0628986797914 + 0 + 0 + 0 + + + 22.378679333036 + 1 + + 14.871418063004 + 28.56 + 0 + 1418917122.4032 + 1418917201.1763 + 0 + 131072 + 2.3476196927567 + 0 + 0 + 0 + + + 22.363961606874 + 1 + + 14.906409847822 + 28.58 + 0 + 1418923767.2001 + 1418924030.2402 + 0 + 32768 + 2.7505969313559 + 0 + 0 + 0 + + + 22.462164003785 + 1 + + 14.906409847822 + 28.58 + 0 + 1418923761.5376 + 1418924030.2345 + 0 + 32768 + 2.8097495535356 + 0 + 0 + 0 + + + 22.140779824541 + 1 + + 14.90148701969 + 28.574956732299 + 0 + 1418918761.3811 + 1418918419.0097 + 0 + 131072 + -3.9244067777343 + 0 + 0 + 0 + + + 22.104054408051 + 1 + + 14.864150850996 + 28.56 + 0 + 1418916487.2415 + 1418916408.0466 + 0 + 131072 + -3.9336493749498 + 0 + 0 + 0 + + + 23.334689073671 + 1 + + 14.864150850996 + 28.56 + 0 + 1418916487.316 + 1418916408.0467 + 0 + 131072 + -3.9373464138361 + 0 + 0 + 0 + + + 23.518514513185 + 1 + + 14.864150850996 + 28.56 + 0 + 1418916487.3905 + 1418916408.0468 + 0 + 131072 + -3.9410434527223 + 0 + 0 + 0 + + + 22.629047158205 + 1 + + 14.864150850996 + 28.56 + 0 + 1418916487.465 + 1418916408.0469 + 0 + 131072 + -3.9447404916085 + 0 + 0 + 0 + + + 22.818791922437 + 1 + + 14.856922413057 + 28.56 + 0 + 1418918910.9886 + 1418918946.4799 + 0 + 131072 + 5.2886141267535 + 0 + 0 + 0 + + + 23.786560547547 + 1 + + 14.856922413057 + 28.56 + 0 + 1418918910.9886 + 1418918946.4924 + 0 + 131072 + 5.2904626461966 + 0 + 0 + 0 + + + 17.814894407511 + 1 + + 14.856922413057 + 28.56 + 0 + 2.6451981543415 + 1418920288.09 + 1418920199.1446 + 0 + 131072 + -13.253884407138 + 0 + 0 + 0 + + + 22.051880230381 + 1 + + 14.879185317697 + 28.57 + 0 + 1418924855.9529 + 1418924025.883 + 0 + 131072 + -17.669997356741 + 0 + 0 + 0 + + + 6.2925362586975 + 0.032650269567966 + + 14.907301879412 + 28.58 + 0 + 1418921813.9569 + 1418918837.2224 + 0 + 512 + -30.714999066808 + 0 + 0 + 0 + 2.3592972079602 + 14.070539474487 + 13.400220870972 + 0 + 45 + + 35,15,31,33,30,255,28,53,31,31,17,17,37,23,21,17,33,39,17,12,21,9,14,27, + 14,13,29,23,0,24,54,32,22,28,16,29,5,24,48,30,37,38,28,24,51 + + + + + 23.786560547547 + 1 + + 14.856922413057 + 28.56 + 0 + 1418918910.9886 + 1418918946.4924 + 0 + 131072 + 5.2904626461966 + 0 + 0 + 0 + + + 17.814894407511 + 1 + + 14.856922413057 + 28.56 + 0 + 2.6451981543415 + 1418920288.09 + 1418920199.1446 + 0 + 131072 + -13.253884407138 + 0 + 0 + 0 + + + 3.1875545978546 + 0.5623345375061 + + 14.884025293173 + 28.57 + 0 + 1418915821.905 + 1418918023.619 + 0 + 16384 + 39.173824038504 + 0 + 0 + 0 + 4.1290321350098 + 1.3583995103836 + 2.0981106758118 + 0 + 9.5102910995483 + + 7,9,13,28,18,7,3,7,1,0,28,33,5,1,8,15,13,12,2,14,13,2,6,57,14,9,0,22,0, + 59,2,63,255,200,71,60,24,83,75,2,52,31,0,6,11,27,7,0,1,21,3,62,1,41,52, + 2,19,3,17,8,24,41,28,18 + + + + 6.2925362586975 + 0.032650269567966 + + 14.907301879412 + 28.58 + 0 + 1418921813.9569 + 1418918837.2224 + 0 + 512 + -30.714999066808 + 0 + 0 + 0 + 2.3592972079602 + 14.070539474487 + 13.400220870972 + 0 + 45 + + 35,15,31,33,30,255,28,53,31,31,17,17,37,23,21,17,33,39,17,12,21,9,14,27, + 14,13,29,23,0,24,54,32,22,28,16,29,5,24,48,30,37,38,28,24,51 + + +
\ No newline at end of file diff --git a/client/test_workunits/reference_work_unit.sah b/client/test_workunits/reference_work_unit.sah new file mode 100644 index 0000000..04dbc04 --- /dev/null +++ b/client/test_workunits/reference_work_unit.sah @@ -0,0 +1,5669 @@ + + +reference.wu + + reference_group + + 14.853 + 28.55 + 14.911 + 28.58 + 0.775 + Fri Mar 3 08:36:01 2000 + 2451606.85836 + 1048576 + + + + 14.853 + 28.55 + + + + 14.856 + 28.56 + + + + 14.858 + 28.56 + + + + 14.861 + 28.56 + + + + 14.864 + 28.56 + + + + 14.867 + 28.56 + + + + 14.869 + 28.56 + + + + 14.872 + 28.56 + + + + 14.875 + 28.56 + + + + 14.878 + 28.57 + + + + 14.881 + 28.57 + + + + 14.883 + 28.57 + + + + 14.886 + 28.57 + + + + 14.889 + 28.57 + + + + 14.892 + 28.57 + + + + 14.895 + 28.57 + + + + 14.897 + 28.57 + + + + 14.900 + 28.57 + + + + 14.903 + 28.58 + + + + 14.906 + 28.58 + + + + 14.909 + 28.58 + + + + 14.911 + 28.58 + + + + + 1 + ao_1420 + 0.10000 + 1420.0 + 18.3538056 + -66.7552222 + 497.0 + 168.0 + 0.0 + 7.4,5.4,-49.1,-1091.0,0,0,0,0,0,0,0,0,0 + -5146.7,66.1,14.3,317.7,0,0,0,0,0,0,0,0,0 + + + sah_recorder + 2 + 2500000.0 + 1.40 + + + 0.17 + encoded + 2048 + 8 + fft + welsh + + + 22.0 + 1 + 17.8 + 1 + 131072 + 2.100 + 1.420 + 3.0 + 3.2 + 64 + 20.0 + 0.5 + 40960 + 16 + 8192 + 256 + 8.50 + 16 + 131072 + 256 + 0.5 + 1 + 0.0021 # should be beams/s rather and degrees + 0.0105 # should be beams/s rather and degrees + 0.333 + 262136 + 8192 # should be seconds + 32768 # should be seconds + + + 20.0 + 262136 + + + 50.0 + 65528 + + + 1 + 30 + + + + 145 +
1418920288.09
+ 1418916015.62 + 9765.62 +
+
+ +DJJ32/(CG&\%:PSY]&BY\ M(NN46 \L1'^V?YQ?S)/+4V8/)L[NQG\H>.IMFIFG@ +DQW;$9F? +:G:AC]7XAJE7G@3@^(JW?.?M0;+:HMOK,%S2_%:Q--OS\_/?]\?M$.(SOHOKV'->&+>T7(\A7P+;T1XH,C,0N1/3C8!2S??RWO&0" +[$V#>#S;+=S^@=>0HP>][^>=@NT!5 +.:=81'1 W7$[@U[4ZT#CK[U!L^ AZ,T==Z=@_NJ)50&30R+[55M=5-!^A1RQ<> OP9(V/X@;@,48K="-3?T +I66C\7@UR)S\,2>P:5V58KQ2$QK;<9F1O_?E4/8[BR]N_'(10 !%T"-#2 +$ 4Y:C8]%O)K4-,+$^\7+IJZ2(-G#S#B8=,[@3C7.7"$\/LU+;8\SYTB-!YW)$YT-9-&V'*,)B=TI6K@(YL?M6UFNEC>^5&@Q:@T5XQDJ3 +4G\O*67*ZGW?$QJXH9U&QOJD_I:A$R1=F@ZA^H8/OY6HHX%/5#?!7E#R/&#W510^ +-5;\L=\/01\)F30M0F;A#(U.R1S,MM"3HM=P97Q^GT,=LKD +K*JR1%6FH-GO497)#.2!LB1_=L!E >CK]!L=?(8X%&U\*P1T-B.'CYEY6K:*Z345 +:YV48]"VS$X;])B$5WDN,:*_82$YO[@E%D6I5!/VK+GDF_[(N@O>84=@598GL,V*@/!^=G8MB-.707<%76\] ,'VZHXM&,%M)35CYA(CAO2Y<7\LS-B4-PH;"^:1 +(=M+P0RE85H0BVE%FAH\MP=BS^"]0_;;R)>12N)@+ X#$OJ*DLZO,\L@6Z-< "O1 +P/?0W4OXV;L)@!"2$@8*@2GSE! EU &O=YZG'\2HZ7#*;XB(]M;A?-K=BQ0:4[SAR[:.6QZ;S; +&V( D#$N(+D+Q0#TN(D3W'+!@RK7/*"):@&[G75']ZG@)M&?/4"-)'^P$&H#.Q1P + !DEW/0ͽ/N&G*W!F,%,)D6V<:EDH3#K5]5UY+O*+<^VXVZWT<:R2)RH&;-"ZJK02, +=43%K[GE(?)G9\D] S\TJO^JOC@1W=70=(%]+<\P4?9Y=SU7L^_*&*\6#B1E?#S5 +M3)5?\8@=@B0DGY#-C.F8FT_4M&+A6'T +%@(PC\RT,Q=J:U0\H/#^,LA0[R;I.\-B0*ODA)#TE5>.QT_0)(P$<' "0H"B4.GU +T?(+"QFKG1QP&542$8^;F 8& LC+%_/_5X_!A(]@_"@-KJ"U^@].)*XRIJ"R+3JJ +!$4[0G?=2BPFQ-DCEI5I:23(<]1,55Y?K@^:%?#HINA:*7"Y$'M1!/GI;Z]5. +F_P%Z4(\ P8?!!(;^4)0>?=C&PABED14!F2^%ZO@R#N8G%RDRK^(9NS93M;+ZF^' +DO(]1#J,BW8"R][_W7D5!E3(XV(J]H_)"QU>*#@#5FTA(I1AMA"K:P9F1^(K +"%)W(HY(O986]3"3;@L)AF <%>!4A#Q'Z/I_[Q:X]HV(:Q7&N6$V[QZ*=Z7 [^@J +$=.<191ZI2$DZ07D@! PQ+01*=*2Q,1/"]6^#9CYCDRM#9OO2JALORL#Z\" +GR@S&/!Y@!9'Q H8R!, S8A0AUS'[?P.RHFQ<;5.73./(]F.K=7IXRH+*/O@#7Z^ +2J!L4!KV4L,EW?.][#9TLK(Y\[*@Z+U6*4/ +JVG7Y-*,)*YA88?D_CH:R::G':Y%,9=0E# 8]O M2PZ8 +3'TSP^I_";\/ZTS<.7PDF$Z!]&W4YFX9K(\AUL=N@=PT=Z$I,!:*#CZYHMD@:* NYT<:YBW#&^E[2(67/@A=5H/BT8*I:CH@OD^?.%R;' YPG!C:]J1(]8VZGZU_D[SG0$LVK%4 +R]D.CDW5 UV:UW"%3CPE A(T'F9E[P"9>RE#P$8[IC5*NA'!<,WEZ3P>+*\89>J+ +N?M8$#)G@;_K0;4,P'L5 RNNH4_\#9CA+T12YX QW;L.PSLC%Q Q[EC/IOFB2CIS +RV5M&-.>75M4V2O"[-V,(_E0)LR(:FR)1*YRL-(H<8>WJ4S_./7#D>-:[84?%Y\* +@"/@^P8-O?0>ZZ4G=K\HBNCWX)9"S76G[AJ^<5CG3^7F6_7M)+&6RT[2'9.8Q>GP + 1\$PFF '%]B--KA5?W8]5OO9';12U4J(DV)5-C%#;@T,6,';@;YY.F\?FJ'\_I)#E8QF +=C@*%>JN!L=KT_+@0B&/\1I60Y]*;'-#J9P[YXJ<,JM. SX2@XN$Q+2-[NGGO_:" +%44M^*RCS-DR71#2'@?WLLB_$]A3C-S\4?1YV%\X^# E,=]*P*8I>OK<&TE9E:(4 +53FM!E&D(VC+D"#*U02SL+R5PPM@DM/ C#<^#:[0*90"6:WIR@C='5",Q?]AX)X[ +05Z=I-(J68\FA4C_JCK%7YGO K%LO_^81G3\,V M*T-+]XFY"PS%T\];E")-LHW/P+$"INZAAK5LZ.T3I#PI ;R%!TSU8'X5VDT1N8 +;P9NQ:@_W[A'$.Z'P/\T-"Z\<]C'EDGR@\O5:TXJ@S%XU:U)QXVA]_ *#9!5?#O, +Z1T)5AY17%M[/JXKPKGXA*ICK91YY#_X 5EWW$ U=;/=]$G='?( 6W%W=N#IM)CM +G[Y6Z*G*[I[OZ[>VONVE)U_S*\W)#/8'L4 +O^UT56?A"_NS1P)W'O)O&PABMNXVZ_W3V1$EJPE:O_?!??I7+A0J6:^I]!?E(HM_#(OKA3)T!Z= +=EZX0%,8X,U-(<^QM"R"&V("7JM38P3I]WIB<>*?RENT$,(HT2A-F$% 84:G&N 6 +_(Q%MZ7&&!4G_,I/VVX*NSJ?NJAQ%7'[3HP@Y](R#>-8,!2: GZ'3=;*=%00 +8&;-:K;^^(!3M%681R$YFIHOWEM@:]/4T!O?6U=8KV*'..QN&#,1AC(PRMYI=" ; +]L)H'ZE]8'D\,VF7!Z(3#C\-P\$Z9ATN-:_1&'1> 4Y)!LX8Q-G9TIFD] $5Q^/0 +N]CBV:_&C!%WV>;UKIJ5+$)C5SL[<#Z=?D!I35AEGD_>27H +8TB\AK2!]D'/:E@>Y=X:V-=%XVQN,4Z58.#LN4YZ?Z_M2:777VKJLL27#*G6LNOHA%^+N(!CN.6FJ7*JI238_JRU(/GSP +Y*JT0'ET255H."VWRCM 2"^5!1*N4-1_>B:Z +&-..**<0^V]C4Q_-IS+$!R2/@PY!4 +<<2A.0K90WI36B1R.Y69Z"&+63VA,4%5/ JBH"W&27^**R "FTJ?+.4J22I#8CM: +O8)]W4]:X6$Y^>Y@7K6D"'!9S,K.G>D-,*CO0TKS>!9,[6+H?")#Y6A46C32/]@K +AH'X3+R&/SX?[9W/N=]9G1.+]/U^SDNK(,&BMY^@*;=N/U-/\XNYNCHFP09U;\DS +*$!IX$G".+=(6\,MC\F(G;C2-*@OF.GQX(&:/,MN/Y4)UCL7D^(,F +$/14=:76H"C90L%V]^P)$0A>JY08NVWW$/M#=)YA>?=]M.K%)'C%)Y!ECH6&R6-^ +\?6GUF(S<':#@1>?2"=_X/46UPL2@QWACQZMW#/]:MBQ,?R ,EO2VY&U$@5@B'6W +CR;6>Y"[VXZSU.?,F(T%D!X1-=&@(9N^JF@8"TUILS1?;E,9-U0B$.;PK2 ^)@-P +'%UX3?4;T_\D?56Y?T4:<^G1\*:,R\.0)%*@6M7_YCVFF>1!-%N[\.=Y%"H2MEK'LA +OM#9Y&Z&T1/-JG7E'C@5JZ>^FC2!YW^R\%C M-Y3-#--./"J*23/W?">%Q_B 5R< +8=/UUAE(@([O+])?>BL>'"Q>(V AQ$!YZLV'"4823*&!^*WMQOOG"52M\+@>;*EM +V6-F(V*H:L]'&N_9#7-)9QM" )BP.Q[!U H23RQC0?,3S1&-Q51SJ !P--_1E_LG*$T;DT?&45$JBB'QVBC1JMTM54&Y +K(R)5*8PKUE*PS.&"H!<%2KCU'(359FI-CL^Z,]VH.D4MUKF;P.H32>.-M1 5D1, +/#HJ @<:J\3VHLKC=V +W(IBR>A^A='H$=X[6H(_+ZL($V!$02ZL(Q.O^X8Y%8J;+04; .50AITG3&,(B.T* +5=05&C)*E_8Y#7%YP*+9IO3/&O49)QC]%>Q0:#JY]GF_%;Y 486SF'"S;\?6UP>V +D@XB6F =9SM5J;J1C2 MF[.Q?-)M?:5NY6.Y^\=8YI(LG*;H>YWH33108O_=!G#) +-5:4P1:YDKXG009BJ-H,TCML:&Z\-T+,_<,L+YK;;BX1DMRA9L +K% :8S_T@X*0_E]%99WSV-^?&)@JW-'ROU9BK\2L^O@'-#^Y&>K+T-<3?Y[!+VDQ +=R3[=QZ=L++TIOJL\4(MX!XR6,>0XY$[&S\+_G _RI"GG-/I= )VL'8Y"LV.G^ M +[.*#*2K7K,W(Q;'G%R[DD ) Q!;O!(Q!A%^IU-4P,:C/+!G45C2M%"<1<DU_L][":PKNW&RGX5MB43F]+1)Q+.?,>WJ_3R4C\J*\_13$FV%> +T!O;^"GKU^E+-_+%1*1>[YLXRA%W&FDXM<1(9B$+(8X19.QDM]_VU5H]1]@@#)Z +]CX9R9B"5PL;P- *9S)/&Y#)!/=H3_L2-]T.,+ J9@6=\1YD'?55<-W@?-SO]. W +AS:RVMAOW287AGQ&*R9G&H_#,^IJQ K#/'B.I%4E-7_)T@FY.)6Z"]OYI1E5,.6" +!+#7_J_7*&+\ [L5025 N%[U:8-BJCXN!9HIM>\EWVS)HS4.V]'$H"&%%]\96.;$ += JR2!9#8)7(QC2$HL$K>_Q\ +GF$4!Y@7')!D_8T=6L]VP:A%_J]BNM>X+D[]?:H'04DR- >MI!$QPQN:5U7N/G&/ +L_6@:M7-G*@H&"^L*+!-X5R0Z2#9FNS:1=; 65I^6E>(5R3G:C,7G*I/: +U:KO2?1SDD5^PW+;R/:&MQ,F: I!V2L)DYM_X!O-P:$I0 "E#M1JJ-P\DD?]/YC8 +S^YWR&>E*V(V(#?\5^1'!B2XUD=)G4\%+8WK(F:+NUL]NP6[J:G;AG7=HZBI^L7[ +Z1NB)@'YXCG L<89J4/(RN+11NY9=_KF[(_AP/HG4S1@@)V"3HTV06#+@V93PVAO4I%QQ>A77>2XE-*863/S27H@J8Q];!W-OQ +I[QS)JDO*U+D1HVGG&?!R0^+@E+\U2,FT>>$RUK :0PBJX09(UFKAEG'?N%8B54B +4S'B(N#MURN\S2WN4^?&#J#PW5E0),<%>ZF?(AP7Q'FE".3XN5Y17 +X@"RZK;+UJ)VJ/%CRHK13,1[<]#+M;!O//4$'XD?7.'5#-'76.OQ22+-.5+NV1M0 +3^R#&M,!:%PVD%T4U73LC^? +#^P2#7ETRJO5Z&W6ES;(<\#'.1%I"B>%A[YQ9,421?EFYI5KBIK?+%\I)&G?:9$ +0R\O=ASM $S*J="OR1_PZIVK?;QB+8CE"2;^T_]9\N7(!?[CDFA^N6 ++.*QRBS^@V/>9/Z6U1$_8$&MF'U'O:?=;:28SE/6T,:<9S#>'J2 >3(^ ,] 9("M + *&"*A:6%LQ%W9D< Z=O$VUSK$ ]NL8+'5BP'.LZ\TD">>+=^%4I3#!,#&5)%=PB +,5:=FZ*&XR]7,%Z_@- IB>EPFV9B1LH,U]R+F?R)MBS4-4)T;'3@K@=!J! +7Y:!DS&X=&G0VQ$Q^P3XUD$JS4_NT91[\TTZFSEC/T2S+Z6#&Z495MJJHCL/2*A[ +>'=XLLJ*PO\?1T7P'L]LK'F.DPR06._YT(XEN]0N[WD$5A!9O%/G]KH>ZA$2_D=Q +16F]2:G&-9@4P]MR !J"FE4N8?<_.V-3&N$,-.M[BK&VTK@]1$NV]U%]BM8%CG%1 +X)!U:#J/_]FQTT?F01;8*)FL2GZK#%+XW4:8!!>D;K'+,+,!/V,[RP0;-EK%Y'+4NZVVMP]/4.. G;?]PWB)[PG)BYJV$JN4C, +6F+)?@T!C*KX*_ 636S[6QT9('6;9(G$40Z]>IG)PO#X)X,1)%PB:6XQ%@\?LZDG +G1J"9[$4WVU>$IMDT2TZ\#Y8,8SX_!4A.BJNJ)_+>^,L??XO@-*%<-/,Q0V;T?,K +(>8*NW-TG8>V_Y$'_^T,MXBEM;?93[/P"MV*W#27AF;9BP7[C/?=F>T2^>-!KBL@ +236_5]AE7+W'6Z,%U:.D<]M-PF4EY:/!UG!FV,\)\)Q%BPCR(='>&MGR=^#S35:_ +)\"5=T)%4/WR5^=+8)=N_[CM8Q=Y-4>TU13DZC(J(GO(O^C$%8H#DV]T8E]F#WYT +%U]I(.U%WKX) +'?$W'D"FA*(O[2'@4MM,/M0)(%4\.UKCE0QP828O3*52P?!D2L +O4#"((KU[_DV^R.%Q#=+%%SEO7';!N6@P=7NB4# ?C,%Y Y>3@ +H-4=S0]'>V0X 3*:HPZ9?WHCO$QDXSW]IS+"ZF(3; +$E#89:QS9'6OCZL5I<_&YIJJ%))2]59@BG5>;@:X,I!+6%(H\-0J4:[)(-3K5+C4 +OY)47VJQ.",J=%8)T_-R1+Z(SS_LH4"W.8T5-W\2O=]H%L]Z1Z"9?8Y2+WS4A32)1&JB4906NXF$F +#O&13XCM##^)->%(QA<$+6^[SSR&5CP^K81:': [S,UNB]BPC"R^I9=1$RS4I,67 +3C/CAOJLAHN)WF(Q9J.[)<%Z09S%&E26XC:@&G>O,\R^'H-G"J)4V/$$[9P35R;N +#B'\;9S_Z6"8K#Y_8!A4%FV>9.PZ",)FBLZB/5;1*!TM& KK*%4QG?%V!]6^0"J$ +<)"F6A9%1Z.T%):4:?EI%85U1&9FW&HS[V?+!D^B/R:1!=9ZJ'CD,,R-QXOA+-\2 +;/)#!K_6L1=$B,I8ZUI+VX%CM[$,4;)WK[^9*>FX<5)JS")GL;@_'X%'3=QDWTL1 +7&26> -A\#>1 !Y&@6T6DK8G2P4@I5N FJC!X"SC_[*DT226?^;%?WQY/9FL+:SH +$/H%FNXTS6L'M] DT<'+#W3U$A8]124#=[%QTW(&]E42[TZ=>@.=+34RFN;D=E$S1>ZK&+DW!,I0?&P-6',4PC_> U1L"B6O +FWJQI59AM=%RGLJDFE("E7.PU:[VZ'+-7JD*LPMH8-%QZC ">F2PSQ)8S)[*JOXH +Y[G\[RTE<_A$XX]0R^9N7%<*\ZO?6JA\'W-[08D/RA0=V2BVIN/V--F7K<<\:^L@ +FJ2#NKH<,)C%U;(#KK,)#/F0MC?E-;R_MB(7:-&E&4QAP-D?#1PZ\,"Q!JB-K0@IGYAB*$RSYN(SV^3_M4=; +994_QW;3?6A*!S&8S;?1V2-JTS@5.B?-\%&SNJQ&^+\_;4#:?KQ\+]91Y.9ONT?]Y +W9=08':OG^' +(!&$)YG,L&L4!DKVMO85?RUC%36E9I#C8_@OO<[Y ;A<6;,+,80 +'Y_5EF/THD*H:B+$$L+1*Z_1,@Z[ =04033R#8N8A;^>ZQE]X63L_8?4X^ZT2^?I +1((_4* L!,B7DJ(XA(*:9,%C:BT98E.,VLVZ3AY*B]@G'[BNVIXDV''E&O9Y/\R- +QBL\>@P)X_!.\)%_&*Y=3X$Q'C+W7I9:+%,CQ1ZN#(O@;I&2B+ER7:@'[6WAP5QA +0HH;=CAWE/S^$[.O1E(!%6*_A$^"+[0&%X\47.6Q^E]=:R1J^V!$^ZT6'D'" +-0;YTO-[=KB8I4IM=05;.7EH#M#2C8O8W:CR$)D5Z6JX[[ +:=-885U#&_0N)9KJ3 B#40]GL.Y]I-@WW/7]:.Q?C/A[[OEN(!TU&-6H/*N;WP.K +)PQN^4.1D@HKMXC1/ 1ZML@%:9P+^(&>NX[W-3Q-P$:3@80O$Q>YA:X%FY4/KJ[R +@_I5!W99FO+2\R*2X;@VF/IO:%L@HSV@0K0%P+\M)P\*2LV';&\2Z;,%0":":+5S +\,[(SN.FK'>$%-AY$QCVNKV"I5=66[SHY "BMTPB]5Q^I(X88!?; +E=J/+@(L'\7"ZWVL/B>[&UU0?]T23^=0VE>L 3S7X[SN(\_6PQ4U92U[V:W<:3J] +?)0.^)**L!_"FD93V\:J,6CT;YDBL$DR.,DJ?9ED6>6EJF-AFHIPJ'2X#Q I- LP +"''[-TAO5.@T\;CK;!74'XVYED+=40W>&PS" +9(\]^T&]J&(*1A'_&LQ_9?+!-5A4C6PM=9_25H2V+.Y*=VR5^-H[TM^D_]'?",5: +;>P-N21 T-$C.CK]I&CSM60W%GJJRP@M%_*% +?<[OL/:[5)4#Q!J):X3L/AAR>-6G,D_@%>?&AV^%8$4 KE<%F-GP-^&66M[4,H&Y +!CT3Q(1YH55!7^LF#(Z[/*VZ?29#M3AZT50(]PV27W(P)HO5&>DJ(+3A +IEQ '$$Y4'([_JMUI.I=?M>$!'R$<06FG V*(VJ%3D3YD&?UO%3 +UOS//\.]T!19\B)4\+$Q>,AR-PR[B!PTD?J? D!O(S-!+D4H/W>AYV5R9\NP(X%P +F#NA)=4E=O&VM!"B.-_H;LSF, ,6^A^]VJ\B5%J!BCKN4VW=^QBXV;0#0Y^"R2ID +;*@'S6I^L_JCX,N[&??[_@FL95^VV[D%)D(&4;?K+YQ*:Z"2'B\7<;Q)1[S5\7V3 +1*P1UK8 F7@L1-2"UA-'A7R 1/Y",(C%0UCPSJH66?Z!%>!_.\RXBEMSE&[NW(2 +)U[-[%M$)1G?76TC^\'AOU:QT0^=="%TGB3)E"3&C +7K$(FHPQ;F_BL@O2:QM7I2;K>*] ZD2E$1=('B.LK=V1)YV42='2Z$ZQ)"V:QP6S + H6<4=S)U@;?@3F7O_@Z1.DS&F/_]WAX8K.=@X-]^+#RH"_5/WH9;OFF!ZGWBU[> ++7HVT?\V"8(;O44_!DK[])IPVQ&Z]B0N*[ F9G#L;Q-1<3Z+FXD8*S.M8FE)Y75B*:ZK4(*)FF1 7S +%L3GZN64&@L9E]%6OUU M%FD%"X>.N1J-:XW45/A0&#IW*)I#-=K0 D2:FG_ +W=G1M-;:A@3E"QSCI5&Y!_-$%.)&_F"(YO_ ;D9;^ #VA$VGNF9F0"+7,RO_FRF_ +^;3<;02U+9J,W'U1)DEOK.?^1B3;B?6OB; <"B +Q%[:V/=0IPVCMH=NL+@O*[_6A=\97BC? +)[V/WU21T'4RC#R69R@^(R1NVCMG=OW&H!\167I2<24F.+J=5I9T$O\!)]!PU47/ +W7_"4<;.[J0XF_\7 +;#2 UE_CEW0[!!1X0F!S(IT)?:OW7D(Y +09^BNB=5NQ+_^ EK4-NQM7,IRY\E2=!3A)+(TF'R6=&24$5FZ\.=X/PFD]S=-.+9 +,VB\_Q2IB(3YC>CA8I(%Q_&LGH1/>.UKK@6[FP0I[XBL(J.^CVMD?8,Q?(D_5<5S +ONMX,@9,LPY8V(H136&2\-Z);HGN?(A ?O/0[YU)>^_LE$ +'M!*8L3";:USB[_6 +9;[T%&AT=)0.4N'%?\+X'IY/&U>@!"G^TB,=AEPN0V:*VG?]^O9&! S0GH1C87/ +JCJ4'V"<[ABDWR$M'Z-0'BF$ +X0:P9*V.XTMU'K=^C#84]9+UR2!-E,]LZ(I[A9S?E/ W\1,2%*\W5@EWF@:I6J+_ +?.F[]9Y?#8(Z=2J>[!3*R"YI7D X>Z-AU5YID?L QT;93EL6D0)HL +,5,[!T.4]47O5HN-%@U>>(8^>^=;Z P-T^WO,C)*1>8(.QO]4UZ=*:'&IK7@H"=B +]CRDC0>G2U!>+B4)_BP_K?WM?YQGW\E8 +B^K<'^I:Q?ZW@MC G-@QUL'_/L.,N7S:W>\GV-RA:YYW/B$T) ^B?1;2J&KF$5<9 +AAPW,JK]WGRC&,T;>%?%ILW=++#>@>.R$F-$[)!G0 *FD?70PYN5;/TZL(R[%]%_ +=6V5[[N"15_;:(TY&$IZ;/YG\8#4RSZ%\P6=M33KDF(N5P/S,B=AJ[)QRTJR)W=W +2"B./_:?JO$W>=([V08,DQIZX-+UZ'L"%=A[-&;FV@*EZ=!'M\NLHN +U+O#L*%+ +HW>J()T1[U9,374_ZXG[HOP2EE4WO+RG?XWKP76C.O)O+ +A1'&>"DHX8<"4G_/*!GL;()[#VZAP5Y#OQP)=._8+L&=M^^;1%_,<\PSUQRI1H*A +',5(%^)*E:S@R*@)%KDSV7-0_A/L?!=]H@5QFPG^K*@&GD=1.% N:0EH2N-'7E3P ++[_#N3PTB7#Q$MXNZ;=WKTG0,]Y&[0;.[A]RY$IQ [2:%':'5/9QRDBR0_R<;'0G +L6!/ZFO=3]"N.2PP/<<66(06/8DW!.D"8UWP"X*IE0,&USV161T/"NR=>/WKI-4' +!:7A"J2]#(..O%??Q*MI^++CEI0-7!U3H88_*$1G7QAS8E HH;8$T2"9(973R=?L +%?5B":5%IGDT9WE+P>=9:8]'2D7H_E4W18;3"]!5-O+GH#ZW=]7V4,HX8< +U5 [G$BF:<\X#5?T\X-M9S: +-;8S,4FO6>WZO\I;C?]9@I3 ><6T]&=-38XM'/HRT^23KKBCD+NGM[7TD7,?YE#A +PF;\?^I=O*I>^4-L.K]WSA1L:_Y+AQOXL<]F_YJ@W4H5(5]1[G.JE6C:GV+.PLIQ +8V8QC!/5'/[]5 @K;S '+7="2P9_E*? +*JGK1MH^%VDRH]P<^?G:&4%J/%TF8=2N5>'$UHGI:[%C11G.C*VKE>S ARX4>KV@6.);_((D"/81&TQ. +3%):I1>3^TN"?XU GZ5CE4*,7GR65X)>-.J4]K-ZQ8+ +SSSN+<)BN8NVWK,O=XDLW4.0HDM8/0Q%D?[MK;SL4AH4]]R?3-']FMAD[VQP(TPK +WI.6KCF>>V:;V/A/",[/::8C^CV%ZBE5O8ZLGAY0>11#<6M#(9^+C3':)F"$HG+U +$JI_@??H%!2V-CKMK'8]$)6 ]6L/3&FD$T4$,G/3+OM4\TLRUJ$L5SM$3%UJC?VJOZ^,9#S\77B^9<\F+TM,4 +A1)H81^@J&4XN$9V-V5M ^H"HTQM15:BXHXNG,BLBC'6:\)5A*E,%PH92?:UL>WN +?0;^$". IY4S:_4ZM^VX7UY)$9F$7$5PJ"+H_"2\]/*:C94&@1<4%V.NL)5V/,[S +XZUR.W$6L= !V3ZH7%$$M 0PJT% L7GFSS,KULU +-OWAGQ![%I9I#/6-9I%Z>W3HD-B<2KY$$LJ%@0!TMX]BMPE<_LH$GQ:H^V\02I$. +JO_:L@4VU46()BS7D%F#%Z(3AIBSPC,N\R,7:)%R,ZJ_/TR +NLV\W$2Y'=\N_+SM&[RN73OB@R?\1/;AF@$FJ+DNK+)&E&A4@ %+''+W;YM5DL.I +C"?FL#/$]G\3=QM8I @^F[]#J1KA)O46E>CDQ,?NSJWD^H(GO0@OH8XT-F+BJ*AE +[N*#=/97JCVB*Q5O$0LMRR1R.$$W;7_46R&]ON,S-J$-<>\>^D4"'>^'M,)3#6+H-1Z*PY'\MZ(.U9,A]RO6*)N P=DV7>%,:+.*(S51S%,XBFTL+62Y70:@RN;G' +F&Y!:P27A5[;(Y_O.6530BB= .IV-TS+U>YH"S#D9M-)05INJD'RK6#/ 1^M&![A +DI#F)QS#5\,4=IUH> N52O W]X/P?Y]]?B$0:HQB!_K5WK>Y#QX-A@:T+83C-21+ +^'3;KAAJ5204O8:R=W126M0./MK"#"_@1++Z0?@(UQOQ3.&"PJ!["3JHC%OO?L\X +Z4T/*DM:27\16!\9 Z +=]WF&U"SH0RFP[^3]3]HN9D'JW4J5 H1 $;OI^=#\1X/ES'HGL0TK9Y.ZE%?)VUP2+>5X6]%7TTUNT2/@G#E_=WCE& A*) +(W1 ]N5]@MPH?$Y\E?,W:%M;*K;=$MA9<_$CX!&L<;EV$PPZ(=OS$E+/^OV&J7*; +==UF1N0]*.X25)C>[,.O]D=!59/38H3!08YZ&R?N"L^G."N(W$3EF^X2B\JT-40; +=I .%^HS%O0O?IS/^:F%OQNMS:R]W\@B]"R^R*]D74C0=)AERRQ^"0_ASO@=F2M? +GDS=HW0)F24+]J++$YC-#Z^-HU^:>-DW1 A20KI;OE@.A"W@F7X=:ZY+/&=N-[]J +EMSG\,M[IV:Q0F.Z!M3^$$6?T>&):.7+@CY_V;$Z3XGY62A$_7J^XPV;$B1DLC^O +I.J#;N&6=:QN*D]_8*Q4HN-/O=B'>*F?F.^,Q+0?:,2OI6=Q5]&BL_;IE:9P.SX= +O9W@Q^4'X*J]BFP!1+R,^*3HBM&L 4,3SI)/1D#]\T-+7OH&F;P9,?UNT+-// +%%:)-F=W\5CZ@9_72+;G:13"E&MSGIEYM"JOPJ+IA@/E#BZ\>3>M ,GKBX7M>V12 +O"T;EDC/+_(:QB#RX(?_LIJJ1-/-\DT3/F 2B/".R/^G0F6)5DM(>YFT_RIMUPSU +<29YF+Q'1>C* F]:!Z]1)[1(DUZKK^9G>'+JF#^O!IRG'?^_@E/5B1Z7,FCBSRLM +(94YW]4@.$;>J.D3KK>JJ65>Z"%8SMC1H!F(#<^MI&JT[A'V P3#NMC&$VW=$5D^EC\WC/*!>UIU+!F.ND +/#)'Y]C:@TQC6Y9=NF19:*:\%$!D1 ZLMOQ$!9>8X*$!O1(("IQ=1:O;'!:PS][^ +HC*@^L/$/^\"G!\EC).*:KP$BHD6L/ +@K9;X%0U8O_P6_3IX1P:NO/NK"_HW%4ZSG^(@V +HQY+$ZP%@W<%G1LW@YF;YRVX +=[?=!G7."+*[2XIL#_6-W#;4E[WOA<]6C XG+:L(9@D9!WQ=7;J=N08!L=@,'FAR +%U1^II[]9 ^CF!@G0;,OQ^H(93KMTG'B40:(,X86>Y%[:-H$%0LQ"H+=2E:S^UG9 +<]4%#GO]P>!0I?>4;>GYQSW=EP/VHM-%=#69PCD3"Q/2GT_F!'<--IB?.MRGUL?? +OO2X=4ZQD89R&2"L^H6[3"8N-\(%@IVNB)S?<_7^^AW267[NU_6FXNOQ2"L1/]A( +E-JPK$R$?4.PRN7/X/D'HAQH"O8WW([[J@B&T$C+YBN=FJASDUCRPAV8\%)&F:/.GN;[>E^4XAZ:,;8U3&\4&3EA5 + KN;/+[%"6%8(<2M'--'65(U^5F^ NHN4W[OS2.]9X/YLG).5"A>[%I(#P0+&8BZ +/;@.61DUXWHL?^JC#NV">6XTZ';#6^@U[C*&2!)\.U5_O*X!%9RMN%$1>C9@0#0F +10K#+US1%VSG^&D\>O:44"K@9F&CKO4(>R\COCH"5.[N/2$,W9-?_/.*7^BP.=L8 +S+ZY(IJ%AJ313E>W,Z?UB1'Q4'Z&U^RTC59$-#RU9>9-=.W2J04_]'R3J( 5+ ;9 +79;S^"74A I*L>"K:>=:[/+/W0 95NN<$I*YK:X?C?A=$>$$U3#&5T(-"#/64<[G +G,[HP$;*:QEEZ*&"P:7HW#P95_L:GCF[,C]=,J3X8!D.%4%ES\4PQ'8];#61C/.[ +C12=0:J8$]IT&WPS$$QCI1GD3'-UC)0.8\%.BMQP'&_2Z1D!K:YB6 41LDG(+@E +QL)^[G\,T[KY77BDA)7!47^+$TM3QQ)EHD]F+[!KTS&(3W%%?4@X58:X]03N9QUN +XG2UC(7R@$'+JEZI )&S9V[V!=\$%25AF_BN)5T/DC%4^>^U[ (.53&]TH%#I 9@ +:91*$EW,P4(7+UR#M5JQ1K,'8$"S9/>J UU\4+8/2'LBN($?\S@4BU_F/&"R7BC +[SC?X>[6LD'RWSL$- B*D$NS2T;&*VN <:CU"B-M)*@0J-J@T[P%*Z8ALI9)9C,/:@6S%Z OX"6"'=3">V/] G8!C6:J[_>>^Y_Z ; H +/JMY 5:#T["INRYIUQ^(4"Z2@6+\)LDH>L_+QVUE+D@99DN ":H2)AQ'O]Z1J4['31093X0#RDVPDD#7Q\W# +/U[EM8<%I(.7Q KB!E>\U':*K>SD^;PEQ3N7+$.52SH68J. +'LW-F4UCH@#!G2OM8D(B%K4&NJ['@7ZFAM'_+:.U;:'"#% MW/4_*3^C>^U@5;*\ +6UC?4(8MD^'Y&NW_N.753Y/=':M;@J2D5P*F1X77>S)BM\G6,:BF^2U;S*]*WFK +P=V7FX!TS%B81;(WO(U9?B9KCVW>'G2PER3W> I@_38<%KD%+I-FF];[(GLJ??E( +I=LSY[5TM58;S^Z^L49U.XTN*[<^[]:K6[\='=<7^K%R5%W*D1I'P?R](R+>"NV7YAOB#5UNG +*-GPX/%:RVW;8UCZ==,8DWH.GB/_@0^60VR5/^O\T>V>(2^-T($_IKJS=^N'.KU9 +U8('E+W1(O5A'*YLM^[XUIVIL^8:KV>A"2E4-$@99=;$\J$5Q$,QC'T<0:*?&EPQ +FD4062;J*3C5G.+?+R+%9.>\R]6CY(:Q9M5N 2"=4I50E +R8Y#)1WOUIFY)\8-OT7E.N"@W2&A60UCW! =CJQ7CUW-S;+FL:1Q%X7164D6'VL] +6-G;*#[D +=BB60"WS,E++^M=% OACA,T& ?:LZ?P*52%WXV=$!'/PK8.DHK6%G# [K#7J-+D# +UA)F,O"T9AR(5**!'H[1SL=6G2C +PF)NCP$#$5AAU4#0S]X^1XB&?C8J+EYOHQV(G9F*@92+[B]-K5"=@9C0E@#52"&M +?8=W4=CADOG^G+2:D"Q9_8<,*R]FFT&C9[!;"!<>**+_PHEAB7T.)]P +XXN"\W6&VH"#2]7HK0>[#RGQVLKX]L_/,1]+[083ED*4^N6T=\C$L+XBUW?Q3F(E +FJ&V5X3?869D8I\G>WAUH-3T32&E"*1,VTK52ZHKW-7?/70FZ']'VT,NJB2# +"^L(QA5+FC'-*;Z(2Y4:D0FO*<^Q42O'MPZ1J/C^S+[-Q\CQ,! +RDT&_0$8$8E>QF/\T, JS&I0OC<4R"AG$W]7DZE"Y)PK NK6L*K[_H&4H&,N/;]T +](12PJZZ25TK3N__C/QZI?X)C(>W3*!TB'0N-BLEV:"\M+:BQ^'W/V:EMPM#0DS<$L>SN/FV U.,*;L>+2YS34]7=X +>G]OYZX4G7SY0)C;QIW;EU3==IXL;J6>S>-)\+R [D1MS:_XRCB113>_IC]-/\ U +=.O3V'M-K/,6Q2^7T@90 U!+H?DOQR6)'8& (DEU?+XRW9YRJL59>0$$-7.YJG3 +4BBY_C1A^/>>\F(N!)MOD/V8E_!)Z2@Z>8)O&_!Q%GY]C2.NX$F80?56O,XBB.Y5/C+J3; +6_V:?FXW:XC6:+E2.W6EQ+HO$,,,;*S0XT/"/?)A[AO=5:R=W55+PQ"=KVI7Z\'] +#Q92CQE$@^S@3W5'$D$)!%_]%Y]\O1(Q^8RX?-'![38;I_8A:7%9G%P6(X+<:Z$A-9%]NIA@\N&NAG/X&M'(WH[136S:QW-RZ>>SYSM +L$FZ3E^:?%\P@&4"UC,>Q,%H_C5!EC-5 ^QTIIED%&U.3T(HV3TD]%Z=OKA98>M< +R^.5P=R9AFY*0WF]Q@5_Q??Z8_)&W BAD6G'ARPT! G'_TJB_IW^>NU2)YCGNJ9? +>.LQ6SUY _Q%DMP;ID1+B&\D->AV0I_6F,6)RY<6M6$!TP[SBUNMWKAA>FR#_S/[XNN +NAFE < Y=_)FU-E067'XD@X!.V8%^^\!1BQ)J*Q?)PQ,U.&9V4^AH,:@=M=_WOCX +"<6_5<8R+20F7;P7\N%'?1)[,2%(!QK>HT5WEAIMZ!%\ T!E_I+]9D 1D$Y&%^0E +8F9!>]4\VK1&#%0O/JVQSF5KE:V27>7N(WV%S[C6&J3ZD8NBW +=0QPVC)S.I./Q/O"7']BS=5@1EMIAY$SC&W7\;N>O^[67G_JT[]]+WL00 8RME_5 +M<19R&6_J^6?"SM6QWWS(=#M!:63R&C?J,#==+; Z^XFUQRT+.4$?H#+NV0.92TU +\[/$AC%T'QQB8.\25GBX@+/NZ"&3H2[ +GW=-Q:JKH^=[9],L5'RC# +@0G\L\-ZX6&R&V%F5Y1%?M_$#=3;:W)N%^=KAH_L +.V2H Y*/J:!V)67"8J9\0J.D!VZ*\=& 8](EE_KG&&>9GV'T1B"%WDD3B#1]YZC[ +1B(PQ>3K.;[HL 9WO/2/[T?,8;BYXU]EXA+^I_=)(FBRY"PCEX>.54E-3")6R+.9 +>.*M 8!%H5U@/8N1RQ0.4K90G 3?*]FZDDK<6L;, RLAE 0$X&HJBKLJ LB7N3NQW-["]M*C39!2('HUYO2R!R\ZRN_0ZK1TM +2(*,Y@&SCDCX#"M"UK7%3:;;*G#?R:Y4SW&*W\,3C,"#A\$Z=KE?T$S;7N')]\P? +"^CX@%Q0]&/B&3_9A;9Q2F618'GA=:*Q]*K-O8%]+-<"(+0#BG7=P'@5U.5A+Q[Z5!LLN-9P/!@1""35.?4JE%L+] !!.LPHWB$=G?"3 +UQ8;%OHK+]YI*SR52F54"F!L13&,I5>X;/.KHPN6!H?!_EO/>L!M!%[/N[D+_BKQ +DE,O$9>VO'HI<:-)D)#7$\YR[C.[N9%L A ;_#"#9GQ;(S'8A%?'0$UV*/*@67'] +L(XJ+CHQ T432$6N;],V$TQA)0(OL5)*P4D[5F$=DJJ)M ;.98XK?"ZWA6;T'S_7 +@\MAM9NJO-!QB58<[8IW?#>F"LX"YT$U^+J'66>,R\F5C\:^/TZRJY7"X_PJK(>" +O=S6O !VZ9T.6ON>,F#,K.D;(T\NB?S3 +VZ9O(U &L%T6AZ$W5HDG6T''W@FJ,LNP+:8*JS"/& ,>Z-/41?0I<8SWWD-7(E5R +@&%8$ =8TX5"&9@@,$)*,@D=&D1R9 7JS" #P73WGA^-'_:!]TR5-JAM^]K-Z7\, +@(C5\#H*.K1"2C(::VFM25D,",IB@LZ/<6RP:L_FRY;TZ.'9?2 88?-!J&A+DY8( +JS"^EF"189]G45V4(3;"XAJ!.Y8]D#%CV?*E'&*W)%PC2L'WRQJ(O!RB8!)JVXOM]MEP)-&7] E@=5U*R@4/ ZD%%R3L8'&:)&H9#/AG:1R_\9U" E +"#* *E6XL7F-4#?)X%$"%-S@Q5J8+;Y@C(.?5,@+V]G/U]Z9UNQ)[?7C.7=5M8KO'LJM21DNV 1YD-)I_'N+SZTIB +VA.ZYW5,/! Z%A,?MGRPLP?K .N[F\ZH"+TN#7T6N,XG>X-@@E^B-GO.(*WU!Z@? +[$@.&0&Z0F2/4,[DJ:Y 567]^GC"@^ &=D0"\U/HN_ ,T>;M?/-E$KS1FC9JV)PE-SBU/_)H&X\BE5SH +4C9K62A6/G1][$-^<8+>KV*R\3JWRZ!C93$0OM?;06_7WUA4.)3]-5]D4]IG/#(+ + &;**M^Q0IU^*L)*2"48T4&FZS@]C6KF]#'G)Y6<>>^)MP_'&:,]<'+^PVC// +_E:FGH3PTU )I%.6-;TZO5B'_\< _*6NE!E FYE[]0(PY\=(^*V?2*&H#SWUOIXY +[= %Q:A*'!]9\1M,Y4J_M7KC+=9+W*!RA0G5(M0G<5J=6U>!PW=Q:C%) :]+ +1 7,[@[X/W=Q$+29T,NDJ;B7E M:S(E&YCH95 T 6=+N,M+>"D^I0-=*\&\/ES4V +:\I2K6*!S."U)8[V#Y7^K6N5N)A)95CM[]*_7X(OYK*7^S5XJNF;0O<*^V^'A>7_ +]3#KP\]W. ";'/-'CE?Q]!V'7EOYQ"">-]4A3L./<'@L@1# C&==QL[F9'9A_PR7 +(*#\'T+\+;+#0%]8:MQ3*M)5Y(ALN6CJ!DE.W[0JX8+,?,)8UB>LL6_^!]>T/VT4 +@C;S6388.(-;9R]2*!8*L@ G@"NI__4:;89TV65*F!=WI.L_G<^IJ(Z\RP9[:N5Y +Y^!^ 'WY'Z6Q$3#GFI ZBI]*!M;F^QW48*#H3CO$\7"[LTR<5H=/33[:*')$J%2N +#+8:#@ZMY\JA>[067J810X(MB&'$H3J-A=L%4A!\H-JO>?K $[S,4C'048>%ZQ/' +U\I.B%C."FT\KVN3!O:DPH+^LQD.)[,<_MD0E$ '4&)WX.LYQ]JO&XL=D&O7QJ^(TR__7?M:Z+NY,>]K?U]9.[.6D=-#5\N@ZF +:5;(W0->&1@]*E\KL3FG.RS5$H189]9TH[ <-4[RWW8I<"GI[];*>?3P*;@+A[1N +0>K<%GJ]RJW#IV+GKO',Z/3K.M+1ZYP65]9@8D(D5K^;7T[":,>;%VT97F7-VD"^ +=Y;!@+O NWV=!NI3[6%UM(8@D%R3QPXS5'&KYT1<=;,"Y8PX87M(N +6D )?W5U1;UTBW%E"M[F&9?J0V=Z#Z)V,L.Z^_T#\YYD>?5E.NSKE6*DA7MZL^/[ +R8HEU(+Y*I2)=S7QD64=R9G^!SBLVZK.#$E%;K%VQ@,!I(7)"]39%J*\L +"%1JO]E^5)$@9LS\@=]@6,I<2(&FG;+?>0.RGR?>!;4R2^M&DQ ZU(Y-S;]L1UD8-!9C!N\0C6#!0U._R*AG::A8A$\6B2-OWR-^(Q=XITG7 +2H;AXOK9?WBBE^>-X"%240V)MB%9!TS(R3N75PZ*/)3$24 :@LPAKLN8H+ +DYI+\L(Z.F]%3@*Y0/IAAD@!1L"A0.#=09LC3ICO4=XD29Z[\E#UD*^YSXF#(>Y% +6PWV3 J],/0?8!FY/RCO_*_*]?TPV0@/Z&RI&BL/%\4&*V19/9E:*A/5['XPM:C_ +DQ25Z.RR#NQK$+\.-K4R87A2&1V(O*\7D-""OHB88U K@)*N%*-,1H:K8;&0038 +DR ([1.&U=,+.9=\9$&-P#6'LF@A+Q"3"$#0JJ'(T[Y*: [Z<.U&0(6 +Q H3FO,W?Y&M,HU]1P.I(4CNH$OA11&?/_B6&4'^(#.L](L!*A LSHGS<7,A*I*D ++/%Z %R')^E9JE/@?H+[Y^FNS4Y#! *M7JMB)<5)JAIPLS0K';BO2)'1' X$G_P, +!^W(<32Y1T!B%^9N0Y,$''G9,G\%&Y/9O3U0&]\JN\SQ5F:ZCV>^:RH;IWA%+A:79:<[/-_2Z +QS?#L6Y=>4T-%5N91.*D1X*9I\T$J*&M /I!_,.X#W+%8]!2:Y6@E--("L+%@QQT +@Q&'_1;4^8WU60BDHBD=#/?!O]73EC+R&11:2;PHZ9VR*J*<7L1]EMP%J.4:_%EB +VRL9K.$/)H%1GWQ]EW"[9R,(SX;*QKKUI5,\G_38I?O8,B!MA*3.C.#>$7)OIA? +W=I)I"+D9^T[;<$F70/N;6,% +?;W8O_&&;8^B8ZI.'"U_]Z#/8)A:<-G01@(PPT"R/6-S0S +)XX&C1[FB7HW/PI-6Z[62F7GF!L*7Q.4T(Y@+]Y(+K5CI%B (&0[,XY[H$,&Z??E +_(8C;_HU9?$$?TH%DVHR7L]L +=RY5OXX84JK%(*%M"A_P6HM5X:E[H5Q2P0\7]0NS) EQ^IT/MZD+,>AZ"' +2[HCG5W%RTMV&(2S*R^7B>%FYR;WDKWL !JL?W6R?S*>=9: $X="RU]Q2R3ON/$+ +:&AP4(&D 4N\+=$BX^05A.E1?/1G,9EU']3ZFYA#O:.G91QU8)V<0/T7F(T9CQNC.YY/\2N?2QJ8I :@I4P>+H!L?>CD^A@.AO9_; 4'5MI>^E@$P&R8Q +=&K_C%N2,B'9_Z)P2Q96M#-UUI?,L5\EH7".&]= ,EKH,J[1$H)LO-)T7'F&$"9 +P>> WBX"Z4\$(:$7CI,/!*+M"5/H6UDM YVRJ +)G;I7:B$<\98 +!Z^/^EU9G'$#X:OO(N>QI+M8@8L'*%?% -<28.O+@:3&OSC2[_5T"3 +>(,GZ420HU46DM':AALC<% 54^ R/Y0E'D-#4#TNT';,<'!93\K48!]499*UK) $ +A+#LUU#"JUNL!+U(K3M+,Q7$Z4NY*-6D1*$SH[TLI)?GDO6<(6W?<_)DCL1V2.HJ +_]=7QW[RXUG'R9I$WWL^A?^N?*1[[._MK+X#IAK)U[[A(=5@"E,A/FVY-M@?L$5\ +GCJW*(:Q^2Z^&'C\^N21DN=;)D+E4\\VW7-C2]G/Z_'ZZ, A@J$I-T0*:*QC$HD: +K8>9P4+P;9>LV!EYE&#G(*^ST$"XV[2N)O +L_JZ 1'0E8/V%3!I4,C"*DC<]C'# Z=E/;&UDXYAA:[/4J]'W"3[ANRU=_ECH8B7F/%OTS/YZ +"E/A_F,XWN=HA#-'WYM>P-A1?_B1N&O%AFT-S^9FK-]?7M* UX!<2U 3C*R:*1*, +DP1LC,QU1#1ES, ) Q( WA =S-7XAM==)" ?EUK"&['\!7A#"N'58]1HM(<[Q$O5 +7.,JEE_+A:K[$@R!=L'!ZY<".FAZ6B..=N8:+[-4^)?I3;/>13'Q4Z>G:92<*CJROP*>&Q@;HV@U=**F& G-W7P.XYI@\\]$'('U3>YDZV=/!F6L&ESV!K +!WH92[B:HS@-L?A7(ER?C@HW14(+'5HRO>,[AX7G_A[A6]PM9FY=C.T1S_UEZ?2? +X!0.XU_NE@C5 3V.)B1TB15NKR7)',@XPQ2(7LVWB^24+?H.DS?:;%W19Z'PBB8[ML!X9TO0S_HS!?#V=!(/R@T_EU6,[D^'+9K_)-_ +(%8M"9A:HY-CZB3H+_G2O[N\2%>Q$.M8?R:+E6:P"K?PU&@=T!DY8A?LBGV)'(E+ +O5ZOSOR:%8"#D=/:O\-V>UM)!TY,9'U>CB]HMUU/2#NA81]:F>'R^1;=^;S09#%P&7+Z^6Q@ 9J+G6K1!?Q"H@6)]')K[IR9"M6=DXEW=KJ-W0BODB,KL&'B."\A$?6-D#1( +=U0=H\TPY:LKWTY,C'Z,1J[?9IR4;_M)X*"ZE>MN#25K*K4W_-72LXH;K'\"L!].V+!@];[ +L]:]PKKG7'B'9?\;_8*QD Q_S[+Y0A>KXU.W,IAM$<+1DP,QM(+)G 9*@7E,9J] +/?EY4<1WVM].KK<:]W9QD.#NT8-0&(C[*Z40QLD3/I# #9#;U6U%21R[NF!?-G#L +W>BB<-/XB<;SVU]\D'K]G-.4(XBM9 ;$[(V4&W"B0.^>XOWIX& %=7(M!,Q^S#&M +IKVY@]/_ERO^6]Q8.[D(%]GQII5K>59I7G=> "5L7PY]4)0;S"TQF9-!KKWO>5M?'=70+&J^WIC*&V.FJ2P<$63WRQ5,:BY< +=82E:4<U5M)T:JEA!]!13=&B4OM:5BPUS0: +LN$4T6_,SU/@CJ=$ !WU0$+$94F'*I+?'>*MX??_#C5M4Z $K$5:QI3J!)S[6/S< +@-TR*O4/YCH$":"/&P1G8"KL4ES6N2TY@L06# +%RK$SHIPT5(]<+]9 V.=]CJ(OL>"?5"F!\*&]B=U1=]]8DVEU:>:"?-\5RA!+_-8 +\)U&"[2S*]?(GI17&U%DWBP;\=SSR/.706_;AQP>!^W@NVL@. !M'2.5*]T IEXYPV+GQ\G--\%8OA%.I@VD)M_@&DMK;N&] 9SA6SE-2*T6T# +\8KMT1Y,JKQ3ZM23(90/R&Z/47%8MTXS$3OI\LU024G(",+,BA:Q^-I;HK\(R^I\ +B\IDTS7Z]B>+$YM%I #TVBC3S/>]B>LQN0[,;&M).PC3JLZR)/_%'I5P7QN1*?Y@+QH9H.RMWD;8,LYZK7'/<3KD#@6U + $@9:!)6".R<$$J-*]CRE(#]"U^9*J'8L !#Q9>@N^7P;T[ENM!&_U3/B1*S"R7@ +3:=UE)9"AY_2CED9Q_!K,Y"W1-+#6KW525-D P7F]RD)9C3F7JA>-^))BS2;"JJQ +73ULL3-+M-5PW>FO, DK?\\G0]CYV+],VM(19WS]<5*_/9**Z31F[R1P=%TNGH,7 +/=69@0@HFR=.YT(2ZBC*B3;K4N#/,,S;8*$S>M#^M?VVGX?>"Z@C>-(2ZROFY[IGIBO +;1V!^,WP'!P N5*MV-4[]BA0R!)$O+RI@ML!-5?312HLG&WX0UM C$R0[99X9 +R"',#/EM0*$LJ5(HRJ.&6(3#>IW':AJQ3:S]/MGWET(B$MC(E]2?!H"U#]Z#8FT= +CFBI ;AA?SI4]W"76VC\&2UEI0?8PCP .&1?!'R&E#;*^0$67TL&!,7/'4@"CX%3 +'JJJD5H?S#_CBDV,P90/X\+.@W=ZZ=R@")J7A&HXZ3*[K4KH +.R)[5@LE\7JV,#WZ.?8+ :W>"E,2>0H5T5Y^&%*0DH;BHB0F G?Z?_O #-63O-%/ +Z]XY=CUW"1N4L%!HN\P>M2GFJ=Q5,7O!+&BX[$+).+8! #Q]!D:$!80MM$:;,]YP +:01E2]\530)E5L_P"^JX+$)A91CJE]*YKC.!C4G: +^U%P1[T>.@_R(S[W]&(A9T8E[W[^*[2%*=XQ]I()2W_NP+Y5(+CM!2QA;B]:Y'LZP7E\XBE7=S6,$0PQNMPP +4C55VDBT=89,\^S6:'&T%#0+V\W^T/ZQEVOQ2%E86:=+O_]EJ[Z:A.KW3/(/3DHM +*N'R4-ID>_4"\)@@EUE:.Q:O2V7BX"MN_IKN\#'MW0#3L"'8#.@CW?UMPU5NC,/W + VVX8) O'*VI*]( N&=QW]\1:H4KK6L]U4W-)JMICGA23!&=$&S@' TNI2E>?'K* +RFEON/UA*=Y476C **\I]_/D1[&5'=%F#.KT*#8LL*\@MJJ9WZ0I=LGU/;B14/SU +(J;?6^: 0!TIQJW0,%ZQ*T%@%-(1M+=465RX:2JSE$_SBM\T2*1V& 11502UNB-Q +O&P&VRF4[KY8=_P"? S<&:P(RO^/5BYD3M[,S;XP6QD6T $EQ[\GK)\,+VL!MO-9 +,9\F_R?-?3B&J^J$F,KAQ)/^M#I1 +D.(JI?/.EU*7DN"ZA+'YP/U9^=)T+74NWYP/O= +N><+PJ[OAV+Z#>:#J=K"EN,>^K!S1MFK(TU=ZO.% ["0."0!U'XR--V15K]RP[?P +>)LU"*1#1-\PP#A'E0@VD)+$#HMQ^13*O+5J (_C;>VIVT'&6<3SP;NV0*.+]#:! +!\2T,U]=%%U@E0%:<>3BNM&0_MC?#/%HA .[6YE7/K0C_HG'53]^W-NL;ZF;I153 +3WS':IC3:=3WLORD[IW$-]'6**!L_M^$,R+DVW(![J.0\WE\!J_J@/M:U R6RLC0+M]#\@;Z"3!838YF6UMVG$X +[WV]?Z 9CG-?K5<1ME!0/TR*P892_3V>3D9;F %3]C:UCL']SQ3SEVIK#=^]#0_& +.1.\;R,XJ.8PQ)*96[.CR*7IQ!>33>E>V6LDG!?3^-W>M&/5LLNX-D34/?PAP0?$ +@=1O^,:Z;0T4X,W$"J?D#0+ABAS6YK3T:Z<]@@%*/VI_O#U5"[Z?%+FT.1T?'(NMO=C$RK/_]ZX^_HL5-.IZ%X);HG+'R*?(+< +!PRCDW#9*2=Y+3;>]L*>@F0 OMPQBC)3AO!E'H2V63Q*$ :[K_Q.3.>,3SA0&E\< +DXRXBNWX]+^-6\.]#N$P/9'+J#Z3>R@066/:K8"KFYZA$^J7@[:ED)ZD9,G/O'Q[ +W)AB6-SI]XUV6B NG(QIU'\(F3,9>8EW3^+"%.(PD=?JQQ5.7'D#6 :8G_)C\:6" +NB<5X$(7Y+A*/7QJ82@Q=;N@=E@J\(3T10-U;_?+.7_&F-61,]'6DY&^M*N]Y*>< +?%1!:X9O_X-KH30L!+S.TT?B?4^(-P[C[+%XI?_:B#F$!@T8%Q.AR;*'13>4!]"P +XX0>*;YV,EF'\ J943UA8%R- 4A +>D?2MM4I>%4MF@#M#^P-2Q@%;)"DOL3^UEJ_"GAO?1%()3ZZA9S$>F),Q>QXP0OQ +6&UC"C/T EZW_/!76Y?X"E_*&Y;8M->4F8$..WX!BN#XWEWY05-JM'=/=1W_9RXH3V$-$@ +&FDEA8':ZO0 P >&4VI3-9I.:YA;^Q?C C[ZRR&BX2NY6/G6_VG%+V*FHF4!(IIV +Z!NX(K5:^QFP_R]>YX$[*MM-V.G26ED5?7-O8D,'I9AE=Q"<9#7?[0!6,&_>@<7;1C=@$\/,>S0XZV''.+TO^^@ O +>'WG#/^D=:_=7U^75@[CLI9HM)?+HBE5+HC^":(T._V57JCU]/WWVY\STPCC8#YI +7;/A< '!D _Z+LG\PM@CQQ^]I/0RMMW98I^B?7XM?Y7DF3AAG[?Q3K?]_@=C!1PI +:4CCMIWWR FTJ+^8BQC%*TLK0&AJ4+RLY/D0^Y >EH>(U!X84.WY0;TH"WJUQYG' +&#AV0"'.B=^%SX=;G:&[4@1#$DR:/UO"^._Y!-9ES +R78-R%"NOP7U7(.Y8H5'0/ JNIF,^H)[ [KT*RCX#;V,IVIKCI -#4Z+]VI02^:M +8#7Q:7JW1:^(*#I9>=2Z<@2TX^F'ZWB3=S(JLK9T6=A9:JNB/+Q5[65$I: +K#P4G'HI_A]]<,.^7&78'56+6+JR6*A]"5SHNAP"3SRI2#8W=$H'=]G\.UL, +G)+\OM%^M+0L_#ANP,EFMFA6*]Z5&K[5V^2 ESZ7NN;B]E7[Z@P.]B ,X:G7)"3 +Z&)CQ X4FUOAB&=2245I;2UDM#I1[VFXFMT\Q13O\L![0T#]5]DN.03A59K.%><[ +'I,8,9N8$-V]X6OT_2?0/A1I10J%:-I%[66"IS6+;Z""V"F8A-M@S@FF!3O."&S< +DL5R7)6BB>2;\LQ\?@]Y))Z/!I)%8PI12.A%&$$[$Y_+J^KG1\V_[\ +.IUSAW*IME_5"!FEL.2('\D;=>KM9ND<:I1]]+83L,1^[J./BNL:6N M,X VA*0P +)^()C5OLK!^A(E&8+/8_TK+S5H!:M^.R^WOBMHI"(92W@J]5H)4.WYL\# B_-.0C +$,Y&N_]!^,>,47@!K3>K27<,(*Y5[K%34P2$ + +9?:"K1)<]56H90$?8Y"H#= +CVHE!\=$DDH-DY D?87N9>J4-T*C@IQ?%9(*_1_0ZU):([DL( "P,MT:-*3EBGS& +"V6"SZK1N[DH_,APF$;XV+HSMHKJ3"29)[#PWU6[0<="S]F*+^-X)T66/MMM2'Z+ +1JH&U5FWQXVS27%!F[0L42880BRGS7$<4L,]Z8BF' ./.HN9OF!%A3Q.]D&Y'OT^ +%(80T*:4-S+]-:$98L[>V& :():[-N^7[592A2(#YO!;.@>3T]X@P*>%RN#KH3T* +ZNAJW5Q31\54Y"S1ZN;CRH\TW<16T"PP=X$HW!T6F]D +_S\.+0X^<\;([RG?JGR[6X3?)[ZH6HI8/GR)_P]0D;+$7W'ST&^"I--A@.3'E5:4 +:'P\&O=65IVM'G)C99E1/S2Y1#'.Z&C$^X'.]-W 3R+V.LP;Y'X4!Z@;YV;6R"N> +@5I:T2++W3>YH^%M\]XXES7TG[S#I^2$ULTR=J#WOTEE;#3C'5&B]9:1\/L^00A, +AV0Z ,*W02' ),0R9MQW2718?]=)1BYBWT8,#GAUB:1&OT5MU\;1F;Y-\3FY3#DJ +S#?G<\;H+#FW\V%!__+7Z:(ZA)!><[FR&M7):C1EP^-F;ORQUXKJI+=0,=ZZV"=. +ZF&P,B\7XO,B?H/:'"(Z/4$^!5B/P6,OLEDVT-,/TPAO -VW#V#DVU+ +;V,MOM ELV A.KH\;(\,VH,/2!']?-C/:G,VH_!1]>3RR!JSK9X6;6FQC=^XWH3O +0:.52%'S]SK'B^_"OMG[[13,2SMX=Y*'H9JG##3J63*&%H'<:?M\(L.E@6F?NOWN +7TL*#)W#Z8*(0L1U=-22RSOQ*EX9T$'$6NR##9VYUJ''G&&#:VP !DDV@:-\1[8T +ROZX:*?J%[0,+5JB=ZEN_GC@N5B\,D$W#:Y%^8&F'B.-7\P$"2L^4^XA50E^G^;_ +H,@I1.AL=$9D9;)'\V75X^B73QXT.-@U*0B\IJT\O_[[%'[8HK?/PZ6W@T7R;-G: +!&PP9"V.2<+,2W0QCI%?O4^_K9 _VTWY)RF%>X:EN<7*WUY%0^3(R(HQ WL=?#)E +&9WL$24FEJ>I K4.UVT87:]+0=5?&:E8C3:NFHX3+V*=]'3$8M^7Y[&,4?J3_#U] +!EH R88'6K!46%2 .36XP'P.;7-WX:CU5RE,.@:"M<$]#2K*)QBI6L,P+)4FD'AN +N1+C>525.IIJ](QHVY8A)JQ7P#)P)])(3HQA3IC6COPZ'17CZP[XQS%!SOLH]TOLJ&;[V]^8 +C.\)A1@,MPE4PF3B )11HI+I)Y0NYI0.-7CNAOA,(4X!=@QQ=KRJSQG.VC('3D]I +@7:1:_XECA- *#^RC4*SMYK( G1*T5B#&#>-#0,-$%<8>F2 C2?-B0)7LO7IOBO +D@G$0/1>PXF_"D?' >'W+N]%/$M[T[@6B'M%XB]G^)Z\U345@@ON#U GB09\)CC- +I14U(D;<$1][4K!(8J)!Y5=RG0L(D*6O/OJB2\F0EH$ +KC4*<&[S89SM,M32XD^EN%.W-A_\6YC<%U9%R% VT:E? 9 ;N3$W5FWZ[!56/I=& +J7MN ZQG*XV!VA$J7U38/0,;S?(TR/4/,_ ]@=YNIF!P8[Y/Q<1K3P;3;)L#K/(Q +SJN^"%1I7CB.M_'I5RD$\[7-KD')6CMY1M#&FEF/@23#J/L3.@IOF&D,HHE-KL;2 +8\V>>%<%A\RG!C2^+52XCY9FMP A*2/#4^SUH5%\4!_>/C*]FY;Y%?5BPTR3B77Q +O,/W[)WQ.@H5^W>P?3@] 4^,-K> <5O$/">4D_EW#P;PLD0T] #3 *5F1F\Y#LC= ++@6_R+FH.QL'[B(X46ASG($VK5M;M.J.07LEBB("^8MF ON^4VRA9U*HC-<"22Z^ +-L1N^T1;M_B/@MC^,WJ?F;3V^39.E-XY<[@D FPY.D+"PP%W920"N^7"K3,)'N!Z ++'M?"GRV7CMK*D>Q'?]5 E#2CPLQ!6X=7R5:8@5Q3Y6XP=3F,PK-[%(Z_1& Q9L( +"0NH#:QXQ(.US61QL1UVW@DF5U2M]?)8F4:CFQ??>T@'N!&'[21F5J^>HX W%%)% +3PP6WSU7O@:T0E40<"J40%M_1=6I"DJ?X%Z0.>S?^B$&BG!)]47XN$IJ[@-NIK]* +6+FS[FDI1),3[U>#0A8S_2M.Y^U@XZ&W6J':=O.B7SQXG6$YRW3TNKZK@#&GNK@\ +C9 TNV,['O3A,B,VML0H@5AR>=N?IC YLS+T7^SC@)%-L,/ABSMQN*&?LSIYWWY< +J\%(BU=HT[:-DS7! (QX7!?M)?&VG_*6H)\$7XN1J(Q6T#6 [H9"\@1_&'W8R=D9 +&W-(Z P<'O)N^=QQ0!XNS.D):8^08XSD2YD1OZ"'2NOKVQS?KI<[($ +4ZC(H2Z*O!G/UQZL(6OL*HU,XK\L3.R5(-F^98R@A?1R9O'7F"Q8)D"DJ8M4ZX7A +\2K4#%T144N[P4X'$..K0<2E4@LKHL3\'=6_NWC/N_G(%0RH%<[OVI1@TA,1C!Z' +"%NA^9S)#-4O#'Q(@S(Q90KA9W';Z[$MJG![UA]#T8;PS-=QEBK,&GF7]7J+^&LI +<9;@[1B*6]ZG%"SB%6:X4]9DFM0E3@QB&)KD??R+790H^AG""6 +&AX$3EK2MKT4B-)8_3-FZD,XNY(056&2N*83!B#$PZ]%_,IL5+2O4W[0TN,P:!]Z +/TN4F WGEQ,/ W;&BTB\VR.-)D*-]ZJ#I*_S^T.R%&P*?6E(HIAP239/$U%68=_Z +K"]*FMA7-/]2N8CC]94N7 +9\\)*3L? V8.FXKGO8*XUI^;CM:=[K";)ZSNI'K="*CUE?B>N YQBC:LRTHLZ%6$ +80)P7O<86B5);._3[TP^>-??+@NQ4+45J8IS*Y\'JBBT/IRQ:YVV(F93_5 FP41@ +TV1,>M.[AW4ZA!!UNL%F]@LD&[8X9\--L8F6;/2)!,+X+TDGXNXP\0O&(?T2E88$ +"Z'*)[?)_&?5^OE=?+PP3SJ5(E6+8P/G?8,O!LA^?4CN'^;DB.MHZJ!>=N@Z-!>I +N].ZM.A=[(2Z_%4C"G9[=[U0P#B&6;_#C?)LE_S2FX/0BXH#$SQ1.#5$P0!^]K " +,F'-9Z)4B 4,0_YWXBDO6WG?7H,^3_)-;3E%ZI"Y7F%I1ZF&A*[YN,9'FXM=L>BC +$(@Y00GP[O'X=T3#B.@OFE(E!Q,FN#J%-7=#1)MIW>C_'Y5GL^Q +MW'+J?.!K-'J;M["1&7:IP4K4*++FX\"/72>?;OZ6=D1MVR=[/G;N#-GEQ=;_QLU +,WY/WI(&4\%RJ_'Y:7.Y"-%5=N^6'V#=42+I3$D7'@2:7;-;U +[+>:60*^)QN1;/3WX_1 +$>9_-'&> +6Z?6GDQ=SI6NS@N?:$+RPQ9HN'I: +ZZ0]*;.XC&! '#Q_-\-+\J075.:WJ.W(@[6<$=>>;*3%1.S@[:9JCKU^0EAF +2:? NXF6F#CV;S*N.=Y[4W\OXU[*=/R%VJCUN<75FF#6>?[E2QGY#Q7%NYR=YAFV +7(VF0Y*93++Q:)J.8+UG#(LUP3,^+HK$=*[C3^".4V1[*P )\N[DZ:T*+?KC;&GN +0> J#4105R&;0S*;LC+WVE#'224UNO)??F/('G;>5]23N&-V&XLLLCD>XP.F>)*6 +C65^C*G-7LZ6,"8SH\S-;^V$3(_A?8R"4WL^^KUUD]2MJ/[3"397A]++4.)@H'T@ +L"XMM!V@4*\QBTJ1,/$?UKR'.I^&\#OK\:?)R-Q?H/7)Q/H/.[GWHU/IFDI3'Y_A +)!E:&5SL'M4>YG24=,A>GHTX(>&._HJF@:@@7ZV$Q9YVU^.OZ,!O7@>%G24ZBQKY +R@DJQP9=XK,JV+QLG-. ZQ;-__BR_6E5LSB;X);0)XJYRT#L@* M500!?(SH!_ 8PB*KC)QGD-P6>-ED,S]7-P@OU!@LK@7H/.U/:,]HA@TQ +=K/I+WXV27V6X/ YA'^U4AOQM\8%T[E=FC&$A3T5*.:.4L'H\EU +-_6(O1R\K\N^'L/J2E(#U0-=,%J3?NCTY_((J-*QK,KTL;QDZU,XN9*E>D7;>W>. +%EJJLP:'2EZX&OQALI?XZPKFBQS0ZC<#\;MZ\>'RD/A)F F"7#,N/U[:D*W<^2N!K1Y09=@J3!0AMF$ G9PG\0 ].%#@.86$ +.T[%_QF:X=9V[T2&]&**H?6=1TE_D+BQQ3O]C3'-D"CVV.)$.M5H"+CJ(B!^$S>^[E%DI)ZRS+C*8B%=D;\-[)9@;)1Y#'Q Y+"8 ,. +&) FQ6'.GVALYIYV7VHW)2IW>E-6*^>7V$5%D/Q9^&9NY,"K,XRQJ*- +E&2(2E@H$5GLJ?2<6,&>'3SX35?ASB[NUM^[D$-5C!=1G.!V\@Y-]5C:2TW_/R&2"XOD +-NWJRI7>PJT->UGQ=N9_0'"H;1NTT[< _>S)HV)D-<)))@Q?Q:G *4%RTS8L/'\2 +TKX%R8JGNG^^X]T_\(3R72 T[C*48OH24KW%.?@[)]N("H_P-5O+77-($0WZ1THU +NXJR#';5BWR]).J3W6,)=T1CUR)"NJ##]@+]42941(#]1NHB>(.LXY,U]85=/4=( +9LG%X<8EW6G?9L)SK@%[:Y*U+"7-P1A""$VE[@@DV6E$-">^RH5_&(4,:PSV:XWX +Q:/7?O].E;NI1=QBW:,[\"7XB7= '^>H<:/QO_YHN8C5BENREW8"%X])EFQ"%J34 +GIQ>58]ULIR]0U3RCVD,7(967*T'A!NK#4Q% #7XCLG!<'/"TYXA2CE:%Q^_NG./ +6%\^A0(UC2+.R&S_-NBP>+*']*J<86N=.KYA'$8'Y1DC9F3G"*.OC>7AU]9?. .: +VXXF6:3-0J?'!JZTOE=3P^Q9^ALOA[="&=WY;&*J#6:N_Z9CQ+E1\3;[BE5KRJ_' +* FTXJV]N]2I=65X2D?N['3/*9"#D[_T9XY+DNV\$+9WU]PN\58;9YQ$AQQ7\#H=8G> ($ +VF]/]^+>Z]\RQJ\[*##P=681!?01VUTX*?(766VRPABW?NJCQM4?!2J(TXQ\F^\] +0:V@<\ FDSF8&MZMP[N&PRGXH%I]%I0#KYM1#[6,XSQAQ(A'DN+DY">#:\$)_IQ;F_XF,J7WUG/L\>@X +MX^L[YX4*>R*">2:%X34%?6B&%.QE*^LHMS$2-\>>1H&JQINE);M4N09/#7\E4U +WF&1.,N>:*=NY" 74U&2F;@FN>AERN_BM*R0C&(S>F Y9@ ,OTQ"5Y'Q70<+[K=[ +^:%]'?:L$MH]URZ \Z\L?Q_9*'52?1W)]0ZY< :)61P( KT-[69.8 +.IWIE9@U8H0Q8ZL8=6#)+M0LG'K91T@(-O!P2)]M\ANV(369P8LSQ2I)6#4]@&32#T%H+K-3JN1#R%NT($8]'CBEY#+'TAV@G +VU@\LQM[*.1!!HWZ0FY.V$+UW_JKD41P.9O$Z/!/QC/1S+4RYP ;F]8LN; +.EJ'DW>OI2@B =?X''&=O-Q(^M@U:^[C<_K.?@)TYEI]\2)T(WMS'NXPIC[;8J!<6+4HK:]7OL'6+BU^SDG,^3NOR*<70"B@6MAT5)?>?E:.Z$0PGB[)!11 + DT#I5TWG,,DI[-NX(D90C)",,F!L?@D9FQA;CZO'P_OB$+GKC20T<_J;+ +F=1U +RF_:%J8A3(>[2*--H9J=O3U[ORBVG^3]^>\;WJYRVJGLE*GFUF(.TZ +6J@(U&ST7/$H9C TQ_AKH;!KQ19S95(L;2G:;Z-71WWN#V;[*;XU1:IJ&"!#X]8@ +TO.#*Q^" 6T>V!63%392[UT4^8:2.9#^'R=F +&ZS]=.J;,T%?;;7\\/O_9"#07YO[?X)!V+//?*&X^H'_9[9XU :5GA#PD^:DD;J. +!\43XAX^C8.P+2#?&P+:/\NU<'+3U,,^NN+0![&RX-6>K8A*^91;2J;7.T(.)/76 +NHBB=G-@6"]QIJO9YV8MTPL^EJ[%#S%AH'F^)XA)Q^2&MEC^>>D\ +F(#*ER/? +=H'Q[H2"#27'1Y&4X/.J3Q_S-3;E&:_F;[B8V%-K9FV\ O@KC0E^!2:=)=D$O:W^ +N4NNM1?E_X1F*W.9L\80AARB!O B;"#"][],HGHF#7/7>0#F=_*0N8UM#\;,4A@Z + J<4QB>><^<+(Y7AE.93H+J ^NI<2O[B9!*ALM2 +5S9ZH';6RT8U(E5^$FG'<,OFWMG=CBE4]1^Y8<6%S*-R?_R= ]4+(,_2LJ>HW#CG +&.C4;6K)I)Z)DSL9*+T7-LZKUF4"\D] &&)Z<-GO@[(Y6C#FZW_8XQ-WGDKHA:P&W +2(SN8E?&H&]8(D/QP;>$:)C9\O@A>+ +! 'KQ(5*SYWYVF^>.45(/'2.@*PEW$2(H!S-<4^2!>)W&UE4 +SP"H9R#^">1>M)M),.3Q&AY,@8B.+F1"AT4T0 )#EM+.VV 46+S[H=B+EZNH_98P +EY#@)DH7 0YP,>0 +[&*:8/+Z]*,?ZLB-57KN\7_CA]%'<*+#//67P!$;'[)JR#'MIG+6J3CZ1U,MH]:= +8+&M"P(YLU2%Z?<'%$2R2&R#V"*'"3Q:-.Q$O646MZPK4>9IMW '((%B.XF2GGIY\%N,P4/9D1ECX#Y9:&+BL7)<+Y3#V'9CE::1T';:6Q1A +J]X+@R#VT4/N*KV^L'A927ALR@B/K; D6T4'0D5CR&42X/K83/K6/!J]<+G2?*7Y +"^+]]$/3-B"AL)"3O*#7Q>EC;F:HYW^$J< V N/U&A3=?'!\R)RS;NX-):MGE(D3 +PL 3VJ9-5S+UKE'1U>N;SUGNB-)T=P(4UDE49W@#=8LH L\)Z"+-FD_?X?P(^'O: +*,V#6TV\T9U"+$[2>:D47[T?9\+* +Q8+XZ:9*H LLZ;$;NL,G1LX!@YR'!C%EB!".T + Q!K'S^F)">Y=9CSZ"KN);V[/'(6A"!7#5=HNYM>JI$5APS +H::9TNC1F2CA,BV/(1!D)&:X7Y'\<^2/2TN/]J$WS07N@ D_6SKC\]*4!0O#'CT! +#."EZXG0(:F$;,D;MR4X\Z#OJ7V$Z_ST^VZXC V8Z!4S9[I&]MN8'IQ6].'S^##3 +SU=KWKG>C^5VOI4ZBDUI'DM8)5?;3NV2 L53N"Z'RBM2/RZ]_QV!#7=L I*MQDP +^_(LGKV,DL81QFLR.]YEHZ_TLUWW;/.V_")>8=3,>Q_=#)8O;4OND=.!"KB?91&+ +:@P)@0',%[*XC;)UTE#.'8W!/*QB6,XOTW("5#&NUD$_95'5OH:2@=M'J +GD:)&P?U5*X.D[:BB?S/*GU_2/L^3*3+=_PF(^P5>PFX@%E>3+F-.KF+N'OT_10^ +N_3KZA7%6]$&O\>+W%7! TJ?'FTZ4O/J=TN +DTX)%; -TNY@-F'CJI1P?N[]725^#,F)N=,6N-];;'&"$]>=K(_&AFR[!W'(O%D3QK,H S2B=DZ,.*O5?=]-Z:='FQ@_8!?B3 +:#KH=EY%D7?(+N22-:\8="PX"J.MON0H>3%@^D/_&^0;(@;+CL!B"Y(_9GIY#>3J +&266D0:'LT.@TM0>55(]5 7P%(Q@DE7XN@.M:@/3R:62,RB.]@E9I,QCBG(<%#IU +A.X)\^[IX:!_88B,='-:G.Y.J]RE/%[!SNG;*=PBI /R!2#V.YM+@4S!R&Z;Y&W* +QE"J)QWS1WH^X#@J!#3<1&V$ APQ71JA<>NCU+EY[&=<; N':'.>U52O2! +<>71W(;XQQ/XRF^"*M=86&FQ$-&SA;[!8TD= +V?4S 1UOT"]2'"7BN1Y=[T2ES(@\$0LS=X9FBENP;<#&W!,8%)?49((L +%0.4K7"#M<\ XL)E$M&CXX5WL%<.VR;.84Y\6+P*[ +5 164N=*P&,I@TU.JE[LP@K4Q,_!"-JC$F=B2B2=S.T^ZF6!@\J^F +/Z2J_ +B)(T;Q-IQ_0SB7/4W[P$Q%7/3/Y*/5@&-7@-6& !P X,B7B BX /R25ZK@$-/PAQ +[&'DJ]ZP0TR!BJLDWD]/N6/0AH_A S%&),]&P*,J.-4LG/CIS;<"!X07_@ E3!S" +T;5VNQ<7.MNL;MSGMO4QYVZ1HU08Q :O*U9=<*330.Q_.Q(#02/++AAF]_TO38"9 +[4N5$^6L\?$-((/6LS/ET/I^?C003O[#;"2.@%LQ/>X/?/'PCT]"*&7#'&#OR\KA +<%P+7 +W!/=,L0D4!S(?QVA+)QG +)^Z3V9&D7Z3I$HLGI2[8<#U?\+\@=D-_WHOIC):I)6'6@3!%+7#OF,S701]8=93O +:#J,(8LQK-C"4ZZ=3U)L9U86RA>\ 0U%0!^E#HZD^[D NYNAM8@?4OEWQ4D8_O4HSO +6K)!,68+&MC-6T9(24*R!YI:+)@"&4E.WHD02""R35E)DHVY\LR6 +A5O'$P38%0T;SD9]O 8]J6:#VA'SK>=!!/K*(NE:Y71"/2PM+?H9NI7)P2V$!H'G +-[8G+6>NIO;V=3X*LD+-Y6#JOB(+/16G8MM.5THI[--$YYO<44XG8+)B(8\F3N = +89H:(U?'EF1GEF!(R#=I:B:NQ14I]0:X0KQT,3DJ2\:+.NZ-T?,0 )"GIT& R)77 +;7_\9"?6K4_<6+!,X.[W30\2JN-#\^(&@2Y9;#7Z :8Y<:[$1U/"#'T'"XNBOP)D +. ARHF*#0?5CH!8[=7;-I8B[RNEV4PX>B'XMXG]]$P9.0H"8CA$V9E$CF)PXJ0$> +_#E(#0@\P8ZP"%4$ZV*L(5'"0_X:(QP9@^$QV?B'\KG%1'ZV^>-,B,E!RSY\_O6B +4C94J+(Y-PK1(L4Q'CM'-M65.48(.N$-.-D! ,*H'2"@^KMS6GRZ4Y['WBQ!>":? +Z+\C+%[FW]?&.MDK4Q9_X57*,&>V9CG7:E.>#F;^-\1NO)1)]K;U)M5UJMP!"'-T +.\Z+X>6*)&G$VD,7-N^PXHH+;GB9MJ84,H@-LFY\L"_A@*EUME\EM6[;H34*)U+. +._."G+XN*R0Y:#)"K<;L34=/X"C;WJZ.UD2A)S?BJ)G/((*^XH8Z +!HXJ7OX0#'$J3Y:Z//4SB"FQOP$TXJS&MJ?8^<< -C,R A,>&W,WI,,VO4POI^#^*+UH3$W.8!;I3R,%VC<_ +QX?X*KLQ)\H:W3Z,MK(O)V&FNG]D(/Q14)X#_76JJFU/A1JK7!0/YYEMUW"S=F?" ++>4KM,J^."I_L@S,Y@$<6>>S(,'15&"A OON!VFSG/!WI%.(O0@@1([ZF#Y?,9&8 +IL88(V.Q>"WM%E1D.Q^JE\T%U\Z25N/-]3B"I!A2'/8/5OL@=(9U_G*Z/ +HC./5&2937;^-M).TL,Q9*^,,IU2H/]WW@^2=PRMR;E""9%RM5 F\('[[T&VD$U- +G9G<2Z/^B#!_//$GTW[>F!=5P;PL($"SX6AFME [] ,]?CQMW#Q5@2_GC'0.SH@6 +-CI&<-79]RG8'$[TI04?N7:B:JGCJC\FD TH0V[?7\/9\&1O2=E VV5)P(^X>@R[ +839 + 88_?2"+Y$B.;I;C4,.>\2C&B:MO\/MLI^"LL!_^2$6&&N,T(MC?;N+86UY!^2O5 +<&*Z%,:&N_ZB"9MB1$,&(E=@W]/K3N96'Y8MO]O7H^_L7:\\GJ?CR 1TL'H)D]*% + >I8L]AN%7-=*MQS9-/NP8"^ZH@'*@TCZ4G;EN9@%/Y]==YTY)%Q;]0?_A$3Q<\B +42Z>'I()5VBG>RFOX/"[@,%>X<:[@2.2X[O)8G&'8RR3GW2^D%>V8/.7:9"@8514 + 'Y0N6PE>>5C03JQL@S=Q_G.6H^"PL=516XZ,9]%Y )8PG3PR:@D8+RG-OA5MJ)% +N@'P(AK$F6@ 6*%,8-\7@OB"3>:F-:Q>3H5-[;H&7;7%8[!D,-,Q%(&L9E1>QQI( +FOK=^DOJU>((H^1].X9SY)6<)P8#5ITW>"Q]L-\.V\\IC;Q2I7(O-_;^3UAB^?6] +NEU\% ^3[NJ2_9&O'^M 4N:<(QQ35<'EM05 6,6(3]GV+G9FV1C@W&I^0/*GMMRI +N,D(58,PE/]5EW5,V3H)![SS;:>29NZP/\!2Q&Z 8CY?-I*-5S:U6N?0WK.4)^8N +JY-O2(E^Z0)JEEDJ1NK>L@(/@0^^ZQM3@2[UGPL<3AH9968K;XN!HNSST$+QF^=K +21;3WE9,:2[3P7_G<2KO.])P$]MV[07;^6C)2+A*K9"-\/OOO(J$45HB(S;TJ;E8 +&T(&SQVUJCL$]_SF7'PKLG$GM-T2D5!AS[F:'Q!O,P%(&;"D,P#QI7?-U]LC4+5&YQO)4 +_$RHHQX%N3RD7&M:NK.9*Z/@\_SWTIC68X1SJ;='@R=QMO1WC_BD<*"FN((6= +W5?-1\,9!I+<%3W&PQ[ +'&H-5,JJV2*L!9GH L].O3F,UP\ =B%S9/Y!]4(N7"#;\,G5]*_),?V)]&R#+G6. +FB$7 (.I5$&A]BJ2_N\1'3-DM2$Q&JB5TJM^@:R2#FA(2;&D+7#R 0J*C/B.[,R^ +. KYQ]K+\^9,!,U(P;$AVZZ28?K +!3PU,M[]Z,Y8':DY!9=SGU+X^:O6IP*A^@BGT)1]RA"XOT_IW((R](U*Q2LGF#;] +I7S36>A9X12=JJ;'KKC>F?81 B,YBVD;B;O#,IHN-8<.J(<$9B$_!@FH3]+_./JS +T0J)-AMQ2^NM7B!6\J?FL'ROZAQ$!D;_/Z@S/_&X+SP7KULV_\.<< _3-> YZ_0V4>]J'F@":1OJF=IJ0 .0FZ>&E5^4>K@ +8B^\A))I*57=BC3XPE$9\K!+Z$%GKPW04FO'^^3D ;(]P=FC/O5\+6YI=IE1SY&> +5N'3$6+8R^!4];>=@':Q5.-%00K# ('6.8?'#2HD^#X^+3>0OL0C%&&S!:7+GL1!,>_FJFS1*LRGDD,W^C@+:@/$?RT)%A&4D\?C +6#ABBG;,6Q#3#INTY3[[8!#%FB"G=\K6*/33J'?CH@YA0_0J]B>:41ZH&LFJ&:N*J!,:H&KF0<50\:+0GYJN +#G='':K#@T?J_2=KBZ :'=:E)MU/<_"(N"DZ;AEE!!Q%F6"7](.F'9;=KBTQGT^ +O_&4'LF=66[-D[+I0"G?1TY+W_37,$$,VPW(=&S99O(_I?8,B:#L5#;2X8&LHJ4% +2F;YU4_F(B2D5%*ZQ9___^ED:V/$3;FL1GCSI&_A'=^*A!W"HSQ]&?UF8G$Y^)Z< +975?AP.?UIXO#6-#['!#!,N\) >\"8^3-XK-'/] #XE&[D;3IS+(*<[TDPCKYVW' +?T,[<_O@8*\M']0JEIAQA(8O/']?BFCE?+-D(V[YU +2AA$4@WQ2".OB'J$HP\P'Q7P0@TE]$3"4*=TK17#I\A3]99=]3F7[]L16H#T=(>@Z\V)*KU04>(% +-Z$1WC,8YCXO>E10P=BO9:J=,LBEN[.RP@N0Q<-M,@:!0^R8A7_IVD:!%\D,VA8UA?HO.Q +:;9G1A5W!H:4[DS$KD#8]".X/)+(TEGYL'R]O%*J<(MF?Z5Z;NH_H=E2 "9G[)$I +=4AX!!F^>-AVJ-H6KL<#@NGE!*>$KB':+H,5+=>M"\#;_.#.IGRD=\3J;OA1V.CD +K0IZ\?WT<%KE7O%A#&QDP-G$D\?FK&6.$.\IQ9$GC&HC$W3MW]$44I-.A6US1TB")Z;VGJ.5V>2]8]@&BT1[4L C3A_%;CXVPB(4SMXV!IE6= +3ZJ/E8VTDWN!:J];=+, .GDQ2),4CL*JKO-)<$-W!$8M.PRYD:'!@B+R]>I5VL4O +?X4%G]F/_5TZ>9A;\T!G^#G+"B:E=[4.A-S@>+YT?]>>-@/8 ?64K/?$4FX.\BU] +3SA<#5J+R'4*./0W"/AQPJ_-8S8(V)N5"$W +,?2HDBIW4U,TD\0?Q/RS=R=8\ZIG:J1Q8^Y*[VAI,!_CMFY,MKCX[]CY:=KXA%&7<+SF +""X8]-JW^IYD9HAVJOA&9M]:JI62@;J1UC@P5(:+O64G,\X6*7J +.OI/DRM7_%=]W$"[E.SCV]Q6;0?"\HK$O4G?A=_(2?+1H';KJ3]CA]-ZC.&2B*2,AN"=992PUF?#!D +8M2CR[L3DT=&]WN/1L_/+7C/X;^B!Q9.Y*,X1UJZF.$:=>YJ9_'+ZWAXKP!S[=+LB76E KM ICR-08 +K.TI<]^LYZMHT#?0[)"[ %_:<]7G%W:+Y/&EF-W)O;*9-]C&P%A=[(3@XZB9II*: +8#WD:_N\\-C?%NG=8W"?/:33^+TAN1J>Q$WHE0YU'.[:;DVF!"+K^G3O2(=1K\JO +*X+EF;3H$,99C&Z\=FI_+.)I+3TQ"NI(3N:8U/IA&U6.B$T5X&&K=A0C"AE\F4)U +NMTW.@OK!$1MM@A&N0GYMISW_'')]%#8=(;V<\O61DN;[B>F4[;#;.3N/$PK]R\% +H2AO@@)GWQ8'2M:_+_=XCA;E4(Q*U";4%7V #=?N<;$VU@K2..PWNX@PF,#8 +.B(L+G(VRO(X+6G@E9F&_?;M/! ?],!*9[7<(K$.#X86S$/ L0!(_G8UN#27DR62 +^PA,2J;QA770HKY$[@I*(MQH>/QPO (S8K)T%*$K,YLHL-3;;;%4?;ZL;*2B0"3O +-ZOX+^&V4;P!/EN2&H3O,O),,2N(I&;-__ *IT(,=8.\]*WB)VQ>$KQ_8]5<>E6- +>GLD,LJA\T!,F8-CYU2K+^6)_]';4_'"$Y<)R?'%FS&SA'W5[(FYQTVS/VG'CFFV + Z16[I1^7N=Y](*>Z&Z7HKBOE;HB;Q=LC;X=1/.09D&[M%A)@24SYGY@$WB67_X@ +\4$Q8\.G(N2]K"!6/0MJ1^IN?D&O8)/=3%MJ; > DB?!LFV;6113R+!2&E-NHRD; +=I01(6E %3H>,RH%">B$X#-RP,82E%CCB9F4Q#PGMRN#]O7"NJ-_QG5M@O,(.A84 +*0+Z!(AQ $2] W$!EX\;J!Z3PZ8S9Z/W/Y*-W*_E?:/ZA/)+YTU5 &*;5E!?]1VW +A%)U!M^=!#D$]-\\Z0-#(I9H1[A1YK/!C ;<%>YV%5PCI[S1M=; UJ1-O<%-+P;/ +P[<)8P+F(,BLLF_8': NHW#YHV7,4*4SPM/> THTFKK08@MX \"9T]=-N8GW +\R*DW<_PQ_I+ BI#>2)AT,3/55\;.^/[LB%?FZ(XZF Y/]%M(!]OR%VYR>A!J&3F + Y-DF8A/^L]V^L;.JYZ$.?Z81A/P>2!R_+78B/O_#$GNS/3HPYD.$JZFFP)_MT43 +2"^ S' 9M0#("*.'V KN_2#@U-D_=(/:.FA/S=GYFEO^8QV-(O*P B3 +RHY9*@MO=>YCBDFF#C<4KASKQ%2A]8>J- ]/&D19**\JG/;5M[YVGQE4(T*= +)YKF-I7,Q8>(*%J_O1(,\L&FBJ2S)8!#9:4!D+GM W )H;, +5R@E"',OVFLX8H=L(\*I+U"A1DEQB423]9V[F-%O&"V_)8]8?NY53> +7Z4AK[3R1)TAS0OLA&:_MGJ[^C%?HQJI+0HG9) GF$'5K(O=]%&VCBMWN6 +902.5OWW3-6*@?S*A5=MOC(%U=A;RH[;MB?Y2[F2HA/I^R$FH1E"51LRNAA[<*E4 +)>B@:?;N9$ZC@63CST[**U+[7)@ZAP6D\]^J62A %/@APJIPE#OO 4K>6=P*PQ,M +9DG=>'GD=6+ISPP;H*"G:#,Y_"G# TVYXI4R9B'VWIGC99J9 JBH>7CJ+EO2!2\Q +1H/5M8MHTN;>Y45!S\]!V8FK,=JL<3[;S@RC)C+!]@%P#&^+@"E_,=ZMDP_RZW34 +:L?8]9>_1V3U50Z()F#B(JZE#?P+L".N:X/"\V]7"7[DI&N4ML:NH+NED$=\ +IM_&?'9(VUYQ)Y[]$6,S"->1_G>)[NG?5ZH!(+J4\'+CB8T/-6_ A#PZ45M9( +A="-(!&-0JTP7VJ;;I:%FI?Y46!7"?<^*&N"(V&.S<2)A J8^(/!]GQ$HQOO'_KP +E/CBNJQS,]TV"(HF[)K]+F-+!.)!JE"I! J 9&&4-:URA?^AA."$RU:G93_5&,,I +F)0::.1BPC.QLO\U>,&@X\/\_(:;N+Y\:YH]:DF .?5^F0\J%U$0/;R3-FWZE_7O +[&)*IFUTZJ22T)42DN>V"@3M/P?A\9 B76G=509"X26G477 +-@DB.\#+HUTC+YTDEANA:H&^#U8JG5X*'[C')G*8WY!2E0>#4F2LZ4.RA9AV4TI/ + V5 "('Z66KXG&JQ]H(B@=BNM$YV I.J'$J)N9;\-<_)OPG<>(I;B*9ZEH&AI1E. +_8AN %TPSQ0[6Z*(6Y0 >\0RX#DZ;0_T;/B0QT>5HY,V^$/0*E*T9C*;9RX#:"S+ +D+-V 8V3G#\M'GAY;A;+ +DFW\HB>!'])#X*9H9$!R57#OJ_]I*UTJ$OK(.AP70,@@^G2YOBZO.%=1#2G4,#8# +.RZRP9>D24>( L*7L$?@QJ<#M)O;5^EX*P_5L(EJ/P'F)RHTZW'("A)1D+0Z]TJV +NKJ?P->W0'^8)<.&VAMUPB;VT*S) -@MX+6JC20?56/IJ-T^L#5BPK0$'D&#?'@* +HW@RLP%ALE$4WR3@\2'^04,JS_=D? +D=_N\6HNJ-=G;"P3X6#9.LFB"/R=H?!38-R,)DY4/".%+ONB.Z:A!YMXAW;=/'>9 + $RDE/M9#_A?DZU%AS<9^V(& +.U]#W&1RERB -=@^UPYG\KVB(^-1 0*8M Z28XB*L,VM]V4 H^;BPZ(_W&__L9(>V;7$VO29+0!9[T$P5K39TE'%K"YV8T\YZ8E#0Q&0FS$ +U.8:^"@F1D>5GXYH#D=!X*6>R;\X47AF._B9,O_T?-E:8K"3GG*O_6P(4[=P +7N"'[2&^U?MW>V\,S,<6@7O:3(=!I*L+VB&D!B(X'2X@X?:?[JE:AY\-(S"O1FNP +.EZ ,033XVSNPAT84F%(LZGH(.(:BC\O."V!37K:XRX[D"5<<6AQ2J&U4' 73>GG +]![H-^5D.XGG#::'HK,HD'THZ+A! U B3._1/WU4RX;":=^%7*=D6NOEXZ&']DUA +RD+Z8R\F*\#A\E36A2?9B/]CP,3#L2,YH);_)O[PMV82A$$6.(L\ +4-F=@VUY4#9''4\)E#+FBFC#Q;YEW[I,34.T( .O3@.ECS1#'5BM6_U[;ZI>*_@] +;:6[G'+6QM F Y>S"K"4/D@9J[-*(?CQMQQ$-6B6:"#VCN'/X1PKJKPT!>6!'2C_ +7C]U<@.]&K'W87+CS7)\[A\6=WWSV\4PM_WJ@;9"@<\//S L^0GUBQ /ZA1.W$@[ +^4/5HDUEA.WU79AYIQS/V=!*T43C 75J9,65&7 +0O (8UB/?[]L9@SD4^*P3GR7#H193(C!>BPWX5@#OYD7/N6'&V@_.DD:]O-]7W!Q +.O2.W=,5 JLA\T)O@ 7 7,M:R(YPA"<[TG_&R0]8(09^4 34KTK3F"2FA-WO;PJ7 +N= U4;THABV74RK[0U_-$H*IX\@?H*-D"+&\H=Y#>I/3TDT2B*ZHB6 3Y-OJ2A"G +6T3*3'GG2MK+4J8V3YL1N?;T@HKQH9.A+&9/T&%N+/D@KF,N6JI?1 Z[N.LANQ0%EM_4U%+%UB +/C4Z,=;S]R PG5--4^RIJ5-*8:2F<8YQ^(-:\R/B+4[-3VOT30':-S *^U8?]4>!]RH)NUF4G4[/ +7-G2GY>+^@;3AV!N[\"DW*6+Y2.C)=[Q6A.%2M8>G;7F+BS,?7[*8%"_7OG6W:U4 +"#6:P,.ES!&LX.,#Z $E4$%%;K]A2!&5T-"X8Y$OURN"L@BB*!C6VKS*K#/-M!U! +'WD? 93L\C.4!$[F49[F1'/%DFKPC*$RTL>WQBZK)LULFCC5 [ 9G?N1#E.9LU\O +HS .P+;,__HS##\YVNS*29QCL_(Q5?0=7HGSYURSB+<'I(!BPR&%0(AW7,JWAN(V +;VIHWM_%=X8-/?W]' B!DYS'FL;ZH +U4S$7MW@'%Y-DGL:X']X@0L!IY&&'E?5W9W/3K?C/SYBLN589LTJ0L: VO*5>-;3 +B%X1>&M\3H'D[=:02-#%5>]%K*0JO^I=O0';PHS:@0_1J#,%S40WCU.>\#&$[-' +50P_B%MKR(M=0QYA<?J$D[9(@=/5"6W['D)]BKU L.<^_1;?3GMYR,LZ +F&KQGM(@WGZ'5N#2GU[CIDA"\F2=4X@$R2B5GFF!H#-,&_)2^#.TG*H!69T>.9A6 +-EW&Z-A-NWBI3_;=<@Y:,RT)[7A*\N!2)[*=$"&PB".OQ&N]AN3^HBOCW5X.J^/" + 5RL+6["F;.!YE3;>:67IHJY@P51=LS7/KKLF;5Q;R!<@6FI41^904NBW*L?"+]= +>6 !'[-?@H.M!UNFE!;&.KASJOO*5']X@T.LK%+?[DTKN2WW/MA2V4"266'W_7JA +H?.]]".'Y@2R,&5SXW3*_R=E? D2ZPP8QF"R:L6K4"]WBF[FG>W6%E@AI +L/6V.F0BE(L=$X+@G,Z36\8A-QA:\]OKI]/"F0W25,I:^73S +JQ3#RV3_J=VIN*A5> "E-"TTNG6IG[;M/IPN(*,@L*!C,2M0,KK:%A@^6Q(-.$S$ +$6BY(JY!RC]?A[6L XC KA!ZL-Y: H?TP>=1#]G%F +TXF1D7+;+?G,C<)^6TQ#W^W1&9*)OQ80<#1--K'P6'R4M$7E1D%9931][O5 +%$YEHLS(PO+*'T$YA +:&-J@9[Z_!LYVQ@4+;1W/ZYIY%%PF0&B'(=2"8<#"V %RJ#Y@S5C,3-@]P_NZF^6D:"E-+9,_:B31ROB?:V +#SY.7@]W8-\)C SQ2+;DRDGXEEH[BU0(<-K]9>W96_GDQ<*H#?R319U8)?CF3A:5K+?R\C!_$?P>Y9_;>'O)/X/UA*_@)*&W[;*711E*+B%OH/\N*MZ=H0"M9?3\V:V[%*<#;;#;@V +GQ]#9"[I[N\QP#L34S>L*\,^5$:YP=V1J;8 B?>AAW@:Y2/JO6ZQU55O B7NKE,J +*-K@Q^T1&V2BZ@\>C9"VYR.7/6WA)UKUL]Z]2&1! 3QJ]2U)LU(V4+0.?/:^4!\K +)T>EEI$ W.)3-5TFCH/0&XEU >/\A*K7R0-=20P2Z]_1T^-(E;6&IZ"K+V;5NF/U +(%GGIBX\]?+P5R-_?ZZA:Z2Z7E32 0P+UQ4I/XR[G_XS/^JF#@AE:^QRKI=O +MZ']IA]=?.(YHIB-%JXU>;=RV1^+N -G!F&@ 0X[(4\:-*3>VAJ$006CT>J=1P"A +H>Y[/K?C#F< U]CT$I5:D$CS8>30/*5O@7(29_&2X,+H!(KZ%$UW2O/G;]L/U^12 +7)P!V/Y*]GTVX(K%D$RK>I_4(0!MF.>ML,V5>K[ZZ@V?S\,_PY!_W 5[?_?@43]E +"&B%J<=UN/8MEW>8$2N\ILDC!%%N%!2BE8HWD;IS+ +15_G%RJ?TVS"I7 HO,6IDMR6[3Y]8*EAFZNI_YA>#-QR1 7AT@?(13P /AFS/""*#!3,C5Y-UU(Z7J=S[%>+<]S58#9K9=7B)Z^=C +T4!93%-U07)5;'*.NYWD/(T.+;CD9#A?EMB)K=FUPGI8K%(07',J=K!YC$5K&%\G +=.3]4M*>]:2B!_P;F1L8H&G7,<34?KK@L 8=@9!9"V_L4Q0Q_0+=C1.&D"XA3GH2 +*3F$(1-K)0Z-X6QP#M@9 +<^VQ'!.J@#F?*'*T%BL0(=[K.&8*'^Y%@2#J"W"U] +8$.+ "+/BB+"-&Q#(B3#OP4ZMJZS$XUFTV+&]8)[.OC7 )Z DKC9ZQ1QD=L"J<3[;@BUH15DD*AV)YXVI!-.W[!>WZ#Y&'@GO1Y9P6-F\7O.8LO<%>WV#Z,J4EC'T59N7<$8N=V+V;!=3!WX;G[SV#%9:/I +!VGZ-GI-\G;"82^FXQ<>A#(_*F5,PO6T>(*OW%*KM#/""J5+@8 _Z7ZJVULHQBUB +Q7@*2E5@TG/OQ6!P'/VI.>H84K+M;GH'_>#'E +*X#W9*.N_P)XM<*T0&>^^&++7"Z=\^B)<#G=\ +7,L@H>A)W'Y]WB$L?%4?R$L&TC5E]S\H:CTJ2ZN)3[KX,#L=@=;3(TZRXU01<\,/ +])F)#H7=^)!_ )"3;G4&IV5S)Y#G=Z(LV[/N:XS:4CU# :+#S/>*0DEGM1\.QI9[ + &0.(@T]X<1QKC.(8TCN$9_4O!2$VNE,>S+.R2NA$-L3M;O5 F+KY++UCI-R_Y;G +/#[7=G'NU_"V U@_>G=GO[.IE&@R^!"GDFLKK>WE-I_9AISQ6ID)!R$ +R56OA/)@=ER%^5>B2E[2DW)MX1U8E*?@/.QF83FX'L3&:A39\X#BE$DI)J(C^*15=Y%:!R7 +)2_0W.4%@T$RA,!VS1'=.1JG^URGU0E)QM$N9L8P,1G;P65G/*VIQJS6@/WV,"4D +O#I5S,9H1?\#42*>"PUR7RZX6\=#W/0^J0\V8Z, +#X-%G[91#8OV9&+&/]B59OCP'7ZF&UC^V-Q8^)T>Y%#1>ON11(%JC*UD (QG +4/[XE3B&Q]$35OQV+,]J_9-2HU$I\X\G7]L%8I*6[ +)=8\S90C!B(T+C&W-^U- 4 #7-JY,<3Z*$R*U;GO+L'J@'- +BM/;A'S@7SJA5DERSH&N9QI!YMA:,\T5S3L,;2%QU(]^FP!Z5_(] HJ;A$)#88DP +:2)@:MJ'[!G0124]VF1>K.MF7;K[Q()Y3=XD?7.48/-A#1B63C\Q:TS)=X?6B)D3 +!$51R8.PMFB$53$T H1=*]49WZR?*3^ 3&'Q.D!P.T'45*1,[7&7L#&VQ=]/JR_H +[*%"KIR/&UWEM-I;,$Q&0;7E*%9]P)#1]J1%U6 EB-^WMQW[)-K!55\!CSE$DH5' +$EF4>;17%\.W/2ART_$\+P:O&*?E1^L4:MVNFH?RQZS5>4=RW:#I7^3N$N.S.RXZ +G_ZWVYYB7,/QWTE=6<. -9],$U9L_3,@HQKK-(8U'CEK)QN(DJL?@?_;XK82'><@ +9%C"! 09'1DUC_M*I\]H>'KD_&M,%F8$$O91HC4Z7JX/8!UR 9'GW)B]$D5H= X +;%(+X_K*SWT9W/N(I)Q8>KO[D3@#EXO.UP;:AST9GF(P\F"7IR"3A1$RX%?_% ;& +/D?Y<@WJ0(SU[ JYT9UQUX$(Q7K[U/-TIJU:8>0B FXXD&S8QO)EA=3ITN?A[4## +U$/B.HICZO(85 KL$_L+JE1.Y"X\X;@N-=/>M>\/Q04'Y9-PFAA\ +W5*PX.'YKPF*GD^X#HU,[J=0]BCC%>\[H@KQ88IR?EQH$WCX@WFT'-@D+C'@&B4M +H0]JN"H27A,G\$&(**T#!3(!2DRB$8D.+BU$NIPJ)*0GM=O)9*]DSMZA$WTCP6; Y4(N9/=^%_"D7B]OZ,(2G^ +;.#KI/L%N& 75*/1[TJ7#'<$VF2=KW]FO.L#[4R"&U)5 IAR."8)Z'DB=7B!FG^H +:*7 Z-G%8HRX*>;$I)=>L=M\$/:\!=9-6>Y28$'"QJWE+]R/;7^#Q)H2:W=[/A&C +(;.D(W)V)KIS=JEU=+I:@Y!N"E$(J/=BX4CUBR:"8C]5^7[T$6,.R00O)W3[X,0. +,*/3RO4%<@7:=#D3IJ$@([G^ YLMQ&^2Z#P9Y\\*\,ZDX5W!8&#E6T4;SU'G^,1* +^D=$L<+];KX@U!D%Z< PE+2*:3V#39)S 8&;9\Z&6]'7,IM<\-\=G&T%W#,E$3GD7\ W +G5;9?09//X^,V\9E<5IRO\!UJMT!JXM:27+(*M&<]Y08.SSOBA_SS)TC47SVXLSU +/L;UVUVW F#38=*Y9&;VN8,=">>' /MBXJWO %'4&MSYIP4#MA)/M/%_Y,/,]+_R +8VEZ3HX13AN^IV=L[MR84),B>Z67??V;P ]Y,9*.]=EU!NCO"W\6A4HN3 -X1E4/ +RVFW=RXA)%DKT <6*"9VH$:87'U'>:TT=\.?@( [$8/Y=Z<>*_,!VL+^#W>035;G +N>;ZLJ;K:!#H((MG_&@TXJ>5B_XD0:AEC2:+6KY\O$WQXN$U16/;66Y;)5]8!8AK +S=]4\2KP)&6B/B3PS#*%?R-P2GBV&/C<8V-K5JH"1=,?L#JIA@ >1$!P%+>#UH?* +.Q ;C%;L +=1E"?[MA@4"?P?2.K\M"NDZ'G'SBB5+P=2/B9\O4<\'"(CK/(EGXOAO90/S?YF;E,F5A8N"$E*7]Y,!XGE>(:MY.)@L2:8DEA@G]!BJYN1>EET4892*T=B5A7-LVE ++K2M.7;',L=T,7V642*6&.D#A'2C^M]':1X$^@"9[]Z#]0UK /*0=S*,O:9;IJ:NKAOO^/2:'LGR#C$O4_98T2WJ'I+*LAS#?9$V7 +)F,+E6SV92NWLN)F=PW'EA*]RD!M>-)886]XY NOT[U+7K]TO;F7V^*GB?^8E96U +0$U<@N!K62X5G>YFNJ%_-LY\L0*,X#=0V^BC2=[+T/#;%T"\;/*^NNA9&9-@C?#8 +&OQ*V$S3_+;[CEL<5U2).L%')>5[;59/2Q8'7Y']A$^09 4X@.=?^B>MW!-7DFZMJ+)INB_QD]%I_C9_X*+W;QUK$6V +._;K7Y,F;J5F22JW";+0C4&\_W8\BXWWB.:LV8@[C!OB!N6]ER/[<0YCI3N?/T3D +UBI79X<(ZY](4HAO_@27UP\6;_DZ:V/JM@KNA.7DZ[$_D C$T7\0^ +JKL8<0%=&7=1>HQ_P!6X3J[4DWWE5]5@+@-U'WY#Z^/H"#F%\UQ=XMJNHN;K(0=N +W''EU"?Y*5T&!C&F[7WWQULOP(N1>J">MA+8^S?KX<_S+GC*)D:"@ >]S;*V[4^5 +SV!Y&TPB4&"!O>Y#$8?/"Z@L_N%W&!98PEI!%;MM+N)X"$-[V4?\3VM\[96U]'/C +%=Z;VU9U -@-28;Z3-VY$Y20ME(]@]/DE[=!]%F"[8@;\#+ONMON4%I1EF*HWV_; +T\A*O[9C<+.<5F\3^E8\'&=G;\*@':B7@D'\#!0CF#(W.YI;[RI3[O5&^?JI_F-. +&])+D!&6"<;)2O0YLA&[JJ>G;F1H>-=UUMJOUOUN24YC^%%*%IZR%8 C/QW;X $^ +UOTORED]*+53"KC69QA?]]7CU*)QC)["^(EL=$5S0!SBDM8B@YZ4CB +9GA3^ =C//6H]VE])[X_%^U&;U/9834ABN?B@J6 K(B^2"?=2ET]LKRNHMI^H85. +:F\VHQ)LK[7:=BUX^ZP_"RLEWWMJ2I$D4:X(-A00,TF?ZTT9\'B54/*[AD(ZGB@= +Z,.+*;KI!]0*BV#U#LFP/H,1-<1KL+E^6=[X^N7LN!O,T+A\%#BV0B@7D4K;5!1' +ZL!F"FNG%(%$"0 +9TW5WH-QHQ)%K%'AN<[ZFI2F@;T=WXS%26^5+5(UL[ZS$#]Z=V +=7[+[T)Q5J"&% E:^21R\OP,;KUXA3/57(:T"/H,9O-(0.^T6 XXN3VQH\[4ULZ) +R>:)WO:Q >UCT:#9,TBU.ZFYV61\ARV]S).KS'XYN X>PG>Y.K@ +RZTD_+)07G\<(\1Q-Q=9[JE8,#'5E9?9!E&"$@0&&B=G:'($\Q@P]9;41MQR#7<1 +IZV.?SX_(%G1.B=%;O;):V^(%EGG"CRO\]+D6A*DXINQWS\CP,YCV=\:Y +; 1J5ZAW[P]BC=8C:WG3WL<"[[,^YEZU#*KHM2C68RCXT(?1L79/\&3W[4W1F59C +_-N:HI&0=V BLP)CDWJ74#MRNSD)\=F#.5(J5R244FM'CE9F 065B*4U\[6YK!=T +JG04NL;NYPQAMO!SVWW)9\$J/D"[:3->Q#LR_VHB)/*QIJ'Y1E^]WP0(\NO3PA X97,&2*= #;6P +XU/A_V!M#8B[HEN5/K%J"KS>2]RA(\:S$'+W +[K/8W +[T\*<:A_RH>S=4R&*!<$--EHN4"[Q8\(&4Y>Q[FE+7.BN2 #T@DTJ<"%,8X8E=8[ +E& 4_IDN?JJ'-1B^$,>!6!8FQ%L&OO++>N$2-&)&@>#!=+C;WFBYXPJ, +R^4@T8OAHT&D&^V-81N[&-F*C>Q[A\$I>'GU2P1"VE^H)16<[!J=PB=>^T%F?+%D +"YR0.20(8GS IM$%K939Z_B)B^B'G]EZ5?<8/R?0OT:%&MTQZ1]61B.P4K"Q-HNR +FQU:8]1U!49F,34\7/4S5N0HK45$++SR4+3@C@.9&+HO>WJ+^A?"$++HH$:%/'&K +JD&TD=W\\5-K.(DCQ= !U>Y5]W-S/F"\O'/A??$*YBOKE3YPXPC WQMU,EDX^@-< +,VMYS<'/S=NL:!X&4!S0$AFFFY8A/Z5:^D_QOQ42%%>25$2> +F30J,U?JT(1H>=S2*E%[2_Q.95J_S68B4YV[Z=Y& *[ +;GS&0L*:?53^"A&AODT)ERY,_!0L,)-H#+D-B<*:]+I2,\5Y'3Y5,47\ 1(S*K*/9":<] XGLW,R9 +,K2#JMBA48[O826V7^S"C< ' \VJM?ZVQI5N0SBD]SI MX^"7O/J_;.*=^&H8E-D<@<>HFL8%5N8'$5; % <;V=?E. +2G6-N+ GFI2;IFW,;?/H&K9&5:V9U#V&*H#>-"Y&;+0!,\F143_G?:GH1;^\+%++ +CCCOPRORHNU9'/)'@B8+U6T@=#&:HJ8RUR=E+R&9M6Z4+-\>@0Y +N?8+ ^TJRFK67^F-EN1DL]*F. +"2/][SC!D#6T,-TQO).)ARMHCCVPA5=/#NPI'[74B^-#B 2%AC!3",DL9]T?"^C@ +A>N7VY[Q'(!]8$6&Y*BKQ6/JT$Q**\$3,\)_R+&F_59;=!V+=[(N>5,>K8H*D679N^Y4(=LY>-F("1G'=^ZP)_<5/( +_5O>#/EF(,4IF1N]KV'K6M3!"V>-=6,E'.>R""JAP 1&DDF/R-/VI%]$9FW"T&_Q +T>W4\H6<@44-&9"6;J0-S!2V"'UY1]K-FCGY^D5X1Q^@ @UP0NR<@&V8&^Q#/(<=6F<#/N&%/@(EI2#3A6^2HWHILPR..W');XN5>?!6Y6NZOG(J"QR[-BZF.*(L>9V?Y8\ PXTK=EG:8J_ +-!&@A]1B! XD1&Q^*9%=9[V2 +%GDH9A >O-> 9E1W/DI\62TB&M(+DJ=4Q'LR04?H\9=UJ(5@]#>SB-&J67F(&Z=O +F\ W28ZW_WX'',O<[EL8JWEGJ &X*FATENSQU<=2=4/G:G3IJ(4Y*T: +<'AF!QG263-Z'!6@9]7L(EQ+<'I5?F^A&-QN8M>^KA!..A/?>,=\V?\OO5;1A:&7 +,F62+J97H#-([-/G:#C9+.$$F,+77JF+,0&Q7/ $$2-Y2RT6)F,R(&JY%=$'"Q? +I.%V#_1,EF6FF4C[9OBZ;T*1=O#YV>SAPA-,X,0-G^.6%BY3Y8\:R5$UL*IYA6X8 +7(! ;#R+*;C:IX1F9S^U,B/,\;]_GENHQ#4D:Y?(EP0YN^CKYXKT +UBJN[5.?[SXARJ48=JKF(>\!7BAQ$-QLAS?47"26G;JC$6+$+U=+*__(?%,LAMNY +8V?C1?9"*O&:X')@ +E/^L6_(% 13)=R^<:-I@4 Q] V\UG>36 /\TZ@)EE##L$*Y6(SW_U7IC[@T >T:R +5U&LX;[+V4#LU'I8SM7<:TV40D=J#C-5=MA3_[_J]+WSW7?S#)M4YDV)B(9<5;L9TX(>U +=7JUC?2T*(3<.ZHDUDYX[_O^8Z8EDT:8M++^&P\8D$.?CLT-M)"#!2[O,-)0A;SY +;T!@:K?#T3%FJU(>/-G;)>1<&QV;7*\EYI2[K*CY0D]3;(R) B_YBZYW)^\N#++^ +>DS'JMX2!1SQ6N60( Z>I"MQ8CWI7X!R%2N_U%1Z 0Z-?[2B7&NPG]K<9+N64 8_O>Z?F+TR.5-^V+)DVW]VE?3 +;LL"!6=NW?R_YA^]EF"))Q!K/L1 9T'/F'+[+(RY(@/(JC9O)_M+?6;:$ XX)=#; +CN4X4FU 4[)9J7$WMW38"MH0JI-]M?!"P7'@5M\4MSVQ+(R\MR&PE"J-216O]"0V +:625H]S.^3$!)HEE<215E6\%&Z4[&G9A-&V*M6:^Y4B*AXT-Y8>0"DU?3&M2<@\] +BRIW4?CQ0G6*.J<9$X5;(,00\/P)$"BD?T +6.V=Z9[DIP^_-%RIN,!ST\8C25G#&U[74Q$S1=2+SG*=5( _QWC3>96W#9CKM-B6 +3C)Q3>\S1(A*1$KL90W9 0K&EZCK#^/XO<1/)HX*&>>JL&('TX(ZZ&U!A/Z1GF=R +4FIF)0F+<@<])I^&U]B_ AP;76/(3"V=IM3P3W;"*'T>VDR?JBFJKOZG3R140^;" +651!B#AW&ZG5M71BE7+ROZL9FB"$9'-$;!,#-']P\"#9^@>YYCZ-C9UD"4%Q+@/( +^ ,XWIS]IE^KH"W=)MNM9Q=>X;L/I=OOILCI&/+&-U4:-#P9U2S%KM(?= T'*WN: +[@*3O-8&%T[?2NAZ[\IS#0[82]'\V]<>'+)\SCX.TBJL=#5QY,2+CRW+M-2$9!B?@<2.Z0 +O!]9/T]I4^@$CLK5GIX1HP'UD%Y2TY,H-G"9Q1$&(9"8C59.KK2VV2S:@OG39264 +VJ9>+,U>+<+^+3TFJ0A"9_&]U6N#*B/Q;5*PWLH+%&HSOOV,GB!.S'DY4;0;LQ@] +Z(JLZ9V!>K$ Q7Y!3*-@V'']>"[XWG)C88N"MUE*(_@798#&!FI_!N:CAE"FYS*] +KQ+TT%.T CX_4&.-Z!1Z5D OD/Q7-T6Y*9ISW.YN+07XE.4JWSZ2*C#+I^FF-S8: +^279&K3%A^EIFW; 0)5=+DX9W#=((J8T^$D/+SJPBV!5OHU)VNV!P2471]> +^4AU@3-3(\C O3EL\V8TBDA+NC&MJ#PE6P?HI,S-H'D:B2+/\NQX]T>#0XB)YA13?UEJ# PO3.>FO?(\"V+0L?F@:E4@]_ + X181N39!8\)\__UC:QL)*0CD_._3:)1L@OJ1 W!&SL+<-3O(/]<_^FFGUX[B_TX +D?148([IU$O3O7:HFSNYUK@DS>M_$,NI>^T&%?&K6B^@@\DZ%HIC4S:2F3MMPP5' +2';NM 3SYT4L8PRVIE6,W936NT:_3;-8]K#V2\CN#U=P\3J[H%@$,Z!GZ.&M'A%V +:XP.W#J$3<'/HW:)F85P?\PY.-SI%T RFZXJ2_%G1F1DPZL+1'=KAU4M3C.1 +7YY8E]H*!9YKI$[:>XFE@+!(Y.)PDSLE""WWX&ASE-/5_C08S1\/ZK*'KNZ&7:;! +4JD]GJ\MNAVWEI4U6 D(NY?\A>:7R&I$M;)Q03> ]Q<7*O8QZG!P$^/ 7.4 -_=Q +],9MU[O@&>'ZUF531QN?8GL-(0I71DYG.7FILS.:^WXQV2 +->V'M-;41 NA&_'5I*F=&"1^=U"K\O3HH8SWA4>\VF7U6$45IG9N9M'I^7Q*PT"/ +7U4GY!6)S4!XOAKJU!V_\!O.1?\&Q;[@/1@05'&^C=2++*##7':56G8B;B"%"8LI +/6#,>!@J.1(GVU^%(:!-B.OF*.C EQ/]TUE\5NF]:I)GS6>QJW\Q?FDYGP(4=%G3 +.BCMKP_4X0<+5RXH!^1,7KB\5F%/""Y97^SEC[:I&YW&B9'NC!XLJL7Z2]!2:'31;-Y2.+_+I;;4:1IA!T4NBJ/1+W..^5&G)5I1E7/.&3$[*&J +A0Y,Y-KP:T3M>^TW,R@/TJ'#:5ME@MAY<$)\J*+=I"N4@AVMKUD!.P&5]K(I]+3[ +5;H_,,"AN!NU%H"Z,DJ]1L-;_6=.HOYCR=R8092'R:C81@6>]-(KHE++ZK%A::I#-&%/W)ZCA@'4RPU-O31?- YUDERT03S6^Z +?DDUSN_4$=*)8QO\#=U9/?UU698F(F,;,=&U*KY##0O-@4(?^!;EY.FW[$U<^6*R +F)D"[&):,,.W_HT]$*+])79'B,H4/X@]ZZEX7S;)"XR X8KK8=-;B(?'0V/(;(=. +FE,7?8K+5I)Q63B_FFHL47Q_X96\[!;728O/*:\K=)T^1H16,2OR@?J5S?S8ZAQB +E%J52/XYCQ%'ALFZOZ)*]S+3AND^@=_"+S2M:1G2,W)QPW=;G1#=,H]]89)]0X+= +<8OCS(RRL3G-#[ \!0%[*QRA!=7V(W9Y.P']4G,RJ"@\D&5MK6PXZBE8QE+RYQER< +?'YP(&Y2#)G<+&-)<+#3H]U$38>#X14_@#&]?:G48"]2@2Q+<$!I63?'JJ! +NT<@3-JPH?T+V3]#(QWU%ZOE)B*:44%TFBXS))2#%"J(1,&5[,<*.(2RSM%T=^:3 +0O[R,!XT"[)E/B\A,9_=T_8M9F/:BF?P '&.9Y'/>V19XR#9G^VL+7.L%W7TO 1I3,18M6)_(6)A*9##0&_2W7K[JQG^4J .QT)K0DX"1S +WA7$^&/\3X6Y;]-OZVUDRM2/"S&V7"DP)39VY*G23\5=YE3V:>,4&&!Y"W]P8:'[ +H/8&Z^:+$-T>[',@F14I(W:%+2X/5O#/7XOYK^)*V+#\:3.A0(?BGY^(MO."(85DNI ]? +G?X=7."AK-6>:="H'^U":5HQQ'+"I?@WG.GW>+7JOEMI6.1MB5_7++EM!IL:*!B4 +$2F(&T/:48 *H?$9+#X %I."?KBZ@IP,"9$5?/-)(XG(P"&Q_@U7%,8J)[E)'JA\ +##Y(7*7$SQ(?&8>GG&GSW!SARK!#-7JR7=.+&UN!G:Q'P(*^\ SC=2H$(WX>B"GJ +E4G%8?E!.S.1].4'9A<[7B3;O_OD)NCX@K&56(I#E[U?3P;KYD'"?_0_, H*JM_6 +[JJ[5VLSH//Y[:4=E71;($]W/[D&Q?%[% )NO!F10V3@T?"\85 .%B)OP\V'@145Z(=)7D(0.M%$9(-%CE] +:-KVO"^C>\IDPXGF(M%+CNE \IB)0J42$A!/'BZ2'77"]I1^.0G8DZ(VH6'.'C=_ +0-+G@"JLHI(^'![%](B Y_[F**++-TF0+LX-G)Q[J"DCY&23J,F2HK_2QAHTI +/7F2!GMAF/D07A_;I))0-+/V,5,EYJ-!\=R8FTXP) V)J^;(VV879Z?JHZ/T;%\C +^K&X7I!LW3D-.L[I"G'R"J3WB>;Z(*"VJ:[+@QGM>('$K$8D_J5V3@O[OP-T6AI* +-MYJL>:B@$^I&;V">&M&9 +HF7S%1KY?U"IF?=["F,ZDOU;8Q<'CG*O(TG2@T-29PBPD6.R>SJ!P +?'9RW-BV<2?M^*,%V,1GC8ND59[L%P6O%2I EV,/_E:%1U:[TB)W@4Y'/DOS-)BH +*"/L8E;;2[TLFSE>/&:[@;BMM\I[82TL0G>%4+>U&N->LZ3O5SE5I1*QJ@L^KRA] +:UCU\I:I=I)^-58085*/5H\XKF9GU/V06HNJ1"*%)TFQ$QN6U-P[BYPGL,_+:$.F&[H I>0* +?N68 I @.D+S=#B1ZK7#)Z>QM:#6[I0NH_IN)DJCOEH4(WC8CCG$!S!ZDWB6\9AJ7V#4J#G29;,$C),V47ZHH2T.>WWMQGSQ\3(JSDTB) +:2#*XAPAY @^O:]=P&.G:+Z1MH':8:".O?_2:-:Z44J5VT9.--PHZG?#BNS=^C"[ +ED$-(MV@[FP6DS DT.0('2\QB#-PB1FY (\3\5.X4-0KO!(1C,6Q*8/:965FWD-] +Z->O7[IR0=E]_8@YT'9<#.J*^,H-.%A6))_UUE@,BHJ;+!2H> 7[QD'JD[1]1"VP +C6YKP9;'UJ+BP@DYIUG5#+@*_-MFGGUSZ;X!PQ-TW_W2)^E;8HMW9A6&&NL/MP5F5=!P3-7"E:[@NQTDB%;J +*@^N=V]T/+&TCO"7;U%G>*1QW=Y(&'1P_;-]X:"T=V3?-$;ZJV=1ZB12HOO8(U(R +_!^I9>^1A5GJ RDJL8"-_(,6Y@$]$(C%3X#=NQE.B]74L6T+=*W(\B$?MA&WN#-QY 2D1W1*@)E+KHN""Z3NE^LCB 03(PGO*2\6&?,2,E/. +XB%%_.Z)PZ,C@^D;587QHWEF&'^:;%.OAK;@G_11>2:S%#1\#%U FS/G+WMXV4)# +9OHF?U[ *"22^#]=6],GEVGS(O@*DTBU-X,+7"7&KGC#0Z7(-N(&)GQV\@9F)O]# >@^< +[JP=,.)3*X41Y2KCAR"EQ3%RW]H>5*Z6A +1S^&*O:6K6&MP6!EW.SV%PXGG3S"TU9+QSAOH"M>W;-^5%*PBZ<]#G4-HH44PJSZO(*EDH:? +<51Q;>=[S(?5I(81MCX*$UG@J6Q]>,^,QT6 +WQ796/.SDA+.-XM^U/Q'$K"(3!! +%X6M<,HL*JJ=ZJU$8'NK?#':KLT6$%T%N(7T;Z=$>2>J&7*$'?,6'*Y>3LGY972/I[1:\J14"X"1ADS.I# +Y='.;J!ZQP:P/IUZB4><$CTWT3.C,E--M<-)Z4J-=WU^6/(3=]P6,59;MBZ(T -D +:>B'9O36F=I52FMA=6:05]#V]?]!,O13P:2UIZ+R*U/LWG@K]J(+:K]RXS'Q%@-C +9N=KV%,Q$SC\U]L^'Z/FFQ+,^F$AX&30N1P>1CZ:1=[:*IE)ZA0K!QL,%880 37-^]TSD%CWE>L"T5FQ(3B*-#@R2AI '%5X2GG.VZ! +WV92I$/CUCBA..U._$M3#)$?]0U=L^!J"<8>VQEN +"5KK3AAXYA1V3_#>XT<-C1- ZSF-71G?(/F%_FZ7EX^B@;Z&5PKJV9:C%1/G(602 +WSD-S5\_)7F1_"RC/:-YE0)TI#E!NJFD],D'&;4AT<*,EC3^27K$DD$;XFG'+*UB +UG63T&#DO?QM89D1(P2. /CS?C3&CT*Q+0(G_=XV!&4/>MG3=S]!" Q.ZD:'T,,) +.>ER_CRP?P^-0YFLG'\=2L073,-F%03!T#102_D[^/=D+18\/Y'8@ZYM.E3W5MCE +*%PS(LNS%S5G+ZS$&Y+GCCMS<2?N7YR0(YXQG!WA(;I.1^TYYV0D8>YR.X]/LOK/ +Y+ T2&#!%UA0O?*X@9F.K=2#G_*?7$QJ7>=JT/3!1002;-C^LQ\X;75;F (R.=XS + 9\Z\)HQWX^%R6C(A%4/\YI>S.%8\!025A![#.\E36@I":^U\W:(W']'4Y"\9FK1 +L&L;6)"701 OM(9WQ+*.A5GD[) M91/%?3BHU_5H\^$< :X1%+&-_UL + ZW=&$15PDKZZ5KE*,"#4$>T>7%Y\4OX$P^ G#.5G\$SIT')$!25II54\P>K]4&?7]O[.8Q[770?=)%P_.O$-3A?3ST_1G +I]%)"%SJGK4#.[62/-*^$=K2WC]5=. P\C[TQG)N$$MXT&2"E*?6@L.[*#X1RQM& +F?BJ<#7Y6[05?G&\ NCOB*KM-M=BK=!OFU*#Z*R0F3?'@!"\6UT]*KT^MB0N)Z," +"BZY9:1(7KE"*%*7L+D&W/W[6D7C:Z>#1SG?6M!G!93.T1LF +CORD653*?M;_-UQ=J?YF=@_9'13W8S8]^RZ\1!!7HX;@+Q]GE9N.E\?GH=P0*//W2M)(&)T +TP5^\OF6UUPTR;77^UUJ,L; +VES4B#/1X.&(ME/C)8*;Y="'<*E.':"M-=_"C^066R9[TCF>P_:-,\EG/^A7BP%Y +_D>-'EDMLD%S<%*>A3W<^:-/*V&:KEUZMYNV6VT=P.TC55+ I/]SX#"TG&3FY2#A2U]!?BQU6G#G-BJ/T.( >3#O)_V?YN +E/O4&:3#\/!\YL&5(8OH&3DI_=RUD73TX>X_^=[U-: R&]B"-!LF*!PKM5&5TWH< + 4D/"DY6G"?3!X:/QB_XR]52LYN/(;'VV^K\^G3I%$RUJPAH%9V%EWI,E%FT.#'()FDJL8>[K?'7BRA_0G-^WT8M?T9?Z6,NHG +N,W7..HP2F*B42#*(MC$+QYN5I3YGN/>4K0+XZQBI^/=@NND0A 'BI +%'755YNB5 N)5&?MCVBT*.7[3@67J'5+5K5P&<6MKO+_K[DK#\_Z-=OWUNOH%2H# +&P::+@)[<-2Q",W N%IP=&B\=\Z!R.3+G8 *_=*_:C['B TIW1;>1N%+@HI1VA0O'WSD *'MH]-#,XI0@A#R&SD^0?OPAVQBQRB=XWM$*4^!$EH7= +$Z26<)+&:AY!!55S3<:H6@R^]$20ZRNW[:4'F =HJ2C%A^!7SZF&G.>62+T-+2,4 +F>7 DF LA$!9*Q%#?=Z).3TQ A*S40P&DVFA?!L'34_%?\"M83+%@XMKG6>D=DST +I6$R..P":GY25_5>N?27P&];ZW+-:9V9R5OY]F/JYM^\@F"N *EYP;C>$2&:J(&7 +ZB]-KUP6,CJ":WB_&A$GEC9]D%UXF-\UF%U])&3I\M;\!0C0,T>TO4+6,-+,^(SI +;(BLQS]<@-^;&Y?FT/#M==4?YJY.KN8I,/L05#*N(@\L0UC^UIGGDAQ?%1 6T8;] +9&X^>\/KI_=/SK%=Q"[WQX+963#VCG?3YCM&"Z/] R'O K'IG6IU\Z>'"4M4,BM] +<ZFURG$ +ZK 11S3<#U&4+OY0^I3^!M$6@A.,6 +] Y0/IHMRC_X=SS^YH79# 2JYYM('E2%W:1[RW:&F2]@I\"7(WFB.7%$(ZF&R)ZC +TAU6]\6KUKC0[.22\CZD(H#KW/9&RR\@"?(N+*6DC80IMI^>-=F8W6S,PX$4.>X: +9J'!\9)A*,F$-TO#5YGAL<4#'C?%>L+DK-Q27")(-^A"'6"; -!TB.D"T+Z$HID( +"\?=[_<95QIGS0953KNO2NCW[^IQP#B;.A5CK*C_9Z#N+HP3-T6_U0JF?Q#>7_!7MN^JJE/@,7(024^!XY[[- +?SPP:3\9Q0UEFTR +2%4W_AY6?QA!J=:K(@_:($&C8'E/81XS\]:HJQM1G#]CE9T]"J0GW.?N"=/BO:T_$6;R$,!^CHIW\\!RFRM*EG-(AXY*Y6K-G*\#0JP](Z\; +0DJ%\/E26Y%GRW;+6O4*8%7Q^'HL^/:$\B'E5V_6HEK%3IYN3+Z>[TUZ'@0BI=(T +W4D8T'B,0L0(#V0&EI81MP9=:CSJ(5];.28U.,HS\Y5UM;V$526'C3_6[([%4;EXN&S3!MO3SC;5VR?/TWCJ +-4VX3AB79KV'#LU:= ]':5-=)$K_1Q"AQL^1#YB+'U$O2^75^%!;2$]E%8 +9[DGQIB&*+>\H(>E!O@\I=9KQ9VG$7EVD'#E^D"OWI?ZU';Z7CKM_LK?]51IE? = +[)IC.NJ *-=P\!YK"TF//@Y(+(OO78$$CF$!X?;S= < YE7[37GU%>$0=94X&]MO +IZ9;6D;T;KD];X=2H7#":I 3.SQ5/YSD!%9NK7+!6>D,0]&VP^\P1H,MWY=SC)2D +Y\3*]BIZQ%EC%"/\_[-YUEJ,,PT$OQP,,UB-6SC?4QY$Z1]-'L4<+&#^50>(@X(Y +I@6*5L+X@\5WM>G@ 1"+==8./S39]'L)FM#D=%M?.4D4-W*G#RC-H_7Y8 _3XCII +S"?TC&X4=2AM5Q8']MO%?A\ UI,^1R-@%C5-I8YS9& =G5'6])CUVJV',7H-'< C +ER7V9Z+3(<^9^.-@LUJ/$QC_:FZY\BF0ZC@VC4A.51M9&BQ(UE^+BJK N*B),F*A +FX.URH8ZUDQZ%&=JRQ,[MG10PQX:H*=;B8=5^IBMZC9:0P >K>:/G]7,N&RFEEUD +YEG3\U70/07OZ>"?3D&K]0$I2;FX&GJ*%M3"P)^ &.""O=6A- C=(/689Q#:.KPA +:X(8X'DU0Q:X5(9L_YIDF"T1R#?#8YP+'O_#TY% [70M]>6[2#C9](6K3,378.2 +/CX;#%9*]Q5\RA85G7Q3?;#UR\6[_L&^6T98KY"EB/96@QPQ''SXA9AJI'OGZ.1[ +^XT@6I]2=6A/RU^0.#=P$9 $I/U+]=@'K;NWCA5<1[$3%NPI@DE6KH*])CM]6 +HBEZE6P6)-1_%'JJ*II<_US])&L)S_Y%D.@0B)'7"FF":SA:?JSKUP(="=!SGH-$B"9QJ>NK?*L)!#;9H:PC/3F@Y$'9WC!F$_/2:)J@;W%=>S9 +TNW0O PEY8?X*;$ !E+?/ +-/XE,N47U9I9P+K@N:G_/?&7GE'YJ55 [A]I75OT1L7,\'J,$,A)B.G(1M[@W'D" +)HBF#?A_L4IJQ0Q&Y\82/ SY8@B,>>F9%X!GUW)3R5GH^UV$)ROJUU(N!9O6A0!J +1W_P>SE-=;A04CB8O]?L(6BF/)1Y3V, +82# 'VX*:N447U!-0M^F##O"=-7KAR2'U*FL&G&:+9OZFS8BH\7?C

+"UU>H8V918[V61ZB5,J!9?[-CDQTO &@JD:558"X67KJP$ ]8=)S,Q=>&(>U_0YB +[UL"NM)^< *X@X[.G1%ODZPH??(F-IR$_73M['HMO>YWR!&PN!"C>J.L@&1)'$:!I6PG\1.^>=JSG!TX +M_4]&VKQIY@]PZ[$)B,Z>S.0.-(E9?;(4]KSNF^^$7W=/P(17Z#V[Z(@5O=M+DRX +F@GN>"$VF%4/"O^@&EXK\:C7GFG$=,_U=9PM 9DC5:07K&U;N!2(X?UR8-:HW 'Q=A\E64[!_ C#!Z$(-T[WP9/F1RWSJ^J\X +K3G:QD91,?(X,%>C%;@$R-Z,)%\VVER5SW85G>VU0BYM9HDG4]O="E!#BXH$^ 2.V +8H]>#>[\=_.$$>Z5#,MA53?<_:4 [RA-"66Z8\;ZU_GV*OT[B#A-J_5??#YS\$FH +^FS/ +)0F/<,:B"U\A1I]$U^)F&@Z6WF3O(<[5NPF+J!(K!ZDTG6QMB3I*X>^; VN]Z*L( +S7QJJ+=;'Q>*?KU';%]-,F%F*U:5UI_N$^B((:P%@NG)AI7897QL='$9?\IVH"PE +L#EKKZD@^VFC&XNI=OXV6JN8/4&JLS>Z0/,P'B43@&<>C$,)?<7*.![E,]ANK*A. +BI";/P-@9@JF-!DLNN#OHIH%YWA)NQ$R-Q##2:#LOM8E5 DS*,HZLTDJ3"F3VZ0T +M%7&UHFRD[Z5(MXV5/;B"/^A0P*^8.E1+ZIL?.9#:J#3)K6R^*>Q_YU@0POT8/K0 +$/?VI/5_)**50*\K&;SCF.._'4\@+D'8#:#E83!T[OQ:XTWB$!F* H-$M=GW[BUG?L&61!>C6^Z'6BWSNEZ_,?+(P)U* +;L3ECOF(..E)(.SVABR!3$4PD:L3; \1N7M/_>$*1"P%%15R^G7CMY,VNBN39]XO +B9NS.Q(>ZANRU(R"_GG;F\0J-"[PYM+]XU>C*4!CFM7>Z4)M(PU" +]D:P[SHM^X;''K3/A6Z^O^AKJ29V\A(+FR@9@RX9'6[UN>?0E) +MTF0+$D6)5LN3-I'G:H.94MLT]0)^RA;0#N*R175^BP0CMJ0$1!/8I.MN]=MLDMN +[\NTO)S&1C(146^\#% _;0B8R, OH7X-M\$! 4C/V_OB21Q+:8(TLWL64Q]T&B\- +NF@#K(S76H3K7Z%?XO+@5S,Z,$4@)AJ5P:-:\6NK)LVF?^V-,92(TP&B*K-A6,.; +J\$6%?*I]=:^U%Q^6Z5:83/DC>ASA0=@"\*7[0G +#5J8ZW._X(HU62]&YQ-Y&\_2EM $@I9V52X<=(MR%?OOM%N%BUB&$P-WQ5P\JNP0 +E2N;D%-^$WY&)P3$,/ FX[%#94RM\RX]L6Q:()K2Y6J/-OWBEZU5RN*IYA[:<;RA +^[8F>9U%'MSC"..4EQ#_P?]PZUH>>8#.EO1X"\ R>GV/M_9)[AS]2D/^Z&*?SI6. +M/GG)LSZ@:'W?R$SXM(U3_>)G^N?HJ1+E@P22^@R@.>]'L)!C&4^U;<613-T3Q944$3FV7K +>_(/J2\ZH4 +MS04@+K .HJ5*-!-&HQWS1LS[%T-JD7NHRX]5;U@]\5J!HI9OKX&1Y%LU?;A!.EI +P'WDC#^8_JC[]-RWQ>!@NAD& ^;I>_'2JA;L3B0]:6"8O2Z71;(U(]QT=]>YJL=0 +'-8-%@"&KEF>'=Y-!#SHH;J]?=E&K:%2$T$C/JF+B,_:(>TV[MT7W[16S?HK8UK\ +"C4/S\O6=2+P*[>"B7/2<\EAQWB?P_?)X:F93._.S9]EE:XW=E9]Y-+5%MJCB^^B +U]'[G@A*9EN%@^09'-Q2?WX'(3N*QY<9B;4*F.JIC +- W#_!%:8+U'*A=YY:BZ$..O\[H[M2JOGM^]M!">:.4:\F +ZA1S@U-$RR+02&:&9(!%[J HVNZB4!3PB0:N'9X97+UL2T\=\9R6N$R,1PQ?\AY^ +XFFFA]K#@FC(P-JTB 0)[,%]<7+,O>NELD"9HAY2&:19?<[:6GPKCPYOV_S\0D 9 +93\H8>?(PEU5 ^GZ,TA:"A^6A#?*CTE +K,#*_?TNC\#'"53:WNW=V"/,RD6HQ@$C--UI%-^C?8>'$Y%BWNQ>#A/!C^X RVA) +0:$>^VB$-MB7,8+FD*@GX/D6&AFA"+&8/6'A?B9O=&(V;7J=;N80 !+F>_[$*L0 9YK&R)Y'(1(:!"F X0 +K(1Q[;AQ8Y>]'V419#&)H8,13N_49>+N!46P_ZTSI(\BL#K>5/$5_TLCB.Z*6A:__7W94,>K +Y&5Q8H9URY%%Z)ED-PY0-$[\K:U20OL8%3J?D6T$X"_1ZGFA:7# 6M +&$V++^6=_)5GF>(07L$6$[N=\\O'/GBSS=HMV(>-HCX.FBGX/._(I^(A%?,Q(EHI +FG(V89PW<[,H$ * \BM@",-"-B.W=K#!U%>N',C49^%GE!0:8C%_\#935"HMOG3N +!/]N4R>HZL,>CC=7]RWM9MN.#J%:(TD'C.04H:!GCCM#25_BNVC'+@L5H" ALY@8ZTW (WDN*7'$N) +W=KV2JXC^53LZ'?F5*G>EDC:J!C$LT7SCHZ3^;,LBO)RA1H][KLG92L__ +YR?SAMOS@QDC.5Q9XP'%=S'$H90YA?^:6>&[_DHRC4?/Q]$4NECGFO[+:TA]K)A1 +S8%4\O%B%NFC0^M/W/XKT,!7EU&"!?SAKY>7O9/Y5/Y#HK^!HGD0L +$$7TWIWW4(/=I ?=W;;(MJW*MM&0Z>8DPSCEC]BE@9$N"32$,5&T5$)3]6#3R/'[ +K2PC+/FBRHU;%?NJ/[V4%EZHQ%PK#@X'+'""%@ZB@20GU:1SH NPK94R*60+"22" +,NLR/.4,?!+,C[QU_W0FS^GHYTVJV$+#-A\'?J!/4#ITE"F\Q, &;V-^;)2M%]])=9OEP8:7SLTC'J1KZQ< +22FPA1TK35DG_61=H]AC;T<9.MCV$I=J]6Y)YB^Z@FF?N4Q<2?;_?"7 QR5)YD88 +*;F!>74^)O%_Z.B_0)B$SMU4=-TNN>N56(>_9JLYV!N:1TDX;G_.*T42I*B3SH:2 +.6Q_Y,AM;+]]GIQTD$:KO#.65SDX-G@E/30PM198$[HMS@VM?GF\Y^H*AMPV8OS[JI0/:W[S>C_#9PIU/WGG-Q +!YQ!^4_G*ZN"B8.OPECW HX>(-6HCX:A 8M\WI>3?FL;)P&-+-0P@#/Y&CX-U4Y +H3?]7-[JG;OH"LV&JQ2E/)\!O5)S^C=QSTGW8_W?:B+'F+JR>GZK_Y<%8H'FI_9/ +95?[,2'L%?-C/?U:"*T(09BC'GH;P9T#5DA\+CQ!G\B4Y;W@!T:W:X1D^RW%:V Y +2 ]^X"[R=QHANL586 YX0"5'(O*F^/+%40/]K<-!V1HI;5?8]:&ZK/)'G2N9Q__N +LRL7G,O$BK_Q1<=!;0NUH$6@+O#UF_QR!BOY.$13'O3(=IEI:*= A]*4HQVBJ +&AT!_:V+M@8]NX'>%G"-47GCY&, B4AAW45C9Z3Y+P4D39,6S[WU,*2DUPY9Y[^NA*%@0^XM:88P_NW88 KK0;VKSVPCI2G]B:4^"6I3@"N- +R11'6.\F)^(\)Z;4_>5,[%].BZKQ_]STB ;1TSAHZ3]BXTKK!:+D=RA+RC#Q;=4" +'R8-#1Z2/2'K2+S)FPDYI\L))&WBXJDP#*"<'H\(@ +@=SLE]?GD)"ULG7Z^MXVK,0(5@$_[>^!V8-D0:=!@;:?(@#&9GTG#%X9O,L(&D'V +-(AYJ2I"C4I_5E2!'^SES=CFF$&KE/>=Y72WHQZUHA!O@39(Y_Q7("LK6N.RB:A= +-!A)[0S($WA)J6@#G8A3&/R9UKN6AK9TCU5=-;NQ$3C$@\QVO0"VKTUSC_C/Q +DI]'H;)-UHU^Z$[1S'TGO99PI8-'C+HQE:R6):H+TQHD'-)#BW.:6H-#/1#X!\[H +I.3@( "URV.MBA+/UI$F\9PGMZ9 +88'FHL><=L+H'3NR_K1M2($V93?HE_CA5?L^[KVTCC5% +CINM8/#_>K3*)CG,>/B?+[I>I0J$I1BMM6I'#%*Y BFA@2@="8/*L]8/P=%@_A5 +LL3&./ED0NZ7#M4G#MC +35D"\92*DYZ@.1=L& BO+=!,GHG$O)Z.!GX=3H'/FBY; O VWJM1-4]H\@,"^$@W +)PBJ&J<,59Q[!BE^O!5QB:WDW,8";2E=+G MY?=GT8=U]:5D#^D?"G X/@6O=XWM +TVI)$N7;E^DVD(B*6S[ Q'O9CC7LC6FKUC;+89CW6<]HSM=)%6V\X8YP_7*/C2!8 +\HMDM<9TM5C?GU"'+XTGF:-M"E8D$ P)/ZOOG2,WAG[]S9-#+ZZ2WY*>K!M7=K@= +SX^7':U,21P$W- E>54*1Z;->TE4+@F*&4MUN0^U M_[R41.P7K;9KK 3 )/6WUB +.-@FPHVUB'^WWY81Q+*7QER^[_3^]<5P;T\4'P*Q4K$K!&^\/:+TA2'!2@AKU%E$ +&X= 4:4/B%[2PVCK8 0CW#?*%K,E7_U5T1TR$GRY(;R'+'N8_.>$5,WASCX7I&D' +XHQ"DT0%"6O6OA9U=XLW'Y($5"H#4.80J3[07WXM>OB[(3Y3<->I>@YM,$ZBL*7R +^^"Q8/ _ICX32 ^N,'G#M*GR4XM# F!JU80<'UC-4P?'Q,@N"1A_L &T?NPKA.I( +!-<\>>G 6@4T12"'&+]6ME$6MOP=I9;P8SGRF;BO-3M$ %;I<68Q\9!9;K$^':VR +@!U?H-D*E8.Y8Y*;P9R*UC*_E>B&>"_U^Q^*B$X$_>PF@I3&L\T;$@??_ +@>YL3N9'P]#8?<"L6I":$3\[&^!1QCS:;= 2U@L8/,98ATDD\VB4DWAZ;K=]OFW0 +/QZ5-R@*07_<]"EE_R5L+%#+_YK6&,)X"S7OVCP.) 0T;KBY5( J?V#%WKW&"=0" +)Y+$4\PY\; ?T5ACN!T>'\^^G@V>=X 4Z-8-TR8AW;%M8FBB_+=PN8+R +#M!^H92^H!=>OVW<2_Q<;/UV\A"[9_%H7QS*ILM'.&IN6N,TM5,M)'9>PU%G\9FK +JN'N;V_+U3C)/190]A 72PGPV?$UMC;(JB@B!L+V@R$^-GHE3)/[[O$:BWNG/7-I +^(O3FJF5I&V5DBRM]K]J:+W4K\'A<#_N?F0-BM?2U$R-$XM1LGQP+#M?\E'K9Z)? +?C(N#6IB33BN#^3#81+^\^VCNZ2[%@9A(K>(]S!A"+C/F_W.E:DR-R\J!>T +&,R1D9!SIK&0==#R6=):E9BQFRL#JEU*9!:E;]^&5?W70@W$A >=N*4P28E8I3:P +^:Z/+4]$NV#6#25'6&-[; 3(8X=O#KB*+8M9S51F/&40S@O8W#/>)Z8S2HV +4#0:U#ZL=B,_*)J(R$K72'U;@%2NG,$T9F._V@Q51BV=Z%QVGE'-LS.>;,^?]"OV +E@01CAAEVXG@S*:@C9XS@8&N]H,?'+0MCK*)A<(Y3AB[MIP N!#9^+]FP +_S#\),PY.8*&2,ZI-1.K2MX1[MUYKH]_0P^6?,8G,<@ (G9 --IK +] )XBJ[W:P,C.>X-*^<'P9$>N#]8^(YNX,^3* DA*8A.($^1Y"BSI6[IIR#:)3DQ +'"XW/OW,4_-M#*VI(#=-M3E&/C#N,D9IR9!D55,2_9YMUTNFYX&XT7ZZ*?WERPCO7(&]:1,*%ZO,=$"8>>5=M7)&)[1^OQ=E-=O9?%,_Z#B8^@%AC& +B):27ON$!UPA66\-FYEJ;;+T7J"6!VCE!H9IA"5B=OGI NSD/.=75TB+F%L56B<+ +E#:VAFJ@:H.,U)P8/V0BM,JEB0O)([/?V2*JIW*$ZP,A;5> GA89G=\?;(&J!T'. +P5 8D8]C29RP+C=LYY)B$WWD,@TQ]]8#9'PBN=O/$:8L>P[4P+GM+U-*IZHC;^2M2R2DK%CCQJ4J7S\AK@]X+:U1(P3 +X=UPEK_*,B0?CAF+Z$4R$ALI(LD,_G/[M[[#H?E;'RE*E3(P-'6T_249J(W )@58=7H]AT&V3I(A[*YEL4F8\(7""Y$_5;'FG:4>NX +_&1O="]!DM%C!?]!P1FTH[[T%@+M+B'RE#@M:&@L>H%HV3F(&92:\C\]0O;F$.WN +9!V[!%8MZ2WA#U"?+RRI*7[3QO>Y6 QS(: 7#U^U"+OQ:8-W:..XN'B,2B%9X:%) +WHBN- /?5?3)J?Z)"<;FU^7]EG-9K-'+L("+:NC7X\[UL76DG6A)O+P1_5/IW[5& +88_'?T(K4:02DM>O6X4?B?C'6P3(WFL/BVD%O6G!RURLC)X_"\3"[Q"30<7'_GN: +3TORSR#)TX^ Q&9^+=9=F?FP1-D"13P)8_OQ1;R3_^YO_RYZ,,9HI;'T5#5[PIN_ +VTX?'TQ'U\)0O9-24##=:IY5B=28,FPJ8IRD\2'V:,*'S'A/ND_ #"QS!D)XJDX0 +<$$^QRF/3$-I9UE)]][P4[O7#/"=R!\!$CG@(J< K/*T$E[SR<>(8,9BC5;W.=3! +=JU;=;WO.S^IW!TIX=81(]/P@L2K<6:&4P$C4H=M!(OFLI64S&)QLH'=;/7@?/5B +\^;.\0?K-=$RF5RN%__/#A+\987)F.?*DKH/'J\58!^)2%3G3LTX,ZQK=Y/_8%$X +Y%!R]Q AC!7C&I"IH4+LZH27+^6K.L8#L#CG2&UW>3XN;UR4L(YDF73*RCN+ITY^ +ONXT00=D(W%"4R/T%!+/-ZX&E"(*[=9@(ALF(:)VPE()MY'RW!-GSO, +#UJM(LAX?#X\J/PA!*V__Z#^D2Z9"Q17[\8Q!T0B$Z@E3MZA04J)\56E1 6+K1(> +#[^ET1?X]5XQ^/[R.,V),MX6Z-F6*_(S29@>FY@"B-?^F/Y@FI/8 73;6]2)L#E0 +VLJ^KFDW&!*%#G3;F3IMMI=*A2_36&=+O,@N;B-KBXOC6\K?^=YD&728$G&OP5#S +!B$(;6S,1ZA,CG\\@5:L&/V@1^$\C$C<;-;R"/?N![C(4\A09GW;RH,1DMJ]T//B +F<>X+BKW;ZV.+:W.NV)[/86T4_XC<+8JP=$:Y[CDKXDL_LEUZNJ9,N;(RP=,^R;0 +&-10L4-94/U(G8FTIX.,^.YHYJFWD[KP[;F 78 B" XX67#(+JW:_(K1KA+AO#%J4>K"=Z(*#'AV(R$/[DPX_.]+RQ%O6I +\!\2?U \F?=+BL#U=]L:"RE^RVO+.8W9W=6W&(/0';FS.FH]K'<8=%_0+S*R^83O +^<_6\.!H =!]E4O2W8KLRGX5DE$H[GC]*H)D9;0]NZ(@)M"?/\6+ZH_N$C:MGY $ +5RWCU.A TA2MQW8=92QUD&60ON4X:^!-P%8G$(-JJ;?H<3Y&C*KWZ&[ONTN!)EDF +G.9U/,B2N[_?O,1BLJ]5,OQ]+\(YE? /J^TLB<)2 ]8:?D,O;2)QGA%UZK":\A-^ +$""RY7>;D/6$2(I8QQJ? >I3GQMV6!:I2]^RJ@E_STP1)P41);7PQ_:Z]CQ%%>[K +% O3.]!/XG0=4*6!T)Q4LN7 Y>[RI4? SLR'Y.=<<,HP2A(']V0.8&,2LGLYN*P8 +]);XDM$L4=,E>MCA<'2A[A!Q%^+,$0Y(3#U8>.!_,#"(WDV.VF^_A67%6UBE0P2S"&SUY%,KP@=F[MNR?ZT0 +Z.WFZ$_0.QC[;+05.?:-+!2+<^CN:0 +91>>PB[B.%US%Z;OB9X+Y^UZCKBK^FNMDQUPSZ,EFWPY3.ZV$WY )X5B^"@9Q__# ++SOU2'CD>6+K6$KYN9\L(P7P]!]FY3R9B)>QUO7-]\9F$\B'>6LB<^*BI'>&HX&V +R,NIGQ='0QO99OCYOE$%P5"*F*UGZ2W@R^L>+,0#8(5@92W4NES^)IPT$VM9D/G1 +$P[/@FHC_^F!RO(,XH?J9^^U(^1W9CJK^IK-SU^#<*5+VDXP> T:3(>?@PJ\)K<0EQX25I-6@BN%=)C^V"Q<(6NQH*>AQ!N,S5] +OQ#_EAP;]B)R2H0FG<64."7J6,"E2B6/\RUUL?)8_'#R$VDMG"4ZI^::MCI<<,P< ;.7-I;S9+K36V3QHHQ>_-/ ++$5$34+OR44E%=)$O[]$X1*;_FY#XR=N',5GY!OMRI[047"$=9R.QX,?+FOA1#@OI3PD9H_-();AH+0L(-E.=<6B +V&ARCYGT90G+%_#SG(Y]DGQ0&E>VM15+M^3/B /6AL135))FR ^O$!@.4PS:4DS^ +33F'./4Y'[U=O)/BFBQV/U&18B'M[T50SPUG"GACU!>D&<2/AZR:.Z?6#Y^U+$3> +>TFZ-%'89*C4DYL?KDJ;\FN.WG'Z=^LYW@057/K8Z +C ,+_IJ'FN5_V]_##KVH>(\Y<"2$3,(&52F]BGP7L:GZ<.B@9K6)?I0@1P_=A:K4 +JYQH1!ST1-X+GWH>#S\6$,0EPA%L6PSWHD,7;I60D7@$ FX15D Q4CS-W%:M;*A] +F2Y)[O8*RF)A47;Y.\:.QNPQ\+-;X:W[=:7A@#ZX[,VVC"3FFUZ'10IX]02.<)\2 +85PH0K5)[&S;0\QE![0B'9F&I(2;DV8I,DKM'#3#%ME_E[RS!"WY#]VS;Q>2<(@ +E@L$E7"3N&2A;LHMXZA1VP:R9.B"M5(X% -ELZ?6K^,E#F,9<1HMNV^2SO;K I"Y +N04U I[ E,Y53ZH0\9OAA2_TX_=PM]0HDM%-K13RT"UGJ0BWPO"^@F:5B1S_]4;T +M '=2I,OBE>'US/ZCJ093XI^I_7_WKU;@S$HYOE=@0+_2U<$B4.G6RT97:@M$@@G +^!YO-N+0AQOB"(Y]GFYG]7]H;^GN:@')LYRV04KD6BC=TP\H3NOZAT3;Z@LZ3< +9ZJVD($=++0GK+WS>-$,>%\*PY +56$C/OH^_&X VZ-5X&!>\)FK$!7O_R9 %$9<]0#1L3HU>HP+NU7:R)B&H&1Z?GB& +WWQ]%J^VA_UL)ON]=F'9X=_P\ELS"2,$IVQ,!\ J81LBC"1C1[J-(Y(Q7GBL5F=N +XB>@"OV?M)^3A^X?=JB6#6#?=7PS +B^%M87+_)%E"&83XC=6@2P_*UJ>E+$1LWRV42.U1-C?"+[*"HI0F$0U.#OMU'-/Q +@QVY\%A;,*QC[&"E11S\ZB?8JDW?-\^_!3QU5B4XY4)-V%*S[*$IG2I*88-2;\@YD-9)22V046P=]RH,<_W[=Y/?EOK"\WVY)VMJ-F,HNWL>-;3@X'9W(]3^1_2X'?H4I^T8]&^)CD'!\QN) +&\3X9O@0+<5VQ%EO R*71,AVM7OIW/241PVGV([EE X6F('PZ_K! !+'$JU8YN/X +Q0U'DZ6]4-)?'M&GLK)%H?GO=R2"(;$$[K^5-O_<%1_#^7JQ]B&/@GD)AAQVAP8# +O?S@$YM7@X +_O!4[L>C4 DL.=&&EY( ,]L?ZXPNR ["PVK[.FS#%06!5W11[F[6 "C15Y7-=!I[ +V3%9/;@'[V)@")/G1TS+NI%;27>2=7 +T4[+Y&!,X"[=)\R8*"Z[>?', ["N6-[UHAN8P2.(KK*=9EJVV&SR!>0G&YL7#EX6 +--IE*2J\EP]'B':DB@8_$H3<*\G6!II'O['6HZ%;H%(4:-D3MX98ERG%CT0\Q\[1 +,(X,0EB!#\R:<+2#;B5D6:IHM2X4 M8VM5VC>%W/9S B_B52FT!- :?KE3XKNLJ5 +XGP)4+[5I4[6Z4 \PI +4.OUZ=Z7^].I^6*437;F<;O[V5)(Y.3>S-U:ZG;\/=X3+]QVL(*,LD5@=P($+YZZ +*$R$ ?@4+%T78>$9W@85V\J,;*+L[BG09*FIDRP%N?.:H +?-Q+.L)8C@<^[$ZXK +@'P\ ([*C6$')GDO0'.^)__A%P,PL.W5&9/.P-=)A7$D9_6I%=$DEID_G;-66W6Y +,@?_E>2'$+U2#12>9>/% A5;W4NBB=+1#C9CH7W;2+*!R@=1(_![^';:XFZ":X"1 +QT">XY0RIF46"$(> ,)(AS:-8(!0;TMXG(T6ER.".=)!GHA;FF +\17:S.LNIP"MY ,"RJ^'YA#KHHIIH'&#Q+2K^I+KEWM][U,KR9Q+*2CQ=B4[Z%QK +X[-)71\?7P/I<97MWTEC+..C6X$ICPZ2V$V#MST!_09,LK7F$<1&(#H@+H57EDY4 +%-54 L2637] XF4D[T71E_W']C:1-0%^ 7J-E&-RTZ2*]0"%0;FW/F"KS3"3WG7& +9BMC'Z&'W$;8-1&SD!(Q90Y&9,D5"97[BH.3% +<.CQP[+,)BTQ.QZ#]CR( 5$)ZW7"&C@3*$TGX^H0S /^[']8QQ>*GR.O=LFH7[>> +84A+0O1OQZ<4+'U\)UD^W!J3BC"9 +76MP'UH\UFJ*E,TVGK'C!A_< .&)>GX6%+1C_V#9IZR._($I'I4*64%3I\:%?E,T +OMI#!D20:TI+AVV=J+X_:3V4CK>')4.V1Y5:9J("+W0W=_( .WE^M:Y,[L=DTB%E +%0_^ L#%C&W A1WV0KZA;D*P(D=7ATD0>AZB44I@IR+GM60;2>!.*SG)M@"',R(W +<_+#:Z\YNDT>D_?:("$]#//\LT2:JN8,)TW(#ZGCW%L9RWTI>X2)MN@3U'W,42IF +^H_24A@+N(%:4C&J?)>24*?3GT\E/ ,=T*<93U4X"5YRK@UHT_1N$J?-'1^W"Y=[ +KX&Q/!#-/.^)4Y$QAUZA#2VO<4WJ::_*BBH_(@TI5#=-RY^U0?-4."E3RMY4\NP4 +"6/.#;4%$??/I%=&R0-W]W= -6/\$(R&NNS:P=&;"RLI6*U1C8K8LW.B\"XAFKF] +R%6$MUQ$)NS:_J].R M0W?&)\-_W1ZY;?JLCN"%,=NU0*J8];5.@FN $ +'.&B22B9]TUP R]"Y(>'1&UATX^&>VN3IH7G]@I1A647KS4S(]',- _EK%\SOP:= +!::$:K&L_Y#9[2B8YS2V0ED_X@M,-X)". ]<6X!,8]/C"_<&P6\EK9#<6,^*7AZ( +S\#0Q25-N 3NR/K-0QN3GN@NX,NA+>68OPN\>NAD+?1)V1X-@\C;WXD)'HC]_$J, +-L_*IQV?Y$ C5OLF#,RO8I@\)9X=4!]4ZJM+7*=/J1642N*TOX+WH@N#3G..TWCM +A?EZ>W5#P,9C>2V7*%307?TFG4#3@[)G/Z9NO#(]5]@6N,V(,]-;2_:+!EO>K3N' +$C^1$7WZR\#7<27Z)505]I_X<9QEQ5MQ68].%F:KI4D% &J62 ML00W$B:'\0[8, +BYO$!QY$4NZ!V9,V;0/=)=&&"3T +.3MK.ITXEA:.?9#)@"(8X*OBP0]1OQ)'WS)R;T 6,MF>DY+.PI8<6_QT'3"6TM&A +ZZWX]%,#@:39^;.BC >G*%.EY:S?R2&T7 ZWC#=+\<7__#Q +MN&)M3UU'T-&@U,2->BJ3S.:[C4*RA1D]9%DL= 5,43%4C&HG:S0+$IIN*:XI"FT +.!XQ-GR(/L771;4MDE]96.+O% +7FY(^ V"&1N0!S1;3=IH6ZMEF/HB4B!YZ*AA#R.C" 1%U8BY?U8\/."8UIC:0'3+ +2&.@=1G6SPL.8:&7J5ET%R@ZPW4T"MDMY ;.H^5'N;C\N"D='QMW:ULN57;$[F$G +RDNC@ C+^-9CMLM<$.'H 5 +MU4&AY?@:!.@DU)O>UPFJTQH&/F-XU4/?]0AEZW ]LY>V<+.G,96VX#%"$E5V%B- +4U=\>L$*G-8\XV#T6&%CD4.UB;-;RGZ%##G"9XUA9EGF! ,L-P?%3ODZ;:W+#=>+ +\?]XP93&NO5=S%WHXND_\!6$>>"_^_\ZX?/1."W)> >R=PK<3)""'Y'-%N=I) +@ 5C$93255,&KM-'?;7(!JV.0?=]"RWUC7FK\=Q,5<<.8[6OY- +':RZ.5H=3,#%YD6W!2RGRS[\LC2 *")3.$1_R=$8"1QDV'&P>9?Y$19]YV.43HS< +T6HWQ5RDZ"N+J7C./GAEGCWN"M5DK;G2 "^DV>HERM>+RF=M:*.\'5 V ;W3U[F +JFC!(8JJ +I"4777KG\<+G<-PIYA%#?II"8D=BKXP7E@T"?<&+OT1,7G76!.Q8TZ"XT6!?'TOE +6,B;/\:->"0O;*@!48A6] &>7-N+YK>ANXJE4W\;#0DL!:8W,6+PM2D_?;"$9-U+0E%,>*M+W:[I7A$P2$=-YTE'Y<4*TA-?P'A0NI!EOO]K +>0;1C9DF4*XFE0?,L&C3L/*S/^NPBABA=4UZ4^%C_1L#PIWM0N6+K0_?QCXDWM1DJ?Q7*/00K'(NL/_M4-W'6K;[0!_$4 +1F5>..VT),&B=(U0^\3R=OWR[RMV4'8A DQ#)68P*BZ<]O@QCI4R'3D)!X^J55(9 +5 74.9@HBKFFLV/]U!1Q'+T\<5A8\P+FJ;G"'+A8[/ @&UHW]CS#G7[B6+_M^7T> +"$F:,J()POJ3<:!#?M6#A"XQTIQL39;9+R[1W+]"-,5?,9<>1>*$M C)R=3YCAAB +VW91S[HUF#KY=@V3!^T%E::'F.U0$T@.+6M%_$/0Y=8Z;/>V?RS): RGZ\+!2>-Z +Z$F )9-,8Y-M>'49D@ +EJA>=4>EV^F]&/U/4&,[V4 IY.%3C5!T(_6?9=IF>]ERT6RIK8LS;YPW[)WHSI@: +7&9FS17V-."FY!#-CNQ?(:KG^.&>LRXX$D.L[.P^/"(WKM$KQI'6@UF(@\\]48YK(9S+-F_D/19 +N)*5K7:<3"DC+X8^B;4Z+@7_#XG)\Q +U=#.##,!Y^IE9+5MC:,G)V(A)@S&M2:.65R4$:$(]Y=X#82*!,L,<)L<>U9D/+9X +ES3,-D%C9^3%0!_S(,UXX9.9@T;(>4 @CT"&9WL.FH14ZET'^5QQ +J\=P^/M UE\<..?Q:+E=%=,A\S&=RWNCY4](62W&WS2=$R:?TO*/R '(X/B9EG_)LJ_MJX;C552<+"QN/9&SV91:F/X@]!;(\29J"1 +L<]&I-%!:/%&EF"PM?7FPAQE[\>LAF@=$K'8 ",>DC,1J\+=1VRV\14O9Y5(#_Y> +IM-KY)0&[U6W7##N7"!O7$F9L* MJUG1YC?O6>")B9S8H#@2$$%=E&%%6$4.)5Z6 +PE<_RI")-[#M@@.JZ_LRE$IE0C^:-I-. D$$TUP>IT^I[/Q75..J.5Z(,T=5Y5J +WMJSF2E+F:RS& L_WL4Q<=[6^6^">*S[]-/[VR](9HE9MX&G=).S?:G/BID.K+6 +G\@DJID!*I(/"V7X>&_L33ZJ:Q5!PFG%6 8H>>"E*C;ZE>SB'UU*\RX^:;BH'5#: +;!"L9JC>FI^2KPM5HQ7;.K9:_+/&M+?4QQJ^2R_XKHPX9;7O.()\OCGXL(R96\@= +-\,/L=3V3UZ+1_WJI-[?DMR-F6T]4!%"T0M0-LVZLO!0T^B=W(!^*VCK7+HIYO)3 +!>O,&CY@V9,!7+0H0&+%*[B)RL,[7&6T$B^NEEMV:B=)N=VU)ZU69?]EIY/I5<"3 +MU1&E&=/Q\CAEK]C!>!&?Y^*O2U%D%:,)FY).@Y]*^=BA5<5BLL548&Y$I[/N/ T +.?)[9+CV,B]-RS+YWIK8=I=8;1T/GV\W ^A.\>\34F'?N=RA.T)".S@AO#Z="Q; +C+1I=TFU$Z5LD('2?5HNKI9]P ](F._.V4HC.Z \WH2PE.L+E"S^'861/ ++?V#7U;]TM?V+EH/2M*3\STL*ZJ$#=J0]F^QI5^>+5;MFM+GO=*_,VLZ7KJ+!\24 +5!E&RIU6X=CDRQV@WSZ&^T-+R?Z#O=?(CX"(=O8QEA$];2_U/C8Q^@+PYH">5):8 +.CI)8CX3WDGM:)S2<2NK];+9]Q4Q]D91>;.D?;JXZM .8@+:_ 2Z +!\DJ]U)>#+R'J2R"V;+.,WZ ]FSGEYT?W+-D2,Y9VKY5WAF$SSRMWL< B>@3NUM, +T=,Q>K;I:Y'[IUZ5"42LM?N_F[W<;_&7C0O$1*: -$C37;*6+P413.6X2[9Y'-^M +\5!^T;[)N<2^A(D=V7.^R5+)0\XY$MQ? U]X[N]>>2(POI_M_/1QB4Q*PWY$>;X_ +.9%)]C]05A?=,R9:B";C!!T:VIU!8\]<2%%M6":RW-D)]Z1,0RW'C/P2BCZ->T_H +A0)6,6?,PMN.$FXY(A^JGK] =70 N#OLRU[9+H@Y%:6U>.@V$+=T'2]IPF#AF/BA +5Z&KF_>*G(V<&/AKEM8>_]#C9#QD5!O:HU@4H'_O9^Y$E[RU)O+V%V'14T .X(GU(5^-/ @7Q%F\*H:+*':KZ41"X-7)N1%;3]N_QO +=-C^Q4-_WP#@2H_40<98S+GZ[\VD]3$,"LHE7@+^*14RX@_>LR#6@BA^;,2^4_Z7Q A +1,, >F06\$BM(*'^#83]M"_\S,Z;7R7M"!;OQ[_'O[%.76,ET9O]73Z Z,D!)+NX +D7#GZ=J9XHA3@.WCQ$X#K#4"TGXB'5WHZ&^J-K*@V.X:\P&,B58'A8B%ENW8B5./ +4+VR^83G!$N3I)I,CHV84NVZ?>J$L#_ZU ,WQ5IS_G1VAW=U5D-60:0X\!RO7=&I +/<:9?!R547C)!1J/RJ:0X>BZ/8WF^[AI)P%!!9XW$$$N-XT6YX<[=ABM+V%UG[VW +M# ?Y,OQ1P#%+M(PR$ZY$-!TQRO\+"]NMZ7>6PJ3;&"JK40%DCL&!_LIF06.8'M0 +F;;FMSDSU*\)D8'V.8 8_WBB@.N+1[8,S*RN)CT-]$YQ*HDE<43KD%VYY@B/2RP0 +Z&;S6)#09I^5P:8)E'(#,-:#>SG,Y4DJ:4LH@&B^]3^>9A+. 6'B.L%8/'_0P)A8 +>ML\_4O7IF4 ?I1%09=S3%K(Q5RTGM"<#L%)QG]/5^A8!?/.E_E%O^B=:>* >IS@ +R%A,/&H4B.P.2Q:S/S&=Q@:;)FO@S6?3GFNM0#X'%#Y[:89FGX.[B2#!A;(5RJ]SZ"!6N(7DDP) 1!O^ R)K)9V%=]U$0[@63!+$ZU;XAJKX<([="WY'J41'D Z!QT*_C<^[VE;-PORN +>(+MU,3A E+GM\L?XEN'\I-MZ#>!3;4>;LEL_'S6B)9!=[::WLY\42&,TI'5 _Y0 +BA!&>G+:C-BUUON,^UI4CSET#W6::+K*>5(Q=]M%$*3=Y&BWR LL=0KO=2GY+;Q_D**!UZ&@X*S%SP;=2]A[FQ7!8E'/\3 )_71EQ>-K +C/*4=2&;KL]NDPW>^+'J+!:OV9DL\Z$9)2#RB,XZ%4#D]/:.:N\9+$^7PQP\;$:( +H>UQ!-[XVJK$D)C[>B99ZRXY;H3@TL/^ M&K':2J>I%GZ "#/5")MFN*MHT [-N9 +[>;+(\(L=3.Z:+Q37,RO(V5>'H8RZT?!B%:83-'KTUA"/AB&-*=CGXQ*038DA9YZ:=-5AH$:Y?(\T<(3!@U66U8GD0%3>Z;'MY&EQ5UFPE+=OJ +:9P_P%$*WB70>@KA01>4=XT7"<-U:TAR$GWVBD+[=%5^0>T8W+.Q'X &NFR:EJQ[<8OL9L)>L5Y!G0D +5&#!I"P)SA*!,LSS/*93#9\_(CX_>Y8&ZBRY@ _)_2@*R16RRAP%8N"]-:>K/A$S +'AS"+NODUBP#_V^ >7/VL)Z*IL'YB'\- X.? 8/&?TV"7.:/-:HR65^G8H(=(6P= +7%DJ)#_^C+O^=&>U'1>C%;FI4OY;H?6&V<)9A43FZC43LGD/%0C0;?PA%B-XT2ZF +3>IZV]T=\6D%!;93GNIO 9<*0")+1?$%V-"2_IPN'A3MD/HTQ!7=%E5HT!7L$T # +*S;X$0/1M]RT.!1*K3;>%8C$#\\MYX6Q2S6C]]G^.F9-X;/W" )2V6L1)9Z +VTLIVS;CC_W&2)B2R5?K$9]!?-A>I=HT%@0JLP/=,54/0&YCKSSO&>TF]4_,7Y"V + '/3*FX^W7.M@RZ(=:38QN$ALJA[^.$V PB;;2<4-1 AK$PR-A-#8-I-*NY&W)9] +@='17]FLM*$$K3N$4S:?+17L1*$HF=)STMQAUE&ZVM EC.9N2ZZ0#BBL:'IWCF#= +A:&?!3_,;N?C2M"HI"C(<>JNBCK-V\>&_&?EX#XIK:HS^BO[#TJ@"Y44)^PHO!GL +1I_FCZ&=M"NG; 3KW'-\.N(-C2P:IP"^,W.6I)@U.^"]LW"F0.3RA+W1TN ?=/&E +3)ZL-R14F82D.3'3?#;HR,A;='YCPS(;?<'.;3.0B*Q: B@?LZ.#] NYXG7>_OY\ +?/X/D-)-E7]5%QP 49]\6/0*/?3:>J09\!!]@SL1?^KMH.,Y5LR0/+AH_W496#JH +\'H@\1&UBDAKB0OKT$E1DZ'4^#C0Y75Q@X+0&"()>76E38/.SN<>T:;6S;4L8:QK +NJ&CHO;FD5KNSZ^#:+"G;W#VIAIF.5K[5_^< [@RMFG>.JQQ?ZHXPU'1&.S#!3M8 +IEEN8C&YP\W0+HOI)(I (<6F[5,>%<&]N#NN;#)18B%=';4G5B+9?^ +-=H'G$Z&T/8/O__8X"QXWUGVD96\^T/:!CM$J_WX##IM:!EQ VJP'JLF?G6<\0( +]1N!@!(;.E?=F@@D8XG7@X+$1MZ@+_?PM^ZGU!VT1(ZM_:-X9)LF\%EZ#5D4?Q^X +>;=E+B[2:_RF#5>8K(^P8 SJBDGQ03E5VC A-/F"LD^DIIC!QM-:[(WO9+R&90VM +;NUG:E6LQ?H%ZI]I5H^U]OC:Q;[:3G3Q5-U$VH<5H609K2FT-NOL!BJTK-F%(->_ +2_0)M2DCW_VR/)^ :"]\](* >M\T0R_+D!"1:4#57R1M7KTJCX;J#RQ\OP 4-6AQ +56C;JA4%0HHLR^%4?.,7$J9#2JE_/5'9?3X:*_*+\9%+91.^'#LO0K,H":5B*DTA +YQ0L7O<;W5(/,K7:L+,"1V1_K(VQ"N+N[:6/$=VXZA:'3!-,R2_@ZL\Z^=B_G, / +P6B^!6;!<+\]>1G:+N'@PN@99_U4HO8FH=7.P,C7;I%Y'(.$N(DKHV8MUA =5B2Q +K>4R*GZ(JFRW%ATU'HDL9IE?QFKL$V:5N#Q-HWB&"'W\*B)(6\,S$1+VNM.\"XS[ +T#+^N.4G&">7.AFE*SWL>JL?BN@)O%+O\ +]M+I#W>?OY_OA61'+L[_I*+MZ7WT &,B4L(\Z(D\-(=F1V&06P_:/5=/@"VS/JN@?K'N: W +P=9!G!AC^"L6V'BA_P"$43I,PQR_94H7R50S)/=';GPB= +"8?/OY7JE[K9YE%MZ5E=HUO8Y\,"-*T[>&5;=!PK[2GW]S4&>U!"0@ZA]8NB17E4_D='_YWXI]%"@2R%#!\RH4 +0U=YQ]=;./Q8#,JD EY@7*E\OG.7AA +4A0,!YP[94I4M^2"^F(!912.(1(V;IOET1 8C9N&68R_?/F[MC0Q -WB%-&>YSFK +\>W?NB<*;[2VY_SSM +#7O%."9*9#Y;]M^7NQ[0V_SAQ.C4:YZW@/.,4$U:)$3HH.!$/M,RG5^W^ +VL3"%1^*O *NFY ?6>#99B_H1QJJ7([GAV/G>:-<'4#\Q-B+F7<4 _^P-%4LS7T: +#B[&G>K^!XIEVDF+8236_*?V'CGQ9;YWC45Q5:K2.;RI?P@GX@VH<:"?B,$<1]@2 +>G"C\2 'IU5B_D%Z+U0]^9^!XVAJ'W5^)3I":0'1:L=%47)$'Y\6RU%L6YPQ1$G' +2D1BB'@S%SLCW"!R(7,'NUA)RC5&9&AQ_UD]"GN,,3X.'SA'!X9CKR2%6PG +WF7D%<8V:;)+J6YVD[(*W?EW%NDUA?V(V3;[UVW?!>W)_93O(BC+PZ@8!ZG+&L$Y +6@=4G;/:S]#U-)/D1\8?EIW[IZ^$A@V8-@[Y8?4EPY=P^7=GYB2%ZS?+31:M G66 +AMR6A@;7S8U#U%PTJ-5=I49\/.+]6@D_63@\@3O)H"H0ZB!S\XBG"BF-94)Z&EV@_ +Y*;>GEY)PN6]2"^'!"E##XD8DV%(*&]LI;>SF/EY B!#E/IYU1QS%#$S;J )O@1G@9!SC4]+#Q +-M1U$#!.=APNS,P\L+!TZY;EC -_ FV+O@>XT'Q7\Q0CA>OR'L.3*S0) NG:8 [: +=KJU-E>^S&@P"- ;B:'R0V-0V0)&%DB+'*>?C&>/F.R7&Q"LIDXX-L0F,G"%YD=+-EV.YA6V'+\47UYAX.K"W!CV65 683+@OJN9H;OUE +"5:370E&D_BA:IXW;<9I%+^Q\P^E/">M\*.U((6%VA"8P%,<7OUH\8I1'$Q"E&>V +*-C'R#MB&!==#<8%>0*7K:!KGNU=);J?*WJ4SM+5P[E<&4JI&HU34[K #X3>FI5 ,38Z@D>G +!/U=92EH)8G&E;6G*$-V0SB$C]MK9I)?0I0Q@.6:N63;]D(@0VTZ+6Y,47PX]/&O +?M%B\7)>0X00?)G=]7294ZL0]V1I2VZS=WD"[)&"L8KYZ5LU=:4;G$,[A/0I^TG/ +Q-@:$!G^4.S, Y".$65\S=HY2Y$X/+H]A:")'L@MI@T:>T6M.+XK=:9#^QWJ;:B +KY@-G=:1WN+3O$H@]L,MK8O-8;Y6H_JM@$H7/*L/_N'*0DS816+ 92*%;WIATYVM +\CE9NV&%"35N&*)$1G;>^:4D_(#B' X#W[G;=)$:XOW$1]\(+L":VQ)=L#^TNU;L +Q-XY4%IMVCY/];9RX*@UC-]V:)=4KC!TB.&E;NM!:5NASR5>BRJX84Y)JF2YO7LA +)>7(#58;^J@NH1$4G0VH$LJA9DJ89"G0[@Q8-[NN! [/%O*8V"-5K/3SUZ!0W8F= +H/8RF"O[MC#6CTU3ZS334^^P%Y)$1P_BL)BNW:%BZ38*\-"]Z;N)R)G[6(G">,J? +6)6YU?U.L(I,/83;"K)23B9*AITD7\-?5-^ZLGZ[761@\@-$\-"1=^GT"$GFW"4\"B-SPJ*)!L.INJR$E +Z=83%I#0(?L=MEH$.L"K//JX#J" 6N6'\A\)[R!+P7TSW$7W^43,:C6FKT^$C [- +"TK->5, TXT2R;38YZ#)^<%>==M/MS[31W2'[HI!\<8F4"#A&7=]+TUV>V.R>'-B +E0]AZ!*HT$,:3Q6HR.%70Q_%XU2U1%OA,+F7Q^Z.+_I[WME)Q9RP;[D0"8L_:'6N +V#EA3D[J=07N'>I(XN(>S>TWII$M^:)QR@ZT:L)) ;20ZB5PCM]![HD4_J&C"YI&>-^65"O18,?T_UYD*@^]*[9\MP#?>G&2SW:L^3?4LA:L15/(L9F=S5 +,M],^:RLZ-/]'^KZY@R%Q(A'R?TE& JK:Z2\Z]YY>BH"%&3ZA(L7^*?CY8<%J6_! +54AE]^(VYX134D^\IB^:C+A6]J;@*+1YHKQ$#U;(*!6GR+63=5[ZK3D3'QQ)Z^< +_W5G$L&.*8Z0"LQ%,N>OBJ9__?[Q1/G+];MUU*;\5C,_\Q&]RG746;$C[,H+\'V* +(3!'8N%%Q1*$NLEF.U,*S!+5E;78&#X#+TZ:97N5\G!-KJRDYJIX1'3#IJ$S/!@=? +M_-7*X")4.DL:K9=>\J,?R\9/=3#BNF\/YSGT@BV&BF13+*1@ T7_:%P'9 +=RZ.1T"@A\2-M9[>%3K(,]$]H/TV6^ KT$T5$?(IN+;!F/ %:R1MK>2KO986TA'[ ++^*_=Y.B%7RR-$%[X40795]\]M@I^[!M738#/K:LQJ(U2)+AKQSMN&!Z?M@$P=CT''XH?FB9@]GAP#'_A_\H!= +>#U )_NN^4RL(RJHM$D/ZAHINWZ3_+I+//A-HFZ%Q%+3GK^:-VB(IA-99^5X>W.3 +$@YY%"8H\J)1 B-?> 0.E"U)2 &=[X\%167[>.D_I!S2-;TVF=I+T0I:U2'D:12( +!>+D$O2Y488#'0/@V-Y;^7T;020E4*M!\!XWZ,;%USQG:YO>V@Z&+Y?(53A9BYXJR,M2W1V5)^FB\!732]4 +*!=[/GA6UCLV%?@LS0=JAE/XN\F(O+O63^H@YI>'[=HD +R]!Q/1)N\!7!XMFWH4BT5'G1RER!8MU]'7\SBBJSFW&1<3T:-=;Y-]@=/BBUU]?( +EXB#)D9@9(@_M)D9 >/_I%=OQOU-P&7*MQE +YNC?M=3>D2))M_LZKC0>1>H!+MK8CX!=JEM*O".<-^V:ZVF T(!""ZA?;9IE@RQ[/2.;J&RZ<9?C&7Z[CV'Z4$QB<+'GZG6/(B3B_[R +A0BKW"WY71D2,IA\V+WL\QY3/]BERWO:!ABB0?1R%=2$KQ=?[[(?*M_@<9( +AK!+X8M/6^^%3FL9KIF*:"2DI5Y79K,<5?\IR2)58G:?+D_P,\)5A'Q)L%)O^('BE,8M,JIQA3Y)=?TU-Q6IFJ^ 9X]D"KR, +JS+[8U-AJS&QU/;^NU/^HIZ.8Q5K,^FFJ32%I!W;@4::=YLL/$5NOL>Y&FJ.6[XP +9'@/W . GY%?/6MTM[YR!4Y7JZ3 X_!0VW']@DJ_)?6*-_AG#;Q.DMI[.JXAT< +6'TQ8JW6R.BY4^)C[=6L2"%X9*W[/0G3,F?,[\#GH#0!Q9V3]KS\U7&RR05:F#U0 +5!UEI=T7>9//'(\/;'<-3EY0^.V +YF^D/N-"@*W@K9*TB$<]0T>W=T2'P7YJ2@+A2+:S$&R/+&_6!M^1";)P! +F%0$V0F*TOZT@@(L?/^/5*URH*XQ@#*K3MW<5BPY$/N@-[$+6D2D #]_U2#>!6VD +3Q^6"M%&,OM\!Z?3'D2#(#:E=R,+D@-MH&KP_!?O,N"0RNWLY/YF>^ G@)YR)/&" +!;//?**'G8J?FBDO>$>D@NL5QX8B%W6#6"VH]\]L&Q%J>QT?"4 ],@6>(K4[K;AZ +,5>_:]/JRS 1CZ1@,BY8H&&Q]FS/G]I +9= ?_+]P;VUSFEWT^M38:0_4/ @:R?1QZ_+.M/-<$L./LDJ#7NXX55 +\<, 4E9A#W41R''HI"I3LU&F([%_!:\C2"]G\^K=/KK[*4R]RRS+6\=_L?RL^XL# +I$4,N%6RMR.HL\9(AL.B53,^*Z+HC"#:L^!XV^) +;\_.6 U5-OKFIMU\/'EU;9X/_*"R_U%4?!_)[V<:EF40V"UXG[#*^4F*SXV&;7H^ +"2RNL,K)>W#4PQ)-G;[.T=\VL77G5L'8QUFS1\<1RV=*S@-ZXM=V1LG(_RP=1M?& +,<3AI7?,>GW /7IW\*(G'LX$DXN4YJ"5FUV<72#'O6_03-27+/XH_/I5(Y\_W)QS +-9<'LHD5Z^'#_Y*./ W&2?5ZS%"CA)3E8\N5]-T&2_YVA#@V66_>';':\3G&0^8[ +Z'G_@\1(!?82CKVQ-AB4"LB]FL1>+>@ZYH!^A-O<45.J :>T3#\#)!S8SO,[/%3' +)%K9V6!P[ILADOOQ\F.E0*>TT3$_%("!R4+"(RNXT-D=P3Z\^$@!->/8UC:$7G.I +0(!U,Z,H*R*3:U132Z(>P+(B!@.'=:U)R)_5S6+37U/!C(6=G#MR;JXL3/KMQ?)7 +' 0G!85]F=NC>P'B$'6SL9.OM/)0RX;VP;P?@OAICNA=.BD6111S<\9C(]F$Y]X +UKEWWZ-/7AR^#FW/U]M,<(]2N86Y4,;4;U9U33D-C]3VISU JP?BS#BT Z093G'6 +6@M-PHF()25.*A@^O43K(W*/DXYT2Q()FJCS!\E.,3X( \8!3M?SF:T3W^!25:I[ +(@H [53%#S"()(P*2O"O!4<.6C2S_+K$#6SP3/72] )S#7"-^#+B'G2P'?L8]9R> +=^U,*B:2X"0'Q6&.>Y]%:HA1+O7:H4==)*90<\/*E(;*ZS'(R8H=H@?@.4Q$^.FO +Y%3A&X.F^=3W-\56'++BQZ6#6"^=F#)DY;W2KTX$9'DD()3P\*70>@!T/ON\%$UH +9FU&?00W0FYB_!>[%$K=@X3.50(UC#LRW1U)]"?#2 +F*.L(4Y24JF^+*NMF(H6T'>N%,TH2&EU6BIST914T&*W]-#..G^A<X7/^K'A'(D3E.:;I))6GYJQ)=4^8 --'D.6D^? + QHTR=>J+ LXDE/]RSYH@\ \"+"'+":X=A>9-]K>B56PKFE;B1^&+*O6//')A]RB +^CY1X]52"(K2A+A$G9%5:#0M,+(6E5%GF.Q&^!59*JP;A9X.]R4RA<6I:>]EA)RK9_N(@D)G];^:]\^ +#Q\^Z>=_H)LEJWA3"!3J^Z5TIZPM\-#VTN"U-?,U +"5V,L@V '71X\CP%Z&^&S^ +\+"0)KZHY:6%9:USJWUQ#U@\>UE$CST@(&P !IG+!UL;C$@//8\@H0EV!"SOOJ)[. +]@@F>]['E7TOA@15;2O[Y#C:9DX<37!4V(L8O9H-?V-JI++$KCC03=4\5W2P5N-Y +& +3T3HLN!GW"Y0V^'<'T >J+Y[K!C;C@DN4(MSL..\^8:@%5:H<0E!($X<9VM0/ 'E +H7%7)2IZ*OH_="SB.U4.^1EBCS810]\>S;-->[W>B#(Q@OP';\R?T9\)]SD6LK/$ +&YLZ?&FNTJ!N\1G[07!QZ7&CB]5_M^E3D<4WNH0A(X8--;+-7 + 6/^U2# 34>(''ZS9- S(!SI>(QKQZW&$]&.RJ0Q&RXKE.1VD;_!L+DIC4BPY&^" +R<@R.&31SH"H9,%9L+1RVO76$5O(R =?TN40.P3^8CC'U6 +C$4J-,UH:0>0N.GBHIL^R#K @W'LII.('J5SF@'KP8=H6YH#'>$S$E N;/T7?A:4>D#1P&!/<.VMZ.YT5M/#4A +7+&!^=*7S'(5"W5J-9H0TRN#\ ,Y];AE*U>$[WA,)!?[#76@L&G@WO]\NHC($GMH +4>0P08L' J#:KK N4)+ +$,Q[4&'6'LOD"7>/E"7(]^4H434S@[0&RC!"CH6,'+M +SS4-=$[>P]@OHHV5W?/_4LI 6.W;LQ2(LKLMEFZ2LS(@/BCO#\%Q6GGI=K@1'9)RD'V23&AQ10*G21!LR"LIRE7Y"R'[F/[*Y]JHD#-=.ECKX3ORDB7$D4\.QP67]@IXW +S;^B;N%:SOZL1UB_RWA;$D9X[SSGJ/P)]J +ZCBN[OC,F>)O2 5KI@W]CNR!+_V/T&N0* EM*:347'XJXVW]14:!*D\O4#$7$C)9 +@'/3F(86:_$*#T?0U[V_?U[A9/I/OT44;.;"ZL\ BN!!O4W#ZM\TQ1CKXLZ>'*;M +C*)[JV8C3(H4=@S:7ML]'QA!W\3Y1V*^,; 9W6(AWI_B<-QK!+O/1I +L'2/8P,#13VI8>?2P%*ZG(XYZ3#$Y34]X_1]((MNP;AK":-QI@0,&_8_B\GCB E1;<(=="Y1[$AS;\RU=D\"#NK Q-=%.^62(&E:6(1WQFHAB%_N,5EZFY6(K +\U\ZI.*GC=_P\0':FUY$9D\W4W]%KWBT9 + G57-69N!WFB?["" L'#^4&X]:3QT X22AL5L!D#D9RXV4N37R)V(*MIY$A5W;S3B5L:;@D?Z1QHY!# +)0S@:?#S(B$P \0=5[T+]B 5<\EUF@XKU&_])[74CX$3PX9/JH>&6O)D+@R_?!Y0 +NI>E)1-EX(95YL[?'RRTS"YQB>@L.)YJ2*ZWQGE9F>#8JJ$%5C5@T64+IM%*3@D* +[$\%M?/F'!>,",I+XJ?W)[N"I)D5L("=HB:!:3I>ZB4'*SDR)CO +>ONJOK+>6CQ1-*(FAW2L\Q 7%-.?7* @JA,!,K[GF]8+33^;8NSG3BX\;87EZO!N +HGUR75"M?JF0:D\M5@-H^,C\3WD^L>4\TC7.M5A7:H-WN_A91M>L=S 9RY%@J*>@$CGS +IC75=<)+KADL&*XR+YE+J"1'+N-^W:F,-3DWEEO6"LQDXR\-%$/B(F^K +^!5OEC@44U[>2(KZ:9>4=/O^4>F9X;<&]?I&M0@#P4J)HWIZFT8\H'^4&*2^[W]& +36IK\(]-/N$0)+OSX'LHNCJ,:KV(#$S6HZY/.URPCH% (BRT)S61(E714;YI,1*^-F\& Q>_C<\X.4*'> &_MUGV +W@P%LV(E)"&Z^"($;<.K]GO6=@3A42Q%[QD*4&18N"*+X=C3(JS?Z#&:_>H$71B7 +P P&D=D[95<[-:%>V\C[PLYJG[_:CN4W.$STD@TZU_J=/E=(&GIM$YD:+Z9*I;!; +<^&H-P.\^UUFY/F_"BHB!:$ ;&'+)7=D3M=Z]C.TT4[34F=7>@Z[)6&<2K@X0>8S +Z'A#0)#OK%7NXM4,\7!".,R'SR"4C_"^FBK::7ZNJ6T:,KUBJYMB4TX1<2'&#L[@ +N4.Q@!+*%-9QM@-+%BJ*30FZ+/G,LKIO!=PD#X[V6&_0$>P^U%Q';,) +/L"8IU$:%,/+V+J@H70SO*\\,+R$6Q&WI*1<\X1CM=_/M[4#:%S'\"*1G8[S?O6A%%4.GZLQ6[FL:NF&2"9M>*W!2'>:PBI8I2O"D).C*_2B$C +XQD)X$((F/%-5,)#F^U39[J@=MG+"P\QOD"MW8;C@ZHP5,QUOYJ8H',)H-9IWG<%=E]8Q#BV(EU>3$/9.QVW,4F*%,V/Z\PJ$:=TTR#8R%P +R&(%:0NF7BS!4*+W4EQ,$=/OFS96/\@W+%EBR90[SI5+G2W>R4G7\!%@MC+D]']+ +X6&<7JLT8?LGVCZ0UNJAXRFT\3Y<4JK.^PZ=\!">2QF.NUF>%=^USY8(?P"B!M18 +I7RAW5DMBW#0>=">G6JH. "F7=R'-3Y1\G$H80W>,+_S^;*KE/0&?LFS.["?=HI$ +'QQY.^YBK^->%\A7&6=R'G%<.@I6J$(JFG,HN%4T3[.(9B(J0&Q$BDP^/35*5;H\ +%?8','R)@_Q*U(VAC$9?;]G$+AEL)9%Z$F/%O4O@-+?8YR&6.KY?])+X)48-A7H2 +=-IIE!L>V7R9"<7IUP2UQKJ.(S/AB"_B*QLW@< [OB+NQO+.W*Y9=1YZ!>FIAF+] +H%^!F($'&7%\)1+X#=.@V"5!'@XZ>:8Y_>@40P-,,AQ CJ[DB(&2\E:G@&X=E1%3 +7GY>FZ!7 7I&ADE;^,0:= ;IXN=#=JOUE +J6]1B6ZV*.QO:V]Q!FC*1E9BA\;O?!&1F=5*Z1CORK!Z^_R@3PHV(8?+^&=,)@=6 +L(*Z-0A3+B&:@HH$BWI5C;>PTG3P"-ZUH%&Q-*TB WII^7R BU4H)/5S7[YBCP@5 +F_D3V[?H-)>*AG^M]!6WDB+*>R%)3<42M&3^!;C^"3&K5Z:0.>>M<^KSH5C:0\V* +?B^R5D"K"KJ)S^#.D#QB*"TEWN;4Z!T\C*'0RQ1Q40$#,QT9T=!T"77KN4ZVEX/ +G"F.# \&2QB\U!$/LL(#_*@VT;C5_WJ%)Y8YAK#'*_A +9J1@$@C?S1B&\A9L&XK(;:K;+Q?#GJ>=]HW>MD*55?K*R['VG(>U>:=,"ZKD/ RE +GV']5QD7(65"G,T)$''I]F=5FZI00TTZ8@0=FGC-#M0=M2G/0FU0]M_MI_ QG,\0 ++[.OQ9SH]AO@L#)[$?\6Y ,6I[-E+^( C RJ:.PV@BMGMJRB/!J:;&$,[N-[!/I3 +Y! QP%U8Q*U*0EHM_X+;LG2&HXYE2MHT*@#VCM'-=X#C.'4FI%(AP-.E[2XC Z&,9* VJ$+#RD8G[".E=5>BG#R( +%M[ UI((@W8?:$Z78PL-]J8='@ONBG&^M;$<2:-#,8;?'>5%:ZF'\%GII3Q"/D.?8AAQC6Q=#=2G;C&(!_P=%7/R\RG +]U2I N-%:/>K5"#'5S3NM.CY"R!@X,,$"%%=+0U@+_>35K81*L$%APP@!\3DWUXW +@6XOZA'0>?E35ZO> F3'9J(Y93:6)RP/ +YBQZY_/GMH(JL77WGL=PHYJ>BEK40Z;U'TO)?A=B.F/J!,[J&NUO9B!\0YX!*K-0 +H"X2(YJY>$ZKW7]2G/U(%6TDZ$5YK6^0KF&E9?KPYSW<6WR4Y<"J GE[-P*I2CV6 +'[?[Z*!:>SLJE)>$X,-9-IP#HAY2\KX/A#\6=\N:,!BG-;RAB.-Y62N%I 2]7>62 +7/S[@0(F0(I&NV(F7S)]B;Y=OD-K.=^>#WO9FQAJ1="8L88A4^[4;Q$))K(;PE7( +=-:.5+?9:3P6/?:19>A(?YF"PWKLA(5_ PG$3]61+,#"65U1(G^#N&%JW> ];Q=J +U%BK.?*!Y.)>SP-[>P#91L.Z@CG^8'!^4?%#?5?+,';XDI7T(B=VH:T70)U+6[B=!TM'9XL3U[\[JYG(9G]0\X: +4,2_R#1=5.U3B-UK8M^U$9>P').5JI0-<[<)%,I93<^-Y_MG,']D?QVI,KE92CS> +MR^/PV=(G$P"5TZ,IY 3$*(=2%TI/)+?D*?.^=BGL5\EIHW5(L&P0;>MAF8&+EQ[ +75OFEXXKZW"BAOT>^K/8IM-AS!";]WY*[C.G",6M(1QAQ;Y;28W8.J!9%U4BYD2R +> &5='("FFRQ5.4+H!2&%'K,M?>Y:?.^$.O'VE)"^?,<^9[Y +4^=(,9YAWF@>V"R%G>Z&O'*#ET4D3*PQ#XC?2(%'RE$"EA%X^4^!2#:K:5C]DVZ* +.U(LMBK7=_O /U"VZJXG?']0Q-R6AZ$C$SB:%:O&P!&37Z-52):N2VO!' Q)KLZ$ +C5VNPU&ZF _JU2A:PA5;X_&D>]MG-8*\5U%%S_B'8'):SH*AR3G%6@660K)'(**> +(/5)7W;-+AE=50-3__HNCZ7H ^F"5/R416ZU$_,@7J?@\AH'A3MQ)[O.C."]DRBH +*0QJH)!:/Z^DY^FZ690O?DNYU@(N_XP,9U?$0S^B ]JPNO,&VDKCH>][\#S\F<%M +#G1I9;H7JGGKWN/EH75QTE5UD"/\9!.;=J^@EW''XA59E>&68V^04'*M3[UOHBAT +:LY6#8Y+F_J9@SHA$V"A\%^)=,.7)F_JJSC&C U(S%S@X,K85UN;GL.::BDC#!:A +)9SG52*(1CEJNPA1!2_ +C?S1FAM&$R;. L/:2X?J^LS0E[]@F/X3RK]L90KXO!6 +>YH(J#9&ZO3LGG^D/%8$+8\6T_V+>D&8KXR1?["MP)8M7;K]Q;K=LXDM1J/9)KEG +%K-Z#:7LM(IO%%G@(?W.#MC'GNV]NF'_(=]=P*@IC/6Z8=OM>,H@(X?KS9X5G +DV.A"^F>7BV3AP7>^%+TM"KOB?1:^)20^Z:OI.10S,Y.),=A+@(DW&UA +?[7XXI-7N8VTKRMM5*(J1,*IR&_8Y):1&Z:)&9^@@Q#AB0SGY*(]$VZLH3W>V8,3 +[BG'8O/ G8C:'"?#*AH2K)E.\^7:WD0I K8AQT@_#7/A-J3<>$E<.XP&]0P]*4SG +]%N6B3X^4YLQO?20R4;+*1VIO![$\18Z$U+XIEK /YID*3O6;8'$D#5BR;[C(@S7 +UD::7NX*5PXQW&7$H43S*<+:B%%[=>;XR%ZV1DM6/>1C@M&ZN#_VOBGI.'@'ZA(J +\;MA#9#)&6&N)KQ%NT9HN">]"X'=BN2HD$RIM>VE>!"HR2JCLBP!W1$SB=.U$4B+ +Z/K3S'&Z%53^E&](WB[*Q5H--:B^U%SB]PC^#KZ$W!$?LY,68;I@FUV?%C4GP%6\CC +F]G?N4)L&8$IN@LWPT3;:+%)KG!D3%;0G]RD9!_7VO$(F];=Z)&GU,38PU*0_%^(24NP0PQ;1%?L(X9#=4UAXK62\;I?75&/XM0+\\NY02+ < +"7(6.1#O1N\V+DAWSLYFBW:9RI245 UYL?YW$'$FP#\$Y@D^V$!*(XWRT+K&>0(X +@0D^$0(GX_!F%(Q7ZNP459@;,2REZW4@0VQDR[@#1PGFYBH&*4?I988 1?H=?E\R +#3(# M0,PH(6&SQ ;6%Q+%4#8=P0A+.#CP>FC.1Y/]Z%:&\-/L!%] K?6F&X@9-Y +817:W&\P?93;@#M)C.;&9+ZVGA?&B/]($Z,UL!Y)Q?0!R(C@?>O1CVHN_TYC1!)^ +/$F!$*@!-NP3]WQ#_UMRJ5Q4#;2^HRJF%:#[FONE&<2EZ4177'[&4GJ;Q4:!/-7U +=06B74LC%DQ(S4?9L9&EM+XKCUO-! ST-?(GSG;?-4&L;EZ45]/,65=.LFD+U["> +*8; ],K9=, +.:,O5=%!Y>(\3AG#/T=.>!BX(2]<1%.U<8=1!VJ;M1HVMR#G3%V_D7Z@9NHU6#$@D8VW(ME;KO/O9?*8_=LG +'XYJ3I$,3&X)QO*[G*C^->#43[%JBO< >ZHV+4D3PP.XM"/1B+VT@Q-S5$$0CZ0P +;/6&$Z.H_9YGVANG;8] JS\LZ*#HYYCMJ=$BH;)GX=R3B9 !?DN66*! +7/;=.))=%(2;+9#1[%+%<.V9EA$D'3JR:U\6=\C5A,B)C^K\#!L,^M [W_F7,J?V +UL@SE]"8;BX_MP>%R1\HBX[R,2Y4NG_UJ ZG-OY*J?X ++S8H/Y&'5GB";8/RHG&RG-T#__5U)-BJ9/VIG>(D=TZVU9"9YB#$7/#AA.>PX-&T;A !+F86M6.V67>0SN6T,\ +&%UJDJC&PL+W?5T-]=\&FI)B\4M/F/R?"!I'A>7S;8TXFH/E6H%%R/Y#*:/AZW[9X:!H@][)'T'S1=QF#:)+"NLD2V=4?V>( +/J09I("@<4?YGI'^36CP>4;H_:H0'\89INW2WUKO3!AZ/6H%T_G@F[_3&>X;\H&* +1G>S,3_NGVZ@[$@]O5M5\DS]K69-LW_)718J:) U-SM.P=^@9U\;VAB;#QG^04S] +*=\A!WW_3<%^B6*@MG:&:7%OS?%O<.@:2L+(=*#+RAW,.)_E[X0KO?X"89VEA"X1;'D5+0VZUC-0,==="I%T>&]57XUISJ8KMU>V +6.K<(S#BT $7&>7S OY6459H#<98;NBA+2UAL]C6IY,PTY0LA5;Z\'*A=)DEW4V&J73XYV\.?QJ?^KA!K>;^#EO[D/P\8&B>KC6#6Z\,H#94\J +DA@8L\F<:TU\WM71R#IS2ZF0 -LWO43DR'+]E_]S[>L2*9SRW",<_^QS;E1P,"K3>X 6)$]02W&*3T'6!!]&3G,0Y)S& +9_WE7'BPK?0V[EUW"^C-/\'<'6&LP1D@?0EA2-J@AQM-)B+/L\H2OEJ^4\89.DG. +$(FO(UNWJY"'SJ9H 8SV.N[#]08:M_1=Y=B?((@7"'CTT6)E +XOF(K!-XE[#JW$=9AK)MNUY].SCYB*4E*@OZ ""H7@G#G^Z-'59VYF;D..'#5=CA:'*IM\>U +"D+0,\+6?U SW.#'L+E"OX6J@A'>ZXJEY7(QK:F@$%S<$_E3!C-FC71H)7MIW,NZ + 9BSRNSXPD;>6/:Q_^#65:_2D!N/&D$X^)HZ%@/E!-^O6/M+P?+&:+2W2E,RI';# +MK@C>[2(61;#@Z!-/=K'Y]Q-D<=U).N4)G:#";_ CS,/0-0XG?>MCQM +F;P&Z;BA_XO#J1(11\F-J,?:LP/LFQ5IVO!ZQ0D7<*SXZR.Z<30N:693&"XZA-1 +U_].EO"OGIXE/L\*#5ELOM*T RY95+4MA?97#C[DQ_QO?=<:H +1#L/WHK_/X8^? +C??,L:'PY_D]>%'G88]G@&6)DYM!.8;UX;,A@L6149OH.4,C3<7B79T"[+D#N.'S +5,"A/AX!.DMHM-:Z$4-MKC7B<#/CN]L8KU%%E2PG=3@S,A6A,VQ:>P 8NL#J%_*Z_23NTKJ*Q$M&0A,@3%]P7AC_)#AH#! +@>)C#'M;%'UQZ6:V:\H7JAWY"%O&PA?KM)@9/WW+5>7+ZNLR,QC5NEO%==]R\XWI +PD-OE@>7T ?*G?+*!T,#MKIR'],:-!2V6Z-0F935EUTNV%GN0QDI*,*E$"(#;YR% +7,R?UHR^)E(D-YP\L8TQ 3RNZ^SN]AR>;1%:@=6VOHR/!R5ZON?ZJ9Y\GKIQ+BYL +Y+Z%];,GI ,+L^K-$^Z*0!MC#%G/%@&0^X? :\T=30.>DHGOYJ)BFGNEF)0+IWN% + O7I-[4YLS^F$9@EYRWNC+J[S%K[]40DOJ7N7A!WV(1G8W9>'/5_:$H=@B$GQX5C +06NJ^5E+C*I)R"L\GS]5[#OH!*B0WFO/C;JP0<"J[IDQ;DG$V3IU5XD\(BQ,6W.Z +N2I\H/7PXXAO$J/8-FFCA_W?),[80V>G>F/YC?NX#/DM1;8F(18&5PP^-,G-'K.0 +,VE;7]L#$%1$DXRG'6M68^ KD4LTVF=Z98H.(.&Z==$?\\,C)V>DMU,%^X*LNX"1 +M '8PL+T8FWV#F) ]5FMSV*EDGJ%F9G9.69_"&2X&%?]Q.4RXF"B"E +\(TMDU.3-?D3P4X1VYY>F,F%/3?=X%1.%$0C\Q6BIXULQ##D/&DE:A!18F4"&WU< +#N/9W<:PQVR&<5A:6X,UM.!B@6<(6Z+G&$<.3ZZO?'+ZA4N87D<0*O5AR'@L+I]= +;OF[-^-=4N[?<5<6(%Y+A<89=?E@%4Z7WZA<5V**=/LK*WRV/;(Y988E3_7$*B-9 +:A6G8*6?X\+YW'61.L3"<:L';CX"X?^:>I3=T?D$-7,0_CD^P9??6#%IUO$$L:F1 +<"2=Y/0>B07OGHR5Q4=1V6;L\VMMQ.-E\,;5*-NC=@ 2@\$&0N &](<69,DO.<\B +R\TAF1W)FD%"7 _$3A*" JB\?WK_HS7R]JG7S36[T4+#6+QP+=G4;&[0P.";8A4I +7*=[#H^;G:$5@F@B[='0(%N>^)2(J(0"D\B0\J\%I#!C+CT/J]5T6E85W"I*=R74 +)"88BV=82&"CK.13'I9$..]Y]&;-Q8E:!PC6?_7'(*EW).&\"UGO:#>9OIJVS(H@ +0EQ[?)Z(ZK%"/64 MF'!#(7W3OT!0^O*'WE9()WL=-T GAX45#.[<%"=N5A% +8N>A_+Q20N&N-7R?Y-IM'+J)M$616D&H-/.N]P.)THQR8ZGE+WC(CS4^+4"FNX I +*:=+X3<9S1"5U<+7K4X]G(CSM@L;+;*2:]&-A>*21HI5KQ'/*D(7A<5 +JG]XYC6H+]U-;U,">&1OOW:7("GAGILF#PS<>I6==+X8*+%K,8S,(&C6/^@S;GW$L\>#E^8:B\AOZ6H"S$G!K\=$B9 + _3*'*3'IF%@[9Y_@&$EL<2%'#%YEDR6H+2E*R#MF5RL?GFHGL1W1#LU5YJ5"/^] +[1-;F)G$F:IWJ"<++%N?4[?R3C!J2$&KX?.8(AV1C)10UEM9D5A,YR1TXBU5*](C +0H?DO?P8+R>OD0/82-O[1(F.-84II=7 +TIT:X1X0-]RFKU<'I#WK3&YCW8[%0X.[=H.FJ3[3?@7)-7Z_&9Q3*[]EPB3\J.+% +UU1=F%\W1F$-I%_GYST&I49;+U 8T>3^E(*N7D$8Y3Z/'2&WU7TG(// +OB$WGV(188."##*!*"\D3B6'G'HUI-(K<-*B6 W@DG^?GZ*W6?3PBD8^!R""M3Q? +ZDN=QX877Y;>^-!EE?6,O\D=%7&/P;6!: IB2'$+:38:QYD*IN,S[>2/ +\?+:/!@#JNUL7;LMIKL"!,T(668:9!;5?0@FE072_"3 ^?3R5\ 4Y(+;?20 W@ER +G/E%@Y.^JWU'GPDB%:/@ -0:4_)\^N!'2F&Z<2B[H^>N2M]+_/^UDV+1+%$W"N?$ +,NBYI^&L>)32EL5VJ<[JF123 #EQU?R71I6UG^BK65;!6WMW4:&-\0W-^)N@*D& +2K/>WGXV.Q5T2J#Q>@H72)IR)Q=QMN4.0LTU*#UE6<[YF]MT= +3"18QVQY%]D*>\%DE^92V6J#.3IE0;C'YA?2D+])A?G:!>*4Z"U\VXS2>\D4@5(7SK!F;%VKD/_%QR78=G7:F61:Q>_DI%"?D# +%*ZC?H%BB4L!IF@.! 2F=42IC=_,S?B%MMS6RPSKZSQC#\S$DF1.D"7*;N1G:)MT( +J]N<]./;<:4)-$+X]5WZZ]$&7?B==3;M[4I>]UX\!E4^OQY3Y$)FG_BG464Y/P%U +U;H)<=IP\%$WZ,UXY$"MODRTZZ!;9$L9B +2>?"WRZAXII##*VB\DB[$&JC*5^0A6I3F0H&\/3T9">R..Y +L6N$"%$C9H>7R")3VO3?^[XRD^#Y^N,K=L,-D.P#CL::Y.P]U+XI'2@/. +05:_6M CO'&AD+JYBUTX$[KW"OO'VH&&S\G:E4-MFAP7P,MU>C=XNG,; +]%X$CMR\CD:\];RIS=T';*/$NFE]*T:> "YFI6LVU:3]*Q.3H*?X4%GV +<^$=E@!"$J;H5D)IO!?NVU-@K9TBJ#>"_@5F^595Z)Z]@N:0 @9E.(+YN*%&U-F* +17O$ )QYHR:84G6H099 +_I32>U;$OMB<*_ICPBWLH7X\Y5OH-:ZS/=ZC_GA/A*'37;^#D-G?O>7,NCA]EAX(,J.(UK8ZIZ7RZW-6I](/_9TFF!"_V>;0ML,2!&X\7A^(D*1 A$ +V+:6%]-WLS+ 8[+4:GJK6NKZ1Y&AH_Y(JO@[ZFX;,Q;#0==S_"Q289S+)ND:^TV- +,(8+Y8W(Z\N):5@6A' H"/,0 <+-P.20!F_6"AW@S79ZCH82@4HOZKHT%LG^VG[H +P&I06KKV&,WN9?Z7 OT'XKH"EGB!&'6ZN?&[Y\]P7;1F ;)TNUF;58>/R>QZ[K$(GD5TQ;,U9)1(V_0Z4GQ93&B*E\^#>- +]-<9[^?U62A-^ARIL@UE^[DM +"_,A5.#ILPO>'QD6!0>V"R3B&E[Z+;@GVGV?[8+3MF3NP25I<@?YL:SLL5K\#+/Z5WHN+&7&TU'>*;;4B>T\CDXTXIR/)/UM)@]06BV= +<-5;.'6.+>$D)UY-%_RK-(G%FW=X4*?A;(IM'90 )CGG!F/91"=7TP[=@>:9;%V- +=B"B$<)KJ*Z:^W"*4(MH(O%Y>>R[W*43]18).34E97?HN/9W@#OP=B0-[&WV]!WD +22F6S=E[CP4YT@LI_^$+>P(I;V^8 OB:/9; TY7D=F62^U 2OPZ>D&NV7O3R-"W@ +:,(3K+Z(_1B8*V+:W,I9>L'OTY+0-5?&A2I2TJD(SM ++Y<4RT*(Y!<4\5<7AN<4T#R&)0F5]?HLL!1/P3"I+O +5OX0ZSC'?'R]-W>O3>]7&FGTWD3?9B,LX\+@S9^44QF!419 @NDJG=S%W!.Y)O!_ +#]-P[B(?O_R%$2P$]"1B[I,A>F%J[H#X +H+I%)O-O3)Z @WT#WLDKOE>(]!H^"':S.S7^..7IW1:&]V(SSYT0"IXCHD_I>[-E +;!(&W6N3!NV;*C827[NU$0KM/ )G[?C7S7IX8?&U8L-$R*V*R")'*DLGI[7:BP<; +):E 5JF-.W7[U,M[ PY1HMFADT>EC"UBZ0U#%#W,EU@G;@#\I]J%=-(]O) #[[(B +)[6_/XF\&O:\^'(*5$]A5EHJ]R_)Y>9[[%G/;40FV14(6LQ>7=5].*0O13O4AT[- +]@A(TJT6N:>2=8:-Y. XV!NTL ON%L(*''K^8%WQC3>Q&U$NT39T+P-K1/ O(VL'2?!],BE) +BQ03ROTB\-!1=#3LP*P3S'$5PYR6^X1EJ8A<1DO&D(38N*C'([[9Y_'& +1/;I]:ZAIYY9;T]:9S:VP+7IG'VY701=/R!5:I.0B.H_-EJ+;3;&Z9/ZO*LB.F@& +J]5 GJ_9\]*DM@TQ6N04-BH@+O79 !;$$/=48TA6-&.T> +\Q<@K!)FC< +SUQL,>71@UWU$RW$\+MLU/\&?S7]Y?S6H$_KGEAI)]!XO =(%M[)&V2Y]0L[6:18 +V^O1+_U+<-$>$05*3Z]-#B)4SS].]*#S%L_'IO9Y7SC]'T1T[^]=193[]E =9ET[[AL>^.D-+&Z#/!5P7(7\K%,.U>_0$\-@&I[B2',D&3VPO]ZDB-VA'H +\\1-/;ZMD_0QSZ]N$SB6^R[SCO]F_5X@ I;@B1$1;E(&M:57%/CA3H?X>JOCQ6VI +..1:0QV:.;+[EP#A6B4-@XH,7+8RHA3_=QW0PLI4*LG<@11>.!/LH;;;A%H6W_V# +$ />R/);=!/+PGX5JY.7/7'N]A4"#GR<>/,U!2)[-A0:PX&[9!P7E15G":-W)31U +UH=5@]+4[+QVTRH@@69-WL7^5%>I=CRCS37/*'3&KHCWAJF)(V0C,RE*&!V7M2$$ +[[%R,9?NZ2UV*?IE,E4^#)T2O]8*8P0.$>%-0!16$AV#([ RQ\$M._('1NG*<-O+ +#Y?\N?'^L=N*%P;QLIY^?*,=)O(SIE9M.XE9"8L;%FN&Y*KJ)WR.C2#^)6D7IS 4 +D%B!G[8I+-X!ERMB(8E$D:\GB\F!3%4X>U:A0K)PDP66LV(Q^ZBETCP5$/& G[#+ +>L,/XSJQ:<81NX52@E2$&B^"F:OG?*^&NZG*EBG;T%4#-X'UD&3_:Q%G-O06-!<,,4@B(3DBK*?!-=^)X=;5+2*OV4SRW 00R)?&@_)IR[ +\N($L"6H/ W#OZZ436PG!',:%0INGMP,6=)X37(%R@5AP6%P9+"&<&//5^DOD<62 +R_ F])A=V7UIZ\F\2_!"-NVO?2H^/Y#IQ#EW<>F$AGLQ\OJ#6?S:+>'6,E&X6-P, +XJ+#O:UA"^U"K?_M^!1$0CQ:8OY9O7)F1>N:@0V#ZS)1Q+Q(\_40'*5IP!T[7U)S +X3,O3N:3OIE1C;T] 1^,+DP2%&!^G>*8IQ6L>V#]"/AFJTL]A )QQV2H_3RXH/MR +FAV+W?G#.5?OK0+F/MTRRO&F).WM 01V'*?.@4"7'Z.8'3%28%5$4)7P.!/,V#JD%F=(")Z.M*U9\^#Y/F+!]/^0"P5R'1U/CT".V77@AP):;@<@QQCF) +@+ABF\N;.DE:[Z]&'X8)1!].5/#'!2"+H'8P^V(<,-C7L0%)+XAOL0S/QM7JP7'$X/$U^)]\]W6F41<(A[I&$A16MB)JCE(V]2QN.M"A.5$55("GF-,R>.UNW^OS +H.&#?-Y"))IE4T2VLE3\%LY"0"@R.AC.@;ATB;N+TG +\&P1]UCSONQ/*G1IM3ZX$ G F%R"MF!_Z1F;/I&8M.+%'YLC5H9@O98(3"SPI%"? +_6V@3Q\.V)3O/?_HHO95=+KTV)Y?]K"WA6Z^:YF2$6ZCI=Y(TUKS=4[WLL7-A7!! +QKB:+;X*^).@=+HZS_*JCGZBR[/@8-%:.F0(>/LO.019X-_*";/L*[XUCRBF,/7' +PR.&?UE6,*H'74!C^MU-=ZR& Z_#MA4QUD^ 56!Z-*1N4K_.<3IW=]<:[KRZ#0S6 +Y[JE3:W75R'/;K1B=D,Z4[(J-J3IN#B$V/U!$=GZL6W7Y,$Y3M0LA5JR>*G8&9)@ +H=I@X]X&#:%+#MD_U!C>R^>ZL(5%GB&$1O?G\@V=:?/(.,Y7@851O.D1464LTBENOOP%IA%2[/@?5RVW"/SV^P H* +IT"AD4CW_FNC".3$ECA]R(_R3F\7 .8=^F(/P?,C-*3M(V':YTM$F; +#!]AUE*B."A>\$MB"%@J/^[BN:_[CD->N*A_;WA?-M@N.,+$[.J"47G%3>A +:ZD@)36#27=XA:*Y^.IR'E(5>@UG )@TD?"J"XAI5X@.QS[<]1U286&)/7AR$F^Q +?'G?8:^0.>WJZ)E\.7C!F4M,T/PPZUO85D,$W";H0#FO:>.V22GR0/^IN$90* YJ +F=J86]?8"Y"+\Q\>H>H@-YT+F#^[\#K?L:"KS-\,U@"[ F&':.G*(&5,E,(EL9!V9EJ4\2=I8/E)B46*][^7:V/H!3@X(I/"X6!2WL_B&&4(?DI>C^%64.$TLJ +7(@'TF$,2> )DNI%,G8@%>C-KZYY)V_M<*/7@+GWVPZ4R#0# D.!2.E[>.PR2N$K +FW^-WG/S0Q>?Y;7)4>\_P:!@+(.V'5E8\^SQ/L]92J_FIX;K39G9IM*$?<5C#2#* +:E9)_+MZ=T;6V27[]S$)@]G5#^1_X@WV/Y]._S\\:K!)AXO:%$V>Y1/'2OE :!N6::WH',]5 K9SP +2@ -9_D )B;I74& J_!]%4 IP3'K7QH\AO>H8@\926BW_BMPKEH&X/PWP.=CML13 +;0]<)/4%JYX4!EK[KO/E.U:\.7##QL +E5**\\,IH!J?/13?.!PJ97VH##>\==.#3Z;?RA*-I[%5WZ/D68SM&5=+HV&O[A,K +%H-(@9@*%1I#-9C!Z7<'HC5,[\FK]$HSNZI*UW9!HI &T!4P^GUF63&Q;S)^K!]\ +5+R'%0(#(_R^<=XC"7NC1&HLR%2\XH8O58&A$ZL#36:-@Z+6AOFC9R^!Y-!DOW;: ++=*N7QU _<4R UMM^.9Y7(M WF3;FV%W^DF4OHRBI1^(4&/OS;2Y^E(YXI+%CQOI +RR2$#U\ ]]Y0ZGI&3Q/)+2)5OOVL+F6L"+H1X!ABI_?]KK.9XI-EW]M7CRSE+N7# +RU _='6U7IU>7RQ$,@2N1KCERC=OI4[=W-G">5W!%,I#3]D(\U1O?4#._[# &+#4 +>+?>3 ]\'J"APF?>:(W'<<(B&!OX4)NTI4;_$X2^XLG(;5*+/ZV -4^2$9(-F]7M +93$/XY):H>8FZX1]C^=W/V/JXC)4FUZQ=$#'2I):Y]4X&W!-;YHZ$T&#NU'?C'RZKE99(N-L4N +1@"<0)S ^"M5Y2]LI[?3RG+1/3,,'4HU>I(_,4%<&*T^5,>9W +[V_5\/&?EFW/@CL2PPQK#)VJ :!_A3G^(%)(?YIVL[+U@&.Y/PQ;-?DXNROA@!+[ +Z"LZMT52H=UDP)>^M+3>$41/@O**WKT3L6STE6@7([]VA!'6_KO#L[N*-.9#4;<) +KOVE$I3S *0$(3;J1QF*D%?:E=)DMRWSC5R\D[W2]/$LMA03Y9$KW1>NNAV T*FZ +86N#8#R-F7Z-C"NK&+'6Y$YGMCS9'=_KZ:[O]H4D*X\*2Z)NW0]$K^H:36D72]VV +UJDT$/2&A"%Q;F8VVG@G;".D?2]@,O.[M9:GP-[/]VN022MZDH'MS'TLWY+6 8]T\ +3/09?R)VYG1:HQ#MBM&[963=4DC(((%!W?)9ID6WI3N85XF%NW8O3!\I\9W/"#M9 +S4M==D^0'\^'PY#.]/JWW@\/_F_F@%?GF1>!!OQTI?2QX%6+1S/L'N"JA'!(>5B6 +@CG+6\Q"V?F$_\=,Z;C5@%&1A%?;J%&A?9]<>Y5F+V3;KOZVK^6LY_[&R;NM4U(N +N+9DK1Y\,WS)*8#9F;>XK3\AQY0]S]7 +?VWBD4EFPB8O'0:]36AT,9K1;*,V%("I/P-($==+<>8L\.6J421NX&4*F6)7=W88 +5].:\L9'HYU3J!60AT,5 @"')6_@CR.-&L)JV7ZZC,U+]F.Q>$]<6$4VC>I6^5"I +609Z/QW]U,NZ].)(SOK!HJC:.L-V\'HP+FPT*ZIQQ=JQCQ*2>-S,-G\8[M +%@\4@U0Y.R0,&.M\0W_O?2-0=8&?ECXA>U)S*5M\G";SV_@O :I&[/DH3$,:,Z7%8Z2T.EV2+<;OE/)"VWBL4B&<*%[EXQI"\+;>BLV[-LJ, @(H +C8ZEJL+<"C/;%6K]S-C9#W>?^[[%B'7Y?)TZHJ\LA!'H2R\M:D'LPZ4/MQ&;P$T,AJT<"E7?D'$&ODB3 +ERBXF$M$^L[B0 T3>T)Z293/./DZ1M(UA(JAE^\/HL.1:*E0Y%$GCB"LVV3*ET]8 +?9E3OE^PV83R!H/NK'SEGY1-E2#V*J6C?4C"T)[#^;H:J V=_ +N8/)NC(Y[[&I7WDXKY0&0,]=G9W9NPI'10SYB]T9TZRZAGB>%@%-R86,$#8#-%]R +S&[MA^[.\Z;9 F25+N#*/-#W\P'P)[KO7J=W,5'CG K.A%H79W<&F;F!)17^RS\&N!T%/8 4"=_5D"LZKO/-9@U!: ++<2<=T+_.(; UG]P']56'SCF?,J&&=? )U:9; +11[;_FO]!.2>*"@Y*4N!8YH<--]&T$J6=1OSD+RUIB*?TKJS<@E0'R1%CN"1)>00 +D1'1"@N^G9[+B8L3/8A-?VVC@>4@J['L0!,Q^"$=J:N^E;[ ,/Q*P%_1>0IHU^)256S(+XMB7]YY[Q=DCE= +L2SKE=K^6^>;'P65:@1\:]K=E \#. >"S72..KJ2VS\6QZ5Y=SB0:4&2%+5<3&CR +B1@,MJF=>9/<9Y[$)D*_:)S_*S^4*=4F%_"<5LD(O0?\#"Y25@_6X7(;:X&+B7_= +N\'B:7182'?[MH@8>>U8AN812J2'C*DDX9=(5>#CR)1ET]X$+P=X^BY@L=-?5?-I +8,LZ]?4W_^0>'N.(N0I_>PX$^;ABF&9ZU>O9VN(?3SWD2T_Y[8PAWO/_IU?ZDPRJP1:S-6@ MVIQ>2_)L8\:]9%4DD&CC$8M@ +-NA]=,$1\'G' ,%UY3Z519'V4/-'N+/"?U3:(6%5XZ H'" +2YS]#3Q?]&2PIJ. . +UUE5ZY>UU2!#-S3&C&"'K0C;9<=(H&P(&[J@S*^AN:QGCK.V_1QPR=GY&QZ93,Q&.XS99-UG[."OD3M>%W)L3=YV'IM+F&,[CXX,A$H.X,VDJP/42=& +XK%,NEYL>V][;[?0^F;RO7LPZ#^0:HU%U_8O:8<;]:;Z"Q(I3^BF.27\;/[,ZH9N +G1^IK^LTG8NMRM)F(OJ].^T ,F,9.@]\#L+LLI-,<:162?O#-0NJJ25L\C$GMAV +IK5\S>!\):(8R'#\2"<>.TCK9E=W'[10L2.FSXGHS(9]Z'BINU8=^-K.,%*O4U]4 +U.FTWP1_9JBY46DXO%[3DWB[V3UAI3 :%F "QP\V$B6@BJ8/?I FY,,0.#DG@E%!#EM'1C,^L:NA0H1G>AMIU!C?:.1@\A'^;<_)V\XJ4FV +=.4(Z ')F'VCTE^CY>XI,#Y'56S]?Z;IJ9R@>%=*QE-2M23GV%S)UG\1!J?X_M;- +=81_=?;#[0C+A3FVWE.YL@EI2+?\QT],?SZCX)U.9D.P>3U2=F_B.7YS\ZTPZ;92 +?JLUD1L+;1X@7!>7=,HZ/6<:*S">G>9X^0JH[BVR5OE%C\8V@3%TT$?\#-)=A7+$ +2-3V2BK4"^[#//^<>4! +NP4QY6'DF&9S&\<-$5Q/@B\:@;?F)F0S-A)ZY[VPX68-B+_]6+(=U(KYU%8?V'?Q +*R68W++1\"-R4^;Z-$EZ +^G]+EE$V_R4X5\;S1F.+]T#F%A[Q+3_6]:9EA!?PSMUKUOIER=S!LU -X,E"H" , +-Z?ML#6=Y!%V CW7HY%'NMN%XO]7+YF]D@X0'\YH[7<*&A,KN*N:R=&2>3EP9&8% +G+)ZJQ-3$Q"SR3'>#)1USL:!D#.%;R= +=#E5476!X/2?0 ,2J2QA!$H/Q.:L-Y=_R"W-#8R4_/.@*Y+6 +Q?"X\>\1V"X&75YNG4EPS<0-O=/KI491/0B=!%;9F"97.HP*Y)>/JQB51\ 8!ZN< +J=/M)!^?UM.K]0VB@B[,.I=*7-9"4%36Q*XYN.E*3(1=Y57QRG.@;M+,S'X?/_6%,5!/! Y.H7!FX^4*I$]7;B+/V9),3V')T +^5M,B0O7B[=L_N5'U8.?V=Z< /A)($O0T-HMA(&&N5@<;K-%RN*E4%8F/Z^I.L)- +MDL-.\F %&*].*>JL&I@IBSMOU?9P@Z[;#7%:0E 1]_'WYR!T06%\5)VV7_!(4W'1[2IP'6+2Y-'<>U_VF WE3>*OFJ>D +S^9( S),AA[U][FB4YF>85JH:QXT0Q61(U&KG?YD9<'KDOO*J&9:I;5B3M_&M.S: +E]D!D3QIR5\GI [&72*=&EZ;-WI:\'\Y?<-NUM9+[9YIP%_1L"!A8?T+7$GLA?XC +V&<9 _;O%5] ;CFK"=&AK EXSQ!/:O4\V6/!>#)K/)98R^-'/)]R3LD<4I;4(3C= +H)$E81=NA8(I([CM .QWYFVR9J8_;V6V_\4F@KKH3!6_=#:U%'^<0"R.\\>7 RNM +9,,*'+V:2WOS'PW35!(K3O%;BK37^R6RW[J[XCL!#"^OTQ;;8 +Y($%!$LG#B88'V.$1)>N9D=4X$;*_:V5V:WN'=@X;H.>HAH:L%7(-KQ;UJ:;E4IE +1=3_HZ.^.XM95EC ]+:ZV'* 1J')C*.]94&%!N80L[-S[T,AY<]>&K!@2&X 5PGK +Z$.>;8,N/2 >>E_!2/XVL>9]\M.3UY@.$.J@6,UJ7$52KVLSS?[9VL?*[5V"!4^CQ/#!W6F!ZXEF2W(VA8[ +^W^4/WV^)(*H&2VQ]C[,CQHNW/H"E &%8TDW#4(E,\ ["%/C!P \ZOB;': +F36$I@D&QU?+<=JH=L&)_)QDA NZ$R,N9"ZS*FY@QIY1?%$ 1LK6P+C3T^TLPOP: +X!?!"?% T=-HJJ_7G6[RC0?\*D$"#\S$BY?82LHD+&_'#>H&;;Z>?-@"=Q9A@[@& +=$.P;.')Q,E2A,?_CBK"^WCI09:ED!TX.3!-XK-BHA- PEFKX")5 &B/L;* 0_3N +)FG!]M,.K-G8ZRR?\(&G11NQ'I_,:+,BK2X4IBXZ)N.TLG[K]%K="<0%HE+M5!IPR)>8U'KE$;O989>SYFED&SHN+/M:1SV +G$6[B+00Q#*]658SE,1S"8<(?.1OZH+5,#,;XEL)?*A'_%J)T%I>^J]VJ3[CK;1Q +=!K_:$FO[;1%[6=.8=FKB*.CY+C+(X\Y[X<\2[XA0PYI, \RN08D<(=6_BQ$O.^F +$DWM]F5D1M/L/>,+[:-4==5F9DA-X5@<<9Y2LWH;0*4M<1Z27[3MV[W0W=;=SJG. +L7 @0NN?V0-#2I\+1"W%CS#9=!TKL#A8_DT^#6TC\3]4"*SEME$W.5A/SE67D[,/ +CXZ,H"+6ME5#*)9U\PLT$YUB.>6/D)"WR"?YJ;!1SR+,U/K@9QH'>6IKD/6"0WH_ +6[V>4YT[2@_P<28[MXZUN"D;^ZB3&GN)KDD7*Z7-[H&+3X?+-<:0G'*Z$[IL!,_' ++_S8OR]5"$YD550VB_$)UVZN[TS_V?$#,50:\-?S?&\&CH&88Q3P-:G1EP1R"V*R +%U&"VLL%_\L$/=_OCJ;XQH1E)=P#&"H,Y)=\,_3'#N+Q1MD.0X];_W.OU<+YO=U@GQWS.( :H\)X=SFI-9#/R)*A=->/^ORT2M!F-K$.$87/ +9[,HW?QP99+",Y$>!#;N$'E+0G/Q8=Q*?8Q5$2.-4]L.KQ)T1:G#)92W% HGW.*B +K541*?'FQ:6VGU<$_#?@K(.1$6YP'7UC;56:-;5EQL:38G#*"V@E66\[ $UOJQ[4?NF[/6@\0KJ-4P"J??QZN:NP(:(T3L>EH#+> +8R.$!]HDASEVL"/PR/]KE/+ (=Z4NRA&J-E)<'HD&3N_[(<7TPH%:]1,K8=SAVN6 +K=5NLVG$8(F6SRZ 7PGAE5]A/?[1B!<$"M?&_1!-PY_F#>YF2>\^- E3<3?;%;!5 +^UN&M<^370PV6SP(BHJZ;-]1 ]-S4/ +YBV[@R(O!R.?>9*E +<3-B->IW]7B58TXW?)$D4-684K'Z"#>'>^3!O:.(GLRE4"$D+:H*>9J&XJ3,LOV3KQ7)CW&-'W49\I,!IKO +:9\/1\2,'(J! ,=8K^R5AWR,$?12BH3<*(OS2I9W29PO%YE"7RQT_AT0I^T=V)+ +P"5.->@]C6CEW#Y94HOABT$VWV8U4_UTU>,4Z?9=5#.9"W4J/>+8N 3#DPSCUF&P +9=P\5TDLT,A5ZTZAOF72%6NZI:K9192>M=I6VT 8@(81FG#E6\H!ERF2'%2WQ9]4 +1M)$/QLV)1@.1;4X>L.718]1RZ-_\_>YB-KN%9^!\FH%[)_J+AWI1'"CVVG;Y.(; +WF FH]%F,2VD<9MM/&,TM;=9/CD$8^I;LRIO3@TF.#M3#-%L4 >!TBF,W.FBU +POR?K>?41,96)C.0? ,W4]QK8CI&G8.7.,4KF*_@\X(7OR^'5Z20MNV3]85SX49F +;+S'S-!7Y>'C52;#]#_N!#XK'G\4*](M6@^O&\0,;-USC@*= -W +3OSCNPUBS%%QY_ZA)E)D\R)M$5Z.JHC-"!LG$2IE#2/LWS]:OPW*#'[*+;I+[8IC +TCV<:C$KY^X+0E7_5K%N('3H^&47(G/<511W;]EH\5&J?5U,$?+,8= LE#?- +WJAW""7,ED>13+^X$K&)I;%H<^?KBM43])_C!]]!K,2I5!_LGDE,"K-A5^XA$S8X +@@+9/;9N8.]DG S70,W2A3?SO"EXO7V8"-UW"F6MFP0S\+M1(D%B?B"5#%2ZS 7A +1.3[0A_>:X5@!<5!CQ<:^V,C04?=A3X/"Y2&PYVE=:H&D^.01TC;%&L +CO<_0/X:">A(BYE'J3\>.EA8-XXL7P?I"P +=^= %I&3(R1_Z_RW&P;B!89KE[2PMT*/[*HV,!!N1(,NV8MD&^AO)+8=#?K& @NG +BPW'Y<..!0?N1+G3>_Y:H.B!MJ[8#_.A\P*^:'RK*WD\[.=' +K:8@\W>%)L(QWE4W:AQ6D7S=ZF.XI/X !5QSD'9;>4Q@$F+"J!.*H1.H +TQV=XD;MPP,M'-YIP6+X(;S&M&!9"MUBD>WLZ3D&.>L@Q@\'ZO3F1_ON_&4[+U17 +T?'-YH!&?:C8JQ:,%6CM43(W9&,1+OGZ> 2N>18 M+JC/>GMZ9L+Y3$GZM.TO%]S +@/'9M';=0VOPXT$@"D4K'#MA6^BL-FLR]L%FMAB#=)2Z,K0RA'1QCM2Q;QJG'R45 +CU/7!CJT,-K')=K1,@A$-FL+F9?5<)W L5F&1N+P+%T0E/;2P-,><>_&V? ^Y*1+.YP +YAMI-".P1@6\(1[)%Q;@SB[7FIBP2XD?6,!]0!;ZNE1>*1[HANM2V0YH.ZX5 +EF.,%S85#HW7?K3WG0K+12"8,AY^]M%=&"H*7):K'%^O< 5M,+"NH@OXYGY.R=O9 +>U9K5X!W<=UVBPAW4?>+64)X,J-(4X9ZP4697?K_Q)Q9KM^-BG'TJ"= K_A?/*6#]D.;?SG,A=P>'L BJTY3'I&6LLFS--]Y8H'#1E +OOAVGF=L02?W+2 Z[F)_1FB:A<(YR[O]1O8+#[09 "F2ZDB !!TNAK?YO.MJA_4Y +')-GVV10@ZK[,.*B._XQ><*$C5Y^5!WJ:VI8K&P%_:LUDD71[0R%ZF)RP +F.OD.&ETQX]WI)?EI')2323>0D@C!=@LLKRM)]>R=LQ/BA&<[E4V7^%YA; +P\?_6H2#S6(] W3JT5L\WDCF1)AO$+JP\:TH$4K2:\*>,BGD))-=F_*)/?Q#7+IJ +N988)<4*?JP5SQZ&MHUU+J\PG%Y3#3$3[,R9?6+Z0NNA)42> +Z&6[98KUXP^<@F +6TEF^4E4/X;PV^#)!>G$M/,)6@!<]FJ!RSXLR.]K3&W#[*HWSW_5&18#WBMCJ>L5 +10O;:M]@ Q!@):>$>:O1>7=VL,8]6^.H!96E#^8S@!I?CO=SFDH>^ <7/6N8YM=[ +QZEA4&<1PFA;SD:A\Y4BXF82VEYHM/\1?Z0=4V9QVI3=4BM[P]8F!<:5'S.XAX?@ +,J=YU%_\P9U)6>Z B$#'Q6OX3@4UL\!-3BD3Y@RUJB&M\+GH;-:/[1D_SMSR.65LET!:E5_\,TDA68H.^\R"L6P)A?R#N4_\](LD7:+-H( +:X]_Q^H$$.-Q2[P P[@Y_%:LA8CXI46KJ7JCDZ%4&;:LR4D+GVT"L%T8>GB+ +7)6! 8[!AR"?DD.>OFC2E-N.EDY5-JXNA,WT4#:N)A*_!FS-G:\5M[H@9\97%,VJ +A%Y/H:):X@OV]2X V!4.%\:Z7,# 5N2@8*&5)',6*P>@8WA.13/7>2#&*"(8;9G0[N0:S1M_"V2ZWV:Y)H P CJ2 +:)P<.3V@)",TN2.\E(=XOOL-Z>#K2M5$LL^),0+:V"4KJ4J5SE0ZO*F43M,%SL?6 +V>VR[#_F ]+NL]>"2CK=A9I$A:'V F@,[8L_%.9L-+-##Z#+P$L=J_EK9@!#@FW" +AL!O?(P_/X,16.CC'*,20WZ8)Q_VR*6../NH?RR2I40^96W+C.,5Y@S[K,SQLHO] +KN9*Z>@%*@LS9[M6$84F*#/!SXC4B6=@BKFK7GV@&>W_(Q(@2'%#\7%...9_4\(O +5J?H2>TRG-56A(GKDC/Q K'UQSA#$9'4WD+!=)'QNH@<8 ))A DO^/] U9!#WT; +<[?(:F-._!PDWZTLO&]F00G.?.RNG!I+:UO"JUT(5Y-ROS+UMKYQQ88?/AQM+;TV.N+4$\12IF-.QBZ +71,K6'_4X>('[F.DG%8&5[.S28B4=K7:WX+@=0T5OI<0IRFPI@[$%G:0HB +;>]:2EL!E@"_%ZB<.L2?FF8;^MQJM\1Q_QTSQ1(@OI2'UG^U6B.*-Z>H'M8OL4*< +.+"MP,CT@QO=&-![;A]\[. *35UM-,Q\VVP;3%GC7F2F\E[:?"$VX.%RP.E")CW +X 216U/U6_T-!8T 3B(U%MZ04/ANX8_TZ+SF:8E\82 +W;=]85.@,6L*QM;\4Q^?&862UL"[)G8QD[@,DDT&, +(T'\>*4^I6[&"VGI?+8*0RVMRRJ7BBSRW=O/=^>H!$VIED4\RAW A)32P16:[_A& +-#:^\2!W:U*J:9NA+%8*E_)/2!A7&?6'6^7R> )CW.-1$CLD_4K2ZZ%*8SRM1%89MJ-VHVUH*YSK +E%H% SM &W;JY.7DT3&+^R_(CT@%A%(>3"YK!WY$DWN59]72M)L@K>@#3\P;W^>P +MWHU@/8JW<4MZ,E#5T0S*G4A_']D_JK NRM$\X,4.?VW9DY+=;="#?AC?EH%;0YS +7RBR^%5Y^(I5J5EZ\3>/,TTG1>3>9[=$&O\9*O2*X*$T@';* ]R-+Y ^?*+D0B%@ +5E0'E;F11&0S.-K/X_TRFV-L.#\.AB6V4$[S"L(LQ:YT0Y&,0R@+)!!J,=90X(JV +0GI[%P#XUCR]I49\B$GIX;",*<_ +.L.0C>(@0;ZB9 QG-7=QIIMHIB8C#MB?&TR5BFXB:C-+6II*>X1 L\YRJ^\<*8)^ +!J6V\C3=2JG@TKB>LD#LC1NX.XH@'70\E_@51/R_@AL,>B_J>S%O9.NRPD_=?JF* +W>Q3W;!Q=1Q##\6+,OG^#[R(_?XC@$V;T6#K=[2 XA_(SRXO*T[43:[T)2C!C%>P +FV1IQUKIC>8=&H=9=YHHY'4B4(:M15GC*PHJC0\YHN,*-GK59YUL0ZS.;[.E/$^1 +<@3V43!W.+4H-8X-KYV!IE2/;.R[NALRK=RC#D[(T* #N84>32YR#H!^_AZ% A;) +]Q-_6P=2:/@P]R%Q)E@=E G^B(R$VA>TPA)+B8UQS0>$''W24*"[^6CB/[6+3+$FZ"DA]1)WU**F:K!CC"!7?7A'6D +0*+DDVRKKU,K,VFG48"_AVX#[XQP;$3MD-O;_BN;7Y.$X)1!U,'DY*E3L(Y!-"Q+ +'^8"("UEC#^RHIP_DUQ,9$WK,MJ:;V+0)+#BEY0.D)9&TPEXT9/_LI!*+;4I9"U!"2D:YC+KZ +WQJ#55V6_B1R)=>E$,V=..A8^U'B5=_UI0&W[Y&(!\BYDA;Y<9ML[+U0EE;1S9^Z +YKI*:HF] (N>LF80T67F&[]]0 A&1OBKM'CIZC ?*_.6*"):N]B6KM>[DR*B==B4 +OE'/<]P5N""7-0?X0&[X;-9?XS?NK@^1_HE<--YO5P6[_J];>F1LX;O>(4SKG&G% +!^&MG:=C>/8F7GQ%+ VYU6S/(Y[/R9(TK!Q=UH +B+[B1V3S?]"]'RN53%D'@"RGB.$=U]]*&-.X+G"R=VH]F#+=Q@BO8Y6:W.])@KWP ++0/9)UJ,RS1RUX>U?0A&_/F=3]@ U&A>6+2LV6KI!2HEW;+_INR 1B(&ZKD\%HM/]*JG9*VQ&< M2.IZ[Y78V5'I"+ R]-& +;9GVS_ .).3(B3TY6SE7)N54_MBJAF7$Z5_KAL@RX7X0N5>CD1D]9^$/65DBU5LK +F*J![(U?Z5.3SZM<"%(,FN;K^M>QYRT>,XQ*ADC=GV756%U!E._R1<&E=E"#E4PA +JB_(HH?@A%ROBG;V[\BC^6F2/P?#9P8Y1JMQQQG1MFWD242'ZDI8/&G9+:'G "U6 +7]_(JE:<4B)J4N#/J$-#*CYK]>"+,$Q/*XS<0H+.-/!Y!'B! :]DP2L9EPJ',VH> +5794$O/0#ZV?P.OVOD)4R8D7U!CK@2Q Y*:(-9 A_O09 ^RV+U&!&1I-&UA%R@Y< +?N:P:ZU[3W*MRYJP^C$GA'WW>=EY4"9AD#AFM9QS(=F'V(9O:-#6K>@$G],&3PH& +"#%>E)=F4J?#UPAI@--J6!@J2Q&S22(6;-M?"O\:3H'9#U5.?#QE""Q#;*9G4._; +C9@BDE_])MLL[D02^WV\W&;>9_$\.'#!''N%+Q+8#;>^D>#$2Y\YRN"7,)S"]&/X +)3ML<)ZP@<1.4 +IQMHWA,BR %DBS]>+06B@\(U 0< +D_"-=("H=45X]5>;1:$A;W"&VO] ZZ:%+DMLP(7+=,2&V2]]^E'LEU&58Y9(TUC> +"K8T-_A/SCK%)0D*3_+F.T8UQLF/^(1MA8ES^RP);;LZ-3>J0_+8TB3XR3FX1>'W +!,YG^Y&%O12:MNY=C7841)&J.&3$P1*K:0K#/]K+X$(1%JPU%DL!^1C"ZS$M\)I4 +YAXT7=08?K\T:@:RQ%*$S?BF&XB03:FZ0%,DE>UL(6G322\)\,2>59&I_V8T@%2^_^(OW_L$IP7^A^#XIS[T=LY5V[V*F_DB',TCJ-<2?F +61!#(U?FC2M)_9T+E=/PVR)D&)%S1%6N:FWP!4#>B4*%L B@G5>/*(:/L56D8JEL +;30OD+$%3]VBJN3.SU,"7291J#'\?01+A'F-EX].:-P$H W"ST:_ID[/FY_:[/A= +M7XRY52GMNRJM'2"@)2';U(ZX$:O_RK^Y%$'\8<_RS*%K2.7N*>6>['UZW'S:SZ- +;(AD7.2%.+9J%7TV*(LJ6/_!MYV[&8?6&C@$R2ZE0N&:A$]T^.=&OK*KPI!D&NJAP)B-V4:0QDLJ 39P9>(T8W%N' +])W]1!$+E&9V[O+/RZ97\KS7M5AO*,NM#.M!]@ECKG-\LWY=(@WF J! +:S9]CXZ.DK'=/,R%##!-R.XEV'8[>]J^L'[QC\ TVM#Y=,^9QU,[DTS4QH +2)3>?>%A#W>E?HS[DQ]D?X(#YSQJYCEJ-C3M+K6PF3'_^)U2NR2!P4]@.#!IM3.3 +8/.V';9Q\#S&_6/L;Q_P+^'F?46>VW]I]=/<:FNF2@G_CA&@L?6FL'8[HTF:*SKP +O);'W@E_\_@]9GG8%[Y:@M)DY!<94$@X75%E5Z3[MWT4SE&@&DS$QF!5EF0CR3%%Y[];^L99M=L"J&@R5T>MB93 +>9A<%J@$PAG$$]*)6M'SF17J38E[."^G+B$7%/@\8KR^,(?F-X<(X\AU%656V[& +*I3/P>[. CET"#\I!.9V'!R_P$<<=FA(6A3B>1TNR[!1 +4)Z@O(D]4B/;71T) K!TS]2$KVC*0[NOP9)Q/=HEZ,IH!3G/M-@*7=]F'X;BPO^L +EPTR,ACSZ1'Z\0WQR#M;66W"]9G*=N#F'K(Q*NB,YHYR,Y SN!:T](6/D,L)YJ3Y +*?$OX8[63D&T%?R;X"D$A8&DP2NT_;-P16OC: \,:J45=ACFIERL%D D:LTG=XP0 +HW8W.L2+WX[3Q?58I?E^TD$SUM\-3DD+6H"^3@K.+@*4'T3^/CRGUNA-M3H&V^ V +\N=@NT#;T.)V9#_BT]4=>]CP4.ZD"LY#>HT/@:B8UM,^UF"[*_S+'M2CDP'O5&>3H*YBA,YH_\>8-U: +^[=CN_ZQ'(?-A5O3+-G/19KV:,$99^Q)/]@S\"$8#< :.PGIE[/(XE0IVE"^^^A#>NJF;C4(8'NVSTU>64E(H@+ +)J3?N/NG)L1ZD9+'4:'+*D XL[MV,^RBSH^['R-4KP*0?US?.698V?HDMDXK'9^N +QMQ6AG6>N$Q:2L$OIDG2?#.MO.4-,R:VB#,WQJZ48&J4;MS52DC_)OZFR7)][;?R!TY30*<$,"*O+WG6WF5.+D7#Q)!B?3J2,')Z=$" +S0F5"!ER"">N'TL'X_(NQ(7[3Y24[K-0&,=7*3PMJA3I[KM %$#YITATTK;8]:T@ZG\BCC>K!D([LEB_'2BI<,W9_PX?(()GG#=1+7 +5]**0-[ K=3B)+\$H4V,- 1U0X)G1E:!5JN3A3.8&)']4Y/Z*"ET4YIU'1ZCO[K +]&<>$N[.]P%A&DO34[N&B-XTK"XJ^^Z^/P5L*V?GZVCD09N\.IZUWZ-,@4TP+R+4 +D*K%G='D=B/\*-OQ['D*GVIK)[]'W:;7=,#612.]E&ZKO5%70<72+':>%B!98SI=4N:FNSS9'[ +UJ1P*XDG'!OR$=%NS&%OZ\C-UIIL\E08 +54^;1M#86W91CF"W(YC?[)&X7+#&.ZQU=4E%-+XH%:3\0/99%)*X]1 7X:<55G.S +!<1>J>D(EY,TYW ;$_7B-PE_MYQ$,A^1*J.(2_+F'PD[OKS9C\1K*S9PNE:Q(Y?N +;B?"!SEL6[@TR4T]=*$# >%!Q2#UW)GSL2:SMR$U/Y/5O)RN@!LQQJ>=NP1&*4Q: +^%%0-,1L?6;-AEKY:L)&M6(\3^B;Y$<:L?3 +]_$&<3QY^X]1.+]6$B.!/->I.O:^]+D9/.E<1MM'BQC,X*8RJ]JG@YS%P'S"TH80 +:G-C3!+L7X'./ +^5/%=-EO <ZIVD?P(& +ZN7UKH(,8&C;W5+>4;;_U8@C8[]\1GHDRVJ:CR5!A<\=GG2@_I(Z!) >8P%_&C>B +?BL!>W?$U32R52;WE/ +/I(%.K-CB _EM=/EGUA([X2:H+B3!' +%F8&\S82_SM19IU\&+\PV\-;6>&^]EV [_-57S-U VROD'2^4/W!WXQZ5V9W +9=5FGH\^<=NQ +)(6-EPH^'6Q98ITP(Q8BQ/#E='-C;G^$'PG>N(K?7Z!/C./4P]T0Q7]]QW8+F2@! + 4@F42U(.VD 1="N:'I^3%;, KIW( _T3UC,343*?ZYKSL=9".7"=#B4QL<0,?>= +V.!#O$![:K#Q-6DN(@$DIEUEUT656G/["VSG$?,;9MA/.7N"U>IFW[AN>K,CMF\B +HV8V6-),]B]UV*Q^NM1WNH*E]$4B2S53"((DR$?T,#9 +]&9H8E:689:)97&"V[6--V*WP/1S\)V#,(Y]M*+UV$FK@ZW[)5?G%,&/-([ULM6L +-XPJLSN2*K/,=<7"4-'>_.R2/V-@)^]6L9RW/_PS8.3! 8QYG$%$!T[^^;N=^R=M +/>12RWH*JO_4.X>2T$B"R+&840+9\F$P^FIA8==1)I<9($G,O +SC/O]WZ(*90I)87BC+ \41L/-5M57'0\W/#2M0,HKDF]79KIF.?%.)58O1#ZE3-D +WJ-R:X!7X#>ODNPV WJ/ZWJ&.KF?5C7;\CZFS<&%746Y9S+<"5MK WL3Q-%OS)N7 +/SW$8:79Y#^2NC/#(;_X$L39/!U7%1/N0I "'2U7&Q>Q$Y8ZM@<)TQTGSJ*Y@VC? +D5)0TSD&N4?=Y8@X%49IY3N[3(]$9F^1(I', * 8[FARX'ZTV;!.EZ%M69D1PHX7 +P<_^Y(.@;*/YV2WSSD1.L&(4C,)KA"IM07CZY([6PL7:D+Q>^LK-T5,$Y2A1!J^[ +][AJ8+- IK;M=(\$UXIQ>KXRW)RLL^@>P^TBB^ZN"C[V4%S\$$U%._?PV;2GL[G8 +@5#*!Z -QW-!RUJS),PL3V_;//4/X4\R"PMRNL]+@ +\!3@G&;/S"S^9/XQ'BT>IU *IDI#3&#=,/!KL(MU&U9-@ /W#DZBO:!2*0K38ZO) +$8X=##WY82I/$D=MY"$'PL)3HL6/1ZW"L/_<'CNAQ@M\ +Y4F-LV3&B<0=F%_;DC2F^:R1AW.C6///"IAHLP9+,BAU]6T,11<]\X<;5$&^@0[F +.VY,+T9RM-XUYQ?'\'#_ +888I4!WSS.9'D_IR!NW+]Z7V:MI&%O]/':DHAMC[)7IPFH\W!V>:D:3 O4>M^XB\#$>^&9S,)V_@I/IRAY.B +BI3N?)<_OM?L^;OA5!HMQZ45\2NI$]48VXY=C@^L@TT+ +D I@PZRKY\(S>PQMNI6CN(68(1TS45KPLOG,)HE ,UX[=EN$_J6;-+(Q)C+4 @5 +?X$H);>?"V.+V--I[).$IV01;.V*)2B9MN[)TQ^YA>]L#?9&["MV4(MXS0]/S-B[ +.@&N*?_RX(H7L;)D)&6GER/1<910W$J9S1>18,-P!N3*3=V;/V]PA + E(B-ZLV[DS]_(#<-R1SUG.DE)8@?7W$G-JU8]SKV =UHF.S/ESOQ<=AD&VY'9-\ +),8_5<:)C\:LU 3J^!N68WNQL2;V2UX@"W][<(>'"1"S<%!NQN?K\:2FXU^TF0@[ +R:'RTQ"=43I[XO4)H'SITP4/>X5S'5D/U+Q0,G0%B!$DUB].@07YRLA4HPOE:F*W +0> HO4?I@5RLOVX+7^TU"VGBI +A8$F:CY6@NA6NB!X:VL_$/S^V@ S+@B ++?K*IZSNC2#$.F'=425FN(;L^;(1"Z^E">C5\PH[_N"\>H2M_G4Z(,1X/IN*@P5=7;J6 +)DO3;TFO8>)V"VV-"\)MW@V)QR+346*HW0025B$W.#PAZ:CI4_&S/UI,[)W88DD+ +WXC[I;7@NDC-S+IK1B3 Y[D\4AX[IEESP,E/-(P9KOJ?H'K(=4& +CBC-Z28Y#WT'/"?U3_!'/T=J7?A8X0<7,<%=NZAX@RU ;7*ZM\?9$)J$W +B$Z@$<7E7.L0*22EIK#7(V;>!S2!)[BNU/K$JZNJ]V5.QQ+HC> )MG./G<>2\S72 +JR/P+MGU$9!R:N"%J?P !#=OF39RQ/KI."N6!0G^40#\FLJ.8)\N[^R+5].;<5\.-I^,A^,:S<=AG0QLAI%T<" T+.*Q,'ATW;;6SEW&G@HQ#F.X_;6#%AX72 +<8$WA[_[L(/E@MPOT?)=E+1T(^;0.0R79A1G8+9K=K\3NMG,LS=@D/Z+/RH/ ;30 +QM)QWJ.T'*G!I\$?:-5Q!HU3HQ/]ZL%_!B?DO(;;R+(37(K?+N9NZ];FYM&O70(% +HSD2B,G16)38#^3'"I2&:8;:$R53&'/QY E^[N/HT1O3]<'OSM4 ='B-P,G:>( ] +[O"78NQ-'*JHD[;K]#G\.0=Z1DV)#%A1$1PA1E>)A8##2?%W'4Z"<-*[IE'&,GZ? +19*Z&^*Q/P>:U2PXLMQ29/01.!<0&[%#*#'*P!Y^7V7U#_$:=(C;T_W=+7X;KQ[6 +,DKKL[,E]\4RN0Y0]M?-ZTM1=++Q0QW )9J"4RPW;>Q6*7%:E1P9B7.[)783D (* +=]^V0IUG1M;QS)_29(?Z#!HI;1Y5^?_)^G-1)5.VR9I^T>!M5=7>5@L,;#CGTPER +7GUV"5IL84XV[MMHC@7JD3D&CWYIDJ79'1,Q.->M#T%%&:,,_&N;[>G \%J0?XQ" +.(WJ__-B&DY]W>4?>X86V$/4_/JF-FY\B+V$Y,>S^/H$:-Y[>$7N3_S\Z)G(_YJU +B JA/=Q\UCD@B&I]@//1\3:5C(O[\H/];FFWL(+J+/)T'W.B[8II;TDA&Z:(B:Q]$]X1J3&"RN!"J?VU&J8G<2\)!"6FH+C,WZ"Z!A<%T +2!!$^\#U30-=0C#-519ZE 1SZ9YD,>W2J,-&F@*HJG8@<#6SELQY"#:P76*]%:?$ +J1!QTW!AN\2N>$ > ,[3^OBJ7&$\=T]'H#KYONOJKYE/B-.%/=3:D2#6/P"?=W/P +JXDMA35H?V:_H*C/=\]W)>'E9*O)&U+[=B^Q//\X[>MLCIALV[FBP,:B6[/S1XL& +/IG2N(J-)1/ -.5X]]AI^X.'!V,E761.&HA'PNJ&BR(2AW9)GY/6]:/^.;X*3$]N +B<%C9R4?G,+G-U$)'DT5X$ED6;:*;;*HYO.T#HHU@QV]-K%3B4B\/_PX; +5FTN,LH7:_/E#C4%)<@Q85E*<$+,7S)759P)TCL+G1AMTDVS=W929Y(K;: $)73> +%90YSI]\5!T^'],G6IIC*L&+R3F[_MS0=BY-VR0;*[S)GDBY-$QJIX=B_,1\Q1D% +7[O_$7DQ;IZ;_-XIY23Z-0I@K B\_O-M=09<7[?.=TR'U09 +A]]]PV;"EB7%22VXU%W@]/>N80WHLVM>0&@7>N=S_MPHDU64FQ_3XU;QT"23I2:U +QC%\/26!387A-<%YD]"RNUTT LK5>E_RHW%HN^ZTA\@$!X3;9X =IEB.L/,KG?)B*T"H5]TH#&['X*"$'K +2:N^/,&>:M6%P=N[PI_:CC[Q(@5YP!G$#IGW@#",UD$I?<^]2%&+-E7A!M+Y=@G0[+Z,E +Y6S5,>*)K8WW5#^ -N$,#Q*0;U"$G%C*Q%([(MXT^ZVHPQ7*+%ELCI&_&M'3/[>. +V\KA8NVL'_@K4NH>H"6S%=EBX7-;CP&(C9\%Q .?D.-6 H\C.-'D*$G2:L(:2@-I +A^5WIA_?'>BRMJM*@3-%.99!PH:[] TK0OK^8$[-3QF")&Z_<7W5B^_<$O-J^PD= +;?87"+DN"C"QWCZ=^+E,<".J)!V-NT4I'#QG$I&C 0]5D\;-C<@YKXI\8(>>80XSR(:U.&0D +XFTGKYV.,\F,R24"J_7&C/"$QV5I/NI.DSB1&FZ1*'_=C2EV[?];U,3YF_O[S6WY +Z"Q$QP<>2(];X'7;(0+:(=&16@U\&7_J\R:U,+?*N6;/@-8X7;QMXPYF3^S,6[ES"07K? +Z/Q^;4R%X_S[U1O6&/)L! WSX<]CS.*C'*_(HA!V"M,P?"3)^JE\6,8TLU@CJ\4D +UQ*;LA:IZ6(2P[ ;(>/V4/V'PFZ.J@V6$14I71<7U +QU!=(5Z"H']C[R*Y6'H7Z?=MS8@Q?0]%)<=.-P=8*&S6!J:/&!I6MW765U=:&P06 +>$Z9B4=CTV;4*\U1PG(#%(\>6VZDF-7I3,!C'GS+^9&/R WN*,_=EH6!(%49P/"/ +1^='#_407>K=WV31_8_%9,DVM49?GZW5OX%MWAPRF"_(KBS&8?P'.U%\-A%+P3<@ +R=]$';#=H5L@B:*GT([X1OOASMN<9]PZI55T;4>D-@7Z>6^!7N:6CNKB3 +=XCA.@/?%V[MU?8#1^/[V^WS+-D"1)WDTF,8CG$B&.3GF-AY\[+O\J_SL;:VTDA: +RAF5^I%9/IM"+#PX*;[_>SUG?/^&H-VI\[ 8[)ND^;>^L5VX<;>C2 +^28V"MYP>":MS:FQ(/<[^'6-%9#\6=O.@5)2TRY/PH)TX&BOOG[0SS[C\,=!(W S=Z(QG-R V/"3L/SRF?6I<4&&:?Q +:Z)(;JZKUFPI3OFRH*LO9C2I.&(]ZRK_601 ]L6_.ZCD9\U^:N,MW3*(O;&@![*] +1FS_8 "2-I@]IJ6_Q&QLH\0S9RB0;RC%/Q(#M&[QML$+@X6#Y6,>LP@O8!7A!0*4<_.>RSU@:2*-ES=_:.,+7 \+3%S0;Y0O]T9ZSF8LDH3D(/I3K9[Q0E(Z@2AS"FP]GZP<<*%.1J'&MB:PV_3U'RBF +M*FDV>,0?/);,-TE[??P(+SV?0*![XF%DP#:ML]F<+5R*G_P5DM,E^Q(MEZ38Q2E +"AC^$FU_D$2.5OO O3DQKT_6$[SRKL<0P:4XY0.HX=<1@@BW"KNTF%$9\_ V33;@ +[5=Z30<]C<38Q/_J)Q]Y,;_LH+M#)\]EXOI'63ZF]X_UL#GI*C@T&&$>2? +*V2#7/^'? "NB)CX#TPBE3%5ZS."U[I1ZX3"@A1&;D3&"_#5*=#*:-QA(E[M/+Q> +5:=BD^?KA=L\%VY9,76Y>9N?DUG>,X9?)!O+GE(SF5FMH8B:A[LQ)FZ*H^H!=7KB9)6FUKP*<85>+!L8RZ32L(/A#@[SMD%@Y_>*R +&'BPOS\'+G;.1!)[;X>Y6GAK?710G:;@F5U\+FK%PJN^CR;IBU1X6.+-'JW$-GOY +GRO1J@U6/^::['@$2^R')6R+11)R_)LW'H,[EJ\T"1)<("8_B<##0.9A$<1:GR3^ +U,?\\+#?\A<(P"3^!+HJ)R(?88GR.@/(?M%M;;[!)[[D2$/5D:FSM;7EG[*8Q8#/ + <1+/$DO8S98Z6]K%+UW1&6LC4-[XT[^?+7&9&+N9\S_C=1680SG^CG\D=.:TDK< ++3;'<^W_DJB7P^AVO:T=3?S(,&0."1<+\1ZLEURP5(T:Q>Y*32%5QRM1AMF>:;[3>]LH4UIF N3B*E>R +U;IH,-.:*S1$M9_<'KMR%#0)PL&>N'C6EGBS9!GT+4PC,>100B\ZT;^(1-,CN !* +W?]?8R+\K'3]$*.T'/K%N1=;O94YL0J%?$A +OP!BOPJ5N?(EN&F!\JEF?F2Z<*M1K>.DO*/,XWHL!Y:N<;[7]93@&_A? ,S"3$\$ +.%3GV75N)O4Q]RQ>8"*ZJY0TBNYRLR/2!6B_1-1-K!\_* ,)",WG_,J;"SQT#3_6V(K#[$(/!ARV Q6)VXIG_#.@%J!1- +)? -<@%ZRGP 'NWE1=,B%73R77@[$VT$U7GZE F7OYLZ"9"AV1]IXQ*#&?!-P'RY +DH^DMC1=ESV:_E"0X6^![>3 ,!;#1*>2M\UE>A/L\[K<1%8IJ:I+SEP\$#]VCS3TBD/F=J$Z&7667-1G6#WRIT/ +%CFH?8##D[JC"\*L=0PQ/TUTYYN:)%B:8Y"'&S;Q#HV==/PQGJ]8CNQZOZ(CWQ]S?/B-3+ +T>_Y'SRM6#EB?-SA9?)2I8 _ZP/*EN+.=A3J>F$GW SHO$NCZ +!<6'>1\#8Z]BA=&9!!C7M>CD*$EYOSV W 7LPQ]@<1T:[$UZH0':-F^ +*8.,N]*-%WI 0XII?.9RG /Z[4[!_?0KE*3?-]_'#@-PX^:18X-7M[#0"-W$G1R7 +H+N@JAN?@57>NQ>((+5B=(Y=7U6=5YSH ^@N!J3;[Z8_!N MNXF?P-;!Z05 'NDX +!Q;&!"= H4W&E\T11F/>F)JT-]D'/0==B:C"+D.()<]L*S#J"! +PT3PFO-_:'M8UOZEZ7H>"]P*F?/.J:%VS%[NCZG(M]7[^D,URY@%Y7 ]U!-]D$ +:/]\I4$J^0^7[,9Q#F,;/R:T)K(D9DV=ETQ8Z&S[/ VZ8"[CZSH"C]\LUC\FNMQ7 +@Q-\SKI:;$R2ORK9.J\)CLZ%]E-B,^E-T/H)F#NT$!TEFT)DLOUV_3((XE'##OM0 +-F.4OIM&T&/')Z# +/(*Q3?M+&A6A*W23%5XG89CBI\XG#A9.O7LIYE]" +UM;>M.D9^D(?P>.D8FE/$"!'Q<&4AW<^?NW>.&T56-5O8M/CFC.&W^%Q&+M>/6(F +^FTRPD.*I;*Q7ENEE#O'7E4&%*Y/9=S^]!HM7,0\!X@ Y;D[N."B_B#M/!5Q8(#5 +Z=AUNL1Z0R:#V/$-*81;0,S"*91EF VKX]&"8#&=7F)]G5]MD00NRQZGMS7);$=$ +IB$>U5"[TX*N7:;(,IC$P]*GR1K=.K)M4)F8XY(#H\%&UT2S&-:M41U'>5Q. +5VE2,"AV*%/3X35BQ'5R+Y5-A]C'85D8EF:C%UY?+2#<1G3Y:(57EY#'&,HJ>$XU +F!PRJM+ST>,C!C^=+>]V(AM],84P"]L51?) +J?6M.2F_:2T+?(L@#"G- ^>4Z;%HY/8$K7;A_E\6Y3$$^XY0+@FK*WD_#<9^2F+D +F[=IK;A+$*!FXPF5?S75_M'<2<.M.[HQ]QY[3JD8UN _7K+C/2651'I$ZDG"^^#D +B?%I[ZIYC'B$P]7B ;C)PS&(>MP\02TS-BFEN!,\?(S0" 1_+C3E' )0"AA)X3" +I8W&?,\NK,&-UA*!!+O>NS!+S$L+H>*ER+@?Z[<6Z_I41/KGI'23+U?YF)Z?$)<\_4 +3?M\[2W8<'G'*+S\6G.AE1!0>1,8R>'(CSR<-H- <]17'I%2J)?M@AK#''^B^$8L +X/83)_SP5U+?/9]4X_C60&+*R_Y[8B=RABXU4WX3!L(BN) 7FEP=3=R[2U.+(#"R +Y6%+I]"X]##XE"CKN'D1/":F.O2[;KY0;#:8O6N&)K&"AC8>* +_->W].O0 89#BP%W/=J(W(X7='U.QIVP7$N+#((/-QDX* N4[V/&]\UOM[TA /WO[)C>B4K$?D+%[UH9HO?X/S_P9)+6I55*.V1H=8? +$QE#P:"+Y>R2ORT0^ =_(SP^8JU5[\@0*%I'O)$M3KJX.#'':^5>UR;/\[&%[FR&;ORSX>S73,=-:IW+!J#SRW^&7@ M@]/2$FGZ)C6 +ES?9@W[1"WI[!W6K%2'IK?)%'$Q$_2+))3F:BE \=@GYU5#XB&BYO'QK<;YP\XO$ +?*BHEKA+DF$]V/8%T[F#NBC&YT5TCX]KVB%HU(>BW$76' +8=G!R[2E5.D:C$\+RL'6 6=LPU!8B&/]M(Z-D1-+'B!GO/@ZH]:^B!B*DL]F+5=' +HLO'0]!&'C???>G\7,!N -!N=*NC_0>B63/#ZW262LWN90S8FXN_,=VPQNWT!?#QD%VLR!W&P)]\3GY(+-&H(CYYQKOY^Q$ESTTYU!!ST@;%RX\#XJD_" +.,*@D(W:5&+U&J\AH2R[91C]641Z7@,U^L.L$3HB2,?VP?0-Y2YW-3NVV.O415G3 +AKG9)=\.8@4;#@H&><61ESU8J-RLRRPQUS/KF?%5T2KN-0E"=WJ*B/%8J-&/7-B< + @ 3O%AN,%32!>'B'9\/%Z'+VJTW96= Q'[,G^XYH =#00T\3 +8L-FLQ::7[J$?4Q6L5GXL*Y=+&03E(9$\!2TCJK+SA,#JL8L+AI![VT +V?']\IKAEYY/K(+X1ACNWS\\]O/OU)+JI!SL\G+PPD6%AF DC%">I^Y[VF,XY60U +V+7U[=_8X43-/V( \7O9=,4(O6H_56OJN!/39! 4,;(E-/+)\@@G'!., +P4?^0_/#=J]ZXY1\'^K0PZ<-I:$:'DHZN +CN,BTJ;ZXND@U#RCUTL*#H)C+:Z ]O8IT"JQ79$=A:$4-.6@BM)@S7S(0>O/826#P_.A7G_G-^.TJI?DEN%G>U;^QN#OR[>8=[*H&(E,+GM;"T4C. +0E,\#FQLT+TO&T!=1%]#_JY&Q4]M3)O.EG51,2<8)^=R_@Z??$%S9@#5-#C%A_0L +$E;!T!]*(-=F>P=$KE 0$7L)5,"CY84Y]@KZES(6X69RE#1!9(D](P98>2 +[ GX>N."X'!MBK>IBXJ8=>8X5Q^)\34G\3!HL79L?PV4X*H_7-@D-5Y*,Q.\/R.,1 +5P1@;XH,=UXG(9L0AC7;J1YV>)L$O\4N_4?=B[O^=]OT4;CH!"\$_1OTEOWD9_WX +"U$DFN7,V!IUZDFN]'83LC=+RJN98Q&U;ME(,#2&Y<83K +K]K1%I2!ZYW7C3%>V6;9*EHGG%];J,)MDX(!L.*F\@ :B]A!?>N/-^=*G!V2XC0# +BL@S93Z(?DL_ZEMG3 [K>/WD[FM7<5URB- 93&_FNA6%9:U2S>'58$'.5_0LP@CZ +)7;/]7DB&E(%<15PVN%E!&_Q ?,C_;3T*,>Y-_472[$@!:"''D@\VC=O4)T5Z7B. +%1_S!(B7"/KHD'ZN'0;+EW$CFEYH2TR!*209/!Z9J6D&S!\_23HL:&H[*[S"[ XU +-W/-+A?O Q'TC_>/#DCH3A(/)@27DY9)P =)[%(?(V,JSZ_)L[4#W]">$QHVIR^T + ][V%F<3AK0:W36RJ=3;#S)LI .L'A>ON,).&K +@E(7-U%Y('J:U[9"&Z4(T_)T.G"!+3 #M>KQQ6/NOC4-E85"C=A]?O![+UZ9S"#3 +R-[A5NN+89P4)("GY[Y0V[%F,.&\^#>YH.%6(;ZNLKK4XCNQF0W#W%[A^:VI+]'< +[DA6U :Z['JAFU2, B*VSSFM6*9FS,D!XIWKHNU-1$II2$4Z%WM=?I_<0#HXT8P_ +T%::PM_L@,-S5[04_!S@,53!W @=+0079#78SSG?[KQ\/$3Y2F)O +?$-,4&#BR7)@=M4C/XV\=UI\D,' 27ZQC.G$)H>*&V=VW$?-B1B(N"6N+A['PT<4 +9][":AIZ57)53)8-9X)I"&,+R*0EI7@=:("D4_J5&'Q.U&BYO)Z3GYKWP.!ZN.3M +4W7CS;BW^[A,.SHH@F^USO(Y9%T= E*_O;Y$:N4<%F0:!J8"9YWXVP3J-;+$-8=R +$-43#C.W^Z![\+N*Y6#Q=8[2WZTFITCS4)\R64N!;($'E1U=YI<8'"C)MSU%'OXP +M-LX@$[SF AGIN3NZF_BB'Z=AYGBZ;L^M +[6EJ:3<#@=10PT+X[=+ZM!$&D$C> 8OWFX$/T+OMJ4D406DOK]N,PMLNK]A6(WXW +5?TRY05,+(7)]E#^./=3=;C-=N@16X31'Y8?36 +/\#6CU=_'_-N;D[^ACG_76BS*JF35= V]QJ67B\QIP)K.[JV$'?,V7H-YDO:8'0> +YD60(+?YJH->%8:MO7B$D$BIVX+Y'&,4OX0X@%4A/9)=M1G!&BJ0[O?YQ_?L)AIGXO>\5 + QJ->V@G1N[]2"S6-,I$ZTV(]2H89.'[;PRT0]#R30RU>S2\MEPJ?NFNOGM!XWKV +&E):7>SOO98]!>" H?!>!:D[ ;M66ZRRP[N+]+A/"%JO&AR<'8W7Q37/*"O6W +J& E]]F9>KTOX(.VZHWFR!WR$8D0??#AG#YP7'7KF.4;?"9H,AL;P!8"4!&>P8>1 +D83:QCMX_PR57Z9_?B-"<7-TK-6.=PEYI,;BS3(D@S-AXR&75!BIT3GH/\"$F)43 +J]_.D%%:M6-9B"@2,17:/1> WU4IEN#_N"K(X EM5Z11\J5 GK(77Z+Z8_Q;[K[V +66$B$*QG0]UUJ@4+1/;P=Q)-=V^8TLVG#NT)1?-'E>3&')*2IA#@A[]SK^(NDE5* +O0O"WN)S.45SN6BBB-V=M&O7<]$$I]EPJ )ZAF>#+";/?WE(VD)3=T)7FTO_YZL" +=?-P;^&/K#H5FC7BQ=)2%L'/T&+[PE;6=Y%9OPEH +SKA!'(@MZ2Z2W98$+C%B:Y.XH5C"?2>[;Z$^)OCDMQ76E86_&@2Y6LO:MC-#F/,5 +YSTEV!#5.2[A];\&):'3]U]3M:(?PC=!28:KMHDEE9\I98B<^LZZ0'"?6#IOMD2G +V-8D4S@.>LG>:F_QF:A\R;0M3Y_\<8,[>/@_DV1@[Z;1#,'$'V-D7-Z[GOU'-,B' +$7^_:_ +WZC%T*ALK,;HUOG+-<74C5?W.K ^1)Q;[7K.ZNN/-W"N'H6XOSL@.PWKR1_ V;GV +K2>8XPQ"[!L"L4W;,6[0FD7^^1F@!J/;5!YAH%\SB/^0G( @J#^/X-'X=JVR)'.N +?/6AYQ=3B#4$?(PY$(3'JEJ0+F:A&]L=X@;8+IZQ=,SN31><)I ='"GH&0>WAYAN +CC!(0: &.@KRU7NG8W+1\B&\N;_D^0!ML +69&:04W]GJ^%8ZP6^CLFBDV>-3GNE#;$,*B[9M/3D9@GS;0A)T-5M&@6#Q\0W>OF +P88;BX=X%UJS!LB=5(JO"RM9;JLO:6$V>5%6X$NR>L@%9G*9TAKGAN:]C@B9Q\R& +'8!V-_DN_HY4_/#]G[4S;6Y&FXFVLTE=*.R/OD7H.H8._WC^N>):7CE0]-YI8)]4 +;F_W;'$J]9B,1,Y@T"<.%WKM>8!.2/E)R8&R15@[_$\%+A*!GQ^MSUB6E)#X&>K% +Y(N"(D"EA:Y[@ME@:$ SZ_MD19L'Z,ZZ*0[+5[FTN;Y."NIZX/5N]UH=FP,/ZW6* +36$0.66J**WCY3!^%7D.W,?=YOSRES$=;,@? +,N.*S\BED"Y[<>_0@(DBJ;F "=!@6$J"8V6, 'QH$_-MG3EF8CAN24295<$\Z/^O + )I(M@2IZ3?49B8U)5UDD-D87P:F/,?#GIF%IDM('!]%;[(FB&]$YEQ*EUE#ZWMA/'\HV:$(6W:.#136 +PIY;Y5+2ATDJ[MIE2W#XPD&.\W9.$HL1MZ S8PB!%R/<$%>R1X-NM]>Z)1K:S61? +V]#>FY#KSBGH;B91J"TZ#I#H*P:N:9BC5UT_YE% ZRZ5"MY,4(,KK@CM,^C@6?R? +RK"=2 V'EXW_X/N@0B^D,P:FSP6+BJ.N@%Z4BZ*0<$L1BL/#,S8L#*U4".+_4]G% +7Y)H!9YA"AM!?/Y?45 # 0-$(BXB^MYC,#40V>+K(E9]>0$H;2\$PH2?2MG?*F2" +!P2<0IS:I,%)_ZD>QI1_)Q(4][>J/(!3_I?H8" >7A,#J;]#>$4T8&'HANI(@58: +P%RV*>-\8YVM<5*EVMGW\_A!86V\'R!T>V8%3:4 )E3L>E4X%"ZG'<03/+GXG9%, +;.JM$Y/%>">*'K2N!4J#'(?3-S/86A'Q3>-@- !? ?TQD< +)+G0 "Q>-\K R-$\ZR4+7JHQ [RK&Y6W.&U^$X3&%+47LW0)^$N!2&C_[=)6O]#? +S=!8'[QE=8;57@:3!0&AS?KF=,JL*0N\")_5AA_"VB//[&L(@FFQ.FYNV!<0 HV_ +8OR?.1OS2NGFY^T(-C/TY'=2;=!7UO%UW_SS3HI@F&GHZ>_&O\LIRK]W<> \XXZ@ +3JU(6OWDNF@>9C!Y)&6@&8Y!AI5C 59Y)(]7\1_[%/%ZV=UW#8A>Q8XF#>ADJX[0?S'HW.&L#6VD2_DU +4I<6<91C#V <2US;_478?/Q$J?]NC&ZI<69I2,V4;.$:)5&2B["@N*MZPC9@ +5BC[ABX_$2VT!WDF]*YI-3+B4ZB2^$9;@.:-F+M-FPX(<68G"2Y^T)('K@G7^RV7 +0.\-Z;K^L,HP2D493&U-G]1OE;"$[[-5UFJMAQ:*P%Z, +M')R^KG\!Z7B3N%92B,P(];O)G="YA\<@:4K477F0O)1D\^[IL"F[B3B#)L*8:1; +[N)Y_?!2*1WS,Y20L31*@T 3F-;*_S=*'0C9I15QO!5#IX=AS%$]R&Q$/@&$;.>K +LT2>LF!@]+^C64A%JTME;O6]0X4G4^=S\$UIXK8"0,C&==G2XASY[?D6W20D>3"& +E@,, A'@B)"GERUP1QBY:S[9]@SD!%O1:W6+KZ@"J%^S@:%1?\XN :9$I@JXAC4 +V(H@%S-0)$(O=AJ+N$58B"8A5^,FG6K'9:0?I@BFWY+,L7C37X0RQ+[)EW,KR2(> +ZXU5"V)Q_@HB,C)$_O<$QX@R4>[N_N-#KIYUP!2>F@Z#R\..K(C/364"(SS3F[MD +LL67Z >XP!:VRSDMVFVL7_CF(Q$& , GXT>TPX.XXRL)H7:U6>YMWA8),"'BX8V1 +MOA]DA_UX*X\5#55._ %0 _Q)F?UF>JW+VM"1>3I%"I:OAG\29WX5C[A D%/)6T< +XRC&?JF[L%[8G*O59*V%J%8-?XM 4EHOL6R^6M4GC,BM860WX@-U8O\D:F'>HEBO +\D?BY[$[]#*S(=-#^N\'0%)*!V?)T5U(60JL-[PVF^7S W+SY8OT]:$^/=_D!\ ?M%-4 +,?83LT1#%_^DAQF8 C*YRWQPNR54@SH-W^?>E3CI.==1% H0XMZOA,LO#'3N&Y3W +NE/MRJ+X]@)+Z!['CY*4;X/M_]N8(H,$),*M;7;7]6:I?7(P0[ 151.+D!YZ]J;= +&ME%CVO,>Q TNWHUT%"_ZF4*@ ;GYG^8\>U"XRY-,?@6W(-5A>U\L-FDEZR%-<8% + @8U('BF00 (QC>6<+ODJ[+F#,T9J)V*>E^HC +.^\N<'"]L=)T:ICM>?:ECG*7.$,>1;[(3.9Z?YC*N8@5A;([ +O%,SZM:S[?-H738CSNW9?1?.O0D^'Q@$UXGL]E] =;HD -7I',?E14+GX"FE%6@S +](BDRO!I=F>L[V69[>.*O[T?T\)-0PN5AVF #QH=$PH]@,FDSZ.-A926;6.D*3P? +4+[EP@]QZEZP1\L:LI*![SL^O*$I\=?@!Z>S G[+(H26T:TU-K31)Q\OS%RE1L6T +M0EW^C_X1RM2;V2MU0Y?*T2OH)-3Q!1\OG\U(:4_,5V$RO! @AC'0%)*1(7POG4 +V 5FS+YM>I>OOGL"!,@7Z3DQ\ ADZ/, %-\*/Z5WDX.T(YVVG,OHR-D].CVB"[.? +V!!ITN:6Z.Q+".H!7$7?.PV!>$77^K4B"Q_%FM*LNPV*V=O@MH0WC>IU6U+\$I[8 + ,>&I'KP:3K=9:#0Z>#L!"9;/@V/H)[583(J<.@]* +T6:[.=N=_(CYC"&0<&Y_E:OD-K%PL,B*'L9*>#3+69?/Y4>)G]Y,VO69A1-:-H3Y +@X_MZUH1=A9:^EY5%X8RZ76GW\I7@?KUT$5%B]1L:163RVK [[U]2;"D^D$PVG=^A1W^!GH\O[D)3A ME7(:0T(^ 4#&G8GA^H+: +JDGA6=H&_2 BA8+ ]M7B]F7*HNVGI(^2M51Q6Z('?=Q#HS6T;X/S]]=@2)V2"[$2 +F.)UQ2&"JV$6@!_H)B2E_3M-Q'>*3*"%35Q/\W<;CEDAST#4C[N^%\DN)_B6Q1!S +H-GB/O#^)K0IWO+0-,(:N?E$;?-$$?\\X$T._-^A/"439@KL(P1Z)"%R<&:EA$_- +7",8RO.&HCEP?8'I3J>ZCMBF->!ZAHD0KGMUT-C 5DF&Y-%#SYY^ N56Z77JM@_ +9 "A':":5+^YL-RD0@6+T[NA$OU!A_];--L!%ENSI[)4($6]/#WT>M)M]YI\JB; +^ZW:>RD]@RZ>,"M*)(\MU6YU1*-7WA F8T%! %4@RG"DE='PE)#38=J918X8,2B" +^/=U$VY^$RZ3R4KR8A*W$CPMMWOAVAIJ[7U9VKQ]",K]OG?8[!?6_ +D"&'BI3F22N&$NFNU2[_/2T6=NDPVH.8*M0VBF 1H],D'3*9?<<+ +MJO=(AX50.M3)$%>6@ IB.[7$SL2AKR:R&$F#\DC3G)9$G_A W83H=&56>]\Y$HL +(#!D;?@U'%5/4T"K&I/!M%P@!-C1;:TBI$(X<08KAQ=&;AR7&H^92)56V4=A(O"] +\2_0[9J_ &XVJ_ (61:?O! 3\M05DJB7]_8,+))E$CF?_P5L,AMP%5I/1T1U;-=" +9AVG2&]T\NX8X@5PK NIYV)M,B [X,)N[2/%2L0*MY=;&6R+4VB:1 +W9P5N(#[\M,9V@@V9(@'1!+*_L*T)]I*ZXDDJ@9(%\9S72/BRX]#)JK9,&4VHEM# +W* F),<4JE+>B\>]GHIW+:9' +%I QQ@P#COXY<\,*.:*W/GH;A/U"]C)#',"7':;?/K.<);0!B*_":I\P2BZ+3 +2>R5J GQFS*GSV$V1R.;RZBYY0W9HM(.96I%MQK>V7"]0#GX^GS+P!DG_+VOBV2P +HQS 0\#S0V-:7#?J,R#5M&R"B_'TAMZCDF="&2>MM:'MF6;F\X@'86Y((>_F+S=3 +P!L@X\)W$'"63K%9G6V07,G]'F1?Y ;H*D\,O YMNM2>10(, /7@2S[O4R$K$CW% +!;C"](^%5D$C?E! +7LHMI<3?IT%MT(J;[%Z2(RH(@DM-]E#T@@]?'(S&)*=^UHO"^P_<2N +&%2[J)@_]!1&5T +COYD=0D86"6#"N-2$@T8TIJ]L @D+8(3EA;1!X^PQ[UGT2;I +6I3!F"R+@\/P/D2,)BV@^1/J&=3<_PAJU_[#$=4ZGHCKTTI-.F( +AVA$P4N3V#S*2(52/LG@A,=C95SLR6$2RS$,MB^?R:RRJYL:TBEK +(EH[*N_I^96,)(*&1O;Q7H1\S^X8!C5(K@S0YIA/'KR+N&W2#V ,\:2Q]^]E<$J6BP*8>PX@CO#$?<,SV +G/W)F*0.,- I+ &%'A]NL$O-6I^-XC_0!' +9(=/29I07I&K>9B*=T;1]B70/>%CR#A!=R1*EI.P>=K<.D'3=1!L 13SNUUB<\IJ +%L [ &#$+*NCS];I %R]B/X[/U/]=)2%?&FN)?A[BJF!V(&8./SAG_"2!C9S3RLJ +!UZZ44I3E3R@>/-^B1MH/5XJW3J+$8HFH217G]')": + F)MR#X:W^=$]0.)]BT]T)L9*R(*):E*7'U9"2>Z UT)?&KXOFX&#E5DX^<<:F\: +60QY\<)2S1YE2*?V$NN#OZ&A? K-9O):M%."0_*XB1W0?9%KW [;DP)UEGG[#B$Y6KM/HM[M9 +(^6A4J#9'(NNUO 2?+1! ""1IG,295!]FE"5# Q(*H@'I1_>R*DYV:#2!2K&9Q38 +%P\'*&5':U#&YW]3FIHDO^3 +6CF-9:W@U_H'R_:C?'EXF17(4H^5)5X["O.*%;*<;B9JX]Q:$?R-)W][^2\.D*L7 +.RI*O'*UY6<;:+^(J42%;+R0D'6,E "^'Z*)'/\;JP(!I*^[0>38.7A%UBW8 DZJ +Z?% %R%'QA!X[?L1(B.T><)6U^VF85Z!^A.W6+E]HF3R%Q41]1$X[IJL>?(2U' 9 +'2H;-PYDJ#QDEJA6T]*05WM.>BVMK[%'F1,7=4S03\$I.++[$9^AD6(;]$)SFSB8 +JA%#Z$'KJ#S !,[J;B6:QA,&EOL0AE@,.6M?NGR0 12\YPYPFNGF?(/GM[7EVF)G +,B5C/B3?C[@F5.R1@ZG[Z4"1NU41X-TQ3T,XABG5PSQA[TOZUKK ICY%JIFH +N&\(T)5E>Y9_5L!-H;>OH<@0A9=EW?_ :/@6[/8O7D+A*/TX!4R?TNVLG+?76V:& +.K:K1/XK<1C0Q4&ITL"WCRHJE6ROCW0\ZZ0S:+-&M SJ9!M. ?N#?'[U3V".23'> +BR1FS_%:TZPS^+:WSGRZE_.9@+'A,D]D1N";O[\%RG.$$L!A@5\X,3*4<3\H;-XJ +N_*#0^06 VJHE'@<8 ^):?XRK9[ .S"T6=B<9-\#?1F(E&?2;XI*C7AR!4H4KF\R +.]3Z/F8%35>4V:1I%Q,1[27FM&ZS%N+^"MZO-.:6$H4YV[_J=1=KX.JYX*HED[V5 +T)D76H)%%$F,D_ $>QT$IG>5M1/V)8;L0@;7@9VZGTUN<&L& ^9Z0[=!BRY+A8E. +&0O#<9\>.@@8A3VE&9#GSUI$Z=!V'1_L8RJ(UWD?OR[U2_BNM2P9IK"6.PW6:X*.J AO !#ED(H>@V@/E2#*(W,'8A +)& RR8(W2-Y[YRP1V&EMV<-QC7U1V@&MMV3,A@8VE46?(HN('JFUC?#]?=ATLFQ +)-A_YC=[F1-KUM!N.3FZ6S2HKRZ!P->*J&6'^29U$[-_B>?L63A#+4&/E:!_+)7H +0>P'&4!W05J!<6,@1MX +P@^\"Q(%M6-.OSX7%U7_U'.>C Y;7K#SX3:"JWQ3/\>),$ F$;-(^J!(DI4R_Q\T +\FGYE%>9:6BE+IZK_?#]+G5:WZ&#=Q%4Q.R1DAC"O(N-6Z(AH+AF5'1Z\3-'.RSW + <_H%'_(WDOP^M<3'YEN<1G^:=J7&P5XT"@EM0-B\CD$2Q?=!)^0P'YV_X_'YP(D +3YM#R5G9@?:'I-M"'6'&D++N97946$O!=0>B1K +LA%"Z;7>80&"CM]V+?KO)02&,"V-IU>6W ]/2SA)9C8S. W*,;MA+^EK6NA &J ?E$RG"#L@(GG1E7_/?5+%^:]/# +\X!?M\OB3H31_$F?VN9?5W]GQ]M@SG;SL"'=K\7#$DIGIYA&*5I]P?AI1XC+;=2 +T+SS#Q382A 1I48YEW1;H6T]<\W(U.2#]I(7@ZQGVQP)G 6/5W4(F^@E\Y;VU85) +B+%%J)U^(?O \12N <^07*1\,\HQYR%;I>67F,G^6#KG,ODMEJ@ ALO4F^*YC$^B +\(;JFA,%0"EA6+#^C+O:R^Z9\K+2=!\-SK:4LJ7%/BWW\ZAW06@;C"WF$ +@6:URU/MSQJ$7'0&G>E/VV%I@(D4MT+VRIPB)M2U _ Z.P#.2O^68*UM-!/B?NJ. +,.*0_C%YE"FTGM]%3"IRR*Q"[SG$R]'_6Y72<3 +-B.!W =MW#(!CP1W$_BD8JP6!**=E-)S= NE8O:1=](;CJ:LEGS]MZZ[QK0X2><. +!R" ,$W&@)A%JML2T6["&%XD=>GM7=$_8L&%_ +*L=V6AG)/C+#JEZ(:+V<5?/3MT(D_YNH;4#8DS $F(*C**)J?UZGX +B.1#?7QN>>MM\&0IJMZ1KW +182 P%P.HJJQKW,8)_O7/E"'3FBDH.,\V'%&')[[.ST?D\+GS:M4NWB[K9YX"H>U +V5"DU2#K35H22_=S+J*=\/>+B:_D62>CQ !:IP(XRJ5ML' +R/2I-?ZJ/<-&8:]#$!2(9.3V;N'O!/>A-%"&EA\DYZD2\$H4WGVQS&A/L4'!X(,H +F&HE.O*L(,Q"#"5+3"#S6Z??!(M8('5/H@ "710]$>'NL@ +;CF8HQUV$.YM=T>R_)D;0CEBE,2F70 VN65HN]&H\HFQ7H!WQ:[*CM<#OHC:6Q'C +CQ>)"-0XP"C[>ST"]8Q#Y54?$G2+:[1T L]<&4/Z$U,BV!IB?\I 9 RRA^-@RS+= +(/$S$,9$QHRTJEW;-AIGWO9K]/O/]'%A['.)M98YQ<'-.'E5G3VI\-X_.!>K-]QV0 +0.1DIDY%4)"I63KPM*P@D>Z#3]U H5;D>D 89EGT&C-O/.:,3T.O8(719P?,"&IY +N:W2:<[-/6Z+J(C3TJ?@T(M1@SQ&ID8>Q;]MOGAL-P%)P'5MUND[50?:WD)B492( +'";OOF?F6PL\JLSY_P43LV%MAHCKE!XI.N7_3>V. 67U%CK^R]7(KFMK>%C@,N5F +<]A0?G#_;USM>AAG=\<"KLTK%N:M,F&HGZ[NQ"O#!CFR[]/]L9Z?-?9+S-J^(ZI27J:"H7BF7\<,54S"J&ON<]-8WE4[\;8*8^GXM\H +H8SLDS@T639W*">P5ZCM7,,ENSV2I8\PHL8C"UD-BR!M'A*PVC[B"2,:N"4N#FXU +XY2N0Y;)5JE\E#0 /OM@Z)G4V])TH[75#K)[OX!B\P\&-68 >GPP[C +(S]Z27IA/A:@AX4^J;P>R*;R!@Q/S=,B0^163\;N7;M-$7-NHF+@@=DP9:UU2 ]^ + FG79&*\6T\]SITQ"PE7X(6K ^K+(P1C, 5H9#2Q3&YU@ +@!7#$=K9 *GFYD?22\?3<>FXH4+]7RT:>TRV5.9Q@A5*."N#0940I%NQO#T']#** +VSO'RC6K2G*(4"KTPJ +B:&.GF$T7 +PYP?K5&48MP-6J3YPN]0'-/\UM.#KEOV,85M30-+ACS".4DN]LYHE +"6N$IDYK ^K]T.DY1NJ5'41#M '#8@*#S=IWH-.7';9V@UF'6$VJ#!?B;N DKW*( +94;NC[>E$BP5>7DV;,'U<5)V0L\ANIRFG&R-^8<36H(3%$J?;,<)]6+$;DVYM([2WOA:7=@PD[J2% G>??4@'<;J^LG.M47IFAMFQ +JP>"8%#X1* :54R!@1$.@Z?Y-X42EWE +C3MIU@)R3:1X_N0\3L&,4 @+/>&&T2;C=\IF(.CM89$AG1Z]+]D-D0O[D6&#!('@ +JCGF(/-\9\+GOU;)OVSO' 7]-0L38R0X\)5;@K#)]4$'1_,3 +;RX?6#-L]S0_N//HZM4H>6HV&Y=LV.?=@V9"D?S*A AX0R$2PA6^1#(PX:Q@J1(D +%C!U6[/.9Q3)OOW)WP_)\ _$W1PJTE?_!R&)5/+/HQ@=C+"P"]JX-))]CI+@84@( +,&FRFG8TNWL1UU %>?NE3\K_;>9W(/8W!^B9L7!&X 1ZQ*,\MR[ZF'B59C!I&4;6 +_5??H+Z#[OK;"CY PT=Z^ORFT13$DD)5_";%5F^H"_OBK.:S2SNX@)'=R@%\C+I< +@WA0[!9T_!6,3]7)3QU&I/3;49+$9?#<-'FL:!T>J*;N9R;JGW?( WI&?8NI-^F= +8_W&/62Q_,Q+Z'IYN,*1CN* )B1K2<7>"O='1%["QI6OOR9K94(A$Z]7GY16*W:2 +WX312:)U&>C(D/QC#'$MVA@?+NC:Y^(/1],YI273TEXR\67Q#0,!RRG,118)U#CV0[->S'ST[=\7HQDU 66[?<)\]'+:#JEJ^ [?-BZ)A]E +HA\2-_QIK7-D,38,<4CZ_,L6:\\_E6BQ_Y#,A6J8!@OR$O(6G5_<\6#=W3\!E+FU +"B[:T-K4,-9F:@+1"7.!N(#2P9:$,"01Y :O-B%0,9[9P.#=],C6_2[+IIMHE+H1 +QL7 M?H4<>ZT@(:F8T6TIGUZQ6,W17<.N,^N1UW*4 +]N&+:#09O6=9B*QP/TF< 79@Z+N">RI3M8RV@_8YJUKDTO*:G6.5[N9)*MG#N%BD\["0>B#QH[L +H.?T6?_7 1@XZ5\(FKA?XFJ'!.VY"5(.KQ3Y[N' *K9FX4:&FM9D^^_PX2D!I-3G +'BK:*L%]CL+E\W1I^?3\:'E2Y$:' 7K7LYT2Y.#HF'S0E=$/XI\'C1)DT!@P."[7 +YX9?"S%?>C M2(MW23/ZTVJRH4]P+,[/@AYGE(VH=.FWKG8*A@#VM35:7R@,^@RC +$*P4E\*M2+11RY$GUD'\G2B_&\U6 + AVQ@D%H!"9>#JM,+<1#)@(JEIUW4^OYB+R"(RL!SGLZ;/"W8K>X2RD LE"%W@C5 +0OQ!.SI UZJ25[ZX2BZ,G[$21"Z>5&0K0ECII%D?!S**SK6*Y?CI7 3'7QH[(AZ, +T!XXT^WQS" X%3YA#0[CRTD!J-,?69^!SG5@Z_>5!%\*FDYR9*W?*%&E=3?OZ+AJ +._3,'IOV@B'+56R0;BR0BFG59;/;K[S<2O4)*ANEP!!](2L8NTQ"O#XYS-!38)3* +>87#L_Y47) E3!CG]L.,=)(&&,0/QW-F?>X8O%J^F^4OJ1\&SJI.1'V/=0--V(%' +U(Q28B,;JU2"=@NP\*/"&-N]!LSU%]AE2#OUS909 G/O^O2\ HB'MMC)(JZZ%MOH +W4KR"1TYF#@W;3Q SL004@WN6EJ-4D>H]; $[1JB/-,<3@\Z>TS!E%)6XH_$4VM= +\-#8PH(T,#?U9B-KV()B_@T@HT:&BW'MM]NMGH\0NZ1R:TK./SZ6W%-$4;U^E!%) +975H(@.%_G,X%"E=ADD%>M8+.RNLX:/P1PPS^^[R+R_\A2[8.S2K(R3- +Z>.'K:WF/HVL:M-_R>WC],Q_7\O69@9AY'KY=FE+A#%Y]:"O#6'SFRQ>?\1^##CK +?@@TO2!]H$B'8H<&HQ-T$]0S=V;NLQ+&CD_\+]2UGSG6A3*!.2\^67);(N7OAZC1 +I$/C%$9M/[8;#<[N/.[W'3-O]'!&PBTT4:)-/X?02SQEZ$HF/4Z"/7"E@TIOJV=+ +'?VUO=6IU!04 5\A_6)2Q31-4NMG2Q*PMNL.A]X(,&O0Y* X^$70DF_1<;DW$*VH +9@7\T-X<5>V$M_.]R/5JB)TJ/A"5Q<(E.<[VIVP%8QV49KAM%(PNI;A;$&1XS7!T +P'<]# Q4V9@5P89_^"(L#C/*D,^Z]:VF0[&P?_*BG&KWVL=1+/YX8(7!Z$EY&L$K +WM7*("#]>J&8YDDD&*$+XS6HAJ>1^D:V(QB>&' GQ!Z ,W&@T:S>+X4&@ U=/BB& +S/"";#W=BNA-_TX1"X.O9% L&ZVI/P6]X>&"GC2$^9(-2WI$EQQ,?84>QT+WEQ]17^P_BE_X2< $XA0VRH)@Z;5"+6OG^!%3K9LO?WM0U9C2"?GF#9 +!O3X2'CB K28!2GC7=,.W>%/^,*7?YY%.)IU%P*\0O '?@L+&Y(-"16VO1[B\,EAZF4@@:.,P!%T6]=U#K'+,G/2@<' +\52L8[!D)-9A4'O&"([R)H+$*U)=,8<.*CJ)LLH$()LO-PC#3-]0$3\%I-RM(+4M +4N?])IWE_6RV( 3&;1E)O^X@SJ:<@NJ3]OG0,%?=8=M,8GLJ6,HMO^/H94\OCZ^% +[\ID&619]_N*A1<<@(T(_7Z =,3VY=<36E<"5.8312_C#0,4!.5U=7R^EN$/4 TI +/-MYOTUJ>_%K[CS$#.9#Y['((:G*&@GS] W')Z1N%TQXLKB:]DOXCA?0J:V7VE63 +A@KDG(]6)VR)WIV3\4"LE:Q3R!I4(_-UQ\05A4FR6MR_5FHB*9,&C4(S''F4\W)6[AXX1@B^E:WQZG@L$ +M4#=C^/S$=N"MEU:] 28?+B1TFN@$+0,@5#?0]V\"$*.D7;M_(V\VTCLGQ8I@7@L +\ET<)@\ +QHON)X(M=1(FM1PX]W_-,]GR78U]A!YA,_:8C:N8&:P0>B$[1RK-T#E%F0[7G81 +.GGW;^KD_(B!,^:,E(6VD337S,D:Z+R&U Z="DA]:_ASX?S^2S;:D!-75[.>9Z;2 +V7:[X;;HA"NLOQ,["-_DP60P=NV^6:=R<,)3W0 MC7$KNE/H&GG2EED$]8>0(7$/ +" '!V2Q/8ZGYP7Z//>S9D)CX2H+H/[_!R1B&$ XW8P2VC$88\*KE7,?U;%HV,9)G +T+H"T/OR=M+RUASU=.QMMXG^SZH561-2?A+@6SE3>RP(/!O@^D'G82G*5U\8GB5XU#B#]M\6; +QLWX+0FQP+O1V+ @'F UI:;Y#L[<0()\ICJAR(8&%IO8\MJ"Z&W"[4BJTD4-GQ'2 +/6-7L#B4\6YFT<%5G*59C&_\2JL\B5,JI\!P>8S80-$R_3P_X?+P:-S%)(H-_Z^B +W>3A D#%(>B&RO]!%NOO0&T\_KQJ2"I^USY#F < '%[X.O9PWT[0>1T,.ABJDPPM +(=1XAR.]PNVQ?G SVAC !Z-9A:Z"+YX16 MHYAB?89[ J+J]- L1V4 +J])3IRO2CZ.O\7!TQ\1G5@OPN.D+;K\0C#JI,/*SQR ;S^UQ(D1\Q=C!#+V/$DB +6+/H(EFL@1P0(.59OZ(]^;[$AQA%(Y^TKPM6;!=4A?LY=9AP7MVLOJW%/Q(!A2U[ +W2M$SDZ/ZR!?GMJ'?BLAXU=E2VNEQ9"7KB 3/[G=.\K3OYG$B[%4\CPZU50T%98Y +)%I/02R G4ARF0!O)]( OG,A!L& !P5#R!@&5SLO95>-5\JXX>&+E7;I2W_YYKP+ +3;K6%.0J.AIG\N0]PGZ ^IM$6>@HMJ:FG%QW-H-;R ";'H:8<&;]V>/J^22^(^60 +X8; -/.G)CAZ/0$=\*MQG5W5+<@9+H;$#[U;!+H@>1<@/L8_,BDN4[9:]8PB$PV +'X!Z<1*"MOFY.S^20IA2_;(6.V\\P4W2V9G"*0-.*:3V^U 1(1W126YGZD#'>*!M +&U&2:JXLCY]F;SO"M2T?Y*0Q/AE1FJV@NEO;#M2,G$]P)7_F&6>,U'*X/1C>,3": +$U46]9H2T[XF1:*-Z\<.[4\_]-G6/(LAV1%Q3* !]F\#1BXCL[FO#*6&_,R/:./Y +NAE>X<7^I&5K_],J9#$1(>,="R!V4 69!7GK:E:X&Y20O 2IC/.91\3+V3UD]JL# +U%SJ^1[LEQ$5T.5,U&H])SU5M)XS&#U50D>W6^[/3UXS2OQ67]GE3:@K_CI2@]TY +;#Y;7DNPS.N7[&Y8*1#I77K)-E*:PO&>B956V$(HPXN35$E-*GI72_T&;03&C?#V +G(M+LT6+[51!^");J&] DN.[,E6H8>QQ\W)H:>56*IC]D7.:C\]0DHK&A[C48D]$%E66AE#D)!K.Z:DT+R +T>RTP'J\24KA0D^&:S&(NGSHQI3->6@2&MB)[Q'7%V804AX^B<>)^7*L\#->,1EX +,USR84F028]&.NQZ/VN_5WE/ZWR<%0,E"#X:G>^^FU8!/K-S7J8MEI*XG +Y]7^&I/Z"%Q:O&6I2^R%IN+X+$9(@EZ?6D3U37TK^ZE;P1X>E13//6<18):G2Y=' +7H_&@<)!$8^F^1 IY .\T@F+--=Q92].FA85+!+85A0#,S4KB730F=P= VEJ' +6]<:2XHR [;\;W/N>X1C!T#1B _H#/;0A;["24^[4VZ?@\_0\/SLG/J=E,K#VI(= +PS3?T*6Z"X[X0$T8::>=7=UA1IV9EG@,CL(@:6DY3,L7&@/9]@;CV#:_32-I1T-? +NJ$2^EI/;/L.C.WE,.#;(B)"K;Z>]#P[C)AC$J93_'S-'1/=%L3NH#>)V2_NO-4U +EV)%]F-HNU@[H0V.ZXQX$JCS#)C:+5_VTX@?SUN+WQ56.U'&!CDO8[OUR>6TX"1+ +]\EJ7[*:'HJA_)2PC%!AL5M$B>XCV +P,8:3]F50Z-R;%O^C'Z4D*7,*2^EV=%EK- &;5IE5\YV$GJ\N_Y3GE@<7,?[.L U +LAZ*4%1DB&\B*?1-CZIIK3L/OUK#ROL(U!DWW*@ARF6>M8:'Z 9J$NQS?(&8EG]P +4J\-_8<0?D&VGPV+K,^UI#A;EL HL:6UN16H6#2BGG+1 C:FU_-)#2'@%QRUQB < +P&0;%X*8'*C33IP)*IR[EM,&16E_@, A9C#THO38R\I$$]3+H4V\OWC-CI#<_-5(KN\/Z/YPNS +E1U+Z,*\-2BRWD'&V5@\DXNQI2/3K U"E9"MGV?=_)9J2=QS*D\\;)PP4"X\3"N@ +#0)F?4.HW%F=U" X(0WUV?FL W(73*+3]?6S<=(X(LC8 KVD-+X;UI!KC0J>,L[< +;S\B 9E]:E>C*;< *PG>WBSN,8^\SP)6Y9L!W&@%^V*UX=;C[P+^H/%(A$>\*2^+ ++IY#S^\Z3MYNAG#:[#7Q(92MX'"&1$?TV-P:^RB$;ZUB,&X,.TAZL3,O)#/FUJ5[ +@LJ)4>^#X$ _=7PPD<@\"YL%V3MW/,XO;Z'^RJT[V"C5QB9TY\.Z<>\O-\'=NLZ,(%:?%_W&9FF>GUWJ"RLM?&L(+39.S W'V$VT&Q< +[CV2O+0& $*/?H>[]'3.F&NM<47/"4%R;C%AKE!#PS->R/28*P\;J4V0*EA,(?AF +)">9B<(R5!+P+%MM=Y D1^@*7IAL909]]C=:HX9]8PX&"JOOK!O[C86*^S(@ON_& +9Q!Y"63,,]0_KGF!4_4R)($[+OPA;N5X!#S8:EWQPZ$MX"^$0+"[-.T*N<_I6TF6C +8Y19)SX>Q>.1/*2\CV.P-;SF!.1GNK+B\*N!LPE'UF$]^__1";[T^UE<6<[#CJ@BXS9?UI[E +I $VX79$D0?*^XR67,PP=X.HW9P01R3$L"Y]2N!-%02HASK\O(_(]>FR!/V'H8^( +5W&?D*"("E!B5@P)Y$.#5\BYA?I]%E(2]M7YFRD"-?L (UUE%/25G(:OB2C"\K M +\_;F5KBB#S46G:W5A"AR$-.D]!VC*UDHQB9&V7H86#68IV2HE8\?S&:FD\T12A%V +C.)*YAGE-=HTLE[&R>93?8GO8J]?;8H&A*AW6F1"G4Y/3%NDC#N^XDIT,QMWG6B& +<\0P2Z=;Q1)R-POU-]\WVWR^6GAJ8EZ,:,A9/E5+@_>BGK]A\?G/!Q.NF<3(/ZA' +!0W&&ITKM! W?G7')%,)RZ[[6$,$WPY8NL32M4=[#9IY"'^U*3IF-@\C8_KU6IN, +=3J4>AH?O%NQ&9RLSL0_-<^TE#KTN'H%SNQPT7J$TO]=4 )#\5.W$X]V5.ERP]^/ +C)BW!7+.+1HSK0!S>?MQ17+ND@QI>=W;Y9/1ES4 B=-]$N#"SN;-*&F_?CQVCCK; +7>MD@8G!%@LRX:U4)!1.UB4?AMC'A^9\A4$3<1)A:M2%D\U&A&A\-GQ$+@ +=3F5X7NB;@SX[#B?A[!7'WRN6[:;2LB=G6JBW3DTO^UF0M5KDA85.[$Y"X?TK@+O/S61%U"UX'27 ]O:87X[4,'H!A/?$51-]M-.> +VO_)FHM"2KIO?_HSF+P=B17GW$,UYC,D33_H!]%3!JH,@F2W*R0'NK2S5J5\\(&? +J.EKR=?)LF,D'I N*(DWG'Z@-.J:YWZ0)$X+T%=KK:7SPC'](0C]-7Q9#Q']_G%6 +FT7P@%NH&Y>B3]/D3XGP)*W#1V<@6B2 C2 +P\WR:G,< @A[(>!U"8GB#E&AR^>AD93P;,M!N/\TE:9<::JH1%.,JGJ7'*[J.DG;K-9]G8=H<@6K6)CM,'-RHB9 /:\@<[F*27:_= Q J1">F[*E7@?0FC^>LX39B_VP.I VQ=41_I +=73@>,]P%[%D>S86??1&#P?0C;JA%N"<>+7RI$V:V2RLVCH(FI9#KB)J=E-_CU0J +M] 8NXA0?*!/@;3NN>0[1I+PSGQ2P&Q 4%E#IPB0SZJK<862-:CV^EM/9?/Y GC4 +@XFG_M'<\;&:CE=CCJ.$FCMKZ!"G2NHO"[^4H"F!1=)^*10D)A);S-UA@,21&ZZ/ +J'FX_NX2_ES?UUAB=N4K KJS:WQ,KZJN(-;U,+,V+1E_/(G"G^%H-64A#/O=Q$4 +68#U^@8)^]-Q2-_$!+&&)X7LD\_]T]^@$IZ3[?:%$&'ECCI;5#O3[2R-ZP0VZ116 +\C;M:1/)W>O66)X\<[AX3=B^?/U2G9B*XF:I[J_(Q0MH@DA9WC6QG8P<";2AIXJ4 +55C,&EO@F'0T%< B>%>!U3@&@W;QU;_7<%O'7[A((%(P>PGW=8KPCLE9>YK#EO$T +7'\11Q,< 2.7DA@L$.-*833B:I$PVYHQ\)9 /&J3I$>)509H/JKU('JW-47D&,>D +ZK\T__F<&<$'__#!*$(R2G+YZWE C;%<+VD*#3ZP3',R:0K/6M6796I4GL@7: +ACUX"!,=L ?$NPWMYY'6F32-'4@?'[NHM&E'"BOSVQKOCB/$5WKGKCMZA<.K>J+L +6=IY#EY;/+[E)BRUHE&HR'4!T =[L1,J8=S1W#C?W9.GG#@!8(V_6]I"IS$M=7AU +P'Z6;VDDW>ECIR:/CV1G)EIVQZ(]7:"#&\X05^S/\^SW.F&CR^4G\4S9IKR@I5\B +QU'S##Y%96T+1#6,B*4X6\$628D=WI?YG6-8!>,P[HJ9>6_6E&(CS@%X+\_:_L*/ +RB;LQ\/2]V@1T16H1&JUF',V_I%JC>#!.\/&H .R>D9(J2*<,3BFY0> G^1@3&_O +%RR 'GYZ6)2\ H),N%?F'TRP;WM'+>"Q387:9ZW53.!R>IM1DV0C,*Q5/^TX,G^& +2]%7BLQS"HYZ0;X2J%'[2*-(9Y1>0?[>2W2V=FKO0IO.F\N=V[" GC'Z4-S![($IX37,3M@M'2:99"2&L7SMH9P68 +?DB5V&7*5145=P=.2Z\4\H81T];=O2"Q+\6U6WYL@Z42YV^GX4C/;HQP+RJSW06# +T4"+DX)/U6@C(]P/R?TU+O;.6$%>F(^+0V<2=\?7W0^!][-?J*$J'!+W(C+B?//H +)RQ'QOX["7L'F#]2JBCQ_[T4^T17$_]V8;^,6TKER+H;-*X*-BTL9A4;;,X'@-2 I37\Y)NU$<8\5[4QTQC@02]* \R WF@J^1( +1>2IV+R$'H(9A$R(M.CWGBD5X]<^&2/N^I.=N(V2*]74)0RU9[SP*%V$%9P2/V/Z +40S'&IF&0F-;(:W13<_&9-8K]/4<:I),BA()6 \@67*O+@FV ^Q)]=F+VAD1 + O7.'MZX[B#9D$73Q%19^F;MP8"?Y>G>Q(>30=N,X>5R,2'::]NF5D"P?P6J)84. +5$:F9YX+]C5#5IQ]QNM#9SG_G!=I*7CVL\16RF@X#"L 0#@>*O]2.U=;MU#'6JSB +^^A @?88XUFEHL:E9(O+BWB4X"+Z\[#J1,N8ET*# H89%2UST/_B6;']'^V#CHE7 +5&JS7_J8"(]4#U' B,MLG*_?'8R0G>TL4#)'339!RPRO;6(>$GK(.S%^3O0W>&J* +L%G9YR*V$?_4DSUM$-?W0J7;Z?*)['0"+I8TS0"Z&/!-6M('=^I08K_JSD? +MP%?@4C\MBM ;9BR;TF,.BR!)6]=P*SLB16@V2R*(B2!'\V/ML)EW+B>)P.^O27S +'HC)$/U5?98(-V ^GX,F%]0>T#L=,1TS=-B-(2L8>U/Q[M?7J!.8_CF[8E;;TE9P +B$+'T^0/2E4-.\&K .Y<(/*B0$'^C7L9X$[ZP_T7?(31TG$<&Q!X5E\[^W-Y)O&> +0=6=#0N":>'ER97C\W=1":%C^!LX?(\-K/=C&M'8E^QUO"%!W;^P(OEKXE-K+=J? +S!V[SNJ2IRNV(48 3Q+[4^X$4X$DM7<8FRO91MV+(W"FHFY*I;H4GTD 6OAJ@&B\JQ"+H5P?635@GL!"R5YA4B"C?)U +#'.D&1_9(\421Y2^*@. TIG@Q;G#A:LF:8#K@1D+/]5S3W;")SYC%@LZI$H1]Y<> +GF]>W&=H&0!##.NLZ9D),V<9)E4=5!;VYG>J4U=PG1FG1X[H P\&3O *.S?S_&+S +LH"G#Q]3>H VZ^>C0VM=#?/Z@XEUAR15W3W;L;\>-::16:[O2B^$%)95>0?]-I:Y +5=N@31&$$2N=IMR$.@J +QRO] >KR&0.*.8UBFX;Q2V=RW-%"TPZO +0Y#[3BN>Z&QD]V!:5PVE^RJ(Q"GD_ +2&S(I(U:@&2X];*4RB_)Q2[+9P:-56?Q^SW:_/L(,9,O1H_!==O/$M(4>-/F&:0& +/:.2UU75T9R ;_8!N#9W?D OUX;>?>0;2$+Y/E&$5<&/W V>L=2)+0@2VIO85*:. +*#G26(K%O9AEE"(]Y@IAB3E+/!%/U&NZXN+!*X4C4L5B]9')B968W)W,6C;\.G!9CFJGB1("%#G9+-%SE=@GU-:ZE88?:-HBYM%K +M*P&3D7#";#/*!46ID \NU8,UK8.X0,?M _A ; +4 MV4PAF%H\)7=D;'74!J0:H[?A ):)*&_YKD^8#Z3@YQWH:XED8Y)X'=HY#_8!' +A])EQ@=5?71870-?'CI9RPDKT=1R6>" +/V$FP&Z3[T^P.VV;:$7BT1] :<(QC2Q OZ#=CF-/L1!5A,VG0/D,)N +=XK&D>3*C3DL28?C$V-(4G3-,!>\=Q X=(&;:17>V+?'W$. +C5UDNK?D$1R!0N3.N%J;'NA01!/F*O$:^;F,\@4+:RF8'DWV.(QV,T!2+_AA"489 +T!\\U]^'^ZC]/DHS=T"DY69$7ZM?/*'@1@D;@OL@<-L?FO +#.R::%L?662,_+&GN&5:\)(15R&JO.RBE$/[62I#LD^PC3%Q C:NX(@X9#!\BT\L +_N(#9M3#$(_R0!31_(!6)BJA$D0CDXT"_MC!8_4$\-(P]^U]&NPWR)*K254//ZHHB@O-/31$)0+HRD +'OXXB87)@!FLZW(E&SPP%*C0.7Q+.K8)]M#]]5-:$[[)'!5(\QO80DYK0!I*WUTR +4#7XC*+6YL]+G=*F!EBW.O"ATK2T\+[2<&DG5AY.;/$Z#@KQ1CY#; O,(B2[6->T +G2$,Q3P4)-S;SXSP#V_S%F#,,.P+X/7#,(>8A)DU)\$\>>\#.>O_>8%$$0A$]5TY@FOG@N=\1@:+QEM8QZ +#.E=V?'ROQN**# ?G(H.CQR#Y;M+HLG[1]3U@O/H=^^B!,'9*@VAT($&UW0+V3ARP3$^*3 L2D00:CV&%'AAV:\RWM\T9?S\ +RFCCI!CW]7(Q4L<)=@YK,3X(SPY*<7>)!>K/'SL1V[P?Y4KZA1^8 [Y0YI8;KXW(>)+&CY&-!W^S_-2)". +VXA)G!X(,G)NBA_#P&&E6"+>.YOKW!4J]4>FPM\(6\CGT8UI;"Y.M( 0[OW*J\++ +HAUY%/ T?\;"(TT2@HV>T;AOW:AXT.^8>SV4C.KZ]_Q,BVR8(F:X'\MXD59?.X%0IVH;-*AG/9['R3>@##G +&S$L+Y):M^S0-@/PB^]NL(.C5G-J!W0ML0FL:JNOI\X>$'YJXSS^2H'F:0#&(_=> +^,X!0KL=CY*=C65\"=MFI9441ND8.F6DP\\Q@+?H?3B]\Y6QC6S,]IV=#CQ88,F+ +HH6T1S\6K]=]WT2]KVN'O064.,"*9X=R:E^Q+43$U,_WF@C1W7\^ 8Q+A[TE=7H" +6$)7%BA5.V^?_-2L;@I^DQ44C'C;PAC.M/!=.4 "P)HL.UJQ ]!(0;:G7F6OH?VY<:BSICWSJ+IPF<-AM[)B8F=?G8OA>4U)$B8TNHH#C/[N +RP7WR_(@O3.?VF&4]L)>_PA#4?=>;W] OTLGPVU$#F(GF<9]0XB.ATC'P8]*L)O/ +Y;[V:-EG^T6XLUO23TBA7=0H=9Z\7_];9M!VJ'7&%?#)B(,&,,-8]U18MFBN,!/, +%#XK;Z>K$Q)@\ ?M,X2&>ND")2[LX;:GVQSE*\/Q5,H'%.W!("KT)?*J9A4T=9KD +5E^\$/JQ9QL*<,A,!\87&0F'/!<@[5_.FKL/Y*XL$J4$3L$%<8A3C1;8_&D=86_/ +W4#V!'U2NBM%9GPO($U[XEPZ0#"-C\#Z+N]EHJ:^TTG! M^SRYE[/-*O\KN@[2$S +4OV)0!$54(4+!?<_!72CR^TQ>3O:ZK(UO^AIK1O,\5*]Q?$:?192*[ ++<%)CT-U.KP:R5<@4@(:Z;#U\YZKI8$XJO,X","&="Z,V=.%LI$4Q? C6X8:]K3A +%KH"F)!:^=6?">N4\70B3'^*Z/LB3ARJWO P\X//1 NJ<;?_<,SZ"^RLD$=WK[F3);$5U0JHRP'(%H&-!&U,@G\ +"+B"-O- +6_53SX.?/F:E^)(LB7/G@EC3PEB%C:Q0>2!?33X08YBYC%HM&6N1J0YWIWPJH<^8 +L%%3'Q]%JOI4D[:M'MY5 \SPT.2_U$A0UR%( +V/"P8EG5@C.PWV8(<5UA&6G!]Q3,"HD54[*".F%?9LI4T?N>^K5-E6Y<#!?)-C[$ +\4NP8OCA3M#," $I6T?QGBI#$4EUPDI'UBM&-QK]I/10WB=NVYM\,Q*IZ)F-OV!\5:XJ],\&6EKA$"GB9\1*K32*W'J3[LZGK +E5DN4L$ 6-$@.(J4S9UQC?/ ]? ETZ_1BEQ VTE5I*.Q)H^NXCS^R5WF$755W2) +B<:HSOG9VLK?=GI9D?MUJ;TN;>9@PJ_/-L\;VGH_^5S/96;?8 +[WKNWVW33T852Q/5]L^'$9X3_KK(;@%\1I=G!XZGO*JO3TD0^,"@T7/KMPV<"T=- +#)BT4B-\6W84!/N,$H9L7*ZF\_)IW40\M9"#-\GZEEV=]^BK7EK]K0=9S-D\\0", +UD^34.HBTL]D"E,T=S;O#RF^K!SYALL%:=3CJ_]_J\&^4(#.WI/"V=$8"A#AZF\P +:C5_EO"I.YL7B5(=]VGLZB=84&#%AQQ:\>Z?VX@<*J(!_S.3TTIGS%<_,9W0710G +N=X6I7EVY:"#/7\U2SJ_\FTJ#/@1HA_#D[C@G79#HLBHB?^-& Y1?'>2K'X%@3!3 +*WAS/@VG B*_HIR2DJ"59]/>_<"=1I0)FW_O\44+D??F9T)YK!\/QLI=K96.@*WQ +4EKZP+2G4G0 ;EA$ZHUK;Z"V;N\PQV>0)B?4XF]MLJ +-822+0ZGY>*5D5%\A]LY7OIHH&70K>4W"^,<+&WFR)*[=I@2=3[[_>&*77:G5!)) +"6.N\["C9HD!@UL_9.4'^ZP.GN5_.<;Y,H-LQN'#Q/ZF^L#,7X#']E0J!$Q):-V2 +BG>KA\OOI*+S1GO$K]XT+@XWR5;N,7RI;!&'569[Q>Y"L,XC'^*C4Q6[#5)R,?Z= +6:I8G*??0'K4C2.';JQ6Y9\KW58\2Q;+F ;79IN9;1<2@VRC1QZ?(VEI+<[-"(SZGZ0NC@AU$0"GB'').'@?"+;K*F,4W< +&!0A:UU$UJ(']A,V,2$>9V[]@(GK7E^ACH>'IY_YSM>*150!43-;RMF2U+ES=$6B +&N5M$AOC&OP.V(49XH<'9(FH9;;%7W,-BO!R@0 HV3CT< #I.Z(,_:H^_"4#__S8 +MO"XXZ0_3D0XZP*\L\_ZX^2XE?0M>#-JT:=VHT0Y$/B'A!KL%-:>;R=B[B<3;^;"OULW".O!QFJ_?1*OK%WL,13_Z9D$MT$"2IY;],A<%[P@?0E +?>BKBLQP=O/^TW)5+7(E7&^[+Q>75H3)=AUR!( =DS)MOWF0:W?QX[,3O7_>;?=! +<*8;C?R4MI#;)L X1F#>H'!U/^67(L>4E9+% +9B^X"%DS%I+'3OG!R[498L\YBR<^X4>._JG(Q@_]T+DRY +Y]P++0"I0\@9PX2#\BI+9;4 HK3%02C(?\6T:(%CO!HOY%TR\65@M-7I. #D.%IG0MIE_D4- T 3HXM"(W($6PG( +ZD,V,5OM-30AY-'[?#2*N.]"+RW+QVAG.K:;[4-WR!Y*2<,#-ULBZOG;#G_5$KPX +H'4D"^VZWOW8UKU>]N?P.QU6^5.<;434\F-3U*SJ#?UCEZR0KK"43*/29)2["RQE +7_&V8A)XJ[MC^VIE=?)[NH!24?Q&Q8[X1^_)C,3N"9:9A +L^M@YF?-'*IV.[*Y0P;0"7"96U27OR2VX5!#Q2SSD[9V$^JL>$9UE+T,.',N@0KO +76B0+1#NESV@P%N;UH^/G,W,&30Z,RS+Q-($H +6^)1^MOTZEZ5.#3=K8B%5)E45/#@AM?4^6(-:9S$,MDZ+)(/)F\T+],6O;.COYB? +B-JGNPSJJ11?Z<"5EPZJ"7/7FY[4L[ &O]$2+(./..R[4D#5X,N/A.(\:"H. +?4GW-7+7Q4T$$=^>9^^[H-I9V8+FL%=*UB^Y!\9R@ +K:!3QL+1'2EPMJJ6,T:[)@0?#009[A//3*7U"=!XYNP:P4IHAZM:+9H,E$>^VSVI +!%\L[*6#X\XJZJU>"E\OH?OA39!HD-?H++6[D]S?9+&^(X^=P&@D0#=&[1DW&? I +3P@6^!(G#41-S)&]ELOFJ";BD1J12@^UZ&[;X(5].2%&IDO97(MJ:VO7 +]Z$'EN$KJ7DA>K-3.59$=*%;RMK2A4 .2X@KED/LR(*K2V#JK 4?)0H'.(*0D/3_NV+]XV^^/1NM*=FN^-D+I)&EB,QV2 !V&!=O +>MRNLHD%RZ25!CVWW BN!TR!Z!V[$>M%5&Y4"Q!-L/HT.1,93NIW5"8@/3[_PJ$? +15L;@EYN!("Y>XCZM5[#L3R.K$;'2C\.)WV_XW#A>I7^X;(B4V\GET1S.C[JU^6"D1>RTL8IE +U-@*BNAQQPM"BQZXH88-J@]7>NA\@5(D[8*;O"*:K]X.%T35_7,EFRPCPY$CZ@M< +T(,^$#,U7-QR)>E.W%\QE"FJ#DI64KH5P\AYA-F:[%918M/\]R1W5HHG=EC(77'!:B$.K^,7Z 1F(1'23?&DZ +,I/:?6BQB]S;D0&$F#-E=3![_^$F3T,76=OC77[RS2T%5 ^J;8J2%B()JKY,.R$' +.[#(C"ILP[+: 3G0FEB-&KE4).']6BI3OY&X(0V>@44H23>DQ?!$L7PAKK)&%ZZ5 +@E*B].3,29^#$\E_6>!I/#:?5GH_4/6VQ?/V[F^;]I_<9&,'MXB4TJ!>"JVX8:($ +-S=S7&%>"XR.3$+T=1_-X\(\I6_:KM[L@*SZPQN@^U$P9,R6/ADN5^ZYS-5\1&/@5W +HX7UF+< +.&/*-$QD-#3/!L3H>E1Z+MTR?6AL:90U@)DXF>'&B=S>,35,]? =#I9X!A(UM(BE +4@1W&=BIG?P"7Y+J ,!=0>BY'[MDF(W(4YWL4SA"*S;>CH@]3""YCY%U@/$ZB13Q +=EF9[BTKLR-VW(KE'>GF6F)+"HGK8J?_$5^MMXV&)04-T.P[H)%TB)2$,KZ-![Q$ +5-!!NZ5F;#,*8,3- +:[(3I(W390=-TJ,O\Y/RO;P.'BP1\F5L>Y A9#TN84()HS\%EGT.M,#@W3+Y5$8; +P4%R#F@L?YA+OJ)/NR\2BZM],10\ .$M4#5G+_6\CP:AU1,Z.L1CG7])_O@Q^WV" +V=_>R"1)8>FKW-T)"]4B3,4[\\?\JW( K1S%XGQ MZ?(3-Q7>&-8ED36, +,!R/F)S!&O()[ $$_VK* 1Y>OH['"K%'VF7YI4H1)D0JK#M"\?N"6M>)KW"Z%;P? +631=G1GAZ&'RH@N6"5SC=!Y5J8=Z@-N E'KWCCP#L]-4.F'15/9FV);[>F8-G NE ++^%U/6?[\DGDF#$.K7SM[C\3 +,YS15'6MYU;C4OVT&6[ES#:/C6EHUY)1M!'.[;QVGM^GGW-U1@[X@B4A+O _^7C$ +\A41$HCE)0>]"%C [T3JR#T[8[KAK)QH7DTFG2>[)/]U4\;<@(,?!M)#EI_K:;*!:-J2QCD" 6D5WX<6;P +3JORDVI8_3MHD5< ]'XB*!C$VSI67)9=,J"#O!R?V/[0Y;[S@;E?ZCK<) +XH3U6R%WFLNN+!>-^'E91NSZ\F2;KALY>:],1*(=C,PP[BM>G[*I1 A3X89]#E[S +@]4T)H?!%N":5GP0(&7+7H_%Q20 $\Y1T-KA"-7T/\Q\.6?D: N'I L_UH '&6W +021)953COR%A$)V"_7\;]QS=7MX521F2%RXP_@&W [B, 4!C0+U(2_$KLO9Z0D,? +*=Y!&K'@(=$'$>I1]RM)8O+'=#"L #,0X!)\ REAI.3-XK>NC5.F=$@:@NCO6C^M +F_6VR;K&,( 75YME[LH+0:9$E0K&M)%@1T+CN3,RO]L(DRB40Z3!* [%Z;9T0G[1 +]H74ID,V"?^ZB[PRX.V[E"L%%SZMS!ISFP:0:8V,+^ W[IOOSH'+9;DG&(J7L*>@ +$ELG&)9B::M)0/Y)H5:;5X!91S!37E55OA*$Q?V>'I:D+F[%- +,'W]X1'\0T7VN'*:[-#)9RJZP^(\1O>D]\0&5E$IMO'1?+0Q!'44D'DM5;099/+) +#^DOR G!&ZLA4)P*5V4^ CM807\\#*T2+5E&8(K,%6=>IS+B"A0\TB8QKJ N>L#D +/SO7/?CZ.IO%RY39#+)VZ%<=^2BW:LZR!P?=-*$JO*I7-4$\O)U.>H17+$JXV8EC +:L?+Z-0: DX5]I;:5+=_4BX:!:O=W\JZ:^#,JZ50<>97-#;D%-Q(!"PJ6JC>Y!JA +=7^<8KD^=(RZ>X6 !;-@$06DQ1];Q%'Z^N=WGF'.B:40 /5?H^]*HW.Y$/O'?KD\KWH*K630V9T!DE(:D*'9H (#.ZE'X\ +D_\$[+REZP25"H'PR!DQ! &$?GBBN8F8N=&^E7*V4@%SE 1E.V YP#[ISX@) +*E);6IJO+E3?YANS)*<7&YN 6\*MR,-L0,N]8J]=U:@0<+2*)OQ3,=2%ED.Q/X&R +!O7/B"RI#J-!$?0%NN@B(X7 Z9#\P;X!79N'Z '._(?]9'% 9U74M1H#T]@B\.,&TKC;86\Z=V_)KR" DH +YY92\')9-#!Q"#*<,"W6ZU8>;VJ_S>P^C?G1Q5FKW;X#O20-D3^SM); [8@&'X*? +. [:-F@\HK%)>2I)KB^2^1HG-LMRB T F^JJ!? 0FR%-<_Z2&K-/3,@06G(0VHG(J,I)K!\:^+HEP1EOM4.,LE61$ZT-8ME4\Y4DJ +;#PWY-'H??JQ]$]#+#WAHU5+00[&_\1LS;0&SA,)M5$BL?2F,\%IQ7GPM/=1LS]-3.II0\TZI9@D H?YX +DTK0&XG2%VI3NT#=<'F8/K$#.X1\TU@%GVV:J +;PDOW.7@7"=NH O[5>OL%)(Z_M\6C$Z^@,L 0=*I ;#@R4EX[0L@F+YSK(_D(+*$ +-;-N9(OR+[XNMX\52;)9W+U6PF0?(20**$3*;1"Y^6J&TMM@+9<2TOCG%B'TW[$[ +F$:S#W1HF[&RO24-*/Z /\C3/1F'=$NMBS=WZF5=4DI/.-+H//Y1:&(4"Z[8U--, +N2&@IWV;8_4/F6&A/'NO7#CC9*/GA! F79 +'+KQK?JO0:)/)I2!W>21?U/S2R-SS0[-ENY.@6H08OVO&1 (EW3Y5AUF +=F8[:+5E 8G5Z0\=I$AS^D8 U<.<0.PUQ =1LQ;%^/V RF+%C]2?N#+QAPIG@_T? +(291H&!*U,PWVT]V3->'8T/I$:+9^]9IF9X4;\P5&'9Y9@=BE=C:OX7(#$KB, )% +'0(+YXP=C8*R[!(#UQ?. +T<"6\45_$9!6$EQG%IOQ5E#KQC@;@=#-Y[L$E12*&* +DMHJ,?#KUMN^?0A*[%G+?F"PEN'C#UKTODR$4L^L(G#]U'JYW?CW[8(NV+-/:*:> +AQG]&LP(A:#J%T=]EG$*/CH(O0YJ-5@NFZ6R_R.<>>2%/?S+A4!L<,JWJ.3@\SEZ +EBKH8DI68"J[\JDTYFM[P4-&>\JA\$'=A_3[FR/F<46S6_-R&G<;W\$+OV1IR%*^ +R^R5Y0U W-0@G3>@DU +6EM%G$O'_PT$-A4(K$[A*=//HOK9F"Y8\H\F8O8-@6XC&'^'%68IUA]%]CVC-9GK +-RX.Z#,*3)NCLUONJ$.?<#**])H?/)*G*8\1<]KPR&_*+J8*230FIYIO8H"1KUE1 +_J@$U% 5O/W#F*+:/%33HT5KQ.-=_"+%GHK4K=N^>%TV"_R-:1BSJ+7K]VZD697 :(EX1T0,./QJV5#(6*0H[ +;0,QC?!#RD3)V>"BY0"U@G(Z![+-+?.*INP[*'0/NJ?ZI08Y-#NW4M8' ;6#CTU< +S2GSM6M*D@U0X9;YZ*-_MSW>VA;B&MHL$P&]-D>?!U[L0F 58#L.S3N(4]/TJ3JNRQD=X]FQ;Q +1[ V6=EP)(<06ENQ1K=R!@A5?7GH5U09&,K)F$D/T\-DJGN:/-,QV@;N)&,92U^8 +XOG_634HGU'XC'C3F=:A'*E'B;/19 +<@DQS8D?9L[%'EU&.FHDI;G$!S6&^F5[#RU!IL[=I !#XAVCC!_@J(E _L4$EG0U +0#,R[66#.IQM-?]APVQ[(0T#0QF_SGB/+7V3*A&6=,& %@@KO7L&@!.V];30F>WD +Q,9C/V&+I.QI?=>@\!*^>*G?F1\IU!1U(3<\RWAR-:I%]D(/U(@?T^F.@3*?S/D+ +[6SE94S?&A^48BH]#+ +I<95>97MIQMRPXGX"#2?M89MZLW5.O5X7*)>;\4PF#1PXCGD0PGD_*#/VB'$VX8A +KP\A2TM*KWZ00 @NXIO,40+*3SF!-H$C3(B(VQU_,J07K%R*UZ=&0.>9;.4TP=P3 +(U+G2>G*5.+RO:;(6:\^;5/-'DK^OVN\X,_'VP+S']O6-0$T[8 UE'CCTZ^^6(_L +"[88>2KLB>86SYL%E!?=](2=*221 ,"]'5?V%!2:&TX2>[>RTDJN0Y\/HF_9E]2? +77$=&3"N"1@^XYG/Z:)2G3'D14(]1"F, <7;KX))A@#\FX&PORKP\5\%D2W0E&^/ +]4CV-9UXR2_ZF[2O0F='Q[;5GK7#28S]H&;:>/D2NJ7(GE%J3:PJY_%#E*U9#%1( +2?Z5!4)@I* +>)I@&BMMZ%:CT 1ZT1%1EYZP5S[V'.W=%:\@G+?YHG/"AG XWOG6& +KK#Y#6.UG(B//^R2"E])O$=A>@L+U7MU#,[)2"-/9-D7[PA*,67W'14OYPK=GD([Q-&6HQ%=IGT]( > A +)CEPR%O/.XT2I#?6[&:+1SJOX+3+=AX)5[MXF=FA(2^^W/7A5V<: ]*"S[XL9-=T +N-E,S$++^SX^O363%,J<5Z/[ Q&>DU9 ^T*E\SRM E&4"%7V0[7;*+K_305PJDGT +6Q$F=S?EWBI.7;NUBJJUYV73A,WNV:RX*8)9@<#C-D^^A3-QKM])2)[?.]C64S>0 +\N'_R74/*%/"V[2.BBYZIV<(^3D*%&D(+22DW)4"ODGKCR=_*>][3.D$=A#54V$# ++I+=3XEU.%@/L7I*7W5"(WLSKN_-":;@ ]KWK(KOU&FW OJ*I +"&,+:""0V7X[G^981-OI:$J)='E9<]@C2V))=>R*EH:EK45 +'BN-1IN!FQ>CYA#WK&9-,ULJF+R_IQC-]AB'1CW=&<9;&/*I9.@B^R3@^ EX-1D/ +63]VC+X!UT7GQ58MSBX;M5W*D67(29Q;Y]]GK:"^9ZA41*YD0BMX -Q2CN[I9C@"KK-0PXV%E""]9B/*NMKLKDA$W>$9: +[RZWOT7_M+WZUPZ?WG$H"=Y,NOIM4W^-/]?DXLG3;UQ;6GB EU&9[?Z@ +NQ5W"#[7CAP *NF:IT)I\$=,\=^F+G>;U]B%$,S6[I#@J4H9X3E*PUB-#TUK$G)*F#P+FB#@\_&3G/F>R381FE#4AO7 !P* +*;LDQV/K?,*A29B.!K+15%LIW,#A/_HDYR*DV2V5)<O&/]XZ&T./)]BZR$=@0/GR(H!$UC=4/KO8&H^D>. +4P+KN>@)0*7Q@@ &_JH?$X.S]P4C#XU/0L10L3UFFOYY*N1FMKP;NZK]\X2*: CV/DNN!FV$S<)>Y@\P^SY\$ +*#:#_GG'YSNU/=,VHE5X4X5T9B6@ 2"F1E$.ZZER6L476;:,4R._$2TW/PS;1CSG +AB+/8;LD::92AAFJYT8GJ=,R9S5>_2JQXO)>^]Y[O[HSFH"?-4D82C\=$H./\94J=5;3*P5A[J\:J +NOO $G.CLC1.=H;0+5N'?T;;WVNN^I1 JWK[1?8!#1/S3JN&\TP\@_*H>M(]J?WV +W3O()'N?AX(,0@PSRK!6(UIP5YZX56Z&N\2O"EJ%;.W&6%N^'S=MQW,O&'!?QG,6 +&664VYZ4&O-^F2.5XV5?19:T8SJW[I?VJ<*>_CPJ&A-UD]Z9#DF XFY(T0#VHQY* +]-UY)(EKTEP+"G1K\L[XT@54T/M$]N<4!F*O\X.?RG^ZL^:G1C@G/KK>$C:E(Z15 +J?^V6RJ]1A>=1J#_% "+"^$0,I_RXJ17!8RH%SLF8_ZN+,H!";JIB.UK!,[9S4V3 +9V%,7Z5HD%V6=AV&5]2B55Y8Y?D4 0E,+(DH#HR>^A=O\2,"-&?VX@1#$^1@.L@Z +!VDDBA]$Q&:L _!![?G2=B4 +3526XT&]CM=]:*F()Q-=B75L?",G-!XO6F-DSQ6X%6!0C;[JFMT#\QR4X9$K?<2+TV0?,HOUHJTDJ3$I'NS+$*23-K7(]Y?M@[O3")SXE%K%, 2L,*O2*\2P8 +2".R18IK\!2P;L%WOQ(-?26118N$3B] +8,UI9\Z"'OJR +?_,%B?&C5!Z=$GM0K3W4(D@@'L9FN<#@UHTBQOQ6LA9KM@GKL0 +U\=Z4MFMG\@@"^V!#L'.1&5R>V#%4BK\6-29Z(D&SSW+@"]*&]378?DT)-:(+HUJ +LW/QV^OAK'=0=I4C"_L0U4DU02N-H1*^;-9;E-MTT$^UY/"=>RO@!TX U^>7O4A] +-R00AK#\Z6H_VX4@Q(^/WSC@"$7:*LRC?GZ>'H_DI!L&/[)F*#/F\X#E;_)LQ!6R +B^KR /.(G;![18NJ>W?PP53H$GRU&X,MA:K9&CI,UD]7:3.5I.[!.B/^H6?-\2,Y +<@8[69,:>KT/1RT@Q%(>*P'X;9$LH)!1PYZ44?<(T*]%#CS#\5*'R:Y[P-OAF/ U +LGAI(OEH\0UIV!XI+62\/X%,KNLIM*[[X5)*!+/]()^P)1 +'(SC^EV3V=#;\Q86C[D<0#%,3?!]^E9$=X9^G_S_H&3PYR^O.7XK5GG$.59SM'IK +I*MVTL),;O!=7V'1"B"MPDR@/I[?:>HO\<[(#<'A_=."8HG">3'JENA?D\X2ZNR8 +37(; +OY#='\UL7\&8\Y<&,8/P1FXV1-JXD.E/"\3D=(,FY X/.JUP"1:::WQ9I! +CY*T5+S8E >KYSB?-8[4D=%?+Q,<.]@5?";!&5JT=2,D-6B5$ 4IDP@KO0T3"V-! +US*M]6D!:J,@ZY0M$9C"FJ!+9YR_[RGL&RX;6NF7TDCC^+S'2U,UU',T/>&2&,]@ +''9<072F!M>N8QW#K]VHG1Y]#\R&6^)1&HQ1\C3RV'C#]#C\G7C\Q3?X@TIIB7CH +'>5K/<2%18U^NQQ^\1@$2\,V,\W3]@1=T19U+8-!.2K^<*9D8Q43F5+G1)A']'%< +;?H> 14V<_\N!$"\YAVC#,->.@,/D%>=Q-)\L)E/B:(@D^QY26>AT$X@ZP6 GNA, +)MHL8-0OVB:6\O*./@"\K?/)+F"#.WKV+QNQ)/';+SB]:F_WS_&!8P#54(5?;-JT +IOEW!&WT^V ;F*<2M66@2G7LQ)S"VP16X0.^?\9U#JR6&\>$ *<$&#,'0Q:9>Y P +4M5V$K0^TOI](*4Q.8PXHFV_Y:-8*CBSA>7F@P4C%]7*KO:.FHCP1J;V&&+0<^E? +/4"ZCX!X,K#?/3]OXT?\:_N#;&X7I9RV>US5(NPHFQ2-4WEX7 1'?'2XI"E7TZLU +H:%]UW.2!]S@ 2NI'9?8^]I !_9P!"9HFGT4 ^O,[A=3^"3R_4"#TI\D91:U@LC!7_2U+.UO_WK>#6@*(M(N(!ZKVV[ )CA8"*14DX6=]KD 1@6QZEDK2V +Y!5T'^!-H:&<4VOT @+AI3. [824SF_4T;O -^P8PI!)K[XL<$.^@!6C4L9@/X[T +J_F71]$L#IS8NRBSLF:')!G"$/5NVTN,&V7'7L:E&X'*O0!O\I$.?8WC)=5X7PGIQ&-_A6/,()>6G%V +5SYK#P#4H&>^Q#G?@0#GP;VM*/!22U@<7O==;XV'Y/R)21-!D$L8CD.,S3:F4SA@ +&[F>@C9KXO?NAW".JB-D 0;0XHPWU@&8;B#084-Q$%]$5:=3!IU/ Q*U2O%,2L;= +4[3:^[7TPF B=8>L(^-E-)>\DJ_>(O OATRV?W?A8- W:L^>%68JJYL%EU/X/CN6 +.^O/7[ *T&*>9[3[4\B:*OXMB%7"VA9'=K:,Z_P#&&)[45'G +XD]B9&E]2$YRUNDWY/@!8 ]DCY?,!>Y%D,R#28SQ1JRJC6AGM_\I.Q#H91H8AHLG +2^]Y[KA;^?X/&N>\_>@;^DD&CU"9.3L20F>\)"9/:#W4]!H$PF"B\(?4#Q@HJ-^= +74D,AHC7^1!$:E'1*@@RA^L]\J\Y+L8BT@*1C_K&Y=ID!\\0 OE,\W&C9F[\Y)*EQ<%^7'14+=*":->^[-@;2%O 0_* $W.&SYV$Y<,%VIG--W6\+L%IE_ +XH+@!J4VNA>8IQB5T6XDZS/7&SZI>I[/_M+KB!@!XDKAP3DNDXKG7T&,1*O.X F> +[YA+K1H$N?:,7DK"U'N]I4XL-+#1>_?=K@E2+BLN!"$VO0/[DX+=(HCM$K7]A-E2 +)>6-MG65%X(P+LF5"E=!7DFWA76O/H)'T0J8Q'4=F4 I\JU[U?X ,=SOU?]&%N6JH\39-)W $'3K+JGZFZ!JW\3YZC.N5"> F[3J2#1 +H*.C?99+;:9:,R*I3?M97+YW%\@:5 7206W"<8FIP'::]CKP]6<01UH&+O*Y:;I4 +6A1MSPPQ\ _&*PIW]K5E^"]VW\/D'1D^U,XQRM,J3GV[4#'#,1.9+I/Y@%V4 U.$H[UIL>-)'7'93/(XTN>+TP<*1QNYNT +5;RT?W7?1U_6P^].F#4/K#Y=X@T'3=C+73[N9EUID,#UC90O%V6T2EG+T)Z4=R=/ +"=JL+Y$^M[H%#:=:Z8Y,#LO4?=PF2K4;3XHP P7/&I2FGWL*.WC[>J82RPM6 7>:!A +[XYUN<^Z,YP[+,A,@ZYC*AUKH)XLW2"D<-*CSS,MYP\;LZ:6Z*C ,Y=\9TI);,;Z +U'@8]N[\N(;^H\H_<1>\(%A#-N59EGW15UXORYOV5E_XG%I ,4'Q0W/C,C7K]DR& +4%NG3))[WUI$%)0W^R=#J#XZ?#0E"Z!;:-6\PWL<8Z,[BD%^FH?5HY$CB8O;HS11 +S]I/IC3R+=S=Y$\DQ6]@WXZ.8WUF*Y@*V"AE*P@WAE2ZSH:EN\7\@D1#JH6G(!@I +=2K/UC+U?9$K012XRQ8X-4 W&EJ-"4FJ4%('_GV../+70X A8[@@2=!-R #V@U*W +,1Q_*?@=C'P5['+E&6I_--.5:KP.0L7!IK?N%= +BD,3&9'.UU$KGCOLG&4.OF,3;XV )E<\#=^JDMRC:':NP7A:Z$0N)1PTF96?F9:! +XUJ*KCPY8:P8M !*1G7U.;-(4>,ZN*'>8ZN'R,\E)N;6@#N%XF9'0,"7&TU_QR+- +2K5X#0C3A/.N2@@ -(3L?#C?_FFY*2 +3;1;VZ*(&QC5M,]I$S57PLA&HI&PVRM0WL5>BW?+&B;_Q+$W6+&81,4S@<8*& '] +^&?_2.X&DT_7V/#4V:RPK^$IY8#-F1*X5,.T95*F:YF!5YD3*P!;E?,XUO0WY&Z& +9*B8WN)]=^GR['MMW9]X9U^._1KT[DD?QRU:&&"S"(B)/1.;%#F?-;7JW9_)(4[61 +^&QS.3PA@C"1Y'\0<1UB#J/ 4;]9VJ R3K2'658[Q7=[]6Q!CK@TVC[ O'(IKZ* +O/105D^Z+H)>@(*EGD9G5]5XQU<]S!'&!<'%VZN[:XJ$=WFR&FO+(8^=0.RR* +N:X'!A78>IR*NL5;4?",H6*?<+=4/3]](&;'+BD +&7)8'Q(XMVONQ) 6&I_*7,C +$,S^]_G@W5K,QX>55P.C]WFXN1.M)J8\;);HWQ\?W.;0?KV6([ I;D2;'1^KE!96 +Y_9H&?B8.3V8%%J>'R=""H":@,17TW#F_@957\1PO&UEV=!_D<2<^O(09]@RFGPUIN=KWE@[,(-D2>(CZ4]Q(XLC6W[_ ++=9U71;Q[7Z;Z-79^&Z/9C__3H[5!E9-JY1H.W;\\%=;PA:F@M1P8?J>1#X@'T02$XU-OVNOH/ A*KOX7-(*I-Z)7(_?Y[ +MX6F8D>PRC/_MF7%)15)0 &>$IRS41CJ2?YE+VRL>'9)!R/"OH"K8Z"OG0T@1 ,6 +V;?=F\R>L,_6_ T?C^^:0DB%7[?+Z_#NQJ]A6^C =KFO6?H24R\)IGQ43^25X +9T^]0ZJ@O36.*T##,?J9B-,: T6^GQU+\%B9V$.R)"I;MX5FR!6A;CDF-!K]&2CJ +1J:[DHBALN4"F3)_HBOD XNN+I W)VUO1L(U:*X:^L]W)DS!6Q6$J\E=!)ZGI+*3 +92;R Z,;LRZXF#O:H>5%PU,4TZSB!>RXN.ZIW->V5R6_ X!*M,/(\0>[KB,]%[1* +5B#+=0^T\6YOH@"7Y["C[J;L03$9^]/AHV .G(L+8XE40?/E%)DQ[25D0+.3GZ!6 +L^W$U/*D!1+<7_C&=U?'^^_] AE#LT*@Q[#=& B4TV4)Y8==5J"L +QKX(ZTQZR+2G+*Q(H71;3(6> E9[_1?MH.=O*3BB-#=E;_ZR? +LN%\WY@X]43X@?6967*8/2>4&L>R]7^#9[M?/)Q847=8^CAYU1JS;NYP_8O(G +R;WNOM=K#^4<(S"59A/;5U:LQ6^E5[/^<@Z-IG$V147K9E LFFSYH^06!A#A%)5P +^IBR>BB4MM7 '%N>P)&SEU747T2BF2&!1OH 0&.9POKRS18 XB;#Q99?"R/7V_7X +"[EY'BZUS*\]XGP)DM&CO<+-];+LG55DH,8Q(1#"E#(<0+3%1! U%K\^-C('\X)7 +"*X[LR]X(XJU;<3V'6OJ*_S^C=]J*E@' PZ0<.@^KB%(7#R]$_2K@7@E!D1TV*^. +\\2!JE/%=0##2<@9_T<>4B2?_\AM'$OCT,$;,0C8T\8[E&M :@/40Y[CN^SO#$'' +E5D#.PY@YH0X.A9"N!![VT:EZ=CUT*92$"!AVPLR0[%(#(1I&*8 7!2O$Q8XDB2: +OE$;?\<4[^X$)E-/>$-SZIJGUOC]Y\6&.OIJI]&A/6X,'X>8!G[A1[/3>]>V\/X& +61]JE1)-?O=0&H6!@XNJRXD!FOHI;FJR34/CXG%/[6/#)E4,^)P9Z[_.97T:PP8G +:&=7E/\.1B>G9<5H_4?H]IL#'RCFIGBJ:P&?JL>#N\5D_(3-4\\Z<&\6!LT +_498\]U/.6X%P1=6W1L/C.4"C+?92:*''T[\LS,\9I7ZJT2Z3F4'"N2 +QE\!W#%XA]/H@Y_\:QUD8VFU=;F5F?AEDHI!]$);=CFI4]DP]$0>-8*@(YZ;[P10 +T'*T8& "V09+#;0[Y$U/9JUW#WA9J\IP@08&D#?,>C;FC:(;[W[O?7$HBTS*?2K8 +.-]8E@"?FK@?U4EI9E=EU2-:TKRQE:-A"3[\[#E^+V<]%.) AWYT+@2@?I:2%5]G + N6&&^K/ZSV/F',VAHP^:4M/%'FN>YN$NY>X%L\M-1OY;+":7IW4$GJ'A=S"C-DP +&;VF*VVHY+Q7EE^C&<3\[G +V))ARQQ-_E^2Q$!?]VJ$S:2NK9# #E?4JWR%=RYU2&87W._?;/\UF +88R1XLS*&+H@Z%SRY*/MQ?6"Z7]Z @#!*!VS>GO:,@82#T]^^=QMEV6M!& +(!^TQ_ /XT:$\4QX(W9.D4Y.]-=X7/I*EAK,&MG#%NR!ILR4DZ]^E_2&=7U!=H:[ +/4!2A.OEU(&U-21XT':Q1"A'&.:]_RZ$N(LL0^.#%S'KC17>H9]["$HQC <>.>NB + MC'!@ZO .GT,^8N=.J8$E_MAA9\'T)LQ,JI&*Y'@",,7S74Z$2[\A5/Z/8QU-X3E%_=HO9]/7O4B +$6*BH& +LV^PN*@!5Z4\7RA7Q3I\#R%UD(+R[GH$)_01Y5!)=@=2T6(ED-"-X"K21W#NTEGC +@H?";O#D+O>9F-=\6XP2Q@; \;?<][BH /@*2Z]H8')Q59K&^N*=5Y3-]I -1Z(#M?UXT$3I[.5-?TY"TYC>8[J^IU?<86U]!MJ0$JV^MG,OHER!AYR91'/^<0%,=)BF_UF_=MGOGP2$Z244YPL, +Z=JP;?LA"D%ZRR8JM8'*DO;RMI^U--A#G)^HCF:/;SC.:9XBQ(KI";^Y,%G \"%% +!],4RB/\W*P>2[>K8;K4,S?B$:-)7<[N!33B4:F4^&$Z=EH>A4-O'P>K,%*)J>XS +F4D)&1Y6E$C'9$VG)US2 8$W&XD!QPIT[Z). /;O6 &5FB_%HO(.K^O7T"Z\&F4. +0\&C]J$<1.OM_\@(^P-HK2;0S,()@_JYX3A7 :C>-$8P7J7)P$D\FWF.57 '7PQ+ +P.3D5S2B_K3#GMF@YI#K/\30/I>;:@*4]3[LU%XT5!_!R?#-.^5E7[)![I5?300 XWL0&@(OC?&D+7#;F)->->V"*0+.:P9!?UV,N[# +,APQA1QJ)*G@V66#%[!F!0WP*OUB=#.>N4#U8@=D;QZ[1K#$OG1A1TD\1%3PJV]+ +UW:'@OB:2GN$&Z($77WL:S2.V&U.ZQLUUSR*PL2 9N&&[/FJ$A"D[G^J"N2'5O* +I5M(TRLMG:SO4 />+^T,;%-).;;NBJTM]260=QW[I+J8X*M0\P-GOA#D] +UFXBK"XU'5O@2K2QS@1T=X1YUZN>S2'(4I&.EA1$::H7%SZ5ZG\:&(F"S&%H"(KN +8@[>$IS4;/36(E(BFKKPDH/I]K_886\?01G3[CBOXZ;*@6CY ATD6U%TP6=&$<@?14X1UPYE?^ +'E8%-&'J6VEMR@7?FR"G4 C)?J%,13==0P^X" 0E*S=Q,##%1O'.:V[GC7>F>%N> +J6B'[!LF0@GRU%-GY N&<_ZHTRA6Z*^@SRGSP!LV1NJ,MN?JH+ '\!@UI:?CEN>8 +-CI=#[>/IK^\%/,=>VE/[99T+,X80M0Y.\TUP>1.+0LW*Y^T ASE?=R<"NT#"SG[ +&F_G&[TL,:1*/?*F&II+%8J@F$#+UR(&)/!K:)4<"2N@-6M:I/8 +45P!*OM8-EH45E/(OMJE)]H@%?37<*.EA]Q@T)=1F+J12&=#J>TAT8<)JZQ&!B*) +-L,R"IT:_/\/NWK\.44&7O15YG1>;+M^3_)\^?=60W,#JD+T+[2@DEN_B=3Q_U=P +#^S5^%>C+J;@NMTW5+B6=1%?0@IO=JOG/)*V/!XT*((-8S4M.GPX%12? >H:=+3F +&,:X-=0@'Q,B,OX0YS[EG ";?B& X=^2FGHZ30**FY\*L:*#!Y =AY8%,,J :3#E +C5>L9P>.)^E9HMTSQH=1L##)'Z\[(WEL&4_A "P1'=ZKG;,"]M8SJBP5*W6AY@01 +Y!31HB*$(M'H&1ETOB6)7RT.S-0P7WYW=SM=ORWE50CXP*]=C7;N188!+EV/\UJ" +0?$8R7 J^2JNOR","(',GS> #;O%1K@X#)XZW]9M44DLTN=("WTU%9K.D*L(I>NG +$IBU\C9(-.YOOK]8$76,!,3[+W?>DF'!/2 +Y[T="&:UZ@W '=A&G.RW0U20/ ])8$2WZA4^!9"Y#1PP.UX6^S1=]"%7_!7GAO^GB"-63MAZJOW27L +M?_TGC_8-*WWBO-,A85;K&V8Q[PY:("A_@((V-RGU)2-+%&C +[M>]LZS%^&CO>IF)I6OI+/-UR=CXFU,I\%,_$NM]0SY5:@MH$Q ,S+6%M:0<@4C%DPXG=@2=L*WGKH@ +,"+U#EC2R4&9U3&"<#,\A.#V1O=-[EDGFWW[%#4S'(<+O8:Z2HJ5V&ZZ%&L89M%9 +ZH1TN5V9Y]8>8O!$(DI[H*TOX3UZ$"-.F7+#B,])X;/3(!>&7ZE0(.B0',A?^)X] +Z=F_[Q+=R-^%4XS8?\N%%]Y21T+8@&AJT?X+%\-HN0U38_F>%.GR3>H%2 :6-R/J +5YZ)2)[;!= Y;)2%H&U:$08CHG-!) +I@K->_4LA$:SO@?74A=]I +(Z&?A]7]2GAE(W OTET$LAQDRA!>]WB#[A;L#2=<@6(Q0*T]0-2&?!""A[:F]HW& +FH?I%#BYUWT S&KCEH:>29?P>^I#BM>]'MW_/MGJ@7KAF.V3=EIG.R=6BR;Y?7TW%LSB$G'.>3'Y0G$VWS$#71E8EE0##@6,H@(N3/ / +=X687M2X7X,8&/_3YOO("^5 ? A)1HNT +F, _V_*EN"K%4:0^^6U>@3,R,ZU'7.JO#[SWJ0BOOQ=]GJ.E +W@=#_9U59!9TJ^#M+7?[?%M'4=)B:]$L_S7.\#5JN\=$F%/0;KDWH/XW1=2>D*D* +82 W5KX8*6T$0A6/BW?-N=_W,N4_<(IVJAL*-_6=<+67<#U]MIDLSBUJY_6G4BFW J9?; +BA2,EI#Y#R9_3P1#B>S1=Q'"Y&S"KFL:8+*=?K00VML-DH^H^4$LF&< SB)XN0!^ +,]8W)E#&6A];4 (FG*;T"$^\C[N8AP6"V23D2WQ;+O3EWJH3 +!S>A]#@BKRE.7-P2I2CK2%4:CK4.)'&^'?_CK=O74!5A+S"_C!IJ ME3P^IAU]"$OQ@"@PD%2;2&_50Y'7I@!U8.T=VLR: +J>"UTC:.OGTXSUDCU._2("XD>M'^"6_\H6^J $0:WL*Y$OTL6M%26?>P0"J@W/O% +6HN^>LPKN3$Y]T-/=@\%+T$QT(%H-@]6>$0 ):P>*O>R_LLS&QIG!.^M#KWNK/R> +&,:IMMO7C<79H?$OS\5_8(#@VV/U<.QX8 2 E]/!YXT#9]>RZP6E;2_5!;@**:GR +VCWAWQB4[)%GUQ63DLGQ1?_\;0)S8HL8T2N+>.XEQ1>:;R^7Y 6+6!9GHT6N,G_@ +FQ0XC7W_:TB&AD3P_@^MM%U--GF\_U[B,MYRGG#_VJ1KX9>ADN-UDKT&+JU_/E7& +_;.Y'S%RIR2^Z/G[40V'(XFFF.AP1Y^<1^D5B)?Y&8?DDSUD[$J&KSLY+X >%\GH +U]&=Y^\.>6L?2_L?1=7M5192KM8 +Q:UVV=?N ^>=T<:6],7*HUS;EO3 +=7GG1?JJR^<8O<#6XX$3*\+==8CVG5>+@NFOJ)PC:\+F#?J.W&?KCNRJ0>">D8)L +5S9<+IY4]$N<'GK=0^F;1]/.#B?@7-S]JO)O6*%I4SP* L*(OKK8N7ZZ?FIWF+O3 +;2,#/.!)[LV*G(88MM3"]AN2PO'1;OY^*HNQKY?,@K_L(CM1!38$SAGJ"[K9H6\# +TZKJ=M>OT;\-9J, NT+P5FB9=H=),+4M] 0][^1OK5X0RL:ZWLMV9MPXO#%A26>[ +X8918D^KU\>FFA!Z-!28L%ETP%*CBR>)5,=!0JL?RS\:<+V?GV@6&:Q\GB-*[@"[ +$@&VF*YK">=O$Q78]/C*8]G\ZHK;B..DCFW+[^LHWS?T(ZCJCQF5[?A''1)':$,D +4O3E0V$-I;=('*% N%]5YE"ZN^;-%FXQJ-Z#D8R14VJIPMAN\)Q1J$++WI.^@K\A +"?\;5@SNF)5Z=Q7_% 7C@,T[.2PC\_;)8R:06B9)SI?JD[F.=@\G6W:U*'TD6EDL"@\ZH.$"L7&R? Q()[2R6D<.9$8K +E@+V>\0V+G2X))?+8S,CU7L%\B*?L^0S\8-&N+_X:.J+'95R ;P8\A-H(:IR!:16 +J+U#T2E"L'#^T>9NAO4M0LL+<,^]V3H-D#W&B%X3I,Y$33?U?V[9>7W9S'@J1+=Q +E@0U.P,@ 0>4 (D])6^ "Q%ZJ']OV2M),V[+NZ%4)_G?@0G.]>=2LX% \5:+,G_[ +*%T/[NR"$O4E^*<8E.?F7V5)28,\0=)E=\ZA4@W_.@]MH5P$.WE@M Q,9-N314_; +S,&[/NG22A9E .N7/A91,[9%%28M^H[;Q8_"ZG#B/O/_9T9\3-+1UY3ZQ/ZN5B9 +P,$>XPU[P6FX,FPHF(%-74 C@H($P=89$DWTEII6S\U4@7D<3L/4L*]RJ+D)JF*X +D4[6F_AY&E6X AY];WJ@2G?[X"3RR.SY"2M\/0E9)@!+)1NLA +).AZZ;!$T;&DDA="CX5J'C940BXE]OU7C>'^31@[]J K$!<#_2(K1>7_%U>=AR.OB)._Q5@#6C+%>]@(&&N._.R] +H)70)I%S'=K3P93I;->Z;A]X7Y/QV-UD8!>-Y#BY=<6 -.]CGMWT+*:T"K\5@E6T +W1V)^""G3KWA+?_:0S+%M;=D1+O# 9 E&%+/P_6V].= +2VG-!M>EF3^[/#K[1X V4DN0&ZN\RMCCER2:92J*S$+K4 77C[JX6F&G41 "Z]PF ++%G38+H9%A7FBOE>O-O8:$Y_I#W5"/_2=;.;%CVLINAQE<"=5SVA9ZUK*6-*X5Z7 +Q8.N_E7UYI$S%)3 V6U^ZG""5G>0XL#3X.BA]% F&_.N-X#\&4H Q4 ,-!(0PO%3 +Q,G1+,\NX0A]7R+!>8:$9)HVU:]A6&_C1?EZQ SF#O4@SW#SNVYZR5$)C\0!8J88 +88.[H,[&.\M*)W42=_:E:%)E27@E5/4$\,MNF7/;[A3R@'WRF#%1$+X>7TK\*&B87BF_B]=CPOA85,<#1%: +511/*Q/G_H.)D<&MONV66MP$2138-->R;"S)I(Z0>EHH'CDT93\TN!E33^TBQW== +G:,6]+T;[MG>Z*X_,<].K[M/6P@O9K)=AEZK36.;]\@SSO +5E,6C6T_U7W$,TVV;)R06O$8JVBS8;I4T1 7YX4!)_(^ZM;?2UL@3R8?HJ [(6_1'7YXA,<65:Y5!.=Q76BD1SR$9EA(KUGQ.^Z$WIN\<)AO;-UYJ&MO4DLI8Z/0$^,3 +Q6M''VY4:< HO7XT$O9EKTVK4-K25616Z?T"I)'0_-D1V((2]4WPIALT3"ADIU%? +^,ZEG!4_[1C!EB582"D?Z)1JK!_>ZH=DP4*&%#8. O,@?JLT-J.2=[7-FL#PO7-A +TS?VCZ8/YA-)'SZI0SS_(X:[R4+UDDNXT) +0C\A)T)9[MO!MU1.Y,P%G#C*FSW65E4WB1TW*91+RUV@(@/<+]/#=LS/RC.-,0+C(F2U(+2_-O9< ED3-SSE0N-D MV^[@A5QDTDR"VZ=; Z8TFP77 +5AK29.6-E; TH/]T*N(H:W'U*+EM5O@G]D+"N3!5*BLE@_=$$%JEXF,>1.)1Y\(0 +G8\@.ZE^>(VC]V7H3RFPZ6 $+.D/]AQ;2XT=7U'NU6 P +_@[GZ/VZW_/GZ.FW_]/R<'F?.\:1 @3F(=Q%,_B=;96L^ [#&+]R.F[%A,;)1Q[I384[*![L[JX-U-^.6SW\/-K_$HG%83?Q*?]P0 P +*F% Q6T3D;!^6T2L6GPJD?^!R\0Q.7D)?CCA=+\U?)&T:C=,[N36T=/+%O)O\N,, +K.:''0<.PZFO#UCNRO'J)L7!\G[',1@E#EJH"M4>"8)UBSP $(#M[;V7\M E?B[,[_X)H.=CF#N\?>#8&Z6$B0F+= +G_KBN7SX!,+(;]/X6WU^19Y2J^R8=!,(@O2V/F_'W"; 7M*(&\532J%HA6?'2!WJ +!#H/T_KUBI/D?)W+5LC4\$ICP.W6/$[GDY-NIX8@3G2*59EI>G'OR*,_Z@K2T2>, +*'#N7R(S.E%8.!]"3MD^BF9]4?Y +L]0@A=$"MVV[9AP 3NA4F@SLYVIK#+18IQ)0%OBFW8F2S26[.!TG1T#413/L674).]2>ZGCS(#=)A/]F@+O, F4* +6D$:BU^N!<0%9?FX9DWTCE(KTC6^+ *'LA-!7KZX%6H*ZP77Z6I-&KY3O'6<';S' +0YJYR G<@.EN*U[NPPJOL=*.]#&1O,)$<,L?Q1<#2?BE0:C>[VN?FR,%\B%TLKD8 +&XL!AR+@[0'H-@^EB:C8$OH_(6O?_CRV+-O!_Z 5S8\3YV"1(OE[Q\$(OU-CU7>JG.^"1# $[E3A1HM#.]@. +0#F())T#H?K?ZXO.!$(KS@CC'$IL$P0PC#9F$"<8(@SL*P]S4AR1B13UX^ZE;$N< +HGMG0$7SF99)8=K6N[0VF#(N]R8#!G[6*2=.B<[L%6J7A%(HP+%G]W$[M%ZRS%JO +TM_B+QW+S>71B0A \L(G-*HJBY^-?!E0^1 R91RKLK9+3,PD8.^^,,;YF=;<:1>K +G/;,TXBQ,<)V*>'_;W93$D-,!Z?E05JP.!&7K;9S6R<=_YO_S[WN^M^YX$ +&K7[Q&C[\'W[((IDJ\2.BVG!Y([M;A?P(K6N=F8/NE\XWI/74WF4D+!EC1R# :Q^ +2ZX\4B]"/7QQB5''%89*W\FF8G/ "4KOK4>_CIET\QFAWK)T[U0O52/%(P'$V/Y$ +^(*#35+9V!9++UP!64\_$F:63I= C6Z#/8*& 1#F[)^LP];?PF%):X#.RL4E +=]CM-0>D%D<$SB>N;Z-%YT/4%0 B:===>4+.=26E_T-O0$ K9*6P5T@2,D"&I'^0 + Z"(4%-=MNL,PNIL'"8-YVUQQ$KX)J;]#*"!E(!9PGHF)HLV^4RV?W7U3@L95>!B +,:WFP:P?>'#'[4=[TI]^GY=8;*"*C5VPB[ZCM\K2 :!"/81SI@X;>A/OK1XZF(", +LX[AI+$['>OD9=V[ENJEFW\]5Z?UV_/X.**)&G+*!BTFGJ]6MGXX+]/]_QLJ%,6Q +4)]\C5=-%;KQ%)O8M:F ?62Q0;",_0)PX_R_:G9,D'F=^ ZK\ &B=.X0EV +/G?+X6"$S8E]VV'5WRL&:(XCD$D@K)(?<>@\HXL6J?ULL'=DM5QAGPE@6]TU<5F@ +(8Q*H(TO 7]@2+R_$';*25%D(M80IM)@O?P]V/T-CR"ZF7&LH3 +]L]HM#]<^6^KG!\_FSY9CH*,SO#/KV$1F(0P9L"5&V>#63AS.[F?)!6C5?9D12NJ;[MR.X-5MTQ(=JB>@M@) +_Y@*Y(CUH)UN':D%M7716LU6*C2_G4;!HHD9XG:+72SA?#R/'4&KLM7PV293ENAB + M1"!*F"OOAH,SRA&?5*L2Z,78;,T62P]"I:FG UI=E1$GHP5SXYU$34?M.FL1FIEE5B9N #P&D<) +%Z]R,EKIJDDD'>>1CY]-XJ(W^Z@R=P+]U-Z76DS4N];]XU2JR"*=^ +KW&H^-Y"<,$,D. LS3%_X>:SF@OW)R,+.CL%VBU&/0W44#+SIS+3Z?4ZL,>3$JZ0 +@43%3?$7+RGQ,NQ83T#?;5YH&R-XBA% @$>C9 V"5(0DHG^,+A8*+:P[. -.?V.9 +.-?S%\0 G(KS/5&AHX25%J[2I3#8)YB1KBFH6(X"PX%8??1QZ;=BDHY2]*8/XS6+8L$NM=F+MR $T\@I-\E$ +X>A_/GM#Q"0PY:-#&*&P.LJ_Q*D*&/4#TOH/"1,8OQFN<E7.8 +Y/-W0AKKN:]-I-&=IBN53^@";U6X:,M_8\R-.U0,YT?B&.55E'<&Q;,E)L/JC +FT_/L'F^*(Y>!J-=S"##)AUGS6+XFPDTKF,T!NZ1&_D0;'H"B;_ZB1!6@F]BE3N: +P19;-@]U1?[G%19C0I@J"UJ#,J *S/9%&76Q6#'J4G,*,,6#P;(7$Z7\\%PRV!S# +(22P$&CC<51G_V ?::N*%]H6*OW=&IDID;I;P@3S5:!VH#RB1:?+XQT6SN//CMWU +B/W' @EY8)/5!2]<,*U'R>IM0,1;.@!'O0:;XA@76Z??1E";JP1BY,X,5N^6I!/. +A63!/F[DLZ G7/YN$/B!)Y*L$0II)A/<6W"D,=9-@8)ISI%54#\(XC+_<)(/*PKM +5,B^I=0RJU>YG-/1)YXS>(+HS0N[L=W<"H^3/LD'(!K.8L*]]?97:ZOI;LC4H[G5 +(3'*'GD'B3@=%@@#-F%NEZ)_G0\;9A^,R@"B7NJZTT-M\27KX<) AJ>VU)R;XV$I +-9:?@(VG6035.XV(SS(*WTH6Q7L4NALZV:&E@-MV9L;DM#MG&^W]?2GQ>'S#J+Z'=E,+!F8(B^V[Z%CB7,0>* +&>D]'2JX1H#05RBRK=@[7A\:V"@9 JK-T?J/V<8R+2LS!-:?^QJ*0T8S01HCRH%J +Z,!RG.<26Z*^(5$"N7F@PMKSHJH;2(5.R\YF)] E+:V!L!TOL'1S @#^:.FODWKW +5T-R'W"3N5=F%+RGETZV%U2ZZ-!$F^L07B74-;"RB-O?8X2U +8%2E?BIU@=:F4\#_Y=?VN$Q1KCG7\1:R2>_JHR&4*"H5$RKXFSAJD0??26^P1-T +(WP/$J@;N/<6CCZDW!_'U5.W:?A@.A/&@TD:>92F&NMEASMUEO +X.JAXM8E8LZV115'@9YHB8<7'=^$KTC5RX*]:%*UXE>"ZKDP+>VW(#:Y:#J._C56M9;F1 +=_H,4%5"H"*>PB=(I&T4$0% +W&[:CYXW$^/.:I?>X^M/A*XN;_X1&6Y6@2O;9$BF_G(L;,>'KUAF-_9HC-B;@55\ +8&$%/81G0''PZ(G;.8:D_Y#,I)3N40G:;G:FHS)->_$\0K\Q?$YYEO5OCG), L>; +H,\,LTN-WG;!@Q*F.PUBL0D_5ZM]OIHNWLF!X*UZ+)<'9;Z?SO11M2357,4^Q!2V +,*KU*4JG8A^_G01;2YS,%NS+K*;O@K8IM&(0R+ 0\:(,^E@\N[NO&N""XB%)_E/V4)7TUJ#D7VE3 +DM(+S^ A#77_(&7(7)5K&(C_0OJDD3R'A3<8MX+\43H3T*2# +2ZHI,;_ZI5!@3P +H$[-!AV0]$#M5#GYQ<#<03K8+/-#P+<8@(\S\3%_N+R:BR;+<0#=TT[?:XL'('9S +'$<(HM[HZ>2PC[:Q.@@]+ 4&P![6^A01/C1;AUF,PJJM*%7<5W(+2W6AMJ+F2RJ) +, 0UV/+JBU\$'4C%[0HKM1PKTMQ]>6U+C]Y/T8BI9D1\%5>ZF5#I<2(=!"("YPYS +QT\C%'NLC/A@:F%/[1<7<;3?39+77WA!Q-3S2(1MK1+6FKX9'BIJ\%/T7D.[% 3R +7017;#6_2JG^S2<;A1#*FP;ARK..L06,UTAX4PJ5D3;6J (J[A3V7?L5P<FS>%"-\1\*[H'FB; )G\Y!"?Q-'-N*M;E^B'C0*"E>KM_KNL7;+.0&0W!(N_ X6;SE>U&:B;W+?*C1$"E&+O +CV>R%0[3+$_M3NQ@Z:7S1:]DOH^JYA'W\S+0;RV,X=!%W8[1T)MTJMMR]EHC6LL- +#Z^%3<=W,Y=92H?6!N)U^L;L0X8%MT-^+-U/R7XV1.&RI! ;$L!X)RW\]9&?3T3] +;(.^5>>AW]];(^:RTZOG[6JU>PRKB)/].W.59/Z$>; OBE*&7KGJ?%6;DI"Y5R>I +"]9CJD'LVC(Z:H?J^X# >:)Y$WV\5(VE3?JJL.+_A=?A]8(@LD>H'DCJ=#N$M[B6 +_GT#RT(\E8-1S.)8E?A\4<;U#T5?JNG/_+KR:!-OM!FHC'RM%W)6%,MR?D@6%%" +UXEWS12N ); HJW2[]>5H5-5K?W'&?/%J:6YIY/RA35F\@6."E&Q)([A\J3/N"(/\K5;6T78XY[3'*CM_2@V^7HVNCGMJ'E +&.J]#Z^KO#G+8_@<$'ZH86,]/GX@DQ76*5-"W9;0-G<.YSS"%HVF(0,S+KH'X[4J +8?) :+1H#<$%>NH\2+5A"I\2LA'7LVWERT(!8,E)1#@[7F+)V9D2^UZ0.WGH?,1) +C\@4MG@ 0NO\7KQ1F'NI%<,_B9,FR*:6QGE-O*3JI@[; &J<^[2# + 9R;VJ\QPW?,4[15#7_)>2"4N.HL,*9#5,6QGLEA)T#H3U[<9I ; Y5C"FDX7$B\ +7E#/XU*.GQ_9O,,7_++^9%LI?+,F/)YPL-52\Y )&5#?-(KXS/:.>D*F0OJP(>A3 +*P9>Q(4 /3:N'6X#S)*W.A]3=D8>4>+NJ#]V5-LQJ;B5;%)&"VSY3]^_KU@A5);9 +%&9T BS_S>TA\YN,R +&>"3&S:Q8U7Y-[Y7MHLM]#L-Q+'!-$5P,VELW/N"8YJ:<*A]>OXF0-TD#[V&MGR'DO;\+E7_IO*:]Z;1O U&1;W?92]/#A\5<%MK9Q):_) +0KK77;3LG834/9[+FJNN[-3/Y1C0] GBW>(Z XE2XS8[')_>>9L6FWX]N?]HN6%K +TK^MF[. 5#->*;,CMG%(DRFA\PLQ0&/'&"$]AE46+L__@:F!G#76#L@/<9IYJR0: +N\W\F+Z/9@OSO>LL!-7)^?SS/ZT=PZ/F3[7[DQ\:EGK2]P<35:9% CRP +@;WK'58'E0%3-!G(,NE@VX=TG;4_W)3AZ1"4PK_KRR6>*YK!*XC[*+A:X*IB_^*VB\BE ,::1$2C<%=H' +%+H *J+U\IR\0E1!=H Q:2LDSI6*'FCXBM=.1HWH#_FIB1VOHB%KW0!J?U[,*?:< +?C^AQ?#?K50[3[%!"*:RLC&K[YA34%\4R^JY_ WS1I6EBY"YD-F;&3U'@!Y4__)S +RQ!;QN/%L\!':&NK^J6!)U%TSA23$*[^5.!1*\,6D6K9;P#\[<.9P_:\%$DQ7J8OUP!>8R#6:'K,4W.BZRZU#E#*K3":BBU$FE/+,0- +\>A$\2;%S4D!F<8[!.+-^ZJ@A*(EO'X#=0>D3-@ML@!!3M8#I?WKOHRO-6OF(5[" +45BR@33\3MHTI8N;$[TI2BH*3W;/FAM*0 P5Y:C[@+E*.X61,!):]M*=G&-:%HRF +K6]#I@"_R]1B7D1LZ2$67*!X EB_$C,GY",1+,\']-? XSPKLE0>G3<>96=%_ST+ +.C2+@@[(#@*,L"-K>&\R:U.==S\0;C)*#5!Y?VOI.77H)=5"XQ2(FVV;1OB*8G>I\4G+:W:)W'[ !# +PV<;@;]FN/C15]<$[VHJ_8M'0-OZK.GZ"@7S/(4U:E0_?^&R*B41/.%LV^YN8/4X +YKF+965BW4 7#76KNF[X;D&,6##.*;IW39IA\I-(]K21WB/Q*NC(G."::\32%?1T +^_Z.BF1HA4._#1<:W^^U"QD&T>2>3I4"5M=D.PX'ZI$*R*LD!^E;I#;8^@:$4!T1 ++8$:=VI^./(?'_!R5-,$):M*B% D%5A_C5CBC44Z!PNZ1$T=:[_-A@K?P$/FE'RS!54WRFK:&I +'GF]EI'D &.[0ZT5V<,Q;/7=-U2 +F^<[&MNV2[,[U^PH?R.WN(RLL%G;-]5+\OU"D$$"!&<7>YIK?P*RK67Y^3DNH0NJ +O]*GYHL"QO,C[V(]1\9<-#H%@$^:^ZI/96$5IKTX6';'H,8(*1*5$L:Y.,FW$(0!W<)! +@A#Y2ABI1<] ;I!\7MQ-2BG:XD.]]-Z,!-#C_:R$J$HP&,U]BONM%KN!HK%LHSS< +H!5PW]4'@L(-B@^4G.'Y-'+.GB[@!C-S%@,N5T$9VVW(!63KZQ=5S.Y-B4=5A%NC +%6.4'#D!S.)? 0[G=(L-,'!./G=_)FD..!M)7[\(-#:L] =R!\,E7<4L;=*I7GL*< E*LV)'V=;*O"XL%I +ZS*7Y0(3>RK0]_M\=F$36.Y0TL@?4_5PR91D*;@YQJ8P./ 2C&S]GDL@M%KN+YGD +@6-3^?<,@<6BSOAJH15/BY_+GZ4QY6(<] 9=AJVFPCZV:;[]R,5WI[V1#-OA9LD7 +O%U )DUS_=0(CX-\^WW&K25''8/[*N&9%?U-1\VO[=TB@,S_3\2D;B=UK@@05 N= +&.5>X]5I>-KGF40JJ+V,;.>"1E=SXB%E\@RTV!%@2U_-V%- +OW;\5"3M^NYM$<*KK>'L8H8,E\.^WI1XZ_V$1V1E#V_[!G#I�UB(^K?A$WQ_;R +ICMJ.J215Z&5^@ 810U $ [2-IUCC(OWKN'FH9=?XY=_I\$E^]-V/E8+\#9VT]_ +;QBBFQ93YLQNS-SV?WI-F'V[V/*5!QV"W57 U=&6J2Z<:TNQ\Q>$RJVRG@!XN\9C +X.'CF'3 5Q/4#J_*U3I:6#20=\L/KDNE:'Q*%K+N5Z+8(>;\^Z(G% FV& ->#_7.!HLX/?8<._K8U:-+5&P1H$$/-OAQ)FAWX<6;E\>_; +X8IZO:@P T81P"Q.'5+9K\P[.QRYYXHCK!F^](7^\4&Y&^*!J^X5X\#I!-S+U@*% +!)C66,\XZ^(1%6T]3[SH6#W)A4C$ZO>4\9W4[Y,OGP5,$)U64QWRI?]MEVBL6W,^ +YW?HHAMYVRQDN#0XONSK[@-]W\/%_+@4>3;-I\&Q@# 45*8S(,&"Q[P9A-&=L8BD +8M3]SC>4=3@N99]!3AAM**A<4'KK,C+V2;*[G=6R1H4(9F[BJ'42Y:%HDP)M;:X'-! +/WC /Q(5ZLE/]=E!5"3NA9.UL@HX/H3;7CI7?0)##+K<*\M$DL,6)_NY+L8D=PS\ +,LZQ&R>Q*G37046KRKUS.4*&92]Y$C?W<2"BO\EZU3KGD_JJ3K>""^V6A/'4E#4K +W.2\6:W:!"3/: &0HLN&ED)O^7C\!'#]B2"/>G.%4"22HMI]K^\:ZWH]TOIG9;O- +N5QJUA&@:T[/FQ):_S3;--@FJ9BL+D';/ BV50/Y#74* O][=Z@[G;Y3&;ZU'9 1 +]))]2P<,@?.98\=W0'^#H@R+)O_$2[V96-R#CJBX8 949(Y!BKCDVZ;^]Y*_/--2 +L%E/19T1U^I;><[E;)_9_O%6*_K]9]KK +!V$7FK*#\L$R-^2YVM>55=FD1/WP$Q4)>E%5[$Z@F;.U M"!?:-V4>-[8]_VW00K +Z^$3N*!"5ZKY(U<1Y-/Y3_"HG4NOME^Z3F\RIK60^#?;-2?F-D>8@5KO+\)3J3Y# +>CGEQ\<62/&NX=FED7,?QAW%?S V#2N)ZHYZ4"LL#JFO3M/9XP +[$09B*W86*Y#;=0(,;\5RB;:@#@,44HPUS1;'Q$<^TA(\[IU@8'=#OY8NE0-, +5\.:B&]DN/3;G7J@Z.'T,OT-DHU/02G\ZUBY[D1I#'GYKA>O^SZ/!BT +^H>E3MT[_,V9M[VUYE)[CRSS#S(>C:6*&=A2SZ2SUZ2OHM5/O1C.1_(6-^3(@G 4 +')4*9(IO..$OV<;MP:RQ)NVWJF.\>Y6'Y2[9PA_F5%_8\^"5!H1@])&(6;V,4 $: +F4<-TFM=+05ENJXA&]!)KMF$4=XW9(!?)87Z.3")0:@)#+?A3@VQ+(9*A>IX>0R' +*%NH9A\0+1Z_ZV.)OVZ*NLT!O]%0&W^(A,VSTSS86% R_U3"$=FI!YR+%L^]_A&! +#YI)UVPK+8+>8 %='7ZNBN9.101?.Y7>>QT*E$$SOO7&PA#EK_O;[3AY@TQ.R^UO +NC6JR^E'_52F!8X:C^W'IAZ+ ?JEV%XQFGL/J ECS#*'25K<]1#,"C9,?[!WGFYJ +K7U]'5# 2AZR*INN.F78;8 +P?#ILWGB.^L,(!MGR++)=84ULT0<,;%X6:%0-:$=W2)VWG +B4>YQN&C3L>5I-,J0%AHYYF-,]KJ_H7D(V'9>)9U#EO,3V%86%DR_CK1_RR:X5EL +[#G]B8; 3(OZG"BN)MMU(U(E^(A81J:WA=8'UV(3.6K[\*+,EF PDSFI+XEW<==V +U]:U >AENTJ"P>NL5+@9=%',%I.-N#T)6*I("QJ MGC3"M2,Q]AZ=T?3["QK9$": +(,?]SX0[$;M@9%25AE.LSE4QCD\RSO3-X5\U67*[">VU6Q-;]',[V85F+$YSEGCY +,INS1(J=1^+W]K-+NZ5.$D-GE(2. (-ODC#DN$K%R2?LM0+$:*O6UTHAD/3L*65N +]+XICX:56&%5[&]IEGQ1@2/K^ASC.97DSA94N1RW;[W;O:\BQ0[&#H[)'P%*3-VGY@\O?(J>S8MB2-O^AD47G&/Q"RQ<+QS*,= +K@!C!XNSG!Z^'=(9=5X"O2D'CO81M1 +'5X+W4@[$LGY),AN\3"_EXF&?X)+EYS[,8Q.TI^&M.%LZ\U]T)E+M/W+9L#VGW;Z +L^%04CM&805%7W,W%,@>?8:1S<3.=1"/I6KB83LU;/[ZB!_865N%5>AD=2P/[WS6 +4["7519[KO=HX1.'A.^I0$#&M"17&D(1H* $L7[8'G@2HBQ U..@GS=#JJ&?PJ/^??9A]5 [#\[HNWD3TUD^'0!<@MN_- F\JNS] +/U@Y]X":=O!N-0N %6VQJIFO+,(-17D\'%S%LEAB44WPA\T8,L+_THA@_O5PEE7//Y<6F=O#..,CG=TEN^D3A#6+*.1 +IX ^XPR:V_(Y6(..\F"3(2=1#24%F9Z:,B:R-R;"[Q#Z%OF'*5KGN3 +8R/O(8)RZ@VG N5I$G[$VKE'X4C,C#<-S0%R&@"X-RE87RYG2@3*.W,$*= MW/93 +O-/LL]U-W&*[1?*X%&[- !NNM8]N:#,$NZH@KPJD?I(#_(E7]C]PWJ\W#@/ !CP>9!_GCT)2F6804S#Y!3!U!N?(K$$7 +REA[T2WE+9.TGBRV4)OL%MQCRQHMP.780\[%B+[E:>&'&+V:9Y.>_F!M_>%F9+RS +Q^,,#&#V[%LU3S5G:$?>Q6OX&.U;=)]W8(D@AV;HD0,Q\^N&5OTF6$8%_O2':KJ% +*YH]4]*H!B..BXV:5AG,GJ*,;0X"!(;FRF82Q\??DUK],@N=-RRIX1M[: R71]B2 +*&NT.FPH%WN1GZE :+/QPWA9B,'OXUX<$\M&B/93#2EH.&ORMC<% &\SO'=L5Q6X +N\F6FCG>$F6&;U)*_EU7. T>!X<7O1(1M10MT;Y[*]CL:8@L\UPP],?B:.BS> 4F +-_Q&5SO.7D0V4/_^Q9WDDZ,-*HLRPUQRF*,C] _ V''."]:04TPC(+O Z;):/MY8 +#5M?NC,OX!D\W/S?&?*F #B:PTPNO#RHUZI$ +7?$5>MX S U;?)W,N285E013^>;-Z:5U*W+*>^?,&@X%2?ZUL)B6R3;\_^-RNA'X ++.U17ZDF>#/W4VZA_V5SETN*9J,*K%NOZ 0GEA>Q[!N/-%Y[[V+P5M%3.(6HQ/O& +WE9.7V;CO>YF")D=;J$D/.BJ-1&03+O8T,4,L+0'^L +T07:''#*\,CG<1H&_)'#*DWQ84 WPC9KA*2/,:,7S=HHYB=@:GRHW#TLXY-< 79"I [A8E4J +8$/D8#/C< +=):]R]8JC!!JWC./H>R>5IO*X-M=%#WGQW??Z)MJ()(4+(P2.G+'= +AU!] #&XG[Q" +0SVZ= K*?\8!C-E^/"+Q^4KNSTS()$ZA2,J@9@TZ2K$G/[6T(=T3/K+&Y2M!J/YA(U<@#&2U+%!J[MYNR09JG +"BMM^G+2Z D2.6GOWXH]R[MVPD4]0&<%H8)-^9ZS>LQ*6E7I="C \4>\Q9IAD.-9 +:G:1Z8PO:*FX7]-'3Y(^HD,F-*B53S-'#*PC;Y(]\0,('30I(=AJV*W,*DR3CG-W +*8R2W +#>:;Q@5?P[**B1QMNAEC9?1TW<\F8GK\:PS;7]B>QKM4?*DCA[VT>&&2L=@H9WAP +9K@0WLF,^WI8WS<*WF#R,.R-M+G]E?U*1GN'AXI7(?YD +1V$C[BY;_/?C_NF\G0,HQVJASMT8"S^.^=P0#LD#_U$U;=*"^\T:1+\*N\ =;7!A +K(E$/2ZIF(5#86ZJ'6";$D06?JAUCRVQ4(XC]?B ^W?85^3[.KY$9#;E,W?!7(^+ +T8=GO"7D3Q-;,E:&!-1W+(AW.EMHI(]D1U$%5 4>:['D]!+'?;'OD^^H,Y[7\#Z! += )8*!$))P:^='P6R7/G,M:[/TI'\E,5:?I!Z]2B" \C#Z'OUA(#AR#61%MX A)_ +1;J/P^QPL0LPAON_4;A<_'1AYS$1"5M1Z1/>G);?].,H"<^,F,'$F36I$"BA,W\* +:$J;?50UD" V"9U4P[(H=+N%2Q#XX,\$<^%,K8T.C,?2+&H:XG0A5OSX.,$L9;\7 +0P&V;.^NZ&#?KNRTD8NGDX/TICS0'H_*:FAF#7YH[ >@A!%>G/.&&VV90PBX[[DG +T6_1KKE*$SK<[RE3!\F)!0,I^+TRIPW?'@4]9P^B5<6X8-R$M-E +!4H2'!/ Q!A@X5\4XC$YDE(?R=TEI_L(Z>#VZZT7NG?"EKM>*U"B*=T(9 +!"(IRH-5J]$*ZV,"&IM'H,MGGC:++X2L?"R?%3/1 A7E*BGF+VJVXJF:\9C9\_W(%-_L!1;]SV#Z +YYI'^+?U%G*+VXCDR_LW%U^>0NBO2A(6?@W51MLF-/)>YU<,M58 F8FZD2\[\LZN +*Q(*W_^YIFG$9CX7B ^):+^D;%5/Z4R@IF)%3*N+\$N).24D)JN'-\'U-_35[J3I +O#OX9'Z9V+>;8H,PIT;[&_]OB$W_+Z,VWOQP4K*HZQRK&P]VL&,"RNBG*[O7]XYR +KK$$E1D&>?<#H!\;ZR#N8IXP!,"1F8(Y*/Y>-"$]B1:?0^:P;BA^],?YE:?*_127 +#L.1A")1)(,D-^5F?A6X@[OKB(*[A%R3=C7Y$_D^7\LN2L.8I6KIM97M[:1(9DO# +B&-Z@!\-OT,T*HU$KQ*U3.CO2_];*"%E=D_#%>GIFF6T#O7QS?I75Z'TFB!$?K%A +Z$$%?:3Y-S1!-(CEA:B[RNMNJ.+< <#7O652UE3=6]\22.4=7F1\+*_ND(NA4IU5 +/122%L^PC^N[+*VSC*4A"(:533AM-;VE24Q@IYQL@^$GP50-!_87Q4#RZ4RO;S8X GX%2=.A+ +/-PS'GGP.Y@25K^WH>QI705B&5Z1\\BX7 % ]V32$]A9=-8M>--2FAKCX!Y,1MX" + ##GE":)9SY7.+2#X$#394[%SO/@=L=:D[U"XN+6+)H-J>\BF-4#B0X*7AQ7B7_# +3,=D"#!T0J% ['7M<\H8,"8K6GJN,*%I,].W.%!.1]%LC"@84P@T\'+?FI!=$.W+ +TT&,O.^16%$P0,J>^G<@TBLFBXBKA5=H%$O5"/2QA0 ZDTUQ)I@0?H]8/)%][/N@ +R%C-9:9U;DQ]+B!:L:)_$16V\T!Y(,0@92I?K+E+&PHY5A<'F$ *9;ICK0*]Q9]% +F\396S(:B*XSB;LT@Q)79YB*WAY,+Q6_[Q+VNU(=AAIO'->@T6=@621=#V+#RVMZI^.)IUX,D4T/[ +!*%LQ41(J8. NX9[7("2&P)>?@:GSN0#3J1:J@V4W%*46!+VFA,6CO,W;,ZE]D,ET0REF/\Y_B$UMP)D*T=2*BZ03/*^)5%MI +9VX-M.=P#C3*877-(4*TJ*8("=?^.-)4ZG3OLGFV?4F-G5VHRZ:A4 +H;.AMKV'6W*:K- Z^YE38MX>T3A[S(EH[#>_,PQC\GFJ6CKEF!U%3O;9P[-,-ET8 +7G*<["!;"E+[:JGU^:"ZO@DSW-M8 Y05DI]TRD T-2SEDQ W&:.;WB)^L9;$J35H +GJEI%M?BKP9U Z,@\6&UBB&W7U8R\'DC'3Y+> ;QK_UU-\95S47A2/S1:%MHAQ.O +6G9I[422U$.ZLE1>AH(*&3'F2A%:R0.D2J:RN,@URGG.KJ[ !B* +3S8_%WP'Q\6ER]-=8T*56:9 +&(0RK/?K'N[0'/<<' #Z4I6D6#-:^7IIT%'DGAV_LZKR@RC36OI+K\H8J2 I/$JM^P@(\FAY\-BN$+,("UV0PD.9CYMH./<3)]M*EFF>?C<>T9N),O'2_\J7U4LP +AB F=&6,J(>X:N!C^A&X0SOH>'LNQI1S^CO\O-UZQ*-IQX$Y%?1,XGKI"4ICBNZ] +F"D^AD!EY]AXM+@>CM\+,"FO6\%FX1<*)$HT?>G'E]A/$%Z\9C*2][= Q/HG%0,K +@B,[@E)HM\"-!KOX=6='5IJ:Z_LBM9YY=F5=ST%7]$X+97!U[KJ:).T];2%D@'QV +>5;&I2CJG.T_DW +:K\^ROL&6U26WJ-=5/RJ)%3'7G_;>\VTDLF;W<+;"PVVJO7X!X_XU]]&F,&]"VVS\:^'>#K\%"(F?YJU^5YBWZ"IG#SQAU%SS9RY +LT_VOC@]J#3\LE6P24S,17]=W=G1$6P?'*.)'5,0\-"[%\8G=1+;T [+A$=_3:O% +\?*Q+8F8:@O:\(E@^.8V3Z1:\D#!UJ=-Q4@H'ULG8WT7XC;42$:6JBBN2"^^%?<% +!@O^^34AR%33$29+P,"T3;./#3X5<'NOASX"2OTM"431[O-)6TO +0IG1_*#[1]VG6DB31@#7R^,K_XHYY <7^5<9M>XM 2\'-CJAL#IB&/SSKB2 5P-0 +!885]DJ?;T:;HKGT67@)JZ6M;BSVE_'UK69AB3L""!7VH;XH(+TD>+[5%J5_*$U> +]95^7YLRBX?#L"Q8"V$PTAE>$UI0_I +*WO4-DRY$Z'I8L!J#=HV<"\5=4^%AU0_V&3Z!%4Q\4L%"$VA$6V#1M1V.V(&*1!% +2DO/L1]Q-,O-;: N&'5U\\6C#@C ZE>V20QFHK%VQ6/$1 EE(D-*=MQ%N3%<$+ UD] +#K,%+F@@J,X);:21R0KB-\SID46]Q4-T$XY05HJ^6W8IU$W\_BR$T!+AVHPG#3[" +#E!O.:9-]!#@SIH6;T27G%5:CHL2C5N9LJPEAFYA(!D8K%E+P1B-!U[]#]KEUG9C +%M4).@#A\72I#>[*RTV://,\@W?@>VK7. A/(;!&AO'1*XXZT9[50/9:N\WO !I3 +C=0*65$/>/A-:X&G?:SSX=;!\7:&*K,X!# 45W]47]W8DX_7AT.^H] 7)I42UIT8 +>',_(*[F<.$,V-IQQX?$"K_N8O9<)&OMR^U?.:IA_)7%=,-WHV6/HV^0D"GZ1"L] +8*M%2_S//WI4+(:PAXWMGI#P2T;FLTW6VN0H=X@8@(>3!OO4))QMIB!T#5#J.YHN +%90^^!PAQ17YYC4)GM0W+M*/YBOK-=N5 Q?4!K1(89Q>C2%(>CVB$]43#'WQ9UAV +NOQ3TF$Q; .#NZE1>U=!GCZ!T+ T1$PW?=T]0^]%@YRM5LJP8=.FH5LK4EV'A>]- +$A?]?/(%C"CVX(1;)(/LACUWD4,.MB*40\?0Y0SF1_M[W/%9!N^34*R)'E^;=ID$ +?#_S2T]AK=Z=%6(D ]J,!9$ ;<&LAL-(0(-SEY0I+CI&11AV;(ICQ IPX9.&&MUR +TBY!2QYZ7A))1]OA +2V'^MK?7CNI>=YG[XJ/E7?P0X7--#V<(_NKM]O5[X3M1+JM;X0E"4?2W];Y3+0Q; +6+)=Y06>L]VJ+BD:*5A&%L+$/*P?_M<_W!2%_[:BBD5]*;T,-[-3@<:+D&[Y^M8? + 3"E3(LDKUJ1VV6PUGCH SZK=;C%R?PQU\X7#&&&:ELEH!(4I]6;@/[73K&3YUOR +$\-Y4O8':!5%AB3-I#B\^XY<6*$E&EUSP+8KN!%&%'&75(Z>F' A-:2V4Q%Y]UNA\[-' 8^(FS9MQ +:*2Q"^6J"8JJ#+/6],#_DA'4YM3%Y9S0R>W?:\*HAM]\*2+B9&_)_;! #V7LS;@4 +SGIRK,N?S1/W)8,:"# CJ10/>LH>'.%9G#J1XT/.>5""IQ 60]0ZUNQ(T&5 %TP$ +:X\YXJ,9^]I-E\C*BLB8J")02YBS).;?MK&=>X?WX1Y%8^\ [YKV/ +QY&_N/CP2^K_+4-/*EF$9S>9F!8!JJZ88#Z7ZW /WAUT&*U5(E7?(, =.08>#*=> +*C[>]9\DS7/N2%DY2]"5AVNVG?74:+L0G\-C"OVQ!R>WT;*D8\$_:MSS3S)F"^L: +!X ;D"E\OR832L[/(A% ?:F\;=0;:B[!:8" +Z2P.!@RQD'JO!J0-L[U'AVQ$\)7A=O\0BH9-4/4YAB[!'H>L\0E ?X%8+Z9F-4M9 +SL&IC)6@UVE6Z^LLNG0_MV_,L6O[31L;O,/,=^7&J5QD%=UDY.WOOQNEZ)5P7;^8 +SA\FD7+IRJ>=U*+"5 +B;&V$B_M"ZRN:/$Z%PQM^D!9@+3..H/<00Y5? +*027H:Y(K?Y*J3#6Q/?Y-2\@73ZDU.35MY?6\V7H:Q/*B'3U:!T>U7=UO*,> +++R?ADMN '2AU=H]%N%#*]%V+F SV4B@IT@E5S\NVX"^EJX99I7TM0R]/H6\M+[C +'U./-=O4"72FR%V<.]Y(R"P_[STZWLT9W_^/!;,OG^]-,Q1TE9.$EEN$8=K#P?]E +2,]*T\?'">K\6DDU?S@7#RR8&-"ZW+LM?(N99I\.'$880!Z'?0Q$SXO8RE] O^A5 +H4>) RR%VO5BG="Z%BD(S\6K["V!I_^K=3??G)%_07X+]9N\B])Y_"OV70;@!EU? +ZDL#$ZT27FIPX["E-Q(EEN),+$/M+-[44=V3VL]KUZWN)2<<5+!<"4^/GZ6DC.1J +=]46(\J1C?24\--9Z*XV-Y4I^%Q7J[?(84'Q_T2R3&. 9S*3ZTN54'A<46@FCT#! +\@Q[%=Z"PT,64Q4E=%1K[.H.[?M6#U' ! +V(E9!G]N8,\(ER>F,<+H$ZF[EA98)^W/[>/"L>O":8!'87NY$C5J-O+EJ"?GD:OA +'-+NH%7A4>7!MZG")5:*IRW6*8 ]TYF&&OI+R9C&+J6)L_[NUT4BY1A6_+]M#!1<^&_[GCL +I@4?M4:VN2&%\:45=?N#2=-MO-:0Z#O+'X->&%406\$*_K^ &+OD)GHY@RSVYF20_C@ +NB#%Y6V8A(86KZR\2K!^V=$7>8$1$5FI-;B4K$X(%+IRAWHA.#2%-:WP;XQL$G)! +PWB;7CZH@=')$,LS4 ]0)+)CJPL%'&?>="D\>CM@6QPE$MC>=_OL167)8KX2!7(U ++AN<'_K?,MA./&PZ+Y]]-!XC,S"!!H3H"6'8'-+]+W99$1=CNP(9K2'B#MG^BBAZ/)&,(!IF)',+A 7J6I%6<9B+!0G +R94YSD2R@SI;V"PY;M69>P\GVB-O&IA5G]K'3;>XL0"I2]<%OI6C0^4FPF;&7 OA + <:GW?N,=0FO.#V/S#3S_O8X#I:;"B3).935L 59S?%0R&_Z.U*\WO:P*E+1-#HL +%SU'GK#AR=/H78)WFX#$\KYG%>XCM5AI.OBP,".@*4M&/J2,-, >( +C'$(N,,CE<2T+ZGU,J RAQ",?0"1L2U&B(I,Q!+U8-E?W!N13G+&^-8*P1W29 YP +:=>CBD:!SR"K^B5* ON5Y)MC0KGBG8UQ1&]!WA>-K$DD7I9! 9IE>RN?,T8= -4J +B9V:9%Y$UEL45O\(?0,S<9>D8%M_WD9RNAA8)P]BXPA\+"Y,T/N1@.>6.O11>\QG<63A*3ZHE@H[ABA +;+Y.AW1PHZ-:T!$!\Q*??SXM71)8?2AU.F['5OF^2:WY>4(N0?1"C,P07#>C.&*H +FT5I&*)_$73L8GTD-L)#GXYY,(Q)0_G"9[683,K@NXK3;Q"J1,2!4&A9*/R+#$I!0\@SJXG6!# +@"XVJ-?"0I@RZ%/),V@O->Z0A>\3QI],B[0IE4Y1A8%[8A#+->.B? FK]M3YLT"D +H/(ORI2JH>HN.6O6J*$"UWDDW<;0Y.7],DPJ$,SEEEX>BEL720(^,['QED\8(YJ5 +V,1>:V.X#C^ERYCS#0;] 48W@^))^Q[KGPMBY-(VM;N#^H^!GQ*SG;MSV^>VAY&$ +@K]L1@^AX]@[Z3W:-#7B#_([\*_HFC1D,?6),WWLW^;^'?!=QP^%0U3KGC/8#R%D +/BEWEGF4"IFKC$W$GKTL\_,>RL0J:)#%!"PAB9X@6])P)MZ&J8$5'UM5$2*B9@[X +1HG(9AXX.63NKIAM+#;MAC*H7LD]TR?85Z:Y6/ 3:+ >9TH)-!$T29[2?Q />4L5 +35S9K1D6NW))<9BRW]'^JC;A @H?OW1D!(5#]%.VI.N2F=C]+.2W"UPP>0_9'AW +D"1RU0/_*^+I3Z-DXU%?:KRNK0*E18XW?1&2(%AW28,7J%_LFDS/1\X_-U;_9Y=W +A804(<;T3:2^\K&*_=8S"S]G:']824\]H^ 5C3%BH[O$B2)\! Q$>0TH/_S[DNA$ +/Z%8<6BABUFP("5:IU'=C&E5!7PE,WB_<$'0.;-)I$2&FW.#1'L@>G>H?.6\:C.V +YL@I--&QMW5;HXHGIC4FY<*C?CCBB3^\M@'D'K$KP!Q-?[.5MO%XK

BZOZ&^D& +(FNVTJ?>_H4B%Z^J6"^"2]RSR%,K*U*/G2A8I1-U5/0_JD_YK/[7?+BFB9;ODQA/ +A6@$0\!+;D&(J-*VZTMX*]UU)#K9BZJ.)2"J!ZBLTHZ4@NPD^K?45X8G*^L&=52P +?/TXFEZ5;HIU>]+]D79FH8WMK3X#JVKLN,N22QE>*RI\UF[HOO<*D14C"3)6P9EJ +#H2EH2C>#!MSLU:E!1 #=Y(GYCDD. +K,<*,>]J,3"!=O$W?O+]1:2W7>:W+-*XD'BAG'X5:P+UWX_Q5@2X;HSNW&O3$*V_ +\*,4$A*+DVCAU>"L#N',<+':3*AJ5ES+"]9:A&K\W^VC:W9;\ML/D@&!8#T7S7JZ +$7!&6*PXU/+I'K@.&$5\#@@.&DZ\%[!1$26#08B"NNQ4 3J):+F$GE.J?&R0K:-Q +PVGX[M7>^DT6:#.P*1L;*>RIS:<8AJ\L@\;"O1XNK*'8I(XLCEVUFFQZL^.X3!V4 +\86RT\9]%@E*BO-0Z>#RVT: [):M0X.B8-45;D$]0EA*=U !7B% P%O1?(UL7]C] +=EZ$=&#'=&]>\^K=I].ZO/[G.IV^J +_CZNOE4$)Y&.!UNX:/ 2 'G_J2,Q&KBJ:P+=>PV,.7VA8*]UQP()--(B;;>;!N 4 ++_*T:IG(U_T1$;3KE@CDNAO%_/L1BIV#UF[(:>M&(F5\TG0/!U^VRRG-U#;98+RB +B0QKW>*B?$#$H([%F\E&W8FM[095ER5JO)-_9>DX7'1D 5;JT00@9?QU-MT0'59H +OD(>_\K;<*?^=@G>B .: --R+L+S*F8YJ%D^M?9H^L;?)5+'(M%J/62?36!3+NMD +ZR,M@(UR\"GN6*MC1-$U>P$0<,9UAJC:RT%WYXLDE<0 1P2)(@W)7.2'B:V:NK_> +8=KTBJUWK>8^$[=WT"X0'U*)NY2+TTN@^7SY.%0J>=PV,I&V??/%9FS,P[-ATK=' +3@PHPQ'KWG.-4%OSUL,!!')FJ4](".I XV1/@)*B6 OH":!0A=)&P3&*FIG>=AIL +Q O<>!$0^#]B).H7; 0&Q1,\5?B<,%P GDD>II]QTIES"/#O#B4YA4/4R+E1I/7" +&C*LE]$SF( )/BX."_9)S" B5E_/5;-BNODGN^NZ_DW)3DOD$DEMVKD'SLZSC5&M +N'CO?8V--BO:J.V< (Z_>7U,'1E[:[?PA&6EQ8UH*N$JBJ&@#))1/<#PY!+_(+3B +1GM ",*GCQ#6VN4Q:H0E^&=/A?'F_-&Y*:6COMP:?XO0W@LCZT)I!I4V!-8[,I.0 +^Q,EO1/0++ MW#[!H\KV0? S'P-H&ALN@NHAM2]+'F2NVGHIZ7J08[RY4N$>\!)T +8]!%&!;)F7,N.[\3D >D^S><>&>U$S@,SIHG?_UHW1\ 6Z9LLU1K7FN_U(RAH%FL +0\MMF:3 #P9/M4$0!DMT;_$I*O$Z(\O2;T%&[A2I@ 2Q;GV+W56,K@!:@J-%XM.1 +T(G'F*DP@8-TGTCRAS9YX'I(Y<[ 2$0I_^%H;T_HM_B!#+"=X=:((;MT-_-@)_YL +(='G7 B]2U2VXN[5HS_=ADUEDZSH-8'JZWWSG)UW36%<)=PMF^KWKVMQ]/_1P +T6_9UN>Y1D?0.Y6N7'B]!1M2F,U5/Q.UW?4(MZ,@1^:5"RU 0^7X1_*^X[A6M_(P +"@_G9MIA#M%U.B3(Y1@G)I;3BZ/E-*!5.+%0Y311;.I&Z&O[<1I6Z^J9"C3Q#1_ +CBF047"Q)V\B#J5OQ[ 4MWBZ7 +]_(8/&=N-RR3JM .P^"(IL0$RU!N4;MKM095_SR<9%'SGDE]'P]58U+!DEB[$!LI +=,6*^2KJ'8,DGM3B\DZ-,-TN0)-N'$.+_BAX'$C-IH, [Z^GF^>^*9&WSW(>V>=C +=*Z>TB@*=$,L5_&5J(@"X2@R LT^7F/8MD3_FDF1=3HRJ8_O7:IT I"/Z(G!D\!B +^FI3CSM?[A$QN72,T:T5CK3"!$*XG7@"PV"Z+&%KP I4!/$JX4DK]SY;@>:X"FTV +EHG<=V>I&X1WHX8XX""&@?)$_!%G1*VHR-7_#*#3N4OZ;G265779KAJ=3PBSID%: +S/@S#JS ZQ]!\JX"_;8_U\YBG#VX$GVH$"WR]:;.8UE.^&3"9%#N((3=9OZAK)LM +-[Q2S/=#"3+J2H5C&S25FMA*$ZGR+8\;W+U)R19WKZ!V[N/7]E +FYB3A,;$!_>XKK'W)8%6AAY00J_-%2$E^R%E51(^"JFK?QWU$4PE-N@"#F@CKJ9# +%SB+0$%Q?G/$^^OUPI.F#LZ,A;P8"/EZDX<:NZ((\#VG@NS/6A:_:/DBS=SRC/_- +I_WJ)2OVGNC>%%5/W-WH-3("Y90_[7#*$V5^(YC2X?LM=P30GRO*KJ<&[# AX;]H +>]5("3&QWWCK6O59""%B\I018IX*;>A=Y(.8OZ$&:]Y2 NX( J.)M26W"E@!- J.0\O?'\$9> +YR?#TV9BLH-M6",LQ593;P)?XHPBM'GL,F4JT,7MW=@K\KI1'37@*7")$E0R&I+S +.U.^P$5(RD *5KC@+Y>M"S(:[6GW' +6SBH>YZ&>51?Z5/^USFQ4T4@V%*OKB1V'"8*#<(TJ2WAF476ZE\UEB_*7QN2'_5? +4 @/ABTF"<6P#H?^^CIW@:9 = +_87 WPT"S[2"&JW=&VN-S#.0J^[*%BK)^S[7<)NZ/)4Y7J6#=R1['F G]8ZT"",( +E=*YOKC2 1J=%-:_;,>:"%6[Z@>2TF[[%&'+EV8$.#%D7XM?T?4M-#>5N(I]')72 +@E#NY (E53W9+G6)J5-YRC()7 EH04-R?HYR+K0)RR0BMWGNA,$)5"MI>A33$[TH +50"?_>$N!T;=;HA5JJIF4+;-BG_$TQ(>RIZ6U0MU.J>0GZI4X7M ,C.JZ<.( >\+,II7PB^[H;KE']Q2# +ARD$Z &*ZX<\Z2%*P*$4N^J3DOQ*K@::B(!(^+[2C>KOP-1FS1=0#5G$MD2.DA\ZI;LR;5G4%R'AR&).K0A7*59GSJM[],FU5 ++F0J%X(/1%31&2V;&A<\M [IF%NV[<)UI;'1'K"Q3C3\;[^WB3<@#Q^WM7*OFR?R +53LD.7LO3R'O<:$X_9\D#!:YH6D&-0P"3ZC%^NH*PM'^T\9:S,P.:KJHJTZNU?HR +'9'F14UTZH(Z2=(PAT0GIHTH%J(^73M=,\JXLQW$)L<<.N?:<)8AG@>$W=:A4">< +V%9I11Y><^1.%26LD$[>Q&QPR#A(5JR>E*+D8>\^W98Y34JW11*Q9VA!K!4[P44B +P)[>6+/MEWDOS_;#H!6R@P0,$9E;'Q!Y,63B"H@Z>//U6KDZL"_:2)^/[JN;4DPE78HC^ND"(<][1<[ +Z/-MMXQ7RXAXIFZ!9?>;MB6J6#%/.E.6OH%O>;/5%!B TXF]SI+BEE U>4NQ(,JI +$T ?I"TN4:?8>PJ>1JAOB(J?Y]J]3UQ)P4A)E>CU(:(*40*H9.C8=&' Z'X^*G"F +'(77Z*W'*T1?-]7HS_$4?YJ>.NS3T37;:+HZF/69AEM2161(L]0MI?1$H)5L:QIS +.VLP0WIZQ@.S"MXT)L]87/JY K_U0EHA;K^&38-XEAI8)2 CV'!,'A.X\HBI(JXP +@784OFSL **F#.;1U%/9PK?1!7M)H\<*8ZX2U5RO=/_$^X4?2TL>P-Z^J%^Y^Q,D +"(/&_?.!.RH5JOD99'IJ,S1>VOBM"N0G02OAL9'#3.9!X.7QNME^^MCRD7B8M:@2 +S:/B]%%TU%0A8W.U+3S[>,L:VVD2^JX1 WDW@%".2W+?-'123,R U$:(\]O;^MVM +Y(-&(,4Y[3+= DNEK>9?5(V)C5&+!EHTA&A\>=UZ*M0)%Z5^BVX65"EZD;<1N?^B +@"-O[K@ZRI?5I)K$P[CCB)<&G!=&=6I>LYBP;R&&N>7#\M\FE#E['8Y10_%&@IE; +JOXN04W2V&K]WM7:*%45DVP 5@(_%R\JWCHY0FHPACL\3^;]A5W2/W9<1IN8& S# +B$5]@;$WQTL;19K#)OJOEB)3:W":=7=9LK3FOZN8R);2-$/Y/1;^\FR^^1,+%'Q@ +);Y@0]UG=[ZE[J:[QTH9-ZN7,9[HQ4?E#(TD3"9VNT;"0HU/8G?)Y,/>XB?F=X4[ +^LR6#91'G'=C3J89UE_:PFC&UMW%A,;J-CN?+EU$A8[M, 4@Q^8QA3K\_@^ IBH= +Z5'#P26Q 9D@VH'V>PN[MOCE$8"ULX["YT@5><8U-J>'YYW7OTX=BD8^W9KZJ,:+!24**4^MUD"RZ8X *F% +Y>="JGT&Q)"VIOYWG@\PT*9XO-YTBY8MNYVV,%&VAU=?!,;UY;$#P.^Q_UI$FU/7 +'DJI_@(OVP@N6- (^)O\U2$&P/+5 $0AKWML\7V(=%CX\6=$82,6U7C#K% '+ +7U.1O/G 99:F_-B*7*@$Z71[%\$;*CHP1RK()JVBKNW8N@R.-A!SLKQ^;X"X$^(W +";Z/KH\C;IX^+6E\<7XDMW2%F:<^HS>!I_R6*NH8CVD!^A6-9QQ>8C?!&I5OLA:& +T:7/JN(8U:3O)GK?_6\Q!&CJE4SA-OQ63(=T(\%#:G Y_H*T^:&.#^0DPPJ^YT2Q +=I28'B="E'U& Z.T= 3XO*'EU^Z,(G^$'XE\\DCWCW$O*IM1/)W41'9\: WH%5^Y +MK4[T]/^;O%, FH-A',>T-\(68_&EG5YX897RYM&V:;&]F@&FB-,D:! +2W.6T?U6C/\#RL7S3B4+M;J'!0MZ+P(OM5DJBYB>]_DK$G- (YM=GA6[VHHN8ZR> +5)1W]U"VZL)JAW.GJ0[\M:L>W"K8KVEU9^(ZJ0NUFH2J J"X*.71DI>8EBHAH]T +;V H5P(+V?093T5XFY0Z5J:Q;OR7V!UA@\65.SK34=&_WR0B.GK&G8R%!(8G^P5G +]C]X@DNX[B6A0S:)Z+8O'"S-]^_=*@RV9X:1VX!C-/CPNY;9Y6=U4D"_OHTR=*G; +$N'*<*-I7;NUFO-Y) Y$G\D;H@?#758_!\$ +ZVG,YO"77,<+QT2Q(%I-&)ATD3V;3;@(4@2<'H]7(8E*9L)YXPOZ+K&_V=S^+BPD +@?U:9<3"CY4K_2#KPC@5EJ@5V(D"-^EQSCJ<,!Y-NB@)6U.^29W](KAW<(!3,!Q( +7VB2)/S'W-X^1UZG*X'&LVK"BJAM4$[+]GYS93-.=$XCR6%MRF5P'&R3+$M7CT%* +B39'0^G#F6.W(6R=,L,V(CX6Q&$F8@A.BW,OAZ.,G0M5 3U=Q>F+ZCX IKWE]TB/ +E )]PS9?,N+L)YZ6).02JV)T4"%DO?E^/]$)Y>Y&5:TL*;?2TY[E8=HO2J +9-V6*X1WEXHA '*599K',*HP&HS&APXO<-(7LFQ=7>>9]OJ$V"(86.TF+T=%DA*< +[X^_+77W3Y@<(8;\7E-2Y-K?-S ^@;]U; +%B")9.!AU1]@>!;KCB$6[_P?!MF]F/UALEO=9D$0[!4;X^B(X Q98A]/E)5;B9B2 +H_ \6W!CYNK7>,26NR"-> =:]A-TDO/Q3D4;8@RP!['IF$[6Y::-](;A)-!W0\YI +1E2CZZ6+M&M3Q^:3F5_-=N\5"!R'!K=$&VVBGPZ8K=8!H5R4POOZU0!@UJA*E=;7'S!BG1B:4NV0'GQ?AOE6=S["G_0L8X=Q3@*4_W?W&D"21D128DQ&'Z'R2Q"(#QE!1T3GRE[S* +:)N<\YOR]KIY3_8W1B8B1DJ7:S4TPI1(*]NTN7=I2]SM#RZ3[2Q?5M$^0TT18J!" +58]3I3$QM=.SI&>G2\>MN48OFTIU^T65(@"ADL")&".V(#:@P,BK?<.@-$?"NIHB)&I[,,3P-I1#SP +(%)1>@D4RY?--.W@Y1PDS#CP+01Z YM$',/((,/Z:<^\1GKT'V;10+."4:D8);-U +LJPQ0?%"(Z7P4NPAS!(5;"2A(5]8 M8&OGHJPF3IZ(U<=$B=5C6U@2-\3200E9L' +@\RZBY#JEZF35--)*1W"FG:$$NW'Q=VYQR8S)N6CZ HG*0^.? ?<,2AJ! +#.5W#S]QSV%U2U,DD.]5VXCQR%L!=[-%X\:B;,T(N^P1)F*>%OR5FI +L)$UK=1ZP@2C5B?IF7HJN2!:UA[4_F73>+W3;:?3,^\.5*C104]LFI&"MH65;8*9 +2IYH!J49H,]K%6]N2_ C0WIN-EV*KE"KF#Y?S0MIC>O15:QE7P7+&^))XIXCQ6;8 +MLX6A22EXLEMQDKML92::G9XD/15)6!=X5[UU0/6!NQQWP8Y0HFU#IU'W[6%\)J< +#1$5#)9AQ=#JYV_%1!]6R(3&9568H8AB![=.G +SU.%5.MK6N)($&_&']4_.N(B3HAHJ:+!]4+N=? ^W +: _YBPF9XNX6P[:@7B^J2V@KN(/HB#%!PTK6I3N@7]!:>RQ3O7H/%Q2DNB/#Q5+(EAXAY +X7*?].O-/:^#'&R:2((56"OV11;EHI$C@ZEY\GSD'YFS]-KN#D^==B]#ZJ=NQ[EZ ++(3D4 \AH2$?K2X6E(_W78,&H6\80C(=/?Y+.R1PS,J&"-DUB@ "[[,1J+P>5ZK+ +W&'24P@C47(KJ;B$V]:>=[ICN4BSRREY90BT8+ Q,>*;D!=( 3P3VA'&/\_H98K8 +PI=SZAVLI[CDCT?;"K>?PK1NE%/J=,TM_(^8?UPTJYI!TGT!6BSZ[2>K(TD)1Y5> +Z[TB*@;D!F*)2?K@*$1VRVL8PB1+C@71#[QG[T(NT4*B%J56H+C>:S&W\+T_!$RL +F(RY=0E<<8:POB[JN/0?,R(.Y?^XA.#Z!)$V3^E-CLV]03LNF9)61IE>RF-SG??) +YMQN1J"V.R0*+6W]7_3=^GZ/3 MC.C#XF.V:A1 PIZ 6Y!HM:,N=_7SAFW,)$B+ +V(DCV);R0LP"@G+:@DUZ"BIF=B0^%%G5/_^#7P]EOL[$,Z%S^P!?9%:8N\W@QYH(8Z=7]L\EOX'N2 &R@T)6*")1^GN="=-M< +?0-VU8:+6TKQCZ_O@A?!?HC_G>:W;!G6U9]-!,/92T4R90<>YR=<:AI)46/IU+K9YE!"Q%8 +QXE838+_P %7S02!8*! 73ZC"S$[P] +ZW,G.N1_"S9P)XYX\X "+J\@2KI_M[4Y5?$_EI(ITMA"?4BSB#";_A4;I&?JU\C? +8 0XFQ.ONPF J 7974Q0(O*$EZ3.,]HJC@4[:<46K.<4G1O!DPZ^6]']>5R\A9 K +DR#4]ICF^5C"U=I(K2G63-[V;MBSL6A$KT6?2@C7VKU[YJ1AL2)[QU">Y[V;;LB9AYU@.!1_?AR( !TL(]+'O'= +#!];0G] X& GI2A+G2=3Z]1E59RB;WT_>M?DO]<>/%WUF4Y1^E,61. +V-DN,PPEP[$C<6FV[<+56?I.SR@:\=Q;>:2P2C.$0.Z?%!,3B(X7L_FQ=0!9 +CDY:=J<^>8A5I[<.!K8;@UD&8Q0J@NC*HW<@U.G4;)))XG74QK9)C^_'HLDMOSR- +_C)NIRB-FS,$F[TU*M]?F5U\$U^:V@*A!?P?W[3X+"<+\$PUNGI_&!:I Y[1004F +Z+/XF-7?WTEI*EPJJ@S+KN>UOYP7@1=LW^PPO/]^$AI+2R.A.C9C B=: "H!$DUV +#.N;<,6967 ;.$["1-P"PS57&G? V*^(F?3%XCD@UN:[X+6&)="3>SQ,@&N#SI+' +X]BH6G/1W ;,%)6S)IH*C^?[V'"@I.Y('&B+J%W$ZBQ#[>9GP_**E18*<<]V=5); +I[?!VR"')U(*0VG]4VL2C/^)G:!R<14G.R;FNO-DWF:E*2#!3PO! +Y+>'%'D>U:":@U/;%KJDE.[1H!UV^B)7#EE8]@5_Q-S.W<>5G\N G=/#2OK1LJ1(/ +-_&:E]S07%JECU].6<&J1DV@5FFM*G7BTXUCE$_&ZVN[/_DB:8\KK-F14#!0 +(@)YP691*P2(^?Y[J,)#Y.*D.H =Y^#+C])!E005Q[[S/B.F +WO@V<-SKDKG]'[-J:&QH1%/"ZG)-RX[5O'QQ33"R*Y21CO\L!'9-BQH_P62.$[#T +T;5&:H4O6K_($1U,MD^M>IE94QJ!;Z3)#A$EEM 5>GEN(/?[K'=+RM&]$[Y)^]'V .B>T:6*4+!)Y=C,AJ +P /?CF_*EOI!P0CU&G&GE2AH!+;R))X?6*4/?D6ATOPJ*@;\Z$@TB(2@IX CPT;9 +7H(RQ779FC!28L)-KF=GO>^\>#T)!@-.4L.L2,B^X'TG5("^-8(5M-[OKRIS*Y>I +69.[HFBO&I+C&D$+_R-7X<6+7(/77-1]?!G=%7!': GIH)K]B#YZ$HRZ 'IJCIOR +,868<-I!6W)\ITPB(">+T93&^D-WVFH@.RU+?E=C25.SDM.R.PM'I>P06J'80-#E +,\^+.4 +M982JIP]G*0DNSP\8UE:I:BFMX]5E_^@,0/""M5N(%)WAE8%E]9N6@6R=[T+X5DX +Z",:;2PW#;:X9[O&Z"G17L521:-2'0YR +'>YHT;]E4& 3UW7W4A5UADMV)+4:-O$F(/ +KP,>N"DP\BDC;_)/'1=OI!8O)H*31#< D.N"HA%Y!3^H)H$Y>?%_7I +*GO0PC'8)+NMY.<(WU]H,[!0=MKD'$$%=)L?UHGG$\E_CUAZHS\F)KJWK"41T4/4F]NG@UD6&"*IO%-Y +=[]NT\K2%#H2MJQF)RV'.(HX;H%AYO +DV;[/L6^#VT#VK6Y@Z) +/2+X!S==F0&5L?,W&Z1Y7.E&NM5,-#?+%,@7"$30[B_=;+ALT([$:FP516J#=TB2 +L]Z=4UH3\"\I$WJURD_^S-G06PW'&Q*[R>5"?Z)1GE5\WU- *9;( .N]ZXM20?0S +4B!TU^$%)$:K2:NW$96C&SX14.ZF.T95EM-J?J +@TF#5 O;EL8:DL#C=NHF,V)MAI[AOF2]\-G^"%)2UV/YV:S9%.P9,3;(!DH#WVI+ +4#FOVVF /*.I2FMG?"#5_\=RD4;T6)K/S6^!S8("-RDI1]X@24A?]+SM@UTI'3(H +IG5!_ X3DS-I2*W$;K& +)I9LI*< +DV+]V%4FCZ8FL"BZUYWACL^2&&M!;/F"0")$T'85 G K&*YO05&(H5I +&M49,DUE<&_)9#X,T=&W4N>%S"I"L+N4:^H<81W%4EM$9ZY;+*%Z\=Y&MD8K>L7X +(?]D![N_@=O=8I&Z0F0"I28Z7XNTYS:2A)X<0 !CC>Z$["T7NUH-:/ Q9-%)O/Z,WT:H:R,*8N@(F=U.ODRKD]"$ +K/BL2_=1B?79UZU:)E.<"B-H G<6K'0[XY*8D+-9KR'_1P!/*W,O!W#>7SG@D>0B9F$416M3UVV2XJS% .;5N++V,\8B"Y0;T1<7&=@?*18NLV)8=Q"09AWMWUR:! +\: %4;XD^B[ UBI^>CVA)CM>Z0+&Z&A!$%NM/*M$BQP97_R5#?)F<=/%@TBZ=!)# +5? L:B,.L/0$_:3H3BXC"%'(+J;K6!><)6Q(1;_\UQ3RQOV( 7 ^LG7N*;ZX2C!I +Y^AD@CT?+1V'FP?KH;\*3_F-NC_RA[]PM,SK>U)M864FLPP6-V\$!5X/-S.W!.>V +;JMK2*E6'7*:J^6^UP]4)*( (V%GB_HUV.7KLES!=#L9:&JC\P$K*_M;_I!>CC1' +"URHC#UL"A%4FP,J.2Z(V^R$U#X8LI_;6'$\H,S+?)-SY[T*LJ/#Z]V_C7F3WFM? +OR;/HA9./)O')'@_?J(^WB:,(66C^-G8F<0:5-WH@?60W7.;YJ_,\-;J=?3IRHN0\$_BPBJJA, +ZS^<@1_B*Y[ 1&=(>'K+GACPE!S,RFF6SUR*9G)_K/5KBL>_+?(,CK-Z+&"JIQG* +<= QPA.Q"M-Z/REP(X,C.*UPRDI$NX46FU28:X0KV()%X/]D=\YJ-K02$55YBX"@&;2"/>Q&B%SC0#$^345ZTA.NFF<'X' +YP^0;XM)Z+*[N!<!C)Z )02,GW-!,\MABG@F +>^.[C[YIT^-$L=F['T2K!+X^D%!P6'W)B>3ROTPW.PYP Q@H\55I%\(4%S@^$+/C +=1K@V\-'&27ERZ-JO-T 34X065F*9.Y&15XO=>$$,F5=JJ4\QP*)J:VNCBKKN!"& +73&<7 5]<$\=OLI6%&%$X 7YP&H$Z,\H <-KN>'*CZ-;1DY/%RZ>+=U@ +9+HL0LAMEUM?GQ\T A*FRF =WE7/.YPV_F*C:BBK3)/S;3'>OT3 5Y#%J/(;S>J' +YEU(!3+35K:S6#_^3-_B^&ZVZ#\D#-&RI.=@I]'4C-TQ#1(LIJGW1LCBD3[GBW2& +B7 DPDK1%,S%[*K_7..17I -5^J5NB6[U5WRF@N W.YAAU*8!F![&U6>VYH=@(&@-4_,@04HL&_> +Z<9=?A;P5LO)\@X$,E(.IZOPRE=K0HM>X8CK#N@XX"!Z8Y&"OS@8A05V8MH#)W^P +U8XQG5<7>QH.#O^4KL6%E\I+^MD8LKCT=U8I^!GUOL-32X%'G?Y_FQ$M;!';6,K_ +7'/B9P++4BC//]2DL!IG\FJ\\8$$$O4<'!NHFO)T:N&77;TTS21TG$\CX6/@=E/D +OZYJ\>S[2(-/\&+Y4M!(:=&]=P&Z&9H2-B8.\,F& "1UR+!D!Z>R/%L][8):O1]G +K_>M54LM/&H4/0:-8H$?AHK3-^-%R:$Z;7SB&=5)&LX@OXXHJ;V0JKCA3Y@2]0'B +$(ZJR#$7@A !RA]0?9HS![>7 6]T=$N?;B;NR%OR.=ZJ$0KSV#N:7SYT+PI1[SE' +R.J<',]4PYN &@TMIH^"+H>]D(,HK=#R2:^(/:!1$HX"[/JG71=<_C6C,A0@3Y0XSN$._ #A!BH-B<2Y=VMM+.? +;*+I,V8(T<)DGU_/GM>N;(E:,^0^T16;A!CP"_=X8-@IHM:X^KAX23%D_DEMJ.'9 +LR)- -P5S[=BB:!#"H#OWRR(Z@@L5,IAZ1-WVS(?"GG\-JTO"*3H+)O!,-(H0K!61!^"%/:6PU@;]%/*V9J=!B[KFZVU?%EM=\MET(A=+;F,G +<\T;D>&TR=LA_ZB8MR>0]^.K^I:G +C]$[<3Q+;^:EE.IO?_=_[E*-2=<"WT3*!VU7A@",PUK#6C&+L;-[.A7U:>A/IKJ\ +&\UV8\S2Q"@?T1],B9%*<-DQ\Y.#!^X<3\K@GHHL[>I!&39G!'!$W\A')N+IA(-Q +[XS)(^ZG>0R*FU]?UYTF!H1 5X:)PL0SA@6+?I%X"\61\%^(BL&Y@2RGK*_'=![N +L3\"M;'<0A7&;<<6K1_N^P4H'-"1MS$8F0#7SKG)C@92OA_DST/6[49MKD(L>PER74]Z8= +B+ &_)"I&@+-3:F0;=2 *QAW0F:;2V%T?LA>3MBD;R/)'(X=:&!WV?0C^NZX[?AD +0@,FM- ?VTIW3/",FW!(T"H9X=[KU]OZS*9+0_&6M=V]9&/RK(6$T.68N9JL <8# +1]R,7ILJ%!-+AG%MZ#?1ARR4NP%!#^G!]'&:"7$$2KT":SA]YRZV5_D/&)7(GX=K7*B:L:J(U_%?PF9,J]K4[ +4=RW>T%Z8M6U0$T&J&7 VZTL@_NW_R?!%C3 *#YZH3-&;'@4WS?0@!KAF+Z5J+)#%0&&#G.'"'2 +@TPU,GUN=F;"O8#R"7:'?D4>"0WLT*VLLYVQ7+-R"-=7Y,(WM08J5M%<0)NT!,Y' +*[-<(GM18.2"!A9F=#".@S4@KB>;GV+!;^?/[(20Q'?$?=>9R%8[F?V9UZ)Q2?NB +'<9S:HQYGK*TO:QS;:EG761GFOFAO3('_Q?UXDNOIWE'%VAX+,DZOL&Y>BF!P.R$ +P+C]\6I85_'$10#W*/24DM@ NIO>>J6Q&O'\@%MS[2)_JM>)QN+HP;XS_#UJY@D60A6 ,(7Z M%\S +XVU3S:,TIA ?T(24:YL7I,+8!/WA;V\[^X[Y#&2MF^<-1*,;YO5 W=P77P.RR\2N?SQ:/R\ +6S&OF9M5 BQ +(UR4ZJMYLR[652&HHBE"_X%SMY#T?&%T#$VBFX8S.Y?/1M?XX]^=_]5L:: +8C3 ])'U+QX$7K40AS)GTZ_GHB)T%KHD)L3E&IG/]T=NP'%?&: *&/S%6?!ZCQ1X ++JOUP#(KT==-N:"][HEB1Q#E*E^?W9",GN*@4)AY;X-[44 H[4\Z;8R >\\V]:Z' +4=*C"QUIRK2P#@(K)*,O,)):"8CI-Z7@UW@G+O^,-:_'-BQV;P)YO:EK.1UO,"^U +,O?-Q:#X[?D+>OXGVB;ISD&ANTXI>2\76#&5-J5ZE8.9[#1B"(-$OL4=G5 4H.13 +2;%!#L,E;U*OK\*IKK6"=(;NV&I$;EI +=QV@ A\W]*LQKV1#6"Z'@5<%&HE,1D^%EB6-/3UP@!O_90+;1(_[ C]-J/?A9SB +F#Q@@"I[C_K =D5M[45"R3K, V% P]I+'*)[Q.'-OYMN,<.#=\E0LD6 +5,T!BU4%L"%.*@%$AH3? IV-$$:3[.BB@L4N3 <./S/G5N!Z;XRZ,^<8GR%$VNC/ +Q1/KY4\F +C2=LJRTJ(&)C2TIO:V +7EJ?JH1X(+T=BO/-!R-6<8F.;=\UY *I@T$V^,P8*Z[3_Z'P/.K\1,?+R-70P"4U +M4OIGAPNLY#?\[[-"(7L'V"M8I1Q>PR>5#T3(JEQ2O$"ET?7;6E-BZA'B^E@606! +1"9A KP!F?E0_BN,EU9HE0;'Y]117)B9[.;&W?U?VE^\*BI1CE0Q#E/:GA(EUS<=I*!)P=& NE=8"(U)L6$P#TTWLK>!V(C&N2(2JWXUER^P27L,X6!;J+LW +X:7M^K\'N4I2*-=B_02XTB+YU. :Y2\3LC1D0Q^BWL<>,NTD1T0D]:*[6\;U0CDW +$[14J'R)*Y!:;K-3SDIPHS>EF_O7PL"G,A)6(*Z5L%VI2%<\$N>FSS\X1%Q<(=[7!BN&AR+FZK"2)"I9JL.^S8":0#ZXTTZCPL:*<" +XX(AGX,VIZ(I%43Q<-YQQ\CL9NIW9*2RS_I'KS4[T0D^&-XH_#RJ%%U-07%^;K4A +=#X>NA'$SZL 5"I,[6_1 !!BR11AKO*)VM_-K/G';.P3@IS$E+"NH4DE OWQ#O9AK1_B:W#9X^KMB'65H, +*2+LL4MXML>N@?;B[U-#>!_S8Y1"4R23>M+8BR\E6N'$$3+E3!4PU)EG0%ZM']*' +/84Z#Z'SE"IX5]MEYM6_E\&" +M%GAPDC$^+O>G)/2\7 A6WX0K%IPF)SCX&+F'JO#R.C2VS+;>]&1P18Y/OQ +,<^KVX+.2FVVSIR$+9YDSU.'4_38B0$KX:!*H-[V"-X1[9;'AJ.Z(LGOQY71;Q.\ +#W57^HLR;7^?IZLY*/8I(^#CP[: 2@J#X*QPJ#:4)"U8(AG.J+:6I,Y!.54&@T.C +NF/ZDJI%\7BYPYW%@;T\G%0QUOHBX2DCWL#2%-/&$6.2X[<:+,;;$,<101]S6UKB^+=@V/L,M;"D-SOS"\1NND-B,1SW*]#RO"3M(^$HZ $98*(\H(@O:$) +HU(&?R+,%B,PDKU/9'H#%Z=W!9JC(7N*24H'8)]\&@QQ H3G^*^S0(O'L)]L!O17 +?="$27@I][[35J@T9%/PNGO_07LOI%L-I;^KNQE;3W&M U-DM;( N;/1P;FIKF6! +FJNB$FE,UPZI\BV3]51\JP\_= 8??F'5#3OBG!O5P%7C4F'\-9J&E3PC8O3[T9E^ +82C1>T/>KLL/L>V.6^E]A@^G=$*;>/HH#N1S@W2>RT?UG31(=-3&G@2(8HE./3^# +YTU%:_'9_\1-? W_RB'9WT?=3:7D5I!\0E_RRBND';.5>^M]VOV4QW!! [IM>0%^ +/&9J$S[6]ZK%C@4N_T/3@PKRW;P$A*0"1E!#D'/M_"Y0G8T>W]-E$2D._W1]$K.@ +B@JE'ZPUI>E/O3)ELS3__2ZT=?A>X\)P1V+N\+^D?)0ZTXGF$;2AO\QLK).;)XDC +W/-&_O7UI7 LU7GGLP,%7C$?[^4NZB*UY^ZG)=T7 +KM\N'P5!]90-8/R2HX.2B^479F1F2P&U):H)_=H-&-(\QBCX0X(Y^&CK]2)![+.F +SUM]!LSDU9&F>/_-AWF_Q.KAM2C36MVH +,/Y#MQ]U-T!&==8<[<:'X*G*7-WLAIM6<>V0!^VG.%; 2O?X9[A0->I^%.&@\Q%X +:^&-K2.^XT7T7B%P?3"RO7,E/,2/EB9!N=*&+5ON\Z7JPTGIIY-O#5#-:)T+/&VK +T\;S #,GP/18+)=8)_%V>+3[AE.=_/?<#.K)^6Q0OK-XLZ?Y\JM9+LD_7 I QN&/)!W)C7TKV0QT +\S7/]O\?]9?.(OB1XH)X@L"\IA;_:"VK/$-A $[>QO*&ZRJ;^,ESQ\8&=^F+8J>L +Z247_0[.>"HBFWC_GQ4 :TY0YG!I[$#&[AHUU^7A8*6V2JY"ZKB;Z6KMD,7)6^!F +J]MKG9"0L/0R7R=*BRN.K-^:NWS9ERG'\HPP:3J[B/UJ>12Y>F9F@\87T!12'V6H\HQVW0YG2Q60#3/\<@/6/IMQ+%:AZZEUDIJ3.EL,S=O=& +IM$L.ES)7I.-ZA1=7M!N^Y!T_$>7[+:Z86R_RTL[JM4TJM%7<<'HUKA;4KCG+[F4 +690W(BUP1^1;#8G -5*D-(#F,']4,^R1:R[5OBGHI(H /GK\Z5\1% +YY\@/ZRL8Z\Y>*:?6T4)%AM,P^NB9F^;W(8OR_4BQ4S"'A &/01 >8S19(PK56^\ +2LUS2Q06EI2>9B/\@!B'FS(SY%-I1 /K'4SS@EI8_NW^GRDT;8;2=!8G;*QG@F/H +@H)[2_\:X2)7B<0(?>LJ5CS4T8V<%39,6H6LBUTR=[9'K+C#+6'YQ9TT7%WX?X T +L]281OH\3>9 X%#E$O,1$4J2L'O_V.$U0X#8BE9GWD#M6;\11->\:$H(;:310MVQ +/(&"%P/("X((J50IYO,U.[_I'0A7.)9^.((8@'Z9O(]26Z3,&J1;,DKB+?&I"EUL +%V ]U)_>#/B!&D/X9A@"Q@XT.\AB3U$;%S9T!TI_1#ZB4GKJBJ!04,Z]3DP[5_*W ++N FX*MBY2X?6)H+NAQ3FHEY$R#(:L#KY1B?M[@MA4179=X>O43;2#$AO,V**^7) +G^FA\A(;OQ"W]$@KI4A1 M-CX>EY&FMRU]QWFHQ +-3\/2U": $S5S$'S05X+;O-$YLF56@H>4PYLO\8(;@I0HRL<2WH$K\U,GSU&$]'0 +/E:@D%=&&1J>SJGYJ_W<= _:J=[8IHI/)DY,5,H14FC$,I/M$Z&QTJ-DNNG,5[FE +12UO!6!.)[O)'?]XP#L9UU!-F1RO>'3LP[NO?_PAKNTNZ9S#YEOEF.K\11E$GF/# +C/L8Z:*S3L'SQI:G9M1W/9LC0^5N(;4&1"GJO!G-=;U/S.?M#"_B8V +Y9T?<]1-6K >3?R, J)%TN+F*Z$'M-!Q9$3#58CYRB'91T'OZ^B<8!^1O$,FZ38^_Z(H1ZM7,%92B\@U'%#+4U'MSC1)'4 LR&2B8VW3R]QV-XHX1W)Z[% +QRQ-UR=2 &]7.X?L-[U^+#![L80#QLUP+EY7N(7^I_/NOCV&RHQB-9TNP]0)$GN& +IBV5J1TO04A>]+@.43JFUW.(L^[B" N(<]6??L+L^>M%BCB,]M?3F)],$G6-JHAQ +**$LX:EDCZE )F!F^ /Z2H$X]BQ=O6BT5J!IX@J1;!Y]4Z&F]TL*7=!'/OX7Z U* +],_?6\$,E-)F+3KI>X>G=5X2Z3J!!8-HS4KR9 +K?C%$[2GV2;6=J[24GK;MVC";MU09JCTGUCX0_X*PP*O\TY!!Y""PP K]&QAGL?- +W:2!\MIS BEC5!X4V0M#[7=,RVJ?KKE,C&Z\255QF:B^V .A%2?A7P'A_$GYQT'Q +11#>I"?\48Q%#=/^)$1!/Z2Z3^L:O\WZ'(B"+@,=FA>^\@*DLXXV8*1WK\/&2P@) +(JNN>@M%@]+K6?;X"Q+&J6=?=/FB4A*ST6,2!.), MK-]:TQQC4+@B@0X>F3N5QKJ'*VM_ +&X*HQIFGS(@[MB/=Y;VC]:LQ$*4Y"3CVL$OP +IY55M\[;[XEC04D*,OI)\:^QV$7#E7A4>/67J7S\!TR'D/TO]US,]E]Q -07_[5F +>:'26Y*=CXMN%D*M4>WGC/6M*2\\X_C^U7_11^SQ8KF/\W.[0YXI# +U/&82%!FD-3KJQ/T7TGBDO'--P#.H8<54U +ANF"FAF4H4Y7]+V]9_P.3,*=9ZVS$,6,0AB?Z3T;MG-1#).4YH59(D+(JYR-"CPR +);H?8=ZV?0H!]D=M*SW)2$Q6@/W$F:JG(XWT.^SL&NFL8!.&-$6-&,]]"+R%_1%9 +-L1]G,AVC0Q[<"U;P8..X'%U19KG=8L +'#U.=[TX?5ER&"\D8H/E89(>+S8Z:TR9[YD#%E!'Y!S/B22N^3Y\ )B-U*#;J,3< +HFI74YH^ 0B\KDD(A"J*RHH58D.-",CF_%E1=HMULUZ># P$WJ>TW8M$;! +2 /\E&XR?*VU<'O6!@>!1]D.']/RF#@[G&5V%TU/X"3EHKM^]0!'7A.T$@ +R;VI637O*2;;VA>/XZ%;!!!KP[L(2%;CI[M-R!<[WCP;%"2:*2O8&0*;."_N8U[Q +*/GBC&9/^N6W:BRD2L+T6A%=+$J0[#0),SR!?FI5#W0DR3Q>$#0+=0^BBY BDHMU +I4Q!"K0DR>!^Y"(8=6-1AU.X"30>J;@=/) =&R49Z9:SF?5958(H3C/_\W#)P@YV +4,N.X,4YX-9H/PN:I^;'&@2NMF[!<(DT.^Y0V&HR;,<#QX?)NQ3H?WT>^83G!=RV +MHD>1IH5A74CKK22/KX6XO5@F>8S;:<>-CP&BX9$R.^.I+"G[J;N$-/.'2=Z#6I[ +@Q(L'8:5\3.,T3F\1SH![*0C2!O@-)2 ?5>(72 +R4\U !)[G+Y=<+_:VE=*D<"[&WS\9M**O0\+N&_GBM;[WE<(KRL*MRM@>; +_2:1;VZ1YQAB5!6XP@P\FEP4?/FCC9M%0OI8E$#_D?<2Q;P&ZTF&FF?4-)2?S#24 +H.0K1UO*HR20;;&SMLB]H]/(=EYS$#YN%P+M1;N&/2+!S:/NN9&,W:.TL4S#3'Y* +\S1R_<)=0)CC.JRFA%XBQ2HF*MAY_=+J+W@&E<'3#AT^2!:9&$(54N(2Y!!# 9 +X.Y:)_=,9#?J23A3Q%W.I&J:6^N48SD!N@GN4;TFJ-VM%J<)K2]5MB!@Q\&3D_+D +-D\L9[(V$"7FH.:-@L#2:[G-:XBO-J&P>%5\)E:E+V[YZ@ 3"G62LLC@X:.B5^F(FP9F]M!-K:W_I;5MT +-63/WDM JA O];AT'2B!.%@IHFQF'VCFJ_+? +.P'RA*;GXC)4@ (P_-K?5>5 _=WHK^/GNQ]:9 :^FP$CM,)H 8=[R).H\1AI_95RHPD5K(I[KD?':6K E83B@>X(Q:LP__L$V%B/>+IUDX+9$3EH\$%L4YS5G_\@RZ#HCS#0"D55>XF!@NN[*8CV?0+3)DUHCJ+HET5U79SPY +^ 5+^[1 2WD(V'9E7DJHWU%>%F"4'ON$4.!4@P5W%#JT95D1N,S??:8A)_LT,:T* +>!E^,80YVU8??FC>(UC/)6$!3_I%..-.*<:FGQ^\[M ^NM?&Z!' +9W/S>D02-N_LA @MH?!=H8D'E/RP8C/&COH*08X=# )/4J62Y( 80*$7S42W$S@K +S[N5+XB74S)GF>A1$YXN:_;WE9^S;9!,9#*H^!CZY^@^(RV$9JKTIFYU\%.,$/C1 +?BZ=T>$M O[?3NY;80[Y_!ZZA[$*P@K.278-@Z56%6Q(E@& 69]8Q!YQ/V@VMN&9 +]A-.:K(%='?\1X'LOW\O]T]R5R4:3];1XX@J5FBFJ$S%T'V*U6OHS451 :]SJ\7] +:.Z+4GOGKQ>^W><>SDJI*B@ .KI*Y;*;^-]%DSN03YU-%H[%*FU?K28R#/"L.@7% +%PP+R9(0GV:I5 JVI4U]5Q^&-ITM-@/\0V7O!5HV5 /TL>YIZK>SI5%S] *2Z)O_ +VMU![9KJ\49FOU8(!W89:#S!I.>D3L]W4#/'QIIZ8S.D\ M7X307X*=#=6OD,_L* +D=@JX[E2 W4N'7GOU=K?1(/V?/6!=^$_%)SWW?:F[7V[6[S0>,!XM"U$"6"LB>H +,@!AHODA "PAC;1R3J7L>IW#DR)PD(@@:#P+/8\",'WC,:BFQ ]>)^3?@[28'6'R +KUI,W?)!"&3 1-4X,GY8#B!?$;[ML='UZWV+CD=.7 +0"ZG;?<:MRU'&\7Y]D)C8;YS8H\<*8O H8U"Q53!(9%:8M'^KI<+TW"#G(BIO=H0 +-B="MG]$V[,&S@QYTM&J#5Z=7!'UY$RZE$_PPR\0(..2AUICW^6'$U/I3\_^$6)M +RTNT.-N[".J+XF94U.QCX&7]T?.>J,-:HYX82ZPW&'26*6II%+$8*:3%@=.+KWM+ +&% \\S3V[I"=%[DP]??=Y:72846)95?5,Q66*>I^ '1.#"D8T_0V%23*?;O"J^+I +%*Z-V)^/WZT\?=LK.Y=]2/5,VQHPMT.UWNNANV(=#VE?$!H'?$:;F]!/.+1.@!0W +[(0UP>$Q+/5M4??VI?L!NQP_.3I!M?TAC@MK3^.21@T=29JE8D_CX)YK* +=R4M2UO8L;'::L#6C&Q^Z1M*!9MHN).+JN*Q!2__P\P_%!H$G( K2[]W$8*.9"/' +%=9%5)!A_R'^C;<39(9;6),9)""]*&%LI#67N)7XWK(&3X3&,>]F/5&*+V4*&2=L +5K]%HTYKRB^41O6:(6:H36->@' +^_%(,!57QV/)/YD92^LTAIAK7 1NYO7 #+#U5W[O*I/3CFU'.2SB8),*'>!WC+#'@4 X;[?!'4\W.B?6%*18!:>?J_9.'J +[KV)].QV:=K)^I_B8+0HPO]COY$WSLDX#3P@@R[87T.=*6\\+H@L680M0 +PU+(O8,(:BBJV\Y(>S<=D=XL7C,F36_8$3!XM1C0K/1NF)R'067(51O_-F=A:K*! +/4;0W-T0HJ$FS,STFG"U@Q"4,&(/1QZK $_%K.9W>4=LKJX+.IO7876A,UB-!PI> +DE,_X0$$R%MS< %".7,;_ =;W:Z;P9VQA('*'Z-"*@ZNHO';350"LL-DH(L*<@^I +E89<6CS%8!J":G/86K/_$, 37\C%-0JO^ZE-A)WCNJ2?(6XC22-6:@PEW?@F:B?$ +,JTE6']YX*2UL-^T: *8/._P_O@VJJ5.QSL.,2_%Q];X3B%1\C05CQB[G!;XDX$L +P6?YI<6,3P$R&*5!=3LKZ%_/[& +([Q*EE.2I1<[^86"6M5"J#),]KGHDC#? MD9\VVZ.I_+ K-#S)\_+W.UF-99* ]Z ++LAMD+Q(OB3R\-<<6H[4 (H31:Y!HTSY9[83(BHBQD5>S,[RT?F@\P$?<5Y5!H6>\[QU8ICL;6/@9@5_G&?@V.33!/A B9=?:YLMDPG'%#.65\+AY +TPBNUJ*FX :'"CSZ9I)3[B-369*:]AHA_6+LYCP.I\RD[YHJ, ^A=/ %Q>[[CHX7NB +CE\_@O4,45:P-DF.4JRI)Y^&7=I& $E8AS4Y!GL8P-!,/%,Q5*9<&)$-F:G%L\M +4%10F2>5BO$T+%XU$Q""E5B!1)P]O_"Y5J'ICCQ(D'8DE(G<_FC=H<(_TMU9 G="8F7V*BO +V@=\]5+C!CO/N!3RLX*?^-P<,'VGI_/,1B9+7L%HWU(]KY"3:BW<.E3**B6>FD6),01BV98,&YB=J :^ +0EW&&Z.]'R$R!S;[3]XRZ>8#567;I\<7@"X! EE_BS1@6:F12WMRE;UST6)WB>?B&:%!@H[P\$ +LW,Q[0T']V5D3P45Y\5^5J:+9;01!>^E9N;S4$F1U%@3,&['ZA-&Y/L[4JDII'FZ +Z*=$H/9L<$9H\WE@5C +,IU\/-8C"4-HR"S=LI$]S\Q-T/0XN?Q6X>'RJW@!]E/.:K[=H&I6/SD?941 M4G# +AH[]^]T2!,9HQHB91Q.XN:'>N[8\7RA9B6&SC(HDKU?&O&' <<7<0[V(R(G U<(P +*J+^#>C***0LW+:4_1R:ZD!5#C#R2PK.X,> +OD*)P<]L*JPHY'-I]BZ,N.FQ[3?C<=[<"/T[J=XK *PGYP@VC.HP8-P)!@;ZAQH,PLYFWPL>1A35))5G>+J-Z2$16&4?OTE/TF=ZS6X +5#@C-$GKR")SU0FP@ ?;L8N@M*M#E[6ZX:K +C[GYF(J[Y9@[X @;BME@+1L:TOK3V?QA$B3V&.5,J=W/D]K535=QX-4M*UNL\8KP +MP>Y"GYI5'QQV9_%5H"&H)96=PJRP?U)GEY]9?ITN_9>;>)DCW1)&AN:IDANGW*: +8V78:Z2 UA7(5PA]]6QZY. .A4\"P]M67QD< @7?V?\?.8X-F5S?C*B_/KZ;[+1) +!$)QU6Y7>L\,*;5O'Q,VE5K+T13=..$VQ;2_T-3V@\OK\KDW0Y6R-HZ[/(6V_--I +5+F_T[!:7M;*W I"286[ 6SCI_L/6IX*(FHVHGUV-4UG[TW?'%L+679_TU=G1XAB +BB%1PJ)SL%=(;+TE8(^2*?PCW'QG$_(E-+H"+#L5E-) 63'8Z(&TRF>[95M;$W*2,JS#/)E(Y## +AWS'483;XVJAM '37*D31A34<*B9K(CETL_@9=Q&*+C;L[(2XJ6T9PZ-(S 8$VZHI>%S4 JB7GH:.5AOM_M +"0<'6HP4VC1EN\6<]W"XD]1^C2B'GVTH-;#Q\,/>S\%A,G.-%%B4AI+:S=BDX_?@ +)!WF?0'F2'?%6N>P'>-9"6;$=-Q1F^Y77H@Q(R5Z%W_W@$CV(3B,EAJC_NPK[ ]^ +G5J#4I?*Y2CG3B7K+/) =^)22Y]^;P007N-FL+ JW9),0JR?*+U<6:N6=[\FLG3%,\.8Y8FN'K-^!O*!3V]2OS'9B'V*/G1\FS%C9: 78S=_+5>K_1 +U7R-,]W@ "YXV*LG1="X@*^!Z1=J*X^3XIG?,B/3-E32O?9[JM!N)0HSZ "2 +P5Z>D,N.>N$[%DXP(4JA:S;&W;FU* !VAEO7=0_G\3[U4"--C 01&*#1M3[45]C5'7?V=C7,6/6 KN5AJ8EL]&GUH8$A0HQD)[H&)\'2LY +%QOUX7?A9B9 -7FF7>^]CV_=AL\:QRXMG'!62_T3<5[<+%[%[D)5FJ)9%V9^#'E: +/A"L6SFI^ LB;U'[^UKW'AW!Y+8XF:[F\^8F=MKIVRI2K9$?9'74AISSNH&,AD/A +'#XD\7$TV*\'.9-O!\WC^^,AD/&XQ;**>7MQ;_H76T%-=+S:\:;[>60WB -8:]T] +!S)WW:_MI/$3U#PXM*)['W!?5_6S'Q!+-9+:\?OBXV,I7+GR%N04:L\!IEAE7#OJ +;#7%LU(*&*A@.*,A=G)NK]:OB3"K23=^(S.N:HPLG*!@A/1F"#<=<4,E1S8MR>7J +KG:=&) +F:WI,9,K!2I 3@]L0^ 7%P5;594AQ!T'Y]3N#GP?+?_O1AWF )^PIYF&'=GSH:Q +F$3=VMR*"*AFW9])/6MB^#G2T40BH:I18[4Q"% [#* H;Q54:$EZR%HMEQ7\5F%R +ADZB?FIINLU^"KZ*6=]-58\%UB-/S2:(%=)3?<6JU+6)6%%E:%.&/&^R>Z/QXOF\ +@+FLRF46NCT S5T OIN#DE]SX-2J7/_F(>IY?"77.KS*%!2B2'+6<@*NB@F477L9 +U1GRK:0,-FAE.+:/Q4[#WW52X$[P_0>+(8>EP0-$_%GDGS4Y)^#]*GIDR].LB"P1 +Y22*W:(TH:?'@^1; CFSH9)F%4AG%5(?BQ5G!6-20Y5V[_+ +P2C(8NE078(?:'1..2-=^FZZ,8*C=L)?N'A%']D!M[4%:$C\_P/4W@5?DM(6EM/< +WC3%+Z<>] PVFO09JY@S-\A8'[)CX.::HTF-MQ>?:" +0+5W6+R6HZ&K+GVO,QB=0Z!F]\060Z"90 "7NQ2%VKC85)W=>C%^J"C7[;3D6&?0 +B[:WQU[DMYVR+)%FL@GW*?4=-D9^_[RTW'O^P)I_TY;J6IG>02PQ\P[IE::%O?@I +@M?A!)VJ#51]3]C%"'4571AZF'M<@GVQVIJC'#:.J[&O/1F>, ]N.!L1^TUY9. +>RW!D(\;VF5Y/F4Z6O[3#!*% #]#YK(T-20:D50*^QN/T G-ONGUC>T4U_ 5#>.6 +RY#2'9LM$VX3'L/X\2.GD;80@8#9R4?0X.Y]SD/3_SC?>G43"=OPHLV_M(U.LY&N.E;B!&.) +O:@:L?DCF(7*YN]X='U?X6MF8FH*HH@?K=CQHC_>['/_H$G^O/ QMNT4?8J-<'^J +M@SR=W(''KK',4E?PEZA#'G-UAB[ & _C,'85M<&>@2(M2J(S3>' !9_G +;;2:4R"B3JCGU8DTJ3 +%KK?Z%CNJ.]5<3+M7]U1M3?WO_8;IV;89)(3'SZC 6I+N:E>$2BP##_WXHP>0(B"XH=9MM2*PGDL_EN8#;:2%3OA@3:I5VKPH)^;S* +W^EWM0LEV (UJ']8W[ BNMS4W=HL5%F]S3C;S?O0Q* K=!'T$17A:SLEE,RG*S1K +Z+0F6MA283M=2"%K! 0@J $!M>V)TQ+A*@,,:E<9U6ON?,(G$@E_-MQEZ(=IS.% +,9(Q$ ZM71$,M*>W#UU",[ 99#95:PK<7)JM-I-<.PZA.DSL$@5- 50I"_>H*J]M +"M GL$4?B"J#)542S]F<8S'][ZHT,+ T),_J-0B\GZYZXY9176TE-[;[FQP84+C6 +%WC?N+<;A(HNZ[2 J OIR&2L-G?J@^[G)8!Y5-)#9H5E)4.A%N J*9A@6Z)FDB@# +QOO-+-4!BX$,M&!BQ_CLE'P)&CTV9%X[S0Z +) 9MW;3F/!;< ?DI]/_T^5I[JP:&6] $.:6,"=;=;V#_WUT+ZW]86'")ORG(P>3T$/UB1Q D-P#/F1IWX@URE:[L@ 2"@Z682#HR\F- ++ON!]%S2"+R?4B]!(^2&DX*P[[I](]& P0.ET9K5=J1=A2WHE)V&[VU.;$3#L-=:+[-NU$ 1.GC(;C]J(*4W,>J.4 +F)VJ+:'?T6J2^9^N2]8"LPQ9X-PMHNV +=IH>Y;DEUW@DL2C*4 _<'>R0JA&I5*:6-<"Q#4%2+$%@#&OPP&K#T/:SH8I&V:08 +_0>58EC)]3:ODUXGM6Q)X="!YY/:WZ;9)3T,,Y^-\]9][;1DH +?NNDM.]UW6\0\VQ6#IH ;JX8"WP;T.4\)NV98^"?OF,$#76ZM)ZJ4"665A-3QWJR +6%4?K!G^MU:\BPK1*U)5:8Y 4Q"&*54>9&D"_?V-J6]E#&B\&$],I_SU_LWX06@8 +&0I6&:]I[Q/M,>KA/7I!%&@?C%@&6IWG=\*>)+>AJ3MG-7]T5ARG%2+96/5*UWCH +RX'^-.!I30J*1\#0/Q@.C+8-SP/Q]!U,VU5>FAEY4:^%B0HJ/UPC)Q:NG&\(,%"' +1" X,YI !(4$ZI8SJ15T*+V90>HS_A[&$:RA]U&]E$GCMC/*(8M'&?N$7\B#J0)1 +%A*HV>GF M^6'D];?A'D_]($P. ST-:KF7E")Y#$3DX_*ZG&W>R!F:MEUMGOCU,M +K6WA4Y+K@2//T)QP;%P6])(V"T4JTO1[1N"S9S;9-8Z-\_6A;5K<7PX2O'-IB)?7 +T:W&6,,./$W]"-C83G0E-Z;-Q?YK@66VGD'HRA9Z<;5 O$6B<5.QGY2?GY0F>&>1 +;3G@]GZ&C +NAXHWUT9;RLMD$UL-'S(-APCR2'M?V=[F(Q,O3K7*U=+82BJ[G+!B'\L(&Z1X+'? +/&+LLYV>I:-)@\A9Z8*+E>'KX3/UP,; +QZO <8LMZSM$:>Z#Z4!?4@X8/*M&B]1#E=[,(1K,'0)8.2 >?DPH0Y)4PFUF]K[O +.F"@6*)5NFVD# A+>\;GZ7LAE)8>[X^EXU[6YG$90/#:?XF&WB4*N[+"Y!K-!>*T +V+F3$S]K9AEZD(G?;L?-I'525K>(DQ]$Y!S= 6RRZ3F2<0GM.9ZMHXIK5 YL_YI_ +.K6K8:&:8J'+:M#*-V)8(.86=)CP-W)#Z&B$UM.V(H5AH.MG:IDL R9-FKE0K7M/PF/%%>V=9=_XV?E/M@ZA"%=G$>> S.=@L3/OP24VX=ARH28"Z:O. ]+QXQ&T +IVV +>:LW"S!T',%=PFKK/.%4Z0RBB3*<<&K%B/ZF=U YT8\/Y#R XG+G>GU$U',3_,]/ +4.N=+ZL[5&,K!/KJ"9@IPQ3#2U\_D+X%'R8:F5_4]M@)2$(:1V_YAOJ6KP4 &"4. +2O6W6( /L6PJ$F8VW'CJ2LXGYBH6N0I]-F'I]>J5E* //O'&766&T..F2CS-U3/T ++-56??.>^%!0)X:V-%\J$NH[;YKW&\NF='JWFM9I#JDG %K)&%LXHJD>EJ2B:GNY +7C5! /0-\?%.T< 7-CSU/Q31<9@8&>\W']O?>3A![%436GVJA049QZ[;E5-Y!S3S +1_CK0P$!6=*(4-9BH>?%'3ND#2)$.@(FVPW-WO>$?K61\$XWUU@-RP]'0\W;N&?E +#3V7H"863E%E[H 'IN""Z\A.C"-90:RK4>8[N$'=VY73Y3R[8]#E).<6:+PF&QY*'8)L"3UX7 +J0!N;=J !U#"PVFNV+; )4ZB-N23XK^NOY HL,6,(Q>XHVC1UV_*^R[>9PWP+7Q/ +ZL9=J!$%P)?"$#1SNCGEK*H)K#_(V#\)C99)=1ISB,M2CGE.%YHMTG8WU$[;EJ)8 +>=)JZ5DLP( C!Q53/1YGEF%\:(BK]@6N*"NP@'3Q#@?FK=_.E5IFX&WNN],ZO!%+ +;2TM('6N*IFM >6MM15J(LCDO-["IPA;2D(W3NGCIYFNL;KBR=O-'G.A3BKG'/Y +KH\N87<@ZW*T8&&?V1'9X='8ZD%U'Z#8LKKEFJ [$&P]D/GP__@"W(O8A?:ESSF, +(VIG:M$(T>^X06)SCHBG7J7.A29EJO"6QYA.0Q0KEW634C6(>M:= +[7!@5PP;3:-B !8L#YS/&RYA>CO^D0%W-+WG6*E7J\("T'('7/*+*89B4Y>@AY[1 +)P)>+_S<=3R@] /"BS_]@\A("L9.3L!+6+ZKN1R8ZUEX2G)5Y@Y+XK;F5?+E;C50 +Y/"8K&4QA6E,GU9>Q04GX\37_5?FW"_4H6&;!9B8]JASIFRTY1@;X:>*V?MN%;K2 +&3$]D.Q+/$5'9G)HTR?]1]SSQ_[,A05\GYT6UD'$M_S#H\F#;]=N$[C@UW44;/7/ +V8$W=ZU-"[G%1EZ(>B-NHA@K,'.$>:%R$81JF):O@C8 VX[7],IDZAE]WSDP\#QG +!O_]\2EYATOY.]#]%11S:; 02$YA/;G[^P F2LS;NPO9P>G-O)"HI!4- ;LP+[%\ +&U'=/9P=^M")VWS4_'$0 @K$WQ^=G1@--X;0L>%QD[(+&Y%M#?:QZ#K9*#L0B&'? +.J*C!P/V6J30VMEP8?+*P>4QYC7C3^U!&CE%&0/PP]I5K6ZZ\BHD<-DBV\;^M'!< +Q!M0?5MCE4'.5PXD_Z'L.:F:*17#\>G]CZV,RJW&.WXS7*:?4@GWXO_0S&@_MS?) +=(@GXAG]8QLB.5'D25Z#>>XPBLE+UFQ(U.)F)%/1K"*FZ-#KIL_IO\._"52F]G2$V"3PC\! +)&"3Q]G0-N$1._[-#G[@7B7*O.;MF?G5(;/))@KW%K,E]<,7C"N7//N07[M;*51L +430M2O40G_PT)S]+(38??EZ^!X=2P9I7:1_@E<"WC604^%10WLS+;N/#,F= K'Z<1%O6D[$7S1;B60N<>90:N[AH;)_[3WSIIP?P7YP[ [0? *](L-\[@# +UV7RB'K)\=%M6=AM+ZN93[W=U:(3F.K\/C+!38'V0Y.AS$JZ3>CW]U[AL8BU0"A 0FMZ\1>9K +O$R.1@5AUFE=*#"K&7*93]R&]AK@[GM RX.'#9TP^%^L\;W2W]B/#K5--:#1 +<:#:_+!#,CW5!'YQ7-C8Q@V;_EL:P=*E*Q+0X2GS&'FZ)]X-:@"1+=#8FR3H]#RW8P A!EL'#%6*[9GE7>XP](TQ9Y2AT@?49__XES*5?WG$\I%^1,Z+VLJ,T^'5'N%H>ET.\D_2I6SHK?"*SL+3Z +6,F2\HJN<2ZU7YUO[K>F%]Q @Y98_F%V@G5.#E2ZGUSOJ@\$*P^)N@)UYYU1%- V +F(0ES>#J69%< (0+C8J8Z)1S%M1AIWT6M:B$&-4;#OBEFDDEA9)T/MD2$.:9BT6& +OCY8@-E1]\X_]TTSI*50W;?X\O1I25YT,(MAB*^QN:I3SCSJS$*\QV\EP +6+N%.+"&@&2)_)2?/FJ_8JN;G;NB)X%HL\TL(=QP/B]@A)R ;NK'7P4.*C3YC.N1 +G 'RF#XH!X+MOTK85 "IN28;*Z9!! < KU1A%%(^LH9B! [SCV?0\Z?C_JNW.D./ +:,BY4FOX9V.J7J]:*P8@TRV8VIV#I;DZV1< YA).=B+E08=N;IP_'C*-7XN&Z?]+ +'=GT'I8%9^Q,B>32?VM5? HGA>2*)Z85$ZEWPX,W5B#4=W7&'$?*U9OJ4/%E4RB +TROHR>3'NNQMNA]X0)CPI'\63O\91T1%Q+-K[X59+OE))YG 2Q_D\5A'-6\]-PZ& +_,;B(V5NE(U!M! -9YT!PO[ 6Q 4I_U&4CFJ'V>CH^82GKH_;?]06_[2%^^5&N5< +I@C1Z_S/NQI$E+#Q^H!+V"4!^TD<^[;=,"@?UM1:@4G!?S\I38N&NMI Z!HV>AP5 +"?1QM,$RZPC%8M7+:[N4_-&*,< VI74&DG/ZO"6K?E/\2M.(@ +,N%W7#U&Z7/(E%.WR#,M^P\?$0Q77.%K)L1706T1\.^0J#&E-/RG %%IFARK"K,+ +X.F;C>PH^E8HXBKDGL'AL"Q9DDFNH609#]'0L4;""W)!C<-\@;@Y3U;ULF:C.7OT +*4VR#E3CW*H/M0@B59ZCRVTZXM^"IQU1)\%P4O!E6X'B&]'K9;Q^GCX>TJ=_0 +;]*N#'0\*WO^/02:]'>[NEL,_LUJ=B,W38KWROU.?QAML3[R0;W)_528JQV"/B +3QX5A81 (1+!T0,Q5N$(E\*B,^N%J6R*YI\I'G7\CKUDXIF2GY>(NSOBN?*H00Q+ +AZ\IJ<:\OLN!6S"__J>=F5844SQ,GP3BUI#]))D'DZ%ROMPTM76"&D )(I9K*+#0 +O+(1^>;HPE\=KSLYKP7ZJ4I;"[8)T67((P"RE54^^](ZDX^-3&B7\&$3AQKP+Z6G +56I(8QZ61#DD6FJU8:P-2,'Q3X*(U.$F.Q4NT3?0)""#:E&'[=O'@K(EX?$JUG5" +*(A>)N(3:1$+^*W]^+PXYP^39M;:&T?>'P+4UJ/N(_ +*]L5&5,L5(O $+V/ :Q-:]E,MHX)1#WG@+^IT8( +3SA:JVIL P+/&''XT17-#4N1+C)NY^YRS9#*%>4R3HZ>RJ)U*A33V\P.2!D8P])8%M? +#;HZV&OM2T"&HNHXB?III[O\.=H/A+:"FGJ9'()]M L"3LM(=XALV7T/B53, R,_ +*_!9=[S"OWOH1Y%_&W9]P)'11JH\FBP9,"Z 5J*: #%R] '1U/O$\F$V8G7E4EA: +UU!1UY>[U,Z_5NO#D7N9/J'DD3F9?#+GZ7>$GLL%L>BN7E,1@%B Q'P*+WK:$YVS +@4YIKNH-N25[9=%[4CC/2CJXN8M1UAVE+Y*3A"^LF8-AZ*3)+Q,\:6#!Z4QKF:#% +57IGIZ-F:1!>#JT!-PN4$-%\1QQ>SP7W(NB'R4B':-'!EJ8<"S?[/E8)^\7I&C?R +&1G(\71>P/;7AN0H\,T(Y457Q7$>;;]%"N^=,@,V@21[CKJ>A!(KW[WE2*3+5GZA +P5Y68UWDM1A^4"EYI8<5E,RNJ39%J\^=%3,$@0C."G3I9DAV5 <\O:6% [R>\5I9 +T_$2VZ?0'Y% 961[^'*7A)>;L4.J\,L02$T"6GD:71UBS1V%G\B=^KX$\U4W@ )BZ.PM]$&QXJ:Y=R-# +<:WF[(F/!LV/'C>[ O[S-*-U6#J";7;0 Q<[N\VJET>76>::"K%,(%%+6BOQ +:9B2,7?W>%( ,".(JM!J KI4UL_U"7N(0 J6!G0BKADMF&5/!U.$J6Y/&:6(7@JN +;WDH($QJ\5 V:5!&=4Z2F9[9NG+?R=COV)\&H!BO^$$=_M+M:RP2.IZ48NOZ-4F6 +[!SC)C?6@(J2\(\I@)=J)(KAO/3)40IIF+3.!US1;!OTDF3+%(.(;WHB/,495XUG3[S8 +Q!BT(UY-(/Y,;#:/9/9 <'[$?M.\GW%PAGU ) +A>,VFNXB>5WV<$JY/BZIN&!#A^]>2HC_*GO*6 [9V)]JU0Y;-H-COV>9&(553SX8 +6XF +_[\0P,FOPX(XQ /,'+>SL+3%Q2T:U_%/&,G2=/X>8M:9D7_>G7,'7K>]ZBSUY%%*>99/VC^FD:;ZDKPHETBBLN5DD\;#^G+&?>O +"]]<'EO-(^1$?%"J:SM,"O2>&FMWIW*@=PY&I9>RNZ[>^@6[E19C^<+UQ)0!K49& +&6A4 ;J^4)@@[_)$&JDWACRWLI"&,184'1;GJ:^T^A) +>JE>61UMKJD6R_I^.,1@AE0<5<[= @UIB%&]FR&VR@.0$3AB520#IGL?"5.FN$*] +@"=5T1B<8YZ(GOQQ0."..UPMA4?TQK?/"@I3 ^ 9Y8EC@*E%: %'MWKNWIOPFV*? +:AW@""(\75& =W')4X(?A:5W >9T'2,>W0QXMLK2[6:=P(N1HI$WQVF50P?B6W=8 +>1F,5B=,?X$G@^^N66N=4D.AA;U6K0!<;X(3U@5WLF%J.D + K/(4[O\T@?3\B);:+'"JG\K_1L4@'2/GF5)":\"GO:=:*3/DA)QB%' LB?C=[C2 + >7WZQR\['7"VI7#2V-NV;WU?^:[.A&3KS9@GPA%#+O32& FZ8)/RF]BZ D1)<5J +R_CA^G"6(2"6QU'D-2!; ZDP;(OCB(ZCCII#]B:"6+?@2LI4: N+QMAML#&.4I;SU-KC%.CU +9[E;5*Z\ J(F1V*Q T:3"-1G H,2<\6J.QVJ /OK)7+Y!QTIL,-"5BK:]2;_7B;? +NP3] CY77Q=WY3VN9L.J\7,-7%UM00#L-.FB0KGZEE@YS-][]H_2, +X/+(&1""L:G9-*)C[=0"DP1V\"_EE3GSP8X3_X ,QJX?>%0^KYA(MNM9!P. +U.0'QHRZWRKM(L0L#C+S&PHJH:$PCST+EZXW5]G#]6+F!@/JW +5V\W[PMR\,MUJBGC"TRNQO<0&Y][&N=:@VJ-"(\MSY)>?GDN:$-+T8Z;C=D+%%%G +(E 5 A/#:XVET($GI//V=)PHZ&SQW/J3^^GUD.& %6JO=:-&/PI@SD-X2Q-N@1B%#(R_4$"MAS7%0[L3[EYCSV#-E7#RVV* +6.J-Y*4BTTP%?K(HFL?]Q,[VMUU.)Z:DF$$KUR7_P12'-PXPG($N (T4MQ-^(E2@ +QL7Y,_7]D[<*#VFL;R!D101F7WB]CF"4&REMG:!Z:EH"Y3/S2>A/;3-9"':F2,"F +76'AU8LU,^5K>1^9?]E6;.T,0O ,B6V#'2,+OWM)^NVL/+>$O6%3XQ2];D0:[=;< +5ZC#@PM.V#R_X/7P?3'9\#A\NL$GXG#F[#CH.W"(DMG8X!U->O6OAD&SI#,@_@\7 +=K,XL4JKIWF<2R- (=.R%&.9G8@F\E(:?2OWL=D99=]MM4 @+*_P.T, 0Z,MZ*R*N9VX,.E_'\+YY79ZME +$E>?>Y/=OMSTFBDZYE,-ZH$Q^G&1O*+XT[,&\MK6EN!U=.$ 7344AFLVR%]&ZVH7 +\;DWNJUJ>B2EYL=G:E 5I@W_:A>C]+2K1FY,N;-/N$W4D_!*JP9GC5]\1+].D+X^ +&V]IV;B5?*VPU8R:I(TQF;*['2BB#UUC),V. Y>@L8#V_\W)_B9]64BP]&DYETW+ +N?WSXE98084>(\IE],L<2U!-.MWA W+,+G#F_LR>( ;KH3 JYC:PT/VS4P-^<07*X]OF##_!RI7J=9:T'[>KN#JO)IP7?.S/4D);="8$F +HC-/K;VTNQSG2.9,IV=KP.O/ @K[:?6BXN+*NR71T'A./F^"@!7D@O$0W JY,PCH +3@&[FW"9;#)(.MA<%ZW $H!M9G*DB?9AO5.\C+7>;"%T)RO/S^\.(1!LR/). +5!#E+RU>L[.S1F[1.;7R77"=@=R8<>:P.F^A3]G(=2D1]C#^XMU-N]193($3N3U$ +[#)C^10LL!;:;0%G' QN.FIED__DFJWK]XA0A=#$&W=I1*;"0@K]*7#KJ#9/H2&C +H*R#C_!<\>J_;0,T0N?2(WDFF82,-[PRRNV7XS.*]'L#5M#9:Z1H[(/5+15$%&?R +93L3OW4!;9:3U_C5]6GX<,FAY.3H9[2!9\"]7338&0ZT:;$75B*3]'@*#H&QTQ<; +B)KYTLH]O_EVKMVQO)=&,Q0V;+0FR$[=MI+G2NBG"_Q"G"=>^R\8E6"$=WDA]11X +B:QOYCZWI#\ZD:W)ERG3*Q?Y??LA0S([,C%INVA;044%AP= +)E\9K7B$])]BRZ,8N*]X02%B3^;=QDP.!WLX]#?[WALIWZ-VRI[:^,."*)0@1JJ< +V08URU-&1)^8L>FH,K"5LIHIJ1#YPN(["W!W^IH.4*N9R4O'K>)N(ZM.1R(&]LO- +,*KP:E3HD/G< *_X^OV'/MVL?QVN[QJY0P,FQ9&;B4UR,O=Y3.@$/]IV/>R3D=WP +9B_?8@>]47&:HV6@ Z-U;F^B.^>]@J<-JH8 5C*2=?L;B5]!3P(_KF$5YK>6G%(3 +8JE]>-P;?05T!2K.M5,Q$$PFJP"I=J8C9B#T.1/A=TCWW0_(9J\.Y?$I?79*OKP= +Z^[(YSDM1$[1"!:SB9BQ6.:-HL.5IIL*^18,L':!!MAA-=>5BVR;GPT3ODROJ.*U +%/V%;_:W_@P.ZP#][2^_=L+M6; +>1V2=ZG[<5D26YHP2%$I_;3"P1J6GA43I$_-E#09-([5E5_#Q][;<"JNGS9I8:D* +!8HK\8;>BJ'%;_7,S .:SSNVX'!? +_3^JSB.W6JLFRAPA'/CX[>6_3:]=NDZIC977DBXP)ULB[#:2J48 D\>3\"(2+EZV +H-C77+!!Y> D10:E7'"R!-L)W$UW*],:+9W6#I?^'5-9("M0+8JD^<+@6MI!+?U3 +9ZC6K&:Y*_V-6GXCKE>,(#+->0LT;0$:9EG_#7'%R=^U2O3YHO?87P57_6@LO$LK +C)%LDXA^9C@2]&K0(!L:G7@U.)!>!:*U@R_+'%@J2QVGY"!V58D^?)=OWNA[NR^! +&&);NGV[=A9RA6DGU*WO7--P\5E15 \SF;0OIHN652MY39(K\D6J7*%**>!HBB19 +EQB91:13J80_1THX7G?>Y,\[O@*3%NN_*P/TFT3T6[D1$,ZQ[,7QUSCZCHK8] +'>HPK?CDE3Y\9?U,(JTVLH +X[$9_'*COWWB_@7KC9?$KGN-I?AC2 X' ][*=KZ#SP7DP>'Q0J53.JGU4:\7P-!C +BP-\%]W):&OH2^ZM=>=4QB0MF!CM"Q>E_<3(I][UJ0,T3.=@\]ZJO*G&0FQGE0L( +5%XK4,9_^5 *O::3H_(V4L 3LA-*+=*L__M;7C&3\Z< M@N_]<:R!Q9RRW RE<13MS,59PRU +%!1>O<6[OTI2U[\H:-O<[C?^I';5X#[%2D\4'MUA?W]?A(VZ*5V(=6E),;9K[5)$ +KF5R"C,$/BIYV428H&G6,]K71;!M>3%QC'*=O>A"/6\S_%D]3C5)C_\NI28TTU": +]> 2T06JAV&)>(:H9J^T_H[&U">7J4*T(R[/7*I!5! ^K:(X'.1>8,4:ETD.,Y1!V5_RK4TEUS#1;!Q +%J87H6/">^!I7_[98UV&QT^#=7MY?TW%A.QXT-E5=9!W4IB*)/"./-]1H]QB'1I^ +Y3[(V/=7SV-DF%ED19'4'-NV+?XP"0!&<4Z4-01K35HZRC[_*&;KYK7J8D;-=B)> +NH02.7.M]J(/9%XY38ZP17708DM,TF0(_;"?VHGG-3_!GH%=]4\15H +T5R^A :9P3F#/[DK=-H@R^Y+4/2H\Y<."#2 H'Y7B=."3 +_?;ML!J94? PR0^=\[GL)^JEOYN20&3;\X\E7+MXC(BQ$C9C74/(\?N8(EUU6T7) +OES_&)(&>"]%I,K?(T+VCU%V5^P4,Q]9'79W&?-;VZ#A@+0$.;%HUWR1<3 @3MZ#C@?-3=,QTA_- +#ZF<< F%.F,=Z5R$-JX^QWY1*82B;:Y?8L WO=Q"@.QF0Y G]! R2;$LI@+HJY1K.&&X+;D23H3\%U'*YE32ST( ^,1LY)\R.U_I7J.,' +CWJ<9/JP,L&-*1(^,O"<[Z_ [8*9%$ +F-[L8IF',K%W(F@BMY)W: (-I[$<#:MSHN3;AB_40%;#!6?V 2^C"%Z>WNGMGSP1 +T?G3>WW$-T$)E+$_O[["E3OE*)+A\",4;?&?=KG'@+/*JO\&A9/M+%CA_59 X97] +5:3 =7\3>R5%IK+TBMLHDW_-"=N87:!]2W>%EV]SS@30#R0@>K#(T199B6Q)NL'R +/]Q*/0 56T;5%L?I>/3"\.A\;)D_?H0P"?\^"[^2P)3'&)3MER(;,A*#QME+DZZV +Z&>\YW8;LP+8,)]_^+G843&Y;>%P49@X?URTY:5/RF"R+*TYMYVDB@6SP_^V15C, +W]D.U?HM<2/J#PV-PX47!D73#X#,?+!'X"T,&^R_+(J9":M@30^K>*8/>DMW,>A% +'%BZ(F]NXW[6:LST!S@4GF#$X%W>,ZW0R,F]&+1T!2ZT[A% +($,2.#\M@M4'S7EK) BE$W"JM,A,<=IEOT^0=6.Q6+7<:@?SZ1F!K)U$-\QR\6%R +DU60. !HQ)E?"D\.Y)\:=*".*,V9\5_N>M::I\].P)C^>GY$2]D5;1M>^1_;.>JY +B!7:3U;PE7-UJ,0&+?7W'[33D,QM;JUH%X8^ KF 4@IH^6_#&T$NXX5Y'=5)Y?>N +=C2&<6(Y6^'\V]WB0;Y8R,@0]]VI9]OBN])VG(\-8 Z8K+TZVT;M-@Q0*U.:EF4G +I3![SIP/TTPZ4,D=>F+WQ9Y,;*8S7D (\'%9?&U*A%VQS!OFTYO;12K)3#) Q;\= +S6N[L87H$W]\<;$ ,8 ]S"2E)Y-BL5P,HCQG_,#&<*,)6HW-8>?/GNO4]"AX3H\: +]^IT@=T?LCHJ]%\$!>TTSKKC6UAUY#=,">*+]; 1$POHLWY;U]92U;DKSZK\607JOW55#> ]/9>C"Y6NLBG:M]_=3K =W5!5&60I3###!>74)#_9EYUSUR_'^= +30*F5-!M<-2P,'A[8T.C17@_2@QIF_J2G?/S;$[>#F,Z=O?5@&5WI*(#*."3L?<5UX.Z6Q9;Q[A.D :18 + 5J"AFZ8A3R5EM>1)O%NB=L 1\[)5A1D[:3 6X4 +*T,S1M%/+!""K>E['73T%Z3KT%.-\?MX[3GFU@(C4!M?DH^Z.BL)#3:[YF07>>0[ +!;86I4G#R__L'3/M.TZ?D1MY8HXD3"VS] +]A$C*1C_=C@/I0YPICC1]AHTG6+UI@AY>DH?6,+V@^S:G+P\Q8I,%)A9M(\#;46H +DDK7#]MA?JM@>"R)7"(_FZ_#KT$?8)3]'5^FET&C(262U/U*2G]:[THZ5]N8F?D" +N"Y0WHKJ(85*;"\\$,EB(KVGP&SE,@^V,-H713J[=8UX^ #^R7AD(ED_2G];LMG> +&Z8'#+N9WWQ30Z''7V8\BEI'),QCVYT:+1@Q@1102DAYLM?;U#&+8WZ0]KT ?F]^ +MG(:#K*5/W_(GGY96MRF<-Q6?/E@\W0N[5!C*C1U:["C9>P99_YURTT^) +K\&UT-QZ(CJL)SKE^")_6 +;3A+^*BQE"UW4S"6^!'J+LEW*.YV!>Y0U1!N2)%M_E;#%,#0V!-AJ5'J>4DT%5#8 +%PUG/8F']/!G^J?+3\&$#=K:3JLO)#DX0>AFV0>=KDH3KZ.O4E[XLQLJ#'W[79%GY:W9IDH%?%9U#M*/7B2[*$XV95!&Y]'2JU*VNN]_T+<] ++^7[%/R(,F/<\=SA9&\3GH/%9,J +B ":[UC+LHT^'B<6A HGCD#R8.KARDO]PO)UD/09+7A>"B[9D +?IOA00SOH F3*6?3Y>G:^9;]Q'QUN5J0E<6H ?R26^#^A_>3^S_A9MS?L $8ZI:: +9GRY&(\CYBAJ#]RL3M^8(]K<9KS1MD!>TDXGHD8,D^Y=%_MJ0(NW%[0%45H.QZ=[ +_9*ZW]AL09*6L#?+[/SH.1%[([-F+LV( -0J#BA#C4196I+CHHV(V"Y&=HPU)")9 +\:=Y>%XOG?9,PZ;.NSZ/MC6! E9JEE@+E+2$N+O]:6(U;#=6E1<<+@A: +FD[BEU!IX+JB<"BPDJ+1<)O=(@B_E_9JF8D X/:\5C>#L@5+OZ,I8LDR)-G_?EEJ +PZR\(\"J;:& ]*!FIC@GB%@\U1U575>J!7_?R409'Z!3I$\6S\M3-T<%.WJ#]]=" +BS1*LQ]Z/[' 9E85$RN\ %>F%_-HH$<"!MP?_*6*I#G<=B_IQLJ:8Y=09+)G%B +)2+MAS"GJWT*V0^_;GF6AP:_Y5*[D7]M$'H9[PLX)TAI=\RK4WS]/"Z3GF7H8GFE +;_GDA+)!]MO6#H92^K$'0_3'C5#6L^[2408?B.WV?'%%RHNC-)%IV;[9:*N#&N?6?V*D* C,86(SC+6Z1V/I6*.T9C9S"N/!/114:Z:\U +S[O)FT=;EU"\G*X13>)^^P'C=,0K:L)JF%([HW;V Z59DA;E$;'$V-W-W#)+=*5& +X>^&2X/X0D/6,$?@K=Y6_$&$R!%(P/_//, ]Z5Y/0FTMNB:IM03*O>![$CPSJVW5 +M%X:ZI7TYTU'J8TR4-4UJB;N^+J1=%Y/Q>4>*(Q9A:F]SS?W\KJ^.+,ZK! ^\XOX +4R!*/^$&\:G551LV/R#,UDH_\E1_LJ3*.Q4C5*-)C\>5C[IJU(?,"G9X!$EM7&LA +LL>&O;++=F^A9&!T1X\I%<'4GR<7C=5(]J?L(W\=_'SD!"'C&9*5K@0K0P1[+7!()"M>&QT&!>AY"IS^9 / 5W +U^PR44*5:Y\VAKZ;BX\)=N0<8YEY?B]>8>/!A?BQ)TST8&&%U+H2+,DM:.V&4GVP +GL4WLLNZVTZ_0NML1L.E=.R$JWNMBS<.CFJ_9)L;4SA*<2Q(]8/^J H3!MI-+JVJ +MQ8;IGCHSN(C-G/GBL[,W=:?DH8 +>#PH>3A'UR_*MU"W#XZ/'3.[D +4"QKPMU"B04,-KFWYZ@J*P,BGM6T8OF$T#R5Q8TU-[#KGTA=J]P@;PFLB0FO1':< +8N-/,>H$1KWP+*##=[$^2EX:*K+?^/:DK(&^ %RG)-!=U2TZ##*""VAJ 0&C&596 +"@9J2M5NJ[W%8YM5E[9]+U(]9[<&@,5NOB?KYTI_G)9#M_&GQJ95>I\/*$=@]8RY +R^&7J9G/>SA$'Y17+XTWES:[S\=>3I9]\Y)9%T(*BC%?W<^V3K:D[4<#C'T,I(:OMP %T9R( +Z2OW_W?IA4T9PA P.88T=//G7B/&NXGR*IL=E&O]X(&=E#?D$/B&P(B'%EFS.7NYEN?V\R4 4/%AA"@\Y$?;04=(VL#X#ZT^R9-PJBG<[#/"1?@AM$FPA7 +384=' ,O) Q":0;_+C*W=T0/UX;*L:%,+'@ /L"2^/<4!Z;4UH9CH-)N\XVQ/'$@ +ZMH%:EL6M[PHSI]F?^DZN5%SB& ;>R0N41+TZ=-/#(==WY,J-H+:!$8>:JGO\NR7 +BHA@X W#A4C :!Q5]F/K]-2X4"QNZK2O+UKD7^2R+&4ZZC2X%CAJ897+[F+C N_W +?_>AF3+9\=&P;+9.H[F$'G0QP5VH,KF[L(&^7P7GY06P5/Q;=D0,)!I^AD]>K2,^ +BA+AAJBC"4K[)-'PXEN.,!PWT,X,B +_?M1[-;I $&7E98;QN$V5MHLC6Z2E.G_;2>H9"4UY/3'AA\H)\B&S2_@_#P2TU,3 +BSE[;@9\C0/UU%V(SA0;HFJZG-AQYO3[/!+9B)H)QG4\5//LMIT.%"QJ%B#:D)]Q +'$&.(GD6"[*=E8WRSS[VSX,>G:7;(,FK:X)VZPV5DJ)P[SD/=V6C7R\;'P/1 +-D$(7E7K=_8P.)&;SF=A$62-%!E=.BPT@JMO+LZ>AJ:)$9LK[E[\OJP*K>^E+Z!! +NUQJ1^U0LG2C'PISO/K,DZ_#(Z?AJ.A):8YG@=_9#/L-P_<-6Q,07%O'ZF%M ]!\ +:%_-%KF8?"AYH*:^[?;XD[[%FGW7NALGH_]Q+:^L[(O>@S>^16*PMR4Z(C.^W7_L +T?99BR9;VK^:B'"*2Q7E<'U WUL:DGP2K8T!T9E&JY;;M0*G-E$ODPFD$?>F0GXQ +>E"!6VM\#1WGXCU:@JI!5)JC1"\S0!#I\63 I9Q*& ?-KM"*%-L3M4VRZU- DC@: +B_1$$X+GI3* +YSW;(VHBP2XL71IV$UVE2K\#D;G^>!XG'QV$UJE/3OVP!>>Z^E?ACOV*R;%?:<89H>%;>WX+/.8FO3S4Q7&LOC[8ISB XF2-$ +J*#PA61U]8.5,*X-;(X!_@S, 0HG=$WC?I,O:?TBQS!#6("2BWTO^--=R$EW4.QW +!2&*&5/> "K/4,!QI+<8=ZO!+N@CN5Y.A( W*YWPKCD?JL$#(7_Y2-JZ@IG;"5G6 +K3KC"]MP=ERP,MN2C>K@"-_QYN*54,9[R*75Y+84$A-?J>S]>'"W$&U4'9<3K0XP +^9S6/*W#4[5?]VQD2"O=SUL]$=\37@,J.-]".=:#"VBF>V _"= V^^5M S 4H)X& +OCS T4%71$5C7]%LZ=S]^P9\L=]9"^%^9CQB@]GT0#W:(0D&FM8BT=Y^B_W-'L)! +M4#*\K!XC[MO%JTLM>8:%"ZSY1L1KUB_L4^ZIHQ%FUI74>GDY2I&!"WBF";XZ/Q( +5U!Z2_[%8X2(PSQ>89I&:"D8MSE?&U1T#MP9M4GQUJ+<;["\.&Z5,10"1_(4T1@"^.'WYC@I5>[4M,R^8.\!O +\P\CRB@3R*/KL$,4LO$(ST.D^*ZIPW+ZL:8(W8V?4-F,ZG]1)+)O>NYX\+YYH(BZ@LP6RN 6%5JP9:23F< +FZ8&SJ)IVY!5., X(YL]72;!B6-6^';5LVOPBBQD5UK;5RO9V(AO +8Z@4^N4\K@T5.5QZ)>*8I"0Z>A2Z#-)1U$@E=C=2_TTJK7*-(:TQAZ(#= ^MM9[HAHCNW/@VQVD/EC)NQB9ZCI;1P9'BY&H +K.K";2@M5%E\5%@T<46Z,#. +$[PN7"-3::2[N:GLQJ Z/&I]K,]BZ7])'[,P:HH.TA^+ID#SQV>V;B9/C>IN#>V$ +$[OLE!N#98]U\E*OR3BOQTK^P5YS;,T=@__"TXULDT=_T&LZWL_DA]58RF+\VU9: + IZB=#:DD+04](7J& %Q4X9E4L?%]";%O(GOQ_R-#BR1/G2EZ!F(VG@] >AY#.=\ +VKI?+DF4 R@3I5L5M \S@WO&T/&"HVIJ/#GIHT +8$1($WX3 ]6A0]Y(F'U/I-R[2V-\NP_A#%@;X(&S'V10@#9H90BI +9>AM$S6W*9CP\XC[_QU&D.B[O)P&O4-72]@%,P7-] 9@6X NA'":;4,GP8&0.(G +^+S4=X<86D*&UGT&A%/G>))(?L#$_?SV+ /VE I? --[HE#HG1G>V28S?H,R\I4P +L-@.V)$.,6;_W^ &&(I(YU'V+_F [>BQ/^OTT+0$O&Y?%18J3-@#292U5BZ!0>(; +S74A;BN=ZZ,[511$/W XN?04;I9>WFR;D!F)+T\46!O\X);($HB3LI' +Z&R4.G+#YJKW?LV#^@F"F7@5(;[X3DF!)V9D?SK*04DJ;@J;?@KE4<^WY#O&^;:U +!M"$\&E_WHY-8"OU912BL]HB5'Q4P^DO1U1HPHDOG]&XUZCYC6\]JE&D\BM+GCU- +8S,+J?VJ\3&_+[?O2036B6;+=X_'N+D6YB!?@@'F$/S3Z7(79']T_+64BF9^4F9W +N:&*YFSZ:G"'U",^\1BGR%_YBRX$)YGWZ#M5%2*G_K]^WQ%S Y>&552FSGVKN7*P +Y^CDX%&27Z"9C/&WK@YYZMN,T,'SP#75BV\W79:G IA_!Q0*-.,M';EBBJ +=TLK 7B$I:=WG6'LYH73VH[8][?#NOG)D?P>XT<73L%@/26B +2L>CCD'IEQFDK5^+1[C9^((;#F D#AG@!R7+?MLN^LF*0=3Z[SD4#^;Y9,788X\, +K4-Q="I";L/F/=N!VAK/4-[W>G 1,C=[=!ZI)_=V+/.B"8-XTN5-IQ*ZTR3J[@SR +_P$!)#W+4\=]H%NC:8L7'2Y;O+\OU(Q=MJ8F?X#RC#%I;<^CF.%T QBB]]\WKPMY +8&D^7H4^@5I\^:*1@Z\,KD?A82/=;R6BQ=]? ^V&P%@YV%.](_6QRI: -?@8]_U: +T-40RMG'_KW6>Q2!0^6=TBR\&(@Q'BX5)6L*5;5Y2'4)CD4X@5PDZU6Y6=?(?=M? +L01(>QD(8*<)&^\A%":LX8U\"#0<$7Z#M='"\$='%&ZSAT(#GUJRF=^+#8)-R/V5 +G?&&\0)3F9;4,XNA&&7U@,E0N75AC3E7^P\#KG_>H1;^/8^]WXCD.J8BKG%AN8@8 +N3C(#0,Y;*#PGX6/2]?=LI7>^XECK8$W+I(G4HD# '*_N,T(V;@KH?PS,G':H1*U +,M__&(XNR3?;QS@V"Z2D*86=-">':;(WS:4.N1-/0=1P0NPJ#G(,R]JTB1R'#Z#%R +$JA) M+K3TGT]57P*164CH U,9/Y=ER]5O!FDS%64B"IL8Q<.?9ZX'&,XV&( CK@ +U/3F?O/9>%;O=#"\SZUQ1P4\=+:+3FD?O>9GQ@R,EC8.G!OE_Q.J"*IR.\UJ(%'RZ11C#5L6ZY&EW KK'SUY0..KA@[O%^H=*CU%VE+1A 1 +OVFHBP<@6QJYL>[S3_JY0 RE 4#,R(?PGR6B F42[ S429_CD'@_>&TW_8:BG_(C +I_4%=]WNIE#DGIPL(4[&$M[A=R%K(7C]);L1G,IB\ VO( JGMJJ,,5^$S=9E4UGV +Y- _O#9S*Y7>/>$_+(9Z$W$BE56@,V:G??1,EW:Z0A;@OZJ8UT\*U16Q*]9\:I?T +N1D4M=CW?:^$CJ0<1@*E?'+K&L,[-]L(L0GE\WD9-^?%[S#6!O*; C8S13NBP@B* +3C%+H0@.F3JX'H'V)M+&/P0L_D;[#)JP;OR^SJPR+PU(N@.;78S-N$RV.Z3H]RI" +]IJ"BG*R3A&DZJO-$6M*4T!AA7A=GA' ">L!7MF56CB\DC9$7/,]; +F'^"H[3CS34/+0$3!^2!6TL,Y-/A!V&0#N>JJ$1M:8=N_4@365$TU.CP:V^<)\.4 +2S>LCCWK/[WWR"ISFS!L<[C958F7Z6!H9#<@$\<__K?CJ3W.D,,:#FB._;4.Q1%U +M=?AW\$ A#?Z,.& A:(NH#/Y-/%:UV\)4/V( *XOLPFFY9<0\& 8"7,41='(8@* +?769#!-W&S2[A\8\#/:8W89#\Y;5OGV&:C]9\5U1W"!$C;$$'^#H;K_J";0=8I=I +R4U:[O)MWM2ICC$3,Y$<0]Y>1&9;'F7NRH&/30R.)VAE(D#XS@[+*V] +M:*M52:RV(#48*II!)1D.-5Y( E.[5DO"*/9M#/TEN!M7X2;T*G$X;U780;F?=D7 +='2S_M,!WQ!TCZ1+QSI'M33OTWA%(L^VRM#O^Y6)6BI%N10.CY1M$I%VE6T.GTHL +X7'%E=7P==Q'IXHWOYF6 X*42MTUX1V''!K5AU!BI^[!)-,M!;@DN"G.J 26PZOH +2& %)=A;"8/N@BOI4YYK5P2 +(%[2X\&M%C9;G-V +;*N,)D7!S0,P(+V%7[)J%)UI6=*I"M\2MN+/ ]6)+GD!$3;R]$]-\OV!Y\:)-J<+ +P(N)96DL28'9T7,UGH9=N\)E_Y*]W+Q@3=D62-.ZO5)^12(.NFNCWZC-). =DRE7 +#KC](H\LJ7!\X0C4[3I8L3K3QN2!6S74R/LB-ZL08D9IZY5I" &,,*O_]OGMY=I/54[S6"W*J_#-K47:R[D2Z&LF0$82RN +N>.OD_ST^/J\@5Z'8O&\*0,M&-J47A["P1QHFW5E2+ _:?Y:38@?='GB&_^,&WFL_ NLVEIATL'^(^CI-+3 +,74_K=79;C+-CIRE]#@'3:Q6IC_/"Q*@)6ZHC]N]U(\),&:#:\TI6#^XLCKS@R_E +^V=">.YC@'^OT1]/,KY<8(AJ+UQ? %@YOE^Q?5.)[+6P +H:P7F+LM!U8*A,4(WWC-Z0DF5//CNS*N:WK9_J]E[1V]RSXSY;Q\A?D+T)-=[+@ +7@F7':/8(;,DM'P[8OF,R]O!N/W =,/ NZ8HZ==QP,PIG>CN.4:[*ZN:ER">E!W$ +B)C_BS+@9AZ_A6V5U!1&00:Q5R6:"*+PU$OC3759^W9WGB$2=,UW^BSGGXRC#M.# +"]R-LL\)30Z=R&TT641SFN&]N0N&HAH7G!]!7.SA91MU5]<)K;#VA]63!CZ(XI!5 +=LD+CJHW3&Q%%#0=DM$NB^V.@Z +.!;TU+XD'8JZGPENF(?",12X3^!XB[YI%47Y_C,_JKZ9/*>9DO]9(Z_,8H5-4/B, + >;!!;U#J8!_PJ18))Q[)\;+>52D?,,E?T +/;G9YM@!RK@X*T?I*B[P%74L>YIF #TJY0!4A'&***5@GW$J+C_3E;_!S^$HH.-6 ++9J5"\#T]$JY46*Q -$+Q*.FD>JQ%P0Q+\G>VCN(H2Q>'_!YX]F.Y*^:#0BEEULZ +G],@E^4@B&>(&Z.DK?2*/\JB^!75='R*$WH>Q'&_630^A4U5T%AW%"O0B::AL?L+ +IZ:'T-C#/IF-7PF=^Q"TM/'C;WBZ#]P-+BCMWR5 M7PUUA_ZG@A)#QX4>IMV4C^' +7M8- !^)1AOC(R:;@U+1=^.O2/P1@D!".(P4XX8;[H?FJ4G877I\'%L0WC"A(4YM +LJ (TVND8:=B\,\VJIG?CU;P.\Y(J^:M+WM>'&)B]248K>#'ILP>+8DGLJ0'ZA9D +/A5G,]-;J=,[^0W.>.W3W2FB2!E37Q0EU[NML5JJ4PW(R "(8Q2CBC?+X]D)*3R-%[RW?Y[5_.G3#);XY[#$$>1X +&/"F*6_IGELDIHW.0 =W)MFRHT2"W71RI)@"ZJ?/U%5_/A^ +V ,[DVLO(>KJ-(P<\:3F!U,OV9'FI]AW[ +K7G:XPQ@DD 1>*16NW[LX]-.]J_\RF7R238!@:H08&*AK=YD),2#^6(XD9U2 ">I,#%M+OY+'S3;S!UYYY7=:_.> 9Z%]303,= +H\,!^":+S^KU*/6G#_1?,!AV\=/+W25Y[C#+V$.MEBO>]AHVZZ^PTZAF/I6J5NBB +X"V9TA2R *MHO3,'CN.0 +NRX[B$XO\OC:23%O0#V)!/5+,6&/ -@\5E 8I110 AOGX*;)'%T=XN NN34LIYSG1SN%A4J0_W@@Q8_G]M1M&9 ^T1#K AE +ZI)O1(:5X, O*IK!#5D B=L\:LRYQ'KX>RO"=S2 +?T2W H !N7-H9'9/:Y\7P5"GH<;>WAC&.Z"=;_&%=(\ALD^3L!;JA'[K,;.AC]5S +2K#94U0M78MQ?LT# Z4U$W22/8:5C-JEX/B&E2W24?MY?^&:<@%UP_3C(P>I[1!% +W#.Y70(95Z\S^BD:^#/T,A.Q?VSM8;^2W3V5!M5+O(E4%&]?JS?S %@[;M%RN4CU +>?Y;EU;T4Q=S_%9KXA AE@*G/+*E!!W8\ )IMF2]2,KQ.I+/%@4'J+4U]X?U5#MM +O2U+V4WTI]]%3[2H,D/AE?B#BX8^>(Z76<=U> +4+&H)I H0EL6+/8=Y.05"A^9P +AF':CTJQ@;+':S-3-YN]Z/ U756AF?OR38?0IY:B='?&G\/HWXS.95WN@8"BF:2+8[=U: +0_7W*FI(0]7!SZH1T\C6T$5[ZW7AI#EUL)<8]-9Q[FBS/=&,C,[BY^NTQ$5,IBH"H 4FB@O;4.=@$ZU/1.*?!4D +BCV<6(T=KX.Y[7X:3["JEB6 ]/N+MKI$R*L>+C#A/?;N-W0<<>E7(W"LV/?RZ;9& +U]9H$AC-#D.Q$&VTN_XI"^_CTE-U/71K[QF;:W2><[(P>-"YUV;#P+3% Y-V5$>]&OW;$(]RY^K3! +RY)*"VCSX4[^KWH 6@"6)8#8/NG#QTS?MI]^?N-YU5@MI,5M(]&.*Q61US4 FFI/ +JPKUDU1'C?(@%ELL:RF0 O;N!0LX^8_P QQWH^O5!L%V:?@&W4MA*^4K&52\8+PG +5!I6_$QO#=$:MU0 7N?EQ*&+VMK?55(VA2E"MAX=X=]9^>U%AR8[]"/S/5?\S&=Z +'("8*KX@OB#[#%P0+&K!"JNSX;;4NH5G%P=ORJ;;5A*??\=N/<>I/>86( RAKK!W +$]:-OS#LM3+';F"))$S?U S]NO?T,-D4'HQXVWP!9(76RSYE2;6IG+*=_.?*02B_ +O1:") H?F3(VN27B!/-H?0J17-.E:4VKJBZI +25WEG46XI,U%H&F#39\<;!2!?<8]ZI;W"+S/LBY+58 +WVJTW?#<>";;Y9E-=QKTNT?1)9+$W?\E9Q;:%W=/!VC82;$SX1:ZT/O4=8)Q_@$R +1C)Y]7)3&A C.P/^I1PP$B"T90G;&.EKD@4%MBRNP5!J2'?[6!6N5P!C?.\34;$; +^0#(@9JK9R?O^@Q7!0/(2)>(5U8^6@D3T1GOS7.H5TX.ID$Z +Y8;\+6+\2JH#TMHOO%]P(S#*1XAT"PD&??Y):Q&^C\R_=XM-9K&BW_0'S&42OOOS +'DP7MK5H$TM7K3T TJKTHG9FSGJL0&C$$])/;T*,X;_+Y91,V<96$@RH <,^C+TO L@.8LG>QP363N1D7V@QLG[W; 9B%__LR)B[9 +-:[AP_/0#^?>!V'^Y=M\F%L3&9<<'*M-4I*G8(@A@_L@D=::, IP8_[K]0[W(=/8 +T-_^)WE;@8Q-9ZXL1 %VGZ7&Y.(5/7@\O#SFANHP@2RJ CP+VEJ[W&%V\DGL[;_/ +^3WP=8\QJ-KP9JH]1<$(1*FX \WH:<$5IHM3GK(WID*3=LXSJ-XG:\M(6,05L.[/ +A[U;]F(8M*H?P3W#%N7M"@G,;0.Y7J*P#SUD00OO8:SU#%D7AYG>[=FY@9&OQB#; +Y41$-'"06EMEL4BI(%6BKPQ^^+@R=H2U%Q_7(J@G1X,C*L=!%$=+(4HP,T]"BU&V +A<6A&VY9I:-CJ9YDODTM2P[A(%L=D>VLP^3^H'HGJ#2B2KKA'*4/TYC#8FI")7$Q +/A8TRL^':*+6+>E:_-[J'P6DV^6:J3*ES<%\9 A @+6.KN_ DU="L S[O'&5PCL. +CE_R?==9 ##\+4;EWR86!ZQU.HAL] &)(N_3#Z@F(=VIRP14X48)^V"RMDKVKG*3 +Q?,0KUR-$F@!!S)-%X#^1)!R$R>O#A&+WD!U=/PJ-5.(VB8MR<'>7ONBEFVI2Q[G +2#?IC&$_4H_!Z88S[B$ZU!(9/>T19D7U20:M,)R V[^UIT!= YZEUKO2B\KN:RL2 +YVYQ?D)"I5\2IGZ>>?TGS;H\%0WT1M?\[BX@/__EF#*9A$8=YM=[EO;TBFU6.KGO +%R$+9B7"M+44$%]\*T(4O4[XG:(2NNZ&E;*V*<<2ZNZ#TA3NI/A9&[J(C3ND):\6 +>_QT.&T<:H?#SKV;:)-N@5PWOI9M-#[<.0MTV*='.DWFQHRJG%EVUA:]A*DT1PQ1SMM&^R61-G8O"MK(0_H'[XC(V +AFX#A--?9_A+005

IVRV,DV(R/"Z!:E##YA9QIZPJDZ6M +B8?V?EF&,1YN"^0!64WJE:C13_19$KXU39,3=NWU+J)S:7)!CUDG!.;22M\22JE(=NYN598+-^'FX6P<)#66LY\&[)C'=BEZK+SG)*G;@/%*U]FD*":C3%KCQM@<+Q/>H046XUR&^MJ,SZX%HJ49P,# M +D/S;#DHB>!L+KUMI6R><415-&3]4#TN"'1 +<8HWXQP^,?"^9>6IUV8 Q*#4@&??S]M:I@#'6K^5G#P$0XR[ZF[<*-F"%T_2V$@2 +*VRO-]O1K',VS(_'J[-V4)!V1>0T:E(Z_N<72=F']SIP%:SF4,1"-MON O88#G#! +G[&,IO,VO15 00Q"_&:6@^X157&,QD%7LN&EHV7 ([B;>!+K%'?N+MVQ&2MXL,O/ +)AG]7Q5=&/ET]A:FZ[43.:_<&/PKUWF68[+Y!-['/'V10S4WW3&;A](N'SL_A,,(F%+.".BIX&FB_8Z;8"CZG+O3U.W5BB$S5NH'B; UR-UR.#F +WK%48$ 'N,H57V,P9W-IB@0C-E^/8UD:=2,0&!@:-NMWPOYMN)?A^)G(5R3>"_GK +6Q%GX"A*.DFTOU)1$:[D)S_3?CB'A?HSALM%?9>:D&F;F02Z QO'--H(N;I/(]O5 +%L_/M1"ZK=N9C<7]_D ZA7'$!^0JO:&:6)N(*V?-;2J#B$ R\ %#W8!$0\T705GX +*";3F10RZ'@IJDH%6$S@3^#^OV6PWOS?Y.T'&64L6E>JNX=@XJ>XL>F_(7TP6Z]L +LM35?YB)]-BA[UN^HD$NV$Y/3W,KLS'#Y'J=Y"'JRU&UBG=H')J2N"==Q[37?ZWU,I9R9'^8V\) EV9:VKQAEG\7=':BPQM_"-_M!PDG7*%A1T5 +@HYM@W:0[D=!<41)EU4Q57)UFV0 T' 4;<>QHAC4G.!W-R.-',\4D.RT:BM'Q +J67)Z:]JA77\53F]E55N#VH+USI%ST7NB*''E J6<%X":F]0DRKWF#HTCL96:K98 +.-\4B*XD$""_&FO:[]*@J4P*H?&=K"?,L4=;984W#-J%3-OY-"!:',G7C_3C.;<5@C;58# +<>K/3!5&1MEZ@J'XCLI0,L9_<_TB]A1MW;I\N^A'UL,.B4W*/E5&,J/=BQ@EC4\- ++$TL=KG=7MJEST+(G]^*.D$(Y9@3,MF_3T-5!3YYL4F*5>[T;>3W<= ]4C8]ZXS? +!G](V/AW-P"@0&2UC_O9N&702WX"$/84+< ,H :9KEE\MNO(V82H=^QCL&\ECD;G +B_GPDL:\5=A!MB&U;8.J*Y6 RC^N5E'<97O8ZO.7]7PW/3;0TF39T.(0++VX_EJ' +_K4@HXKHA[^A"H*HF*@D+WA=-4!YR\$A>JXJ6,"P_)$-X_D47< N@*S-.:%YU3G\ +(@10'Q-BWK_V0IW;H5D"W%T0].NS^;JH#P6@]CT9>-U_/9(L_W(0!-99=J=FMPFF +!O[3.[AV,5NCZYF")U,^D3 T9ULO-CAU_C"B0B:=LC!E]C/SUUB:5I^R[P0@K@$??B;'B)M-T +./!%VO1Z7B@A,"" +%L%V1N^S-5V+ W2)T@-H5-YE I&/=L5K]RUL6WU&WJV%_>Y*UQ*OT"HZGQ=7!N(> +R@Y4G!*<-5Z\YC_"GM.Q-*!F);VX9_H:E=?@[/FVQK@ATX$'] E$&V%HRO_SX)&& +4&%WN&\0U;:A<*N)YP['2KF4/G+$!K@'98!ZHE]J3/0HTKB:^>#FG,SNMA&0I;@MF/YM16W*(44I#?,@F*5?W.4SULNJ#Q&9^SO\]'LP9%L +4$-[)<$T5($PG+Z4^-T,5^%-'F308;K QTJ$HH&G)CA4H/A4I&6M'KO4G$::,XY@ +:A0M Y<%;RS'_R>OVA":CT^Q*[2?/39M5/Z5(O_KS\)S+4+.1QROI%N1/XP(L]\! +6KFPDBK.Z@K.)!X]CXJM&6/OVST<'!J^1 .; +)OT.RO>KQ^K1N$RIB$WX/!L0EE;ZJN#QI0%'CF[TNZ9K.<-=[PF[U\DJ+YU+YO D'0AJ6D/01&VM3/<%ROM[K*N33K/P ]=?+KT]U;7 "$?ZVIU-N'A\>0*MS77S>C]VDG UA+VS^],J>HFD@4N +M$BO$K!?7!PVD(7U4.J8%-5!Q9WD">VY1L.J0T[PHZ$P \::EQON\UB3!'B,+;[U ++?H[BC_:*)5WO7QA.++ZSI;W7^[*25?H T^'BY>:CU,IN[+;+0:P/'!L_:":ODI. +V-N RV-8NZ9+$.:\:=RQ_F?>=94,O.D]26(X$=I!O/()E)SQ;"[.E>GX&U?^1HGI6&^B]6Y0:W#58#UF8SVQ>[]O. 5W\9#8CX_UX%J\!+ +\-S7ZG+O#C9E3C6PJV@+^F@!2%V(+[J >^5'2W15VXM9IC-4SIN[-D5%[91B;)'. +M(C^V]&Z.+0X",;@&*L>L54 MBUPBM@!G<:84,VD^G&:727#>PC8U$17:-JLI,J% +3EJIHP^A-ZU&)*-;!@:U@;:RK<-0]F\4/#UA$$2 .*X%Y+9Y3Y^HUP8 6VSBB'0\2H8 +-/BN#;0EJ(_-=$<5?#ZM&83XC+.!:X +R[N5L[\E]Y-SO8YFJ3[T4"J\(^$/I0/V$T_L1J5ERQ9?%J,H$51M5'-O9)@T2Y3 +5X:;-S-"]0$JE$I,9^4U=>10,EK,:ZNA+KA1N/6,MF*_B,#%4=.[Z>./65)_.(^? +(-Z$I:M^/N*Z!R?$&AZ"+ELNT3(/8B)FYC!=YAOYK,)BQM00:Y/3:S_C9RC/AG6Q +5;J\>6()?OU*ZL!T'*U)4&SNW>"OPN*<>731 [_X (GWZ4.H$\$)SS9]TQ O1M01 +*D(9S _Z);+A DY5B0Z#]FN#I$/6#'\*GS&"OR* N;_+4ORM*4L:B.T>"[T&,_N\ N20)FZ>C37M/+?FWY4_MC_8\>R34 +[E5_'X(+JFOEVQ;,!;X!OW*?*CO9.P4W2$*]GR5Q+2/?.!T+XKH*R$YVM%2]"V=) +]6_X,&>C@ +IO#2TBZ9D+*D7MX?U?:,X9JB:0'7>=BXS$B-_P]F''K#W*B)P@H Z[M*)LN:\,C_ +;.!*D9!K!=?9'JL0'IT7LMNJ,IC3(91/5GG+F@XD3IG;_BOFA#,L7O6LKWZ-X!3K +0E+3;LQW^I0W>QDDZ-';:0T$8REQ!SK MJKCJ%.>OB\ K%A-3?UUMXN"WB<#NV%7+\C"I +67/4LL!INY]A58DY6Z121_'UL*X5$_T(A-^!OF:DG5%]H7<<-LM=P+G:X'GQ"DO9 +\N,\8T/UA$'5C-IOL8^58,JHP?JMOT:&BISHLPBV'AC[SO&_*TLW-Q6,JAF!H!]L +YEE,C09H73_'GE-##5'])AA^^?L7M$F.6Q57 # *E +\F]'+8C']^2/ H"!;O0QQDH&]HK/%/ 2CZ"\_UY_=OTR940H WI^U\"[>U3N\?/; +^C/DM>U1(9)\=4RX561YMX#P2')L0U>66F*_V[[L0BR66Y(8-Y+X H]A"SK+BN,A +L)UL]_YNJQ-Y19.\6VZJ?)V57=G1PVMVN%25'4V]!#[PRFQ%'%QSRJMFBRG535,G +KZ7D%CTTL8S#GF'4T&G1=P27"FXGK4$IV'T2S;8%(N4%$D&V'T +&MDER;'>R0:2MGEZQ7EK/LF&X^VK&[E9*7*MT4)GH= 2<=OL%)[ ^?_10-G!K,]@ +M!&S,#B"$6Y:APE4,!2 V MZ5/$0@(CY"AOE5FAY7YV",V]DR(-T U_1+U#=X*EX +YJN*Q#,V<,KJ:='],]EUS$F OAWG="IC@,YL<"(8Y XF].5J9BMLK\'H*4<1"SK^ +90^-M,6FR(GE\1O7$7W!AL)#:#OF.!KGFM"VSCST8 +[/8PDE [B?+<_EMR+E[L@_A]\OYT><%A5*ZJI^6VO0T;5X)LXF?R@EO#53G9.CDS +S$\-]E)&G(/C0:_%L5#QUDRXV2H90/7:.U#^.01@7$V,H>+X%?9,!=S[OGCZP=(9 +Z6**V]= ]ENYA1,E36;2RMS3N3'"DNY@CM)+8VFKTZ/X8\?V>FG6LT1:2T2O1RVG +J@R640\$R@YQ]#)0PN79C0>AI27GLD(;][4EYK +C/!8P(TP+[KBIZ^$V>M,^^-4ZG*]$3+; (36P8WXY,* BAHVA"\RPI_KC*T*Z@T= +U5>\FFXELYMJC',-&(C,6!(\B0H@"]2>V78@!8\+8\\!SL9I%+?MCR1"*X=6 BTH +1 TS&^D-@'AOOYEZU\*-44_W!.4(\L;9N4[WVX<5*$ZSO8!+EJUE!:GV3V+(TZ5J +%9V@T*UBO^'V%+/QM/]ET5KZ8W^K(B+!#+PXI #8,,>>@BVWCCE03?@?'W^L&QMR +VJ(BO4=@,7]/6\KX Y_M5(Z:,/#]9/J/F?GH!A&27^8@?.Y6\N9;NVDV$8Y!YSC? +W8F"I28Y'97%YFJU:/YXS.@I!4EO]P.I]/E%)0G^#JDIYK-[AS +=RR<]9OV[R,X^!WC$'US0RP)OS";FC]62^FH!),0F +5$WJ!R('P)$T, FT01[T[F2\H>DLB"P$_%3L+FU"C)R_XQ0W)(&,6V$XK)56;G7K +PM..@?%[T3=,B$5]PNE ;D2UE?W-@*>"T=M*]16.V=T_U_89@=[# +P;*\R]D<4["7.'/-A1'0-"SJV+U_SKH(&@=KP*O&&)W#311<\@8'5!#4WS*Y4KYEE>]0D" +J:!-LNIH6SGDH2>F5H4\6*\'X"I-5&?(?M"(R/HTX3O=18;U3_2HI^S8\0VR8OYJ;.="H_HXZ!Z'.&QL +TF['9+Q;)D"O+K"FUSEA];G7KN4R&SZPZC:UTO3I49.O(;D$US39YO0-S=U%,,O= +PW2Q"9^D8PH7%, H +@N28_IM_B*:UG#MB5+^^Z.809^'&$M/;/OALWZE5@%UY; C."\\\0?]C-4Y+IYO\ +-J53M]EOWRPJ385\ E;I:B)8HC^E3W$!#K.5=?YGH6%/[TZR$#H,JS]#V%/Y4%J?H(F.5DC'5B@D-VA= +@K"1']S2H'>T;.B-%TWU-"^FFQ/H;+6 :<*J.8LA$!@JOE>\WAZLP&!_;+,D-M]5 +2[93^!T+[7_J6>ZLL!549M:Q %LX]VRO/;?DO]VJTMJ2Q1P_!E)Q'M,%I\SZ_<=L +&]'NU8\S-?:GK7%,9SDMVETTT0OLCI"(-DVAHA][W?%%.3%J'__Z?[F!R6?MIJM7 +G-^MAQR*31\C= S:Z_H5HD7_3_[-S@;B$1Q+%BHC%UZ/L/([!QX8;TL^\K>O5L?@ +'W?7"@PS?]J12XW1Y6=(%#0/?EC-Y']Z<:S2W49'#&M<*%B^$!0 +H?W?BNJDI?HWH<8! 8K\BHF&7YH!*0H@KT4DN(\Y4858*?=5(?M0RLB*X,!A4RBS +#'Q3&S\4Y1D*:SOV[QP'^1M1L* +>U]"FRH'Q2^=#!VC.-H2=&F;=AS\LZ&YUM=D5*BF>FA@]&>AU^EV9@,JDH'@*'%8 +X.\D*,NZ$@W;F!.%WR*L(U!*G@8['EP<[R>H+VLW9Q\;9&:2+/@[B.<]P7.(Q(X-3D(PJ>\S9 ,@/3\S:5#Q(FY7(P_X>>&ISCOD A +/(RP!;1)1,-#56S-U<#P_M*)0H&SU7$T3D'P/>(K*I"OWJ^<'^J#@8/:: DX +VG*UT!PZU.'N43HSK5ZU&*:^^4UAQ^6D'T=4MGW:@1F9+KT>[L7]);!#.=F%;R:0 +NF'?1MWTA>UK+:!IOQLK\&X4V=J6^9>^Z:P32D)9(:956G1\)BP#B:$@/%W);XQN +G!MG:S89\7ZR"?8N(N3F:R(M]CCY.,+\*W*#W/&X-B/'AP,=E.#DW^*WL0>V1 VU +BOQ:E@3*?E3D,7F%\)(.-EP9:*SSR\OMEQLX =)7DGIRW^GD%@%!\1(8"G(S/]D6 +YNR8T](&KT&!2PRXZV/4?\U.[WQZ&1L2'F)ZPD<1,SA .!ZQIOGN[5%8DSGQ@3:/.3A[=N>+RL7DK[&*$/#SACP#\L1>[ +PZ(4A^O-PU#Q#6V-B4^?JIITA3W,R%C].'6P!(")?#R&"NDWX,.+>UHD?L<4??4I +Q>[8>;?T-][(V"PTS^)Z4)K!HEWKS$I(B2K1J%-.>'X1+9HR:LQC,<7^;?4">W/V;VJ(GRO%T=%>JSO;%F8ZT;8Z6K_Q66QI +O?0&V/CO6;@,G$QR:%K<@MA*KAJWAP,)D_2R.)00U']44!%'1M-%CAWZG];U9'8FZWH'>C)X81=$S?^1'HFA=W/"[D4<(PU ! +3/,98.SVA"0H#H<''(W^6L*#L]4VNX]D,(4\U364,P>B2G@+_*+@FP+..L#0!,SD +/Z&(IDI?K'>W%$J;5[.@0?K/F62)V3;R(')LO1.LBWC 2(;KJ24D2!N=XNT'8-B\ +&T+M,<;^G.[&'+*\:DP-!,IZC:2H,T4/.Z,(8X.1>".4/)X(5!$(PJ0*B\R,8E:" +_/48R-BED 0RPKX2W;B(0S/$GK?<"J+)M'(H@V@[/FMZCUA",C)4KQ+_;IF^,]0= +;7I7@#S7C0NR"P$[MZHP#<+9 PI!$Q?V!_R7NN)H:NPDT>CGERJA60081_L.Q3HT +3,D2:"]1QV)RUF>]PU+_:6[ML187!N+$C.R.+F+VVX4!T=!Q:B&>T:B=O9#)G5PW]UB +W=OIE8+%0"VUB(AO G+(I0R>3\_9[.6W"A *_$?1P>\,C!TJ <7;,[,[8'P7P<56 +<^?$_^%KPJ\6<&,+8^DON35*S(SB-&UIN@CUN8_P4/BL*MM81('%-[3)).=5.A7FK7"'%9X$+^4[#UVTL) J7 +?5(ITY@T]&[[M^9R \;%X#NM\H86-5"6DV20\7=:][3!?^Z)B=8(-9^&G4CW0^ > +3:[O-I&E0+'7#7+(RHG1KY4@ C VYC<(5FU)4_@FL0BQJ_US?"8[!8::++7I3?;N +EC7#%%W#5IUH.)UE >/S\$G$2+M6)4-!R2N<)H;[NMD72D(L'@BDUEYI<]9R_%Y, +WKR+0-=MCJXQQ^ACTQX66CT'$XE:1,AIGHXZ!."4QF:.$6>EK^,;L/WV^!W4W;W* +.5$&NU)[<_'W+UF7'&4WD/J+2$YCS8P=#0J[\!RMUCG]4&2L1G^@&E;RGOE8-*!O +" ]-(QBC[O;)0P?.89G)_Y'L!--;*HQ.?I&3 V=?G+_BVWUR87#L#/2>V^#9.+#-2$*Z,P,D5_1-AK0(#[2QV3C5-NP^M5QPNHW=6U*/ +D(9!';_YNC-OKES][$=_R.QFB3R;::K%$J;BEM0F-L3?T$ +;NKY[5TF>L=2 >72=XM[;4QU])NMM='.H !ZERS_&B(S8,7RHC9 +EYWZM^0(9>*/A3;\#^*E8*8T*87$$*0-G4;PMM0KY<_5,6O-Y6,+BT()=1+HS$ ,5&]P9'B +V%2(G&OH,H4UOI23? G)\$UP'9ZB/T3\D)FVMY>$QI0&W=I_>2O2RB,J^\FD%B=U +[J-=5X_,$'$1U?\L)G/<%+FU8%CN]-&I[NP;=P5UH;0LT@,D^8#U66KABC\H+34L +HN#B7_U]U^X\]OR3.I8- +;[EQ0H'Y&K7/E]OF:J':-2"G@@_*'+_#)$8T[D8:7PH\E)_X06(?$ >'K;B3I0 B +I,;&G1M)E0H35P_W>Y]S"0\G:">J%=D;L>$PT=_R!:#K???_]OR+3M!FM])GG5DY,7!](Y!AE#&_]S0+.J +S-NJ3+]\J(T I>/\WI=,!5KX=IQ1@O.. YI#/%W@X$>3J5IC^;/&YMCX++WK#9E@ +)Z[AK+Y"QB;35?" N-T:?Z^V/XC-1(ML#@3N#*!S)F;C'P #$S/=5E*UB2GO$S3K +KPZPM!ZTV:-P8=+Z0,5KTZ[*,/)O5#HBA>8M"';2Z3ZEK!48S\<[1E5%9#^ +LQ&3NY9B,#6SXCT>P5%[L5'7E.W:Z29MT/[XJNFN?F@DMRH9'8;PC'Z\/?56Q)2& + H94KN],:F&M%"\IQ.W=F',H(;"'7NAV]['14NOT)KO^(: '!&9XP\-L?J"QU+=, +Y3+Q3,RLB:=B)UCK2+]^=](; '<94N',WYJ9]).\'\*E_3;)48[H8,XQ;T.:-T)] +"ZE>B \Y1$WN_X"Q)*HCA "$OZG)7::O+B?M?H?BOG&,9P(D*V(W^.7R:1ZJ^C:: +\_I<==Q_W%K00ZIQ(UB@ H'_KEBM :6/K1.2/$VCTBKHFM"'>C 2X"93LS##>+ 5 +8)MKR]#O@E/I0JSDVH/@^9(&8I^R]QS\3=GKMW?FG=NEOPZSVQ^V3HN]5A\I](KB +[LF=TD4(@?LO]W.6427C!J!95S+0 .U\A1=U#(+M?)T>EQ,.1.R:;3Z4,#PZ/O50 +3>ESA:&I;O>R?08 KV-P"I*^)G:E5X=_.EJ*F(;YO0.T633Z:P?F,FCP0OC"K!>\ +UW;62G)Y*!TG,EPPX?.:=M5MV )VV"VQ*I\Y2F3V*/6^*YM^RR(ZKD^9OEOG1&8 +?K!Q!,B55X7H4+*IZ*]SOL MSVU16#S03F>"$,&*=[Y'G=%;S][H^7 +Z$NIR5G9;1]R5"T-DN;'A-/$D@'PS$$*5D?NU3.'+^JC%]>%G_;<>!3L^Z$P1!B;VP2@2LRVHT'C_J!>Z'7\Y44Z"!+@/K=!T" +5QN*;5CLV>QUFVM!WN CQGA!$$H:#/>W^\#S1Z[>ZWEX*HB[#"^K: ZI.U0$V+EQ +W69NOPD04GFS-I8DD%DNJQR;X-Y>$,DL&# 6IP*:_Q>/EB*<$6$EGLB E%KXC\K] +E[6"A)]#S;.5K82,_MO'L#=*"@/5G-M+#VZ[#.W6GQ8S5O8Z.;Y[FCOZ6 1\\3V-#'-R^104P:(19 +D[8>;L3A&)2R2A7,LNV5# 79/&:E"K[,%EC)9^62[FNX,(U'$3$#,<9O2$/7NMWW +)K&U#\H&6BQ/;H0Q M63E8:0OXC7+B,J'50>3F>/^+VL/@9WJ78+[V;6J)TO?1F3HJ3UGN +QD@^D"ZLXJO]]>*\HI06.Q1R1S+@%2O6ZC)Y1;99#1!\O2BE8R?)Y 92VC*E.]B< +=4 "Z^WXX5@P<$5UA\P0^201]YMTD&I\FN9A^0[K+0D>H, 0U!_F_RXN2'=Y:+'O +T:N!V]7"B\[[H%>PY+HE.JNW2;C4/FW):7674WX+J0*)'Q\6>Y3++_'$)$%]%!WW@_;NGN +7U4'V]E![QT?ZR_PG,L[P.SSD/K]+A6BI*"VK7CBIDZI/K9&"OQIK@/#?+%H_]"O +[1TR_?[UY=/?>V\\< BVCF*77S,JC[O=%F,63LF)-_,!X5UP/&'.RE*N +0I1C"#/9 8)*XFFBNW$JHX YP3E2$[.%C4@P)74J-%_2F.ICH-YK;+;JR&(/>Q30W<(=GQZ&SZ/]YV=IXL= +D$J6&I#8(+9T$3YTX%+BRR=& 3\:5A%_<;J"@4K4<*@HMM9'GN%EM@=$V&\MNV1E +N?F>SH1O+,0211TI)M!*+BY-'1[C'T%69-7GOG(NXE&*!]7WGH?[*K3MJ/1I/7?O +;TA&>'!B\G_0 C@W49$R]UM+=U*[N7;* _6MD@5S3?=%A60\K'W+Y)QAU]S<+L2] +S]H0P,M=JC9W^\=S2*M81G>>^_O'01$.UK%[Q'5"]U V]I?0$-^*81-8JQ_ +RB! +&_W&8(5-UQ/R>%\D)&G@4=TD_VTV=N92?ZH#(^F7.45AQR3\6,ZV6K[M3* +.>:."S+4,("[(FME!%3.->O;YN%UL,+*&RWQ_%?[UGH*_I:#SCX(@KR@31G]5+P; +$(C7AM(UK\X!,6ZXL:\;CR)"8Q7+J8'4JBWFX*-"X+2YS?1%-Y +1_\LO]AVIX $>S6/0.>MLZNU&_#W,]8LO\IYV.C7Q2K7O5:V@U+/< H_ L9=^E_TVJZ3/<-(<.*M @\$51(C=.ITJ#S'S*K<&#!O$CIUTF0V C!] +N0>PP,?&#@3)(G*!'DM #TU]I8#8F@&<8W4>J\(18E_?Z345.^")MKHXI_NOV"-O +SU5O%Z)!4?%(=T+#6S=7P4:R6!LV*7KK%0-/Y5ET-E]'\E)-W8OA&?JA::P +Z;2KI.2O!YY<3L3 V_<7A'$_.K^.&1=K#]<7FCB52KZ85<15 +A\7/*T_6>'-8_/ +]8%U#UH^FOZ+'X$"V)GNM42EHXOC4$BX3+/ZDZI<"WSH[_+EG635SAB*RVD,WF/U +2W#9P69@.PGFN?9XJZ?MG/> .^NYRF+(.906,A^#&ID.>4F6,OI:%4?*,/$7[)_ +%?61RGB M=+^$W]WMG!N#2'@&5J\^Y/,%#S*Z2#5 4G),[I72GL>PDT +?>UA29#&((@L_.1!;HS#@&GWN,UVZ)ER"C6IV?GLP/0[;]RP&7CAI69OM*K'4(U ++6[DN.K/_.:ORAQZ>#4/NJLB([#7CPP-"8L."-=K"OWTUK-&>GY4+!X-0\0>*SO\ +H$Z'V2&NYE@(T" <6&"G]Q^,Q?2TNL7H S,^YY=5C&AQ*8PD_P7[EIIQ0HAP%@[S +XG_*!H\*WF*X=M)?7=.W78^[-BFY2^:=>MC"P])41R^".?_T'C34R;P$HY/)E$-1 +R\35"9O])#PG34!SK/$JR\B2X>0,#(6C-FBGPEMG;8/+-CA845 8MG.S4]EW9\K0 +!IQSP<=*H,_QU4XH(^%D\"N?T&Q>KL)(B> +((=60['EWMY=IG-ER4F4R[L631 1RMM40 +3_ZJ[9.*)-W.N_T(%GV6EB +-LA5$EVP1F>R*HC5KPPA:XJI4K<:.UIBS=;$H.>, +%%Z][<P4UEASLP1/ +VZZF23CFBI@F)-:*P5+Q'S^>75-3@4=[H@_!)BY-3_M.LWZ,EY(&>$5".29(/B'Z>_FLQ-?B-#:EM1' +RZ;-5 *,Y*O(EG(]I^(= 7'*\/0T5(I_&D7BX7.GEZ%/7H1M!$])]#=7Z_M$,'*/ +%=)$TTD[!OZT*.UPC9Z.R&?CE%-T#L^E6=K04\QD/$U#<%18VRQ^8#H60IY*#UH2 +NV=GR2U[^%PR1O:U>+M=[Q4+S/.0 TO-/@'SVPXH=:AVC&3[. 0NDF3=B$Y_J^*L + '?DLK$R'RSE==!^TZ+G@">5ODNC6Z*QJ6>S[HDXP095W7^N<0FQ=S<(/;FN$]/; +N+&1?@<9*31H)6AC^IOQ]YK2 3;BJW68UN'88Q9R1U.[3G=X85WR;J&JGVX6%K0< +]+]^[)U$D)2>Z4CDJD'BF\X7"B_'L'J90<0S!^9(.5[,CC"9_;U^:TF:B:UXKSSG +QAWV@D J>K:GEI7-GZ*/CC2PP'>(;QL,]X)J;..XG<-J4=WBC!MBF"C!OZ&!CC]V +TVGI' ,6IJ3?B\+/F0!T0/L/;T5[LEG>DY?PF@$\*ZJZB>+JM"'N;]8P6_5"SS$- +YM&T"!$0AOOFP(UMW2#\PFU9F?&/_-'ZWES!M #.'A>=/N:>82-D(J #3A$Z@48G +JL(_?%#U*:\(]2T&= A#:B2DXRG WFEUGU6>86MGEE2]5A^0T.=#Y%'6ZS*(,616 +#ZV+I>K''4^T#>(HHXN9J_J:F\&4$9?\0@6+HB:D6BBI +P:9([8XU89@/*1O@5=BFXVSDP/6&U,'T%6CA'*MG$\RIK75EAL=*)@TT*H=Z62Y8 +AR[^/FIYL6T/7!IS@*L=V*T:D;#F'F5MO5/?:'044T#&OV85XLK R"?4U4:([2 ? +1Z'UP$NX&TMY?1/WV4\6N5%__+]CYQH_IJ"CX=7;WBFPUH6@?/+7KV(3'=BG^>V+ +:;>=O$\6A=JW=2IPO["4Q.L/O-_F!HI=CW0I!J9W 1M]H8[F>7A3MALWW26>XFA T-6BNLI;KB#M[9? :34#,B=Q,M]_^QHM ++E;K-,SNP7XO#MCQ*I^]*#>&DL!,.N#!7:K2XK#&F\U*+?GQYI'CGV:7:,F8[A*] +:@.8G9C[/R@5DA3N(NP-8V_7J>:"Q4][U#LM'FR)O,UCIP8INIE/PVX;;ZYPM85> +MRJ1P?TT_BITD*0"3MX<4PJ%\EFSSS3RIBA\^V)ITG%XL%7$(",9%H-G!^^R QA* +1N<63 ""L^T6YQN/M'2-]]H8; (@XV>FSFG=FZ1.O$(Y/]F71LS\9A>1&((S@PKO_!WXD9PV'?)8IJ3] 0SGZ?"%$UDGT"C#EF,[B)57?;Q@WI%_2?S'7FO4)8II?[)]&>T +Y>J712H1_HG6MP^*GJ+\7]FA+*(-D"]WO>#1'M'DAHQT"):06R;JK $G*%6<)!N\ +0I ; 7%-:&^EY;6G.IYAAKWUC'W+!ETWX61@2]!^5 -!(%&)6KQURKP34<3TBR== +E8//)3LA&!W'(^(C;!%"I_2&I!D*K?>LAQP,F8SE90_>K@1LG( +\Q^AC:?=+E'STDB%;MWA0ZW@PT+?)_U"O(KRWM'[&.D5H!96#=YIYOH.,Q[BB85H +^23P3Z* E>_K9W-B,^G[+ 3G(9#3B6!U2>+KB&W@N+/OR]UU+PITR37]6>;3V=! +5_3&!>9O[&;".WGA)VV _?@6R^98"@.FG04FG?0""2X"\3O8,CE/?L,)?^3< L#I +9T[>5,JF4;DO268*]!68BC"OX,]1=0S0].&I6* 02N!)7GG-H:271 U-Y9#NB)KO +G\C%V9]+2FOK$:[0Q6MKQUXQV<8$Y#;F:SH0[^@+J5DYQI3?@8/\OM2Y/5?4^-S] +TBI]SPOW@P82Q*-;FQ8*TO^7SYBVF"_[F@0@;=3V7Z8/4>96@F8G^0QY;SR4R^'& +J]PB7HUI9^#8HE+>O-A!)])0XJV-J8^!ECNVHZZ?A-K4I19S_);/#=O\=@"J-X)$O8?L0W6U-N)+9:&FSY=4@PMNP<.3>?840:(7%< +\3A^7^:0E^W"I%7Z9.T33JEC;?T4-V6=7H'-_J%X>3N]->-&A_JB5KZ5_\I30: 2BR]>!#G=P-1 GKWPS-!:%4:;F"DDRY#(F''W_>BR A G' +7>-YOPB&=A77CEI6EA%R52/<&<(\(G,]]0MD2J^PH'7%GCN_[?G%R&W\4A4.H58O +9U[OXX@-_)X4NY.)*9AWW.J$IRY$I$[]DF]Z^*&K )L \5]80^7IK0!"=*:S60GV +W/Y!5Y?;7<']\@=GQ'_JJSB.0<"-U[51-:T%4^3^+[7E<6X-P-.'9<9>&Z\TMV"N +"G0Z>VW#WG$FU)3$6E(U?*/]XYA@[LG H^ +@8ED8N[_UR0=BABG#BVT:K#X7KE@6PDDP'D)*Z264:N>PI=SOCF]6L=S1Q Z8$VD +AMC)2DD:G:8Y9W("9H>DS6KKTDLE5>9J]I<>V^E&&R9FK/<$#@S6^4V_]3%3(1L[ +M$\\@&Q+18R_[:B%L_'J59.Y#\@,LJ:%0\OW<(49I2!5,:BZH3%ZKVH'7#H@!0\/A=:^7 +J+5LN8T-;#UT*&^K_4F,HY_\4U"5(\[MW@-Y1^F;,VF>R4:! Z5B%'PL)6) +^N&(AG(7LUMU"P&ED$2L9;M5BEXK9;5V,&3/<<#9)(?YSU 77S/X^'NU1U4VD<1O + C>AB=FW1; &O.6H?+ 54]SI./A;1@."_LJ1!7\A5PQ5A> H41[0, (*/_7$BXGR +X+.293$.;P9'>E[[RSI)6517,?3%"^58"7CF>*W<0CC7['FR%9_=6PD#F4H6)?H% +'@L=CDG?$E:M5AYI=NF-[T:N<$>6NB(,7J>M76/YN]W^6PB"3GOB45 B/0BUUDP7 +$G$F-=Y:56TG';PEDDT]6TB_?T>%PEAX2*^#R[PN?F-WC%UDAVQXZ+Y8]6Z:);W6R$J/DR1^YY5G5].\LFFHB"Y(XD^5\E]"[YC;7>_:%!'OG6@ +,C6T35NY:^$!;#9$0,&NB@-1%YAJ+(L4*H\0^M"QB=,,-1W%]9W/H@3?% /IYQ#7 +R^6"RSEE+:F*JW\(4T;6MSEK@SC+;SR+D*3.;)BD1I@>\)-EKH' +5G79-+B$A:NEH+VWHL>G=F$'FMDU-@RF4#;GLJ9]WM[.Z2H\17U6][L'OP7#MCI! +'0LL"4$,%*- @.8_RR\MTU_!S_H '$*[K=L/JQG@SCT?^"))5BC>7YJ75;C4_E0 +'B-+0CH66P'H%OT*G]E1O[K2!/J!9UK;V6%O%T9)B:KZL5J7R,[4%K^AI^**EZ9= +(@?9JUN=>^#O!TLV)75%ZDW3NWC=$9#K] +ES!+K,=:>5AS2^T-BM&>=:,&7(K<*F-'.0#Y*K4?P+'!HA0$1W]Y\IYQ=A@Q_/ +!KZ=MH=11:%=2@R3? A'2XZN@.T";@*;PD'7T!8R4#?1:8Q?HT[BO,.4PN H=H&C +P5<-?^G]0_^:,%1#8-N^ ;O"BW&48?VIOW3>'QDJ.>? +#KF;!!/I8*]:=JM107"+O\AU)P[[:)L0ZH'8M8S8%>,%;Z\4TA31DZP\38<:84PH +JU49_S)4U/._U[@^]PF^V]I)ZC76Z8Z1ZF"7Y \QLCW5->>8L'=M5[%1ZSF)2LN@ +OU0;*'\YK@[[C_\,P\K($"^&28WOTYKTU4]C-Y=ABA),\=C-^6RRH154; 8;QS([ +^H=L4(#\6H$]4=\.N@GNE9))I HP,G12J[-SH,A_7;J9B SCY-[ (3R\)$!->:,8 +=HL!:BV]4=;%N!5;X/E!E#/4C3M&%:0&?.OHU:=U;-_H#OU$]KX 63[>M6M13XD0\G +-J"*(-'I1^&N=-:T6FQ3,")#4\_@E!28G6SS^+)KHXDL;MOXH?@5IQ5O>]_J@,Y5 +*--+N[8K,HEOVUPW=-W7$+FP7?3Y^#)B0.U?19 +/."#P-2C"UL?@R?K8 #ZG+-1%[5L ?2.=T32H103NPL,)U3)&E4@Q?XIY JCQV2* +_1NVDI<5KP7#!N8>P373="[D/> \=YV3YM@,.=8UC^1N75I4[_NWO5H$0 +D 56\-^YF=W 0!%1]X)K76-U"["$-J,CZ;Z( P!2 /$2&U6\ +1IUW?WWE2R=I'";)^+25!/WO[0*DVM +W]Q97OD3>C:X%MN\?NG)C]\%U::V_1?3)M#%'G1%55^S,/8 L:'L;\$<3^SKUEUJ +NZ[)A]R)5FPU^QQ9_,U^FI%1/3=7@/KI6CXV<4WC"3?2'!AX:6*I^<[L@'!N02Y/ +.IGG)?""2J$8:/5)2A^<^BTH7Y'ICPIYVU@54H;Q=T;[IHD5_>2Y!W[XQE + F\\ECSJZ8PH&U=$5.W4^S+D(4.OYTX!7_ 8+U7AY'D(I\(#(B/8$M%*+/0ZZT#5 +":1*Q]2E<3'YA9$X%82T53+P%@<3%E=-&>=8.F*[. @B, ;5__V72D03IKQ/LB], +,R':MQU#KQXIE_>T:+#,S3OYY$C"6\VEPWS]?@0CC92#RN\;L'KM H"+C@:YZ>4! +>[P(L&SHY';-5PTJGJ(!03L4"&UHJD!VF]?:&";2MG>X04BF[YGK/[R&^LSF3%<- +$Z OY!GKM>LP3G-JY^ 2OLB:DX!$L]QFHLF(", V(U;M\O4>/A"*D'70=/**]\U/ +,"! \?!([/3ZR.E9.'/G]+A#@]-V9,U&J>LD9Q4WAGT2O:QWT5SL=^,9*#5L68[* +.KTTZG']*\).QIR!@,X O&D7Q (/;D5FO6FSY?YBJD(URNF(#)Z2'4U14%&D(KI? +S&IX"&WS\7%6:@?\YK2\$PCOAO?L.AH>-92Y7,&9(@TT!5^,PYJ;O T&7^Y0E#E9 +?;GG:Y&ELPX;!2@9.%-(I'!(%%TN85#N8)9GMR>)% G&3V7"\$;.Q_="H>8 Y 3 +M5\W0"HM7^1'.M@;=!A'!@*;0=GUQGX.O)Q-/# +>1,B9;1AT@[ZJA0BYP0K4'2NM:<8<.,&])CV5X9!OTA7V +LCK],4?GU(SM)3NT/M(/TLPXU@1#:P10TA +^P$UB;,;?=E3O>FY]!5>TR9N]EF*>(E,C2R@T"7AX=$O^V4UYNI1\H8?1X(I&9F:M"?7 HAHJY!")!( +,Z?W['-]WC:^=&LUF\>EHA87+H]=8PKE4/53IKW'^)/N$LF])V60 +@^'*O*POL_@EL:MQDQKDRH3B6:F\TSSLZ>J<76\MVMG'I"=Z+T4:,D.J2X#E_M(' +QQCT5L-9-I[,AN-WY_GCOXA.Y$*]DVRH)TY[LK+!."+F3BKW,95]7@$-Z'*TU2 25(JER +X!P4N_%(2%2BT!A=EE4$X+2OP[>X'7WNWV!R#1BE7HT&NMV%AFIS[YE_\H/-E@_C +ZOT-'C!,FX4Z\"0(I"&\]R*.'/W$&_?RC4>A+Z/UZ<#[R-71TN1;HG'Q.@.-@^NDE4LB>O_Q +U]SS?'7DP&CFML=%JY=MFG3@"N?55G25QP@MRM%W7>V?PNKV8"M0%LWK4JK$#IA( +=U4@7A#;!+B)79P804K?J[Q(&"AWP-EY],B<(.U>\.-7#@KPW1%1CC?NX3B'J$!D;6/[D0G7Z0W;1: +3 +9/3*N<6DWO$1C_@?2**J.]4?<,4K,+[Y[]<!)Q%6MBU)8L0O6<7D +/#_J*:T\N5M=D+F[S]]O:#V4SO>UI5'LZ24@-RTI VO>_S(\Y6AU&V%W@ITQ\ '[ +<[D$99GK4Y&8?=)L(&^N89QU,D#4?)-M*F>5U]2O0!ZO#* :R%;;Z"G )TS_:5BD +JVJ[X]J.H:$GF:S A/PH:J XP,IKTV\F!ZFA*&5>I1 ^6Z[^Q27$*^?[\1^ -9NM +SE,>CPC)+$^:YMI[V[>IU1RD+"SK]6<<3,_#/1?L9SP;>P).*AO+A!2!=2X4] [;,J",!-;CZ7M."VZES4M +@VS5KD)JDG#-E9;11WIF5HD; NJ.G_M!M4P)-5Z)^$7 +OH&9K6$[BG)"#LV=RH,4!-_$-T>C"Y90Y75=&;6AH$P1W!]3'B>0\;_#,-9K_(A" +.977R)O,5V[DO+U>$%C%PN*EW"\-^T#SH1/!X?,H^Z;Y<1!NRG:."]F?2A4U123B +A]+J:_95?Y^Q%XXA9TV)/ZJA?JVTA_OV E2)9FCJLW85@;WX^I9E>M#7#DKC(PB +H1\T;'%'_C?)U8IP/-/-Z9=T:?HDT%X5H7AD@IV$V+NG]GEIAEK,\AFL"]^^J5[; +[-J4;@@EY%#RNH,#24M*F@.P(*6(^C>R-[(C;'F#D+RON*YXX8*2XEVQ?7S0UU. +D?DDL W*^HOC9!5(I8&Y$SP8,SQ7CZ>KWASC],2.9L)[G]NFR;77NUMG93LVFVP& +0=5&YG'3LL(; 1TCQ@^%L3[*5% +#4UT1$;2W+GI#7B\H:O_%0]:2E"FN*I0(7&F20RHV'VQX9KV=2?F7MS,WJ3QMGK7 +3ELQ>BNXC0NUQ'XKK_D +@#4M_W!=D>E;<'J_T$LNBP4UT](V9L R"FF.5&=69$9 +.S"B^^\;<.8QGDCF0!/(C,^?2(Q3)N"@R4ECP.@Y%19SM^@]R[VKXR)"QOD"T=[* +_X5S@3$>5YHH0CSJH74JEZK@_EI%1W[@NK9-.AW? ^/SDH>S51=F8X470MI5"MF^ +@T.1B&F3IIA3G#'EZ-)98_&79'@4 +_*$CG%:D:('UH?.>@P)M:RN=/K-_HUQZT\Q X53<2UMFG:B*@14)O8B64N9>K86( +U@$5H8JG\F)X43\+QLW=2A.I9RE:3P%&[[?K#V7 G%*-W0.-!$XY?FS,70K9172R +FD-^CV^C-B;*VX,\B(('BS; C;7&398EXK.5Q#E;XD<3!L2-5^#4.44DXV^];:H?(+Q"$;)MU0N GH1 +WQG4D:_(+"O>2J2REOJ K?P^PX_$+AI$D L;9J95*BS?Y]F$2G>V +GI)UQ)V2'@W+PLVL!*+[8I?NIG>TH^V>YQ?\F.>&.%8^1 >!D[[H3@*.UEVT>6P!+7"8BZV;=2(Z7#7\]S30CU1\NXD=! +0CE/@X*&3ZQ'R71_J)E(/7&[WG.=-Z"^:&)V$9\EP[_<22;KE47L,3! +5PH95+$)9 1H'CJM_Y7/3LK+@3'#5]=:2WZ@\"J;Y_F%U^3.5&G]AA40WO^D,V3+ +]/C(<'F8&.ULDIJE]E*!5)2:(2.&,AJ0#239MOP%+83I$S!0B!DJL:"K2L9^"Y$_ +GY +K5>9#/*R\7_IAG8+JV>2?UPU8'>??F&@7P#A2C&4WX0]1:8"W_-PKD6]JT0!X&7%M[XT[;%PY>.A_7'1Y4Q*%E +UV?3?S!L11)WT6K;_@K:[>(@1,ZF)MN9VS[6$W9UG^*0Z1%*K/O(.9Z#=C!FO (/ +?\N1XG=T^VZI(K[*]9*!I1.]%M\0S/CJH]5:(I;/$7XGS6@L,]"]> +2;:!WA,7VK.:,@KH(*=,X1MTL\RUJ^=*((T_72I;3&TLN6F/RJ!2H;(0-'7[3LTW,HM;T,8()P1K)W(;7EY:G%; +#,(48; 9[@]_M$9H:H)B>5^<48E%.+SR>Q:>5R0_5P680R(N%&&&/>)F^[O:;FU" +LU'W9K>&'K3790_@!4D.;AL%[J)MA(/'5X#C!+(01I:@7BTM0LCK'P#(;6J*FS&+O!+!BUZI. O!:/.M >-35L +3#F-G+RU.UADVR^>D$I&9Q!TKL1(0_?A6(&6UPV%B8FCO]:@W= +WM6E $X(:]R&WA0 *ZE*;(\1( C300,XB83@@;G>'EH(M([S=[(?>T1-KIO7GYE5DD1" +:@55\(JW8J7[*]FMB!4#)SF+3'FOZ:YW%^EVO,L?7G=K-=W#[WGG5#WFK4(QS"B- +C2V]L,+V!3L=9@PH,92550D7.QK82DZ/;ZDB;\>*4G2G?2I=OAU5/"3A[I!M,!-1 +NEYZ^5PA5RM>,;\:// $U_((I^_40?O05*1:S[\X0ZDT\G7N;4JK,TG*[;CZ '.1 +L9F0,I?>+KR'#(6"/BUC.F3B<-U ; +=Y/P'ZY3=1\"RB'T/(G $J"IH 1ZEG:9.)2-#8;\M]C_P(33 +VZ=1>Q6(6!ZQY&=TZI\G-A=?]8'2(J3"N9?45E;BFBF/#>T( 7V*#L&@])#UCNLG +61B.^RVP18+ W 2PE-*L,B'4K_.P0LK,Y_]8A2^ +6\L*<@ X]R6Q:^PM7>Y@[M72 +IM']W/IT+IX-+DB-UG\/+Y_C\J?A.'(GIWI=-7FE'3=.!2/ANV9!^M*)NY R'Q%[]M_PXJ +(T5 3Z8AS1%%Q\+A#[X_+#@A)8X]L9RQ2(+HI<&\_0+U-!V&6\AW1'&N#/H"N.KF +*BU1?*>6XA%=J16)!@Y'L"8!8@$+]B,\T/P!B1J#E@J[-+(<-25^,D0&7""JB)MI +U2,LBT.0_T3E\=%GDORRN'6#'A70.WBCI):<4XJL3K1VL675UB1/&>9#AG=B+I:^ +!/\.H@[, ?C@RQ4*TLTGS0O*2?IAOC5&B]N1.3$ZW4#K RQ'@X)AA%5&FG(,*3O +E1;DY[>,*7K')Z8A>-TT0=S@'IZR3:/13-YAS[_J=]8%^[&Q'P[!7I0TE"Y^+S,I +*D5=?(0J*<8L8Y0""V%087[_Z\K1_NT5A!YIUF3)M('X[;#LS^''$UA\M'<6*:K$ +5VLJW\>@0IR^*K-4_OXO-1P#1(V!7N]E%6N)Y@'" \QO :S;CTA.=660KFC>+2TY +YB>CO>RZ>!A!-9%0MK"V:N[EB,$^83J7K4K64< 3&#-AV;1Y[:\48X/RI/HH=R]$ +U*JNM9F21E3I65JZGP0DXNK2=1M!UG1*FHC+NF+(Q_F:!S85IR/VKFE#;=#U@-7F=ALH#(:>7)A-!XV139OF7 M)7:AC0-C1Z8IA*_]_=V'9>B>YH&?7,1MGX?/ +A;6PAIB)G1Y^@2">\U#_F#I;FV)"D!\=OA!!U"YNW(0/=N,>"0L_;87\W'HD&?D?F9L(H0'[071I\ TF0 +:CRPP7IYI)QU0I#WYMI)01E+A@7G#TK]S2V&[/S5?@ZA*#B.\+A_F#)@&79S)6)@ +0&IY5[6E==\'C'4'-P\65:VW.&%'ZW8V2#5,GZV\<(^:>W![,(AC+]:[)JPBOURL +^S8@/OOF;$-8/3U#_!>8=7P(S=@S1HE(2NG%.Z]LJ +A 6(@H>'@2M,V-_V+7PB#09T,O;[+7-M;]T"8T:7L_"I]'1-,MGBG 0@YDAL&-#< +W'D=AE/31ITQQ:A.:UUWU^+.X8(_=CI>1#[7 U#]N821YJ)&U%.='U2Q:U^;T!8' +F_U97;QEO?&QN5=QZDL#]&H6#/@[HTQ!I6.:Q-MDNF*!>]('MKLPDJ>A09/ZW-7[JII9?#D4[_M*2-P:DD#9WTMAXD89N6_G,6G.ZW<+@O-1783)G2-O$SP@&T?IK)5C+.HVUH8S'X?KBI=1;DF6 %3J1L]6M_9C5L56]8 +(3;*A)[+88__V.L1&'A/5T_ N&NGR^->:6N9J)BU$J+3*E>W(&M2SC&T7,&C36,@ +-4YS?B80QG(U>=V'2@XB;G01@%1HV2I[QW5;X&2 +U7>XEDD$'G0_6I+^?/& N60T2F:.&^G.B[;A.A90Q_@_U4ZZ*N_+8UU%! ,."XQ] +=:#SL[>&9IA'%2'^'2=(DCGM0T:Z70D;162.GA>VEZCVR<9*W#0A@R+A%RW?..RP + &08RYR&ZF/D/7-%CE%]I\NI7&FSZ;6K#M/Q]JAS8AE,Q!2N,L4*"*!J!E%++QQQ +V%RU;5R2O!5."S.RJLA-@L\=-6@ A/&XGDDT27S?'Q4H8X[)^3RB@'@L= ?HRW^5 +?$ZN_929BM7;>:L!GH&KQ9'2^UIZ'$O46PMMC>HL[GU9W#]ZAK_\I$KI'E5Z*6$' +2\(P[L>7C# !F8(Z=NN6BT*V_L1Y'4K,#2^GFW"C"A\,,5UTP$^D?!B. J6-)#^ +=&#$_T#HJ!0:%&PDR8D5"7"=D4>S-]_V:-W= @83YK9_C;G?4$ZV)!?'U[7C+&HL +SFM_'-/']./>*$CN>8//K@?D0[58>J3R G[C)AS^K+WNK3/.\,\X](GIZ2_@(\)9_$N!.&)0,@\X@84 +2AN9W]F?+!]5JJ_.%8^?$E@*%C!L%U4XTTN)44E:[P[3J#L0"2<\W9* +0%)N%6Q.86)@K3?>A^\%I"YA2S,7QWL?Z8W@2YHRD9MPM=:[#.*&9+L0.0+S@GE& +TH48 HLIK8-PT6#,?I<_8&QX_;2FOTWP7268Q'%8W$@XE\@,<+BUV)B;'^;Q):/% +IX](N@K6(I;"%-=ED%4Z'=8"B_4GBGL0O4-CSHBY]BD.JKPT&JX3_\1NQ("'%;%. +$%_Q5#T/+T4\4H<=4;*IQFU ?86F[KUN:'0Z>G(,M]>D02PU^C3LR6!VB&FJS.2I +XE_RR8YBJ=D/3NMWWFE[,2?;9?X7%:_)>T&.[<87E7TVT]R?>QBKPF&/T+")<>CC +KI"RZDC:\56S*Q( 5TK:!^ MQEG,<3@1MV9Z@('(MVYQ+Y73"Y;5-!Y+^\QTQ+>J +!R?],LV X^8_R1.=^5PZ5J-=<3/H\&BKK%,S] H;#[YA@5[8CE1U +/ON ==5;TV1O*CZ/[BYT@-M>'BQE!P)I3$5N#"!$3VZBHK_^K(6<&_P/"^LD!Z][%/BCQ- +MIPZ$+AZM3( :722>3O)C*O"#L1 M9JHJF>RW:@IP\9@3?PU1K">J/T@V:7OQH"4 +Y?=[1--SYP)F0XC>:-Q? (E/JCU,!O#T=^";!Q KCC/X@Y#@^L=HZ(.Q\GQ:48"2 +#C>: +AUGYR<&%BPG5ZN4U+QB_BXE>9/Y3-_"5%*TRB8./"G1.,1^6VB _9_@A)IR8)DGT0V$>N/D!/GKWA&)"ZD3SC C13DIFMB X85Y9.:< +S1,]C)-^>QN:(OPG@UXSPT@'YOP(0\KKL)[R537/1AG=6<-QZ'VA[NT[W!Z;@4D= +XMB*J:K^-P.M,%&*+HI(S,&O 3QD',S)QNZ8,.ONI_IHGW4Y+\*KEZ=P?7Z.'QM@ +<.SPU6DD!&2XZV3VGJ6D"5-SB^.7,O?ZD^O,]9O(-B93BGZ:'6P WS^E8.$/Z;4U +*6Z0+L*,+VT1.8&)[$0F'MTO\T?1R$@"UQ)G\S[:]C>+)/Z9%/ %KIAM40!M$FK2 +.:MQK*6*^SWKF4"CPB#"#8Q!N!6:O95;O.+8++($V%4#D'45$7V,+=:).DBT<7!+ +2LZ1GH&]--#87BZ63D3^ME5AT4?L[8\L6Z;"E'AW1'HC# 478XFSC/Y*2*"'-X]- +":#1C%!!5URC1UX&&Y%-:] )SD^3 C6^GW(==.4R/&54EM+QT/M](-(Z1 U4@&T6 +=AZ]"F[:?"MD6FJ4F164MMO?@GJB;<:9ZP&OA$ZU\+SXN&%26PJ;J! D-]=3)VH5 +V3YF-Q!^N+E;#XW_<^%PUW.?. ?UF9GP_/V5V XUE0.>BK?N+'FGHN!WI(Y#@S#R +W573&:A9/N_$:$&'^B<1T4 :Q()&[N)"#Y%;4Q,['NGE5K 9FA C/@J9T=,>2L +8) ,)"E2$-3LN@\:,N$CXQTW2\%\Q[&QDMD\RJ!TM:1\_8!4>.=:/PI)'G[[%<.! +#XGNK=8- 2FI[=]OS7AE0@:@3.?)S7PWTP/)VWLN9J-9YX&9]XS'X#-+9>GC9HU8 +P38*#IUO.O1DF_]9RSLJPPDT&,A2#RAN\M 'ML?!2/V?64@VY!-.K8I-:QL(SBNF +'Z2#PKS6#R%W."0(QD'U3:3B-\8E(O1PHLIUDK[J'9>SL# N#4:$FQ]>&HB +*Y SL7=T?+@^O-QKQ< +[7/.4W@PSF9E+$4!*J=>."#^$A];/6N"8 7AF.*UT(DT[)*7&5W!:SW *D4.#"!*9,=E-=G[5,TI*039>@BW;!DK&?,ZV]JE_ +)%DVTM-?;$^]G]N2)S$\J@>2S?L]=#W7Y# &0[FG?H (0'T!IP!(FS_QZ7[Y#']W +U(38.<:X3WY 0A'G.X*^):_2^EH26*=*.@)3U8T_]@6ZP@'( +G33F>M(KP]>KD9'1*J1HI!*8B-*,(5LZ7($F%]GAH>S!M%9>RJ]Y>^YUJN3S^&.> +:;P*75E<'7U/*HV4C]4DG+R!=#_+\X,063;Q5(@\7'.S408]KK=Y-J]2 +;BT7>%ZI*S';J;A&08=PK.JJ\46F^_@_6]=87-W.F2 ,R*;*EU5A>9GKZCK") %S +*6UBF&7%0%QLT:N#RKI[9H1QI@&0B$*RN2>S2!8P:.\] +BMHJ-@)^-O<7S'X%KG*;V3RHJ \&O\LI)IIZ6FQ5%J.,CPW3_UV\_CK1>)\5RJ5F +Q,B1)UF+T)L$@XTDGV?4%1U?Q!5DKYJ/&WEUKCNG&GVQMNWU-?D2)G +89RKJEU-.M@D?A7,HZ/!XC:*6D33NJ325[XP860H=:?" A&E')HE(DB3014ZXDD8UIRY, +V-HSVCXN-^9U'T#)=W_E8 ! E*8_7M-#( V-WJ1&D^7M[:RE4_/'8>+:(=IY;SK( +;T5CDU6;PO9(%%G8O!QS\KDKH5(DY:*NSJIC![-WAW/RUI8OOVX7I.J^#S+R+P.5 +:[AI6[#%;M2TJ/5S83[&XNNBZE"!Y/%Y3F1]>LEM^Y%SFA,D/.K3#K47_&?HZIX@=N6WFS!N)A/).T_^A7NBZ*-_Y +"8@_,[SC(2H=A.HZR-+G]WR9HBR5:%K(R70R>!\Y0*58A6Y0#'M\D$] +\"H80K#JF7,@#'L3.M=0B H4 O: +=)/$V? ^T+LR;16'Q L3=FV +W-;6"&N_EQ,Y$J:BMPC*#.=ZJX+2A:#LX&?@MDY@U,:K#"0RU"95)XTG#MFA'#-8 +85Y\-],2:ZC]P1WW6+E_F)A3-LMOT/*3USG08$,BE,?,N?O"/_A?P=W)8DI'YB4 +:*X\T@/UAN^7+CS\S$;*M^6]&1Z)YSPK5[^TKYO$:[)H29SALE'7TRHPPU3=GS8/ +=:MO]B2#]-]V>K]?V1HK 9!IKWM#Z4U&+'AQ\BR)*=\8+DR6:)?=A-;ECRU:@%<' +F0]RS%Z*:.R':1SES*"EB&_"\ R3'W"?5+Q#)O2^7D?5?+E =%C,PJIKEH5SW=RE +''S921+@1_((5+W>7,XOCRW%7W;HR7-*=\<*U^;TT$>HE"X*]#;5\8*X&Q^HQ%#P +-9>>6>UMH0!OV8-!HNGB%A1!C+A412..9JV-N)/BTV430G^1X%5X/NA$/G*TPW*' +Z523M=RS%JS$N,F$?K[IH)0+O+?R^(@/1QN4,@@R,':\-1K/ISOL/&/RY=!C243; +CN]L135.W?HJV!1R#R.UL)V'P$:53$Q'5 WX&K0FVJ(GB.E;JL4G<'Q7X1U N(* +>A\ID9\ 5;F:>J9\>XFNZB?TXHR" UWQ=#C%7OU3!5C6GCA;- 0B&0[R*0?(/'DU +;II?9M/(I#+O_V1= JQ?XKP@+FJA_W'7*= =W GS7F"O\A1.>XRG*,J3)P%V^O4% +%3::N:[\S^6S \+]J6A/*3)4I'^W?\'![6SO(@7/=:(>WR;7LT1#!<\ T?:B5MNH +DCOND(,BM9,*RUG2 C; F6MC- ,7A*3.J<7EY(M:N>^ +^->)TE"!HC9Z7*2+54@ +65[*^;U[Y$?0E"D;"U0]](C,%('=+9#4Y-[+YD:@U&:I($Z$P/N'6SIT>UV;0@+5 +;P%$X^6X;6HB J!A'W$3@HT3R9W@EAP.%O +=OFF>GB%Q++[;G&"H?#/,[')J]2T-Y".\]NWXYZX$LH^4&>J98GRA3YMO]$5],9[ +* ;2&B6SB@!LA"(P%R=G?Q5L)NJ$' +\2/_%$VI3F0M4NR+2\(CZ%%5.HB"LBPR397B+Q*O HEJD!HO_PZMZ*96! +N ]#&I)Y1_)5X9B R>]ZW%SP^KU=ZW;PCB>?@>V23;."G86G[J*:2U]\*N<=N.64 ++4-U&>NQ.:KV(,QC4;CA%F_/P <9Z"_MD1+E^U00B+?M2$'>ZD;@6:A/XN1,K0Z; +>+F(X8J_JNE)DD$DO&ZJ?M9I64:&CI'S]H)-A?.UN1^8/3T^'AF*[3%I@,)[(H@CLKMG<@POMY5)NSPG'!CO6$O +*+X"$X*R94IO,NU4?\[)$3PJL,RN%]]Z-1(MZ;DJ*3!MZ]ZNA2%Y"! ;J(G&K8!5 +M$I>T$M,;'C>(1XCQZ/P^,0*;(H$EO(ZD>MS5\E:2!DAQAA[,;&'!Y<55)Q6G;L1<[->5 EW\=8VYY4+#QE#P +!1TJ"4(1P@*KD)YTK(O^\IQ3" 27,1FI(,$Z;_'G*91R?H4MBPN-V,RJL[IH< N7 +!EDPK1M^V>+P>#7A5E1+O"@Y^4.=YO%#FC?%YY1W=N\21C%( 8HH(Q;Q7XP3^:8! +1)V%RGG6!^'7-P5&J1Q]>)@. + + diff --git a/client/timecvt.cpp b/client/timecvt.cpp new file mode 100644 index 0000000..25abcce --- /dev/null +++ b/client/timecvt.cpp @@ -0,0 +1,172 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +/* + * + * timecvt.c + * + * Time conversion routines. + * + * $Id: timecvt.cpp,v 1.6.2.4 2007/02/22 02:28:42 vonkorff Exp $ + * + */ + +#include "sah_config.h" +#include "str_util.h" +#include "str_replace.h" + +#include +#include +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif + + +#include "util.h" +#include "s_util.h" +#include "timecvt.h" + +void timecvt_start() {} + +static void trim_newline(char*p) { + int n = (int)strlen(p); + if (n && (p[n-1]=='\n')) { + p[n-1] = 0; + } +} + +char* jd_string(double jd) { + static char buf[256], datestr[64]; + time_t tmptime; + + if ( jd > JD0 ) { + tmptime=jd_to_time_t(jd); + strlcpy(datestr, asctime(gmtime(&tmptime)), sizeof(datestr)); + trim_newline(datestr); + sprintf(buf, "%14.5f (%s)", jd, datestr); + } else { + sprintf(buf,"%14.5f",jd); + } + return buf; +} + +// output in human-readable form +// +char* short_jd_string(double jd) { + static char buf[256]; + time_t tmptime; + + if ( jd > JD0) { + tmptime=jd_to_time_t(jd); + strlcpy(buf, asctime(gmtime(&tmptime)),sizeof(buf)); + trim_newline(buf); + } else { + strlcpy(buf,"Unknown",sizeof(buf)); + } + return buf; +} + +void st_to_ut(TIME *st) { + double hour=((double)st->h)+((double)st->m)/60+((double)st->s)/3600 + +((double)st->c)/360000; + if (st->tz !=0) { + hour-=st->tz; + st->tz=0; + if (hour<0) { + hour+=24; + st->d--; + if (st->d<1) { + st->y--; + st->d+=NUM_DAYS(st->y); + } + } + if (hour>=24) { + hour-=24; + st->d++; + if (st->d>NUM_DAYS(st->y)) { + st->d-=NUM_DAYS(st->y); + st->y++; + } + } + st->h=(int)hour; + hour-=st->h; + hour*=60; + st->m=(int)hour; + hour-=st->m; + hour*=60; + st->s=(int)hour; + hour-=st->s; + hour*=100; + st->c=(int)hour; + } +} + +double ut_to_jd(long year, long month, long day, double hour) { + double jd; + long l=(month-14)/12; + jd=(double)(day-32075L+1461L*(year+4800L+l)/4+367l*(month-2-l*12)/12- + 3*((year+4900l+l)/100)/4); + jd+=(hour/24-0.5); + return(jd); +} + +double time_t_to_jd(time_t unix_time) { + return (((double)unix_time)/SECONDS_PER_DAY+JD0); +} + +time_t jd_to_time_t(double jd) { + return ((time_t)((jd-JD0)*SECONDS_PER_DAY)); +} + + +void st_time_convert(TIME *st) { + /* Fix Y2K Bug */ + if (st->y < 90) { + st->y+=2000; + } else if (st->y < 100) { + st->y+=1900; + } + + /* Convert time zome time into UT */ + st_to_ut(st); + + /* Fill in julian date field */ + { + double hour=((double)st->h)+((double)st->m)/60+((double)st->s)/3600 + +((double)st->c)/360000; + st->jd=ut_to_jd(st->y,1,st->d,hour); + } + + /* Fill in unix_time field */ + st->unix_time=jd_to_time_t(st->jd); + +} +void timecvt_end() {} + diff --git a/client/timecvt.h b/client/timecvt.h new file mode 100644 index 0000000..28cbd1d --- /dev/null +++ b/client/timecvt.h @@ -0,0 +1,87 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +/* + * + * timecvt.h + * + * Time conversion routines. + * + * $Id: timecvt.h,v 1.3.2.2 2005/10/09 18:24:22 korpela Exp $ + * + */ + +#ifndef TIMECVT_H +#define TIMECVT_H + +#include + +struct TIME { + int y,d,h,m,s,c; + double tz; + double jd; + time_t unix_time; + TIME operator -(const TIME &b) const; +}; + + + +#ifdef __MWERKS__ +// Note: Although Macintosh time is based on 1/1/1904, the +//MetroWerks Standard Libraries time routines use a base of 1/1/1900. +//#define JD0 2416480.5 /* Time at 0:00 GMT 1904 Jan 1 */ +#define JD0 2415020.5 /* Time at 0:00 GMT 1900 Jan 1 */ +#else +#define JD0 2440587.5 /* Time at 0:00 GMT 1970 Jan 1 */ +#endif + +#define SECONDS_PER_DAY 86400 + +#define ISLEAP(y) ((!((y) % 4) && ((y) % 100)) || !((y) % 400)) +#define NUM_DAYS(year) (365+ISLEAP(year)) + +extern char* jd_string(double jd); +extern char* short_jd_string(double jd); +extern double ut_to_jd(long year, long month, long day, double hour); +extern double time_t_to_jd(time_t unix_time); +extern time_t jd_to_time_t(double jd); +extern void st_time_convert(TIME *st); + +inline TIME TIME::operator -(const TIME &b) const { + TIME r; + r.tz=tz-b.tz; + r.jd=jd-b.jd; + r.unix_time=jd_to_time_t(r.jd); + if (r.tz != 0) { + r.jd-=(r.tz/24); + r.unix_time-=((long)(r.tz)*3600); + r.tz=0; + } + return r; +} + +#endif diff --git a/client/vector/analyzeFuncs_altivec.cpp b/client/vector/analyzeFuncs_altivec.cpp new file mode 100644 index 0000000..105aba7 --- /dev/null +++ b/client/vector/analyzeFuncs_altivec.cpp @@ -0,0 +1,1662 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +// $Id: analyzeFuncs_altivec.cpp,v 1.1.2.4 2006/12/14 22:21:59 korpela Exp $ +// + +// This file is empty is USE_ALTIVEC is not defined +#include "sah_config.h" + +#if defined(__ppc__) && defined(USE_ALTIVEC) + +#define INVALID_CHIRP 2e+20 + +#include "analyzeFuncs.h" +#include "analyzeFuncs_vector.h" +#include "analyzePoT.h" +#include "analyzeReport.h" +#include "gaussfit.h" +#include "s_util.h" +#include "pulsefind.h" + +#include +#include +#include + +// polynomial coefficients for sine / cosine approximation in the chirp routine +#define SS1 ((vector float) (1.5707963268)) +#define SS2 ((vector float) (-0.6466386396)) +#define SS3 ((vector float) (0.0679105987)) +#define SS4 ((vector float) (-0.0011573807)) +#define CC1 ((vector float) (-1.2341299769)) +#define CC2 ((vector float) (0.2465220241)) +#define CC3 ((vector float) (-0.0123926179)) + +#define ZERO ((vector float) (0)) +#define ONE ((vector float) (1.0)) +#define TWO ((vector float) (2.0)) +#define RECIP_TWO ((vector float) (0.5)) +#define RECIP_THREE ((vector float) (1.0 / 3.0)) +#define RECIP_FOUR ((vector float) (0.25)) +#define RECIP_FIVE ((vector float) (0.2)) + +// 2^52 (used by quickRound) +#define TWO_TO_52 4.503599627370496e15 + + + +static bool checked=false; +static bool hasAltiVec=false; + +bool AltiVec_Available( void ) +{ + if (!checked) { + checked=true; + long cpuAttributes; + OSErr err = Gestalt( gestaltPowerPCProcessorFeatures, &cpuAttributes ); + + if( noErr == err ) + hasAltiVec = ( 1 << gestaltPowerPCHasVectorInstructions) & cpuAttributes; + } + return hasAltiVec; +} + +inline vector float vec_fpsplat(float f_Constant) { + vector unsigned char vuc_Splat; + vector float vf_Constant; + vuc_Splat = vec_lvsl(0, &f_Constant); + vf_Constant = vec_lde(0, &f_Constant); + vuc_Splat = (vector unsigned char) vec_splat((vector float) vuc_Splat, 0); + vf_Constant = vec_perm(vf_Constant, vf_Constant, vuc_Splat); + return vf_Constant; +} + +inline vector float vec_rsqrt(vector float v) { + const vector float _0 = (vector float)(-.0); + // obtain estimate + vector float y = vec_rsqrte(v); + // two rounds of Newton-Raphson + y = vec_madd(vec_nmsub(v,vec_madd(y,y,_0),(vector float)(1.0)),vec_madd(y,(vector float)(0.5),_0),y); + y = vec_madd(vec_nmsub(v,vec_madd(y,y,_0),(vector float)(1.0)),vec_madd(y,(vector float)(0.5),_0),y); + return y; +} + +inline vector float vec_sqrt(vector float v) { + const vector float _0 = (vector float)(-.0); + return vec_sel(vec_madd(v,vec_rsqrt(v),_0),_0,vec_cmpeq(v,_0)); +} + +inline vector float vec_recip(vector float v) { + // obtain estimate + vector float estimate = vec_re( v ); + // one round of Newton-Raphson + return vec_madd( vec_nmsub( estimate, v, (vector float) (1.0) ), estimate, estimate ); +} + +int v_vTranspose(int i, int j, float *in, float *out) { + if (AltiVec_Available()) { + vSgetmo(j, i, (vector float *) in, (vector float *) out); + return 0; + } else { + return UNSUPPORTED_FUNCTION; + } +} + +int v_vGetPowerSpectrum( + sah_complex* FreqData, + float* PowerSpectrum, + int NumDataPoints +) { + int i, vEnd; + const vector unsigned char real = (vector unsigned char) (0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27); + const vector unsigned char imag = (vector unsigned char) (4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31); + + if (!AltiVec_Available()) return UNSUPPORTED_FUNCTION; + + analysis_state.FLOP_counter+=3.0*NumDataPoints; + + vEnd = NumDataPoints - (NumDataPoints & 3); + for (i = 0; i < vEnd; i += 4) { + const float *f = (const float *) (FreqData + i); + float *p = PowerSpectrum + i; + vector float f1, f2; + vector float re1, im1; + vector float p1; + + f1 = vec_ld(0, f); + f2 = vec_ld(16, f); + re1 = vec_perm(f1, f2, real); + im1 = vec_perm(f1, f2, imag); + p1 = vec_madd(re1, re1, vec_madd(im1, im1, ZERO)); + vec_st(p1, 0, p); + } + + // handle tail elements, although in practice this never happens + for (; i < NumDataPoints; i++) { + PowerSpectrum[i] = FreqData[i][0] * FreqData[i][0] + + FreqData[i][1] * FreqData[i][1]; + } + return 0; +} + + +int v_vGetPowerSpectrumG4( + sah_complex* FreqData, + float* PowerSpectrum, + int NumDataPoints + ) { + int i = 0, vEnd; + const vector unsigned char real = (vector unsigned char) (0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27); + const vector unsigned char imag = (vector unsigned char) (4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31); + + if (!AltiVec_Available()) return UNSUPPORTED_FUNCTION; + analysis_state.FLOP_counter+=3.0*NumDataPoints; + + vEnd = NumDataPoints - (NumDataPoints & 15); + for (i = 0; i < vEnd; i += 16) { + const float *f = (const float *) (FreqData + i); + float *p = PowerSpectrum + i; + vector float f1, f2, f3, f4, f5, f6, f7, f8; + vector float re1, im1, re2, im2, re3, im3, re4, im4; + vector float p1, p2, p3, p4; + + // prefetch next 512 bytes into L1 cache + vec_dstt(f, 0x10020100, 0); + + f1 = vec_ld(0, f); + f2 = vec_ld(16, f); + f3 = vec_ld(32, f); + f4 = vec_ld(48, f); + f5 = vec_ld(64, f); + f6 = vec_ld(80, f); + f7 = vec_ld(96, f); + f8 = vec_ld(112, f); + re1 = vec_perm(f1, f2, real); + im1 = vec_perm(f1, f2, imag); + re2 = vec_perm(f3, f4, real); + im2 = vec_perm(f3, f4, imag); + re3 = vec_perm(f5, f6, real); + im3 = vec_perm(f5, f6, imag); + re4 = vec_perm(f7, f8, real); + im4 = vec_perm(f7, f8, imag); + + // zero out a spot for our power data in the cache + __dcbz(0, p); + __dcbz(32, p); + + p1 = vec_madd(re1, re1, vec_madd(im1, im1, ZERO)); + p2 = vec_madd(re2, re2, vec_madd(im2, im2, ZERO)); + p3 = vec_madd(re3, re3, vec_madd(im3, im3, ZERO)); + p4 = vec_madd(re4, re4, vec_madd(im4, im4, ZERO)); + vec_st(p1, 0, p); + vec_st(p2, 16, p); + vec_st(p3, 32, p); + vec_st(p4, 48, p); + } + + vEnd = NumDataPoints - (NumDataPoints & 3); + for (; i < vEnd; i += 4) { + const float *f = (const float *) (FreqData + i); + float *p = PowerSpectrum + i; + vector float f1, f2; + vector float re1, im1; + vector float p1; + + f1 = vec_ld(0, f); + f2 = vec_ld(16, f); + re1 = vec_perm(f1, f2, real); + im1 = vec_perm(f1, f2, imag); + p1 = vec_madd(re1, re1, vec_madd(im1, im1, ZERO)); + vec_st(p1, 0, p); + } + + // handle tail elements, although in practice this never happens + for (; i < NumDataPoints; i++) { + PowerSpectrum[i] = FreqData[i][0] * FreqData[i][0] + + FreqData[i][1] * FreqData[i][1]; + } + return 0; +} + + + +// quickRound +// +// Quickly round a value to the nearest integer. This is done by adding a large +// value (which depends on the format of an IEEE double precision variable) and +// then subtracting it again to extract the fractional part of the variable. +// +// If x is positive, roundVal must be TWO_TO_52. +// If x is negative, roundVal must be -TWO_TO_52. +// +// NOTE: This function does not do any fancy IEEE compliant arithmetic (like +// handling NaN etc. or preserving the sign of +/-0). +// +// NOTE: Make sure that you don't use any compiler flags that will cancel +// out the operations. +inline double +quickRound(double x, double roundVal) +{ + return (x + roundVal) - roundVal; +} + + +// chirp +// +// Increase the frequency of the input signal over time. +// +// Note that the input angle is calculated in double-precision. The angle +// becomes so large that single-precision arithmetic is insufficient for the +// accuracy that we need. We can only convert to single-precision after +// reducing the range to (-0.5, 0.5). +// +// The algorithm used to generate the sine / cosine values is based on that +// described in "A Fast, Vectorizable Algorithm for Producing Single-Precision +// Sine-Cosine Pairs" by Marcus H. Mendenhall. The paper is available at: +// http://arxiv.org/pdf/cs.MS/0406049 +// +// Differences from the implementation in the paper: +// 1. The arguments are not scaled by 1/(2 pi) because the original chirp +// algorithm multiplies the chirp rate by (2 pi). +// 2. The slower version of the algorithm has been used (as if FASTER_SINCOS +// had not been defined for the code in the paper). +// 3. The loop has been unrolled once so the variables have been renamed to make +// things more readable. +// 4. The "struct phase" data type is not used. +// 5. The rounding of the input value to the range (-0.5, 0.5) is done in +// double-precision as mentioned above, and not via Altivec. +int v_vChirpData( + sah_complex* cx_DataArray, + sah_complex* cx_ChirpDataArray, + int chirp_rate_ind, + double chirp_rate, + int ul_NumDataPoints, + double sample_rate +) { +// int offset, int numPoints, double chirpRate + int i; + + if (!AltiVec_Available()) return UNSUPPORTED_FUNCTION; + + if (chirp_rate_ind == 0) { + memcpy(cx_ChirpDataArray, + cx_DataArray, + (int)ul_NumDataPoints * sizeof(sah_complex) + ); + } else { + int vEnd; + const vector unsigned char real = (vector unsigned char) (0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27); + const vector unsigned char imag = (vector unsigned char) (4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31); + double rate = chirp_rate * 0.5 / (sample_rate * sample_rate); + double roundVal = rate >= 0.0 ? TWO_TO_52 : -TWO_TO_52; + + // main vectorised loop + vEnd = ul_NumDataPoints - (ul_NumDataPoints & 7); + for (i = 0; i < vEnd; i += 8) { + const float *d = (const float *) (cx_DataArray + i); + float *c = (float *) (cx_ChirpDataArray + i); + double a1 = i; + double a2 = i + 1.0; + double a3 = i + 2.0; + double a4 = i + 3.0; + double a5 = i + 4.0; + double a6 = i + 5.0; + double a7 = i + 6.0; + double a8 = i + 7.0; + float v[8] __attribute__ ((aligned (16))); + vector float d1, d2, d3, d4; + vector float cd1, cd2, cd3, cd4; + vector float dre1, dre2; + vector float dim1, dim2; + vector float cre1, cre2; + vector float cim1, cim2; + vector float x1, x2; + vector float y1, y2; + vector float s1, s2; + vector float c1, c2; + vector float m1, m2; + + // load the signal to be chirped + d1 = vec_ld(0, d); + d2 = vec_ld(16, d); + d3 = vec_ld(32, d); + d4 = vec_ld(48, d); + + // calculate the input angle + a1 *= a1 * rate; a2 *= a2 * rate; + a3 *= a3 * rate; a4 *= a4 * rate; + a5 *= a5 * rate; a6 *= a6 * rate; + a7 *= a7 * rate; a8 *= a8 * rate; + + // reduce the angle to the range (-0.5, 0.5) and store to + // memory so we can load it into the vector unit + v[0] = a1 - quickRound(a1, roundVal); + v[1] = a2 - quickRound(a2, roundVal); + v[2] = a3 - quickRound(a3, roundVal); + v[3] = a4 - quickRound(a4, roundVal); + v[4] = a5 - quickRound(a5, roundVal); + v[5] = a6 - quickRound(a6, roundVal); + v[6] = a7 - quickRound(a7, roundVal); + v[7] = a8 - quickRound(a8, roundVal); + + // load angle into the vector unit + x1 = vec_ld(0, v); + x2 = vec_ld(16, v); + + // square to the range [0, 0.25) + y1 = vec_madd(x1, x1, ZERO); + y2 = vec_madd(x2, x2, ZERO); + + // perform the initial polynomial approximations + s1 = vec_madd(x1, + vec_madd(y1, + vec_madd(y1, + vec_madd(y1, SS4, SS3), + SS2), + SS1), + ZERO); + s2 = vec_madd(x2, + vec_madd(y2, + vec_madd(y2, + vec_madd(y2, SS4, SS3), + SS2), + SS1), + ZERO); + c1 = vec_madd(y1, + vec_madd(y1, vec_madd(y1, CC3, CC2), CC1), + ONE); + c2 = vec_madd(y2, + vec_madd(y2, vec_madd(y2, CC3, CC2), CC1), + ONE); + + // permute the loaded data into separate real and complex vectors + dre1 = vec_perm(d1, d2, real); + dim1 = vec_perm(d1, d2, imag); + dre2 = vec_perm(d3, d4, real); + dim2 = vec_perm(d3, d4, imag); + + // perform first angle doubling + x1 = vec_nmsub(s1, s1, vec_madd(c1, c1, ZERO)); + x2 = vec_nmsub(s2, s2, vec_madd(c2, c2, ZERO)); + y1 = vec_madd(TWO, vec_madd(s1, c1, ZERO), ZERO); + y2 = vec_madd(TWO, vec_madd(s2, c2, ZERO), ZERO); + + // calculate scaling factor to correct the magnitude +// m1 = vec_nmsub(y1, y1, vec_nmsub(x1, x1, TWO)); +// m2 = vec_nmsub(y2, y2, vec_nmsub(x2, x2, TWO)); + m1 = vec_recip(vec_madd(y1, y1, vec_madd(x1, x1, ZERO))); + m2 = vec_recip(vec_madd(y2, y2, vec_madd(x2, x2, ZERO))); + + // perform second angle doubling + c1 = vec_nmsub(y1, y1, vec_madd(x1, x1, ZERO)); + c2 = vec_nmsub(y2, y2, vec_madd(x2, x2, ZERO)); + s1 = vec_madd(TWO, vec_madd(y1, x1, ZERO), ZERO); + s2 = vec_madd(TWO, vec_madd(y2, x2, ZERO), ZERO); + + // correct the magnitude (final sine / cosine approximations) + s1 = vec_madd(s1, m1, ZERO); + s2 = vec_madd(s2, m2, ZERO); + c1 = vec_madd(c1, m1, ZERO); + c2 = vec_madd(c2, m2, ZERO); + + // chirp the data + cre1 = vec_nmsub(dim1, s1, vec_madd(dre1, c1, ZERO)); + cre2 = vec_nmsub(dim2, s2, vec_madd(dre2, c2, ZERO)); + cim1 = vec_madd(dim1, c1, vec_madd(dre1, s1, ZERO)); + cim2 = vec_madd(dim2, c2, vec_madd(dre2, s2, ZERO)); + + // permute into interleaved form + cd1 = vec_mergeh(cre1,cim1); + cd2 = vec_mergel(cre1,cim1); + cd3 = vec_mergeh(cre2,cim2); + cd4 = vec_mergel(cre2,cim2); + + // store chirped values + vec_st(cd1, 0, c); + vec_st(cd2, 16, c); + vec_st(cd3, 32, c); + vec_st(cd4, 48, c); + } + + // handle tail elements with scalar code + for (; i < ul_NumDataPoints; ++i) { + double angle = rate * i * i * 0.5; + double s = sin(angle); + double c = cos(angle); + float re = cx_DataArray[i][0]; + float im = cx_DataArray[i][1]; + + cx_ChirpDataArray[i][0] = re * c - im * s; + cx_ChirpDataArray[i][1] = re * s + im * c; + } + analysis_state.FLOP_counter+=12.0*ul_NumDataPoints; + } + return 0; +} + + +int v_vChirpDataG4( + sah_complex* cx_DataArray, + sah_complex* cx_ChirpDataArray, + int chirp_rate_ind, + double chirp_rate, + int ul_NumDataPoints, + double sample_rate + ) { + // int offset, int numPoints, double chirpRate + int i; + if (!AltiVec_Available()) return UNSUPPORTED_FUNCTION; + + if (chirp_rate_ind == 0) { + memcpy(cx_ChirpDataArray, + cx_DataArray, + (int)ul_NumDataPoints * sizeof(sah_complex) + ); + } else { + int vEnd; + const vector unsigned char real = (vector unsigned char) (0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27); + const vector unsigned char imag = (vector unsigned char) (4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31); + double rate = chirp_rate * 0.5 / (sample_rate * sample_rate); + double roundVal = rate >= 0.0 ? TWO_TO_52 : -TWO_TO_52; + + // main vectorised loop + vEnd = ul_NumDataPoints - (ul_NumDataPoints & 7); + for (i = 0; i < vEnd; i += 8) { + const float *d = (const float *) (cx_DataArray + i); + float *c = (float *) (cx_ChirpDataArray + i); + double a1 = i; + double a2 = i + 1.0; + double a3 = i + 2.0; + double a4 = i + 3.0; + double a5 = i + 4.0; + double a6 = i + 5.0; + double a7 = i + 6.0; + double a8 = i + 7.0; + float v[8] __attribute__ ((aligned (16))); + vector float d1, d2, d3, d4; + vector float cd1, cd2, cd3, cd4; + vector float dre1, dre2; + vector float dim1, dim2; + vector float cre1, cre2; + vector float cim1, cim2; + vector float x1, x2; + vector float y1, y2; + vector float s1, s2; + vector float c1, c2; + vector float m1, m2; + + // prefetch next 256 bytes into L1 cache + vec_dstt(d, 0x10010100, 0); + + // load the signal to be chirped + d1 = vec_ld(0, d); + d2 = vec_ld(16, d); + d3 = vec_ld(32, d); + d4 = vec_ld(48, d); + + // calculate the input angle + a1 *= a1 * rate; a2 *= a2 * rate; + a3 *= a3 * rate; a4 *= a4 * rate; + a5 *= a5 * rate; a6 *= a6 * rate; + a7 *= a7 * rate; a8 *= a8 * rate; + + // reduce the angle to the range (-0.5, 0.5) and store to + // memory so we can load it into the vector unit + v[0] = a1 - quickRound(a1, roundVal); + v[1] = a2 - quickRound(a2, roundVal); + v[2] = a3 - quickRound(a3, roundVal); + v[3] = a4 - quickRound(a4, roundVal); + v[4] = a5 - quickRound(a5, roundVal); + v[5] = a6 - quickRound(a6, roundVal); + v[6] = a7 - quickRound(a7, roundVal); + v[7] = a8 - quickRound(a8, roundVal); + + // load angle into the vector unit + x1 = vec_ld(0, v); + x2 = vec_ld(16, v); + + // square to the range [0, 0.25) + y1 = vec_madd(x1, x1, ZERO); + y2 = vec_madd(x2, x2, ZERO); + + // perform the initial polynomial approximations + s1 = vec_madd(x1, + vec_madd(y1, + vec_madd(y1, + vec_madd(y1, SS4, SS3), + SS2), + SS1), + ZERO); + s2 = vec_madd(x2, + vec_madd(y2, + vec_madd(y2, + vec_madd(y2, SS4, SS3), + SS2), + SS1), + ZERO); + c1 = vec_madd(y1, + vec_madd(y1, vec_madd(y1, CC3, CC2), CC1), + ONE); + c2 = vec_madd(y2, + vec_madd(y2, vec_madd(y2, CC3, CC2), CC1), + ONE); + + // permute the loaded data into separate real and complex vectors + dre1 = vec_perm(d1, d2, real); + dim1 = vec_perm(d1, d2, imag); + dre2 = vec_perm(d3, d4, real); + dim2 = vec_perm(d3, d4, imag); + + // perform first angle doubling + x1 = vec_nmsub(s1, s1, vec_madd(c1, c1, ZERO)); + x2 = vec_nmsub(s2, s2, vec_madd(c2, c2, ZERO)); + y1 = vec_madd(TWO, vec_madd(s1, c1, ZERO), ZERO); + y2 = vec_madd(TWO, vec_madd(s2, c2, ZERO), ZERO); + + // calculate scaling factor to correct the magnitude + // m1 = vec_nmsub(y1, y1, vec_nmsub(x1, x1, TWO)); + // m2 = vec_nmsub(y2, y2, vec_nmsub(x2, x2, TWO)); + m1 = vec_recip(vec_madd(y1, y1, vec_madd(x1, x1, ZERO))); + m2 = vec_recip(vec_madd(y2, y2, vec_madd(x2, x2, ZERO))); + + // zero out a spot for our chirped data in the cache + __dcbz(0, c); + __dcbz(32, c); + + // perform second angle doubling + c1 = vec_nmsub(y1, y1, vec_madd(x1, x1, ZERO)); + c2 = vec_nmsub(y2, y2, vec_madd(x2, x2, ZERO)); + s1 = vec_madd(TWO, vec_madd(y1, x1, ZERO), ZERO); + s2 = vec_madd(TWO, vec_madd(y2, x2, ZERO), ZERO); + + // correct the magnitude (final sine / cosine approximations) + s1 = vec_madd(s1, m1, ZERO); + s2 = vec_madd(s2, m2, ZERO); + c1 = vec_madd(c1, m1, ZERO); + c2 = vec_madd(c2, m2, ZERO); + + // chirp the data + cre1 = vec_nmsub(dim1, s1, vec_madd(dre1, c1, ZERO)); + cre2 = vec_nmsub(dim2, s2, vec_madd(dre2, c2, ZERO)); + cim1 = vec_madd(dim1, c1, vec_madd(dre1, s1, ZERO)); + cim2 = vec_madd(dim2, c2, vec_madd(dre2, s2, ZERO)); + + // permute into interleaved form + cd1 = vec_mergeh(cre1,cim1); + cd2 = vec_mergel(cre1,cim1); + cd3 = vec_mergeh(cre2,cim2); + cd4 = vec_mergel(cre2,cim2); + + // store chirped values + vec_st(cd1, 0, c); + vec_st(cd2, 16, c); + vec_st(cd3, 32, c); + vec_st(cd4, 48, c); + } + + // handle tail elements with scalar code + for (; i < ul_NumDataPoints; ++i) { + double angle = rate * i * i * 0.5; + double s = sin(angle); + double c = cos(angle); + float re = cx_DataArray[i][0]; + float im = cx_DataArray[i][1]; + + cx_ChirpDataArray[i][0] = re * c - im * s; + cx_ChirpDataArray[i][1] = re * s + im * c; + } + analysis_state.FLOP_counter+=12.0*ul_NumDataPoints; + } + return 0; +} + + +int v_vChirpDataG5( + sah_complex* cx_DataArray, + sah_complex* cx_ChirpDataArray, + int chirp_rate_ind, + double chirp_rate, + int ul_NumDataPoints, + double sample_rate + ) { + // int offset, int numPoints, double chirpRate + int i; + if (!AltiVec_Available()) return UNSUPPORTED_FUNCTION; + + if (chirp_rate_ind == 0) { + memcpy(cx_ChirpDataArray, + cx_DataArray, + (int)ul_NumDataPoints * sizeof(sah_complex) + ); + } else { + int vEnd; + const vector unsigned char real = (vector unsigned char) (0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27); + const vector unsigned char imag = (vector unsigned char) (4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31); + double rate = chirp_rate * 0.5 / (sample_rate * sample_rate); + double roundVal = rate >= 0.0 ? TWO_TO_52 : -TWO_TO_52; + + // main vectorised loop + vEnd = ul_NumDataPoints - (ul_NumDataPoints & 15); + for (i = 0; i < vEnd; i += 16) { + const float *d = (const float *) (cx_DataArray + i); + float *c = (float *) (cx_ChirpDataArray + i); + double a1 = i; + double a2 = i + 1.0; + double a3 = i + 2.0; + double a4 = i + 3.0; + double a5 = i + 4.0; + double a6 = i + 5.0; + double a7 = i + 6.0; + double a8 = i + 7.0; + double a9 = i + 8.0; + double a10 = i + 9.0; + double a11 = i + 10.0; + double a12 = i + 11.0; + double a13 = i + 12.0; + double a14 = i + 13.0; + double a15 = i + 14.0; + double a16 = i + 15.0; + float v[16] __attribute__ ((aligned (16))); + vector float d1, d2, d3, d4, d5, d6, d7, d8; + vector float cd1, cd2, cd3, cd4, cd5, cd6, cd7, cd8; + vector float dre1, dre2, dre3, dre4; + vector float dim1, dim2, dim3, dim4; + vector float cre1, cre2, cre3, cre4; + vector float cim1, cim2, cim3, cim4; + vector float x1, x2, x3, x4; + vector float y1, y2, y3, y4; + vector float s1, s2, s3, s4; + vector float c1, c2, c3, c4; + vector float m1, m2, m3, m4; + + // load the signal to be chirped + d1 = vec_ld(0, d); + d2 = vec_ld(16, d); + d3 = vec_ld(32, d); + d4 = vec_ld(48, d); + d5 = vec_ld(64, d); + d6 = vec_ld(80, d); + d7 = vec_ld(96, d); + d8 = vec_ld(112, d); + + // calculate the input angle + a1 *= a1 * rate; a2 *= a2 * rate; + a3 *= a3 * rate; a4 *= a4 * rate; + a5 *= a5 * rate; a6 *= a6 * rate; + a7 *= a7 * rate; a8 *= a8 * rate; + a9 *= a9 * rate; a10 *= a10 * rate; + a11 *= a11 * rate; a12 *= a12 * rate; + a13 *= a13 * rate; a14 *= a14 * rate; + a15 *= a15 * rate; a16 *= a16 * rate; + + // reduce the angle to the range (-0.5, 0.5) and store to + // memory so we can load it into the vector unit + v[0] = a1 - quickRound(a1, roundVal); + v[1] = a2 - quickRound(a2, roundVal); + v[2] = a3 - quickRound(a3, roundVal); + v[3] = a4 - quickRound(a4, roundVal); + v[4] = a5 - quickRound(a5, roundVal); + v[5] = a6 - quickRound(a6, roundVal); + v[6] = a7 - quickRound(a7, roundVal); + v[7] = a8 - quickRound(a8, roundVal); + v[8] = a9 - quickRound(a9, roundVal); + v[9] = a10 - quickRound(a10, roundVal); + v[10] = a11 - quickRound(a11, roundVal); + v[11] = a12 - quickRound(a12, roundVal); + v[12] = a13 - quickRound(a13, roundVal); + v[13] = a14 - quickRound(a14, roundVal); + v[14] = a15 - quickRound(a15, roundVal); + v[15] = a16 - quickRound(a16, roundVal); + + // load angle into the vector unit + x1 = vec_ld(0, v); + x2 = vec_ld(16, v); + x3 = vec_ld(32, v); + x4 = vec_ld(48, v); + + // square to the range [0, 0.25) + y1 = vec_madd(x1, x1, ZERO); + y2 = vec_madd(x2, x2, ZERO); + y3 = vec_madd(x3, x3, ZERO); + y4 = vec_madd(x4, x4, ZERO); + + // perform the initial polynomial approximations + s1 = vec_madd(x1, + vec_madd(y1, + vec_madd(y1, + vec_madd(y1, SS4, SS3), + SS2), + SS1), + ZERO); + s2 = vec_madd(x2, + vec_madd(y2, + vec_madd(y2, + vec_madd(y2, SS4, SS3), + SS2), + SS1), + ZERO); + c1 = vec_madd(y1, + vec_madd(y1, vec_madd(y1, CC3, CC2), CC1), + ONE); + c2 = vec_madd(y2, + vec_madd(y2, vec_madd(y2, CC3, CC2), CC1), + ONE); + s3 = vec_madd(x3, + vec_madd(y3, + vec_madd(y3, + vec_madd(y3, SS4, SS3), + SS2), + SS1), + ZERO); + s4 = vec_madd(x4, + vec_madd(y4, + vec_madd(y4, + vec_madd(y4, SS4, SS3), + SS2), + SS1), + ZERO); + c3 = vec_madd(y3, + vec_madd(y3, vec_madd(y3, CC3, CC2), CC1), + ONE); + c4 = vec_madd(y4, + vec_madd(y4, vec_madd(y4, CC3, CC2), CC1), + ONE); + + // permute the loaded data into separate real and complex vectors + dre1 = vec_perm(d1, d2, real); + dim1 = vec_perm(d1, d2, imag); + dre2 = vec_perm(d3, d4, real); + dim2 = vec_perm(d3, d4, imag); + dre3 = vec_perm(d5, d6, real); + dim3 = vec_perm(d5, d6, imag); + dre4 = vec_perm(d7, d8, real); + dim4 = vec_perm(d7, d8, imag); + + // perform first angle doubling + x1 = vec_nmsub(s1, s1, vec_madd(c1, c1, ZERO)); + x2 = vec_nmsub(s2, s2, vec_madd(c2, c2, ZERO)); + y1 = vec_madd(TWO, vec_madd(s1, c1, ZERO), ZERO); + y2 = vec_madd(TWO, vec_madd(s2, c2, ZERO), ZERO); + x3 = vec_nmsub(s3, s3, vec_madd(c3, c3, ZERO)); + x4 = vec_nmsub(s4, s4, vec_madd(c4, c4, ZERO)); + y3 = vec_madd(TWO, vec_madd(s3, c3, ZERO), ZERO); + y4 = vec_madd(TWO, vec_madd(s4, c4, ZERO), ZERO); + + // calculate scaling factor to correct the magnitude + // m1 = vec_nmsub(y1, y1, vec_nmsub(x1, x1, TWO)); + // m2 = vec_nmsub(y2, y2, vec_nmsub(x2, x2, TWO)); + m1 = vec_recip(vec_madd(y1, y1, vec_madd(x1, x1, ZERO))); + m2 = vec_recip(vec_madd(y2, y2, vec_madd(x2, x2, ZERO))); + m3 = vec_recip(vec_madd(y3, y3, vec_madd(x3, x3, ZERO))); + m4 = vec_recip(vec_madd(y4, y4, vec_madd(x4, x4, ZERO))); + + // perform second angle doubling + c1 = vec_nmsub(y1, y1, vec_madd(x1, x1, ZERO)); + c2 = vec_nmsub(y2, y2, vec_madd(x2, x2, ZERO)); + s1 = vec_madd(TWO, vec_madd(y1, x1, ZERO), ZERO); + s2 = vec_madd(TWO, vec_madd(y2, x2, ZERO), ZERO); + c3 = vec_nmsub(y3, y3, vec_madd(x3, x3, ZERO)); + c4 = vec_nmsub(y4, y4, vec_madd(x4, x4, ZERO)); + s3 = vec_madd(TWO, vec_madd(y3, x3, ZERO), ZERO); + s4 = vec_madd(TWO, vec_madd(y4, x4, ZERO), ZERO); + + // correct the magnitude (final sine / cosine approximations) + s1 = vec_madd(s1, m1, ZERO); + s2 = vec_madd(s2, m2, ZERO); + c1 = vec_madd(c1, m1, ZERO); + c2 = vec_madd(c2, m2, ZERO); + s3 = vec_madd(s3, m3, ZERO); + s4 = vec_madd(s4, m4, ZERO); + c3 = vec_madd(c3, m3, ZERO); + c4 = vec_madd(c4, m4, ZERO); + + // chirp the data + cre1 = vec_nmsub(dim1, s1, vec_madd(dre1, c1, ZERO)); + cre2 = vec_nmsub(dim2, s2, vec_madd(dre2, c2, ZERO)); + cim1 = vec_madd(dim1, c1, vec_madd(dre1, s1, ZERO)); + cim2 = vec_madd(dim2, c2, vec_madd(dre2, s2, ZERO)); + cre3 = vec_nmsub(dim3, s3, vec_madd(dre3, c3, ZERO)); + cre4 = vec_nmsub(dim4, s4, vec_madd(dre4, c4, ZERO)); + cim3 = vec_madd(dim3, c3, vec_madd(dre3, s3, ZERO)); + cim4 = vec_madd(dim4, c4, vec_madd(dre4, s4, ZERO)); + + // permute into interleaved form + cd1 = vec_mergeh(cre1,cim1); + cd2 = vec_mergel(cre1,cim1); + cd3 = vec_mergeh(cre2,cim2); + cd4 = vec_mergel(cre2,cim2); + cd5 = vec_mergeh(cre3,cim3); + cd6 = vec_mergel(cre3,cim3); + cd7 = vec_mergeh(cre4,cim4); + cd8 = vec_mergel(cre4,cim4); + + // store chirped values + vec_st(cd1, 0, c); + vec_st(cd2, 16, c); + vec_st(cd3, 32, c); + vec_st(cd4, 48, c); + vec_st(cd5, 64, c); + vec_st(cd6, 80, c); + vec_st(cd7, 96, c); + vec_st(cd8, 112, c); + } + + // handle tail elements with scalar code + for (; i < ul_NumDataPoints; ++i) { + double angle = rate * i * i * 0.5; + double s = sin(angle); + double c = cos(angle); + float re = cx_DataArray[i][0]; + float im = cx_DataArray[i][1]; + + cx_ChirpDataArray[i][0] = re * c - im * s; + cx_ChirpDataArray[i][1] = re * s + im * c; + } + analysis_state.FLOP_counter+=12.0*ul_NumDataPoints; + } + return 0; +} + +float f_vGetChiSq( + float fp_PoT[], + int ul_PowerLen, + int ul_TOffset, + float f_PeakPower, + float f_MeanPower, + float f_weight[], + float *xsq_null=0 +) { + // We calculate our assumed gaussian powers + // on the fly as we try to fit them to the + // actual powers at each point along the PoT. + + if (!AltiVec_Available()) return UNSUPPORTED_FUNCTION; + + int i; + int vEnd, vul_PowerLen; + float f_ChiSq=0,f_null_hyp=0, f_PredictedPower; + vector float v_PeakPower, v_MeanPower, v_rMeanPower, v_rebin; + vector float v_TempChiSq = ZERO, v_ChiSq, v_temp_null_hyp = ZERO, v_null_hyp, v_PredictedPower, v_weight; + double rebin=swi.nsamples/ChirpFftPairs[analysis_state.icfft].FftLen + /ul_PowerLen; + + // splat Altivec versions of function constants + v_PeakPower = vec_fpsplat(f_PeakPower); + v_MeanPower = vec_fpsplat(f_MeanPower); + v_rMeanPower = vec_fpsplat(1.0f / f_MeanPower); + v_rebin = vec_fpsplat((float) rebin); + + // set up unaligned loads for weight array + int offwt = PoTInfo.GaussTOffsetStop - 1 - ul_TOffset; + vector float msqwt = vec_ld(0, f_weight + offwt); + vector unsigned char maskwt = vec_add(vec_lvsl(-1L, f_weight + offwt), vec_splat_u8(1)); + + vul_PowerLen = ul_PowerLen - (ul_PowerLen & 0x3); + for (i = 0; i < vul_PowerLen; i += 4) { + const float *p = fp_PoT + i; + const float *wt = f_weight + offwt + i; + vector float lsqwt = vec_ld(15, wt); + vector float v_PoT = vec_ld(0, p); + vector float v_weight = vec_perm(msqwt, lsqwt, maskwt); + vector float v_noise, v_rnoise; + + v_PredictedPower = vec_madd(v_PeakPower, v_weight, v_MeanPower); + v_PredictedPower = vec_madd(v_PredictedPower, v_rMeanPower, ZERO); + v_noise = vec_madd(vec_sqrt(vec_sub(vec_max(v_PredictedPower, ONE), ONE)), TWO, ONE); + v_rnoise = vec_recip(v_noise); + + v_TempChiSq = vec_madd(vec_madd(vec_madd(vec_nmsub(v_PoT, v_rMeanPower, v_PredictedPower), + vec_nmsub(v_PoT, v_rMeanPower, v_PredictedPower), + ZERO), + v_rnoise, ZERO), + v_rebin, + v_TempChiSq); + v_temp_null_hyp = vec_madd(vec_madd(vec_madd(vec_nmsub(v_PoT, v_rMeanPower, ONE), + vec_nmsub(v_PoT, v_rMeanPower, ONE), + ZERO), + v_rnoise, ZERO), + v_rebin, + v_temp_null_hyp); + + msqwt = lsqwt; + } + v_ChiSq = v_TempChiSq; + v_null_hyp = v_temp_null_hyp; + + // handle tail elements + for (; i < ul_PowerLen; i++) { + f_PredictedPower = f_MeanPower + f_PeakPower * f_weight[offwt+i] ; + // ChiSq in this realm is: + // sum[0:i]( (observed power - expected power)^2 / expected variance ) + // The power of a signal is: + // power = (noise + signal)^2 = noise^2 + signal^2 + 2*noise*signal + // With mean power normalization, noise becomes 1, leaving: + // power = signal^2 +or- 2*signal + 1 + f_PredictedPower/=f_MeanPower; + double signal=f_PredictedPower; + double noise=(2.0*sqrt(std::max(f_PredictedPower,1.0f)-1)+1); + + f_ChiSq += + (static_cast(rebin)*SQUARE(fp_PoT[i]/f_MeanPower - signal)/noise); + f_null_hyp+= + (static_cast(rebin)*SQUARE(fp_PoT[i]/f_MeanPower-1)/noise); + } + + // sum vector and scalar elements + float *vp_ChiSq = (float *) &v_ChiSq; + float *vp_null_hyp = (float *) &v_null_hyp; + f_ChiSq += vp_ChiSq[0] + vp_ChiSq[1] + vp_ChiSq[2] + vp_ChiSq[3]; + f_null_hyp += vp_null_hyp[0] + vp_null_hyp[1] + vp_null_hyp[2] + vp_null_hyp[3]; + + analysis_state.FLOP_counter+=20.0*ul_PowerLen+5; + f_ChiSq/=ul_PowerLen; + f_null_hyp/=ul_PowerLen; + + if (xsq_null) *xsq_null=f_null_hyp; + return f_ChiSq; +} + + +float f_vGetTrueMean( + float fp_PoT[], + int ul_PowerLen, + float f_TotalPower, + int ul_TOffset, + int ul_ExcludeLen + ) { + // TrueMean is the mean power of the data set minus all power + // out to ExcludeLen from our current TOffset. + if (!AltiVec_Available()) return UNSUPPORTED_FUNCTION; + int i, i_start, i_lim, vStart, vEnd; + float f_ExcludePower = 0; + vector float v_TempExcludePower = ZERO, v_ExcludePower; + + // take care that we do not add to exclude power beyond PoT bounds! + i_start = std::max(ul_TOffset - ul_ExcludeLen, 0); + i_lim = std::min(ul_TOffset + ul_ExcludeLen + 1, swi.analysis_cfg.gauss_pot_length); + + vStart = i_start + 3; + vStart = vStart - (vStart & 3); + vEnd = i_lim - (i_lim & 3); + + // handle leading elements + for (i = i_start; i < vStart; i++) { + f_ExcludePower += fp_PoT[i]; + } + for (; i < vEnd; i += 4) { + v_TempExcludePower = vec_add(vec_ld(0, fp_PoT + i), v_TempExcludePower); + } + v_ExcludePower = v_TempExcludePower; + // handle tail elements + for (; i < i_lim; i++) { + f_ExcludePower += fp_PoT[i]; + } + + // sum vector and scalar elements + float *vp_ExcludePower = (float *) &v_ExcludePower; + f_ExcludePower += vp_ExcludePower[0] + vp_ExcludePower[1] + vp_ExcludePower[2] + vp_ExcludePower[3]; + + analysis_state.FLOP_counter+=(double)(i_lim-i_start+5); + return((f_TotalPower - f_ExcludePower) / (ul_PowerLen - (i - i_start))); +} + + + + + +int vGaussFit( + float * fp_PoT, + int ul_FftLength, + int ul_PoT +) { + int i, retval; + BOOLEAN b_IsAPeak; + float f_NormMaxPower; + float f_null_hyp; + + if (!AltiVec_Available()) return UNSUPPORTED_FUNCTION; + + int ul_TOffset; + int iSigma = static_cast(floor(PoTInfo.GaussSigma+0.5)); + double diSigma = iSigma; + float f_GroupSum, f_GroupMax; + int i_f, iPeakLoc; + + float f_TotalPower, + f_TrueMean, + f_ChiSq, + f_PeakPower; + float f_rMeanPower; + float f_TotalPowerOverTrueMeanElems; + vector float v_TotalPower; + vector float v_rMeanPower; + vector float v_PowerThresh; + + // For setiathome the Sigma and Gaussian PoT length don't change during + // a run of the application, so these frequently used values can be + // precalculated and kept. + static float f_PeakScaleFactor; + static float *f_weight; + static float *f_vweight; + static float *f_PeakFilter; + static float *f_BoxFilter; + static float *f_corr; + static float *f_swsum; + static float f_rTrueMeanElems = 1.0f / (swi.analysis_cfg.gauss_pot_length - (4*iSigma+1)); + + if (!f_weight) { + f_PeakScaleFactor = f_GetPeakScaleFactor(static_cast(PoTInfo.GaussSigma)); + // Altivec code uses double-sided f_weight to make memory accesses simpler + f_vweight = reinterpret_cast(malloc((2*PoTInfo.GaussTOffsetStop-1)*sizeof(float))); + if (!f_vweight) SETIERROR(MALLOC_FAILED, "!f_vweight"); + f_vweight[PoTInfo.GaussTOffsetStop-1] = 1; + + f_PeakFilter = reinterpret_cast(malloc((2*iSigma+1)*sizeof(float))); + if (!f_PeakFilter) SETIERROR(MALLOC_FAILED, "!f_PeakFilter"); + f_BoxFilter = reinterpret_cast(malloc((4*iSigma+1)*sizeof(float))); + if (!f_BoxFilter) SETIERROR(MALLOC_FAILED, "!f_BoxFilter"); + f_PeakFilter[iSigma] = f_PeakScaleFactor; + f_BoxFilter[2*iSigma] = f_rTrueMeanElems; + + f_weight = reinterpret_cast(malloc(PoTInfo.GaussTOffsetStop*sizeof(float))); + if (!f_weight) SETIERROR(MALLOC_FAILED, "!f_weight"); + f_weight[0] = 1; + + for (i = 1; i <= iSigma; i++) { + float weight = static_cast(EXP(i, 0, PoTInfo.GaussSigmaSq)); + f_vweight[PoTInfo.GaussTOffsetStop-1+i] = weight; + f_vweight[PoTInfo.GaussTOffsetStop-1-i] = weight; + f_PeakFilter[iSigma+i] = weight * f_PeakScaleFactor; + f_PeakFilter[iSigma-i] = weight * f_PeakScaleFactor; + f_BoxFilter[2*iSigma+i] = f_rTrueMeanElems; + f_BoxFilter[2*iSigma-i] = f_rTrueMeanElems; + + f_weight[i] = weight; + } + + for (; i <= 2*iSigma; i++) { + float weight = static_cast(EXP(i, 0, PoTInfo.GaussSigmaSq)); + f_vweight[PoTInfo.GaussTOffsetStop-1+i] = weight; + f_vweight[PoTInfo.GaussTOffsetStop-1-i] = weight; + f_BoxFilter[2*iSigma+i] = f_rTrueMeanElems; + f_BoxFilter[2*iSigma-i] = f_rTrueMeanElems; + + f_weight[i] = weight; + } + + for (; i < PoTInfo.GaussTOffsetStop; i++) { + float weight = static_cast(EXP(i, 0, PoTInfo.GaussSigmaSq)); + f_vweight[PoTInfo.GaussTOffsetStop-1+i] = weight; + f_vweight[PoTInfo.GaussTOffsetStop-1-i] = weight; + + f_weight[i] = weight; + } + } + + // Find reciprocal of mean over power-of-time array + // Assumes that swi.analysis_cfg.gauss_pot_length is a multiple of 4 + v_TotalPower = ZERO; + for (i = 0; i < swi.analysis_cfg.gauss_pot_length; i += 4) { + const float *p = fp_PoT + i; + vector float v_PoT = vec_ld(0, p); + v_TotalPower = vec_add(v_TotalPower, v_PoT); + } + v_TotalPower = vec_add(v_TotalPower, vec_sld(v_TotalPower, v_TotalPower, 8)); + v_TotalPower = vec_add(v_TotalPower, vec_sld(v_TotalPower, v_TotalPower, 4)); + v_rMeanPower = vec_madd(vec_recip(v_TotalPower), + vec_fpsplat((float) swi.analysis_cfg.gauss_pot_length), ZERO); + + // Normalize power-of-time and check for the existence + // of at least 1 peak. + b_IsAPeak = false; + v_PowerThresh = vec_fpsplat(PoTInfo.GaussPowerThresh); + for (i = 0; i < swi.analysis_cfg.gauss_pot_length; i += 4) { + float *p = fp_PoT + i; + vector float v_PoT = vec_ld(0, p); + v_PoT = vec_madd(v_PoT, v_rMeanPower, ZERO); + b_IsAPeak |= vec_any_gt(v_PoT, v_PowerThresh); + vec_st(v_PoT, 0, p); + } + analysis_state.FLOP_counter+=3.0*swi.analysis_cfg.gauss_pot_length+2; + + if (!b_IsAPeak) { + //printf("no peak\n"); + return 0; // no peak - bail on this PoT + } + + // Recalculate Total Power across normalized array. + // Given that powers are positive, f_TotalPower will + // end up being == swi.analysis_cfg.gauss_pot_length. + f_TotalPower = 0; + f_NormMaxPower = 0; + // Also locate group with the highest sum for use in second bailout check. + f_GroupSum = 0; + f_GroupMax = 0; + for (i = 0, i_f = -iSigma; i < swi.analysis_cfg.gauss_pot_length; i++, i_f++) { + f_TotalPower += fp_PoT[i]; + if(fp_PoT[i] > f_NormMaxPower) f_NormMaxPower = fp_PoT[i]; + f_GroupSum += fp_PoT[i] - ((i_f < 0) ? 0.0f : fp_PoT[i_f]); + if (f_GroupSum > f_GroupMax) { + f_GroupMax = f_GroupSum; + iPeakLoc = i - iSigma/2; + } + } + f_TotalPowerOverTrueMeanElems = f_TotalPower * f_rTrueMeanElems; + + // Check at the group peak location whether data may contain Gaussians + // (but only after the first hurry-up Gaussian has been set for graphics) + + if (best_gauss->display_power_thresh != 0) { + iPeakLoc = std::max(PoTInfo.GaussTOffsetStart, + (std::min(PoTInfo.GaussTOffsetStop - 1, iPeakLoc))); + + f_TrueMean = f_vGetTrueMean( + fp_PoT, + swi.analysis_cfg.gauss_pot_length, + f_TotalPower, + iPeakLoc, + 2 * iSigma + ); + + f_PeakPower = f_GetPeak( + fp_PoT, + iPeakLoc, + iSigma, + f_TrueMean, + f_PeakScaleFactor, + f_weight + ); + + analysis_state.FLOP_counter+=5.0*swi.analysis_cfg.gauss_pot_length+5; + + if (f_PeakPower < f_TrueMean * best_gauss->display_power_thresh*0.5f) { + return 0; // not even a weak peak at max group - bail on this PoT + } + } + + f_corr = reinterpret_cast(malloc((PoTInfo.GaussTOffsetStop - PoTInfo.GaussTOffsetStart)*sizeof(float))); + f_swsum = reinterpret_cast(malloc((swi.analysis_cfg.gauss_pot_length-4*iSigma)*sizeof(float))); + conv(fp_PoT, 1, f_PeakFilter, 1, f_corr, 1, + PoTInfo.GaussTOffsetStop - PoTInfo.GaussTOffsetStart, 2*iSigma+1); + conv(fp_PoT, 1, f_BoxFilter, 1, f_swsum, 1, + swi.analysis_cfg.gauss_pot_length-4*iSigma, 4*iSigma+1); + + // slide dynamic gaussian across the Power Of Time array + double loop_flops = 0; + float display_power_thresh = best_gauss->display_power_thresh; + float f_tempTotalPowerOverTrueMeanElems = f_TotalPowerOverTrueMeanElems; + for (ul_TOffset = PoTInfo.GaussTOffsetStart; + ul_TOffset < PoTInfo.GaussTOffsetStop; + ul_TOffset++ + ) { + + // TrueMean is the mean power of the data set minus all power + // out to 2 sigma from our current TOffset. + if ((ul_TOffset - 2 * iSigma) < 0 || (ul_TOffset + 2 * iSigma) >= swi.analysis_cfg.gauss_pot_length) { + f_TrueMean = f_vGetTrueMean( + fp_PoT, + swi.analysis_cfg.gauss_pot_length, + f_TotalPower, + ul_TOffset, + 2 * iSigma + ); + } else { + f_TrueMean = f_tempTotalPowerOverTrueMeanElems - f_swsum[ul_TOffset - 2 * iSigma]; + loop_flops+=4.0*diSigma+6.0; + } + + f_PeakPower = f_corr[ul_TOffset-iSigma] - f_TrueMean; + loop_flops+=6.0*diSigma; + + // worth looking at ? + if (f_PeakPower < f_TrueMean * display_power_thresh) { + continue; + } + + // bump up the display threshold to its final value. + // We could bump it up only to the gaussian just found, + // but that would cause a lot of time waste + // computing chisq etc. + if (display_power_thresh == 0) { + display_power_thresh = best_gauss->display_power_thresh = PoTInfo.GaussPeakPowerThresh/3; + } + + f_ChiSq = f_vGetChiSq( + fp_PoT, + swi.analysis_cfg.gauss_pot_length, + ul_TOffset, + f_PeakPower, + f_TrueMean, + f_vweight, + &f_null_hyp + ); + + retval = ChooseGaussEvent( + ul_TOffset, + f_PeakPower, + f_TrueMean, + f_ChiSq, + f_null_hyp, + ul_PoT, + static_cast(PoTInfo.GaussSigma), + f_NormMaxPower, + fp_PoT + ); + if (retval) SETIERROR(retval,"from ChooseGaussEvent"); + + } // End of sliding gaussian + + analysis_state.FLOP_counter+=loop_flops; + free(f_corr); + free(f_swsum); + + return 0; + +} // End of vGaussFit() + + +/********************** +* +* Subroutines for pulse folding, refactored by Joe Segur from code by Alex Kan +* +*/ +inline vector unsigned int vec_uisplat(unsigned int ui_Constant) { + vector unsigned char vuc_Splat; + vector unsigned int vui_Constant; + + vuc_Splat = vec_lvsl(0, &ui_Constant); + vui_Constant = vec_lde(0, &ui_Constant); + vuc_Splat = (vector unsigned char) vec_splat((vector unsigned int) vuc_Splat, 0); + vui_Constant = vec_perm(vui_Constant, vui_Constant, vuc_Splat); + + return vui_Constant; +} + +/********************** +* +* foldArrayBy2 - Perform "folds" on 2 adjacent parts of the power over time +* array. Each element in the "folded" array is the sum of the 2 elements +* in the power over time array. Array is folded in-place. +* +* Assumes 16-byte alignment of input array, but offsets within the array may be +* arbitrary. +* +*/ +float foldArrayBy2SPA(float *ss[], struct PoTPlan *P) { + float max; + int vEnd; + vector float tempMaxV = ZERO, maxV; + vector float msq2 = vec_ld(0, ss[1]+P->tmp0); + vector float msqz; + vector unsigned char mask2 = vec_add(vec_lvsl(-1L, ss[1]+P->tmp0), vec_splat_u8(1)); + vector unsigned int tailelem = {0, 1, 2, 3}; + vector unsigned int taillim = vec_uisplat(((P->di-1)&0x3) + 1); + vector unsigned int tailmask; + int i = 0, index = 0; + + // int d_elemsWritten = 0; + const float *p1 = ss[1]+P->offset, *p2 = ss[1]+P->tmp0; + float *pst = P->dest; + vector float lsq2, x1, x2, xs, zst; + +#define F2_STAGE1 x1 = vec_ld(0, p1); lsq2 = vec_ld(15, p2); i += 4; p1 += 4; p2 += 4; +#define F2_STAGE2 x2 = vec_perm(msq2, lsq2, mask2); msq2 = lsq2; xs = vec_add(x1, x2); + // was vec_madd(xs, RECIP_TWO, ZERO); +#define F2_STAGE3 zst = xs; +#define F2_STAGE4 tempMaxV = vec_max(tempMaxV, zst); vec_st(zst, index, pst); pst += 4; + + // software pipelined main loop - omit last stage of tail element + if (P->di-i >= 12) { + F2_STAGE1; + F2_STAGE2; F2_STAGE1; + F2_STAGE3; F2_STAGE2; F2_STAGE1; + while (i < P->di) { + F2_STAGE4; F2_STAGE3; F2_STAGE2; F2_STAGE1; + } + F2_STAGE4; F2_STAGE3; F2_STAGE2; + F2_STAGE4; F2_STAGE3; +// F2_STAGE4; + } else { + // main loop + while (i < P->di-4) { + F2_STAGE1; F2_STAGE2; F2_STAGE3; F2_STAGE4; + } + F2_STAGE1; F2_STAGE2; F2_STAGE3; + } + +#undef F2_STAGE1 +#undef F2_STAGE2 +#undef F2_STAGE3 +#undef F2_STAGE4 + + tailmask = (vector unsigned int) vec_cmplt(tailelem, taillim); + zst = vec_and(zst, (vector float) tailmask); + tempMaxV = vec_max(tempMaxV, zst); + vec_st(zst, index, pst); + + // take the maximum across max and maxV and return it + tempMaxV = vec_max(tempMaxV, vec_sld(tempMaxV, tempMaxV, 8)); + maxV = vec_max(tempMaxV, vec_sld(tempMaxV, tempMaxV, 4)); + float *maxVp = (float *) &maxV; + max = *maxVp; + + return max; +} + +/* Assumes 16-byte alignment of both halves of input array +*/ +float foldArrayBy2SPAL(float *ss[], struct PoTPlan *P) { + float max; + int vEnd; + vector float tempMaxV = ZERO, maxV; + vector unsigned int tailelem = {0, 1, 2, 3}; + vector unsigned int taillim = vec_uisplat(((P->di-1)&0x3) + 1); + vector unsigned int tailmask; + int i = 0, index = 0; + + // int d_elemsWritten = 0; + const float *p1 = ss[1]+P->offset + i, *p2 = ss[1]+P->tmp0 + i; + float *pst = P->dest + i; + vector float lsq1, lsq2, x1, x2, xs, lsqz, zst; + +#define F2_STAGE1 x1 = vec_ld(0, p1); x2 = vec_ld(0, p2); i += 4; p1 += 4; p2 += 4; +#define F2_STAGE2 xs = vec_add(x1, x2); + // was vec_madd(xs, RECIP_TWO, ZERO); +#define F2_STAGE3 zst = xs; +#define F2_STAGE4 tempMaxV = vec_max(tempMaxV, zst); vec_st(zst, index, pst); pst += 4; + + // software pipelined main loop - omit last stage of tail element + if (P->di-i >= 12) { + F2_STAGE1; + F2_STAGE2; F2_STAGE1; + F2_STAGE3; F2_STAGE2; F2_STAGE1; + while (i < P->di) { + F2_STAGE4; F2_STAGE3; F2_STAGE2; F2_STAGE1; + } + F2_STAGE4; F2_STAGE3; F2_STAGE2; + F2_STAGE4; F2_STAGE3; + // F2_STAGE4; + } else { + // main loop + while (i < P->di-4) { + F2_STAGE1; F2_STAGE2; F2_STAGE3; F2_STAGE4; + } + F2_STAGE1; F2_STAGE2; F2_STAGE3; + } + +#undef F2_STAGE1 +#undef F2_STAGE2 +#undef F2_STAGE3 +#undef F2_STAGE4 + + tailmask = (vector unsigned int) vec_cmplt(tailelem, taillim); + zst = vec_and(zst, (vector float) tailmask); + tempMaxV = vec_max(tempMaxV, zst); + vec_st(zst, index, pst); + + // take the maximum across max and maxV and return it + tempMaxV = vec_max(tempMaxV, vec_sld(tempMaxV, tempMaxV, 8)); + maxV = vec_max(tempMaxV, vec_sld(tempMaxV, tempMaxV, 4)); + float *maxVp = (float *) &maxV; + max = *maxVp; + + return max; +} + + +/********************** +* +* foldArrayBy3 - Perform "folds" on 3 adjacent parts of the power over time +* array. Each element in the "folded" array is the sum of the 3 elements +* in the power over time array. +* +* Assumes 16-byte alignment of input and output arrays. +* +*/ +float foldArrayBy3SP(float *ss[], struct PoTPlan *P) { + float max; + int vEnd; + vector float tempMaxV = ZERO, maxV; + vector float msq2 = vec_ld(0, ss[0]+P->tmp0); + vector float msq3 = vec_ld(0, ss[0]+P->tmp1); + vector unsigned char mask2 = vec_add(vec_lvsl(-1L, ss[0]+P->tmp0), vec_splat_u8(1)); + vector unsigned char mask3 = vec_add(vec_lvsl(-1L, ss[0]+P->tmp1), vec_splat_u8(1)); + vector unsigned int tailelem = {0, 1, 2, 3}; + vector unsigned int taillim = vec_uisplat(((P->di-1)&0x3) + 1); + vector unsigned int tailmask; + int i = 0; + + const float *p1 = ss[0], *p2 = ss[0]+P->tmp0, *p3 = ss[0]+P->tmp1; + float *pst = P->dest; + vector float lsq2, lsq3, x1, x2, x3, xs12, xs, z; + +#define F3_STAGE1 lsq2 = vec_ld(15, p2); i += 4; p2 += 4; x1 = vec_ld(0, p1); x2 = vec_perm(msq2, lsq2, mask2); lsq3 = vec_ld(15, p3); p1 += 4; msq2 = lsq2; p3 += 4; xs12 = vec_add(x1, x2); x3 = vec_perm(msq3, lsq3, mask3); msq3 = lsq3; +#define F3_STAGE2 xs = vec_add(xs12, x3); + // was vec_madd(xs, RECIP_THREE, ZERO); +#define F3_STAGE3 z = xs; +#define F3_STAGE4 tempMaxV = vec_max(tempMaxV, z); vec_st(z, 0, pst); pst += 4; + + // software pipelined main loop + if (P->di-i >= 12) { + F3_STAGE1; + F3_STAGE2; F3_STAGE1; + F3_STAGE3; F3_STAGE2; F3_STAGE1; + while (i < P->di) { + F3_STAGE4; F3_STAGE3; F3_STAGE2; F3_STAGE1; + } + F3_STAGE4; F3_STAGE3; F3_STAGE2; + F3_STAGE4; F3_STAGE3; +// F3_STAGE4; + } else { + // main loop + while (i < P->di-4) { + F3_STAGE1; F3_STAGE2; F3_STAGE3; F3_STAGE4; + } + F3_STAGE1; F3_STAGE2; F3_STAGE3; + } + +#undef F3_STAGE1 +#undef F3_STAGE2 +#undef F3_STAGE3 +#undef F3_STAGE4 + + tailmask = (vector unsigned int) vec_cmplt(tailelem, taillim); + z = vec_and(z, (vector float) tailmask); + tempMaxV = vec_max(tempMaxV, z); + vec_st(z, 0, pst); + + // take the maximum across max and maxV and return it + tempMaxV = vec_max(tempMaxV, vec_sld(tempMaxV, tempMaxV, 8)); + maxV = vec_max(tempMaxV, vec_sld(tempMaxV, tempMaxV, 4)); + float *maxVp = (float *) &maxV; + max = *maxVp; + + return max; +} + + +/********************** +* +* foldArrayBy4 - Perform "folds" on 4 adjacent parts of the power over time +* array. Each element in the "folded" array is the sum of the 4 elements +* in the power over time array. +* +* Assumes 16-byte alignment of input and output arrays. +* +*/ +float foldArrayBy4SP(float *ss[], struct PoTPlan *P) { + float max; + int vEnd; + vector float tempMaxV = ZERO, maxV; + vector float msq2 = vec_ld(0, ss[0]+P->tmp0); + vector float msq3 = vec_ld(0, ss[0]+P->tmp1); + vector float msq4 = vec_ld(0, ss[0]+P->tmp2); + vector unsigned char mask2 = vec_add(vec_lvsl(-1L, ss[0]+P->tmp0), vec_splat_u8(1)); + vector unsigned char mask3 = vec_add(vec_lvsl(-1L, ss[0]+P->tmp1), vec_splat_u8(1)); + vector unsigned char mask4 = vec_add(vec_lvsl(-1L, ss[0]+P->tmp2), vec_splat_u8(1)); + vector unsigned int tailelem = {0, 1, 2, 3}; + vector unsigned int taillim = vec_uisplat(((P->di-1)&0x3) + 1); + vector unsigned int tailmask; + int i = 0; + + const float *p1 = ss[0], *p2 = ss[0]+P->tmp0, *p3 = ss[0]+P->tmp1, *p4 = ss[0]+P->tmp2; + float *pst = P->dest; + vector float lsq2, lsq3, lsq4, x1, x2, x3, x4, xs12, xs34, xs, z; + +#define F4_STAGE1 lsq2 = vec_ld(15, p2); lsq3 = vec_ld(15, p3); lsq4 = vec_ld(15, p4); i += 4; p2 += 4; p3 += 4; p4 += 4; x1 = vec_ld(0, p1); x2 = vec_perm(msq2, lsq2, mask2); x3 = vec_perm(msq3, lsq3, mask3); x4 = vec_perm(msq4, lsq4, mask4); p1 += 4; msq2 = lsq2; msq3 = lsq3; msq4 = lsq4; xs12 = vec_add(x1, x2); xs34 = vec_add(x3, x4); +#define F4_STAGE2 xs = vec_add(xs12, xs34); + // was vec_madd(xs, RECIP_FOUR, ZERO); +#define F4_STAGE3 z = xs; +#define F4_STAGE4 tempMaxV = vec_max(tempMaxV, z); vec_st(z, 0, pst); pst += 4; + + // software pipelined main loop + if (P->di-i >= 12) { + F4_STAGE1; + F4_STAGE2; F4_STAGE1; + F4_STAGE3; F4_STAGE2; F4_STAGE1; + while (i < P->di) { + F4_STAGE4; F4_STAGE3; F4_STAGE2; F4_STAGE1; + } + F4_STAGE4; F4_STAGE3; F4_STAGE2; + F4_STAGE4; F4_STAGE3; +// F4_STAGE4; + } else { + // main loop + while (i < P->di-4) { + F4_STAGE1; F4_STAGE2; F4_STAGE3; F4_STAGE4; + } + F4_STAGE1; F4_STAGE2; F4_STAGE3; + } + +#undef F4_STAGE1 +#undef F4_STAGE2 +#undef F4_STAGE3 +#undef F4_STAGE4 + + tailmask = (vector unsigned int) vec_cmplt(tailelem, taillim); + z = vec_and(z, (vector float) tailmask); + tempMaxV = vec_max(tempMaxV, z); + vec_st(z, 0, pst); + + // take the maximum across max and maxV and return it + tempMaxV = vec_max(tempMaxV, vec_sld(tempMaxV, tempMaxV, 8)); + maxV = vec_max(tempMaxV, vec_sld(tempMaxV, tempMaxV, 4)); + float *maxVp = (float *) &maxV; + max = *maxVp; + + return max; +} + + +/********************** +* +* foldArrayBy5 - Perform "folds" on 5 adjacent parts of the power over time +* array. Each element in the "folded" array is the sum of the 5 elements +* in the power over time array. +* +* Assumes 16-byte alignment of input and output arrays. +* +*/ +float foldArrayBy5SP(float *ss[], struct PoTPlan *P) { + float max; + int vEnd; + vector float tempMaxV = ZERO, maxV; + vector float msq2 = vec_ld(0, ss[0]+P->tmp0); + vector float msq3 = vec_ld(0, ss[0]+P->tmp1); + vector float msq4 = vec_ld(0, ss[0]+P->tmp2); + vector float msq5 = vec_ld(0, ss[0]+P->tmp3); + vector unsigned char mask2 = vec_add(vec_lvsl(-1L, ss[0]+P->tmp0), vec_splat_u8(1)); + vector unsigned char mask3 = vec_add(vec_lvsl(-1L, ss[0]+P->tmp1), vec_splat_u8(1)); + vector unsigned char mask4 = vec_add(vec_lvsl(-1L, ss[0]+P->tmp2), vec_splat_u8(1)); + vector unsigned char mask5 = vec_add(vec_lvsl(-1L, ss[0]+P->tmp3), vec_splat_u8(1)); + vector unsigned int tailelem = {0, 1, 2, 3}; + vector unsigned int taillim = vec_uisplat(((P->di-1)&0x3) + 1); + vector unsigned int tailmask; + int i = 0; + + const float *p1 = ss[0], *p2 = ss[0]+P->tmp0, *p3 = ss[0]+P->tmp1, *p4 = ss[0]+P->tmp2, *p5 = ss[0]+P->tmp3; + float *pst = P->dest; + vector float lsq2, lsq3, lsq4, lsq5, x1, x2, x3, x4, x5, xs12, xs34, xs345, xs, z; + +#define F5_STAGE1 lsq3 = vec_ld(15, p3); lsq4 = vec_ld(15, p4); i += 4; p3 += 4; p4 += 4; lsq2 = vec_ld(15, p2); x3 = vec_perm(msq3, lsq3, mask3); x4 = vec_perm(msq4, lsq4, mask4); lsq5 = vec_ld(15, p5); p2 += 4; msq3 = lsq3; msq4 = lsq4; p5 += 4; x1 = vec_ld(0, p1); x2 = vec_perm(msq2, lsq2, mask2); xs34 = vec_add(x3, x4); x5 = vec_perm(msq5, lsq5, mask5); p1 += 4; msq2 = lsq2; msq5 = lsq5; +#define F5_STAGE2 xs12 = vec_add(x1, x2); xs345 = vec_add(xs34, x5); +#define F5_STAGE3 xs = vec_add(xs12, xs345); + // was vec_madd(xs, RECIP_FIVE, ZERO); +#define F5_STAGE4 z = xs; +#define F5_STAGE5 tempMaxV = vec_max(tempMaxV, z); vec_st(z, 0, pst); pst += 4; + + // software pipelined main loop + if (P->di-i >= 16) { + F5_STAGE1; + F5_STAGE2; F5_STAGE1; + F5_STAGE3; F5_STAGE2; F5_STAGE1; + F5_STAGE4; F5_STAGE3; F5_STAGE2; F5_STAGE1; + while (i < P->di) { + F5_STAGE5; F5_STAGE4; F5_STAGE3; F5_STAGE2; F5_STAGE1; + } + F5_STAGE5; F5_STAGE4; F5_STAGE3; F5_STAGE2; + F5_STAGE5; F5_STAGE4; F5_STAGE3; + F5_STAGE5; F5_STAGE4; +// F5_STAGE5; + } else { + // main loop + while (i < P->di-4) { + F5_STAGE1; F5_STAGE2; F5_STAGE3; F5_STAGE4; F5_STAGE5; + } + F5_STAGE1; F5_STAGE2; F5_STAGE3; F5_STAGE4; + } + +#undef F5_STAGE1 +#undef F5_STAGE2 +#undef F5_STAGE3 +#undef F5_STAGE4 +#undef F5_STAGE5 + + tailmask = (vector unsigned int) vec_cmplt(tailelem, taillim); + z = vec_and(z, (vector float) tailmask); + tempMaxV = vec_max(tempMaxV, z); + vec_st(z, 0, pst); + + // take the maximum across max and maxV and return it + tempMaxV = vec_max(tempMaxV, vec_sld(tempMaxV, tempMaxV, 8)); + maxV = vec_max(tempMaxV, vec_sld(tempMaxV, tempMaxV, 4)); + float *maxVp = (float *) &maxV; + max = *maxVp; + + return max; +} + +sum_func AKavTB3[FOLDTBLEN] = { foldArrayBy3SP }; +sum_func AKavTB4[FOLDTBLEN] = { foldArrayBy4SP }; +sum_func AKavTB5[FOLDTBLEN] = { foldArrayBy5SP }; +sum_func AKavTB2[FOLDTBLEN] = { foldArrayBy2SPA }; +sum_func AKavTB2AL[FOLDTBLEN] = { foldArrayBy2SPAL }; + +FoldSet AKavfold = {AKavTB3, AKavTB4, AKavTB5, AKavTB2, AKavTB2AL, "AK AltiVec"}; + + +#endif diff --git a/client/vector/analyzeFuncs_avx.cpp b/client/vector/analyzeFuncs_avx.cpp new file mode 100644 index 0000000..4bcf4ee --- /dev/null +++ b/client/vector/analyzeFuncs_avx.cpp @@ -0,0 +1,1358 @@ +/****************** + * + * analyzeFuncs_avx.cpp + * + * Description: Intel AVX optimzized functions + * CPUs: Intel Core iX xxxx+ + * + */ + +// Copyright 2011 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#include "sah_config.h" + +//JWS: For a release build using this module, compile with -mavx on GCC 4.4 or +// later or whatever is equivalent for the compiler used. Define USE_AVX and +// USE_INTRINSICS also. +// +// For tests on x86 hardware without AVX capability, Intel provides an SDE +// (Software Development Emulator) to do runtime replacement of AVX instructions +// or an avxintrin_emu.h header file which does compile-time replacement of the +// AVX intrinsics. For that latter method, define AVX_EMU to get the header +// file included and build for SSE3 or better. + +// The following is empty if USE_AVX and USE_INTRINSICS are not both defined +#if defined(USE_AVX) && defined (USE_INTRINSICS) + +#include +#include + +#ifdef AVX_EMU +#include "avxintrin_emu.h" +#elif defined(_MSC_VER) +#include +#else +#include +#endif + +#include "s_util.h" +#include "analyzeFuncs_vector.h" +#include "analyzeFuncs.h" +#include "x86_ops.h" +#include "pulsefind.h" + +// ============================================================================= +// JWS: Four variant chirp functions, first expands constants in memory +// +// Using Mendenhall Faster SinCos, coding based on +// v_vChirpData for SSE3 by: Alex Kan +// +int avx_ChirpData_a( + sah_complex * cx_DataArray, + sah_complex * cx_ChirpDataArray, + int chirp_rate_ind, + const double chirp_rate, + int ul_NumDataPoints, + const double sample_rate +) { + int i, vEnd; + + if (chirp_rate_ind == 0) { + memcpy(cx_ChirpDataArray, cx_DataArray, (int)ul_NumDataPoints * sizeof(sah_complex) ); + return 0; + } + + const double srate = chirp_rate * 0.5 / (sample_rate * sample_rate); + + __m256 ss1fA = _mm256_set1_ps(1.5707963235f); + __m256 ss2fA = _mm256_set1_ps(-0.645963615f); + __m256 ss3fA = _mm256_set1_ps(0.0796819754f); + __m256 ss4fA = _mm256_set1_ps(-0.0046075748f); + __m256 cc1fA = _mm256_set1_ps(-1.2336977925f); + __m256 cc2fA = _mm256_set1_ps(0.2536086171f); + __m256 cc3fA = _mm256_set1_ps(-0.0204391631f); + __m256 oneA = _mm256_set1_ps(1.0f); + __m256 twoA = _mm256_set1_ps(2.0f); + __m256d eightA = _mm256_set1_pd(8.0); + + __m256d rate = _mm256_broadcast_sd(&srate); + __m256d roundVal = _mm256_set1_pd((srate >= 0.0) ? TWO_TO_52 : -TWO_TO_52); + + // main vectorised loop + vEnd = ul_NumDataPoints - (ul_NumDataPoints & 7); + __m256d di1 = _mm256_set_pd(5.0, 1.0, 4.0, 0.0); // set time patterns for eventual moveldup/movehdup + __m256d di2 = _mm256_set_pd(7.0, 3.0, 6.0, 2.0); + + for (i = 0; i < vEnd; i += 8) { + const float *data = (const float *) (cx_DataArray + i); + float *chirped = (float *) (cx_ChirpDataArray + i); + + __m256d a1, a2; + __m256 d1, d2; + __m256 cd1, cd2; + __m256 td1, td2; + __m256 x; + __m256 y; + __m256 z; + __m256 s; + __m256 c; + __m256 m; + + // load the signal to be chirped + prefetchnta((const void *)( data+64 )); + d1 = _mm256_load_ps(data); + d2 = _mm256_load_ps(data+8); + + // calculate the input angles + a1 = _mm256_mul_pd(_mm256_mul_pd(di1, di1), rate); + a2 = _mm256_mul_pd(_mm256_mul_pd(di2, di2), rate); + + // update time values for next iteration + di1 = _mm256_add_pd(di1, eightA); + di2 = _mm256_add_pd(di2, eightA); + + // reduce the angles to the range (-0.5, 0.5) + a1 = _mm256_sub_pd(a1, _mm256_sub_pd(_mm256_add_pd(a1, roundVal), roundVal)); + a2 = _mm256_sub_pd(a2, _mm256_sub_pd(_mm256_add_pd(a2, roundVal), roundVal)); + + // convert the 2 packed doubles to packed single + x = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm256_cvtpd_ps(a1)), _mm256_cvtpd_ps(a2), 1); + + // square to the range [0, 0.25) + y = _mm256_mul_ps(x, x); + + // perform the initial polynomial approximations + z = _mm256_mul_ps(y, y); + s = _mm256_mul_ps(_mm256_add_ps(_mm256_mul_ps(_mm256_add_ps(_mm256_mul_ps(y, ss4fA), + ss3fA), + z), + _mm256_add_ps(_mm256_mul_ps(y, ss2fA), + ss1fA)), + x); + c = _mm256_add_ps(_mm256_mul_ps(_mm256_add_ps(_mm256_mul_ps(y, cc3fA), + cc2fA), + z), + _mm256_add_ps(_mm256_mul_ps(y, cc1fA), + oneA)); + + // perform first angle doubling + x = _mm256_sub_ps(_mm256_mul_ps(c, c), _mm256_mul_ps(s, s)); + y = _mm256_mul_ps(_mm256_mul_ps(s, c), twoA); + + // calculate scaling factor to correct the magnitude + m = _mm256_sub_ps(_mm256_sub_ps(twoA, _mm256_mul_ps(x, x)), _mm256_mul_ps(y, y)); + + // perform second angle doubling + c = _mm256_sub_ps(_mm256_mul_ps(x, x), _mm256_mul_ps(y, y)); + s = _mm256_mul_ps(_mm256_mul_ps(y, x), twoA); + + // correct the magnitude (final sine / cosine approximations) + s = _mm256_mul_ps(s, m); + c = _mm256_mul_ps(c, m); // c7 c3 c6 c2 c5 c1 c4 c0 + + // chirp the data + cd1 = _mm256_moveldup_ps(c); // c3 c3 c2 c2 c1 c1 c0 c0 + cd2 = _mm256_movehdup_ps(c); // c7 c7 c6 c6 c5 c5 c4 c4 + cd1 = _mm256_mul_ps(cd1, d1); // c3.i3 c3.r3 c2.i2 c2.r2 c1.i1 c1.r1 c0.i0 c0.r0 + cd2 = _mm256_mul_ps(cd2, d2); // c7.i7 c7.r7 c6.i6 c6.r6 c5.i5 c5.r5 c4.i4 c4.r4 + d1 = _mm256_shuffle_ps(d1, d1, 0xb1); + d2 = _mm256_shuffle_ps(d2, d2, 0xb1); + td1 = _mm256_moveldup_ps(s); + td2 = _mm256_movehdup_ps(s); + td1 = _mm256_mul_ps(td1, d1); + td2 = _mm256_mul_ps(td2, d2); + cd1 = _mm256_addsub_ps(cd1, td1); + cd2 = _mm256_addsub_ps(cd2, td2); + + // store chirped values + _mm256_stream_ps(chirped, cd1); + _mm256_stream_ps(chirped+8, cd2); + } + _mm256_zeroupper (); + _mm_sfence(); + + // handle tail elements with scalar code + for ( ; i < ul_NumDataPoints; ++i) { + double angle = srate * i * i * 0.5; + angle -= floor(angle); + angle *= M_PI * 2; + double s = sin(angle); + double c = cos(angle); + float re = cx_DataArray[i][0]; + float im = cx_DataArray[i][1]; + + cx_ChirpDataArray[i][0] = re * c - im * s; + cx_ChirpDataArray[i][1] = re * s + im * c; + } + analysis_state.FLOP_counter+=12.0*ul_NumDataPoints; + + return 0; +} + +// JWS: Second variant, using vbroadcast to expand constants when used +int avx_ChirpData_b( + sah_complex * cx_DataArray, + sah_complex * cx_ChirpDataArray, + int chirp_rate_ind, + const double chirp_rate, + int ul_NumDataPoints, + const double sample_rate +) { + int i, vEnd; + + if (chirp_rate_ind == 0) { + memcpy(cx_ChirpDataArray, cx_DataArray, (int)ul_NumDataPoints * sizeof(sah_complex) ); + return 0; + } + + const double srate = chirp_rate * 0.5 / (sample_rate * sample_rate); + + const float ss1f = 1.5707963235f; + const float ss2f = -0.645963615f; + const float ss3f = 0.0796819754f; + const float ss4f = -0.0046075748f; + const float cc1f = -1.2336977925f; + const float cc2f = 0.2536086171f; + const float cc3f = -0.0204391631f; + const float one = 1.0f; + const float two = 2.0f; + const double eight = 8.0; + + __m256d rate = _mm256_broadcast_sd(&srate); + __m256d roundVal = _mm256_set1_pd((srate >= 0.0) ? TWO_TO_52 : -TWO_TO_52); + + vEnd = ul_NumDataPoints - (ul_NumDataPoints & 7); + + // main vectorised loop + __m256d di1 = _mm256_set_pd(5.0, 1.0, 4.0, 0.0); // set time patterns for eventual moveldup/movehdup + __m256d di2 = _mm256_set_pd(7.0, 3.0, 6.0, 2.0); + + for (i = 0; i < vEnd; i += 8) { + const float *data = (const float *) (cx_DataArray + i); + float *chirped = (float *) (cx_ChirpDataArray + i); + + __m256d a1, a2; + __m256 d1, d2; + __m256 cd1, cd2; + __m256 td1, td2; + __m256 x; + __m256 y; + __m256 z; + __m256 s; + __m256 c; + __m256 m; + + // load the signal to be chirped + prefetchnta((const void *)( data+64 )); + d1 = _mm256_load_ps(data); + d2 = _mm256_load_ps(data+8); + + // calculate the input angles + a1 = _mm256_mul_pd(_mm256_mul_pd(di1, di1), rate); + a2 = _mm256_mul_pd(_mm256_mul_pd(di2, di2), rate); + + // update time values for next iteration + di1 = _mm256_add_pd(di1, _mm256_broadcast_sd(&eight)); + di2 = _mm256_add_pd(di2, _mm256_broadcast_sd(&eight)); + + // reduce the angles to the range (-0.5, 0.5) + a1 = _mm256_sub_pd(a1, _mm256_sub_pd(_mm256_add_pd(a1, roundVal), roundVal)); + a2 = _mm256_sub_pd(a2, _mm256_sub_pd(_mm256_add_pd(a2, roundVal), roundVal)); + + // convert the 2 packed doubles to packed single + x = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm256_cvtpd_ps(a1)), _mm256_cvtpd_ps(a2), 1); + + // square to the range [0, 0.25) + y = _mm256_mul_ps(x, x); + + // perform the initial polynomial approximations + z = _mm256_mul_ps(y, y); + s = _mm256_mul_ps(_mm256_add_ps(_mm256_mul_ps(_mm256_add_ps(_mm256_mul_ps(y, _mm256_broadcast_ss(&ss4f)), + _mm256_broadcast_ss(&ss3f)), + z), + _mm256_add_ps(_mm256_mul_ps(y, _mm256_broadcast_ss(&ss2f)), + _mm256_broadcast_ss(&ss1f))), + x); + c = _mm256_add_ps(_mm256_mul_ps(_mm256_add_ps(_mm256_mul_ps(y, _mm256_broadcast_ss(&cc3f)), + _mm256_broadcast_ss(&cc2f)), + z), + _mm256_add_ps(_mm256_mul_ps(y, _mm256_broadcast_ss(&cc1f)), + _mm256_broadcast_ss(&one))); + + // perform first angle doubling + x = _mm256_sub_ps(_mm256_mul_ps(c, c), _mm256_mul_ps(s, s)); + y = _mm256_mul_ps(_mm256_mul_ps(s, c), _mm256_broadcast_ss(&two)); + + // calculate scaling factor to correct the magnitude + m = _mm256_sub_ps(_mm256_sub_ps(_mm256_broadcast_ss(&two), _mm256_mul_ps(x, x)), _mm256_mul_ps(y, y)); + + // perform second angle doubling + c = _mm256_sub_ps(_mm256_mul_ps(x, x), _mm256_mul_ps(y, y)); + s = _mm256_mul_ps(_mm256_mul_ps(y, x), _mm256_broadcast_ss(&two)); + + // correct the magnitude (final sine / cosine approximations) + s = _mm256_mul_ps(s, m); + c = _mm256_mul_ps(c, m); + + // chirp the data + cd1 = _mm256_moveldup_ps(c); + cd2 = _mm256_movehdup_ps(c); + cd1 = _mm256_mul_ps(cd1, d1); + cd2 = _mm256_mul_ps(cd2, d2); + d1 = _mm256_shuffle_ps(d1, d1, 0xb1); + d2 = _mm256_shuffle_ps(d2, d2, 0xb1); + td1 = _mm256_moveldup_ps(s); + td2 = _mm256_movehdup_ps(s); + td1 = _mm256_mul_ps(td1, d1); + td2 = _mm256_mul_ps(td2, d2); + cd1 = _mm256_addsub_ps(cd1, td1); + cd2 = _mm256_addsub_ps(cd2, td2); + + // store chirped values + _mm256_stream_ps(chirped, cd1); + _mm256_stream_ps(chirped+8, cd2); + } + _mm256_zeroupper(); + _mm_sfence(); + + // never happens, handle tail elements with scalar code + for ( ; i < ul_NumDataPoints; ++i) { + double angle = srate * i * i * 0.5; + angle -= floor(angle); + angle *= M_PI * 2; + double s = sin(angle); + double c = cos(angle); + float re = cx_DataArray[i][0]; + float im = cx_DataArray[i][1]; + + cx_ChirpDataArray[i][0] = re * c - im * s; + cx_ChirpDataArray[i][1] = re * s + im * c; + } + analysis_state.FLOP_counter+=12.0*ul_NumDataPoints; + + return 0; +} + +// Third variant, like the first but instruction sequences modified so most instructions +// are not dependent on results of immediately preceding instruction. +// This may not have much effect on CPUs with excellent out of order capability. +int avx_ChirpData_c( + sah_complex * cx_DataArray, + sah_complex * cx_ChirpDataArray, + int chirp_rate_ind, + const double chirp_rate, + int ul_NumDataPoints, + const double sample_rate +) { + int i, vEnd; + + if (chirp_rate_ind == 0) { + memcpy(cx_ChirpDataArray, cx_DataArray, (int)ul_NumDataPoints * sizeof(sah_complex) ); + return 0; + } + + const double srate = chirp_rate * 0.5 / (sample_rate * sample_rate); + + __m256 ss1fA = _mm256_set1_ps(1.5707963235f); + __m256 ss2fA = _mm256_set1_ps(-0.645963615f); + __m256 ss3fA = _mm256_set1_ps(0.0796819754f); + __m256 ss4fA = _mm256_set1_ps(-0.0046075748f); + __m256 cc1fA = _mm256_set1_ps(-1.2336977925f); + __m256 cc2fA = _mm256_set1_ps(0.2536086171f); + __m256 cc3fA = _mm256_set1_ps(-0.0204391631f); + __m256 oneA = _mm256_set1_ps(1.0f); + __m256 twoA = _mm256_set1_ps(2.0f); + __m256d eightA = _mm256_set1_pd(8.0); + + __m256d rate = _mm256_broadcast_sd(&srate); + __m256d roundVal = _mm256_set1_pd((srate >= 0.0) ? TWO_TO_52 : -TWO_TO_52); + + // main vectorised loop + vEnd = ul_NumDataPoints - (ul_NumDataPoints & 7); + __m256d di1 = _mm256_set_pd(5.0, 1.0, 4.0, 0.0); // set time patterns for eventual moveldup/movehdup + __m256d di2 = _mm256_set_pd(7.0, 3.0, 6.0, 2.0); + + for (i = 0; i < vEnd; i += 8) { + const float *data = (const float *) (cx_DataArray + i); + float *chirped = (float *) (cx_ChirpDataArray + i); + + __m256d a1, a2; + __m256 d1, d2; + __m256 cd1, cd2; + __m256 td1, td2; + __m256 v; + __m256 w; + __m256 x; + __m256 y; + __m256 z; + __m256 s; + __m256 c; + __m256 m; + + // load the signal to be chirped + prefetchnta((const void *)( data+64 )); + d1 = _mm256_load_ps(data); + d2 = _mm256_load_ps(data+8); + + // calculate the input angles + a1 = _mm256_mul_pd(di1, di1); + a2 = _mm256_mul_pd(di2, di2); + a1 = _mm256_mul_pd(a1, rate); + a2 = _mm256_mul_pd(a2, rate); + + // reduce the angles to the range (-0.5, 0.5) + a1 = _mm256_sub_pd(a1, _mm256_sub_pd(_mm256_add_pd(a1, roundVal), roundVal)); + a2 = _mm256_sub_pd(a2, _mm256_sub_pd(_mm256_add_pd(a2, roundVal), roundVal)); + + // update time values for next iteration + di1 = _mm256_add_pd(di1, eightA); + di2 = _mm256_add_pd(di2, eightA); + + // convert the 2 packed doubles to packed single + y = _mm256_castps128_ps256(_mm256_cvtpd_ps(a1)); + x = _mm256_insertf128_ps(y, _mm256_cvtpd_ps(a2), 1); + + // square to the range [0, 0.25) + y = _mm256_mul_ps(x, x); + + // perform the initial polynomial approximations with interleaved Estrin sequences + z = _mm256_mul_ps(y, y); + s = _mm256_mul_ps(y, ss4fA); + c = _mm256_mul_ps(y, cc3fA); + s = _mm256_add_ps(s, ss3fA); + c = _mm256_add_ps(c, cc2fA); + s = _mm256_mul_ps(s, z); + c = _mm256_mul_ps(c, z); + v = _mm256_mul_ps(y, ss2fA); + w = _mm256_mul_ps(y, cc1fA); + v = _mm256_add_ps(v, ss1fA); + w = _mm256_add_ps(w, oneA); + s = _mm256_add_ps(s, v); + c = _mm256_add_ps(c, w); + s = _mm256_mul_ps(s, x); + + // perform first angle doubling + v = _mm256_mul_ps(c, c); + w = _mm256_mul_ps(s, s); + y = _mm256_mul_ps(s, c); + x = _mm256_sub_ps(v, w); + y = _mm256_mul_ps(y, twoA); + + // calculate scaling factor to correct the magnitude + // and interleave the second angle doubling + v = _mm256_mul_ps(x, x); + w = _mm256_mul_ps(y, y); + m = _mm256_sub_ps(twoA, v); + c = _mm256_sub_ps(v, w); + s = _mm256_mul_ps(y, x); + m = _mm256_sub_ps(m, w); + s = _mm256_mul_ps(s, twoA); + + // correct the magnitude (final sine / cosine approximations) + c = _mm256_mul_ps(c, m); + s = _mm256_mul_ps(s, m); + + // chirp the data + cd1 = _mm256_moveldup_ps(c); + td1 = _mm256_moveldup_ps(s); + cd2 = _mm256_movehdup_ps(c); + td2 = _mm256_movehdup_ps(s); + cd1 = _mm256_mul_ps(cd1, d1); + cd2 = _mm256_mul_ps(cd2, d2); + d1 = _mm256_shuffle_ps(d1, d1, 0xb1); + d2 = _mm256_shuffle_ps(d2, d2, 0xb1); + td1 = _mm256_mul_ps(td1, d1); + td2 = _mm256_mul_ps(td2, d2); + cd1 = _mm256_addsub_ps(cd1, td1); + cd2 = _mm256_addsub_ps(cd2, td2); + + // store chirped values + _mm256_stream_ps(chirped, cd1); + _mm256_stream_ps(chirped+8, cd2); + } + _mm256_zeroupper (); + _mm_sfence(); + + // handle tail elements with scalar code + for ( ; i < ul_NumDataPoints; ++i) { + double angle = srate * i * i * 0.5; + angle -= floor(angle); + angle *= M_PI * 2; + double s = sin(angle); + double c = cos(angle); + float re = cx_DataArray[i][0]; + float im = cx_DataArray[i][1]; + + cx_ChirpDataArray[i][0] = re * c - im * s; + cx_ChirpDataArray[i][1] = re * s + im * c; + } + analysis_state.FLOP_counter+=12.0*ul_NumDataPoints; + + return 0; +} + +// Fourth variant, like third but using _mm256_round_pd for angle reduction. +int avx_ChirpData_d( + sah_complex * cx_DataArray, + sah_complex * cx_ChirpDataArray, + int chirp_rate_ind, + const double chirp_rate, + int ul_NumDataPoints, + const double sample_rate +) { + int i, vEnd; + + if (chirp_rate_ind == 0) { + memcpy(cx_ChirpDataArray, cx_DataArray, (int)ul_NumDataPoints * sizeof(sah_complex) ); + return 0; + } + + const double srate = chirp_rate * 0.5 / (sample_rate * sample_rate); + + __m256 ss1fA = _mm256_set1_ps(1.5707963235f); + __m256 ss2fA = _mm256_set1_ps(-0.645963615f); + __m256 ss3fA = _mm256_set1_ps(0.0796819754f); + __m256 ss4fA = _mm256_set1_ps(-0.0046075748f); + __m256 cc1fA = _mm256_set1_ps(-1.2336977925f); + __m256 cc2fA = _mm256_set1_ps(0.2536086171f); + __m256 cc3fA = _mm256_set1_ps(-0.0204391631f); + __m256 oneA = _mm256_set1_ps(1.0f); + __m256 twoA = _mm256_set1_ps(2.0f); + __m256d eightA = _mm256_set1_pd(8.0); + + __m256d rate = _mm256_broadcast_sd(&srate); + + // main vectorised loop + vEnd = ul_NumDataPoints - (ul_NumDataPoints & 7); + __m256d di1 = _mm256_set_pd(5.0, 1.0, 4.0, 0.0); + __m256d di2 = _mm256_set_pd(7.0, 3.0, 6.0, 2.0); + + for (i = 0; i < vEnd; i += 8) { + const float *data = (const float *) (cx_DataArray + i); + float *chirped = (float *) (cx_ChirpDataArray + i); + + __m256d a1, a2; + __m256 d1, d2; + __m256 cd1, cd2; + __m256 td1, td2; + __m256 v; + __m256 w; + __m256 x; + __m256 y; + __m256 z; + __m256 s; + __m256 c; + __m256 m; + + // load the signal to be chirped + prefetchnta((const void *)( data+64 )); + d1 = _mm256_load_ps(data); + d2 = _mm256_load_ps(data+8); + + // calculate the input angles + a1 = _mm256_mul_pd(di1, di1); + a2 = _mm256_mul_pd(di2, di2); + a1 = _mm256_mul_pd(a1, rate); + a2 = _mm256_mul_pd(a2, rate); + + // reduce the angles to the range (-0.5, 0.5) + a1 = _mm256_sub_pd(a1, _mm256_round_pd(a1, 0)); // round to nearest + a2 = _mm256_sub_pd(a2, _mm256_round_pd(a2, 0)); + + // update time values for next iteration + di1 = _mm256_add_pd(di1, eightA); + di2 = _mm256_add_pd(di2, eightA); + + // convert the 2 packed doubles to packed single + y = _mm256_castps128_ps256(_mm256_cvtpd_ps(a1)); + x = _mm256_insertf128_ps(y, _mm256_cvtpd_ps(a2), 1); + + // square to the range [0, 0.25) + y = _mm256_mul_ps(x, x); + + // perform the initial polynomial approximations with interleaved Estrin sequences + z = _mm256_mul_ps(y, y); + s = _mm256_mul_ps(y, ss4fA); + c = _mm256_mul_ps(y, cc3fA); + s = _mm256_add_ps(s, ss3fA); + c = _mm256_add_ps(c, cc2fA); + s = _mm256_mul_ps(s, z); + c = _mm256_mul_ps(c, z); + v = _mm256_mul_ps(y, ss2fA); + w = _mm256_mul_ps(y, cc1fA); + v = _mm256_add_ps(v, ss1fA); + w = _mm256_add_ps(w, oneA); + s = _mm256_add_ps(s, v); + c = _mm256_add_ps(c, w); + s = _mm256_mul_ps(s, x); + + // perform first angle doubling + v = _mm256_mul_ps(c, c); + w = _mm256_mul_ps(s, s); + y = _mm256_mul_ps(s, c); + x = _mm256_sub_ps(v, w); + y = _mm256_mul_ps(y, twoA); + + // calculate scaling factor to correct the magnitude + // and interleave the second angle doubling + v = _mm256_mul_ps(x, x); + w = _mm256_mul_ps(y, y); + m = _mm256_sub_ps(twoA, v); + c = _mm256_sub_ps(v, w); + s = _mm256_mul_ps(y, x); + m = _mm256_sub_ps(m, w); + s = _mm256_mul_ps(s, twoA); + + // correct the magnitude (final sine / cosine approximations) + c = _mm256_mul_ps(c, m); + s = _mm256_mul_ps(s, m); + + // chirp the data + cd1 = _mm256_moveldup_ps(c); + td1 = _mm256_moveldup_ps(s); + cd2 = _mm256_movehdup_ps(c); + td2 = _mm256_movehdup_ps(s); + cd1 = _mm256_mul_ps(cd1, d1); + cd2 = _mm256_mul_ps(cd2, d2); + d1 = _mm256_shuffle_ps(d1, d1, 0xb1); + d2 = _mm256_shuffle_ps(d2, d2, 0xb1); + td1 = _mm256_mul_ps(td1, d1); + td2 = _mm256_mul_ps(td2, d2); + cd1 = _mm256_addsub_ps(cd1, td1); + cd2 = _mm256_addsub_ps(cd2, td2); + + // store chirped values + _mm256_stream_ps(chirped, cd1); + _mm256_stream_ps(chirped+8, cd2); + } + _mm256_zeroupper (); + _mm_sfence(); + + // handle tail elements with scalar code + for ( ; i < ul_NumDataPoints; ++i) { + double angle = srate * i * i * 0.5; + angle -= floor(angle); + angle *= M_PI * 2; + double s = sin(angle); + double c = cos(angle); + float re = cx_DataArray[i][0]; + float im = cx_DataArray[i][1]; + + cx_ChirpDataArray[i][0] = re * c - im * s; + cx_ChirpDataArray[i][1] = re * s + im * c; + } + analysis_state.FLOP_counter+=12.0*ul_NumDataPoints; + + return 0; +} + + +// ============================================================================= +// JWS: AVX transpose functions +// + +inline void v_avxSubTranspose4x8ntw(float *in, float *out, int xline, int yline) { + // Do two simultaneous 4x4 transposes in the YMM registers, non-temporal writes. + // Input is 8 rows of 4 floats, output is 4 columns of 8 floats. + // An sfence is needed after using this sub to ensure global visibilty of the writes. + + __m256 r04 = _mm256_insertf128_ps(_mm256_castps128_ps256(*((__m128*)(in+0*xline))), (*((__m128*)(in+4*xline))), 0x1); // a0b0c0d0a4b4c4d4 + __m256 r26 = _mm256_insertf128_ps(_mm256_castps128_ps256(*((__m128*)(in+2*xline))), (*((__m128*)(in+6*xline))), 0x1); // a2b2c2d2a6b6c6d6 + __m256 r15 = _mm256_insertf128_ps(_mm256_castps128_ps256(*((__m128*)(in+1*xline))), (*((__m128*)(in+5*xline))), 0x1); // a1b1c1d1a5b5c5d5 + __m256 r37 = _mm256_insertf128_ps(_mm256_castps128_ps256(*((__m128*)(in+3*xline))), (*((__m128*)(in+7*xline))), 0x1); // a3b3c3d3a7b7c7d7 + + __m256 c01e = _mm256_unpacklo_ps(r04, r26); // a0a2b0b2a4a6b4b6 + __m256 c23e = _mm256_unpackhi_ps(r04, r26); // c0c2d0d2c4c6d4d6 + __m256 c01o = _mm256_unpacklo_ps(r15, r37); // a1a3b1b3a5a7b5b7 + __m256 c23o = _mm256_unpackhi_ps(r15, r37); // c1c3d1d3c5c7d5d7 + + _mm256_stream_ps(out+0*yline, _mm256_unpacklo_ps(c01e, c01o)); // a0a1a2a3a4a5a6a7 + _mm256_stream_ps(out+1*yline, _mm256_unpackhi_ps(c01e, c01o)); // b0b1b2b3b4b5b6b7 + _mm256_stream_ps(out+2*yline, _mm256_unpacklo_ps(c23e, c23o)); // c0c1c2c3c4c5c6c7 + _mm256_stream_ps(out+3*yline, _mm256_unpackhi_ps(c23e, c23o)); // d0d1d2d3d4d5d6d7 +} + +int v_avxTranspose4x8ntw(int x, int y, float *in, float *out) { + int i,j; + + for (j=0;jdi) - 1) & 7); + __m256 tailelem = _mm256_set_ps(7.0f, 6.0f, 5.0f, 4.0f, 3.0f, 2.0f, 1.0f, 0.0f); + __m256 taillim = _mm256_broadcast_ss(&lim); + __m256 maxV = _mm256_setzero_ps(); + int i = 0; + + const float *p1 = ss[0], *p2 = ss[0]+P->tmp0, *p3 = ss[0]+P->tmp1; + float *pst = P->dest; + __m256 x1, x2, tailmask; + + // No unroll, Sandy Bridge has a limited uop cache which should be conserved. + while (i < P->di-8) { + x1 = _mm256_load_ps(p1+i); + x2 = _mm256_add_ps(x1, *(__m256*)(p2+i)); + x1 = _mm256_add_ps(x2, *(__m256*)(p3+i)); + _mm256_store_ps(pst+i, x1); + maxV = _mm256_max_ps(maxV, x1); + i += 8; + } + x1 = _mm256_load_ps(p1+i); + x2 = _mm256_add_ps(x1, *(__m256*)(p2+i)); + x1 = _mm256_add_ps(x2, *(__m256*)(p3+i)); + + tailmask = _mm256_cmp_ps(taillim, tailelem, 0x0d); // taillim floats >= tailelem floats + _mm256_maskstore_ps(pst+i, AVX_MASKSTORE_TYPECAST(tailmask), x1); + x2 = _mm256_and_ps(x1, tailmask); + maxV = _mm256_max_ps(maxV, x2); + x1 = _mm256_permute2f128_ps(maxV, maxV, 0x81); + maxV = _mm256_max_ps(maxV, x1); // max in low 4 + maxV = _mm256_max_ps(maxV, _mm256_shuffle_ps(maxV, maxV, 0xee)); // in low 2 + maxV = _mm256_max_ps(maxV, _mm256_shuffle_ps(maxV, maxV, 0x01)); // 1 + float max = _mm_cvtss_f32(_mm256_castps256_ps128(maxV)); + _mm256_zeroupper(); + return max; +} + +sum_func AVXTBa3[FOLDTBLEN] = {foldBy3}; + + +float foldBy4(float *ss[], struct PoTPlan *P) { + const float lim = (float)(((P->di) - 1) & 7); + __m256 tailelem = _mm256_set_ps(7.0f, 6.0f, 5.0f, 4.0f, 3.0f, 2.0f, 1.0f, 0.0f); + __m256 taillim = _mm256_broadcast_ss(&lim); + __m256 maxV = _mm256_setzero_ps(); + int i = 0; + + const float *p1 = ss[0], *p2 = ss[0]+P->tmp0, *p3 = ss[0]+P->tmp1, *p4 = ss[0]+P->tmp2; + float *pst = P->dest; + __m256 x1, x2, tailmask; + + while (i < P->di-8) { + x1 = _mm256_load_ps(p1+i); + x2 = _mm256_add_ps(x1, *(__m256*)(p2+i)); + x1 = _mm256_add_ps(x2, *(__m256*)(p3+i)); + x2 = _mm256_add_ps(x1, *(__m256*)(p4+i)); + _mm256_store_ps(pst+i, x2); + maxV = _mm256_max_ps(maxV, x2); + i += 8; + } + x1 = _mm256_load_ps(p1+i); + x2 = _mm256_add_ps(x1, *(__m256*)(p2+i)); + x1 = _mm256_add_ps(x2, *(__m256*)(p3+i)); + x2 = _mm256_add_ps(x1, *(__m256*)(p4+i)); + + tailmask = _mm256_cmp_ps(taillim, tailelem, 0x0d); + _mm256_maskstore_ps(pst+i, AVX_MASKSTORE_TYPECAST(tailmask), x2); + x1 = _mm256_and_ps(x2, tailmask); + maxV = _mm256_max_ps(maxV, x1); + x2 = _mm256_permute2f128_ps(maxV, maxV, 0x81); + maxV = _mm256_max_ps(maxV, x2); + maxV = _mm256_max_ps(maxV, _mm256_shuffle_ps(maxV, maxV, 0xee)); + maxV = _mm256_max_ps(maxV, _mm256_shuffle_ps(maxV, maxV, 0x01)); + float max = _mm_cvtss_f32(_mm256_castps256_ps128(maxV)); + _mm256_zeroupper(); + return max; +} + +sum_func AVXTBa4[FOLDTBLEN] = {foldBy4}; + + +float foldBy5(float *ss[], struct PoTPlan *P) { + const float lim = (float)(((P->di) - 1) & 7); + __m256 tailelem = _mm256_set_ps(7.0f, 6.0f, 5.0f, 4.0f, 3.0f, 2.0f, 1.0f, 0.0f); + __m256 taillim = _mm256_broadcast_ss(&lim); + __m256 maxV = _mm256_setzero_ps(); + int i = 0; + + const float *p1 = ss[0], *p2 = ss[0]+P->tmp0, *p3 = ss[0]+P->tmp1, *p4 = ss[0]+P->tmp2, *p5 = ss[0]+P->tmp3; + float *pst = P->dest; + __m256 x1, x2, tailmask; + + while (i < P->di-8) { + x1 = _mm256_load_ps(p1+i); + x2 = _mm256_add_ps(x1, *(__m256*)(p2+i)); + x1 = _mm256_add_ps(x2, *(__m256*)(p3+i)); + x2 = _mm256_add_ps(x1, *(__m256*)(p4+i)); + x1 = _mm256_add_ps(x2, *(__m256*)(p5+i)); + _mm256_store_ps(pst+i, x1); + maxV = _mm256_max_ps(maxV, x1); + i += 8; + } + x1 = _mm256_load_ps(p1+i); + x2 = _mm256_add_ps(x1, *(__m256*)(p2+i)); + x1 = _mm256_add_ps(x2, *(__m256*)(p3+i)); + x2 = _mm256_add_ps(x1, *(__m256*)(p4+i)); + x1 = _mm256_add_ps(x2, *(__m256*)(p5+i)); + + tailmask = _mm256_cmp_ps(taillim, tailelem, 0x0d); + _mm256_maskstore_ps(pst+i, AVX_MASKSTORE_TYPECAST(tailmask), x1); + x2 = _mm256_and_ps(x1, tailmask); + maxV = _mm256_max_ps(maxV, x2); + x1 = _mm256_permute2f128_ps(maxV, maxV, 0x81); + maxV = _mm256_max_ps(maxV, x1); + maxV = _mm256_max_ps(maxV, _mm256_shuffle_ps(maxV, maxV, 0xee)); + maxV = _mm256_max_ps(maxV, _mm256_shuffle_ps(maxV, maxV, 0x01)); + float max = _mm_cvtss_f32(_mm256_castps256_ps128(maxV)); + _mm256_zeroupper(); + return max; +} + +sum_func AVXTBa5[FOLDTBLEN] = {foldBy5}; + + +float foldBy2(float *ss[], struct PoTPlan *P) { + const float lim = (float)(((P->di) - 1) & 7); + __m256 tailelem = _mm256_set_ps(7.0f, 6.0f, 5.0f, 4.0f, 3.0f, 2.0f, 1.0f, 0.0f); + __m256 taillim = _mm256_broadcast_ss(&lim); + __m256 maxV = _mm256_setzero_ps(); + int i = 0; + + const float *p1 = ss[1]+P->offset, *p2 = ss[1]+P->tmp0; + float *pst = P->dest; + __m256 x1, x2, tailmask; + + while (i < P->di-8) { + x1 = _mm256_load_ps(p1+i); + x2 = _mm256_add_ps(x1, *(__m256*)(p2+i)); + _mm256_store_ps(pst+i, x2); + maxV = _mm256_max_ps(maxV, x2); + i += 8; + } + x1 = _mm256_load_ps(p1+i); + x2 = _mm256_add_ps(x1, *(__m256*)(p2+i)); + + tailmask = _mm256_cmp_ps(taillim, tailelem, 0x0d); + _mm256_maskstore_ps(pst+i, AVX_MASKSTORE_TYPECAST(tailmask), x2); + x1 = _mm256_and_ps(x2, tailmask); + maxV = _mm256_max_ps(maxV, x1); + x2 = _mm256_permute2f128_ps(maxV, maxV, 0x81); + maxV = _mm256_max_ps(maxV, x2); + maxV = _mm256_max_ps(maxV, _mm256_shuffle_ps(maxV, maxV, 0xee)); + maxV = _mm256_max_ps(maxV, _mm256_shuffle_ps(maxV, maxV, 0x01)); + float max = _mm_cvtss_f32(_mm256_castps256_ps128(maxV)); + _mm256_zeroupper(); + return max; +} + +sum_func AVXTBa2[FOLDTBLEN] = {foldBy2}; + +FoldSet AVXfold_a = {AVXTBa3, AVXTBa4, AVXTBa5, AVXTBa2, AVXTBa2, "JS AVX_a"}; + + + +// Alternate set using 16 byte unaligned loads and inserts for the probably unaligned +// elements, based on Intel optimization recommendations. +float foldBy3c(float *ss[], struct PoTPlan *P) { + const float lim = (float)(((P->di) - 1) & 7); + __m256 tailelem = _mm256_set_ps(7.0f, 6.0f, 5.0f, 4.0f, 3.0f, 2.0f, 1.0f, 0.0f); + __m256 taillim = _mm256_broadcast_ss(&lim); + __m256 maxV = _mm256_setzero_ps(); + int i = 0; + + const float *p1 = ss[0], *p2 = ss[0]+P->tmp0, *p3 = ss[0]+P->tmp1; + float *pst = P->dest; + __m256 x1, x2, tailmask; + + while (i < P->di-8) { + x2 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(p2+i)), _mm_load_ps(p2+i+4), 1); + x1 = _mm256_add_ps(x2, *(__m256*)(p1+i)); + x2 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(p3+i)), _mm_load_ps(p3+i+4), 1); + x1 = _mm256_add_ps(x1, x2); + _mm256_store_ps(pst+i, x1); + maxV = _mm256_max_ps(maxV, x1); + i += 8; + } + x2 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(p2+i)), _mm_load_ps(p2+i+4), 1); + x1 = _mm256_add_ps(x2, *(__m256*)(p1+i)); + x2 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(p3+i)), _mm_load_ps(p3+i+4), 1); + x1 = _mm256_add_ps(x1, x2); + + tailmask = _mm256_cmp_ps(taillim, tailelem, 0x0d); + _mm256_maskstore_ps(pst+i, AVX_MASKSTORE_TYPECAST(tailmask), x1); + x2 = _mm256_and_ps(x1, tailmask); + maxV = _mm256_max_ps(maxV, x2); + x1 = _mm256_permute2f128_ps(maxV, maxV, 0x81); + maxV = _mm256_max_ps(maxV, x1); + maxV = _mm256_max_ps(maxV, _mm256_shuffle_ps(maxV, maxV, 0xee)); + maxV = _mm256_max_ps(maxV, _mm256_shuffle_ps(maxV, maxV, 0x01)); + float max = _mm_cvtss_f32(_mm256_castps256_ps128(maxV)); + _mm256_zeroupper(); + return max; +} + +sum_func AVXTBc3[FOLDTBLEN] = {foldBy3c}; + + +float foldBy4c(float *ss[], struct PoTPlan *P) { + const float lim = (float)(((P->di) - 1) & 7); + __m256 tailelem = _mm256_set_ps(7.0f, 6.0f, 5.0f, 4.0f, 3.0f, 2.0f, 1.0f, 0.0f); + __m256 taillim = _mm256_broadcast_ss(&lim); + __m256 maxV = _mm256_setzero_ps(); + int i = 0; + + const float *p1 = ss[0], *p2 = ss[0]+P->tmp0, *p3 = ss[0]+P->tmp1, *p4 = ss[0]+P->tmp2; + float *pst = P->dest; + __m256 x1, x2, tailmask; + + while (i < P->di-8) { + x1 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(p2+i)), _mm_load_ps(p2+i+4), 1); + x2 = _mm256_add_ps(x1, *(__m256*)(p1+i)); + x1 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(p3+i)), _mm_load_ps(p3+i+4), 1); + x2 = _mm256_add_ps(x2, x1); + x1 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(p4+i)), _mm_load_ps(p4+i+4), 1); + x2 = _mm256_add_ps(x2, x1); + _mm256_store_ps(pst+i, x2); + maxV = _mm256_max_ps(maxV, x2); + i += 8; + } + x1 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(p2+i)), _mm_load_ps(p2+i+4), 1); + x2 = _mm256_add_ps(x1, *(__m256*)(p1+i)); + x1 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(p3+i)), _mm_load_ps(p3+i+4), 1); + x2 = _mm256_add_ps(x2, x1); + x1 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(p4+i)), _mm_load_ps(p4+i+4), 1); + x2 = _mm256_add_ps(x2, x1); + + tailmask = _mm256_cmp_ps(taillim, tailelem, 0x0d); + _mm256_maskstore_ps(pst+i, AVX_MASKSTORE_TYPECAST(tailmask), x2); + x1 = _mm256_and_ps(x2, tailmask); + maxV = _mm256_max_ps(maxV, x1); + x2 = _mm256_permute2f128_ps(maxV, maxV, 0x81); + maxV = _mm256_max_ps(maxV, x2); + maxV = _mm256_max_ps(maxV, _mm256_shuffle_ps(maxV, maxV, 0xee)); + maxV = _mm256_max_ps(maxV, _mm256_shuffle_ps(maxV, maxV, 0x01)); + float max = _mm_cvtss_f32(_mm256_castps256_ps128(maxV)); + _mm256_zeroupper(); + return max; +} + +sum_func AVXTBc4[FOLDTBLEN] = {foldBy4c}; + + +float foldBy5c(float *ss[], struct PoTPlan *P) { + const float lim = (float)(((P->di) - 1) & 7); + __m256 tailelem = _mm256_set_ps(7.0f, 6.0f, 5.0f, 4.0f, 3.0f, 2.0f, 1.0f, 0.0f); + __m256 taillim = _mm256_broadcast_ss(&lim); + __m256 maxV = _mm256_setzero_ps(); + int i = 0; + + const float *p1 = ss[0], *p2 = ss[0]+P->tmp0, *p3 = ss[0]+P->tmp1, *p4 = ss[0]+P->tmp2, *p5 = ss[0]+P->tmp3; + float *pst = P->dest; + __m256 x1, x2, tailmask; + + while (i < P->di-8) { + x1 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(p2+i)), _mm_load_ps(p2+i+4), 1); + x1 = _mm256_add_ps(x1, *(__m256*)(p1+i)); + x2 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(p3+i)), _mm_load_ps(p3+i+4), 1); + x1 = _mm256_add_ps(x1, x2); + x2 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(p4+i)), _mm_load_ps(p4+i+4), 1); + x1 = _mm256_add_ps(x1, x2); + x2 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(p5+i)), _mm_load_ps(p5+i+4), 1); + x1 = _mm256_add_ps(x1, x2); + _mm256_store_ps(pst+i, x1); + maxV = _mm256_max_ps(maxV, x1); + i += 8; + } + x1 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(p2+i)), _mm_load_ps(p2+i+4), 1); + x1 = _mm256_add_ps(x1, *(__m256*)(p1+i)); + x2 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(p3+i)), _mm_load_ps(p3+i+4), 1); + x1 = _mm256_add_ps(x1, x2); + x2 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(p4+i)), _mm_load_ps(p4+i+4), 1); + x1 = _mm256_add_ps(x1, x2); + x2 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(p5+i)), _mm_load_ps(p5+i+4), 1); + x1 = _mm256_add_ps(x1, x2); + + tailmask = _mm256_cmp_ps(taillim, tailelem, 0x0d); + _mm256_maskstore_ps(pst+i, AVX_MASKSTORE_TYPECAST(tailmask), x1); + x2 = _mm256_and_ps(x1, tailmask); + maxV = _mm256_max_ps(maxV, x2); + x1 = _mm256_permute2f128_ps(maxV, maxV, 0x81); + maxV = _mm256_max_ps(maxV, x1); + maxV = _mm256_max_ps(maxV, _mm256_shuffle_ps(maxV, maxV, 0xee)); + maxV = _mm256_max_ps(maxV, _mm256_shuffle_ps(maxV, maxV, 0x01)); + float max = _mm_cvtss_f32(_mm256_castps256_ps128(maxV)); + _mm256_zeroupper(); + return max; +} + +sum_func AVXTBc5[FOLDTBLEN] = {foldBy5c}; + + +float foldBy2c(float *ss[], struct PoTPlan *P) { + const float lim = (float)(((P->di) - 1) & 7); + __m256 tailelem = _mm256_set_ps(7.0f, 6.0f, 5.0f, 4.0f, 3.0f, 2.0f, 1.0f, 0.0f); + __m256 taillim = _mm256_broadcast_ss(&lim); + __m256 maxV = _mm256_setzero_ps(); + int i = 0; + + const float *p1 = ss[1]+P->offset, *p2 = ss[1]+P->tmp0; + float *pst = P->dest; + __m256 x1, x2, tailmask; + + while (i < P->di-8) { + x1 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(p2+i)), _mm_load_ps(p2+i+4), 1); + x2 = _mm256_add_ps(x1, *(__m256*)(p1+i)); + _mm256_store_ps(pst+i, x2); + maxV = _mm256_max_ps(maxV, x2); + i += 8; + } + x1 = _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_loadu_ps(p2+i)), _mm_load_ps(p2+i+4), 1); + x2 = _mm256_add_ps(x1, *(__m256*)(p1+i)); + + tailmask = _mm256_cmp_ps(taillim, tailelem, 0x0d); + _mm256_maskstore_ps(pst+i, AVX_MASKSTORE_TYPECAST(tailmask), x2); + x1 = _mm256_and_ps(x2, tailmask); + maxV = _mm256_max_ps(maxV, x1); + x2 = _mm256_permute2f128_ps(maxV, maxV, 0x81); + maxV = _mm256_max_ps(maxV, x2); + maxV = _mm256_max_ps(maxV, _mm256_shuffle_ps(maxV, maxV, 0xee)); + maxV = _mm256_max_ps(maxV, _mm256_shuffle_ps(maxV, maxV, 0x01)); + float max = _mm_cvtss_f32(_mm256_castps256_ps128(maxV)); + _mm256_zeroupper(); + return max; +} + +sum_func AVXTBc2[FOLDTBLEN] = {foldBy2c}; + +FoldSet AVXfold_c = {AVXTBc3, AVXTBc4, AVXTBc5, AVXTBc2, AVXTBc2, "JS AVX_c"}; + + + +#endif // (USE_AVX) && (USE_INTRINSICS) diff --git a/client/vector/analyzeFuncs_fpu.cpp b/client/vector/analyzeFuncs_fpu.cpp new file mode 100644 index 0000000..0bbe8db --- /dev/null +++ b/client/vector/analyzeFuncs_fpu.cpp @@ -0,0 +1,333 @@ +// Copyright 2007 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +#include "sah_config.h" +#include +#include +#include "analyzeFuncs.h" +#include "analyzeFuncs_vector.h" +#include "sincos.h" +#ifdef BOINC_APP_GRAPHICS +#include "sah_gfx_main.h" +#endif + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +// ********************************************************* +// +// JWS: FPU chirp using Flemming Pedersen (CERN) fast double sincos, +// http://pedersen.web.cern.ch/pedersen/project-leir-dsp-bc/matlab/fast_sine_cosine/fast_sine_cosine.doc +// Similar to Marcus Mendenhall Faster SinCos except no final adjustment +// because doubles produce good accuracy without. +// +// Includes quick FPU rounding developed for sse1 version. +// +inline void set_up_fastfrac(double roundVal) { +// this routine only exists for compilers that can't tell that a value is +// being popped from the FP stack and then immediately reloaded. +#if defined(_MSC_VER) && !defined(_WIN64) + __asm fld roundVal; // get roundVal +#endif +} + +inline void clean_up_fastfrac() { +// this routine only exists for compilers than needed set_up_fastfrac() +#if defined(_MSC_VER) && !defined(_WIN64) + __asm fstp st(0); // pop roundVal off FPU stack +#endif +} + +// This routine should work as long as x86_64 supports x87 instructions. +// After that the illegal instruction trap should take care of it. +inline double fastfrac(double val, double roundVal) { + // reduce val to the range (-0.5, 0.5) using "val - round(val)" +#if defined(_MSC_VER) && !defined(_WIN64) + __asm { + fld val // get angle + fadd st(0), st(1) // + roundVal + fsub st(0), st(1) // - roundVal, integer in st(0) + fsubr val // angle - integer + fstp val // store reduced angle + } + +#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) + __asm__ __volatile__( + "fadd %2,%0\n" // + roundVal +" fsub %2,%0\n" // - roundVal, integer in st(0) +" fsubr %3,%0\n" // angle - integer + : "=&t" (val) + : "0" (val), "f" (roundVal), "f" (val) + ); +#elif defined(_WIN64) + val -= ((val + roundVal) - roundVal); // TODO: ADD CHECK THAT THIS WORKS +#else + val -= floor(val + 0.5); +#endif + return val; +} + +static unsigned short fpucw1; + +inline void set_extended_precision() { + // Windows and *BSD operate the X87 FPU so it rounds at mantissa bit 53, the + // quick rounding algorithm needs rounding at the last bit. + unsigned short fpucw2; +#if defined(_MSC_VER) && !defined(_WIN64) // MSVC no inline assembly for 64 bit + __asm fnstcw fpucw1; + fpucw2 = fpucw1 | 0x300; + __asm fldcw fpucw2; +#elif defined(__GNUC__) && (defined(_WIN32) || defined(_WIN64) || defined(_BSD)) + __asm__ __volatile__ ("fnstcw %0" : "=m" (fpucw1)); + fpucw2 = fpucw1 | 0x300; + __asm__ __volatile__ ("fldcw %0" : : "m" (fpucw2)); +#else + // Nothing necessary for linux, osx, _WIN64 VC++ and most everything else. +#endif +} + +inline void restore_fpucw() { +#if defined(_MSC_VER) && !defined(_WIN64) + __asm fldcw fpucw1; +#elif defined(__GNUC__) && (defined(_WIN32) || defined(_WIN64) || defined(_BSD)) + __asm__ __volatile__ ("fldcw %0" : : "m" (fpucw1)); +#else + // NADA +#endif +} + +double z; + +int fpu_ChirpData ( + sah_complex * cx_DataArray, + sah_complex * cx_ChirpDataArray, + int ChirpRateInd, + double ChirpRate, + int ul_NumDataPoints, + double sample_rate +) { + if (ChirpRateInd == 0) { + memcpy(cx_ChirpDataArray, cx_DataArray, (int)ul_NumDataPoints * sizeof(sah_complex) ); + return 0; + } + + double srate = ChirpRate * 0.5 / (sample_rate * sample_rate); + + +#if (!defined(__GNUC__) && defined(_WIN64)) || \ + (defined(__GNUC__) && !(defined(__i386__) || defined(__x86_64__))) + double roundVal = (srate >= 0.0) ? TWO_TO_52 : -TWO_TO_52; +#else + double roundVal = (srate >= 0.0) ? ROUNDX87 : -ROUNDX87; +#endif + + int i, j, vEnd; + unsigned short fpucw1, fpucw2; + + vEnd = ul_NumDataPoints - (ul_NumDataPoints & 7); + + // main loop + for (i = 0; i < vEnd; i += 8) { + double angles[8], dtemp; + double cd1, cd2, cd3; + double x, y; + double s, c; + float real, imag; + + dtemp = double( i ); + angles[0] = dtemp+0.0; + angles[1] = dtemp+1.0; + angles[2] = dtemp+2.0; + angles[3] = dtemp+3.0; + angles[4] = dtemp+4.0; + angles[5] = dtemp+5.0; + angles[6] = dtemp+6.0; + angles[7] = dtemp+7.0; + + // calculate the input angle + angles[0] *= angles[0] * srate; // angle^2 * rate + angles[1] *= angles[1] * srate; + angles[2] *= angles[2] * srate; + angles[3] *= angles[3] * srate; + angles[4] *= angles[4] * srate; + angles[5] *= angles[5] * srate; + angles[6] *= angles[6] * srate; + angles[7] *= angles[7] * srate; + + // Do 8 angles to amortize the time cost of precision switching. + set_extended_precision(); + set_up_fastfrac(roundVal); + angles[0]=fastfrac(angles[0],roundVal); + angles[1]=fastfrac(angles[1],roundVal); + angles[2]=fastfrac(angles[2],roundVal); + angles[3]=fastfrac(angles[3],roundVal); + angles[4]=fastfrac(angles[4],roundVal); + angles[5]=fastfrac(angles[5],roundVal); + angles[6]=fastfrac(angles[6],roundVal); + angles[7]=fastfrac(angles[7],roundVal); + clean_up_fastfrac(); + restore_fpucw(); + + for ( j = 0; j < 8; j++ ) { + + // square angle to the range [0, 0.25) + y = angles[j] * angles[j]; + + // perform the initial polynomial approximations + s = y * FS4; + c = y * FC3; + s += FS3; + c += FC2; + s *= y; + c *= y; + s += FS2; + c += FC1; + s *= y; + c *= y; + s += FS1; + s *= angles[j]; + c += 1; + + // perform first angle doubling + x = c * c - s * s; + y = s * c * 2; + cd1 = x * y; + cd2 = x * x; + cd3 = y * y; + + // perform second angle doubling + s = cd1 * 2; + c = cd2 - cd3; + + // chirp and store + real = (float)(cx_DataArray[i + j][0] * c - cx_DataArray[i + j][1] * s); + imag = (float)(cx_DataArray[i + j][0] * s + cx_DataArray[i + j][1] * c); + cx_ChirpDataArray[i + j][0] = real; + cx_ChirpDataArray[i + j][1] = imag; + + } + } + + if( i < ul_NumDataPoints) { + // use original routine to finish up any tailings (max stride-1 elements) + v_ChirpData(cx_DataArray+i, cx_ChirpDataArray+i + , ChirpRateInd, ChirpRate, ul_NumDataPoints-i, sample_rate); + } + analysis_state.FLOP_counter+=12.0*ul_NumDataPoints; + + return 0; +} + + +// opt_v_ChirpData +// 8-10-06 BENH - Unrolled loop 3 times to allow for FPU latency & reduce loop overhead +//..............- Removed conditionals from loop +// xx-xx-03 ERICK - Created function +// +extern void CalcTrigArray (int len, int ChirpRateInd); +int fpu_opt_ChirpData ( + sah_complex * cx_DataArray, + sah_complex * cx_ChirpDataArray, + int ChirpRateInd, + double ChirpRate, + int ul_NumDataPoints, + double sample_rate + +){ + float chirp_sign; // BENH - Pulled conditional out of loop + if ( ChirpRateInd == 0 ) + { + memcpy( cx_ChirpDataArray, cx_DataArray, int( ul_NumDataPoints * sizeof(sah_complex)) ); + return ( 0 ); + } + + // calculate trigonometric array this function returns w/o doing + // anything when sign of chirp_rate_ind reverses. so we have to take care + // of it. + // + double recip_sample_rate=1.0/sample_rate; + chirp_sign = ( ChirpRateInd >= 0 ) ? 1 : -1; + + const int stride = 2; + int i = 0; + int last = ul_NumDataPoints - ( stride - 1 ); + // what we do depends on how much memory we have... + // If we have more than 64MB, we'll cache the chirp table. If not + // we'll calculate it each time. + bool CacheChirpCalc=((app_init_data.host_info.m_nbytes == 0) || + (app_init_data.host_info.m_nbytes >= (double)(64*1024*1024))); + // calculate trigonometric array + // this function returns w/o doing nothing when sign of chirp_rate_ind + // reverses. so we have to take care of it. + if ( CacheChirpCalc ){ + CalcTrigArray(ul_NumDataPoints, ChirpRateInd ); + for ( ; i < last ; i += stride ){ + register double c1, c2, d1, d2; + register float R1, R2, I1, I2, t1, t2; + + c1 = CurrentTrig[i + 0].Cos; + d1 = CurrentTrig[i + 0].Sin * chirp_sign; // BENH - opt - avoid branch by multiply + c2 = CurrentTrig[i + 1].Cos; + d2 = CurrentTrig[i + 1].Sin * chirp_sign; + + // d = (chirp_rate_ind >0)? CurrentTrig[i].Sin : + // -CurrentTrig[i].Sin; Sometimes chirping is done in place. We + // don't want to overwrite data prematurely. + // + R1 = cx_DataArray[i + 0][0] * c1; + t1 = cx_DataArray[i + 0][1] * d1; + I1 = cx_DataArray[i + 0][0] * d1; + t2 = cx_DataArray[i + 0][1] * c1; + cx_ChirpDataArray[i + 0][0] = R1 - t1; + cx_ChirpDataArray[i + 0][1] = I1 + t2; + R2 = cx_DataArray[i + 1][0] * c2; + t1 = cx_DataArray[i + 1][1] * d2; + I2 = cx_DataArray[i + 1][0] * d2; + t2 = cx_DataArray[i + 1][1] * c2; + cx_ChirpDataArray[i + 1][0] = R2 - t1; + cx_ChirpDataArray[i + 1][1] = I2 + t2; + } + } +// cx_ChirpDataArray[64][1] = 3.012345; + + // Too little memory to cache sin/cos or just falling out of + // 'CacheChirpCalc' loop + // use original routine to finish up any tailings (max stride-1 elements) + for( ;i < ul_NumDataPoints; i++) { + double dd,cc; + double time=static_cast(i)*recip_sample_rate; + // since ang is getting moded by 2pi, we calculate "ang mod 2pi" + // before the call to sincos() inorder to reduce roundoff error. + // (Bug submitted by Tetsuji "Maverick" Rai) + double ang = 0.5*ChirpRate*time*time; + float c, d, real, imag; + ang -= floor(ang); + ang *= M_PI*2; + sincos(ang,&dd,&cc); + c=cc; + d=dd; + // Sometimes chirping is done in place. + // We don't want to overwrite data prematurely. + real = cx_DataArray[i][0] * c - cx_DataArray[i][1] * d; + imag = cx_DataArray[i][0] * d + cx_DataArray[i][1] * c; + cx_ChirpDataArray[i][0] = real; + cx_ChirpDataArray[i][1] = imag; + } + +//R count_flops( 12 * ul_NumDataPoints ); + analysis_state.FLOP_counter+=12.0*ul_NumDataPoints; + return ( 0 ); +} diff --git a/client/vector/analyzeFuncs_mmx.cpp b/client/vector/analyzeFuncs_mmx.cpp new file mode 100644 index 0000000..ad182f8 --- /dev/null +++ b/client/vector/analyzeFuncs_mmx.cpp @@ -0,0 +1,107 @@ +/****************** + * + * opt_mmx.cpp + * + * Description: Intel & AMD MMX optimized functions + * CPUs: Intel Pentium II and beyond, AMD K6 - and beyond + * + */ + +// Copyright 2006 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#include "x86_ops.h" + +typedef __m64 MMX; + +#define s_begin() _mm_empty() +#define s_end() _mm_empty() + +#define s_get64( ptr ) *( (MMX *) (ptr) ) +#define s_put64( ptr, aa ) ( *((MMX *) (ptr)) = aa ) +#define s_put64nc _mm_stream_pi + + +// +// +// +void __fastcall copy_MMX(char *dest, const char *src, int blocks) + { + MMX m0,m1,m2,m3,m4,m5,m6,m7; + + MMX *m_src = (MMX *)src; + MMX *m_dst = (MMX *)dest; + s_begin(); + while( blocks-- ) + { + m0 = s_get64( m_src + 0 ); + m1 = s_get64( m_src + 1 ); + m2 = s_get64( m_src + 2 ); + m3 = s_get64( m_src + 3 ); + m4 = s_get64( m_src + 4 ); + m5 = s_get64( m_src + 5 ); + m6 = s_get64( m_src + 6 ); + m7 = s_get64( m_src + 7 ); + m_src += 8; + s_put64( m_dst + 0, m0 ); + s_put64( m_dst + 1, m1 ); + s_put64( m_dst + 2, m2 ); + s_put64( m_dst + 3, m3 ); + s_put64( m_dst + 4, m4 ); + s_put64( m_dst + 5, m5 ); + s_put64( m_dst + 6, m6 ); + s_put64( m_dst + 7, m7 ); + m_dst += 8; + } + s_end(); + } + +// +// copyMMXnt - Use Non temporal writes, +// only available with 3DNow+ and SSE+ - Athlon and Pentium III +// +void __fastcall copy_MMXnt(char *dest, const char *src, int blocks) + { + MMX m0,m1,m2,m3,m4,m5,m6,m7; + + MMX *m_src = (MMX *)src; + MMX *m_dst = (MMX *)dest; + s_begin(); + while( blocks-- ) + { + s_fetch( m_src + 16 ); + m0 = s_get64( m_src + 0 ); + m1 = s_get64( m_src + 1 ); + m2 = s_get64( m_src + 2 ); + m3 = s_get64( m_src + 3 ); + m4 = s_get64( m_src + 4 ); + m5 = s_get64( m_src + 5 ); + m6 = s_get64( m_src + 6 ); + m7 = s_get64( m_src + 7 ); + m_src += 8; + s_put64nc( m_dst + 0, m0 ); + s_put64nc( m_dst + 1, m1 ); + s_put64nc( m_dst + 2, m2 ); + s_put64nc( m_dst + 3, m3 ); + s_put64nc( m_dst + 4, m4 ); + s_put64nc( m_dst + 5, m5 ); + s_put64nc( m_dst + 6, m6 ); + s_put64nc( m_dst + 7, m7 ); + m_dst += 8; + } + s_end(); + s_fence_writes(); + } diff --git a/client/vector/analyzeFuncs_sse.cpp b/client/vector/analyzeFuncs_sse.cpp new file mode 100644 index 0000000..f07d455 --- /dev/null +++ b/client/vector/analyzeFuncs_sse.cpp @@ -0,0 +1,3167 @@ + +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +// $Id: analyzeFuncs_sse.cpp,v 1.1.2.10 2007/06/08 03:09:47 korpela Exp $ +// + +// This file is empty is __i386__ is not defined +#include "sah_config.h" +#include + +#if defined(__i386__) || defined(__x86_64__) || defined(USE_SSE) + +#define INVALID_CHIRP 2e+20 + +#include "analyzeFuncs.h" +#include "analyzeFuncs_vector.h" +#include "analyzePoT.h" +#include "analyzeReport.h" +#include "gaussfit.h" +#include "s_util.h" +#include "diagnostics.h" +#include "asmlib.h" +#include "pulsefind.h" + +#include "x86_ops.h" +#include "x86_float4.h" + +static bool checked=false; +static bool hasSSE=false; + +bool boinc_has_sse( void ) { +#ifdef USE_ASMLIB + static bool hasSSE = (InstructionSet() >= 3) ? true : false; + return hasSSE; +#else + return true; +#endif +} + +template +inline void v_pfsubTranspose(float *in, float *out, int xline, int yline) { + // Transpose an X by X subsection of a XLINE by YLINE matrix into the + // appropriate part of a YLINE by XLINE matrix. "IN" points to the first + // (lowest address) element of the input submatrix. "OUT" points to the + // first (lowest address) element of the output submatrix. + int i,j; + float *p; + register float tmp[x*x]; + for (j=0;j(in+j*x+i,out+y*i+j,x,y); + } + for (;i(in+j*x+i,out+y*i+j,x,y); + } + for (;i(in+j*x+i,out+y*i+j,x,y); + } + for (;i(in+j*x+i,out+y*i+j,x,y); + } + for (;i(in+j*x+i,out+y*i+j,x,y); + } + for (;i(in+j*x+i,out+y*i+j,x,y); + } + for (;i(in+j*x+i,out+y*i+j,x,y); + } + for (;i(in+j*x+i,out+y*i+j,x,y); + } + for (;i(in+j*x+i,out+y*i+j,x,y); + } + for (;i(in+j*x+i,out+y*i+j,x,y); + } + for (;i(in, out, xline, yline); +#endif + prefetcht0(in+0*xline+4); + prefetcht0(in+1*xline+4); + prefetcht0(in+2*xline+4); + prefetcht0(in+3*xline+4); +} + +int v_vTranspose4(int x, int y, float *in, float *out) { + int i,j; + for (j=0;j(in+j*x+i,out+y*i+j,x,y); + } + for (;i(in+j*x+i,out+y*i+j,x,y); + } + for (;i(in, out, xline, yline); +#endif +} + +int v_vTranspose4np(int x, int y, float *in, float *out) { + int i,j; + for (j=0;j= 0.0) ? TWO_TO_52 : -TWO_TO_52; +#else + // For X87 FPU + double roundVal = (srate >= 0.0) ? ROUNDX87 : -ROUNDX87; +#endif + int i, vEnd; + unsigned short fpucw1, fpucw2; + + // main vectorised loop + vEnd = ul_NumDataPoints - (ul_NumDataPoints & 7); + for (i = 0; i < vEnd; i += 8) { + const float *data = (const float *) (fp_DataArray + i); + float *chirped = (float *) (fp_ChirpDataArray + i); + double angles[8], dtemp; + ALIGNED(float, 16) v_angle[4], v_angle2[4]; +// float __attribute__ ((aligned (16))) v_angle[4], v_angle2[4]; + + __m128 d1, d2; + __m128 cd1, cd2, cd3; + __m128 td1, td2; + __m128 x; + __m128 y; + __m128 s; + __m128 c; + __m128 m; + + prefetchnta((const void *)( data+32 )); + + dtemp = double( i ); + angles[0] = dtemp+0.0; + angles[1] = dtemp+1.0; + angles[2] = dtemp+2.0; + angles[3] = dtemp+3.0; + angles[4] = dtemp+4.0; + angles[5] = dtemp+5.0; + angles[6] = dtemp+6.0; + angles[7] = dtemp+7.0; + + // calculate the input angle + angles[0] *= angles[0] * srate; // angle^2 * rate + angles[1] *= angles[1] * srate; + angles[2] *= angles[2] * srate; + angles[3] *= angles[3] * srate; + angles[4] *= angles[4] * srate; + angles[5] *= angles[5] * srate; + angles[6] *= angles[6] * srate; + angles[7] *= angles[7] * srate; + + // reduce the angle to the range (-0.5, 0.5) + // convert doubles into singles + // This does "angles - round(angles)" + set_extended_precision(); + set_up_fastfrac(roundVal); + v_angle[0] = fastfrac(angles[0],roundVal); + v_angle[1] = fastfrac(angles[1],roundVal); + v_angle[2] = fastfrac(angles[2],roundVal); + v_angle[3] = fastfrac(angles[3],roundVal); + v_angle2[0] = fastfrac(angles[4],roundVal); + v_angle2[1] = fastfrac(angles[5],roundVal); + v_angle2[2] = fastfrac(angles[6],roundVal); + v_angle2[3] = fastfrac(angles[7],roundVal); + clean_up_fastfrac(); + restore_fpucw(); + + x = _mm_load_ps( v_angle ); + + // square to the range [0, 0.25) + y = _mm_mul_ps(x, x); + + // perform the initial polynomial approximations + s = _mm_mul_ps(y, SS4); + c = _mm_mul_ps(y, CC3); + s = _mm_add_ps(s, SS3); + c = _mm_add_ps(c, CC2); + s = _mm_mul_ps(s, y); + c = _mm_mul_ps(c, y); + s = _mm_add_ps(s, SS2); + c = _mm_add_ps(c, CC1); + s = _mm_mul_ps(s, y); + c = _mm_mul_ps(c, y); + s = _mm_add_ps(s, SS1); + s = _mm_mul_ps(s, x); + c = _mm_add_ps(c, ONE); + + // perform first angle doubling + cd1 = _mm_mul_ps(s, c); + cd2 = _mm_mul_ps(c, c); + cd3 = _mm_mul_ps(s, s); + y = _mm_mul_ps(cd1, TWO); + x = _mm_sub_ps(cd2, cd3); + + // load the signal to be chirped + d1 = _mm_load_ps(data); + d2 = _mm_load_ps(data+4); + + // calculate scaling factor to correct the magnitude + // m1 = vec_nmsub(y1, y1, vec_nmsub(x1, x1, TWO)); + // m2 = vec_nmsub(y2, y2, vec_nmsub(x2, x2, TWO)); + cd1 = _mm_mul_ps(x, y); + cd2 = _mm_mul_ps(x, x); + cd3 = _mm_mul_ps(y, y); + m = vec_recip1(_mm_add_ps(cd2, cd3 )); //scaling factor + + // perform second angle doubling + s = _mm_mul_ps(cd1, TWO); + c = _mm_sub_ps(cd2, cd3); + + // correct the magnitude (final sine / cosine approximations) + c = _mm_mul_ps(c, m); + s = _mm_mul_ps(s, m); + + x = d1; + y = d2; + x = _mm_shuffle_ps(x, x, 0xB1); + y = _mm_shuffle_ps(y, y, 0xB1); + x = _mm_mul_ps(x, R_NEG); + y = _mm_mul_ps(y, R_NEG); + cd1 = _mm_shuffle_ps(c, c, 0x50); // 01 01 00 00 AaBb => BBbb => c3c3c4c4 + cd2 = _mm_shuffle_ps(c, c, 0xfa); // 11 11 10 10 AaBb => AAaa => c1c1c2c2 + td1 = _mm_shuffle_ps(s, s, 0x50); + td2 = _mm_shuffle_ps(s, s, 0xfa); + + cd1 = _mm_mul_ps(cd1, d1); + cd2 = _mm_mul_ps(cd2, d2); + td1 = _mm_mul_ps(td1, x); + td2 = _mm_mul_ps(td2, y); + + cd1 = _mm_add_ps(cd1, td1); + cd2 = _mm_add_ps(cd2, td2); + + // store chirped values + _mm_stream_ps(chirped+0, cd1); + _mm_stream_ps(chirped+4, cd2); + + // Retrieve second set of reduced angles + x = _mm_load_ps( v_angle2 ); + + // square to the range [0, 0.25) + y = _mm_mul_ps(x, x); + + // perform the initial polynomial approximations + s = _mm_mul_ps(y, SS4); + c = _mm_mul_ps(y, CC3); + s = _mm_add_ps(s, SS3); + c = _mm_add_ps(c, CC2); + s = _mm_mul_ps(s, y); + c = _mm_mul_ps(c, y); + s = _mm_add_ps(s, SS2); + c = _mm_add_ps(c, CC1); + s = _mm_mul_ps(s, y); + c = _mm_mul_ps(c, y); + s = _mm_add_ps(s, SS1); + s = _mm_mul_ps(s, x); + c = _mm_add_ps(c, ONE); + + // perform first angle doubling + cd1 = _mm_mul_ps(s, c); + cd2 = _mm_mul_ps(c, c); + cd3 = _mm_mul_ps(s, s); + y = _mm_mul_ps(cd1, TWO); + x = _mm_sub_ps(cd2, cd3); + + // load the signal to be chirped + d1 = _mm_load_ps(data+8); + d2 = _mm_load_ps(data+12); + + // calculate scaling factor to correct the magnitude + // m1 = vec_nmsub(y1, y1, vec_nmsub(x1, x1, TWO)); + // m2 = vec_nmsub(y2, y2, vec_nmsub(x2, x2, TWO)); + cd1 = _mm_mul_ps(x, y); + cd2 = _mm_mul_ps(x, x); + cd3 = _mm_mul_ps(y, y); + m = vec_recip1(_mm_add_ps(cd2, cd3 )); //scaling factor + + // perform second angle doubling + s = _mm_mul_ps(cd1, TWO); + c = _mm_sub_ps(cd2, cd3); + + // correct the magnitude (final sine / cosine approximations) + c = _mm_mul_ps(c, m); + s = _mm_mul_ps(s, m); + + x = d1; + y = d2; + x = _mm_shuffle_ps(x, x, 0xB1); + y = _mm_shuffle_ps(y, y, 0xB1); + x = _mm_mul_ps(x, R_NEG); + y = _mm_mul_ps(y, R_NEG); + cd1 = _mm_shuffle_ps(c, c, 0x50); // 01 01 00 00 AaBb => BBbb => c3c3c4c4 + cd2 = _mm_shuffle_ps(c, c, 0xfa); // 11 11 10 10 AaBb => AAaa => c1c1c2c2 + td1 = _mm_shuffle_ps(s, s, 0x50); + td2 = _mm_shuffle_ps(s, s, 0xfa); + + cd1 = _mm_mul_ps(cd1, d1); + cd2 = _mm_mul_ps(cd2, d2); + td1 = _mm_mul_ps(td1, x); + td2 = _mm_mul_ps(td2, y); + + cd1 = _mm_add_ps(cd1, td1); + cd2 = _mm_add_ps(cd2, td2); + + // store chirped values + _mm_stream_ps(chirped+8, cd1); + _mm_stream_ps(chirped+12, cd2); + } + _mm_sfence(); + + if ( i < ul_NumDataPoints) { + // use original routine to finish up any tailings (max stride-1 elements) + v_ChirpData(fp_DataArray+i, fp_ChirpDataArray+i + , ChirpRateInd, ChirpRate, ul_NumDataPoints-i, sample_rate); + } + analysis_state.FLOP_counter+=12.0*ul_NumDataPoints; + + return 0; +} + +/*************************************************** + * + * Alternate chirp function using Faster SinCos and Estrin method + * for polynomial calculations. Derived from version 8 Alex Kan code. + */ +int sse1_ChirpData_ak8e( + sah_complex * fp_DataArray, + sah_complex * fp_ChirpDataArray, + int ChirpRateInd, + double ChirpRate, + int ul_NumDataPoints, + double sample_rate +) { + + if (ChirpRateInd == 0) { + memcpy(fp_ChirpDataArray, fp_DataArray, (int)ul_NumDataPoints * sizeof(sah_complex) ); + return 0; + } + + double srate = ChirpRate * 0.5 / (sample_rate * sample_rate); +#if defined(_LP64) || defined(_WIN64) || (defined(__GNUC__) && defined(__SSE_MATH__)) + // For scalar XMM code or any FPU with 64 bit registers + double roundVal = (srate >= 0.0) ? TWO_TO_52 : -TWO_TO_52; +#else + // For X87 FPU + double roundVal = (srate >= 0.0) ? ROUNDX87 : -ROUNDX87; +#endif + int i, vEnd; + unsigned short fpucw1, fpucw2; + + // main vectorised loop + vEnd = ul_NumDataPoints - (ul_NumDataPoints & 7); + + for (i = 0; i < vEnd; i += 8) { + const float *data = (const float *) (fp_DataArray + i); + float *chirped = (float *) (fp_ChirpDataArray + i); + double angles[8], dtemp; + + ALIGNED(float, 16) v_angle[4], v_angle2[4]; + + __m128 d1, d2; + __m128 cd1, cd2, cd3; + __m128 td1, td2; + __m128 v; + __m128 w; + __m128 x; + __m128 y; + __m128 z; + __m128 s; + __m128 c; + __m128 m; + + prefetchnta((const void *)( data+32 )); + + dtemp = double( i ); + angles[0] = dtemp+0.0; + angles[1] = dtemp+1.0; + angles[2] = dtemp+2.0; + angles[3] = dtemp+3.0; + angles[4] = dtemp+4.0; + angles[5] = dtemp+5.0; + angles[6] = dtemp+6.0; + angles[7] = dtemp+7.0; + + // calculate the input angle + angles[0] *= angles[0] * srate; // angle^2 * rate + angles[1] *= angles[1] * srate; + angles[2] *= angles[2] * srate; + angles[3] *= angles[3] * srate; + angles[4] *= angles[4] * srate; + angles[5] *= angles[5] * srate; + angles[6] *= angles[6] * srate; + angles[7] *= angles[7] * srate; + + // reduce the angle to the range (-0.5, 0.5) + // convert doubles into singles + // This does "angles - round(angles)" + set_extended_precision(); + set_up_fastfrac(roundVal); + v_angle[0] = fastfrac(angles[0],roundVal); + v_angle[1] = fastfrac(angles[1],roundVal); + v_angle[2] = fastfrac(angles[2],roundVal); + v_angle[3] = fastfrac(angles[3],roundVal); + v_angle2[0] = fastfrac(angles[4],roundVal); + v_angle2[1] = fastfrac(angles[5],roundVal); + v_angle2[2] = fastfrac(angles[6],roundVal); + v_angle2[3] = fastfrac(angles[7],roundVal); + clean_up_fastfrac(); + restore_fpucw(); + + x = _mm_load_ps( v_angle ); + + // square to the range [0, 0.25) + y = _mm_mul_ps(x, x); + + // perform the initial polynomial approximations with interleaved Estrin sequences + z = _mm_mul_ps(y, y); + s = _mm_mul_ps(y, SS4F); + c = _mm_mul_ps(y, CC3F); + s = _mm_add_ps(s, SS3F); + c = _mm_add_ps(c, CC2F); + s = _mm_mul_ps(s, z); + c = _mm_mul_ps(c, z); + v = _mm_mul_ps(y, SS2F); + w = _mm_mul_ps(y, CC1F); + v = _mm_add_ps(v, SS1F); + w = _mm_add_ps(w, ONE); + s = _mm_add_ps(s, v); + c = _mm_add_ps(c, w); + s = _mm_mul_ps(s, x); + + // perform first angle doubling + cd1 = _mm_mul_ps(s, c); + cd2 = _mm_mul_ps(c, c); + cd3 = _mm_mul_ps(s, s); + y = _mm_mul_ps(cd1, TWO); + x = _mm_sub_ps(cd2, cd3); + + // load the signal to be chirped + d1 = _mm_load_ps(data); + d2 = _mm_load_ps(data+4); + + // calculate scaling factor to correct the magnitude + // and perform second angle doubling + cd2 = _mm_mul_ps(x, x); + cd3 = _mm_mul_ps(y, y); + c = _mm_sub_ps(TWO, cd2); + cd1 = _mm_mul_ps(x, y); + m = _mm_sub_ps(c, cd3); + s = _mm_mul_ps(cd1, TWO); + c = _mm_sub_ps(cd2, cd3); + + // correct the magnitude (final sine / cosine approximations) + s = _mm_mul_ps(s, m); + c = _mm_mul_ps(c, m); + + x = d1; + y = d2; + x = _mm_shuffle_ps(x, x, 0xB1); + y = _mm_shuffle_ps(y, y, 0xB1); + x = _mm_mul_ps(x, R_NEG); + y = _mm_mul_ps(y, R_NEG); + cd1 = _mm_shuffle_ps(c, c, 0x50); + cd2 = _mm_shuffle_ps(c, c, 0xfa); + td1 = _mm_shuffle_ps(s, s, 0x50); + td2 = _mm_shuffle_ps(s, s, 0xfa); + + cd1 = _mm_mul_ps(cd1, d1); + cd2 = _mm_mul_ps(cd2, d2); + td1 = _mm_mul_ps(td1, x); + td2 = _mm_mul_ps(td2, y); + + cd1 = _mm_add_ps(cd1, td1); + cd2 = _mm_add_ps(cd2, td2); + + // store chirped values + _mm_stream_ps(chirped+0, cd1); + _mm_stream_ps(chirped+4, cd2); + + // Retrieve second set of reduced angles + x = _mm_load_ps( v_angle2 ); + + // square to the range [0, 0.25) + y = _mm_mul_ps(x, x); + + // perform the initial polynomial approximations with interleaved Estrin sequences + z = _mm_mul_ps(y, y); + s = _mm_mul_ps(y, SS4F); + c = _mm_mul_ps(y, CC3F); + s = _mm_add_ps(s, SS3F); + c = _mm_add_ps(c, CC2F); + s = _mm_mul_ps(s, z); + c = _mm_mul_ps(c, z); + v = _mm_mul_ps(y, SS2F); + w = _mm_mul_ps(y, CC1F); + v = _mm_add_ps(v, SS1F); + w = _mm_add_ps(w, ONE); + s = _mm_add_ps(s, v); + c = _mm_add_ps(c, w); + s = _mm_mul_ps(s, x); + + // perform first angle doubling + cd1 = _mm_mul_ps(s, c); + cd2 = _mm_mul_ps(c, c); + cd3 = _mm_mul_ps(s, s); + y = _mm_mul_ps(cd1, TWO); + x = _mm_sub_ps(cd2, cd3); + + // load the signal to be chirped + d1 = _mm_load_ps(data+8); + d2 = _mm_load_ps(data+12); + + // calculate scaling factor to correct the magnitude + // and perform second angle doubling + cd2 = _mm_mul_ps(x, x); + cd3 = _mm_mul_ps(y, y); + c = _mm_sub_ps(TWO, cd2); + cd1 = _mm_mul_ps(x, y); + m = _mm_sub_ps(c, cd3); + s = _mm_mul_ps(cd1, TWO); + c = _mm_sub_ps(cd2, cd3); + + // correct the magnitude (final sine / cosine approximations) + c = _mm_mul_ps(c, m); + s = _mm_mul_ps(s, m); + + x = d1; + y = d2; + x = _mm_shuffle_ps(x, x, 0xB1); + y = _mm_shuffle_ps(y, y, 0xB1); + x = _mm_mul_ps(x, R_NEG); + y = _mm_mul_ps(y, R_NEG); + cd1 = _mm_shuffle_ps(c, c, 0x50); // 01 01 00 00 AaBb => BBbb => c3c3c4c4 + cd2 = _mm_shuffle_ps(c, c, 0xfa); // 11 11 10 10 AaBb => AAaa => c1c1c2c2 + td1 = _mm_shuffle_ps(s, s, 0x50); + td2 = _mm_shuffle_ps(s, s, 0xfa); + + cd1 = _mm_mul_ps(cd1, d1); + cd2 = _mm_mul_ps(cd2, d2); + td1 = _mm_mul_ps(td1, x); + td2 = _mm_mul_ps(td2, y); + + cd1 = _mm_add_ps(cd1, td1); + cd2 = _mm_add_ps(cd2, td2); + + // store chirped values + _mm_stream_ps(chirped+8, cd1); + _mm_stream_ps(chirped+12, cd2); + } + _mm_sfence(); + + if ( i < ul_NumDataPoints) { + // use original routine to finish up any tailings (max stride-1 elements) + v_ChirpData(fp_DataArray+i, fp_ChirpDataArray+i + , ChirpRateInd, ChirpRate, ul_NumDataPoints-i, sample_rate); + } + analysis_state.FLOP_counter+=12.0*ul_NumDataPoints; + + return 0; +} + +/*************************************************** + * + * Alternate chirp function using Faster SinCos and Horner method + * for polynomial calculations. Derived from version 8 Alex Kan code. + */ +int sse1_ChirpData_ak8h( + sah_complex * fp_DataArray, + sah_complex * fp_ChirpDataArray, + int ChirpRateInd, + double ChirpRate, + int ul_NumDataPoints, + double sample_rate +) { + + if (ChirpRateInd == 0) { + memcpy(fp_ChirpDataArray, fp_DataArray, (int)ul_NumDataPoints * sizeof(sah_complex) ); + return 0; + } + + double srate = ChirpRate * 0.5 / (sample_rate * sample_rate); +#if defined(_LP64) || defined(_WIN64) || (defined(__GNUC__) && defined(__SSE_MATH__)) + // For scalar XMM code or any FPU with 64 bit registers + double roundVal = (srate >= 0.0) ? TWO_TO_52 : -TWO_TO_52; +#else + // For X87 FPU + double roundVal = (srate >= 0.0) ? ROUNDX87 : -ROUNDX87; +#endif + int i, vEnd; + unsigned short fpucw1, fpucw2; + + // main vectorised loop + vEnd = ul_NumDataPoints - (ul_NumDataPoints & 7); + + for (i = 0; i < vEnd; i += 8) { + const float *data = (const float *) (fp_DataArray + i); + float *chirped = (float *) (fp_ChirpDataArray + i); + double angles[8], dtemp; + + ALIGNED(float, 16) v_angle[4], v_angle2[4]; + + __m128 d1, d2; + __m128 cd1, cd2, cd3; + __m128 td1, td2; + __m128 x; + __m128 y; + __m128 s; + __m128 c; + __m128 m; + + prefetchnta((const void *)( data+32 )); + + dtemp = double( i ); + angles[0] = dtemp+0.0; + angles[1] = dtemp+1.0; + angles[2] = dtemp+2.0; + angles[3] = dtemp+3.0; + angles[4] = dtemp+4.0; + angles[5] = dtemp+5.0; + angles[6] = dtemp+6.0; + angles[7] = dtemp+7.0; + + // calculate the input angle + angles[0] *= angles[0] * srate; // angle^2 * rate + angles[1] *= angles[1] * srate; + angles[2] *= angles[2] * srate; + angles[3] *= angles[3] * srate; + angles[4] *= angles[4] * srate; + angles[5] *= angles[5] * srate; + angles[6] *= angles[6] * srate; + angles[7] *= angles[7] * srate; + + // reduce the angle to the range (-0.5, 0.5) + // convert doubles into singles + // This does "angles - round(angles)" + set_extended_precision(); + set_up_fastfrac(roundVal); + v_angle[0] = fastfrac(angles[0],roundVal); + v_angle[1] = fastfrac(angles[1],roundVal); + v_angle[2] = fastfrac(angles[2],roundVal); + v_angle[3] = fastfrac(angles[3],roundVal); + v_angle2[0] = fastfrac(angles[4],roundVal); + v_angle2[1] = fastfrac(angles[5],roundVal); + v_angle2[2] = fastfrac(angles[6],roundVal); + v_angle2[3] = fastfrac(angles[7],roundVal); + clean_up_fastfrac(); + restore_fpucw(); + + x = _mm_load_ps( v_angle ); + + // square to the range [0, 0.25) + y = _mm_mul_ps(x, x); + + // perform the initial polynomial approximations using interleaved Horner sequences + s = _mm_mul_ps(y, SS4F); + c = _mm_mul_ps(y, CC3F); + s = _mm_add_ps(s, SS3F); + c = _mm_add_ps(c, CC2F); + s = _mm_mul_ps(s, y); + c = _mm_mul_ps(c, y); + s = _mm_add_ps(s, SS2F); + c = _mm_add_ps(c, CC1F); + s = _mm_mul_ps(s, y); + c = _mm_mul_ps(c, y); + s = _mm_add_ps(s, SS1F); + c = _mm_add_ps(c, ONE); + s = _mm_mul_ps(s, x); + + // perform first angle doubling + cd1 = _mm_mul_ps(s, c); + cd2 = _mm_mul_ps(c, c); + cd3 = _mm_mul_ps(s, s); + y = _mm_mul_ps(cd1, TWO); + x = _mm_sub_ps(cd2, cd3); + + // load the signal to be chirped + d1 = _mm_load_ps(data); + d2 = _mm_load_ps(data+4); + + // calculate scaling factor to correct the magnitude + // and perform second angle doubling + cd2 = _mm_mul_ps(x, x); + cd3 = _mm_mul_ps(y, y); + c = _mm_sub_ps(TWO, cd2); + cd1 = _mm_mul_ps(x, y); + m = _mm_sub_ps(c, cd3); + s = _mm_mul_ps(cd1, TWO); + c = _mm_sub_ps(cd2, cd3); + + // correct the magnitude (final sine / cosine approximations) + s = _mm_mul_ps(s, m); + c = _mm_mul_ps(c, m); + + x = d1; + y = d2; + x = _mm_shuffle_ps(x, x, 0xB1); + y = _mm_shuffle_ps(y, y, 0xB1); + x = _mm_mul_ps(x, R_NEG); + y = _mm_mul_ps(y, R_NEG); + cd1 = _mm_shuffle_ps(c, c, 0x50); + cd2 = _mm_shuffle_ps(c, c, 0xfa); + td1 = _mm_shuffle_ps(s, s, 0x50); + td2 = _mm_shuffle_ps(s, s, 0xfa); + + cd1 = _mm_mul_ps(cd1, d1); + cd2 = _mm_mul_ps(cd2, d2); + td1 = _mm_mul_ps(td1, x); + td2 = _mm_mul_ps(td2, y); + + cd1 = _mm_add_ps(cd1, td1); + cd2 = _mm_add_ps(cd2, td2); + + // store chirped values + _mm_stream_ps(chirped+0, cd1); + _mm_stream_ps(chirped+4, cd2); + + // Retrieve second set of reduced angles + x = _mm_load_ps( v_angle2 ); + + // square to the range [0, 0.25) + y = _mm_mul_ps(x, x); + + // perform the initial polynomial approximations using interleaved Horner sequences + s = _mm_mul_ps(y, SS4F); + c = _mm_mul_ps(y, CC3F); + s = _mm_add_ps(s, SS3F); + c = _mm_add_ps(c, CC2F); + s = _mm_mul_ps(s, y); + c = _mm_mul_ps(c, y); + s = _mm_add_ps(s, SS2F); + c = _mm_add_ps(c, CC1F); + s = _mm_mul_ps(s, y); + c = _mm_mul_ps(c, y); + s = _mm_add_ps(s, SS1F); + c = _mm_add_ps(c, ONE); + s = _mm_mul_ps(s, x); + + // perform first angle doubling + cd1 = _mm_mul_ps(s, c); + cd2 = _mm_mul_ps(c, c); + cd3 = _mm_mul_ps(s, s); + y = _mm_mul_ps(cd1, TWO); + x = _mm_sub_ps(cd2, cd3); + + // load the signal to be chirped + d1 = _mm_load_ps(data+8); + d2 = _mm_load_ps(data+12); + + // calculate scaling factor to correct the magnitude + // and perform second angle doubling + cd2 = _mm_mul_ps(x, x); + cd3 = _mm_mul_ps(y, y); + c = _mm_sub_ps(TWO, cd2); + cd1 = _mm_mul_ps(x, y); + m = _mm_sub_ps(c, cd3); + s = _mm_mul_ps(cd1, TWO); + c = _mm_sub_ps(cd2, cd3); + + // correct the magnitude (final sine / cosine approximations) + c = _mm_mul_ps(c, m); + s = _mm_mul_ps(s, m); + + x = d1; + y = d2; + x = _mm_shuffle_ps(x, x, 0xB1); + y = _mm_shuffle_ps(y, y, 0xB1); + x = _mm_mul_ps(x, R_NEG); + y = _mm_mul_ps(y, R_NEG); + cd1 = _mm_shuffle_ps(c, c, 0x50); // 01 01 00 00 AaBb => BBbb => c3c3c4c4 + cd2 = _mm_shuffle_ps(c, c, 0xfa); // 11 11 10 10 AaBb => AAaa => c1c1c2c2 + td1 = _mm_shuffle_ps(s, s, 0x50); + td2 = _mm_shuffle_ps(s, s, 0xfa); + + cd1 = _mm_mul_ps(cd1, d1); + cd2 = _mm_mul_ps(cd2, d2); + td1 = _mm_mul_ps(td1, x); + td2 = _mm_mul_ps(td2, y); + + cd1 = _mm_add_ps(cd1, td1); + cd2 = _mm_add_ps(cd2, td2); + + // store chirped values + _mm_stream_ps(chirped+8, cd1); + _mm_stream_ps(chirped+12, cd2); + } + _mm_sfence(); + + if ( i < ul_NumDataPoints) { + // use original routine to finish up any tailings (max stride-1 elements) + v_ChirpData(fp_DataArray+i, fp_ChirpDataArray+i + , ChirpRateInd, ChirpRate, ul_NumDataPoints-i, sample_rate); + } + analysis_state.FLOP_counter+=12.0*ul_NumDataPoints; + + return 0; +} + + + +/********************************************************************* + * + * SSE Folding subroutine sets + * + */ +// These functions reduce an array length by a factor of 3, 4, 5, +// or 2 by summing and return the maximum of the summed values. +// Since each adjacent float is added to the next, simd works well. +// To keep multiple FPU or SSE units in any processor busy we try to +// avoid dependancy chains ( x += a, x += b, x += c) where each +// computation must wait til previous sum is computed. +// having two maximums running from two colums of numbers +// avoids a single max register from being the bottleneck + +int sse_mask1[] = {4, 1, 2, 3, 0, 0, 0, 0 }; +int sse_mask2[] = {4, 4, 4, 4, 4, 1, 2, 3 }; + +// ALIGN_SIMD unsigned int sse_partMask[][4] = { +ALIGNED(unsigned int, 16) sse_partMask[][4] = { + { 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF }, // 0 + { 0xFFFFFFFF,0x00000000,0x00000000,0x00000000 }, // 1 + { 0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000 }, // 2 + { 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0x00000000 }, // 3 + { 0x00000000,0x00000000,0x00000000,0x00000000 }, // 4 + }; + +#define SSE_MASK(idx) (*(__m128 *)&sse_partMask[idx]) + + +// maxp2f - +// function: Given a 4 packed float input, return the max among them +// concept: Ben Herndon +// +inline float s_maxp2f( __m128 max1 ) { + float tMax; + __m128 maxReg = max1; + + maxReg = _mm_movehl_ps( maxReg, max1 ); + maxReg = _mm_max_ps( maxReg, max1 ); // [0][1] vs [3][4] + max1 = _mm_shuffle_ps( maxReg, maxReg, 1 ); + maxReg = _mm_max_ss( maxReg, max1 ); // [1] vs [0] + + _mm_store_ss( &tMax, maxReg ); + return ( tMax ); +} + +#define s_getU( aaaa, ptr ) \ + aaaa = _mm_loadh_pi( _mm_loadl_pi(aaaa, (__m64 *)ptr), ((__m64 *)(ptr))+1 ) + +#define s_putU( ptr, aaaa ) \ + _mm_storel_pi((__m64 *)ptr, aaaa), _mm_storeh_pi( ((__m64 *)ptr)+1 , aaaa) + + +/****************** + * + * ben SSE folding + * + * Description: Intel & AMD SSE optimized folding + * CPUs: Intel Pentium III and beyond, AMD Athlon model 6 - and beyond + * + * Original code by Ben Herndon, modified by Joe Segur + * + */ + +// +// fold by 2 +// +float sse_sum2(float *ss[], struct PoTPlan *P) { + __m128 sum1, sum2, tmp1, tmp2, max1, max2; + int i, length = P->di; + float *ptr1 = ss[1]+P->offset; + float *ptr2 = ss[1]+P->tmp0; + float *sums = P->dest; + + max1 = max2 = ZERO; + + const int stride = 8; + + for (i = 0; i < length-(stride - 1); i += stride ) { + // SSE Pipeline #1 SSE Pipeline #2 + // + s_getU(sum1, &ptr1[i + 0] ); + s_getU(sum2, &ptr1[i + 4] ); + s_getU(tmp1, &ptr2[i + 0] ); + s_getU(tmp2, &ptr2[i + 4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + max1 = _mm_max_ps( max1, sum1 ); + max2 = _mm_max_ps( max2, sum2 ); + s_putU( &sums[i + 0], sum1 ); + s_putU( &sums[i +4], sum2 ); + } + + int mask1 = sse_mask1[ length-i]; + int mask2 = sse_mask2[ length-i]; + s_getU(sum1, &ptr1[i + 0] ); + s_getU(sum2, &ptr1[i + 4] ); + s_getU(tmp1, &ptr2[i + 0] ); + s_getU(tmp2, &ptr2[i + 4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + sum1 = _mm_and_ps(sum1, SSE_MASK( mask1 ) ); + sum2 = _mm_and_ps(sum2, SSE_MASK( mask2 ) ); + max1 = _mm_max_ps( max1, sum1 ); + max2 = _mm_max_ps( max2, sum2 ); + s_putU( &sums[i + 0], sum1 ); + s_putU( &sums[i +4], sum2 ); + + return s_maxp2f( _mm_max_ps( max1, max2 ) ); +} + +// +// fold by 3s +// +float sse_sum3(float *ss[], struct PoTPlan *P) { + __m128 sum1, sum2, tmp1, tmp2, max1, max2; + int i, length = P->di; + float *ptr1 = ss[0]; + float *ptr2 = ss[0]+P->tmp0; + float *ptr3 = ss[0]+P->tmp1; + float *sums = P->dest; + + max1 = max2 = ZERO; + + const int stride = 8; + for (i = 0; i < length-(stride - 1); i += stride ) { + // SSE Pipeline #1 SSE Pipeline #2 + // + s_getU(sum1, &ptr1[i + 0] ); + s_getU(sum2, &ptr1[i + 4] ); + s_getU(tmp1, &ptr2[i + 0] ); + s_getU(tmp2, &ptr2[i + 4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + s_getU(tmp1, &ptr3[i + 0] ); + s_getU(tmp2, &ptr3[i + 4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + max1 = _mm_max_ps( max1, sum1 ); + max2 = _mm_max_ps( max2, sum2 ); + s_putU( &sums[i + 0], sum1 ); + s_putU( &sums[i +4], sum2 ); + } + + int mask1 = sse_mask1[ length-i]; + int mask2 = sse_mask2[ length-i]; + s_getU(sum1, &ptr1[i + 0] ); + s_getU(sum2, &ptr1[i + 4] ); + s_getU(tmp1, &ptr2[i + 0] ); + s_getU(tmp2, &ptr2[i + 4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + s_getU(tmp1, &ptr3[i + 0] ); + s_getU(tmp2, &ptr3[i + 4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + sum1 = _mm_and_ps(sum1, SSE_MASK( mask1 ) ); + sum2 = _mm_and_ps(sum2, SSE_MASK( mask2 ) ); + max1 = _mm_max_ps( max1, sum1 ); + max2 = _mm_max_ps( max2, sum2 ); + s_putU( &sums[i + 0], sum1 ); + s_putU( &sums[i +4], sum2 ); + + return s_maxp2f( _mm_max_ps( max1, max2 ) ); +} + +// +// fold by 4 +// +float sse_sum4(float *ss[], struct PoTPlan *P) { + __m128 sum1, sum2, tmp1, tmp2, max1, max2; + int i, length = P->di; + float *ptr1 = ss[0]; + float *ptr2 = ss[0]+P->tmp0; + float *ptr3 = ss[0]+P->tmp1; + float *ptr4 = ss[0]+P->tmp2; + float *sums = P->dest; + + max1 = max2 = ZERO; + + const int stride = 8; + for (i = 0; i < length-(stride - 1); i += stride ) { + // SSE Pipeline #1 SSE Pipeline #2 + // + s_getU(sum1, &ptr1[i + 0] ); + s_getU(sum2, &ptr1[i + 4] ); + s_getU(tmp1, &ptr2[i + 0] ); + s_getU(tmp2, &ptr2[i + 4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + s_getU(tmp1, &ptr3[i + 0] ); + s_getU(tmp2, &ptr3[i + 4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + s_getU(tmp1, &ptr4[i + 0] ); + s_getU(tmp2, &ptr4[i + 4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + max1 = _mm_max_ps( max1, sum1 ); + max2 = _mm_max_ps( max2, sum2 ); + s_putU( &sums[i + 0], sum1 ); + s_putU( &sums[i +4], sum2 ); + } + + int mask1 = sse_mask1[ length-i]; + int mask2 = sse_mask2[ length-i]; + s_getU(sum1, &ptr1[i + 0] ); + s_getU(sum2, &ptr1[i + 4] ); + s_getU(tmp1, &ptr2[i + 0] ); + s_getU(tmp2, &ptr2[i + 4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + s_getU(tmp1, &ptr3[i + 0] ); + s_getU(tmp2, &ptr3[i + 4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + s_getU(tmp1, &ptr4[i + 0] ); + s_getU(tmp2, &ptr4[i + 4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + sum1 = _mm_and_ps(sum1, SSE_MASK( mask1 ) ); + sum2 = _mm_and_ps(sum2, SSE_MASK( mask2 ) ); + max1 = _mm_max_ps( max1, sum1 ); + max2 = _mm_max_ps( max2, sum2 ); + s_putU( &sums[i + 0], sum1 ); + s_putU( &sums[i +4], sum2 ); + + return s_maxp2f( _mm_max_ps( max1, max2 ) ); +} + +// +// fold by 5 +// +float sse_sum5(float *ss[], struct PoTPlan *P) { + __m128 sum1, sum2, tmp1, tmp2, max1, max2; + int i, length = P->di; + float *ptr1 = ss[0]; + float *ptr2 = ss[0]+P->tmp0; + float *ptr3 = ss[0]+P->tmp1; + float *ptr4 = ss[0]+P->tmp2; + float *ptr5 = ss[0]+P->tmp3; + float *sums = P->dest; + + max1 = max2 = ZERO; + + const int stride = 8; + for (i = 0; i < length-(stride - 1); i += stride ) { + // SSE Pipeline #1 SSE Pipeline #2 + // + s_getU(sum1, &ptr1[i + 0] ); + s_getU(sum2, &ptr1[i + 4] ); + s_getU(tmp1, &ptr2[i + 0] ); + s_getU(tmp2, &ptr2[i + 4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + s_getU(tmp1, &ptr3[i + 0] ); + s_getU(tmp2, &ptr3[i + 4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + s_getU(tmp1, &ptr4[i + 0] ); + s_getU(tmp2, &ptr4[i + 4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + s_getU(tmp1, &ptr5[i + 0] ); + s_getU(tmp2, &ptr5[i + 4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + max1 = _mm_max_ps( max1, sum1 ); + max2 = _mm_max_ps( max2, sum2 ); + s_putU( &sums[i + 0], sum1 ); + s_putU( &sums[i +4], sum2 ); + } + + int mask1 = sse_mask1[ length-i]; + int mask2 = sse_mask2[ length-i]; + s_getU(sum1, &ptr1[i + 0] ); + s_getU(sum2, &ptr1[i + 4] ); + s_getU(tmp1, &ptr2[i + 0] ); + s_getU(tmp2, &ptr2[i + 4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + s_getU(tmp1, &ptr3[i + 0] ); + s_getU(tmp2, &ptr3[i + 4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + s_getU(tmp1, &ptr4[i + 0] ); + s_getU(tmp2, &ptr4[i + 4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + s_getU(tmp1, &ptr5[i + 0] ); + s_getU(tmp2, &ptr5[i + 4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + sum1 = _mm_and_ps(sum1, SSE_MASK( mask1 ) ); + sum2 = _mm_and_ps(sum2, SSE_MASK( mask2 ) ); + max1 = _mm_max_ps( max1, sum1 ); + max2 = _mm_max_ps( max2, sum2 ); + s_putU( &sums[i + 0], sum1 ); + s_putU( &sums[i +4], sum2 ); + + return s_maxp2f( _mm_max_ps( max1, max2 ) ); +} + +sum_func sse_list3[FOLDTBLEN] = { + sse_sum3, sse_sum3, sse_sum3, sse_sum3, + sse_sum3, sse_sum3, sse_sum3, sse_sum3, + sse_sum3, sse_sum3, sse_sum3, sse_sum3, + sse_sum3, sse_sum3, sse_sum3, sse_sum3, + sse_sum3, sse_sum3, sse_sum3, sse_sum3, + sse_sum3, sse_sum3, sse_sum3, sse_sum3, + sse_sum3, sse_sum3, sse_sum3, sse_sum3, + sse_sum3, sse_sum3, sse_sum3, sse_sum3 + }; +sum_func sse_list4[FOLDTBLEN] = { + sse_sum4, sse_sum4, sse_sum4, sse_sum4, + sse_sum4, sse_sum4, sse_sum4, sse_sum4, + sse_sum4, sse_sum4, sse_sum4, sse_sum4, + sse_sum4, sse_sum4, sse_sum4, sse_sum4, + sse_sum4, sse_sum4, sse_sum4, sse_sum4, + sse_sum4, sse_sum4, sse_sum4, sse_sum4, + sse_sum4, sse_sum4, sse_sum4, sse_sum4, + sse_sum4, sse_sum4, sse_sum4, sse_sum4 + }; +sum_func sse_list5[FOLDTBLEN] = { + sse_sum5, sse_sum5, sse_sum5, sse_sum5, + sse_sum5, sse_sum5, sse_sum5, sse_sum5, + sse_sum5, sse_sum5, sse_sum5, sse_sum5, + sse_sum5, sse_sum5, sse_sum5, sse_sum5, + sse_sum5, sse_sum5, sse_sum5, sse_sum5, + sse_sum5, sse_sum5, sse_sum5, sse_sum5, + sse_sum5, sse_sum5, sse_sum5, sse_sum5, + sse_sum5, sse_sum5, sse_sum5, sse_sum5 + }; +sum_func sse_list2[FOLDTBLEN] = { + sse_sum2, sse_sum2, sse_sum2, sse_sum2, + sse_sum2, sse_sum2, sse_sum2, sse_sum2, + sse_sum2, sse_sum2, sse_sum2, sse_sum2, + sse_sum2, sse_sum2, sse_sum2, sse_sum2, + sse_sum2, sse_sum2, sse_sum2, sse_sum2, + sse_sum2, sse_sum2, sse_sum2, sse_sum2, + sse_sum2, sse_sum2, sse_sum2, sse_sum2, + sse_sum2, sse_sum2, sse_sum2, sse_sum2 + }; +sum_func sse_list2_L[FOLDTBLEN] = { + sse_sum2, sse_sum2, sse_sum2, sse_sum2, + sse_sum2, sse_sum2, sse_sum2, sse_sum2, + sse_sum2, sse_sum2, sse_sum2, sse_sum2, + sse_sum2, sse_sum2, sse_sum2, sse_sum2, + sse_sum2, sse_sum2, sse_sum2, sse_sum2, + sse_sum2, sse_sum2, sse_sum2, sse_sum2, + sse_sum2, sse_sum2, sse_sum2, sse_sum2, + sse_sum2, sse_sum2, sse_sum2, sse_sum2 + }; + +FoldSet sse_ben_fold = {sse_list3, sse_list4, sse_list5, sse_list2, sse_list2_L, "ben SSE"}; + + + +/****************** + * + * BH SSE folding + * + * Description: Intel & AMD SSE optimized folding + * CPUs: Intel Pentium III and beyond, AMD Athlon model 6 - and beyond + * + * Original code by Ben Herndon, modified by Joe Segur + * + */ + +int sse_msks1[] = {4, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +int sse_msks2[] = {4, 4, 4, 4, 4, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + +//ALIGN_SIMD float sse_foldLim[][4] = { +ALIGNED(float, 16) sse_foldLim[][4] = { + { 0.0f, 0.0f, 0.0f, 0.0f }, // 0 + { 0.0f, 1e37f, 1e37f, 1e37f }, // 1 + { 0.0f, 0.0f, 1e37f, 1e37f }, // 2 + { 0.0f, 0.0f, 0.0f, 1e37f }, // 3 + { 1e37f, 1e37f, 1e37f, 1e37f }, // 4 + }; + +#define SSE_LIM(idx) (*(__m128 *)&sse_foldLim[idx]) + + +// +// Fold by 3 versions +// +float sse_pulPoTf3u(float *ss[], struct PoTPlan *P) { + __m128 sum1, sum2, max1, max2; + __m128 tmp1, tmp2; + int i; + + max1 = max2 = _mm_set_ps1( 0.0 ); + float *ptr1 = ss[0]; + float *ptr2 = ss[0] + P->tmp0; + float *ptr3 = ss[0] + P->tmp1; + + const int stride = 24; + for (i = 0; i < P->di - ( stride - 1 ); i += stride ) { + // SSE Pipeline #1 SSE Pipeline #2 + // + sum1 = _mm_load_ps( &ptr1[i + 0] ); + sum2 = _mm_load_ps( &ptr1[i + 4] ); + s_getU(tmp1, &ptr2[i + 0] ); + s_getU(tmp2, &ptr2[i + 4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + s_getU(tmp1, &ptr3[i + 0] ); + s_getU(tmp2, &ptr3[i + 4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + max1 = _mm_max_ps( max1, sum1 ); + max2 = _mm_max_ps( max2, sum2 ); + _mm_store_ps( &P->dest[i + 0], sum1 ); + _mm_store_ps( &P->dest[i + 4], sum2 ); + + sum1 = _mm_load_ps( &ptr1[i + 8] ); + sum2 = _mm_load_ps( &ptr1[i + 12] ); + s_getU(tmp1, &ptr2[i + 8] ); + s_getU(tmp2, &ptr2[i + 12] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + s_getU(tmp1, &ptr3[i + 8] ); + s_getU(tmp2, &ptr3[i + 12] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + max1 = _mm_max_ps( max1, sum1 ); + max2 = _mm_max_ps( max2, sum2 ); + _mm_store_ps( &P->dest[i + 8], sum1 ); + _mm_store_ps( &P->dest[i + 12], sum2 ); + + sum1 = _mm_load_ps( &ptr1[i + 16] ); + sum2 = _mm_load_ps( &ptr1[i + 20] ); + s_getU(tmp1, &ptr2[i + 16] ); + s_getU(tmp2, &ptr2[i + 20] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + s_getU(tmp1, &ptr3[i + 16] ); + s_getU(tmp2, &ptr3[i + 20] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + max1 = _mm_max_ps( max1, sum1 ); + max2 = _mm_max_ps( max2, sum2 ); + _mm_store_ps( &P->dest[i + 16], sum1 ); + _mm_store_ps( &P->dest[i + 20], sum2 ); + } + max1 = _mm_max_ps( max1, max2 ); + for ( ; i < P->di ; i += 4) { + int mask1 = sse_msks1[ P->di-i]; + sum1 = _mm_load_ps( &ptr1[i + 0] ); + s_getU(tmp1, &ptr2[i + 0] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + s_getU(tmp1, &ptr3[i + 0] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + _mm_store_ps( &P->dest[i + 0], sum1 ); + sum1 = _mm_sub_ps(sum1, SSE_LIM( mask1 ) ); + max1 = _mm_max_ps( max1, sum1 ); + } + return ( s_maxp2f( max1 ) ); +} + +float sse_pulPoTf3(float *ss[], struct PoTPlan *P) { + __m128 sum1, sum2, max1, max2; + __m128 tmp1, tmp2; + int i; + + max1 = max2 = _mm_set_ps1( 0.0 ); + float *ptr1 = ss[0]; + float *ptr2 = ss[0] + P->tmp0; + float *ptr3 = ss[0] + P->tmp1; + + const int stride = 8; + for (i = 0; i < P->di - (stride - 1); i += stride ) { + // SSE Pipeline #1 SSE Pipeline #2 + // + sum1 = _mm_load_ps( &ptr1[i + 0] ); + sum2 = _mm_load_ps( &ptr1[i + 4] ); + s_getU(tmp1, &ptr2[i + 0] ); + s_getU(tmp2, &ptr2[i + 4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + s_getU(tmp1, &ptr3[i + 0] ); + s_getU(tmp2, &ptr3[i + 4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + max1 = _mm_max_ps( max1, sum1 ); + max2 = _mm_max_ps( max2, sum2 ); + _mm_store_ps( &P->dest[i + 0], sum1 ); + _mm_store_ps( &P->dest[i + 4], sum2 ); + } + max1 = _mm_max_ps( max1, max2 ); + for ( ; i < P->di ; i += 4) { + int mask1 = sse_msks1[ P->di-i]; + sum1 = _mm_load_ps( &ptr1[i + 0] ); + s_getU(tmp1, &ptr2[i + 0] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + s_getU(tmp1, &ptr3[i + 0] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + _mm_store_ps( &P->dest[i + 0], sum1 ); + sum1 = _mm_sub_ps(sum1, SSE_LIM( mask1 ) ); + max1 = _mm_max_ps( max1, sum1 ); + } + return ( s_maxp2f( max1 ) ); +} + +float sse_pulPoTf3L8(float *ss[], struct PoTPlan *P) { + __m128 sum1, sum2, max1, max2; + __m128 tmp1, tmp2; + + max1 = max2 = _mm_set_ps1( 0.0 ); + float *ptr1 = ss[0]; + float *ptr2 = ss[0] + P->tmp0; + float *ptr3 = ss[0] + P->tmp1; + + // SSE Pipeline #1 SSE Pipeline #2 + // + int mask1 = sse_msks1[ P->di ]; + int mask2 = sse_msks2[ P->di ]; + sum1 = _mm_load_ps( &ptr1[0] ); + sum2 = _mm_load_ps( &ptr1[4] ); + s_getU(tmp1, &ptr2[0] ); + s_getU(tmp2, &ptr2[4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + s_getU(tmp1, &ptr3[0] ); + s_getU(tmp2, &ptr3[4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + _mm_store_ps( &P->dest[0], sum1 ); + _mm_store_ps( &P->dest[4], sum2 ); + sum1 = _mm_sub_ps(sum1, SSE_LIM( mask1 ) ); + sum2 = _mm_sub_ps(sum2, SSE_LIM( mask2 ) ); + max1 = _mm_max_ps( max1, sum1 ); + max2 = _mm_max_ps( max2, sum2 ); + + return ( s_maxp2f( _mm_max_ps( max1, max2 ) ) ); +} + +sum_func BHSSETB3[FOLDTBLEN] = + { + sse_pulPoTf3L8, sse_pulPoTf3L8, sse_pulPoTf3L8, sse_pulPoTf3L8, + sse_pulPoTf3L8, sse_pulPoTf3L8, sse_pulPoTf3L8, sse_pulPoTf3L8, + sse_pulPoTf3L8, sse_pulPoTf3, sse_pulPoTf3, sse_pulPoTf3, + sse_pulPoTf3, sse_pulPoTf3, sse_pulPoTf3, sse_pulPoTf3, + sse_pulPoTf3, sse_pulPoTf3, sse_pulPoTf3, sse_pulPoTf3, + sse_pulPoTf3, sse_pulPoTf3, sse_pulPoTf3, sse_pulPoTf3, + sse_pulPoTf3u + }; + +// +// Fold by 4 versions +// +float sse_pulPoTf4u(float *ss[], struct PoTPlan *P) { + __m128 sum1, sum2, max1, max2; + __m128 tmp1, tmp2; + int i; + + max1 = max2 = _mm_set_ps1( 0.0 ); + float *ptr1 = ss[0]; + float *ptr2 = ss[0] + P->tmp0; + float *ptr3 = ss[0] + P->tmp1; + float *ptr4 = ss[0] + P->tmp2; + + const int stride = 24; + for (i = 0; i < P->di - ( stride - 1 ); i += stride ) { + // SSE Pipeline #1 SSE Pipeline #2 + // + sum1 = _mm_load_ps( &ptr1[i + 0] ); + sum2 = _mm_load_ps( &ptr1[i + 4] ); + s_getU(tmp1, &ptr2[i + 0] ); + s_getU(tmp2, &ptr2[i + 4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + s_getU(tmp1, &ptr3[i + 0] ); + s_getU(tmp2, &ptr3[i + 4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + s_getU(tmp1, &ptr4[i + 0] ); + s_getU(tmp2, &ptr4[i + 4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + max1 = _mm_max_ps( max1, sum1 ); + max2 = _mm_max_ps( max2, sum2 ); + _mm_store_ps( &P->dest[i + 0], sum1 ); + _mm_store_ps( &P->dest[i + 4], sum2 ); + + sum1 = _mm_load_ps( &ptr1[i + 8] ); + sum2 = _mm_load_ps( &ptr1[i + 12] ); + s_getU(tmp1, &ptr2[i + 8] ); + s_getU(tmp2, &ptr2[i + 12] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + s_getU(tmp1, &ptr3[i + 8] ); + s_getU(tmp2, &ptr3[i + 12] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + s_getU(tmp1, &ptr4[i + 8] ); + s_getU(tmp2, &ptr4[i + 12] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + max1 = _mm_max_ps( max1, sum1 ); + max2 = _mm_max_ps( max2, sum2 ); + _mm_store_ps( &P->dest[i + 8], sum1 ); + _mm_store_ps( &P->dest[i + 12], sum2 ); + + sum1 = _mm_load_ps( &ptr1[i + 16] ); + sum2 = _mm_load_ps( &ptr1[i + 20] ); + s_getU(tmp1, &ptr2[i + 16] ); + s_getU(tmp2, &ptr2[i + 20] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + s_getU(tmp1, &ptr3[i + 16] ); + s_getU(tmp2, &ptr3[i + 20] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + s_getU(tmp1, &ptr4[i + 16] ); + s_getU(tmp2, &ptr4[i + 20] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + max1 = _mm_max_ps( max1, sum1 ); + max2 = _mm_max_ps( max2, sum2 ); + _mm_store_ps( &P->dest[i + 16], sum1 ); + _mm_store_ps( &P->dest[i + 20], sum2 ); + } + max1 = _mm_max_ps( max1, max2 ); + for ( ; i < P->di ; i += 4) { + int mask1 = sse_msks1[ P->di-i]; + sum1 = _mm_load_ps( &ptr1[i + 0] ); + s_getU(tmp1, &ptr2[i + 0] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + s_getU(tmp1, &ptr3[i + 0] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + s_getU(tmp1, &ptr4[i + 0] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + _mm_store_ps( &P->dest[i + 0], sum1 ); + sum1 = _mm_sub_ps(sum1, SSE_LIM( mask1 ) ); + max1 = _mm_max_ps( max1, sum1 ); + } + return ( s_maxp2f( max1 ) ); +} + +float sse_pulPoTf4(float *ss[], struct PoTPlan *P) { + __m128 sum1, sum2, max1, max2; + __m128 tmp1, tmp2; + int i; + + max1 = max2 = _mm_set_ps1( 0.0 ); + float *ptr1 = ss[0]; + float *ptr2 = ss[0] + P->tmp0; + float *ptr3 = ss[0] + P->tmp1; + float *ptr4 = ss[0] + P->tmp2; + + const int stride = 8; + for (i = 0; i < P->di - ( stride - 1 ); i += stride ) { + // SSE Pipeline #1 SSE Pipeline #2 + // + sum1 = _mm_load_ps( &ptr1[i + 0] ); + sum2 = _mm_load_ps( &ptr1[i + 4] ); + s_getU(tmp1, &ptr2[i + 0] ); + s_getU(tmp2, &ptr2[i + 4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + s_getU(tmp1, &ptr3[i + 0] ); + s_getU(tmp2, &ptr3[i + 4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + s_getU(tmp1, &ptr4[i + 0] ); + s_getU(tmp2, &ptr4[i + 4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + max1 = _mm_max_ps( max1, sum1 ); + max2 = _mm_max_ps( max2, sum2 ); + _mm_store_ps( &P->dest[i + 0], sum1 ); + _mm_store_ps( &P->dest[i + 4], sum2 ); + } + max1 = _mm_max_ps( max1, max2 ); + for ( ; i < P->di ; i += 4) { + int mask1 = sse_msks1[ P->di-i]; + sum1 = _mm_load_ps( &ptr1[i + 0] ); + s_getU(tmp1, &ptr2[i + 0] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + s_getU(tmp1, &ptr3[i + 0] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + s_getU(tmp1, &ptr4[i + 0] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + _mm_store_ps( &P->dest[i + 0], sum1 ); + sum1 = _mm_sub_ps(sum1, SSE_LIM( mask1 ) ); + max1 = _mm_max_ps( max1, sum1 ); + } + return ( s_maxp2f( max1 ) ); +} + + +float sse_pulPoTf4L8(float *ss[], struct PoTPlan *P) { + __m128 sum1, sum2, max1, max2; + __m128 tmp1, tmp2; + int i; + + max1 = max2 = _mm_set_ps1( 0.0 ); + float *ptr1 = ss[0]; + float *ptr2 = ss[0] + P->tmp0; + float *ptr3 = ss[0] + P->tmp1; + float *ptr4 = ss[0] + P->tmp2; + + // SSE Pipeline #1 SSE Pipeline #2 + // + int mask1 = sse_msks1[ P->di ]; + int mask2 = sse_msks2[ P->di ]; + sum1 = _mm_load_ps( &ptr1[0] ); + sum2 = _mm_load_ps( &ptr1[4] ); + s_getU(tmp1, &ptr2[0] ); + s_getU(tmp2, &ptr2[4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + s_getU(tmp1, &ptr3[0] ); + s_getU(tmp2, &ptr3[4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + s_getU(tmp1, &ptr4[0] ); + s_getU(tmp2, &ptr4[4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + _mm_store_ps( &P->dest[0], sum1 ); + _mm_store_ps( &P->dest[4], sum2 ); + sum1 = _mm_sub_ps(sum1, SSE_LIM( mask1 ) ); + sum2 = _mm_sub_ps(sum2, SSE_LIM( mask2 ) ); + max1 = _mm_max_ps( max1, sum1 ); + max2 = _mm_max_ps( max2, sum2 ); + + return ( s_maxp2f( _mm_max_ps( max1, max2 ) ) ); +} + +sum_func BHSSETB4[FOLDTBLEN] = { + sse_pulPoTf4L8, sse_pulPoTf4L8, sse_pulPoTf4L8, sse_pulPoTf4L8, + sse_pulPoTf4L8, sse_pulPoTf4L8, sse_pulPoTf4L8, sse_pulPoTf4L8, + sse_pulPoTf4L8, sse_pulPoTf4, sse_pulPoTf4, sse_pulPoTf4, + sse_pulPoTf4, sse_pulPoTf4, sse_pulPoTf4, sse_pulPoTf4, + sse_pulPoTf4, sse_pulPoTf4, sse_pulPoTf4, sse_pulPoTf4, + sse_pulPoTf4, sse_pulPoTf4, sse_pulPoTf4, sse_pulPoTf4, + sse_pulPoTf4u + }; + +// +// Fold by 5 versions +// +float sse_pulPoTf5u(float *ss[], struct PoTPlan *P) { + __m128 sum1, sum2, max1, max2; + __m128 tmp1, tmp2; + int i; + + max1 = max2 = _mm_set_ps1( 0.0 ); + float *ptr1 = ss[0]; + float *ptr2 = ss[0] + P->tmp0; + float *ptr3 = ss[0] + P->tmp1; + float *ptr4 = ss[0] + P->tmp2; + float *ptr5 = ss[0] + P->tmp3; + + const int stride = 24; + for (i = 0; i < P->di - ( stride - 1 ); i += stride ) { + // SSE Pipeline #1 SSE Pipeline #2 + // + sum1 = _mm_load_ps( &ptr1[i + 0] ); + sum2 = _mm_load_ps( &ptr1[i + 4] ); + s_getU(tmp1, &ptr2[i + 0] ); + s_getU(tmp2, &ptr2[i + 4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + s_getU(tmp1, &ptr3[i + 0] ); + s_getU(tmp2, &ptr3[i + 4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + s_getU(tmp1, &ptr4[i + 0] ); + s_getU(tmp2, &ptr4[i + 4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + s_getU(tmp1, &ptr5[i + 0] ); + s_getU(tmp2, &ptr5[i + 4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + max1 = _mm_max_ps( max1, sum1 ); + max2 = _mm_max_ps( max2, sum2 ); + _mm_store_ps( &P->dest[i + 0], sum1 ); + _mm_store_ps( &P->dest[i + 4], sum2 ); + + sum1 = _mm_load_ps( &ptr1[i + 8] ); + sum2 = _mm_load_ps( &ptr1[i + 12] ); + s_getU(tmp1, &ptr2[i + 8] ); + s_getU(tmp2, &ptr2[i + 12] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + s_getU(tmp1, &ptr3[i + 8] ); + s_getU(tmp2, &ptr3[i + 12] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + s_getU(tmp1, &ptr4[i + 8] ); + s_getU(tmp2, &ptr4[i + 12] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + s_getU(tmp1, &ptr5[i + 8] ); + s_getU(tmp2, &ptr5[i + 12] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + max1 = _mm_max_ps( max1, sum1 ); + max2 = _mm_max_ps( max2, sum2 ); + _mm_store_ps( &P->dest[i + 8], sum1 ); + _mm_store_ps( &P->dest[i + 12], sum2 ); + + sum1 = _mm_load_ps( &ptr1[i + 16] ); + sum2 = _mm_load_ps( &ptr1[i + 20] ); + s_getU(tmp1, &ptr2[i + 16] ); + s_getU(tmp2, &ptr2[i + 20] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + s_getU(tmp1, &ptr3[i + 16] ); + s_getU(tmp2, &ptr3[i + 20] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + s_getU(tmp1, &ptr4[i + 16] ); + s_getU(tmp2, &ptr4[i + 20] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + s_getU(tmp1, &ptr5[i + 16] ); + s_getU(tmp2, &ptr5[i + 20] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + max1 = _mm_max_ps( max1, sum1 ); + max2 = _mm_max_ps( max2, sum2 ); + _mm_store_ps( &P->dest[i + 16], sum1 ); + _mm_store_ps( &P->dest[i + 20], sum2 ); + } + max1 = _mm_max_ps( max1, max2 ); + for ( ; i < P->di ; i += 4) { + int mask1 = sse_msks1[ P->di-i]; + sum1 = _mm_load_ps( &ptr1[i + 0] ); + s_getU(tmp1, &ptr2[i + 0] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + s_getU(tmp1, &ptr3[i + 0] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + s_getU(tmp1, &ptr4[i + 0] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + s_getU(tmp1, &ptr5[i + 0] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + _mm_store_ps( &P->dest[i + 0], sum1 ); + sum1 = _mm_sub_ps(sum1, SSE_LIM( mask1 ) ); + max1 = _mm_max_ps( max1, sum1 ); + } + return ( s_maxp2f( max1 ) ); +} + +float sse_pulPoTf5(float *ss[], struct PoTPlan *P) { + __m128 sum1, sum2, max1, max2; + __m128 tmp1, tmp2; + int i; + + max1 = max2 = _mm_set_ps1( 0.0 ); + float *ptr1 = ss[0]; + float *ptr2 = ss[0] + P->tmp0; + float *ptr3 = ss[0] + P->tmp1; + float *ptr4 = ss[0] + P->tmp2; + float *ptr5 = ss[0] + P->tmp3; + + const int stride = 8; + for (i = 0; i < P->di - ( stride - 1 ); i += stride ) { + // SSE Pipeline #1 SSE Pipeline #2 + // + sum1 = _mm_load_ps( &ptr1[i + 0] ); + sum2 = _mm_load_ps( &ptr1[i + 4] ); + s_getU(tmp1, &ptr2[i + 0] ); + s_getU(tmp2, &ptr2[i + 4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + s_getU(tmp1, &ptr3[i + 0] ); + s_getU(tmp2, &ptr3[i + 4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + s_getU(tmp1, &ptr4[i + 0] ); + s_getU(tmp2, &ptr4[i + 4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + s_getU(tmp1, &ptr5[i + 0] ); + s_getU(tmp2, &ptr5[i + 4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + max1 = _mm_max_ps( max1, sum1 ); + max2 = _mm_max_ps( max2, sum2 ); + _mm_store_ps( &P->dest[i + 0], sum1 ); + _mm_store_ps( &P->dest[i + 4], sum2 ); + } + max1 = _mm_max_ps( max1, max2 ); + for ( ; i < P->di ; i += 4) { + int mask1 = sse_msks1[ P->di-i]; + sum1 = _mm_load_ps( &ptr1[i + 0] ); + s_getU(tmp1, &ptr2[i + 0] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + s_getU(tmp1, &ptr3[i + 0] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + s_getU(tmp1, &ptr4[i + 0] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + s_getU(tmp1, &ptr5[i + 0] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + _mm_store_ps( &P->dest[i + 0], sum1 ); + sum1 = _mm_sub_ps(sum1, SSE_LIM( mask1 ) ); + max1 = _mm_max_ps( max1, sum1 ); + } + return ( s_maxp2f( max1 ) ); +} + +float sse_pulPoTf5L8(float *ss[], struct PoTPlan *P) { + __m128 sum1, sum2, max1, max2; + __m128 tmp1, tmp2; + int i; + + max1 = max2 = _mm_set_ps1( 0.0 ); + float *ptr1 = ss[0]; + float *ptr2 = ss[0] + P->tmp0; + float *ptr3 = ss[0] + P->tmp1; + float *ptr4 = ss[0] + P->tmp2; + float *ptr5 = ss[0] + P->tmp3; + + // SSE Pipeline #1 SSE Pipeline #2 + // + int mask1 = sse_msks1[ P->di ]; + int mask2 = sse_msks2[ P->di ]; + sum1 = _mm_load_ps( &ptr1[0] ); + sum2 = _mm_load_ps( &ptr1[4] ); + s_getU(tmp1, &ptr2[0] ); + s_getU(tmp2, &ptr2[4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + s_getU(tmp1, &ptr3[0] ); + s_getU(tmp2, &ptr3[4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + s_getU(tmp1, &ptr4[0] ); + s_getU(tmp2, &ptr4[4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + s_getU(tmp1, &ptr5[0] ); + s_getU(tmp2, &ptr5[4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + _mm_store_ps( &P->dest[0], sum1 ); + _mm_store_ps( &P->dest[4], sum2 ); + sum1 = _mm_sub_ps(sum1, SSE_LIM( mask1 ) ); + sum2 = _mm_sub_ps(sum2, SSE_LIM( mask2 ) ); + max1 = _mm_max_ps( max1, sum1 ); + max2 = _mm_max_ps( max2, sum2 ); + + return ( s_maxp2f( _mm_max_ps( max1, max2 ) ) ); +} + +float sse_pulPoTf5L4(float *ss[], struct PoTPlan *P) { + __m128 sum1, sum2, max1, max2; + __m128 tmp1, tmp2; + int i; + + max1 = max2 = _mm_set_ps1( 0.0 ); + float *ptr1 = ss[0]; + float *ptr2 = ss[0] + P->tmp0; + float *ptr3 = ss[0] + P->tmp1; + float *ptr4 = ss[0] + P->tmp2; + float *ptr5 = ss[0] + P->tmp3; + + int mask1 = sse_msks1[ P->di ]; + sum1 = _mm_load_ps( &ptr1[0] ); + s_getU(tmp1, &ptr2[0] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + s_getU(tmp1, &ptr3[0] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + s_getU(tmp1, &ptr4[0] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + s_getU(tmp1, &ptr5[0] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + _mm_store_ps( &P->dest[0], sum1 ); + sum1 = _mm_sub_ps(sum1, SSE_LIM( mask1 ) ); + max1 = _mm_max_ps( max1, sum1 ); + + return ( s_maxp2f( max1 ) ); +} + +sum_func BHSSETB5[FOLDTBLEN] = { + sse_pulPoTf5L4, sse_pulPoTf5L4, sse_pulPoTf5L4, sse_pulPoTf5L4, + sse_pulPoTf5L4, sse_pulPoTf5L8, sse_pulPoTf5L8, sse_pulPoTf5L8, + sse_pulPoTf5L8, sse_pulPoTf5, sse_pulPoTf5, sse_pulPoTf5, + sse_pulPoTf5, sse_pulPoTf5, sse_pulPoTf5, sse_pulPoTf5, + sse_pulPoTf5, sse_pulPoTf5, sse_pulPoTf5, sse_pulPoTf5, + sse_pulPoTf5, sse_pulPoTf5, sse_pulPoTf5, sse_pulPoTf5, + sse_pulPoTf5u + }; + +// +// Fold by 2 versions +// +float sse_pulPoTf2u(float *ss[], struct PoTPlan *P) { + __m128 sum1, sum2, tmp1, tmp2, max1, max2; + int i; + + max1 = max2 = _mm_set_ps1( 0.0 ); + float *ptr1 = ss[1]+P->offset; + float *ptr2 = ss[1]+P->tmp0; + + const int stride = 24; + + for (i = 0; i < P->di - ( stride - 1 ); i += stride ) { + // SSE Pipeline #1 SSE Pipeline #2 + // + sum1 = _mm_load_ps( &ptr1[i + 0] ); + sum2 = _mm_load_ps( &ptr1[i + 4] ); + s_getU(tmp1, &ptr2[i + 0] ); + s_getU(tmp2, &ptr2[i + 4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + max1 = _mm_max_ps( max1, sum1 ); + max2 = _mm_max_ps( max2, sum2 ); + _mm_store_ps( &P->dest[i + 0], sum1 ); + _mm_store_ps( &P->dest[i +4], sum2 ); + + sum1 = _mm_load_ps( &ptr1[i + 8] ); + sum2 = _mm_load_ps( &ptr1[i + 12] ); + s_getU(tmp1, &ptr2[i + 8] ); + s_getU(tmp2, &ptr2[i + 12] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + max1 = _mm_max_ps( max1, sum1 ); + max2 = _mm_max_ps( max2, sum2 ); + _mm_store_ps( &P->dest[i + 8], sum1 ); + _mm_store_ps( &P->dest[i +12], sum2 ); + + sum1 = _mm_load_ps( &ptr1[i + 16] ); + sum2 = _mm_load_ps( &ptr1[i + 20] ); + s_getU(tmp1, &ptr2[i + 16] ); + s_getU(tmp2, &ptr2[i + 20] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + max1 = _mm_max_ps( max1, sum1 ); + max2 = _mm_max_ps( max2, sum2 ); + _mm_store_ps( &P->dest[i + 16], sum1 ); + _mm_store_ps( &P->dest[i +20], sum2 ); + } + max1 = _mm_max_ps( max1, max2 ); + for ( ; i < P->di ; i += 4) { + int mask1 = sse_msks1[ P->di-i]; + sum1 = _mm_load_ps( &ptr1[i + 0] ); + s_getU(tmp1, &ptr2[i + 0] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + _mm_store_ps( &P->dest[i + 0], sum1 ); + sum1 = _mm_sub_ps(sum1, SSE_LIM( mask1 ) ); + max1 = _mm_max_ps( max1, sum1 ); + } + return ( s_maxp2f( max1 ) ); +} + +float sse_pulPoTf2(float *ss[], struct PoTPlan *P) { + __m128 sum1, sum2, tmp1, tmp2, max1, max2; + int i; + + max1 = max2 = _mm_set_ps1( 0.0 ); + float *ptr1 = ss[1]+P->offset; + float *ptr2 = ss[1]+P->tmp0; + + const int stride = 8; + + for (i = 0; i < P->di - ( stride - 1 ); i += stride ) { + // SSE Pipeline #1 SSE Pipeline #2 + // + sum1 = _mm_load_ps( &ptr1[i + 0] ); + sum2 = _mm_load_ps( &ptr1[i + 4] ); + s_getU(tmp1, &ptr2[i + 0] ); + s_getU(tmp2, &ptr2[i + 4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + max1 = _mm_max_ps( max1, sum1 ); + max2 = _mm_max_ps( max2, sum2 ); + _mm_store_ps( &P->dest[i + 0], sum1 ); + _mm_store_ps( &P->dest[i +4], sum2 ); + } + max1 = _mm_max_ps( max1, max2 ); + for ( ; i < P->di ; i += 4) { + int mask1 = sse_msks1[ P->di-i]; + sum1 = _mm_load_ps( &ptr1[i + 0] ); + s_getU(tmp1, &ptr2[i + 0] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + _mm_store_ps( &P->dest[i + 0], sum1 ); + sum1 = _mm_sub_ps(sum1, SSE_LIM( mask1 ) ); + max1 = _mm_max_ps( max1, sum1 ); + } + return ( s_maxp2f( max1 ) ); +} + +float sse_pulPoTf2L8(float *ss[], struct PoTPlan *P) { + __m128 sum1, sum2, tmp1, tmp2, max1, max2; + int i; + + max1 = max2 = _mm_set_ps1( 0.0 ); + float *ptr1 = ss[1]+P->offset; + float *ptr2 = ss[1]+P->tmp0; + + // SSE Pipeline #1 SSE Pipeline #2 + // + int mask1 = sse_msks1[ P->di ]; + int mask2 = sse_msks2[ P->di ]; + sum1 = _mm_load_ps( &ptr1[0] ); + sum2 = _mm_load_ps( &ptr1[4] ); + s_getU(tmp1, &ptr2[0] ); + s_getU(tmp2, &ptr2[4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + _mm_store_ps( &P->dest[0], sum1 ); + _mm_store_ps( &P->dest[4], sum2 ); + sum1 = _mm_sub_ps(sum1, SSE_LIM( mask1 ) ); + sum2 = _mm_sub_ps(sum2, SSE_LIM( mask2 ) ); + max1 = _mm_max_ps( max1, sum1 ); + max2 = _mm_max_ps( max2, sum2 ); + + return ( s_maxp2f( _mm_max_ps( max1, max2 ) ) ); +} + +float sse_pulPoTf2L4(float *ss[], struct PoTPlan *P) { + __m128 sum1, tmp1, max1; + int i; + + max1 = _mm_set_ps1( 0.0 ); + float *ptr1 = ss[1]+P->offset; + float *ptr2 = ss[1]+P->tmp0; + + // + int mask1 = sse_msks1[ P->di ]; + sum1 = _mm_load_ps( &ptr1[0] ); + s_getU(tmp1, &ptr2[0] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + _mm_store_ps( &P->dest[0], sum1 ); + sum1 = _mm_sub_ps(sum1, SSE_LIM( mask1 ) ); + max1 = _mm_max_ps( max1, sum1 ); + + return ( s_maxp2f( max1 ) ); +} + +sum_func BHSSETB2[FOLDTBLEN] = { + sse_pulPoTf2L4, sse_pulPoTf2L4, sse_pulPoTf2L4, sse_pulPoTf2L4, + sse_pulPoTf2L4, sse_pulPoTf2L8, sse_pulPoTf2L8, sse_pulPoTf2L8, + sse_pulPoTf2L8, sse_pulPoTf2, sse_pulPoTf2, sse_pulPoTf2, + sse_pulPoTf2, sse_pulPoTf2, sse_pulPoTf2, sse_pulPoTf2, + sse_pulPoTf2, sse_pulPoTf2, sse_pulPoTf2, sse_pulPoTf2, + sse_pulPoTf2, sse_pulPoTf2, sse_pulPoTf2, sse_pulPoTf2, + sse_pulPoTf2u, sse_pulPoTf2u, sse_pulPoTf2u, sse_pulPoTf2u, + sse_pulPoTf2u, sse_pulPoTf2u, sse_pulPoTf2u, sse_pulPoTf2u + }; + + +// versions for tmp0 aligned +// +float sse_pulPoTf2ALu(float *ss[], struct PoTPlan *P) { + __m128 sum1, sum2, tmp1, tmp2, max1, max2; + int i; + + max1 = max2 = _mm_set_ps1( 0.0 ); + float *ptr1 = ss[1]+P->offset; + float *ptr2 = ss[1]+P->tmp0; + + const int stride = 24; + + for (i = 0; i < P->di - ( stride - 1 ); i += stride ) { + // SSE Pipeline #1 SSE Pipeline #2 + // + sum1 = _mm_load_ps( &ptr1[i + 0] ); + sum2 = _mm_load_ps( &ptr1[i + 4] ); + tmp1 = _mm_load_ps( &ptr2[i + 0] ); + tmp2 = _mm_load_ps( &ptr2[i + 4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + max1 = _mm_max_ps( max1, sum1 ); + max2 = _mm_max_ps( max2, sum2 ); + _mm_store_ps( &P->dest[i + 0], sum1 ); + _mm_store_ps( &P->dest[i +4], sum2 ); + + sum1 = _mm_load_ps( &ptr1[i + 8] ); + sum2 = _mm_load_ps( &ptr1[i + 12] ); + tmp1 = _mm_load_ps( &ptr2[i + 8] ); + tmp2 = _mm_load_ps( &ptr2[i + 12] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + max1 = _mm_max_ps( max1, sum1 ); + max2 = _mm_max_ps( max2, sum2 ); + _mm_store_ps( &P->dest[i + 8], sum1 ); + _mm_store_ps( &P->dest[i +12], sum2 ); + + sum1 = _mm_load_ps( &ptr1[i + 16] ); + sum2 = _mm_load_ps( &ptr1[i + 20] ); + tmp1 = _mm_load_ps( &ptr2[i + 16] ); + tmp2 = _mm_load_ps( &ptr2[i + 20] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + max1 = _mm_max_ps( max1, sum1 ); + max2 = _mm_max_ps( max2, sum2 ); + _mm_store_ps( &P->dest[i + 16], sum1 ); + _mm_store_ps( &P->dest[i +20], sum2 ); + } + max1 = _mm_max_ps( max1, max2 ); + for ( ; i < P->di ; i += 4) { + int mask1 = sse_msks1[ P->di-i]; + sum1 = _mm_load_ps( &ptr1[i + 0] ); + tmp1 = _mm_load_ps( &ptr2[i + 0] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + _mm_store_ps( &P->dest[i + 0], sum1 ); + sum1 = _mm_sub_ps(sum1, SSE_LIM( mask1 ) ); + max1 = _mm_max_ps( max1, sum1 ); + } + return ( s_maxp2f( max1 ) ); +} + +float sse_pulPoTf2AL(float *ss[], struct PoTPlan *P) { + __m128 sum1, sum2, tmp1, tmp2, max1, max2; + int i; + + max1 = max2 = _mm_set_ps1( 0.0 ); + float *ptr1 = ss[1]+P->offset; + float *ptr2 = ss[1]+P->tmp0; + + const int stride = 8; + + for (i = 0; i < P->di - ( stride - 1 ); i += stride ) { + // SSE Pipeline #1 SSE Pipeline #2 + // + sum1 = _mm_load_ps( &ptr1[i + 0] ); + sum2 = _mm_load_ps( &ptr1[i + 4] ); + tmp1 = _mm_load_ps( &ptr2[i + 0] ); + tmp2 = _mm_load_ps( &ptr2[i + 4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + max1 = _mm_max_ps( max1, sum1 ); + max2 = _mm_max_ps( max2, sum2 ); + _mm_store_ps( &P->dest[i + 0], sum1 ); + _mm_store_ps( &P->dest[i +4], sum2 ); + } + max1 = _mm_max_ps( max1, max2 ); + for ( ; i < P->di ; i += 4) { + int mask1 = sse_msks1[ P->di-i]; + sum1 = _mm_load_ps( &ptr1[i + 0] ); + tmp1 = _mm_load_ps( &ptr2[i + 0] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + _mm_store_ps( &P->dest[i + 0], sum1 ); + sum1 = _mm_sub_ps(sum1, SSE_LIM( mask1 ) ); + max1 = _mm_max_ps( max1, sum1 ); + } + return ( s_maxp2f( max1 ) ); +} + + +float sse_pulPoTf2AL8(float *ss[], struct PoTPlan *P) { + __m128 sum1, sum2, tmp1, tmp2, max1, max2; + int i; + + max1 = max2 = _mm_set_ps1( 0.0 ); + float *ptr1 = ss[1]+P->offset; + float *ptr2 = ss[1]+P->tmp0; + + // SSE Pipeline #1 SSE Pipeline #2 + // + int mask1 = sse_msks1[ P->di ]; + int mask2 = sse_msks2[ P->di ]; + sum1 = _mm_load_ps( &ptr1[0] ); + sum2 = _mm_load_ps( &ptr1[4] ); + tmp1 = _mm_load_ps( &ptr2[0] ); + tmp2 = _mm_load_ps( &ptr2[4] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + sum2 = _mm_add_ps( sum2, tmp2 ); + _mm_store_ps( &P->dest[0], sum1 ); + _mm_store_ps( &P->dest[4], sum2 ); + sum1 = _mm_sub_ps(sum1, SSE_LIM( mask1 ) ); + sum2 = _mm_sub_ps(sum2, SSE_LIM( mask2 ) ); + max1 = _mm_max_ps( max1, sum1 ); + max2 = _mm_max_ps( max2, sum2 ); + + return ( s_maxp2f( _mm_max_ps( max1, max2 ) ) ); +} + +float sse_pulPoTf2AL4(float *ss[], struct PoTPlan *P) { + __m128 sum1, tmp1, max1; + int i; + + max1 = _mm_set_ps1( 0.0 ); + float *ptr1 = ss[1]+P->offset; + float *ptr2 = ss[1]+P->tmp0; + + // + int mask1 = sse_msks1[ P->di]; + sum1 = _mm_load_ps( &ptr1[0] ); + tmp1 = _mm_load_ps( &ptr2[0] ); + sum1 = _mm_add_ps( sum1, tmp1 ); + _mm_store_ps( &P->dest[0], sum1 ); + sum1 = _mm_sub_ps(sum1, SSE_LIM( mask1 ) ); + max1 = _mm_max_ps( max1, sum1 ); + + return ( s_maxp2f( max1 ) ); +} + +sum_func BHSSETB2AL[FOLDTBLEN] = { + sse_pulPoTf2AL4, sse_pulPoTf2AL4, sse_pulPoTf2AL4, sse_pulPoTf2AL4, + sse_pulPoTf2AL4, sse_pulPoTf2AL8, sse_pulPoTf2AL8, sse_pulPoTf2AL8, + sse_pulPoTf2AL8, sse_pulPoTf2AL, sse_pulPoTf2AL, sse_pulPoTf2AL, + sse_pulPoTf2AL, sse_pulPoTf2AL, sse_pulPoTf2AL, sse_pulPoTf2AL, + sse_pulPoTf2AL, sse_pulPoTf2AL, sse_pulPoTf2AL, sse_pulPoTf2AL, + sse_pulPoTf2AL, sse_pulPoTf2AL, sse_pulPoTf2AL, sse_pulPoTf2AL, + sse_pulPoTf2ALu + }; + + +FoldSet BHSSEfold = {BHSSETB3, BHSSETB4, BHSSETB5, BHSSETB2, BHSSETB2AL, "BH SSE"}; + +/************************************* + * + * SSE folding subroutines from SSE2 by Alex Kan + * + * Modified by Joe Segur + * + */ + +typedef union submask { + float f[4]; + __m128 v; +}; + +submask tailmask[4] = { + { 0.0f, 0.0f, 0.0f, 0.0f}, + { 0.0f, 1e37f, 1e37f, 1e37f}, + { 0.0f, 0.0f, 1e37f, 1e37f}, + { 0.0f, 0.0f, 0.0f, 1e37f} + }; + + +float foldArrayBy3(float *ss[], struct PoTPlan *P) { + float max; + __m128 maxV = ZERO; + int i = 0; + + const float *p1 = ss[0], *p2 = ss[0]+P->tmp0, *p3 = ss[0]+P->tmp1; + float *pst = P->dest; + __m128 x1, x2, x3, xs12, xs; + + while (i < P->di-4) { + x1 = _mm_load_ps(p1+i); + x2 = _mm_loadu_ps(p2+i); + x3 = _mm_loadu_ps(p3+i); + xs12 = _mm_add_ps(x1, x2); + xs = _mm_add_ps(xs12, x3); + _mm_store_ps(pst+i, xs); + maxV = _mm_max_ps(maxV, xs); + i += 4; + } + x1 = _mm_load_ps(p1+i); + x2 = _mm_loadu_ps(p2+i); + x3 = _mm_loadu_ps(p3+i); + xs12 = _mm_add_ps(x1, x2); + xs = _mm_add_ps(xs12, x3); + + _mm_store_ps(pst+i, xs); + xs = _mm_sub_ps(xs, tailmask[P->di & 0x3].v); + maxV = _mm_max_ps(maxV, xs); + + maxV = _mm_max_ps(maxV, _mm_shuffle_ps(maxV, maxV, 0x4e)); + maxV = _mm_max_ps(maxV, _mm_shuffle_ps(maxV, maxV, 0x39)); + _mm_store_ss(&max, maxV); + + return max; +} + + +float foldArrayBy3LO(float *ss[], struct PoTPlan *P) { + + const float *p1 = ss[0], *p2 = ss[0]+P->tmp0, *p3 = ss[0]+P->tmp1; + float *pst = P->dest; + float max = 0.0f; + int i = 0; + + while (i < P->di) { + pst[i] = p1[i] + p2[i] + p3[i]; + if (pst[i] > max) max = pst[i]; + i += 1; + } + return max; +} +sum_func AKSSETB3[FOLDTBLEN] = { + foldArrayBy3LO, foldArrayBy3LO, foldArrayBy3LO, foldArrayBy3LO, + foldArrayBy3LO, foldArrayBy3LO, foldArrayBy3LO, foldArrayBy3LO, + foldArrayBy3, foldArrayBy3LO, foldArrayBy3LO, foldArrayBy3LO, + foldArrayBy3 + }; + +float foldArrayBy4(float *ss[], struct PoTPlan *P) { + float max; + __m128 maxV = ZERO; + int i = 0; + + const float *p1 = ss[0], *p2 = ss[0]+P->tmp0, *p3 = ss[0]+P->tmp1, *p4 = ss[0]+P->tmp2; + float *pst = P->dest; + __m128 x1, x2, x3, x4, xs12, xs34, xs; + + while (i < P->di-4) { + x1 = _mm_load_ps(p1+i); + x2 = _mm_loadu_ps(p2+i); + x3 = _mm_loadu_ps(p3+i); + x4 = _mm_loadu_ps(p4+i); + xs12 = _mm_add_ps(x1, x2); + xs34 = _mm_add_ps(x3, x4); + xs = _mm_add_ps(xs12, xs34); + _mm_store_ps(pst+i, xs); + maxV = _mm_max_ps(maxV, xs); + i += 4; + } + x1 = _mm_load_ps(p1+i); + x2 = _mm_loadu_ps(p2+i); + x3 = _mm_loadu_ps(p3+i); + x4 = _mm_loadu_ps(p4+i); + xs12 = _mm_add_ps(x1, x2); + xs34 = _mm_add_ps(x3, x4); + xs = _mm_add_ps(xs12, xs34); + + _mm_store_ps(pst+i, xs); + xs = _mm_sub_ps(xs, tailmask[P->di & 0x3].v); + maxV = _mm_max_ps(maxV, xs); + + maxV = _mm_max_ps(maxV, _mm_shuffle_ps(maxV, maxV, 0x4e)); + maxV = _mm_max_ps(maxV, _mm_shuffle_ps(maxV, maxV, 0x39)); + _mm_store_ss(&max, maxV); + + return max; +} + +float foldArrayBy4LO(float *ss[], struct PoTPlan *P) { + + const float *p1 = ss[0], *p2 = ss[0]+P->tmp0, *p3 = ss[0]+P->tmp1, *p4 = ss[0]+P->tmp2; + float *pst = P->dest; + float max = 0.0f; + int i = 0; + + while (i < P->di) { + pst[i] = p1[i] + p2[i] + p3[i] + p4[i]; + if (pst[i] > max) max = pst[i]; + i += 1; + } + return max; +} +sum_func AKSSETB4[FOLDTBLEN] = { + foldArrayBy4LO, foldArrayBy4LO, foldArrayBy4LO, foldArrayBy4LO, + foldArrayBy4LO, foldArrayBy4LO, foldArrayBy4LO, foldArrayBy4LO, + foldArrayBy4, foldArrayBy4LO, foldArrayBy4LO, foldArrayBy4LO, + foldArrayBy4 + }; + +float foldArrayBy5(float *ss[], struct PoTPlan *P) { + float max; + __m128 maxV = ZERO; + int i = 0; + + const float *p1 = ss[0], *p2 = ss[0]+P->tmp0, *p3 = ss[0]+P->tmp1, *p4 = ss[0]+P->tmp2, *p5 = ss[0]+P->tmp3; + float *pst = P->dest; + __m128 x1, x2, x3, x4, x5, xs12, xs34, xs125, xs; + + while (i < P->di-4) { + x1 = _mm_load_ps(p1+i); + x2 = _mm_loadu_ps(p2+i); + x3 = _mm_loadu_ps(p3+i); + x4 = _mm_loadu_ps(p4+i); + x5 = _mm_loadu_ps(p5+i); + xs12 = _mm_add_ps(x1, x2); + xs34 = _mm_add_ps(x3, x4); + xs125 = _mm_add_ps(xs12, x5); + xs = _mm_add_ps(xs34, xs125); + _mm_store_ps(pst+i, xs); + maxV = _mm_max_ps(maxV, xs); + i += 4; + } + x1 = _mm_load_ps(p1+i); + x2 = _mm_loadu_ps(p2+i); + x3 = _mm_loadu_ps(p3+i); + x4 = _mm_loadu_ps(p4+i); + x5 = _mm_loadu_ps(p5+i); + xs12 = _mm_add_ps(x1, x2); + xs34 = _mm_add_ps(x3, x4); + xs125 = _mm_add_ps(xs12, x5); + xs = _mm_add_ps(xs34, xs125); + + _mm_store_ps(pst+i, xs); + xs = _mm_sub_ps(xs, tailmask[P->di & 0x3].v); + maxV = _mm_max_ps(maxV, xs); + + maxV = _mm_max_ps(maxV, _mm_shuffle_ps(maxV, maxV, 0x4e)); + maxV = _mm_max_ps(maxV, _mm_shuffle_ps(maxV, maxV, 0x39)); + _mm_store_ss(&max, maxV); + + return max; +} + +float foldArrayBy5LO(float *ss[], struct PoTPlan *P) { + + const float *p1 = ss[0], *p2 = ss[0]+P->tmp0, *p3 = ss[0]+P->tmp1, *p4 = ss[0]+P->tmp2, *p5 = ss[0]+P->tmp3; + float *pst = P->dest; + float max = 0.0f; + int i = 0; + + while (i < P->di) { + pst[i] = p1[i] + p2[i] + p3[i] + p4[i] + p5[i]; + if (pst[i] > max) max = pst[i]; + i += 1; + } + return max; +} + +sum_func AKSSETB5[FOLDTBLEN] = { + foldArrayBy5LO, foldArrayBy5LO, foldArrayBy5LO, foldArrayBy5LO, + foldArrayBy5LO, foldArrayBy5LO, foldArrayBy5LO, foldArrayBy5LO, + foldArrayBy5, foldArrayBy5LO, foldArrayBy5LO, foldArrayBy5LO, + foldArrayBy5 + }; + +// 2A version allows non-aligned tmp0 + +float foldArrayBy2A(float *ss[], struct PoTPlan *P) { + float max; + __m128 maxV = ZERO; + int i = 0; + + const float *p1 = ss[1]+P->offset, *p2 = ss[1]+P->tmp0; + float *pst = P->dest; + __m128 x1, x2, xs; + + while (i < P->di-4) { + x1 = _mm_load_ps(p1+i); + x2 = _mm_loadu_ps(p2+i); + xs = _mm_add_ps(x1, x2); + _mm_store_ps(pst+i, xs); + maxV = _mm_max_ps(maxV, xs); + i += 4; + } + x1 = _mm_load_ps(p1+i); + x2 = _mm_loadu_ps(p2+i); + xs = _mm_add_ps(x1, x2); + + _mm_store_ps(pst+i, xs); + xs = _mm_sub_ps(xs, tailmask[P->di & 0x3].v); + maxV = _mm_max_ps(maxV, xs); + + maxV = _mm_max_ps(maxV, _mm_shuffle_ps(maxV, maxV, 0x4e)); + maxV = _mm_max_ps(maxV, _mm_shuffle_ps(maxV, maxV, 0x39)); + _mm_store_ss(&max, maxV); + + return max; +} + +// 2AL version requires aligned tmp0 + + +float foldArrayBy2AL(float *ss[], struct PoTPlan *P) { + float max; + __m128 maxV = ZERO; + int i = 0; + + const float *p1 = ss[1]+P->offset, *p2 = ss[1]+P->tmp0; + float *pst = P->dest; + __m128 x1, x2, xs; + + while (i < P->di-4) { + x1 = _mm_load_ps(p1+i); + x2 = _mm_load_ps(p2+i); + xs = _mm_add_ps(x1, x2); + _mm_store_ps(pst+i, xs); + maxV = _mm_max_ps(maxV, xs); + i += 4; + } + x1 = _mm_load_ps(p1+i); + x2 = _mm_load_ps(p2+i); + xs = _mm_add_ps(x1, x2); + + _mm_store_ps(pst+i, xs); + xs = _mm_sub_ps(xs, tailmask[P->di & 0x3].v); + maxV = _mm_max_ps(maxV, xs); + + maxV = _mm_max_ps(maxV, _mm_shuffle_ps(maxV, maxV, 0x4e)); + maxV = _mm_max_ps(maxV, _mm_shuffle_ps(maxV, maxV, 0x39)); + _mm_store_ss(&max, maxV); + + return max; +} + +float foldArrayBy2LO(float *ss[], struct PoTPlan *P) { + + const float *p1 = ss[1]+P->offset, *p2 = ss[1]+P->tmp0; + float *pst = P->dest; + float max = 0.0f; + int i = 0; + + while (i < P->di) { + pst[i] = p1[i] + p2[i]; + if (pst[i] > max) max = pst[i]; + i += 1; + } + return max; +} +sum_func AKSSETB2[FOLDTBLEN] = { + foldArrayBy2LO, foldArrayBy2LO, foldArrayBy2LO, foldArrayBy2LO, + foldArrayBy2LO, foldArrayBy2LO, foldArrayBy2LO, foldArrayBy2LO, + foldArrayBy2A, foldArrayBy2LO, foldArrayBy2LO, foldArrayBy2LO, + foldArrayBy2A + }; + +sum_func AKSSETB2AL[FOLDTBLEN] = { + foldArrayBy2LO, foldArrayBy2LO, foldArrayBy2LO, foldArrayBy2LO, + foldArrayBy2LO, foldArrayBy2LO, foldArrayBy2LO, foldArrayBy2LO, + foldArrayBy2AL, foldArrayBy2LO, foldArrayBy2LO, foldArrayBy2LO, + foldArrayBy2AL + }; + +FoldSet AKSSEfold = {AKSSETB3, AKSSETB4, AKSSETB5, AKSSETB2, AKSSETB2AL, "AK SSE"}; + + +#endif // USE_INTRINSICS + +#endif // (__i386__) || (__x86_64__) + + diff --git a/client/vector/analyzeFuncs_sse2.cpp b/client/vector/analyzeFuncs_sse2.cpp new file mode 100644 index 0000000..833aa5f --- /dev/null +++ b/client/vector/analyzeFuncs_sse2.cpp @@ -0,0 +1,329 @@ +/****************** + * + * analyzeFuncs_SSE2.cpp + * + * Description: Intel & AMD SSE2 optimzized functions + * CPUs: Intel Pentium IV, AMD Athlon Model 6+, AMD Athlon 64 + */ + +// Copyright 2007 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#include "sah_config.h" + +// The following is empty if USE_INTRINSICS is not defined +#ifdef USE_INTRINSICS +#include +#include +#include + +#include "s_util.h" +#include "x86_float4.h" +#include "analyzeFuncs_vector.h" +#include "analyzeFuncs.h" + + +__inline __m128 vec_recip2(__m128 v) + { + // obtain estimate + __m128 estimate = _mm_rcp_ps( v ); + // one round of Newton-Raphson + return _mm_add_ps(_mm_mul_ps(_mm_sub_ps(ONE, _mm_mul_ps(estimate, v)), estimate), estimate); + } + + +// ============================================================================= +// +// sse2_vChirpData +// version by: Alex Kan - SSE2 mods (haddsum removal) BH +// http://tbp.berkeley.edu/~alexkan/seti/ +// +int sse2_ChirpData_ak( + sah_complex * cx_DataArray, + sah_complex * cx_ChirpDataArray, + int chirp_rate_ind, + double chirp_rate, + int ul_NumDataPoints, + double sample_rate +) { + int i; + + if (chirp_rate_ind == 0) { + memcpy(cx_ChirpDataArray, cx_DataArray, (int)ul_NumDataPoints * sizeof(sah_complex) ); + return 0; + } + + int vEnd; + double srate = chirp_rate * 0.5 / (sample_rate * sample_rate); + __m128d rate = _mm_set1_pd(chirp_rate * 0.5 / (sample_rate * sample_rate)); + __m128d roundVal = _mm_set1_pd(srate >= 0.0 ? TWO_TO_52 : -TWO_TO_52); + + // main vectorised loop + vEnd = ul_NumDataPoints - (ul_NumDataPoints & 3); + for (i = 0; i < vEnd; i += 4) { + const float *data = (const float *) (cx_DataArray + i); + float *chirped = (float *) (cx_ChirpDataArray + i); + __m128d di = _mm_set1_pd(i); + __m128d a1 = _mm_add_pd(_mm_set_pd(1.0, 0.0), di); + __m128d a2 = _mm_add_pd(_mm_set_pd(3.0, 2.0), di); + __m128d x1, y1; + + __m128 d1, d2; + __m128 cd1, cd2; + __m128 td1, td2; + __m128 x; + __m128 y; + __m128 s; + __m128 c; + __m128 m; + + // load the signal to be chirped + prefetchnta((const void *)( data+32 )); + d1 = _mm_load_ps(data); + d2 = _mm_load_ps(data+4); + + // calculate the input angle + a1 = _mm_mul_pd(a1, a1); + a2 = _mm_mul_pd(a2, a2); + a1 = _mm_mul_pd(a1, rate); + a2 = _mm_mul_pd(a2, rate); + + // reduce the angle to the range (-0.5, 0.5) + x1 = _mm_add_pd(a1, roundVal); + y1 = _mm_add_pd(a2, roundVal); + x1 = _mm_sub_pd(x1, roundVal); + y1 = _mm_sub_pd(y1, roundVal); + a1 = _mm_sub_pd(a1, x1); + a2 = _mm_sub_pd(a2, y1); + + // convert pair of packed double into packed single + x = _mm_movelh_ps(_mm_cvtpd_ps(a1), _mm_cvtpd_ps(a2)); + + // square to the range [0, 0.25) + y = _mm_mul_ps(x, x); + + // perform the initial polynomial approximations + s = _mm_mul_ps(y, SS4); + c = _mm_mul_ps(y, CC3); + s = _mm_add_ps(s, SS3); + c = _mm_add_ps(c, CC2); + s = _mm_mul_ps(s, y); + c = _mm_mul_ps(c, y); + s = _mm_add_ps(s, SS2); + c = _mm_add_ps(c, CC1); + s = _mm_mul_ps(s, y); + c = _mm_mul_ps(c, y); + s = _mm_add_ps(s, SS1); + s = _mm_mul_ps(s, x); + c = _mm_add_ps(c, ONE); + + // perform first angle doubling + x = _mm_sub_ps(_mm_mul_ps(c, c), _mm_mul_ps(s, s)); + y = _mm_mul_ps(_mm_mul_ps(s, c), TWO); + + // calculate scaling factor to correct the magnitude + // m1 = vec_nmsub(y1, y1, vec_nmsub(x1, x1, TWO)); + // m2 = vec_nmsub(y2, y2, vec_nmsub(x2, x2, TWO)); + m = vec_recip2(_mm_add_ps(_mm_mul_ps(x, x), _mm_mul_ps(y, y))); + + // perform second angle doubling + c = _mm_sub_ps(_mm_mul_ps(x, x), _mm_mul_ps(y, y)); + s = _mm_mul_ps(_mm_mul_ps(y, x), TWO); + + // correct the magnitude (final sine / cosine approximations) + c = _mm_mul_ps(c, m); + s = _mm_mul_ps(s, m); + +/* c1 c2 c3 c4 + s1 s2 s3 s4 + + R1 i1 R2 I2 R3 i3 R4 i4 + + R1 * c1 + (i1 * s1 * -1) + i1 * c1 + R1 * s1 + R2 * c2 + (i2 * s2 * -1) + i2 * c2 + R2 * s2 +*/ + + x = d1; + y = d2; + x = _mm_shuffle_ps(x, x, 0xB1); + y = _mm_shuffle_ps(y, y, 0xB1); + x = _mm_mul_ps(x, R_NEG); + y = _mm_mul_ps(y, R_NEG); + cd1 = _mm_shuffle_ps(c, c, 0x50); // 01 01 00 00 AaBb => BBbb => c3c3c4c4 + cd2 = _mm_shuffle_ps(c, c, 0xfa); // 11 11 10 10 AaBb => AAaa => c1c1c2c2 + td1 = _mm_shuffle_ps(s, s, 0x50); + td2 = _mm_shuffle_ps(s, s, 0xfa); + + cd1 = _mm_mul_ps(cd1, d1); + cd2 = _mm_mul_ps(cd2, d2); + td1 = _mm_mul_ps(td1, x); + td2 = _mm_mul_ps(td2, y); + + cd1 = _mm_add_ps(cd1, td1); + cd2 = _mm_add_ps(cd2, td2); + + // store chirped values + _mm_stream_ps(chirped+0, cd1); + _mm_stream_ps(chirped+4, cd2); + } + _mm_sfence(); + + if( i < ul_NumDataPoints) { + // use original routine to finish up any tailings (max stride-1 elements) + v_ChirpData(cx_DataArray+i, cx_ChirpDataArray+i + , chirp_rate_ind, chirp_rate, ul_NumDataPoints-i, sample_rate); + } + analysis_state.FLOP_counter+=12.0*ul_NumDataPoints; + + return 0; +} + +// ============================================================================= +// +// JWS: alternate SSE2 chirp +// +// Using Mendenhall Faster SinCos, coding based on +// version 8 v_vChirpData for SSE3 by Alex Kan +// +int sse2_ChirpData_ak8( + sah_complex * cx_DataArray, + sah_complex * cx_ChirpDataArray, + int chirp_rate_ind, + const double chirp_rate, + int ul_NumDataPoints, + const double sample_rate +) { + int i, vEnd; + + if (chirp_rate_ind == 0) { + memcpy(cx_ChirpDataArray, cx_DataArray, (int)ul_NumDataPoints * sizeof(sah_complex) ); + return 0; + } + + const double srate = chirp_rate * 0.5 / (sample_rate * sample_rate); + + __m128d dfourv = _mm_set1_pd(4.0); + + __m128d rate = _mm_set1_pd(srate); + __m128d roundVal = _mm_set1_pd((srate >= 0.0) ? TWO_TO_52 : -TWO_TO_52); + + // main vectorised loop + vEnd = ul_NumDataPoints - (ul_NumDataPoints & 3); + __m128d di1 = _mm_set_pd(1.0, 0.0); + __m128d di2 = _mm_set_pd(3.0, 2.0); + + for (i = 0; i < vEnd; i += 4) { + const float *data = (const float *) (cx_DataArray + i); + float *chirped = (float *) (cx_ChirpDataArray + i); + + __m128d a1, a2; + __m128 d1, d2; + __m128 x; + __m128 y; + __m128 z; + __m128 s; + __m128 c; + __m128 m; + + // load the signal to be chirped + prefetchnta((const void *)( data+32 )); + d1 = _mm_load_ps(data); + d2 = _mm_load_ps(data+4); + + // calculate the input angles + a1 = _mm_mul_pd(_mm_mul_pd(di1, di1), rate); + a2 = _mm_mul_pd(_mm_mul_pd(di2, di2), rate); + + // update time values for next iteration + di1 = _mm_add_pd(di1, dfourv); + di2 = _mm_add_pd(di2, dfourv); + + // reduce the angles to the range (-0.5, 0.5) + a1 = _mm_sub_pd(a1, _mm_sub_pd(_mm_add_pd(a1, roundVal), roundVal)); + a2 = _mm_sub_pd(a2, _mm_sub_pd(_mm_add_pd(a2, roundVal), roundVal)); + + // convert the 2 packed doubles to packed single + x = _mm_movelh_ps(_mm_cvtpd_ps(a1), _mm_cvtpd_ps(a2)); + + // square to the range [0, 0.25) + y = _mm_mul_ps(x, x); + + // perform the initial polynomial approximations + z = _mm_mul_ps(y, y); + s = _mm_mul_ps(_mm_add_ps(_mm_mul_ps(_mm_add_ps(_mm_mul_ps(y, SS4F), + SS3F), + z), + _mm_add_ps(_mm_mul_ps(y, SS2F), + SS1F)), + x); + c = _mm_add_ps(_mm_mul_ps(_mm_add_ps(_mm_mul_ps(y, CC3F), + CC2F), + z), + _mm_add_ps(_mm_mul_ps(y, CC1F), + ONE)); + + // perform first angle doubling + x = _mm_sub_ps(_mm_mul_ps(c, c), _mm_mul_ps(s, s)); + y = _mm_mul_ps(_mm_mul_ps(s, c), TWO); + + // calculate scaling factor to correct the magnitude + m = _mm_sub_ps(_mm_sub_ps(TWO, _mm_mul_ps(x, x)), _mm_mul_ps(y, y)); + + // perform second angle doubling + c = _mm_sub_ps(_mm_mul_ps(x, x), _mm_mul_ps(y, y)); + s = _mm_mul_ps(_mm_mul_ps(y, x), TWO); + + // correct the magnitude (final sine / cosine approximations) + s = _mm_mul_ps(s, m); + c = _mm_mul_ps(c, m); + + // chirp the data + x = _mm_mul_ps(_mm_shuffle_ps(d1, d1, 0xb1), R_NEG); + y = _mm_mul_ps(_mm_shuffle_ps(d2, d2, 0xb1), R_NEG); + + d1 = _mm_mul_ps(d1, _mm_shuffle_ps(c, c, 0x50)); + d2 = _mm_mul_ps(d2, _mm_shuffle_ps(c, c, 0xfa)); + x = _mm_mul_ps(x, _mm_shuffle_ps(s, s, 0x50)); + y = _mm_mul_ps(y, _mm_shuffle_ps(s, s, 0xfa)); + + // store chirped values + _mm_stream_ps(chirped+0, _mm_add_ps(d1, x)); + _mm_stream_ps(chirped+4, _mm_add_ps(d2, y)); + } + _mm_sfence(); + + // handle tail elements with scalar code + for ( ; i < ul_NumDataPoints; ++i) { + double angle = srate * i * i * 0.5; + angle -= floor(angle); + angle *= M_PI * 2; + double s = sin(angle); + double c = cos(angle); + float re = cx_DataArray[i][0]; + float im = cx_DataArray[i][1]; + + cx_ChirpDataArray[i][0] = re * c - im * s; + cx_ChirpDataArray[i][1] = re * s + im * c; + } + analysis_state.FLOP_counter+=12.0*ul_NumDataPoints; + + return 0; +} + + +#endif // USE_INTRINSICS diff --git a/client/vector/analyzeFuncs_sse3.cpp b/client/vector/analyzeFuncs_sse3.cpp new file mode 100644 index 0000000..6b50111 --- /dev/null +++ b/client/vector/analyzeFuncs_sse3.cpp @@ -0,0 +1,329 @@ +/****************** + * + * analyzeFuncs_SSE3.cpp + * + * Description: Intel SSE3 (Prescott New Instruction) optimzized functions + * CPUs: Intel Pentium IV Model 3+ + * + */ + +// Copyright 2007 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#include "sah_config.h" + +// The following is empty if USE_INTRINSICS is not defined +#ifdef USE_INTRINSICS + +#include +#include + +#ifdef HAVE_INTRIN_H +#include +#endif +#ifdef HAVE_PMMINTRIN_H +#include +#endif +#include +#include + +#include "s_util.h" +#include "x86_float4.h" +#include "analyzeFuncs_vector.h" +#include "analyzeFuncs.h" + + +__inline __m128 vec_recip3(__m128 v) + { + // obtain estimate + __m128 estimate = _mm_rcp_ps( v ); + // one round of Newton-Raphson + return _mm_add_ps(_mm_mul_ps(_mm_sub_ps(ONE, _mm_mul_ps(estimate, v)), estimate), estimate); + } + +// ============================================================================= +// +// sse3_vChirpData +// version by: Alex Kan +// http://tbp.berkeley.edu/~alexkan/seti/ +// +int sse3_ChirpData_ak( + sah_complex * cx_DataArray, + sah_complex * cx_ChirpDataArray, + int chirp_rate_ind, + double chirp_rate, + int ul_NumDataPoints, + double sample_rate +) { + int i; + + if (chirp_rate_ind == 0) { + memcpy(cx_ChirpDataArray, cx_DataArray, (int)ul_NumDataPoints * sizeof(sah_complex) ); + return 0; + } + + int vEnd; + double srate = chirp_rate * 0.5 / (sample_rate * sample_rate); + __m128d rate = _mm_set1_pd(chirp_rate * 0.5 / (sample_rate * sample_rate)); + __m128d roundVal = _mm_set1_pd(srate >= 0.0 ? TWO_TO_52 : -TWO_TO_52); + + // main vectorised loop + vEnd = ul_NumDataPoints - (ul_NumDataPoints & 3); + for (i = 0; i < vEnd; i += 4) { + const float *data = (const float *) (cx_DataArray + i); + float *chirped = (float *) (cx_ChirpDataArray + i); + __m128d di = _mm_set1_pd(i); + __m128d a1 = _mm_add_pd(_mm_set_pd(1.0, 0.0), di); + __m128d a2 = _mm_add_pd(_mm_set_pd(3.0, 2.0), di); + + __m128 d1, d2; + __m128 cd1, cd2; + __m128 td1, td2; + __m128 x; + __m128 y; + __m128 s; + __m128 c; + __m128 m; + + // load the signal to be chirped + prefetchnta((const void *)( data+32 )); + d1 = _mm_load_ps(data); + d2 = _mm_load_ps(data+4); + + // calculate the input angle + a1 = _mm_mul_pd(_mm_mul_pd(a1, a1), rate); + a2 = _mm_mul_pd(_mm_mul_pd(a2, a2), rate); + + // reduce the angle to the range (-0.5, 0.5) + a1 = _mm_sub_pd(a1, _mm_sub_pd(_mm_add_pd(a1, roundVal), roundVal)); + a2 = _mm_sub_pd(a2, _mm_sub_pd(_mm_add_pd(a2, roundVal), roundVal)); + + // convert pair of packed double into packed single + x = _mm_movelh_ps(_mm_cvtpd_ps(a1), _mm_cvtpd_ps(a2)); + + // square to the range [0, 0.25) + y = _mm_mul_ps(x, x); + + // perform the initial polynomial approximations + s = _mm_mul_ps(_mm_add_ps(_mm_mul_ps(_mm_add_ps(_mm_mul_ps(_mm_add_ps(_mm_mul_ps(y, SS4), + SS3), + y), + SS2), + y), + SS1), + x); + c = _mm_add_ps(_mm_mul_ps(_mm_add_ps(_mm_mul_ps(_mm_add_ps(_mm_mul_ps(y, CC3), + CC2), + y), + CC1), + y), + ONE); + + // perform first angle doubling + x = _mm_sub_ps(_mm_mul_ps(c, c), _mm_mul_ps(s, s)); + y = _mm_mul_ps(_mm_mul_ps(s, c), TWO); + + // calculate scaling factor to correct the magnitude + // m1 = vec_nmsub(y1, y1, vec_nmsub(x1, x1, TWO)); + // m2 = vec_nmsub(y2, y2, vec_nmsub(x2, x2, TWO)); + m = vec_recip3(_mm_add_ps(_mm_mul_ps(x, x), _mm_mul_ps(y, y))); + + // perform second angle doubling + c = _mm_sub_ps(_mm_mul_ps(x, x), _mm_mul_ps(y, y)); + s = _mm_mul_ps(_mm_mul_ps(y, x), TWO); + + // correct the magnitude (final sine / cosine approximations) + s = _mm_mul_ps(s, m); + c = _mm_mul_ps(c, m); + + // chirp the data + cd1 = _mm_shuffle_ps(c, c, 0x50); + cd2 = _mm_shuffle_ps(c, c, 0xfa); + cd1 = _mm_mul_ps(cd1, d1); + cd2 = _mm_mul_ps(cd2, d2); + d1 = _mm_shuffle_ps(d1, d1, 0xb1); + d2 = _mm_shuffle_ps(d2, d2, 0xb1); + td1 = _mm_shuffle_ps(s, s, 0x50); + td2 = _mm_shuffle_ps(s, s, 0xfa); + td1 = _mm_mul_ps(td1, d1); + td2 = _mm_mul_ps(td2, d2); + cd1 = _mm_addsub_ps(cd1, td1); + cd2 = _mm_addsub_ps(cd2, td2); + + // store chirped values + _mm_stream_ps(chirped, cd1); + _mm_stream_ps(chirped+4, cd2); + } + _mm_sfence(); + + // handle tail elements with scalar code + for ( ; i < ul_NumDataPoints; ++i) { + double angle = srate * i * i * 0.5; + double s = sin(angle); + double c = cos(angle); + float re = cx_DataArray[i][0]; + float im = cx_DataArray[i][1]; + + cx_ChirpDataArray[i][0] = re * c - im * s; + cx_ChirpDataArray[i][1] = re * s + im * c; + } + analysis_state.FLOP_counter+=12.0*ul_NumDataPoints; + + return 0; +} + +// ============================================================================= +// +// JWS: alternate SSE3 chirp +// +// Using Mendenhall Faster SinCos, coding based on +// version 8 v_vChirpData for SSE3 by Alex Kan +// + +int sse3_ChirpData_ak8( + sah_complex * cx_DataArray, + sah_complex * cx_ChirpDataArray, + int chirp_rate_ind, + double chirp_rate, + int ul_NumDataPoints, + double sample_rate +) { + int i; + + if (chirp_rate_ind == 0) { + memcpy(cx_ChirpDataArray, cx_DataArray, (int)ul_NumDataPoints * sizeof(sah_complex) ); + return 0; + } + + int vEnd; + double srate = chirp_rate * 0.5 / (sample_rate * sample_rate); + __m128d rate = _mm_set1_pd(chirp_rate * 0.5 / (sample_rate * sample_rate)); + __m128d roundVal = _mm_set1_pd(srate >= 0.0 ? TWO_TO_52 : -TWO_TO_52); + __m128d DFOUR = _mm_set_pd(4.0, 4.0); + + + // main vectorised loop + vEnd = ul_NumDataPoints - (ul_NumDataPoints & 3); + __m128d di1 = _mm_set_pd(2.0, 0.0); // set time patterns for eventual moveldup/movehdup + __m128d di2 = _mm_set_pd(3.0, 1.0); + + for (i = 0; i < vEnd; i += 4) { + const float *d = (const float *) (cx_DataArray + i); + float *cd = (float *) (cx_ChirpDataArray + i); + + __m128d a1, a2; + + __m128 d1, d2; + __m128 cd1, cd2; + __m128 td1, td2; + + __m128 x; + __m128 y; + __m128 z; + __m128 s; + __m128 c; + __m128 m; + + // load the signal to be chirped + d1 = _mm_load_ps(d); + d2 = _mm_load_ps(d+4); + + // calculate the input angle + a1 = _mm_mul_pd(_mm_mul_pd(di1, di1), rate); + a2 = _mm_mul_pd(_mm_mul_pd(di2, di2), rate); + + // update times for next + di1 = _mm_add_pd(di1, DFOUR); + di2 = _mm_add_pd(di2, DFOUR); + + // reduce the angle to the range (-0.5, 0.5) + a1 = _mm_sub_pd(a1, _mm_sub_pd(_mm_add_pd(a1, roundVal), roundVal)); + a2 = _mm_sub_pd(a2, _mm_sub_pd(_mm_add_pd(a2, roundVal), roundVal)); + + // convert pair of packed double into packed single + x = _mm_movelh_ps(_mm_cvtpd_ps(a1), _mm_cvtpd_ps(a2)); // 3 1 2 0 + + // square to the range [0, 0.25) + y = _mm_mul_ps(x, x); + + // perform the initial polynomial approximations, Estrin's method + z = _mm_mul_ps(y, y); + + s = _mm_mul_ps(_mm_add_ps(_mm_mul_ps(_mm_add_ps(_mm_mul_ps(y, SS4F), + SS3F), + z), + _mm_add_ps(_mm_mul_ps(y, SS2F), + SS1F)), + x); + c = _mm_add_ps(_mm_mul_ps(_mm_add_ps(_mm_mul_ps(y, CC3F), + CC2F), + z), + _mm_add_ps(_mm_mul_ps(y, CC1F), + ONE)); + + // perform first angle doubling + x = _mm_sub_ps(_mm_mul_ps(c, c), _mm_mul_ps(s, s)); + y = _mm_mul_ps(_mm_mul_ps(s, c), TWO); + + // calculate scaling factor to correct the magnitude + m = _mm_sub_ps(_mm_sub_ps(TWO, _mm_mul_ps(x, x)), _mm_mul_ps(y, y)); + + // perform second angle doubling + c = _mm_sub_ps(_mm_mul_ps(x, x), _mm_mul_ps(y, y)); + s = _mm_mul_ps(_mm_mul_ps(y, x), TWO); + + // correct the magnitude (final sine / cosine approximations) + c = _mm_mul_ps(c, m); // c3 c1 c2 c0 + s = _mm_mul_ps(s, m); + + // chirp the data + cd1 = _mm_moveldup_ps(c); // c1 c1 c0 c0 + cd2 = _mm_movehdup_ps(c); // c3 c3 c2 c2 + cd1 = _mm_mul_ps(cd1, d1); // c1.i1 c1.r1 c0.i0 c0.r0 + cd2 = _mm_mul_ps(cd2, d2); // c3.i3 c3.r3 c2.i2 c2.r2 + d1 = _mm_shuffle_ps(d1, d1, 0xb1); + d2 = _mm_shuffle_ps(d2, d2, 0xb1); + td1 = _mm_moveldup_ps(s); + td2 = _mm_movehdup_ps(s); + td1 = _mm_mul_ps(td1, d1); + td2 = _mm_mul_ps(td2, d2); + cd1 = _mm_addsub_ps(cd1, td1); + cd2 = _mm_addsub_ps(cd2, td2); + + // store chirped values + _mm_stream_ps(cd, cd1); + _mm_stream_ps(cd+4, cd2); + } + + // handle tail elements with scalar code + for (; i < ul_NumDataPoints; ++i) { + double angle = srate * i * i * 0.5; + double s = sin(angle); + double c = cos(angle); + + float re = cx_DataArray[i][0]; + float im = cx_DataArray[i][1]; + + cx_ChirpDataArray[i][0] = re * c - im * s; + cx_ChirpDataArray[i][1] = re * s + im * c; + } + analysis_state.FLOP_counter+=12.0*ul_NumDataPoints; + return 0; +} + + + +#endif // USE_INTRINSICS diff --git a/client/vector/analyzeFuncs_vector.cpp b/client/vector/analyzeFuncs_vector.cpp new file mode 100644 index 0000000..811f6b9 --- /dev/null +++ b/client/vector/analyzeFuncs_vector.cpp @@ -0,0 +1,1326 @@ + +// Copyright (c) 1999-2006 Regents of the University of California +// +// FFTW: Copyright (c) 2003,2006 Matteo Frigo +// Copyright (c) 2003,2006 Massachusets Institute of Technology +// +// fft8g.[cpp,h]: Copyright (c) 1995-2001 Takya Ooura + +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) any later +// version. + +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with this program; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions +// as an alternative to FFTW and distribute a linked executable and +// source code. You must obey the GNU General Public License in all +// respects for all of the code used other than the FFT library itself. +// Any modification required to support these libraries must be distributed +// under the terms of this license. If you modify this program, you may extend +// this exception to your version of the program, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. Please be aware that FFTW is not covered by this exception, +// therefore you may not use FFTW in any derivative work so modified without +// permission of the authors of FFTW. +// +// $Id: analyzeFuncs_vector.cpp,v 1.1.2.29 2007/08/16 10:13:56 charlief Exp $ + +#include "sah_config.h" + +#ifdef __APPLE_CC__ +#define _CPP_CMATH // Block inclusion of which undefines isnan() (for using GCC 3 on OS X) +#define _GLIBCXX_CMATH // Block inclusion of which undefines isnan() (for using GCC 4 on OS X) +#endif +#ifdef _WIN32 +#define uint32_t unsigned long +#endif + +#include +#include +#include +#include +#include +#ifdef HAVE_FLOAT_H +#include +#endif +#ifdef HAVE_FLOATINGPOINT_H +#include +#endif +#ifdef HAVE_IEEEFP_H +#include +#endif + +#include "util.h" +#include "s_util.h" +#include "boinc_api.h" +#ifdef BOINC_APP_GRAPHICS +#include "sah_gfx_main.h" +#endif +#include "diagnostics.h" + +#include "sighandler.h" +#include "analyzeFuncs.h" +#include "analyzeFuncs_vector.h" + +#include "hires_timer.h" + +#include "chirpfft.h" +#include "analyzePoT.h" +#include "pulsefind.h" +#include "sincos.h" +#ifdef USE_ASMLIB +#include "asmlib.h" +#endif + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#ifdef __APPLE_CC__ +#include +#ifdef HAVE___ISNAN +#define isnotnan(x) (!isnan(x)) +#else +#define isnotnan(x) ((x) == (x)) +#endif +#endif + + +#ifndef __APPLE_CC__ +#ifdef HAVE___ISNAN +#define isnotnan(x) (!__isnan(x)) +#elif defined(HAVE__ISNAN) +#define isnotnan(x) (!_isnan(x)) +#elif defined(HAVE_ISNAN) +#define isnotnan(x) (!isnan(x)) +#else +#define isnotnan(x) ((x) == (x)) +#endif +#endif + +// Bit patterns to compare host capabilities and what SIMD capability a routine needs +#define BA_ANY 0x00000001 // any CPU OK +#define BA_MMX 0x00000002 +#define BA_SSE 0x00000004 +#define BA_SSE2 0x00000008 +#define BA_SSE3 0x00000010 +#define BA_3Dnow 0x00000020 +#define BA_3DnowP 0x00000040 +#define BA_MMX_P 0x00000080 +#define BA_SSSE3 0x00000100 +#define BA_SSE41 0x00000200 +#define BA_SSE4a 0x00000400 +#define BA_SSE42 0x00000800 +#define BA_XOP 0x00001001 +#define BA_AVX 0x00002000 +#define BA_FMA 0x00004000 +#define BA_FMA4 0x00008000 +#define BA_ALTVC 0x00100000 + +uint32_t CPUCaps = BA_ANY; + +/*********************************** + *JWS: Temporary hack for AVX support, based on section 2.2 of Intel 319433-010.pdf + * (Intel® Advanced Vector Extensions Programming Reference) + * + * Note this does not check for whether the CPU supports cpuid, etc. so must + * not be used unless such details have already been confirmed. + */ +#if defined(USE_AVX) + +int avxSupported(void) { + int retval = 1; +#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ > 3)) || (__GNUC__ > 4)) +#if defined(__i386__) && (defined(__PIC__) || defined(__pic__)) +// EBX can't be clobbered on linux PIC. + __asm__ ( "pushl %ebx \n\t" ); +#endif + __asm__ ( "\n\t" + "movl $1, %%eax \n\t" + "cpuid \n\t" + "andl $0x18000000, %%ecx \n\t" + "cmpl $0x18000000, %%ecx \n\t" + "jne 1f \n\t" + "xorl %%ecx, %%ecx \n\t" + "xgetbv \n\t" + "andl $6, %%eax \n\t" + "cmpl $6, %%eax \n\t" + "jne 1f \n\t" + "movl $1, %0 \n\t" + "jmp 2f \n\t" + "1: \n\t" + "movl $0, %0 \n\t" + "2: \n\t" +# if defined(_WIN64) || defined(__LP64__) || defined (__X86_64__) + : "=g" (retval) :: "%rax", "%rbx", "%rcx", "%rdx" +# elif defined(__i386__) && (defined(__PIC__) || defined(__pic__)) + "popl %%ebx \n\t" + : "=g" (retval) :: "%eax", "%ecx", "%edx" +# else + : "=g" (retval) :: "%eax", "%ebx", "%ecx", "%edx" +# endif + ); +#elif (_MSC_VER >= 1600) && !defined(_WIN64) + _asm { + mov eax, 1 + cpuid + and ecx, 018000000H + cmp ecx, 018000000H + jne NOSUPPORT + xor ecx, ecx + xgetbv + and eax, 06H + cmp eax, 06H + jne NOSUPPORT + mov retval, 1 + jmp DONE + NOSUPPORT: + mov retval, 0 + DONE: + }; +#endif // compiler + return retval; +} +#endif // USE_AVX + +/********************** + */ +void SetCapabilities(void) { + +#if defined(__APPLE_CC__) + // OS X assumes MMX, SSE and SSE2 are present on Intel processors + // SSE3 and Altivec are optional +#if defined(__i386__) || defined(__x86_64__) + CPUCaps |= (BA_MMX|BA_SSE|BA_SSE2); + int sse3flag=0; + size_t length=sizeof(sse3flag); + int error=sysctlbyname("hw.optional.sse3",&sse3flag,&length,NULL,0); + if (sse3flag && !error) CPUCaps |= BA_SSE3; +#else // PowerPC + int altivecflag=0; + size_t length=sizeof(altivecflag); + int error=sysctlbyname("hw.optional.altivec",&altivecflag,&length,NULL,0); + if (altivecflag && !error) CPUCaps |= BA_ALTVC; +#endif + +#elif defined( USE_BHCPUID ) + CPU_INFO theCPU; + + if (theCPU.mmx()) CPUCaps |= BA_MMX; + if (theCPU.sse()) CPUCaps |= BA_SSE; + if (theCPU.sse2()) CPUCaps |= BA_SSE2; + if (theCPU.sse3()) CPUCaps |= BA_SSE3; + if (theCPU._3Dnow()) CPUCaps |= BA_3Dnow; + if (theCPU._3DnowPlus()) CPUCaps |= BA_3DnowP; + if (theCPU.mmxPlus()) CPUCaps |= BA_MMX_P; + +#elif defined( USE_ASMLIB ) + int dp = DetectProcessor(); + if (dp & 0x00800000) CPUCaps |= BA_MMX; + if ((dp & 0x02000800) == 0x02000800) CPUCaps |= BA_SSE; + if ((dp & 0x04000800) == 0x04000800) CPUCaps |= BA_SSE2; + if ((dp & 0x08000800) == 0x08000800) CPUCaps |= BA_SSE3; + if (dp & 0x80000000) CPUCaps |= BA_3Dnow; + if (dp & 0x40000000) CPUCaps |= BA_3DnowP; + if (dp & 0x20000000) CPUCaps |= BA_MMX_P; +#if defined(USE_AVX) + if ((dp & 0x00000800) && avxSupported()) CPUCaps |= BA_AVX; +#endif + +#elif defined(__i386__) || defined (__x86_64__) + /* we're goping to rely on signal handling to keep us out of trouble */ + CPUCaps |= (BA_MMX | BA_SSE | BA_SSE2 | BA_SSE3 | BA_3Dnow | BA_3DnowP | BA_MMX_P ); +#if defined(USE_AVX) + CPUCaps |= BA_AVX; +#endif + +#elif defined(USE_ALTIVEC) + CPUCaps |= BA_ALTVC; + +#endif +} + + +struct BLStb { + BaseLineSmooth_func func; + int ba; + const char * const nom; +}; + +BLStb BaseLineSmoothFuncs[]={ + v_BaseLineSmooth, BA_ANY, "v_BaseLineSmooth", +}; + +struct GPStb { + GetPowerSpectrum_func func; + int ba; + const char * const nom; +}; + +GPStb GetPowerSpectrumFuncs[]={ + v_GetPowerSpectrum, BA_ANY, "v_GetPowerSpectrum", +#ifdef USE_ALTIVEC + v_vGetPowerSpectrum, BA_ALTVC, "v_vGetPowerSpectrum", + v_vGetPowerSpectrumG4, BA_ALTVC,"v_vGetPowerSpectrumG4", +#endif +#ifdef USE_SSE + v_vGetPowerSpectrum, BA_SSE, "v_vGetPowerSpectrum", + v_vGetPowerSpectrum2, BA_SSE, "v_vGetPowerSpectrum2", + v_vGetPowerSpectrumUnrolled, BA_SSE, "v_vGetPowerSpectrumUnrolled", + v_vGetPowerSpectrumUnrolled2, BA_SSE, "v_vGetPowerSpectrumUnrolled2", +#endif +#ifdef USE_AVX +# ifdef AVX_EMU + v_avxGetPowerSpectrum, BA_SSE3, "v_avxGetPowerSpectrum", +# else + v_avxGetPowerSpectrum, BA_AVX, "v_avxGetPowerSpectrum", +# endif +#endif + +}; + +struct CDtb { + ChirpData_func func; + int ba; + const char * const nom; +}; +CDtb ChirpDataFuncs[]={ + v_ChirpData, BA_ANY, "v_ChirpData", + fpu_ChirpData, BA_ANY, "fpu_ChirpData", + fpu_opt_ChirpData, BA_ANY, "fpu_opt_ChirpData", +#ifdef USE_ALTIVEC + v_vChirpData, BA_ALTVC, "v_vChirpData", + v_vChirpDataG4, BA_ALTVC, "v_vChirpDataG4", + v_vChirpDataG5, BA_ALTVC, "v_vChirpDataG5", +#endif +#ifdef USE_SSE + v_vChirpData_x86_64, BA_SSE2, "v_vChirpData_x86_64", + sse1_ChirpData_ak, BA_SSE, "sse1_ChirpData_ak", + sse1_ChirpData_ak8e, BA_SSE, "sse1_ChirpData_ak8e", + sse1_ChirpData_ak8h, BA_SSE, "sse1_ChirpData_ak8h", + sse2_ChirpData_ak, BA_SSE2, "sse2_ChirpData_ak", + sse2_ChirpData_ak8, BA_SSE2, "sse2_ChirpData_ak8", + sse3_ChirpData_ak, BA_SSE3, "sse3_ChirpData_ak", + sse3_ChirpData_ak8, BA_SSE3, "sse3_ChirpData_ak8", +#endif +#ifdef USE_AVX +# ifdef AVX_EMU + avx_ChirpData_a, BA_SSE3, "avx_ChirpData_a", + avx_ChirpData_b, BA_SSE3, "avx_ChirpData_b", + avx_ChirpData_c, BA_SSE3, "avx_ChirpData_c", +/* avx_ChirpData_d, BA_SSE41, "avx_ChirpData_d", // needs SSE4.1, not sensed yet */ +# else + avx_ChirpData_a, BA_AVX, "avx_ChirpData_a", + avx_ChirpData_b, BA_AVX, "avx_ChirpData_b", + avx_ChirpData_c, BA_AVX, "avx_ChirpData_c", + avx_ChirpData_d, BA_AVX, "avx_ChirpData_d", +# endif +#endif +}; + + +struct TPtb { + Transpose_func func; + int ba; + const char * const nom; +}; + +TPtb TransposeFuncs[]={ + v_Transpose, BA_ANY, "v_Transpose", + v_Transpose2, BA_ANY, "v_Transpose2", + v_Transpose4, BA_ANY, "v_Transpose4", + v_Transpose8, BA_ANY, "v_Transpose8", +#ifdef USE_ALTIVEC + v_vTranspose, BA_ALTVC, "v_vTranspose", +#endif +#ifdef USE_SSE + v_pfTranspose2, BA_SSE, "v_pfTranspose2", + v_pfTranspose4, BA_SSE, "v_pfTranspose4", + v_pfTranspose8, BA_SSE, "v_pfTranspose8", + v_vTranspose4, BA_SSE, "v_vTranspose4", + v_vTranspose4np, BA_SSE, "v_vTranspose4np", + v_vTranspose4ntw, BA_SSE, "v_vTranspose4ntw", + v_vTranspose4x8ntw, BA_SSE, "v_vTranspose4x8ntw", + v_vTranspose4x16ntw, BA_SSE, "v_vTranspose4x16ntw", + v_vpfTranspose8x4ntw, BA_SSE, "v_vpfTranspose8x4ntw", +#endif +#ifdef USE_AVX +# ifdef AVX_EMU + v_avxTranspose4x8ntw, BA_SSE3, "v_avxTranspose4x8ntw", + v_avxTranspose4x16ntw, BA_SSE3, "v_avxTranspose4x16ntw", + v_avxTranspose8x4ntw, BA_SSE3, "v_avxTranspose8x4ntw", + v_avxTranspose8x8ntw_a, BA_SSE3, "v_avxTranspose8x8ntw_a", + v_avxTranspose8x8ntw_b, BA_SSE3, "v_avxTranspose8x8ntw_b", +# else + v_avxTranspose4x8ntw, BA_AVX, "v_avxTranspose4x8ntw", + v_avxTranspose4x16ntw, BA_AVX, "v_avxTranspose4x16ntw", + v_avxTranspose8x4ntw, BA_AVX, "v_avxTranspose8x4ntw", + v_avxTranspose8x8ntw_a, BA_AVX, "v_avxTranspose8x8ntw_a", + v_avxTranspose8x8ntw_b, BA_AVX, "v_avxTranspose8x8ntw_b", +# endif +#endif +}; + +struct FolSub { + FoldSet *fsp; + int ba; +}; + +FolSub FoldSubs[] = { + &swifold, BA_ANY, +#ifdef USE_ALTIVEC + &AKavfold, BA_ALTVC, +#endif +#ifdef USE_SSE +// sse_ben_fold doesn't seem to work on PIII and Athlon. +// What are the chances we'll see one of those these days? +// Still, we should fix at some point. + &sse_ben_fold, BA_SSE, + &AKSSEfold, BA_SSE, + &BHSSEfold, BA_SSE, +#endif +#ifdef USE_AVX + &AVXfold_a, BA_AVX, + &AVXfold_c, BA_AVX, +#endif +}; + + +static bool do_print; + +bool TestBoincSignalHandling() { +#ifdef USE_ASMLIB + return true; +#endif + install_sighandler(); + FORCE_FRAME_POINTER; + if (sigsetjmp(jb,1)) { + uninstall_sighandler(); + return true; + } else { + // Try some illegal instructions to check the signal handling. +#ifdef __GNUC__ +#if defined(__APPLE__) + uninstall_sighandler(); + return true; +#elif defined(__x86_64__) + __asm__ ("movq %cr4,%rax"); +#elif defined(__i386__) + __asm__ ("movl %cr4,%eax"); +#elif defined(__ppc__) || defined(__sparc__) + __asm__ (".long %0": : "i" (0xfeedface) ); +#endif +#elif defined(_MSC_VER) && ( defined(_M_IX86) || defined(_M_X64) ) +#ifndef _NDEBUG + uninstall_sighandler(); + return true; +#else + __asm { + __asm __emit 00fh + __asm __emit 020h + __asm __emit 0e0h + } +#endif +#endif + } + uninstall_sighandler(); + return false; +} + + +BaseLineSmooth_func ChooseBaseLineSmooth() { + hires_timer timer; + BaseLineSmooth_func baseline_smooth; + int i,j,rv,k = sizeof(BaseLineSmoothFuncs)/sizeof(BLStb); + int NumDataPoints=128*1024; + double speed=1e+6,timing,accuracy; + int best; + double best_timing, best_accuracy; + + if (k == 1) { + if (do_print) fprintf(stderr,"%32s (no other)%s\n", + BaseLineSmoothFuncs[0].nom, + verbose ? "\n": ""); + return v_BaseLineSmooth; + } + sah_complex *indata=(sah_complex *)malloc_a(NumDataPoints*sizeof(sah_complex),MEM_ALIGN); + sah_complex *outdata=(sah_complex *)malloc_a(NumDataPoints*sizeof(sah_complex),MEM_ALIGN); + sah_complex *save=(sah_complex *)malloc_a(NumDataPoints*sizeof(sah_complex),MEM_ALIGN); + + FORCE_FRAME_POINTER; + if (!indata || !outdata || !save) { + if (indata) + free_a(indata); + if (outdata) + free_a(outdata); + if (save) + free_a(save); + return v_BaseLineSmooth; + } + for (i=0;i(RAND_MAX/2))?-1.0f:1.0f; + indata[i][1]=((rand()&RAND_MAX)>(RAND_MAX/2))?-1.0f:1.0f; + } +#if !defined(USE_ASMLIB) && !defined(__APPLE_CC__) + install_sighandler(); + for (i=0;i= (double)(64*1024*1024))); + if (default_functions_flag) { + if (do_print) + fprintf(stderr,"%32s (default)\n",ChirpDataFuncs[0].nom); + return ChirpDataFuncs[0].func; + } // else + hires_timer timer; + ChirpData_func chirp_data; + int i,j,rv,k = sizeof(ChirpDataFuncs)/sizeof(CDtb); + double speed=1e+6,timing,accuracy; + int NumDataPoints=1024*1024; + int best; + double best_timing, best_accuracy; + FORCE_FRAME_POINTER; + + if (k == 1) { + if (do_print) fprintf(stderr,"%32s (no other)\n",ChirpDataFuncs[0].nom); + return v_ChirpData; + } + sah_complex *indata=(sah_complex *)malloc_a(NumDataPoints*sizeof(sah_complex),MEM_ALIGN); + sah_complex *outdata=(sah_complex *)malloc_a(NumDataPoints*sizeof(sah_complex),MEM_ALIGN); + sah_complex *test=(sah_complex *)malloc_a(NumDataPoints*sizeof(sah_complex),MEM_ALIGN); + + if (!indata || !outdata || !test) { + if (indata) + free_a(indata); + if (outdata) + free_a(outdata); + if (test) + free_a(test); + fprintf(stderr,"Memory allocation failed in ChooseChirp\n"); + return v_ChirpData; + } + //JWS: Generate indata as the chirp of flat line (constant) data + for (i=0;i(i)*recip_sample_rate; + ang=0.5*chirp_rate*time*time; + ang -= floor(ang); + ang *= M_PI*2; + sincos(ang,&dd,&cc); + // Notionally: + // c=cc; + // d=dd; + // indata[i][0] = save[i][0] * c - save[i][1] * d; + // indata[i][1] = save[i][0] * d + save[i][1] * c; + indata[i][0] = static_cast(cc); + indata[i][1] = static_cast(dd); + } + +#if !defined(USE_ASMLIB) && !defined(__APPLE_CC__) + install_sighandler(); + for (i=0;i0) { + ind*=-1; + } else { + ind=-1*(ind-2); + } + j++; + } + if (rv) continue; + timing/=j; + accuracy=0; + //JWS: indata is positive chirp of constant at TESTCHIRPIND, test was copied + // at -TESTCHIRPIND so we check for deviation from flat + for (j=0;j>= 1); + FFTtbl[iL][0] = ChirpFftPairs[i].FftLen; + FFTtbl[iL][2] += 1; + } + } + + // For testing, the chirp/fft table may just be a short list. If so, add the FFT + // length to the counts to simulate distribution for a full table. (This also affects + // very high angle range WUs, but Pulse folding is a small factor there so looser + // testing will have very little effect.) + if (num_cfft < 14) { + for (iL = 0; iL < 32; iL++) FFTtbl[iL][2] += FFTtbl[iL][0]; + } + + // Scale the counts so the minimum is 1. Use the scaled value directly for fold + // sequences starting with a fold by 4. Adjust the values for fold by 3 and + // fold by 5 to get close to the 10, 9, 8 ratios. Add the PoT length values to + // the table, and tot up the needed number of PoTPlans. + for (iL = 0; iL < 32; iL++) { + if ((FFTtbl[iL][0]) && ((double)FFTtbl[iL][2] < dTmp)) dTmp = (double)FFTtbl[iL][2]; + } + for (iL = 0; iL < 32; iL++) { + if (FFTtbl[iL][0]) { + FFTtbl[iL][2] = (int)((double)FFTtbl[iL][2] / dTmp + 0.5); + FFTtbl[iL][1] = (int)((double)FFTtbl[iL][2] * 10.0 / 9.0 + 0.5); + FFTtbl[iL][3] = FFTtbl[iL][2] + FFTtbl[iL][2] - FFTtbl[iL][1]; + PoTLen = (int)(NumSamples / FFTtbl[iL][0] + 0.5); + GetPulsePoTLen(PoTLen, &PulsePoTLen, &Overlap); + FFTtbl[iL][4] = PulsePoTLen; + for (i = 32, ndivs = 1; i <= PulsePoTLen; ndivs++, i *= 2); + NumPlans += 3 * FFTtbl[iL][2] * ndivs; + } + } + if (NumPlans == 0) return 0; // No pulse finding in this WU, abort test. + + // At some angle ranges the total number of test folds may be too few to get good + // timing measurements. Scale up so there are at least 16K test folds. + while (NumPlans < 16384) { + for (iL = 0; iL < 32; iL++) { + FFTtbl[iL][1] *= 2; + FFTtbl[iL][2] *= 2; + FFTtbl[iL][3] *= 2; + } + NumPlans *= 2; + } + +// fprintf(stderr, "Calculated Preplans = %d\n", NumPlans); +// NumPlans *= 2; // temporary safety measure + + + // Now we know what we're doing - allocate memory in which to do it. + PoTPlan *PlanBuf = (PoTPlan *)malloc_a((NumPlans + 1) * sizeof(PoTPlan), MEM_ALIGN); + float *indata = (float *)malloc_a(MaxPulsePoT * sizeof(float), MEM_ALIGN); + float *outdata = (float *)malloc_a(MaxPulsePoT * sizeof(float), MEM_ALIGN); + float *maxdata = (float *)malloc_a(NumPlans * sizeof(float), MEM_ALIGN); + float *save = (float *)malloc_a(NumPlans * sizeof(float), MEM_ALIGN); + + FORCE_FRAME_POINTER; + if (!PlanBuf || !indata || !outdata || !maxdata || !save) { + if (PlanBuf) + free_a(PlanBuf); + if (indata) + free_a(indata); + if (outdata) + free_a(outdata); + if (maxdata) + free_a(maxdata); + if (save) + free_a(save); + return 0; // Can't test, make no change + } + + SrcSel[0] = indata; + SrcSel[1] = outdata; + + // Generate PowerSpectrum random data + srand(11); + for (i = 0; i < MaxPulsePoT; i++) { + float fr1 = (float)(rand()) / RAND_MAX; + float fr2 = (float)(rand()) / RAND_MAX; + indata[i] = fr1 * fr1 + fr2 * fr2; + } + +#if !defined(USE_ASMLIB) && !defined(__APPLE_CC__) + install_sighandler(); + for (i=0;(i*sizeof(FolSub))name); + continue; + } + j = 0; + timing = 0; + CopyFoldSet(&TestFoldSet, FoldSubs[i].fsp); + int n = planFoldTest(PlanBuf, outdata, FFTtbl); +// if (!i) fprintf(stderr, "Actual Preplans = %d\n", n); + while ((j < 100) && ((j < 10) || ((j * timing) < (3 * timer.resolution())))) { + memset(outdata, 0, MaxPulsePoT * sizeof(float)); + memset(maxdata, 0, NumPlans * sizeof(float)); + maxdata[0] = -1.234f; + timer.start(); + for ( k = 0; PlanBuf[k].di; k++) { + maxdata[k] = PlanBuf[k].fun_ptr(SrcSel, &PlanBuf[k]); + } + onetime = timer.stop(); + if (j) timing = std::min(onetime, timing); + else timing = onetime; +#if !defined(USE_ASMLIB) && !defined(__APPLE_CC__) + if (maxdata[0] < 0) siglongjmp(jb,1); +#else + if (maxdata[0] < 0) break; +#endif + j++; + } + accuracy = 0; + errmax = 0; + if (i == 0) { + memcpy(save, maxdata, NumPlans * sizeof(float)); + } else { + for (j = 0; j < NumPlans; j++) { + // a zero max should never happen, but be safe... + if (save[j]) { + double relerr = fabs((save[j] - maxdata[j]) / save[j]); + accuracy += relerr; + if (relerr > errmax) errmax = relerr; + } + } + } + accuracy /= NumPlans; + if (verbose) { + fprintf(stderr, "%24s folding %8.6f %7.5f test\n", FoldSubs[i].fsp->name, timing, accuracy); + fflush(stderr); + } + if ((timing < speed) && isnotnan(accuracy) && (accuracy < 1e-6) && (errmax < 1e-4)) { + speed = timing; + best = i; + best_timing = timing; + best_accuracy = accuracy; + } +#if !defined(USE_ASMLIB) && !defined(__APPLE_CC__) + } else { + // reinstall_sighandler(); + if (verbose) { + fprintf(stderr, "%24s folding faulted\n", FoldSubs[i].fsp->name); + fflush(stderr); + } + } + } + uninstall_sighandler(); +#else + } +#endif + free_a(PlanBuf); + free_a(indata); + free_a(outdata); + free_a(maxdata); + free_a(save); + if (do_print) + fprintf(stderr, "%24s folding %8.6f %7.5f %s\n", + FoldSubs[best].fsp->name, + best_timing, + best_accuracy, + verbose ? " choice\n": ""); + CopyFoldSet(&Foldmain, FoldSubs[best].fsp); + return 0; +} + + + +void ChooseFunctions(BaseLineSmooth_func *baseline_smooth, + GetPowerSpectrum_func *get_power_spectrum, + ChirpData_func *chirp_data, + Transpose_func *transpose, + ChirpFftPair_t * ChirpFftPairs, + int num_cfft, + int nsamples, + bool print_choices) { + do_print=print_choices; + if (verbose) do_print = true; + if (do_print) { + fprintf(stderr,"Optimal function choices:\n"); + fprintf(stderr,"--------------------------------------------------------\n"); + fprintf(stderr,"%32s %8s %7s\n","name","timing","error"); + fprintf(stderr,"--------------------------------------------------------\n"); + fflush(stderr); + } + if (TestBoincSignalHandling()) { + SetCapabilities(); + hires_timer durtimer; + double TestDur=0; + durtimer.start(); + *baseline_smooth=ChooseBaseLineSmooth(); + fflush(stderr); + *get_power_spectrum=ChooseGetPowerSpectrum(); + fflush(stderr); + *chirp_data=ChooseChirpData(); + fflush(stderr); + *transpose=ChooseTranspose(); + fflush(stderr); + ChooseFoldSubs(ChirpFftPairs, num_cfft, nsamples); + fflush(stderr); + TestDur+=durtimer.stop(); + if (verbose) + fprintf(stderr,"%32s %8.2f seconds\n\n","Test duration",TestDur); + } + + if (do_print) { + fflush(stderr); + } + +} + + diff --git a/client/vector/analyzeFuncs_vector.h b/client/vector/analyzeFuncs_vector.h new file mode 100644 index 0000000..d2e482e --- /dev/null +++ b/client/vector/analyzeFuncs_vector.h @@ -0,0 +1,297 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +// $Id: analyzeFuncs_vector.h,v 1.1.2.9 2007/06/08 03:09:47 korpela Exp $ +#ifndef ANALYZEFUNCS_VECTOR_H +#define ANALYZEFUNCS_VECTOR_H + +#include "chirpfft.h" +#define FUNCTION_FILE_NAME "functions.sah" + +#define TWO_TO_52 4.503599627370496e15 +// 2^52+2^51 recommended by AMD optimization manual, scaled to 2^64+2^63 for X87 +#define ROUNDX87 6755399441055744.0 * 2048.0 + +// Flemming Pedersen (CERN) SinCos polynomial coefficients +#define FS1 1.5707963267948966 +#define FS2 -0.64596348437163809 +#define FS3 0.079679708649230657 +#define FS4 -0.0046002309092153379 +#define FC1 -1.2336979844380824 +#define FC2 0.25360671639164339 +#define FC3 -0.020427240364907607 + + +typedef int (*BaseLineSmooth_func)(sah_complex *, int, int, int); +typedef int (*GetPowerSpectrum_func)(sah_complex *, float*, int); +typedef int (*ChirpData_func)(sah_complex *, sah_complex *, int, double, int, double); +typedef int (*Transpose_func)(int, int , float *, float *); + +extern void ChooseFunctions( + BaseLineSmooth_func *, + GetPowerSpectrum_func *, + ChirpData_func *, + Transpose_func *, + ChirpFftPair_t * ChirpFftPairs, + int num_cfft, + int nsamples, + bool print_choice); + +#if defined(__i386__) || defined(__x86_64__) || defined(USE_SSE) +extern double fastfrac( double val, double returnVal) +#if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 3)) + __attribute__ ((__optimize__ ("-fno-fast-math"))); +#define SUPPORTS_ATTRIB_OPT 1 +#else + ; +#undef SUPPORTS_ATTRIB_OPT +#endif +#endif + +extern int v_vBaseLineSmooth( + sah_complex * cx_DataIn, + int ul_NumDataPoints, + int ul_BoxCarLength, + int ul_TimeLength + ); + +extern int v_vGetPowerSpectrum( + sah_complex * cx_FreqData, + float * fp_PowerSpectrum, + int ul_NumDataPoints + ); + +extern int v_vChirpData( + sah_complex * cx_DataArray, + sah_complex * cx_ChirpDataArray, + int ChirpRateInd, + double ChirpRate, + int ul_NumDataPoints, + double sample_rate + ); +extern int fpu_ChirpData ( + sah_complex * cx_DataArray, + sah_complex * cx_ChirpDataArray, + int ChirpRateInd, + double ChirpRate, + int ul_NumDataPoints, + double sample_rate +); +extern int fpu_opt_ChirpData ( + sah_complex * cx_DataArray, + sah_complex * cx_ChirpDataArray, + int ChirpRateInd, + double ChirpRate, + int ul_NumDataPoints, + double sample_rate +); +#if defined(__i386__) || defined(__x86_64__) || defined(USE_SSE) +extern int v_vChirpData_x86_64( + sah_complex * cx_DataArray, + sah_complex * cx_ChirpDataArray, + int ChirpRateInd, + double ChirpRate, + int ul_NumDataPoints, + double sample_rate + ); +extern int sse1_ChirpData_ak( + sah_complex * cx_DataArray, + sah_complex * cx_ChirpDataArray, + int ChirpRateInd, + double ChirpRate, + int ul_NumDataPoints, + double sample_rate + ); +extern int sse1_ChirpData_ak8e( + sah_complex * cx_DataArray, + sah_complex * cx_ChirpDataArray, + int ChirpRateInd, + double ChirpRate, + int ul_NumDataPoints, + double sample_rate + ); +extern int sse1_ChirpData_ak8h( + sah_complex * cx_DataArray, + sah_complex * cx_ChirpDataArray, + int ChirpRateInd, + double ChirpRate, + int ul_NumDataPoints, + double sample_rate + ); +extern int sse2_ChirpData_ak( + sah_complex * cx_DataArray, + sah_complex * cx_ChirpDataArray, + int ChirpRateInd, + double ChirpRate, + int ul_NumDataPoints, + double sample_rate + ); +extern int sse2_ChirpData_ak8( + sah_complex * cx_DataArray, + sah_complex * cx_ChirpDataArray, + int ChirpRateInd, + double ChirpRate, + int ul_NumDataPoints, + double sample_rate + ); +extern int sse3_ChirpData_ak( + sah_complex * cx_DataArray, + sah_complex * cx_ChirpDataArray, + int ChirpRateInd, + double ChirpRate, + int ul_NumDataPoints, + double sample_rate + ); +extern int sse3_ChirpData_ak8( + sah_complex * cx_DataArray, + sah_complex * cx_ChirpDataArray, + int ChirpRateInd, + double ChirpRate, + int ul_NumDataPoints, + double sample_rate + ); +#endif + +extern int v_vTranspose(int i, int j, float *in, float *out); +#if defined(__i386__) || defined(__x86_64__) || defined(USE_SSE) +extern int v_pfTranspose2(int i, int j, float *in, float *out); +extern int v_pfTranspose4(int i, int j, float *in, float *out); +extern int v_pfTranspose8(int i, int j, float *in, float *out); +extern int v_vTranspose4(int i, int j, float *in, float *out); +extern int v_vTranspose4np(int i, int j, float *in, float *out); +extern int v_vTranspose4ntw(int i, int j, float *in, float *out); +extern int v_vTranspose4x8ntw(int i, int j, float *in, float *out); +extern int v_vTranspose4x16ntw(int i, int j, float *in, float *out); +extern int v_vpfTranspose8x4ntw(int i, int j, float *in, float *out); +#endif + + +#if defined(__i386__) || defined(__x86_64__) || defined(USE_SSE) +extern int v_vGetPowerSpectrumUnrolled( + sah_complex * cx_FreqData, + float * fp_PowerSpectrum, + int ul_NumDataPoints + ); +extern int v_vGetPowerSpectrum2( + sah_complex * cx_FreqData, + float * fp_PowerSpectrum, + int ul_NumDataPoints + ); +extern int v_vGetPowerSpectrumUnrolled2( + sah_complex * cx_FreqData, + float * fp_PowerSpectrum, + int ul_NumDataPoints + ); +#endif + +#ifdef USE_ALTIVEC +extern int v_vGetPowerSpectrumG4( + sah_complex * cx_FreqData, + float * fp_PowerSpectrum, + int ul_NumDataPoints + ); + + +extern int v_vChirpDataG4( + sah_complex * cx_DataArray, + sah_complex * cx_ChirpDataArray, + int ChirpRateInd, + double ChirpRate, + int ul_NumDataPoints, + double sample_rate + ); + +extern int v_vChirpDataG5( + sah_complex * cx_DataArray, + sah_complex * cx_ChirpDataArray, + int ChirpRateInd, + double ChirpRate, + int ul_NumDataPoints, + double sample_rate + ); +#endif + +#if defined(__x86_64__) || defined(_M_AMD64) +extern int v_vChirpData_x86_64( + sah_complex * cx_DataArray, + sah_complex * cx_ChirpDataArray, + int ChirpRateInd, + double ChirpRate, + int ul_NumDataPoints, + double sample_rate + ); +#endif + +#if defined(USE_AVX) +extern int avxSupported(void); + +extern int avx_ChirpData_a( + sah_complex * cx_DataArray, + sah_complex * cx_ChirpDataArray, + int chirp_rate_ind, + const double chirp_rate, + int ul_NumDataPoints, + const double sample_rate +); +extern int avx_ChirpData_b( + sah_complex * cx_DataArray, + sah_complex * cx_ChirpDataArray, + int chirp_rate_ind, + const double chirp_rate, + int ul_NumDataPoints, + const double sample_rate +); +extern int avx_ChirpData_c( + sah_complex * cx_DataArray, + sah_complex * cx_ChirpDataArray, + int chirp_rate_ind, + const double chirp_rate, + int ul_NumDataPoints, + const double sample_rate +); +extern int avx_ChirpData_d( + sah_complex * cx_DataArray, + sah_complex * cx_ChirpDataArray, + int chirp_rate_ind, + const double chirp_rate, + int ul_NumDataPoints, + const double sample_rate +); +extern int v_avxTranspose4x8ntw(int x, int y, float *in, float *out); +extern int v_avxTranspose4x16ntw(int x, int y, float *in, float *out); +extern int v_avxTranspose8x4ntw(int x, int y, float *in, float *out); +extern int v_avxTranspose8x8ntw_a(int x, int y, float *in, float *out); +extern int v_avxTranspose8x8ntw_b(int x,int y, float *in, float *out +); +extern int v_avxGetPowerSpectrum( + sah_complex* FreqData, + float* PowerSpectrum, + int NumDataPoints +); +#endif + +#endif diff --git a/client/vector/analyzeFuncs_x86_64.cpp b/client/vector/analyzeFuncs_x86_64.cpp new file mode 100644 index 0000000..15b37fc --- /dev/null +++ b/client/vector/analyzeFuncs_x86_64.cpp @@ -0,0 +1,187 @@ +// Copyright 2003-2005 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +// AMD optimizations by Evandro Menezes + +// $Id: analyzeFuncs_x86_64.cpp,v 1.1.2.4 2007/05/31 22:03:13 korpela Exp $ + + +#if defined(__i386__) || defined(__x86_64__) || defined (_M_AMD64) || defined(_M_IX86) +#include "sah_config.h" + +#include +#include +#include +#include + +#include "x86_ops.h" +#include "x86_float4.h" + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#include "seti.h" +#include "s_util.h" +#include "worker.h" + +// chirp_rate is in Hz per second +int v_vChirpData_x86_64( + sah_complex * fp_DataArray, + sah_complex * fp_ChirpDataArray, + int ChirpRateInd, + double chirp_rate, + int ul_NumDataPoints, + double sample_rate +) { + static const int as [4] __attribute__((aligned(16)))= {INT_MIN, 0, INT_MIN, 0} ; // {-, +, -, +} + char *cblock = (char *)alloca(11*16); + cblock+=(16-((ssize_t)cblock % 16)); + x86_m128 *fblock=reinterpret_cast(cblock); + x86_m128d *dblock=reinterpret_cast(cblock); + #define CC dblock[0] + #define DD dblock[1] + #define cc fblock[2] + #define dd fblock[3] + #define ri fblock[4] + #define ri1 fblock[5] + #define ri2 fblock[6] + #define ss fblock[7] + #define zz fblock[8] + + memcpy(&(ss),as,sizeof(as)); + zz = _mm_setzero_ps (); + int i, j; + // float c, d, real, imag; + float time; + float ang; + + double aC [] __attribute__((aligned(16))) = {0, 0}; + double aD [] __attribute__((aligned(16))) = {0, 0} ; + + float chirpInvariant = (float)(0.5*chirp_rate/(sample_rate*sample_rate)); + + if (chirp_rate == 0.0) { + memcpy(fp_ChirpDataArray, + fp_DataArray, + (int)ul_NumDataPoints * 2 * sizeof(float) + ); // NOTE INT CAST + } else { + for (i = 0, j = 0; i < (ul_NumDataPoints - 2); i += 2, j += 2) { + + // _mm_prefetch (fp_DataArray + i + 32, _MM_HINT_T0); + _mm_prefetch ((char *) (fp_ChirpDataArray + i) + 384, _MM_HINT_T0); + + time = (float)j*j; + ang = time*chirpInvariant; + ang -= floor(ang); + ang *= (float)(M_PI*2); +#ifndef HAVE_SINCOS + aC [0] = cos (ang); + aD [0] = sin (ang); +#else + sincos (ang, aD + 0, aC + 0); +#endif + + time = (float)(j + 1)*(j + 1); + ang = chirpInvariant*time; + ang -= floor(ang); + ang *= (float)(M_PI*2); +#ifndef HAVE_SINCOS + aC [1] = cos (ang); + aD [1] = sin (ang); +#else + sincos (ang, aD + 1, aC + 1); +#endif + + CC = _mm_loadu_pd (aC); + DD = _mm_loadu_pd (aD); + + cc = _mm_cvtpd_ps (CC); + dd = _mm_cvtpd_ps (DD); + + cc = _mm_unpacklo_ps (cc, cc); + dd = _mm_unpacklo_ps (dd, dd); + + // Sometimes chirping is done in place. + // We don't want to overwrite data prematurely. + // real = fp_DataArray[i] * c - fp_DataArray[i+1] * d; + // imag = fp_DataArray[i] * d + fp_DataArray[i+1] * c; + ri1 = _mm_loadu_ps ((float *)(fp_DataArray + i)); + ri2 = _mm_shuffle_ps (ri1, ri1, _MM_SHUFFLE (2, 3, 0, 1)); + ri2 = _mm_xor_ps (ri2, ss); + ri1 = _mm_mul_ps (ri1, cc); + ri2 = _mm_mul_ps (ri2, dd); + ri = _mm_add_ps (ri1, ri2); + + // fp_ChirpDataArray[i] = real; + // fp_ChirpDataArray[i+1] = imag; + _mm_storeu_ps ((float *)(fp_ChirpDataArray + i), ri); + } + for (; i < ul_NumDataPoints; i ++, j++) { + + // _mm_prefetch (fp_DataArray + i + 16, _MM_HINT_T0); + _mm_prefetch ((char *) (fp_ChirpDataArray + i) + 384, _MM_HINT_T0); + + time = (float)j*j; + ang = chirpInvariant*time; + ang -= floor(ang); + ang *= (float)(M_PI*2); +#ifndef HAVE_SINCOS + aC [0] = cos (ang); + aC [1] = sin (ang); +#else + sincos (ang, aC + 0, aC + 1); +#endif + + CC = _mm_loadu_pd (aC); + + cc = _mm_cvtpd_ps (CC); + + cc = _mm_unpacklo_ps (cc, cc); + dd = _mm_movehl_ps (zz, cc); + + // Sometimes chirping is done in place. + // We don't want to overwrite data prematurely. + // real = fp_DataArray[i] * c - fp_DataArray[i+1] * d; + // imag = fp_DataArray[i] * d + fp_DataArray[i+1] * c; + ri1 = _mm_loadl_pi (zz, (__m64 *) (fp_DataArray + i)); + ri2 = _mm_shuffle_ps (ri1, ri1, _MM_SHUFFLE (2, 3, 0, 1)); + ri2 = _mm_xor_ps (ri2, ss); + ri1 = _mm_mul_ps (ri1, cc); + ri2 = _mm_mul_ps (ri2, dd); + ri = _mm_add_ps (ri1, ri2); + + // fp_ChirpDataArray[i] = real; + // fp_ChirpDataArray[i+1] = imag; + _mm_storel_pi ((__m64 *) (fp_ChirpDataArray + i), ri); + } + } + return 0; +} +#endif + diff --git a/client/vector/asmlib.h b/client/vector/asmlib.h new file mode 100644 index 0000000..63217e1 --- /dev/null +++ b/client/vector/asmlib.h @@ -0,0 +1,16 @@ +// ASMLIB.H © Agner Fog 2004 + +// Header file for asmlibM.lib, asmlibO.lib, and asmlibE.a +// See asmlib.txt for further details + +extern "C" int InstructionSet (void); // tell which instruction set is supported +extern "C" int DetectProcessor (void); // information about microprocessor features +extern "C" void ProcessorName (char * text); // ASCIIZ text describing microprocessor +extern "C" int Round (double x); // round to nearest or even +extern "C" int Truncate (double x); // truncation towards zero +extern "C" int ReadClock (void); // read microprocessor internal clock +extern "C" int MinI (int a, int b); // the smallest of two integers +extern "C" int MaxI (int a, int b); // the biggest of two integers +extern "C" double MinD (double a, double b); // the smallest of two double precision numbers +extern "C" double MaxD (double a, double b); // the biggest of two double precision numbers + diff --git a/client/vector/asmlib.zip b/client/vector/asmlib.zip new file mode 100644 index 0000000000000000000000000000000000000000..6cc8eaa64806a079fd3fb2f3817aa95f96929fb5 GIT binary patch literal 30585 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 Quz=r-5WpnK`PXm%53REq2LJ#7 literal 0 HcmV?d00001 diff --git a/client/vector/asmlibe.a b/client/vector/asmlibe.a new file mode 100644 index 0000000000000000000000000000000000000000..4b435defe1c64d73a7b322ef772056c97b30281e GIT binary patch literal 7382 zcmc&(Z)_aZ5uZC>?X&O79%)KwL&X{vku=Dxea3d$1RUXD8O6lp4>lp;a=AOo726l> zt*Mb*ah9>#)1rzG`9P%rlKH|XD<4t>Qd@jJ8Vi&U5$cB|CaN9MDi!$CEt6>~V>)J*jx|$-zwG6dgG&A z5bI43cY$?dxd*lJ(H_#`jaspN+Q@JsuBX6h#P(!HhLd33A!+X5sMeIoyhKswNN>de zi!p9i)wZ@a>~HD7JJI2W*LUuE%IEW8z%BAY4XjE4C;gVb)nuEX4g$8N#r8heA1xgp zcnm;>zITql5G_7LO=&WKUZOM7)Z~ox2F4zu^SK+kbgY=Wu|qmGd*))p`NCJh(7!*T z$)u^m<-kKFY=u@P7JY@qjiKwt=i`fzD{Y{bsS8`JNMW(w?!}>n#oEyIYjc3B)Hi>G z4sz1ecGTyzjpP|6V-^<#Goh97ivXQaxL6nZ7Y+dM>q(RQ^n;Rb;e)`){{6-`<5$Sl z#HFjo6=`}W7?WZ2GX4j;|GD+RIcd5V@}|!0eTVcc_d>L|-84EjBYikiSO|qyjDH+5 z=3+0tP`v!t|CCA?tNq59vVL-AM4qebP+L3Zx&v);Mw{yn%7d9-&2@)Uc;x^28(f`n zm3M>j&S}b@a9O#2<1f-wzAhgNG{CtCOFK58-s_!PjJ*?g_a!gVQBbgR*f7gFmrQ7f^rO9W+i&EJy)$+tye8 zf%<%R?0h95w^c}8$JrH*y*+E7(n1Mp~XI-zBd-p zIx?8j2D0`iS zRMFUoHniSa+qM(=B~sWFv3VnMQse4PQZd#dvE9R{Bs=aVyJrPMc6~SM*cWw=qaFPa zOl&9mqQ28O=nQgNZ#`a=X*4&rMSsV!xU(wYXx%pOM*R-&I9UyWZUQ{8{U|310}EDj|kn!>3H42%@awWtbOYOvxF zp!HNq_oE%HS*#472xB?pse(}UF@1|k5JZ8-(Rj*Gk_lo+c5(y->SJPmTTnrESP)Di zkgTSH>_rS!pWK{hLha~8cT2%A>_WC!pu&ga8GYe_wu;NpQ* z!RraEy><0j*Xs#v!QKz#$JMPgQ}%l6`{ zV3p9Ckd%pYs1X&k7d|bA*}&#(=SFL?dq%J&A4G1no<^N&_E;AIr?k^-HA?c8F-bo()azgCCd4evr##j*g|Q2CX*><0+TKdSm92b#}ZH zsp1RIPXb`R;l+^2;9wvfBz8>zi;mW+y*$?MlsH+heFdOv?_ z@4Cx7%|Y8+XJ>Fo2;^Gi@STEdC1m|0ZNetbPB*ef5F9$urW#~rU&Ps;8(Ar6eS)EV zL~hFVKI{-rI@=K!v;9*PuAAJL`w%(xTT4qf1!5;(6Y=ME~tf#(lQem2@LK8tUzuTPwX zV)V1gFQoShn2r{vpP=cS_gQgcYms($3c0w}N~qh1dM5s*-Kd+xgLW?(d7evoMYItShwX@qSvp{6sTb;Q!hQ5tm{(AlO`gZnf7kD`;Ci10=n@u8 zSu4J;m|5zaMej7dC9FFCA~+2PQP<)8gp^MsC#2NqZw5|i#6Yi{Zf~|fi&cS?XY9Rl zPP>uPO5MQxeab+QOzF2@q4&pw0^k-^M|075oV*v&r*V`tSZdR*Zp}L)M}8PN1?s G+5QVM%1A!| literal 0 HcmV?d00001 diff --git a/client/vector/asmlibm.lib b/client/vector/asmlibm.lib new file mode 100644 index 0000000000000000000000000000000000000000..712b3aad305e1a434b0b9e2dd85b8d3bdb7c4536 GIT binary patch literal 5612 zcmb_gYiv|S6h6CM``BH*3pNmgj}f@zL|R;UmQ)x-h9Ei$ZM8Bz~A7n2?Rq8X1ia_2K@n5+vWs-IRN$}=2U(S zz?iBqPswdJCt*2&G0o}*pj3@+tDz|&C1O%rIu%P~GO09Z+H29y1VpUG5p#J_=N>9?) zrhB?#Q3=PUX{%E`U2*iMyzV;EHK9f=(iIq!BN)GH<(R54-fn>90zmgHC0Mi!U;{fi z;65eUpbRRY{FXL5*0YAs5+62ib(%^9S}Y5o$B4~Nn{)BXSbXzHl6MwQ7C*}h8dgCK zpdQzVwrZNMP*)*Vor$Ilh@`n{$P&3|{^1`qB}M@ckG` z5}%aVB{5Zbp0NRZWXO~1g|=o)|aK5ws6yzlvZQ?RgrRAIn@9R!Dk!GU4n{VUiiIF`L33A+o~8%u@VBS%g-kLOQU zx~}i1aR`I?bB+a5sJX86PuTJk^ITWu!+jHwotjIUVskUilb@(kOR;HwqTF@$@+d+C zq=oy@K~@-Cg7$2B9(l%`Jc0v)Vb_(uQvhMepQ>!%0oSMQ|t&@Aj>Ve@N?`TEHUmF^2cGP=Q>Cxs&Z%69w(Pnod4e<8| zI6C zG5iPo=<2`8p_QW*-dCcX*j=*Y9WQqGqPI1L-Nh3fUilyfzkj^K;s3C?Qa;!}E;#&) z8+Y0rRk>!*78*QG5*~yq+?~jXM&Q;8sKa~sWcGJ80d>g@I<Q#)~Q7c zYekl2n6pxamCdYq^Vz^TLt_emsIegs^f%PrnkgFm{3v8h@!fZq!r$P4OEJYSI6`8I z6*MUndKsC5%1J01>(x4n0Ut)DD5yq?<;J3Vo@Jk)tT8gh(cti9Y(!-7DYju$@iA&D zCt&diLK~!a!>D9&hfAd32&K1_w_S=cgF|wLFXyRG$rhGRXq#9Va)|OrBJI+?@0AzZ z#BMRitV)I5N{ME1i^0S4>AtH}RkH83e~E5kQvnX(3y(59rKV7*Gi^^8m*^hu3C-Hv*iKGqR=R)9>Al@lPt6+p2M7eCR#5$E#|wB zGaZ*QF%Eu&Jf4&_HMKRN27bj;w*fyXYwPrT2%VI5XTDu}0ef_*W3Zl-bS1gnNlE3U z#E5@h?=`Hv$I?JKDW5@l76NUn>AkU?(W*zK)hcb4_YgnKrv@Gz({wnM&qJR=F@E$i zt`*~l;!rFcc{(=mTBr!a#zUwZ?o#@_&Dojk>WuD+Ye)zvJm{}4$%74M9$fYHrSLiI zmiK4H!H?K8;b1up4W$y3kq4=~lo)Zq>$PF!PgP&M9pRvV3FREUb0-B)ljxWfwls#xhq_5fkPEJhBc62^~wS1=3v?O<6pW)80k3jWsI2vfBjhqMPWq)NO)raXU7p@={{lMZ6wGaLCetc9D#m zKwcqMK9m3KiIK8=!H~cFyJEQowv=h#YiuQbcZV%LGksF`3R~>Ml=k*L#<Hgd0L5{*F+74{)H|iEZl|>r6OlL!8i!vJ_5eT?r>AFp-pDGO{g| zml7jRc)e9v8GqWC#K^W4lftt)yF#y@ShW9wd#qYKwpMf;7sX?n#me^AHx3-yxFD1>b2D|An8pVlX ztjo+$M{zdGbQq0Vn7^I0A23+LaQFyn7PiuVp*Yj@Q;LHTk*491)02um?G_m11&p@{ zk7u!mQnx@imfeoGsJxUI@yP4Z?T1c0qYxe$>>Ohci|xvHwSEEQ6PzhjiqAe4GYuv< il<6Ra&p;pf%#c!i|5JaADUKN%v7d3QCx!yzp8o+8du)gR literal 0 HcmV?d00001 diff --git a/client/vector/avxcheck.asm b/client/vector/avxcheck.asm new file mode 100644 index 0000000..6de2591 --- /dev/null +++ b/client/vector/avxcheck.asm @@ -0,0 +1,36 @@ +; AVX detection based on section 2.2 of "Intel Advanced Vector Extensions Programming Reference" +; +; MASM source needed for 64 bit builds with MicroSoft tools + + +PUBLIC avxSupported + + +_TEXT SEGMENT + +avxSupported PROC + + mov eax, 1 + cpuid + and ecx, 018000000H + cmp ecx, 018000000H ; check both OSXSAVE and AVX feature flags + jne NOSUPPORT + xor ecx, ecx ; specify 0 for XFEATURE_ENABLED_MASK register + xgetbv ; result in EDX:EAX + and eax, 06H + cmp eax, 06H ; check OS has enabled both XMM and YMM state support + jne NOSUPPORT + mov eax, 1 + jmp DONE + + NOSUPPORT: + mov eax, 0 + + DONE: + ret + +avxSupported ENDP + +_TEXT ENDS + +END \ No newline at end of file diff --git a/client/vector/hires_timer.cpp b/client/vector/hires_timer.cpp new file mode 100644 index 0000000..2c7979b --- /dev/null +++ b/client/vector/hires_timer.cpp @@ -0,0 +1,302 @@ + +// Copyright (c) 1999-2006 Regents of the University of California +// +// FFTW: Copyright (c) 2003,2006 Matteo Frigo +// Copyright (c) 2003,2006 Massachusets Institute of Technology +// +// fft8g.[cpp,h]: Copyright (c) 1995-2001 Takya Ooura + +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) any later +// version. + +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with this program; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions +// as an alternative to FFTW and distribute a linked executable and +// source code. You must obey the GNU General Public License in all +// respects for all of the code used other than the FFT library itself. +// Any modification required to support these libraries must be distributed +// under the terms of this license. If you modify this program, you may extend +// this exception to your version of the program, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. Please be aware that FFTW is not covered by this exception, +// therefore you may not use FFTW in any derivative work so modified without +// permission of the authors of FFTW. +// + +// $Id: hires_timer.cpp,v 1.1.2.6 2006/09/07 00:26:56 korpela Exp $ + +#include "sighandler.h" +#include "hires_timer.h" +#include "diagnostics.h" +#include +#include + +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_TIME_H +#include +#endif +#ifdef HAVE_MACH_MACH_TIME_H +#include +#endif +#ifdef HAVE_SYS_PARAM_H +#include +#endif +#ifdef HAVE_SYS_SYSTM_H +#include +#endif +#ifdef HAVE_MACHINE_CPU_H +#include +#endif + +#if _MSC_VER >= 1400 +#include "intrin.h" // include intrinsic assembly functions +#endif + +#ifdef _WIN32 +#include "windows.h" +#endif + + +#if defined(_WIN32) +static inline tick_t fallback_ticks() { + LARGE_INTEGER time; + FILETIME sysTime; + GetSystemTimeAsFileTime(&sysTime); + time.LowPart = sysTime.dwLowDateTime; + time.HighPart = sysTime.dwHighDateTime; + return static_cast(time.QuadPart); +} +#elif defined(HAVE_GETTIMEOFDAY) +static inline tick_t fallback_ticks() { + struct timeval tp; + gettimeofday(&tp,0); + return static_cast(tp.tv_sec)*1000000+tp.tv_usec; +} +#else +static inline tick_t fallback_ticks() { + return static_cast(time(0)); +} +#endif + +#ifdef _WIN32 +static inline tick_t get_ticks() { + LARGE_INTEGER rv; + QueryPerformanceCounter(&rv); + return static_cast(rv.QuadPart); +} +#elif defined(HAVE_HRTIME_T) && defined(HAVE_GETHRTIME) +static inline tick_t get_ticks() { + return gethrtime(); +} + +#elif defined(HAVE_MACH_ABSOLUTE_TIME) +static inline tick_t get_ticks() { + return mach_absolute_time(); +} + +#elif defined(HAVE_GET_CYCLECOUNT) +static inline tick_t get_ticks() { + return get_cyclecount(); +} + +#elif defined(HAVE_NANOTIME) +static inline tick_t get_ticks() { + struct timespec tsp; + nanotime(&tsp); + return static_cast(tsp.tv_sec)*static_cast(1000000000LL)+tsp.tv_nsec; +} + +#elif defined(__GNUC__) && defined(__i386__) +static inline tick_t get_ticks() { + register tick_t rv; + asm volatile ( + "rdtsc" + : "=A" (rv) + ); + return rv; +} + +#elif defined(__GNUC__) && defined(__x86_64__) +static inline tick_t get_ticks() { + register tick_t rv; + register unsigned int hi,lo; + asm volatile ( + "rdtsc" + : "=a" (lo), "=d" (hi) + : /* no inputs */ + : /* no clobbers */ + ); + rv=(static_cast(hi)<<32)|lo; + return rv; +} + +#elif defined(__GNUC__) && (defined(__ia64) || defined (__ia64__)) +static inline tick_t get_ticks() { + register tick_t rv; + asm volatile ( + "mov %0=ar.itc" + : "=r" (rv) + : /* no inputs */ + : /* no clobbers */ + ); + return rv; +} + +#elif defined(__GNUC__) && defined(__sparc) +static inline tick_t get_ticks() { + register long lo; + asm volatile ( +#ifdef __sparcv9 + "rd %%tick,%0" + : "=r" (lo) +#else + ".long %1\n" + "mov %%g1,%0\n" + : "=r" (lo) + : "i" (0x83410000) // rd %tick, %g1 +#endif + ); + return static_cast(lo); +} + +#elif defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__)) +static inline tick_t get_ticks() { + register tick_t rv; + register unsigned int hi1,hi,lo; + do { + asm volatile ( + "mftbu %0\n\t" + "mftb %1\n\t" + "mftbu %2\n\t" /* don't forget to check overflow */ + : "=r" (hi), "=r" (lo), "=r" (hi1) + ); + } while (hi != hi1); + rv=(static_cast(hi)<<32)|lo; + return rv; +} + +#elif _MSC_VER >= 1400 && (defined(_M_X64) || defined(_M_AMD64)) +static inline tick_t get_ticks() { + return __rdtsc(); +} + +#elif defined(HAVE_MICROTIME) +static inline tick_t get_ticks() { + struct timeval tsp; + microtime(&tsp); + return static_cast(tsp.tv_sec)*static_cast(1000000LL)+tsp.tv_usec; +} + +#else +static inline tick_t get_ticks() { + raise(SIGILL); + return static_cast(0); +} +#endif + +hires_timer::hires_timer() : rollover(0),last_ticks(0),start_time(0.0) { + if (period==0) { + install_sighandler(); + if (setjmp(jb)) { + use_fallback=1; + } else { + ticks(); + } + uninstall_sighandler(); + calibrate(); + } +} + +tick_t hires_timer::ticks() { + if (use_fallback) { + tick_t t=fallback_ticks(); + if (t < last_ticks) { + // Assume the rollover is a power of two + tick_t this_rollover=2; + unsigned long long u=last_ticks-t; + while (u>>=1) this_rollover<<=1; + rollover+=this_rollover; + // unfortunately a rollover probably returns a + // bogus elapsed time. + } + return (last_ticks=fallback_ticks()+rollover); + } else { + tick_t t=get_ticks(); + if (t < last_ticks) { + // Assume the rollover is a power of two + tick_t this_rollover=2; + unsigned long long u=last_ticks-t; + while (u>>=1) this_rollover<<=1; + rollover+=this_rollover; + } + return (last_ticks=get_ticks()+rollover); + } +} + +tick_t hires_timer::find_increment() { + int i; + tick_t delta=0; + for (i=0;i<32;i++) { + tick_t t1,t2=ticks(); + while ((t1=ticks()) <= t2) ; /* do nothing */ + delta+=(t1-t2); + } + return (delta/32); +} + +second_t hires_timer::find_frequency() { + time_t t1,t2=time(0); + tick_t start,fin; + // Beware time resets. + while ((t1=time(0)) <= t2) ; /* do nothing */ + start=ticks(); + while ((t2=time(0)) <= t1) ; /* do nothing */ + fin=ticks(); + return static_cast(fin-start)/(t2-t1); +} + +void hires_timer::calibrate() { + double freq=find_frequency(); + if (freq<=0) freq=find_frequency(); /* in case it rolled over */ + BOINCASSERT(freq > 0); + period=1.0/freq; + ticks_min_incr=find_increment(); + increment=period*ticks_min_incr; + if (increment < 1e-6) { + increment=1e-6; + ticks_min_incr=static_cast(floor((second_t)increment/period+0.5)); + } +} + +second_t hires_timer::period; +tick_t hires_timer::ticks_min_incr; +second_t hires_timer::increment; +int hires_timer::use_fallback; + + +#ifdef TEST_TIMER +#include + +int main(void) { + hires_timer t; + t.start(); + printf("frequency:%f resolution:%f seconds:%f\n",t.frequency(),t.resolution(),t.seconds()); + while (t.elapsed() < t.resolution()) ; + printf("%f elapsed\n",t.stop()); + return 0; +} +#endif diff --git a/client/vector/hires_timer.h b/client/vector/hires_timer.h new file mode 100644 index 0000000..a8134e8 --- /dev/null +++ b/client/vector/hires_timer.h @@ -0,0 +1,98 @@ + +// Copyright (c) 1999-2006 Regents of the University of California +// +// FFTW: Copyright (c) 2003,2006 Matteo Frigo +// Copyright (c) 2003,2006 Massachusets Institute of Technology +// +// fft8g.[cpp,h]: Copyright (c) 1995-2001 Takya Ooura + +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) any later +// version. + +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with this program; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions +// as an alternative to FFTW and distribute a linked executable and +// source code. You must obey the GNU General Public License in all +// respects for all of the code used other than the FFT library itself. +// Any modification required to support these libraries must be distributed +// under the terms of this license. If you modify this program, you may extend +// this exception to your version of the program, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. Please be aware that FFTW is not covered by this exception, +// therefore you may not use FFTW in any derivative work so modified without +// permission of the authors of FFTW. + +// $Id: hires_timer.h,v 1.1.2.4 2006/12/14 22:22:00 korpela Exp $ +// +#include "sah_config.h" +#ifdef HAVE_INTTYPES_H +#include +#endif +#ifdef HAVE_STDINT_H +#include +#endif +#ifdef HAVE_SYS_TIME_H +#include +#elif defined(HAVE_TIME_H) +#include +#endif + +#if defined(HAVE_HRTIME_T) && defined(HAVE_GETHRTIME) +typedef hrtime_t tick_t; +#elif defined(HAVE_INT_FAST64_T) +typedef int_fast64_t tick_t; +#elif defined(HAVE_INT64_T) +typedef int64_t tick_t; +#elif defined(HAVE__INT64) +typedef _int64 tick_t; +#elif defined(HAVE_LONG_LONG) +typedef long long tick_t; +#else +typedef double tick_t; +#endif + +typedef double second_t; + +class hires_timer { + public: + hires_timer(); + tick_t ticks(); // current time value in ticks + tick_t delta() const {return ticks_min_incr;}; + inline second_t seconds() {return (second_t)(ticks()*period);}; + inline second_t frequency() const {return 1.0/period;}; + inline second_t resolution() const {return (second_t)ticks_min_incr*period;}; + inline second_t start() { + register second_t tmp=seconds(); + do { + start_time=seconds(); + } while ((start_time-tmp) +#include + +#ifndef MAXSIG + +#ifdef NSIG +#define MAXSIG (NSIG+1) + +#elif defined(__linux__) +#define MAXSIG 64 + +#elif defined(SIGRTMAX) +#define MAXSIG SIGRTMAX + +#elif defined(_SIGRTMAX) +#define MAXSIG _SIGRTMAX + +#else +#define MAXSIG 32 +#endif + +#endif + +#ifdef HAVE_SIGLONGJMP +static sigjmp_buf jb; +#else +static jmp_buf jb; +#define sigsetjmp(x,y) setjmp(x) +#define siglongjmp(x,y) longjmp(x,y) +#endif +static int sc; + +typedef void (*signal_handler)(int); + +#if defined(HAVE_SYSV_SIGNAL) +#define signal(x,y) sysv_signal(x,y) +#elif defined(HAVE_BSD_SIGNAL) +#define signal(x,y) bsd_signal(x,y) +#endif + +/* all our signal handler does is jump to a place we've set */ +static void sighandler(int x) { +#if defined(HAVE_SIGACTION) + sigset_t unblock; + sigemptyset(&unblock); + sigaddset(&unblock,x); + sigprocmask(SIG_UNBLOCK,&unblock,NULL); +#elif defined(HAVE_SYSV_SIGNAL) + // SYSV resets the handler but keeps signal unblocked + sysv_signal(x,sighandler); +#elif defined(HAVE_BSD_SIGNAL) + // BSD keeps the handler, but blocks the signal. + // Nothing should need to be done here. +#else + // who knows which version of signal this is. + // Do the safe thing. + signal(x,sighandler); +#endif + sc++; + siglongjmp(jb,1); +} + +/* flags to mark whether we've been installed already */ +static int installed[MAXSIG]; + +/* a place to save our the existing signal handlers */ +#ifdef HAVE_SIGACTION +static struct sigaction oldhandler[MAXSIG]; +#else +static signal_handler oldhandler[MAXSIG]; +#endif + +/* these are the signals we'll handle */ +static const int install_handler[]={ +#ifdef SIGILL + SIGILL, +#endif +#ifdef SIGPRIV + SIGPRIV, +#endif +#ifdef SIGSEGV + SIGSEGV, +#endif +#ifdef SIGBUS + SIGBUS, +#endif +#ifdef SIGIOT + SIGIOT, +#endif +#ifdef SIGABRT + SIGABRT, +#endif +#ifdef SIGSTKFLT + SIGSTKFLT, +#endif + 0 +}; + +/* Keep these as stubs even if signal handling is not enabled */ +static inline void install_sighandler() { +#ifdef HAVE_SIGACTION + struct sigaction new_action; + new_action.sa_handler=sighandler; + sigemptyset(&new_action.sa_mask); + new_action.sa_flags=0; +#endif + int i=0,sig; + while ((sig=install_handler[i])!=0) { + if (!installed[sig]) { +#ifdef HAVE_SIGACTION + sigaction(sig,&new_action,oldhandler+sig); +#else + oldhandler[sig]=signal(sig,sighandler); +#endif + installed[sig]=1; + } + i++; + } +} + + +static inline void uninstall_sighandler() { + /* Don't uninstall the windows signal handler! */ + int i=0,sig; + while ((sig=install_handler[i])!=0) { + if (installed[sig]) { +#ifdef HAVE_SIGACTION + sigaction(sig,oldhandler+sig,NULL); +#else + signal(sig,oldhandler[sig]); +#endif + installed[sig]=0; + } + i++; + } +} + +//static inline void reinstall_sighandler() { +// uninstall_sighandler(); +// install_sighandler(); +//} + +#endif /* SIGHANDLER_H */ diff --git a/client/vector/x86_float4.cpp b/client/vector/x86_float4.cpp new file mode 100644 index 0000000..b4f4d6d --- /dev/null +++ b/client/vector/x86_float4.cpp @@ -0,0 +1,77 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +// $Id: x86_float4.cpp,v 1.1.2.5 2007/07/16 15:36:56 korpela Exp $ +// + +// This file is empty is __i386__ is not defined +#include "sah_config.h" +#include "math.h" +#include "limits.h" +#include "x86_ops.h" +#include "x86_float4.h" + +#if defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_AMD64) + +// polynomial coefficients for sine / cosine approximation in the chirp routine +const_float4 SS4F(-0.0046075748); +const_float4 CC3F(-0.0204391631); +const_float4 SS3F(0.0796819754); +const_float4 CC2F(0.2536086171); +const_float4 SS2F(-0.645963615); +const_float4 CC1F(-1.2336977925); +const_float4 SS1F(1.5707963235); +const_float4 ONE(1.0); +const_float4 TWO(2.0); + +const_float4 SS1(1.5707963268); +const_float4 SS2(-0.6466386396); +const_float4 SS3(0.0679105987); +const_float4 SS4(-0.0011573807); +const_float4 CC1(-1.2341299769); +const_float4 CC2(0.2465220241); +const_float4 CC3(-0.0123926179); + +const_float4 ZERO(0.0); +const_float4 THREE(3.0); +const_float4 RECIP_TWO(0.5); +const_float4 RECIP_THREE(1.0 / 3.0); +const_float4 RECIP_FOUR(0.25); +const_float4 RECIP_FIVE(0.2); +const_float4 RECIP_PI(1.0/M_PI); +const_float4 RECIP_TWOPI(0.5/M_PI); +const_float4 RECIP_HALFPI(2.0/M_PI); +const_float4 PI(M_PI); +const_float4 TWOPI(2.0*M_PI); +const_float4 HALFPI(0.5*M_PI); +const_float4 R_NEG(-1,1,-1,1); + +// 2^23 (used by round()) +const_float4 TWO_TO_23(8388608.0); +const_float4 INDGEN[]={const_float4(1,2,3,4),const_float4(5,6,7,8)}; + +#endif diff --git a/client/vector/x86_float4.h b/client/vector/x86_float4.h new file mode 100644 index 0000000..524d90e --- /dev/null +++ b/client/vector/x86_float4.h @@ -0,0 +1,266 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +// $Id: x86_float4.h,v 1.1.2.4 2007/07/16 15:36:57 korpela Exp $ +// + +// This file is empty is __i386__ is not defined +// +#ifndef _X86_FLOAT4_H_ +#define _X86_FLOAT4_H_ + +#include "sah_config.h" + +#if defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_AMD64) + +#include "x86_ops.h" + +#ifndef M_PI + #define M_PI 3.14159265358979323846 +#endif + +struct float4; +struct const_float4; + +extern const_float4 SS1, SS2, SS3, SS4, CC1, CC2, CC3; +extern const_float4 SS1F, SS2F, SS3F, SS4F, CC1F, CC2F, CC3F; +extern const_float4 ZERO, ONE, TWO, THREE, RECIP_TWO; +extern const_float4 RECIP_THREE, RECIP_FOUR, RECIP_FIVE; +extern const_float4 RECIP_PI, RECIP_TWOPI, RECIP_HALFPI; +extern const_float4 R_NEG; +// 2^23 (used by quickRound) +extern const_float4 TWO_TO_23; +extern const_float4 INDGEN[2]; + +ALIGNED(static const int sign_bits[4],16)={INT_MIN, INT_MIN, INT_MIN, INT_MIN}; +ALIGNED(static const int other_bits[4],16)={INT_MAX, INT_MAX, INT_MAX, INT_MAX}; +#define SIGN_BITS (*(__m128i *)sign_bits) +#define OTHER_BITS (*(__m128i *)other_bits) + + + +struct float4 { + float4() {}; + float4(const __m128 b) { m=b; }; + float4(const float &fval) { +#ifdef USE_INTRINSICS + m=_mm_load1_ps(&fval); +#elif defined(__GNUC__) + __asm__ ( "shufps $0,%0,%0\n":"=x" (m):"0" (fval) ); +#endif + }; + float4(const float &f1, const float &f2, const float &f3, const float &f4) + { v[0]=f1; v[1]=f2; v[2]=f3; v[3]=f4; }; + float4(const float4 &b) { m=b.m; }; + float4(const const_float4 &b) { m=((float4 *)&b)->m; }; + inline float4 operator +(const float4 &f) const { + register float4 rv; +#ifdef USE_INTRINSICS + rv.m=_mm_add_ps(m,f.m); +#elif defined(__GNUC__) + __asm__ ( "addps %2,%0" : "=x" (rv.m) : "0" (m), "xm" (f.m) ); +#endif + return rv; + }; + inline float4 operator -(const float4 &f) const { + register float4 rv; +#ifdef USE_INTRINSICS + rv.m=_mm_sub_ps(m,f.m); +#elif defined(__GNUC__) + __asm__ ( "subps %2,%0" : "=x" (rv.m) : "0" (m), "xm" (f.m) ); +#endif + return rv; + }; + inline float4 operator *(const float4 &f) const { + register float4 rv; +#ifdef USE_INTRINSICS + rv.m=_mm_mul_ps(m,f.m); +#elif defined(__GNUC__) + __asm__ ( "mulps %2,%0" : "=x" (rv.m) : "0" (m), "xm" (f.m) ); +#endif + return rv; + }; + inline float4 operator |(const __m128i &b) const { + register float4 rv; +#ifdef USE_INTRINSICS + rv.m=_mm_or_ps(*(__m128 *)&b,m); +#elif defined(__GNUC__) + __asm__ ( "orps %2,%0" : "=x" (rv.m) : "0" (b), "xm" (m)); +#endif + return rv; + }; + inline float4 operator &(const __m128i &b) const { + register float4 rv; +#ifdef USE_INTRINSICS + rv.m=_mm_and_ps(*(__m128 *)&b,m); +#elif defined(__GNUC__) + __asm__ ( "andps %2,%0" : "=x" (rv.m) : "0" (b), "xm" (m)); +#endif + return rv; + }; + inline float4 &operator =(const float4 &b) { + m=b.m; + return *this; + }; + inline float4 &operator *=(const float4 &b) { +#ifdef USE_INTRINSICS + m=_mm_mul_ps(m,b.m); +#elif defined(__GNUC__) + __asm__ ( "mulps %2,%0" : "=x" (m) : "0" (m), "xm" (b.m) ); +#endif + return *this; + } + inline float4 &operator +=(const float4 &b) { +#ifdef USE_INTRINSICS + m=_mm_add_ps(m,b.m); +#elif defined(__GNUC__) + __asm__ ( "addps %2,%0" : "=x" (m) : "0" (m), "xm" (b.m) ); +#endif + return *this; + } + inline float4 &operator -=(const float4 &b) { +#ifdef USE_INTRINSICS + m=_mm_sub_ps(m,b.m); +#elif defined(__GNUC__) + __asm__ ( "subps %2,%0" : "=x" (m) : "0" (m), "xm" (b.m) ); +#endif + return *this; + } + inline float4 &operator /=(const float4 &b) { +#ifdef USE_INTRINSICS + m=_mm_div_ps(m,b.m); +#elif defined(__GNUC__) + __asm__ ( "divps %2,%0" : "=x" (m) : "0" (m), "xm" (b.m) ); +#endif + return *this; + } + inline operator __m128() {return m;}; + inline operator __m128i() {return *(__m128i *)&m; }; + inline float4 abs() const { + // clear the sign bits + return *this & OTHER_BITS; + }; + + inline float4 sign() const { + // return the sign bits + return *this & SIGN_BITS; + }; + inline float4 round() const { + // add and subtract the largest exactly + // representable integer value of the same sign + register float4 s(sign()); + register float4 a(s | (float4)TWO_TO_23); + a=(*this+a)-a; + return a; + }; + inline float4 ceil() const { + return (*this+RECIP_TWO).round(); + } + inline float4 floor() const { + return (*this-RECIP_TWO).round(); + } + inline float4 mod(const float4 &x) const { + register float4 nx(*this*x.recip()); + nx-=nx.round(); // [-0.5,0.5) + nx*=x; // [-x/2,x/2) + return nx; + } + inline float4 round_pos() const { + return ((*this+TWO_TO_23)-TWO_TO_23); + }; + inline float4 round_neg() const { + return ((*this-TWO_TO_23)+TWO_TO_23); + }; + inline void sincos(float4 &s, float4 &c) const { + register float4 x(*this*RECIP_TWOPI); + x-=x.round(); + register float4 x2(x*x); + register float4 t1(x2*SS4+SS3); + register float4 t2(x2*CC3+CC2); + t1*=x2; + t2*=x2; + t1+=SS2; + t2+=CC1; + t1*=x2; + t2*=x2; + t1+=SS1; + c=t2+ONE; + s=t1*x; + } + inline float4 sin() const { + register float4 x(*this*RECIP_TWOPI); + x-=x.round(); + register float4 x2(x*x); + return ((((x2*SS4+SS3)*x2+SS2)*x2+SS1)*x); + } + inline float4 cos() const { + register float4 x(*this*RECIP_TWOPI); + x-=x.round(); + x*=x; + return (((x*CC3+CC2)*x+CC1)*x+ONE); + } + template + inline float4 shuffle(float4 b) const { +#ifdef USE_INTRINSICS + return _mm_shuffle_ps(m,b.m,_MM_SHUFFLE(p3,p2,p1,p0)); +#elif defined(__GNUC__) + register float4 rv; + __asm__ ( "shufps %3,%2,%0" : "=x" (rv) : "0" (m), "x" (b.m), "i" (p0 | (p1 << 2) | (p2<<4) | (p3 << 6)) ); + return rv; +#endif + } + inline float4 rsqrt() const { + } + inline float4 sqrt() const { + } + inline float4 recip() const { + } + union { + ALIGNED(__m128 m,16); + float v[4]; + float f; + }; +} ; + +struct const_float4 : public float4 { + public: + inline const_float4() : float4() {}; + inline const_float4(const __m128 b) : float4() { m=b; }; + inline const_float4(const float &fval) : float4() { + v[0]=fval; v[1]=fval; v[2]=fval; v[3]=fval; + } + inline const_float4(const float &f1, const float &f2, const float &f3, const float &f4) + { v[0]=f1; v[1]=f2; v[2]=f3; v[3]=f4; }; + inline const_float4(const float4 &b) { m=b.m; }; + inline operator float4() const { return *this; }; + inline operator __m128() {return m;}; + inline operator __m128i() {return *(__m128i *)&m; }; +}; + +#endif +#endif + diff --git a/client/vector/x86_ops.h b/client/vector/x86_ops.h new file mode 100644 index 0000000..a81ff34 --- /dev/null +++ b/client/vector/x86_ops.h @@ -0,0 +1,201 @@ +// Copyright (c) 1999-2006 Regents of the University of California +// +// FFTW: Copyright (c) 2003,2006 Matteo Frigo +// Copyright (c) 2003,2006 Massachusets Institute of Technology +// +// fft8g.[cpp,h]: Copyright (c) 1995-2001 Takya Ooura + +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) any later +// version. + +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with this program; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions +// as an alternative to FFTW and distribute a linked executable and +// source code. You must obey the GNU General Public License in all +// respects for all of the code used other than the FFT library itself. +// Any modification required to support these libraries must be distributed +// under the terms of this license. If you modify this program, you may extend +// this exception to your version of the program, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. Please be aware that FFTW is not covered by this exception, +// therefore you may not use FFTW in any derivative work so modified without +// permission of the authors of FFTW. + +#ifndef _X86_OPS_H_ +#define _X86_OPS_H_ + +#if defined(_M_AMD64) || defined(__x86_64__) +// Make sure we use MMX,SSE/2/3 on x86_64 +#ifndef USE_MMX +#define USE_MMX 1 +#ifndef __MMX__ +#define __MMX__ +#endif +#endif +#ifndef USE_3DNOW +#define USE_3DNOW 1 +#define __3DNOW__ 1 +#endif +#ifndef USE_SSE +#define USE_SSE 1 +#define __SSE__ 1 +#endif +#ifndef USE_SSE2 +#define USE_SSE2 1 +#define __SSE2__ 1 +#endif +#ifndef USE_SSE3 +#define USE_SSE3 1 +#define __SSE3__ 1 +#endif +#endif + +#if defined(__GNUC__) +#define ALIGN_ATTR(x) __attribute__((aligned(x))) +#define ALIGN_DECL(x) +#else +#define ALIGN_ATTR(x) +#define ALIGN_DECL(x) __declspec(align(x)) +#endif + +// How to declare an aligned variable. +#define ALIGNED(decl,x) \ + ALIGN_DECL(x) decl ALIGN_ATTR(x) + + + +#if defined (_WIN64) && defined (_M_AMD64) +#ifdef HAVE_EMMINTRIN_H +#ifdef USE_SSE2 +#include +#endif +#endif +#elif defined(__SSE__) || defined(USE_SSE) || defined(__SSE2__) +// Make sure MSC doesn't use slow emulations +#undef _MM_FUNCTIONALITY +#undef _MM2_FUNCTIONALITY +#ifdef HAVE_EMMINTRIN_H +#ifdef USE_SSE2 +#if (__GNUC__ < 4) || ((__GNUC__ > 3) && defined(__SSE2__)) +#include +#endif +#endif +#endif +#ifdef HAVE_XMMINTRIN_H +#include +#endif +#endif + + +// We will use the defines __SSE__, __SSE2__ and __SSE3__ +// GCC defines these based upon command line args. +#if defined(USE_MMX) && !defined(__MMX__) +#define __MMX__ 1 +#endif +#if defined(USE_SSE) && !defined(__SSE__) +#define __SSE__ 1 +#endif +#if defined(USE_SSE2) && !defined(__SSE2__) +#define __SSE2__ 1 +#endif +#if defined(USE_SSE3) && !defined(__SSE3__) +#define __SSE3__ 1 +#endif + +#if defined(__MMX__) +// MMX instructions/macros here. +#endif + +#if defined(__3DNOW__) + +// 3DNOW functions/macros here +#ifdef HAVE_MM3DNOW_H +#include +#else +// #warning No 3DNow header available... +#endif + +#endif + +#if defined(__SSE3__) +// PNI specific functions/macros here. +#endif + +#if defined(__SSE2__) +// SSE2 specific functions/macros here. +#ifdef _MSC_VER +typedef __m128d x86_m128d; +#else +typedef double x86_m128d __attribute__ ((mode(V2DF))) __attribute__((aligned(16))); +#endif +#endif + +#if defined(__SSE__) +// SSE specific functions/macros here. +#ifdef _MSC_VER +typedef __m128 x86_m128; +typedef __m128i x86_m128i; +#else +typedef float x86_m128 __attribute__ ((mode(V4SF))) __attribute__((aligned(16))); +typedef int x86_m128i __attribute__ ((mode(V4SI))) __attribute__((aligned(16))); +#endif + +static inline void prefetcht0(const void *v) { +#ifdef USE_INTRINSICS + _mm_prefetch((const char *)v,_MM_HINT_T0); +#elif defined(__GNUC__) + __asm__ volatile ( "prefetcht0 %0" : : "m" (*(const char *)v) ); +#endif +} + +static inline void prefetcht1(const void *v) { +#ifdef USE_INTRINSICS + _mm_prefetch((const char *)v,_MM_HINT_T1); +#elif defined(__GNUC__) + __asm__ volatile ( "prefetcht1 %0" : : "m" (*(const char *)v) ); +#endif +} + +static inline void prefetcht2(const void *v) { +#ifdef USE_INTRINSICS + _mm_prefetch((const char *)v,_MM_HINT_T2); +#elif defined(__GNUC__) + __asm__ volatile ( "prefetcht2 %0" : : "m" (*(const char *)v) ); +#endif +} + +static inline void prefetchnta(const void *v) { +#ifdef USE_INTRINSICS + _mm_prefetch((const char *)v,_MM_HINT_NTA); +#elif defined(__GNUC__) + __asm__ volatile ( "prefetchnta %0" : : "m" (*(const char *)v) ); +#endif +} + +#endif + +#ifndef __m128d +#define __m128d x86_m128d +#endif + +#ifndef __m128i +#define __m128i x86_m128i +#endif + +#ifndef __m128 +#define __m128 x86_m128 +#endif + +#endif diff --git a/client/win-sah_config.h b/client/win-sah_config.h new file mode 100644 index 0000000..02a0d95 --- /dev/null +++ b/client/win-sah_config.h @@ -0,0 +1,473 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +/* config.h. Generated by configure. */ + +#ifndef _SAH_WIN_CONFIG_H_ +#define _SAH_WIN_CONFIG_H_ + +#include "boinc_win.h" + + + +#ifdef __MINGW32__ +#include "seti_boinc_private.h" +#elif defined(_MSC_VER) +#include "win_build/seti_boinc_private.h" +#endif + +#ifdef _MSC_VER +#define HAVE_INTRIN_H 1 +#else +#define HAVE_IMMINTRIN_H 1 +#define HAVE_PMMINTRIN_H 1 +#endif +#define HAVE_XMMINTRIN_H 1 +#define HAVE_EMMINTRIN_H 1 +#define USE_INTRINSICS 1 +#define USE_SSE 1 +#define USE_SSE2 1 +#define USE_SSE3 1 +#define USE_AVX 1 + +/* Define to 1 if you have the _aligned_malloc() function */ +#ifdef _MSC_VER +#define HAVE__ALIGNED_MALLOC 1 +#endif + +/* Define to the typecast required for arg 2 of _mm256_maskstore_ps() */ +// TODO: Simply this mess. Should only need 1 #if and an #else +#if defined(_MSC_VER) +#define AVX_MASKSTORE_TYPECAST(x) static_cast<__m256i>(x) +#elif (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5) \ + || ((__GNUC__ == 4) && (__GNUC_MINOR__ == 5) && (__GNUC_PATCHLEVEL__ > 2)) \ + || ((__GNUC__ == 4) && (__GNUC_MINOR__ == 4) && (__GNUC_PATCHLEVEL__ > 5))) +#define AVX_MASKSTORE_TYPECAST(x) static_cast<__m256i>(x) +#elif defined(__GNUC__) +#define AVX_MASKSTORE_TYPECAST(x) static_cast<__m256>(x) +#else +#define AVX_MASKSTORE_TYPECAST(x) static_cast<__m256i>(x) +#endif + +// Deactivate AVX when it's definitely not supported. +#if defined(__GNUC__) && ( \ + (__GNUC__ < 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ < 4))) +#undef USE_AVX +#undef HAVE_IMMINTRIN_H +#endif + +/* Define to 1 if you have the alloca() function */ +#define HAVE_ALLOCA 1 + +/* Define to 1 if you have the atanf() function */ +#define HAVE_ATANF 1 + +/* Define to 1 if you have the `atexit' function. */ +#define HAVE_ATEXIT 1 + +/* Define to 1 if you have the `atoll' function. */ +#ifdef __MINGW32__ +#define HAVE_ATOLL 1 +#endif + +/* Define to 1 if the system has the type `bool'. */ +#define HAVE_BOOL 1 + +/* Define to 1 if you have the cosf() function */ +#define HAVE_COSF 1 + +/* Define to 1 if you have the header file. */ +/* #define HAVE_DIRENT_H 1 */ + +/* Define to 1 if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define to 1 if you have the `floor' function. */ +#define HAVE_FLOOR 1 + +/* Define to 1 if you have the `fork' function. */ +//#define HAVE_FORK 1 + +/* Define to 1 if you have the `getcwd' function. */ +#define HAVE_GETCWD 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_GLUT_GLUT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_GLUT_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_GLU_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_GL_GLUT_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_GL_GLU_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_GL_GL_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_GL_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_INTTYPES_H */ + +#ifdef __MINGW32__ +#define HAVE_INT32_T 1 +#define HAVE_INT64_T 1 +#endif + +#define HAVE__ISNAN 1 + +/* Define to 1 if you have the `aio' library (-laio). */ +//#define HAVE_LIBAIO 1 + +/* Define to 1 if you have the `dl' library (-ldl). */ +//#define HAVE_LIBDL 1 + +/* Define to 1 if you have the `elf' library (-lelf). */ +//#define HAVE_LIBELF 1 + +/* Define to 1 if you have the `fftw' library (-lfftw). */ +#define HAVE_LIBFFTW 1 + +/* Define to 1 if you have the `GL' library (-lGL). */ +#define HAVE_LIBGL 1 + +/* Define to 1 if you have the `ICE' library (-lICE). */ +//#define HAVE_LIBICE 1 + +/* Define to 1 if you have the `m' library (-lm). */ +#define HAVE_LIBM 1 + +/* Define to 1 if you have the `nsl' library (-lnsl). */ +//#define HAVE_LIBNSL 1 + +/* Define to 1 if you have the `rsaeuro' library (-lrsaeuro). */ +/* #undef HAVE_LIBRSAEURO */ + +/* Define to 1 if you have the `s4' library (-ls4). */ +/* #undef HAVE_LIBS4 */ + +/* Define to 1 if you have the `SM' library (-lSM). */ +//#define HAVE_LIBSM 1 + +/* Define to 1 if you have the `socket' library (-lsocket). */ +//#define HAVE_LIBSOCKET 1 + +/* Define to 1 if you have the `stdc++' library (-lstdc++). */ +//#define HAVE_LIBSTDC__ 1 + +/* Define to 1 if you have the `X11' library (-lX11). */ +//#define HAVE_LIBX11 1 + +/* Define to 1 if you have the `Xaw' library (-lXaw). */ +//#define HAVE_LIBXAW 1 + +/* Define to 1 if you have the `Xext' library (-lXext). */ +//#define HAVE_LIBXEXT 1 + +/* Define to 1 if you have the `Xmu' library (-lXmu). */ +//#define HAVE_LIBXMU 1 + +/* Define to 1 if you have the `Xt' library (-lXt). */ +/* #define HAVE_LIBXT 1 */ + +/* Define to 1 if you have the `z' library (-lz). */ +/* #define HAVE_LIBZ 1 */ + +/* Define to 1 if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* Define to 1 if long double works and has more range or precision than + double. */ +#define HAVE_LONG_DOUBLE 1 + +/* Define to 1 if the system has the type `long long'. */ +#ifdef __MINGW32__ +#define HAVE_LONG_LONG 1 +#endif + +/* Define to 1 if your system has a GNU libc compatible `malloc' function, and + to 0 otherwise. */ +#define HAVE_MALLOC 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MALLOC_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the `memset' function. */ +#define HAVE_MEMSET 1 + +/* Define to 1 if you have the `munmap' function. */ +/* #define HAVE_MUNMAP 1 */ + +/* Define if your C++ compiler supports namespaces */ +#define HAVE_NAMESPACES 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_OPENGL_GLUT_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_OPENGL_GLU_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_OPENGL_GL_H */ + +/* Define to 1 if you have the `putenv' function. */ +#define HAVE_PUTENV 1 + +/* Define to 1 if your system has a GNU libc compatible `realloc' function, + and to 0 otherwise. */ +#define HAVE_REALLOC 1 + +/* Define to 1 if you have the sinf() function */ +#define HAVE_SINF 1 + +/* Define to 1 if you have the sincosf() function */ +/* #undef HAVE_SINCOSF */ + +/* Define to 1 if you have the `sqrt' function. */ +#define HAVE_SQRT 1 + +/* Define to 1 if `stat' has the bug that it succeeds when given the + zero-length file name argument. */ +/* #undef HAVE_STAT_EMPTY_STRING_BUG */ + +#if ( _MSC_VER > 1300 ) || defined(__MINGW32__) + /* Define to 1 if the max template is in namespace std. */ + #define HAVE_STD_MAX 1 + + /* Define to 1 if the min template is in namespace std. */ + #define HAVE_STD_MIN 1 +#endif + +/* Define to 1 if the transform template is in namespace std. */ +#define HAVE_STD_TRANSFORM 1 + +/* Define to 1 if stdbool.h conforms to C99. */ +/* #undef HAVE_STDBOOL_H */ + +/* Define to 1 if you have the header file. */ +#ifdef __MINGW32__ +#define HAVE_STDINT_H 1 +#endif + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +#ifdef __MINGW32__ +#define HAVE_STRCASECMP 1 +#endif + +/* Define to 1 if you have the `strchr' function. */ +#define HAVE_STRCHR 1 + +/* Define to 1 if you have the `strftime' function. */ +#define HAVE_STRFTIME 1 + +/* Define to 1 if you have the header file. */ +/* #define HAVE_STRINGS_H 1 */ + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the `strstr' function. */ +#define HAVE_STRSTR 1 + +/* Define to 1 if `st_blocks' is member of `struct stat'. */ +/* #define HAVE_STRUCT_STAT_ST_BLOCKS 1 */ + +/* Define to 1 if your `struct stat' has `st_blocks'. Deprecated, use + `HAVE_STRUCT_STAT_ST_BLOCKS' instead. */ +/* #define HAVE_ST_BLOCKS 1 */ + +/* Define to 1 if you have the header file. */ +/* #define HAVE_SYS_IOCTL_H 1 */ + +/* Define to 1 if you have the header file. */ +/* #define HAVE_SYS_STATVFS_H 1 */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_TIME_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have that is POSIX.1 compatible. */ +/* #define HAVE_SYS_WAIT_H 1 */ + +/* Define to 1 if you have the header file. */ +/* #define HAVE_UNISTD_H 1 */ + +/* Define to 1 if you have the `vfork' function. */ +/* #define HAVE_VFORK 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_VFORK_H */ + +/* Define to 1 if `fork' works. */ +/* #define HAVE_WORKING_FORK 1 */ + +/* Define to 1 if `vfork' works. */ +/* #define HAVE_WORKING_VFORK 1 */ + +/* Define to 1 if the system has the type `_Bool'. */ +/* #undef HAVE__BOOL */ + +#ifndef __MINGW32__ + +/* Define to 1 if the system has the type `_int32'. */ +#define HAVE__INT32 1 + +/* Define to 1 if the system has the type `_int64'. */ +#define HAVE__INT64 1 + +#endif + +/* Define to 1 if `lstat' dereferences a symlink specified with a trailing + slash. */ +/* #undef LSTAT_FOLLOWS_SLASHED_SYMLINK */ + +/* Define to 1 if `major', `minor', and `makedev' are declared in . + */ +#define MAJOR_IN_MKDEV 1 + +/* Define to 1 if `major', `minor', and `makedev' are declared in + . */ +/* #undef MAJOR_IN_SYSMACROS */ + +/* Define for custom build identification in stderr */ + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT +#define PACKAGE_BUGREPORT "korpela@ssl.berkeley.edu" + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME +#define PACKAGE_NAME FILE_DESCRIPTION + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING +#define PACKAGE_STRING FILE_DESCRIPTION" "FILE_VERSION + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME +#define PACKAGE_TARNAME FILE_DESCRIPTION + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION +#define PACKAGE_VERSION FILE_VERSION + +#ifndef COMPILER_STRING +#ifdef __MINGW32__ +#define QUOTEME_(x) #x +#define QUOTEME(x) QUOTEME_(x) +#define COMPILER_STRING "DevC++/MinGW/g++ "\ + QUOTEME(__GNUC__) "."\ + QUOTEME(__GNUC_MINOR__) "."\ + QUOTEME(__GNUC_PATCHLEVEL__) +#elif defined(_MSC_VER) +#define COMPILER_STRING "Visual Studio 2005/Microsoft Visual C++ 8" +#else +#define COMPILER_STRING "Unknown Compiler" +#endif +#endif + +#ifndef CUSTOM_STRING +#define CUSTOM_STRING "setiathome_v7 "FILE_VERSION" "COMPILER_STRING +#endif + +/* The size of a `long double', as computed by sizeof. */ +#define SIZEOF_LONG_DOUBLE sizeof (long double) + +/* The size of a `long int', as computed by sizeof. */ +#define SIZEOF_LONG_INT 4 + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define to 1 if your declares `struct tm'. */ +/* #undef TM_IN_SYS_TIME */ + +/* Define to 1 if informix is installed */ +/* #undef USE_INFORMIX */ + +/* Define if MYSQL is installed */ +/* #undef USE_MYSQL */ + +/* SETI@home major version number */ +#define VERSION_MAJOR VER_MAJOR + +/* SETI@home minor version number */ +#define VERSION_MINOR VER_MINOR + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Define as `__inline' if that's what the C compiler calls it, or to nothing + if it is not supported. */ +#ifdef _MSC_VER +#undef inline +typedef ptrdiff_t ssize_t; +#endif + +/* Define to rpl_malloc if the replacement function should be used. */ +/* #undef malloc */ + +/* Define to `long' if does not define. */ +/* #undef off_t */ + +/* Define to `int' if does not define. */ +/* #undef pid_t */ + +/* Define to rpl_realloc if the replacement function should be used. */ +/* #undef realloc */ + +/* Define to `unsigned' if does not define. */ +/* #undef size_t */ + +/* Define as `fork' if `vfork' does not work. */ +/* #undef vfork */ + +#if defined(HAVE_LIBFFTW) +#define USE_FFTWF +#endif + +#if defined(USE_INFORMIX) && defined(USE_MYSQL) && defined(HAVE_NAMESPACES) +#define USE_NAMESPACES +#endif + +#endif diff --git a/client/win_build/DevCpp_MinGW4_4plus/seti_boinc4_4plus.dev b/client/win_build/DevCpp_MinGW4_4plus/seti_boinc4_4plus.dev new file mode 100644 index 0000000..23534b9 --- /dev/null +++ b/client/win_build/DevCpp_MinGW4_4plus/seti_boinc4_4plus.dev @@ -0,0 +1,1299 @@ +[Project] +FileName=seti_boinc4_4plus.dev +Name=seti_boinc4_4plus +UnitCount=125 +Type=0 +Ver=1 +ObjFiles= +Includes=Release;..;../..;../../..;../../../db;../../../../boinc;../../../../boinc/lib;../../../../boinc/api;../../../jpeglib;../../../image_libs;../../../glut;../../../vector_lib;. +Libs=Release +PrivateResource=seti_boinc_private.rc +ResourceIncludes= +MakeIncludes= +Compiler=-DUSE_ASMLIB_@@_-DWIN32_@@_-D_WIN32_@@_-D_MT_@@_-DNDEBUG_@@_-D_WINDOWS _@@_-DBOINC_@@_-DCLIENT_@@_-DNODB_@@_-D_CONSOLE_@@_-DBOINC_APP_GRAPHICS_@@_-DHAVE_STRCASECMP_@@_-DUSE_AVX_@@_-ffast-math_@@_-mtune=pentium-m_@@_-malign-double_@@_-mpreferred-stack-boundary=5_@@_-momit-leaf-frame-pointer_@@_-fstrict-aliasing _@@__@@_ +CppCompiler=-DUSE_ASMLIB_@@_-DWIN32_@@_-D_WIN32_@@_-D_MT_@@_-DNDEBUG_@@_-D_WINDOWS _@@_-DBOINC_@@_-DCLIENT_@@_-DNODB_@@_-D_CONSOLE_@@_-DBOINC_APP_GRAPHICS_@@_-DHAVE_STRCASECMP_@@_-DUSE_AVX_@@_-ffast-math_@@_-mtune=pentium-m_@@_-malign-double_@@_-mpreferred-stack-boundary=5_@@_-momit-leaf-frame-pointer_@@_-fstrict-aliasing _@@__@@_ +Linker=../libfftw3f.lib_@@_../../vector/asmlibm.lib_@@_ +IsCpp=1 +Icon=seti_boinc4_4plus.ico +ExeOutput=.\Release +ObjectOutput=.\obj +OverrideOutput=1 +OverrideOutputName=setiathome_6.93_windows_intelx86.exe +HostApplication= +Folders=fftw3,libboinc,libboinc/include,libboinc/src,libboincapi,libboincapi/include,libboincapi/src,libgraphics2,libgraphics2/include,libgraphics2/src,seti_boinc,seti_boinc/include,seti_boinc/src,setiboincdb,setiboincdb/include,setiboincdb/src +CommandLine= +UseCustomMakefile=0 +CustomMakefile= +IncludeVersionInfo=1 +SupportXPThemes=1 +CompilerSet=1 +CompilerSettings=0000001011010000000110 + +[Unit1] +FileName=..\..\worker.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=..\..\analyze.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=..\..\analyzeFuncs.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit4] +FileName=..\..\analyzeFuncs.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=..\..\analyzePoT.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit6] +FileName=..\..\analyzePoT.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit7] +FileName=..\..\analyzeReport.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit8] +FileName=..\..\analyzeReport.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit9] +FileName=..\..\chirpfft.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit10] +FileName=..\..\chirpfft.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit11] +FileName=..\..\fft8g.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit12] +FileName=..\..\fft8g.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit13] +FileName=..\..\gaussfit.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit14] +FileName=..\..\gaussfit.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit15] +FileName=..\..\gdata.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit16] +FileName=..\..\gdata.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit17] +FileName=..\..\lcgamm.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit18] +FileName=..\..\lcgamm.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit19] +FileName=..\..\main.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit20] +FileName=..\..\malloc_a.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit21] +FileName=..\..\malloc_a.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit22] +FileName=..\..\progress.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit23] +FileName=..\..\progress.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit24] +FileName=..\..\pulsefind.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit25] +FileName=..\..\pulsefind.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit26] +FileName=..\..\s_util.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit27] +FileName=..\..\s_util.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit31] +FileName=..\..\seti_header.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit32] +FileName=..\..\sincos.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit33] +FileName=..\..\spike.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit34] +FileName=..\..\spike.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit35] +FileName=..\..\timecvt.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit36] +FileName=..\..\timecvt.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit37] +FileName=..\..\sah_version.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit38] +FileName=..\..\sah_version.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit39] +FileName=..\..\win-sah_config.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit40] +FileName=..\..\worker.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit41] +FileName=..\..\..\db\track_mem.h +CompileCpp=1 +Folder=setiboincdb/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit42] +FileName=..\..\..\db\xml_util.h +CompileCpp=1 +Folder=setiboincdb/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit43] +FileName=..\..\..\db\db_table.h +CompileCpp=1 +Folder=setiboincdb/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit44] +FileName=..\..\..\db\sqlapi.h +CompileCpp=1 +Folder=setiboincdb/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[VersionInfo] +Major=6 +Minor=93 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName=Space Sciences Laboratory +FileVersion=6.93 +FileDescription=setiathome_v7 +InternalName=setiathome_v7 +LegalCopyright=Copyright 2011, Regents University of California +LegalTrademarks= +OriginalFilename= +ProductName=setiathome_v7 +ProductVersion=6.93 +AutoIncBuildNr=0 + +[Unit45] +FileName=..\..\..\db\sqlblob.h +CompileCpp=1 +Folder=setiboincdb/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit46] +FileName=..\..\..\db\sqldefs.h +CompileCpp=1 +Folder=setiboincdb/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit47] +FileName=..\..\..\db\sqlint8.h +CompileCpp=1 +Folder=setiboincdb/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit48] +FileName=..\..\..\db\sqlrow.h +CompileCpp=1 +Folder=setiboincdb/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit49] +FileName=..\..\..\db\xml_util.cpp +CompileCpp=1 +Folder=setiboincdb/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit50] +FileName=..\..\..\db\sqlblob.cpp +CompileCpp=1 +Folder=setiboincdb/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit51] +FileName=..\..\..\db\sqlint8.cpp +CompileCpp=1 +Folder=setiboincdb/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit52] +FileName=..\..\..\db\sqlrow.cpp +CompileCpp=1 +Folder=setiboincdb/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit60] +FileName=..\..\..\..\boinc\lib\mem_usage.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit63] +FileName=..\..\..\..\boinc\lib\parse.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit64] +FileName=..\..\..\..\boinc\lib\prefs.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit65] +FileName=..\..\..\..\boinc\lib\proxy_info.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit66] +FileName=..\..\..\..\boinc\lib\shmem.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit67] +FileName=..\..\..\..\boinc\lib\util.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit68] +FileName=..\..\..\..\boinc\lib\app_ipc.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit69] +FileName=..\..\..\..\boinc\lib\diagnostics.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit70] +FileName=..\..\..\..\boinc\lib\error_numbers.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit71] +FileName=..\..\..\..\boinc\lib\filesys.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit72] +FileName=..\..\..\..\boinc\lib\hostinfo.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit73] +FileName=..\..\..\..\boinc\lib\mem_usage.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit74] +FileName=..\..\..\..\boinc\lib\mfile.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit76] +FileName=..\..\..\..\boinc\lib\parse.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit77] +FileName=..\..\..\..\boinc\lib\std_fixes.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit78] +FileName=..\..\..\..\boinc\lib\boinc_win.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit79] +FileName=..\..\..\..\boinc\api\boinc_api.cpp +CompileCpp=1 +Folder=libboincapi/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit80] +FileName=..\..\..\..\boinc\api\graphics_data.cpp +CompileCpp=1 +Folder=libboincapi/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit81] +FileName=..\..\..\..\boinc\api\reduce_main.cpp +CompileCpp=1 +Folder=libboincapi/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit83] +FileName=..\..\..\..\boinc\api\texture.h +CompileCpp=1 +Folder=libboincapi/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit84] +FileName=..\..\..\..\boinc\api\boinc_api.h +CompileCpp=1 +Folder=libboincapi/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit86] +FileName=..\..\..\..\boinc\api\graphics_api.h +CompileCpp=1 +Folder=libboincapi/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit87] +FileName=..\..\..\..\boinc\api\graphics_data.h +CompileCpp=1 +Folder=libboincapi/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit90] +FileName=..\fftw3.h +CompileCpp=1 +Folder=fftw3 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit91] +FileName=..\..\..\db\schema_master.cpp +CompileCpp=1 +Folder=setiboincdb/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=1 +BuildCmd=$(CPP) -c ..\..\..\db\schema_master.cpp -o ./obj/schema_master.o $(CXXFLAGS) -Os + +[Unit92] +FileName=..\..\..\db\schema_master.h +CompileCpp=1 +Folder=setiboincdb/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit93] +FileName=..\..\..\..\boinc\version.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit94] +FileName=..\..\..\..\boinc\lib\stackwalker_win.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit95] +FileName=..\..\..\..\boinc\lib\diagnostics_win.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit96] +FileName=..\..\..\..\boinc\lib\diagnostics_win.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit100] +FileName=..\..\vector\sighandler.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit101] +FileName=..\..\vector\hires_timer.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit102] +FileName=..\..\vector\hires_timer.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit103] +FileName=..\..\vector\x86_float4.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit104] +FileName=..\..\vector\x86_ops.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit105] +FileName=..\..\..\..\boinc\lib\win_util.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit106] +FileName=..\..\..\..\boinc\lib\win_util.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit107] +FileName=..\..\..\..\boinc\lib\str_util.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit108] +FileName=..\..\..\..\boinc\lib\str_util.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit109] +FileName=..\..\vector\analyzeFuncs_fpu.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit110] +FileName=..\..\sah_gfx_main.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit111] +FileName=..\..\sah_gfx_main.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit112] +FileName=..\..\..\..\boinc\api\graphics2_util.cpp +CompileCpp=1 +Folder=libgraphics2/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit113] +FileName=..\..\..\..\boinc\api\graphics2.h +CompileCpp=1 +Folder=libgraphics2/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit114] +FileName=..\..\..\..\boinc\lib\url.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit115] +FileName=..\..\..\..\boinc\lib\coproc.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit116] +FileName=..\..\..\..\boinc\lib\coproc.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit118] +FileName=..\..\autocorr.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit122] +FileName=..\..\vector\analyzeFuncs_x86_64.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1010 +OverrideBuildCmd=1 +BuildCmd=$(CPP) -msse2 -DUSE_SSE -DUSE_SSE2 -c ../../vector/analyzeFuncs_x86_64.cpp -o ./obj/analyzeFuncs_x86_64.o $(CXXFLAGS) + +[Unit123] +FileName=..\..\vector\analyzeFuncs_sse2.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1010 +OverrideBuildCmd=1 +BuildCmd=$(CPP) -msse2 -DUSE_SSE -DUSE_SSE2 -c ../../vector/analyzeFuncs_sse2.cpp -o ./obj/analyzeFuncs_sse2.o $(CXXFLAGS) -march=pentium4 + +[Unit124] +FileName=..\..\vector\x86_float4.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1015 +OverrideBuildCmd=1 +BuildCmd=$(CPP) -msse -c ../../vector/x86_float4.cpp -o ./obj/x86_float4.o $(CXXFLAGS) + +[Unit75] +FileName=..\..\..\..\boinc\lib\miofile.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit82] +FileName=..\..\..\..\boinc\api\texture.cpp +CompileCpp=1 +Folder=libboincapi/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit88] +FileName=..\..\..\..\boinc\api\graphics_impl.h +CompileCpp=1 +Folder=libboincapi/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit89] +FileName=..\..\..\..\boinc\api\gutil.h +CompileCpp=1 +Folder=libboincapi/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit28] +FileName=..\..\seti.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit29] +FileName=..\..\seti.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit30] +FileName=..\..\seti_header.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit117] +FileName=..\..\..\..\boinc\lib\str_replace.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit98] +FileName=..\..\vector\analyzeFuncs_vector.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=1 +BuildCmd=$(CPP) $(CXXFLAGS) -DUSE_SSE -DUSE_SSE2 -DUSE_SSE3 -DUSE_3DNOW -c ../../vector/analyzeFuncs_vector.cpp -o ./obj/analyzeFuncs_vector.o + +[Unit99] +FileName=..\..\vector\analyzeFuncs_vector.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit57] +FileName=..\..\..\..\boinc\lib\hostinfo.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit58] +FileName=..\..\..\..\boinc\lib\md5.c +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit59] +FileName=..\..\..\..\boinc\lib\md5_file.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit61] +FileName=..\..\..\..\boinc\lib\mfile.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit62] +FileName=..\..\..\..\boinc\lib\miofile.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit85] +FileName=..\..\..\..\boinc\api\boinc_gl.h +CompileCpp=1 +Folder=libboincapi/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit97] +FileName=..\..\vector\analyzeFuncs_altivec.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit119] +FileName=..\..\autocorr.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit120] +FileName=..\..\vector\analyzeFuncs_avx.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=1 +BuildCmd=$(CPP) -mavx -c ..\..\vector\analyzeFuncs_avx.cpp -o ./obj/analyzeFuncs_avx.o $(CXXFLAGS) -march=nocona + +[Unit121] +FileName=..\..\vector\analyzeFuncs_sse3.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1005 +OverrideBuildCmd=1 +BuildCmd=$(CPP) -msse3 -DUSE_SSE -DUSE_SSE2 -DUSE_SSE3 -c ../../vector/analyzeFuncs_sse3.cpp -o ./obj/analyzeFuncs_sse3.o $(CXXFLAGS) -march=prescott + +[Unit53] +FileName=..\..\..\..\boinc\lib\util.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit54] +FileName=..\..\..\..\boinc\lib\app_ipc.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit55] +FileName=..\..\..\..\boinc\lib\diagnostics.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit56] +FileName=..\..\..\..\boinc\lib\filesys.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit125] +FileName=..\..\vector\analyzeFuncs_sse.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1015 +OverrideBuildCmd=1 +BuildCmd=$(CPP) -msse -DUSE_SSE -c ../../vector/analyzeFuncs_sse.cpp -o ./obj/analyzeFuncs_sse.o $(CXXFLAGS) -march=pentium3 + diff --git a/client/win_build/DevCpp_MinGW4_4plus/seti_boinc4_4plus.ico b/client/win_build/DevCpp_MinGW4_4plus/seti_boinc4_4plus.ico new file mode 100644 index 0000000000000000000000000000000000000000..5e7927af80deef1aaaa9d4c6e7cff8b12f533008 GIT binary patch literal 4710 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°g~<2u+#v&zw!rGaB6R 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%0D#%;}MU3=iih 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 literal 0 HcmV?d00001 diff --git a/client/win_build/Logo2.jpg b/client/win_build/Logo2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..00ce4a3b91107916f092acf715e81325a995cb14 GIT binary patch literal 16198 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 literal 0 HcmV?d00001 diff --git a/client/win_build/SAHjpeg.dev b/client/win_build/SAHjpeg.dev new file mode 100755 index 0000000..a2163d3 --- /dev/null +++ b/client/win_build/SAHjpeg.dev @@ -0,0 +1,2119 @@ +[Project] +FileName=SAHjpeg.dev +Name=SAHjpeglib +UnitCount=205 +Type=2 +Ver=1 +ObjFiles= +Includes=Release;..;../..;../../db;../../../boinc;../../../boinc/api;../../../boinc/incmore;../../../boinc/lib;../../jpeglib;../../image_libs;../../glut +Libs=Release +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler=--include ../../../boinc/version.h_@@_-DWIN32_@@_-D_WIN32_@@_-D_MT_@@_-DNDEBUG_@@_-D_WINDOWS _@@_-DBOINC_@@_-DCLIENT_@@_-DNODB_@@_-DBOINC_APP_GRAPHICS_@@_-D_CONSOLE_@@_-mtune=pentium-m_@@_-O3 _@@_-fomit-frame-pointer _@@_-malign-double _@@_-fstrict-aliasing _@@_-ffast-math_@@_ +CppCompiler=--include ../../../boinc/version.h_@@_-DWIN32_@@_-D_WIN32_@@_-D_MT_@@_-DNDEBUG_@@_-D_WINDOWS _@@_-DBOINC_@@_-DCLIENT_@@_-DNODB_@@_-DBOINC_APP_GRAPHICS_@@_-D_CONSOLE_@@_-mtune=pentium-m_@@_-O3 _@@_-fomit-frame-pointer _@@_-malign-double _@@_-fstrict-aliasing _@@_-ffast-math_@@_ +Linker=libfftw3f.lib_@@_G:/DEVCPP/lib/libglu32.a_@@_G:/DEVCPP/lib/libglaux.a_@@_G:/DEVCPP/lib/libopengl32.a_@@_G:/DEVCPP/lib/libwinmm.a_@@_ +IsCpp=1 +Icon= +ExeOutput=. +ObjectOutput=.\Release +OverrideOutput=1 +OverrideOutputName=jpeg.lib +HostApplication= +Folders=fftw3,glut,glut/include,glut/src,image_libs,image_libs/include,image_libs/src,jpeglib,jpeglib/include,jpeglib/src,libboinc,libboinc/include,libboinc/src,libboincapi,libboincapi/include,libboincapi/src,seti_boinc,seti_boinc/include,seti_boinc/src,setiboincdb,setiboincdb/include,setiboincdb/src +CommandLine= +UseCustomMakefile=0 +CustomMakefile= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=0 +CompilerSettings=0000001000001000000110 + +[Unit1] +FileName=..\worker.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=..\analyze.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=..\analyzeFuncs.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit4] +FileName=..\analyzeFuncs.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=..\analyzePoT.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit6] +FileName=..\analyzePoT.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit7] +FileName=..\analyzeReport.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit8] +FileName=..\analyzeReport.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit9] +FileName=..\chirpfft.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit10] +FileName=..\chirpfft.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit11] +FileName=..\fft8g.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit12] +FileName=..\fft8g.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit13] +FileName=..\gaussfit.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit14] +FileName=..\gaussfit.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit15] +FileName=..\gdata.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit16] +FileName=..\gdata.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit17] +FileName=..\lcgamm.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit18] +FileName=..\lcgamm.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit19] +FileName=..\main.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit20] +FileName=..\malloc_a.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit21] +FileName=..\malloc_a.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit22] +FileName=..\progress.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit23] +FileName=..\progress.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit24] +FileName=..\pulsefind.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit25] +FileName=..\pulsefind.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit26] +FileName=..\s_util.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit27] +FileName=..\s_util.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit28] +FileName=..\sah_gfx.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit29] +FileName=..\sah_gfx.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit30] +FileName=..\sah_gfx_base.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit31] +FileName=..\sah_gfx_base.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit32] +FileName=..\seti.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit33] +FileName=..\seti.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit34] +FileName=..\seti_header.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit35] +FileName=..\seti_header.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit36] +FileName=..\sincos.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit37] +FileName=..\spike.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit38] +FileName=..\spike.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit39] +FileName=..\timecvt.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit40] +FileName=..\timecvt.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit41] +FileName=..\win-sah_config.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit42] +FileName=..\worker.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit43] +FileName=..\..\db\track_mem.h +CompileCpp=1 +Folder=setiboincdb/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit44] +FileName=..\..\db\xml_util.h +CompileCpp=1 +Folder=setiboincdb/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[VersionInfo] +Major=0 +Minor=1 +Release=1 +Build=1 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 + +[Unit45] +FileName=..\..\db\db_table.h +CompileCpp=1 +Folder=setiboincdb/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit46] +FileName=..\..\db\sqlapi.h +CompileCpp=1 +Folder=setiboincdb/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit47] +FileName=..\..\db\sqlblob.h +CompileCpp=1 +Folder=setiboincdb/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit48] +FileName=..\..\db\sqldefs.h +CompileCpp=1 +Folder=setiboincdb/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit49] +FileName=..\..\db\sqlint8.h +CompileCpp=1 +Folder=setiboincdb/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit50] +FileName=..\..\db\sqlrow.h +CompileCpp=1 +Folder=setiboincdb/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit51] +FileName=..\..\db\xml_util.cpp +CompileCpp=1 +Folder=setiboincdb/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit52] +FileName=..\..\db\sqlblob.cpp +CompileCpp=1 +Folder=setiboincdb/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit53] +FileName=..\..\db\sqlint8.cpp +CompileCpp=1 +Folder=setiboincdb/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit54] +FileName=..\..\db\sqlrow.cpp +CompileCpp=1 +Folder=setiboincdb/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit55] +FileName=..\..\glut\win32_x11.h +CompileCpp=1 +Folder=glut/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit56] +FileName=..\..\glut\glut.h +CompileCpp=1 +Folder=glut/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit57] +FileName=..\..\glut\glutbitmap.h +CompileCpp=1 +Folder=glut/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit58] +FileName=..\..\glut\glutint.h +CompileCpp=1 +Folder=glut/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit59] +FileName=..\..\glut\glutstroke.h +CompileCpp=1 +Folder=glut/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit60] +FileName=..\..\glut\glutwin32.h +CompileCpp=1 +Folder=glut/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit61] +FileName=..\..\glut\stroke.h +CompileCpp=1 +Folder=glut/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit62] +FileName=..\..\glut\win32_glx.h +CompileCpp=1 +Folder=glut/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit63] +FileName=..\..\glut\win32_x11.c +CompileCpp=1 +Folder=glut/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit64] +FileName=..\..\glut\glut_roman.c +CompileCpp=1 +Folder=glut/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit65] +FileName=..\..\glut\glut_stroke.c +CompileCpp=1 +Folder=glut/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit66] +FileName=..\..\glut\glut_swidth.c +CompileCpp=1 +Folder=glut/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit67] +FileName=..\..\glut\win32_glx.c +CompileCpp=1 +Folder=glut/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit68] +FileName=..\..\glut\win32_util.c +CompileCpp=1 +Folder=glut/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit69] +FileName=..\..\image_libs\bmplib.h +CompileCpp=1 +Folder=image_libs/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit70] +FileName=..\..\image_libs\tgalib.h +CompileCpp=1 +Folder=image_libs/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit71] +FileName=..\..\image_libs\bmplib.cpp +CompileCpp=1 +Folder=image_libs/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit72] +FileName=..\..\image_libs\tgalib.cpp +CompileCpp=1 +Folder=image_libs/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit73] +FileName=..\..\jpeglib\jerror.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit74] +FileName=..\..\jpeglib\jinclude.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit75] +FileName=..\..\jpeglib\jmemsys.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit76] +FileName=..\..\jpeglib\jmorecfg.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit77] +FileName=..\..\jpeglib\jpegint.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit78] +FileName=..\..\jpeglib\jpeglib.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit79] +FileName=..\..\jpeglib\jversion.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit80] +FileName=..\..\jpeglib\cderror.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit81] +FileName=..\..\jpeglib\cdjpeg.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit82] +FileName=..\..\jpeglib\jchuff.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit83] +FileName=..\..\jpeglib\jconfig.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit84] +FileName=..\..\jpeglib\jdct.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit85] +FileName=..\..\jpeglib\jdhuff.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit86] +FileName=..\..\jpeglib\rdtarga.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit87] +FileName=..\..\jpeglib\jcapimin.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit88] +FileName=..\..\jpeglib\jcapistd.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit89] +FileName=..\..\jpeglib\jccoefct.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit90] +FileName=..\..\jpeglib\jccolor.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit91] +FileName=..\..\jpeglib\jcdctmgr.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit92] +FileName=..\..\jpeglib\jchuff.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit93] +FileName=..\..\jpeglib\jcinit.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit94] +FileName=..\..\jpeglib\jcmainct.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit95] +FileName=..\..\jpeglib\jcmarker.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit96] +FileName=..\..\jpeglib\jcmaster.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit97] +FileName=..\..\jpeglib\jcomapi.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit98] +FileName=..\..\jpeglib\jcparam.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit99] +FileName=..\..\jpeglib\jcphuff.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit100] +FileName=..\..\jpeglib\jcprepct.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit101] +FileName=..\..\jpeglib\jcsample.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit102] +FileName=..\..\jpeglib\jctrans.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit103] +FileName=..\..\jpeglib\jdapimin.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit104] +FileName=..\..\jpeglib\jdapistd.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit105] +FileName=..\..\jpeglib\jdatadst.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit106] +FileName=..\..\jpeglib\jdatasrc.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit107] +FileName=..\..\jpeglib\jdcoefct.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit108] +FileName=..\..\jpeglib\jdcolor.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit109] +FileName=..\..\jpeglib\jddctmgr.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit110] +FileName=..\..\jpeglib\jdhuff.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit111] +FileName=..\..\jpeglib\jdinput.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit112] +FileName=..\..\jpeglib\jdmainct.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit113] +FileName=..\..\jpeglib\jdmarker.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit114] +FileName=..\..\jpeglib\jdmaster.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit115] +FileName=..\..\jpeglib\jdmerge.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit116] +FileName=..\..\jpeglib\jdphuff.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit117] +FileName=..\..\jpeglib\jdpostct.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit118] +FileName=..\..\jpeglib\jdsample.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit119] +FileName=..\..\jpeglib\jdtrans.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit120] +FileName=..\..\jpeglib\jerror.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit121] +FileName=..\..\jpeglib\jfdctflt.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit122] +FileName=..\..\jpeglib\jfdctfst.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit123] +FileName=..\..\jpeglib\jfdctint.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit124] +FileName=..\..\jpeglib\jidctflt.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit125] +FileName=..\..\jpeglib\jidctfst.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit126] +FileName=..\..\jpeglib\jidctint.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit127] +FileName=..\..\jpeglib\jidctred.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit128] +FileName=..\..\jpeglib\jmemmgr.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit129] +FileName=..\..\jpeglib\jmemnobs.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit130] +FileName=..\..\jpeglib\jquant1.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit131] +FileName=..\..\jpeglib\jquant2.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit132] +FileName=..\..\jpeglib\jutils.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit133] +FileName=..\..\jpeglib\rdbmp.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit134] +FileName=..\..\jpeglib\rdcolmap.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit135] +FileName=..\..\jpeglib\rdgif.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit136] +FileName=..\..\jpeglib\rdppm.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit137] +FileName=..\..\jpeglib\rdrle.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit138] +FileName=..\..\jpeglib\rdswitch.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit139] +FileName=..\..\..\boinc\lib\util.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit140] +FileName=..\..\..\boinc\lib\app_ipc.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit141] +FileName=..\..\..\boinc\lib\diagnostics.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit143] +FileName=..\..\..\boinc\lib\hostinfo.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit144] +FileName=..\..\..\boinc\lib\md5.c +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit145] +FileName=..\..\..\boinc\lib\md5_file.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit146] +FileName=..\..\..\boinc\lib\mem_usage.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit147] +FileName=..\..\..\boinc\lib\mfile.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit148] +FileName=..\..\..\boinc\lib\miofile.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit149] +FileName=..\..\..\boinc\lib\parse.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit150] +FileName=..\..\..\boinc\lib\prefs.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit151] +FileName=..\..\..\boinc\lib\proxy_info.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit152] +FileName=..\..\..\boinc\lib\shmem.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit153] +FileName=..\..\..\boinc\lib\util.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit154] +FileName=..\..\..\boinc\lib\app_ipc.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit155] +FileName=..\..\..\boinc\lib\diagnostics.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit156] +FileName=..\..\..\boinc\lib\error_numbers.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit157] +FileName=..\..\..\boinc\lib\filesys.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit158] +FileName=..\..\..\boinc\lib\hostinfo.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit159] +FileName=..\..\..\boinc\lib\mem_usage.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit160] +FileName=..\..\..\boinc\lib\mfile.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit161] +FileName=..\..\..\boinc\lib\miofile.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit162] +FileName=..\..\..\boinc\lib\parse.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit163] +FileName=..\..\..\boinc\lib\std_fixes.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit164] +FileName=..\..\..\boinc\lib\boinc_win.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit165] +FileName=..\..\..\boinc\api\windows_opengl.cpp +CompileCpp=1 +Folder=libboincapi/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit166] +FileName=..\..\..\boinc\api\boinc_api.cpp +CompileCpp=1 +Folder=libboincapi/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit167] +FileName=..\..\..\boinc\api\graphics_api.cpp +CompileCpp=1 +Folder=libboincapi/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit168] +FileName=..\..\..\boinc\api\graphics_data.cpp +CompileCpp=1 +Folder=libboincapi/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit169] +FileName=..\..\..\boinc\api\graphics_impl.cpp +CompileCpp=1 +Folder=libboincapi/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit170] +FileName=..\..\..\boinc\api\gutil.cpp +CompileCpp=1 +Folder=libboincapi/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit171] +FileName=..\..\..\boinc\api\reduce_lib.cpp +CompileCpp=1 +Folder=libboincapi/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit172] +FileName=..\..\..\boinc\api\reduce_main.cpp +CompileCpp=1 +Folder=libboincapi/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit173] +FileName=..\..\..\boinc\api\texture.cpp +CompileCpp=1 +Folder=libboincapi/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit174] +FileName=..\..\..\boinc\api\texture.h +CompileCpp=1 +Folder=libboincapi/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit175] +FileName=..\..\..\boinc\api\boinc_api.h +CompileCpp=1 +Folder=libboincapi/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit176] +FileName=..\..\..\boinc\api\boinc_gl.h +CompileCpp=1 +Folder=libboincapi/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit177] +FileName=..\..\..\boinc\api\graphics_api.h +CompileCpp=1 +Folder=libboincapi/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit178] +FileName=..\..\..\boinc\api\graphics_data.h +CompileCpp=1 +Folder=libboincapi/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit179] +FileName=..\..\..\boinc\api\graphics_impl.h +CompileCpp=1 +Folder=libboincapi/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit180] +FileName=..\..\..\boinc\api\gutil.h +CompileCpp=1 +Folder=libboincapi/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit181] +FileName=fftw3.h +CompileCpp=1 +Folder=fftw3 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit182] +FileName=..\..\db\schema_master.cpp +CompileCpp=1 +Folder=setiboincdb/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit183] +FileName=..\..\db\schema_master.h +CompileCpp=1 +Folder=setiboincdb/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit184] +FileName=..\..\..\boinc\api\gutil_text.cpp +CompileCpp=1 +Folder=libboincapi/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit185] +FileName=..\..\..\boinc\api\tgalib.h +CompileCpp=1 +Folder=libboincapi/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit186] +FileName=..\..\..\boinc\version.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit142] +FileName=..\..\..\boinc\lib\filesys.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit187] +FileName=..\..\..\boinc\lib\stackwalker_win.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit188] +FileName=..\..\..\boinc\lib\diagnostics_win.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit189] +FileName=..\..\..\boinc\lib\diagnostics_win.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit190] +FileName=..\vector\analyzeFuncs_altivec.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit191] +FileName=..\vector\analyzeFuncs_vector.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit192] +FileName=..\vector\analyzeFuncs_vector.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit193] +FileName=..\vector\sighandler.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit194] +FileName=..\vector\hires_timer.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit195] +FileName=..\vector\hires_timer.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit196] +FileName=..\vector\analyzeFuncs_x86_64.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=1 +BuildCmd=$(CPP) -msse2 -mpreferred-stack-boundary=5 -malign-double -DUSE_SSE -DUSE_SSE2 -c ../vector/analyzeFuncs_x86_64.cpp -o ./Release/analyzeFuncs_x86_64.o $(CXXFLAGS) + +[Unit197] +FileName=..\vector\analyzeFuncs_sse.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=1 +BuildCmd=$(CPP) -msse -DUSE_SSE -c ../vector/analyzeFuncs_sse.cpp -o ./Release/analyzeFuncs_sse.o $(CXXFLAGS) + +[Unit198] +FileName=..\vector\x86_float4.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=1 +BuildCmd=$(CPP) -msse -c ../vector/x86_float4.cpp -o ./Release/x86_float4.o $(CXXFLAGS) + +[Unit199] +FileName=..\vector\x86_float4.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit204] +FileName=..\..\..\boinc\lib\str_util.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit205] +FileName=..\vector\AKfoldSSE.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=1 +BuildCmd=$(CPP) -msse -DUSE_SSE -c ../vector/AKfoldSSE.cpp -o ./Release/AKfoldSSE.o $(CXXFLAGS) + +[Unit200] +FileName=..\vector\x86_ops.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit201] +FileName=..\..\..\boinc\lib\win_util.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit202] +FileName=..\..\..\boinc\lib\win_util.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit203] +FileName=..\..\..\boinc\lib\str_util.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit206] +FileName=..\..\..\boinc\lib\str_util.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit207] +FileName=..\vector\AKfoldSSE.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=0 +Priority=1000 +OverrideBuildCmd=1 +BuildCmd=$(CPP) -msse -DUSE_SSE -c ../vector/AKfoldSSE.cpp -o ./Release/AKfoldSSE.o $(CXXFLAGS) + diff --git a/client/win_build/SETI_app.ico b/client/win_build/SETI_app.ico new file mode 100644 index 0000000000000000000000000000000000000000..5e7927af80deef1aaaa9d4c6e7cff8b12f533008 GIT binary patch literal 4710 zcmeI0K}Z}|7{|Zeops%H5_Q*wp3EY9Fx#BGDWZ$4*0n-mSucf3O}qC^kWwAwA{bMDw)!+pe7c`UAZ~_)UBsU&VLuSNN%9vo#qXugT0zO_rBy zvbjnAy5PIvd*S=w2jR!yr{HJdEAVUZTkr?)Irw4tGW<0B0{jYm6@D9j5B?DT2>t|q z2>vGgJp3yB4*VwlP-Q6#OiF1%3^F3;qB;2R{s7hM$ICfM0>H z!f(Ux!5_jO!John!QX_RhhK%?fqw;m3eS6h^;}~;*I3Ur)^iSi7`_ZY4Zi@t0$+vS zhTnrfgg=5mf$xIvhVO;%gCB$+gP($*g|EP`!EeDIz_+xtNHUp}YuB#HjT<+lzrSBb zM@OYpD#@)|xA<<&$lTnVR4Ns@bLWoSyLV4`vB=}ck7a*Qb&U`4)$B9xftV8ybOi`1U!B3dlcWz58-TrNvfTn0Fr;{yW&P4R&# z_$f=EFBhlOie)?gKylJPl<=I9hIw|(Ns$o|O3chZNqe$+ek2yPamN`U+PHo{_5mt= z&t~vE9_&XFrs3O%-;ex(-#%Q=R5LlVnP^v=N5KQv&Bd6rpL~a zk3FNmFcJ=HRoBC3450DP3I!V3Lg6;?n09MkZElTz0=%b3FTlpvO}oc~()a`$urWWr z9vA@e{F6_8dt~%&W`j0`iQ5g^w1fGZ?mxEAv=fB|yeNtTwDhv3~#v1XM-yO4Y$JH^K;+=KCfWB7s zHqe<0026l*Grvpa#+<0z*_rA(1NhUOt6KS`cCn??R{}ona2CfMEv&T=4~KjMh;umc zpd%F4c)%jo5t`KLwACkkffI@7Cy*!3>(dcOKTU?dy*_^^!~;l20y(wLf3<;|pG;2k z0CoLURoRH0-*lYSJ27ib1Jw1QP}INr2zLN~i9H~y~aa?<>(KJ`9p(wh{rJk8=vM~u|;p-+Z`$H)5D z#p&2<*Bj9JlLj + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/win_build/VS2008/glut.vcproj b/client/win_build/VS2008/glut.vcproj new file mode 100644 index 0000000..dc73e5c --- /dev/null +++ b/client/win_build/VS2008/glut.vcproj @@ -0,0 +1,455 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/win_build/VS2008/image_libs.vcproj b/client/win_build/VS2008/image_libs.vcproj new file mode 100644 index 0000000..ef49e70 --- /dev/null +++ b/client/win_build/VS2008/image_libs.vcproj @@ -0,0 +1,317 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/win_build/VS2008/jpeglib.vcproj b/client/win_build/VS2008/jpeglib.vcproj new file mode 100644 index 0000000..48d5b06 --- /dev/null +++ b/client/win_build/VS2008/jpeglib.vcproj @@ -0,0 +1,571 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/win_build/VS2008/seti_boinc.sln b/client/win_build/VS2008/seti_boinc.sln new file mode 100644 index 0000000..00e9939 --- /dev/null +++ b/client/win_build/VS2008/seti_boinc.sln @@ -0,0 +1,124 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "seti_boinc", "seti_boinc.vcproj", "{EE96AAE0-7D9F-48AA-8ECD-7EECED30289C}" + ProjectSection(ProjectDependencies) = postProject + {7E3EB322-3341-4821-90C3-EBD6E0D46D57} = {7E3EB322-3341-4821-90C3-EBD6E0D46D57} + {814EBFD3-3CE6-4933-A580-C1FE3147ACB4} = {814EBFD3-3CE6-4933-A580-C1FE3147ACB4} + {07BDA8F7-4AAF-4A3B-B96E-EA72A143C5AE} = {07BDA8F7-4AAF-4A3B-B96E-EA72A143C5AE} + {B00664BD-71EB-46C1-957E-CD851418D395} = {B00664BD-71EB-46C1-957E-CD851418D395} + {D3D21F11-A7E7-4EA2-8518-E24695133BFF} = {D3D21F11-A7E7-4EA2-8518-E24695133BFF} + {C4165626-F68F-4F66-A126-3B82DDBB7480} = {C4165626-F68F-4F66-A126-3B82DDBB7480} + {5F065EAC-B881-4E9A-9E34-7A21D7A01D98} = {5F065EAC-B881-4E9A-9E34-7A21D7A01D98} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "image_libs", "image_libs.vcproj", "{D3D21F11-A7E7-4EA2-8518-E24695133BFF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jpeglib", "jpeglib.vcproj", "{5F065EAC-B881-4E9A-9E34-7A21D7A01D98}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "setiboincdb", "setiboincdb.vcproj", "{7E3EB322-3341-4821-90C3-EBD6E0D46D57}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "glut", "glut.vcproj", "{C4165626-F68F-4F66-A126-3B82DDBB7480}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "seti_graphics", "seti_graphics.vcproj", "{3CF31288-A44D-4C78-A3AA-B05B6E32DF11}" + ProjectSection(ProjectDependencies) = postProject + {07BDA8F7-4AAF-4A3B-B96E-EA72A143C5AE} = {07BDA8F7-4AAF-4A3B-B96E-EA72A143C5AE} + {B00664BD-71EB-46C1-957E-CD851418D395} = {B00664BD-71EB-46C1-957E-CD851418D395} + {D3D21F11-A7E7-4EA2-8518-E24695133BFF} = {D3D21F11-A7E7-4EA2-8518-E24695133BFF} + {7E3EB322-3341-4821-90C3-EBD6E0D46D57} = {7E3EB322-3341-4821-90C3-EBD6E0D46D57} + {814EBFD3-3CE6-4933-A580-C1FE3147ACB4} = {814EBFD3-3CE6-4933-A580-C1FE3147ACB4} + {5F065EAC-B881-4E9A-9E34-7A21D7A01D98} = {5F065EAC-B881-4E9A-9E34-7A21D7A01D98} + {EE96AAE0-7D9F-48AA-8ECD-7EECED30289C} = {EE96AAE0-7D9F-48AA-8ECD-7EECED30289C} + {C4165626-F68F-4F66-A126-3B82DDBB7480} = {C4165626-F68F-4F66-A126-3B82DDBB7480} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libboinc_staticcrt", "..\..\..\..\boinc\win_build\libboinc_staticcrt.vcproj", "{B00664BD-71EB-46C1-957E-CD851418D395}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libboincapi_staticcrt", "..\..\..\..\boinc\win_build\libboincapi_staticcrt.vcproj", "{07BDA8F7-4AAF-4A3B-B96E-EA72A143C5AE}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libgraphics2", "..\..\..\..\boinc\win_build\libgraphics2.vcproj", "{814EBFD3-3CE6-4933-A580-C1FE3147ACB4}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {EE96AAE0-7D9F-48AA-8ECD-7EECED30289C}.Debug|Win32.ActiveCfg = Debug|Win32 + {EE96AAE0-7D9F-48AA-8ECD-7EECED30289C}.Debug|Win32.Build.0 = Debug|Win32 + {EE96AAE0-7D9F-48AA-8ECD-7EECED30289C}.Debug|x64.ActiveCfg = Debug|x64 + {EE96AAE0-7D9F-48AA-8ECD-7EECED30289C}.Debug|x64.Build.0 = Debug|x64 + {EE96AAE0-7D9F-48AA-8ECD-7EECED30289C}.Release|Win32.ActiveCfg = Release|Win32 + {EE96AAE0-7D9F-48AA-8ECD-7EECED30289C}.Release|Win32.Build.0 = Release|Win32 + {EE96AAE0-7D9F-48AA-8ECD-7EECED30289C}.Release|x64.ActiveCfg = Release|x64 + {EE96AAE0-7D9F-48AA-8ECD-7EECED30289C}.Release|x64.Build.0 = Release|x64 + {D3D21F11-A7E7-4EA2-8518-E24695133BFF}.Debug|Win32.ActiveCfg = Debug|Win32 + {D3D21F11-A7E7-4EA2-8518-E24695133BFF}.Debug|Win32.Build.0 = Debug|Win32 + {D3D21F11-A7E7-4EA2-8518-E24695133BFF}.Debug|x64.ActiveCfg = Debug|x64 + {D3D21F11-A7E7-4EA2-8518-E24695133BFF}.Debug|x64.Build.0 = Debug|x64 + {D3D21F11-A7E7-4EA2-8518-E24695133BFF}.Release|Win32.ActiveCfg = Release|Win32 + {D3D21F11-A7E7-4EA2-8518-E24695133BFF}.Release|Win32.Build.0 = Release|Win32 + {D3D21F11-A7E7-4EA2-8518-E24695133BFF}.Release|x64.ActiveCfg = Release|x64 + {D3D21F11-A7E7-4EA2-8518-E24695133BFF}.Release|x64.Build.0 = Release|x64 + {5F065EAC-B881-4E9A-9E34-7A21D7A01D98}.Debug|Win32.ActiveCfg = Debug|Win32 + {5F065EAC-B881-4E9A-9E34-7A21D7A01D98}.Debug|Win32.Build.0 = Debug|Win32 + {5F065EAC-B881-4E9A-9E34-7A21D7A01D98}.Debug|x64.ActiveCfg = Debug|x64 + {5F065EAC-B881-4E9A-9E34-7A21D7A01D98}.Debug|x64.Build.0 = Debug|x64 + {5F065EAC-B881-4E9A-9E34-7A21D7A01D98}.Release|Win32.ActiveCfg = Release|Win32 + {5F065EAC-B881-4E9A-9E34-7A21D7A01D98}.Release|Win32.Build.0 = Release|Win32 + {5F065EAC-B881-4E9A-9E34-7A21D7A01D98}.Release|x64.ActiveCfg = Release|x64 + {5F065EAC-B881-4E9A-9E34-7A21D7A01D98}.Release|x64.Build.0 = Release|x64 + {7E3EB322-3341-4821-90C3-EBD6E0D46D57}.Debug|Win32.ActiveCfg = Debug|Win32 + {7E3EB322-3341-4821-90C3-EBD6E0D46D57}.Debug|Win32.Build.0 = Debug|Win32 + {7E3EB322-3341-4821-90C3-EBD6E0D46D57}.Debug|x64.ActiveCfg = Debug|x64 + {7E3EB322-3341-4821-90C3-EBD6E0D46D57}.Debug|x64.Build.0 = Debug|x64 + {7E3EB322-3341-4821-90C3-EBD6E0D46D57}.Release|Win32.ActiveCfg = Release|Win32 + {7E3EB322-3341-4821-90C3-EBD6E0D46D57}.Release|Win32.Build.0 = Release|Win32 + {7E3EB322-3341-4821-90C3-EBD6E0D46D57}.Release|x64.ActiveCfg = Release|x64 + {7E3EB322-3341-4821-90C3-EBD6E0D46D57}.Release|x64.Build.0 = Release|x64 + {C4165626-F68F-4F66-A126-3B82DDBB7480}.Debug|Win32.ActiveCfg = Debug|Win32 + {C4165626-F68F-4F66-A126-3B82DDBB7480}.Debug|Win32.Build.0 = Debug|Win32 + {C4165626-F68F-4F66-A126-3B82DDBB7480}.Debug|x64.ActiveCfg = Debug|x64 + {C4165626-F68F-4F66-A126-3B82DDBB7480}.Debug|x64.Build.0 = Debug|x64 + {C4165626-F68F-4F66-A126-3B82DDBB7480}.Release|Win32.ActiveCfg = Release|Win32 + {C4165626-F68F-4F66-A126-3B82DDBB7480}.Release|Win32.Build.0 = Release|Win32 + {C4165626-F68F-4F66-A126-3B82DDBB7480}.Release|x64.ActiveCfg = Release|x64 + {C4165626-F68F-4F66-A126-3B82DDBB7480}.Release|x64.Build.0 = Release|x64 + {3CF31288-A44D-4C78-A3AA-B05B6E32DF11}.Debug|Win32.ActiveCfg = Debug|Win32 + {3CF31288-A44D-4C78-A3AA-B05B6E32DF11}.Debug|Win32.Build.0 = Debug|Win32 + {3CF31288-A44D-4C78-A3AA-B05B6E32DF11}.Debug|x64.ActiveCfg = Debug|x64 + {3CF31288-A44D-4C78-A3AA-B05B6E32DF11}.Debug|x64.Build.0 = Debug|x64 + {3CF31288-A44D-4C78-A3AA-B05B6E32DF11}.Release|Win32.ActiveCfg = Release|Win32 + {3CF31288-A44D-4C78-A3AA-B05B6E32DF11}.Release|Win32.Build.0 = Release|Win32 + {3CF31288-A44D-4C78-A3AA-B05B6E32DF11}.Release|x64.ActiveCfg = Release|x64 + {3CF31288-A44D-4C78-A3AA-B05B6E32DF11}.Release|x64.Build.0 = Release|x64 + {B00664BD-71EB-46C1-957E-CD851418D395}.Debug|Win32.ActiveCfg = Debug|Win32 + {B00664BD-71EB-46C1-957E-CD851418D395}.Debug|Win32.Build.0 = Debug|Win32 + {B00664BD-71EB-46C1-957E-CD851418D395}.Debug|x64.ActiveCfg = Debug|x64 + {B00664BD-71EB-46C1-957E-CD851418D395}.Debug|x64.Build.0 = Debug|x64 + {B00664BD-71EB-46C1-957E-CD851418D395}.Release|Win32.ActiveCfg = Release|Win32 + {B00664BD-71EB-46C1-957E-CD851418D395}.Release|Win32.Build.0 = Release|Win32 + {B00664BD-71EB-46C1-957E-CD851418D395}.Release|x64.ActiveCfg = Release|x64 + {B00664BD-71EB-46C1-957E-CD851418D395}.Release|x64.Build.0 = Release|x64 + {07BDA8F7-4AAF-4A3B-B96E-EA72A143C5AE}.Debug|Win32.ActiveCfg = Debug|Win32 + {07BDA8F7-4AAF-4A3B-B96E-EA72A143C5AE}.Debug|Win32.Build.0 = Debug|Win32 + {07BDA8F7-4AAF-4A3B-B96E-EA72A143C5AE}.Debug|x64.ActiveCfg = Debug|x64 + {07BDA8F7-4AAF-4A3B-B96E-EA72A143C5AE}.Debug|x64.Build.0 = Debug|x64 + {07BDA8F7-4AAF-4A3B-B96E-EA72A143C5AE}.Release|Win32.ActiveCfg = Release|Win32 + {07BDA8F7-4AAF-4A3B-B96E-EA72A143C5AE}.Release|Win32.Build.0 = Release|Win32 + {07BDA8F7-4AAF-4A3B-B96E-EA72A143C5AE}.Release|x64.ActiveCfg = Release|x64 + {07BDA8F7-4AAF-4A3B-B96E-EA72A143C5AE}.Release|x64.Build.0 = Release|x64 + {814EBFD3-3CE6-4933-A580-C1FE3147ACB4}.Debug|Win32.ActiveCfg = Debug|Win32 + {814EBFD3-3CE6-4933-A580-C1FE3147ACB4}.Debug|Win32.Build.0 = Debug|Win32 + {814EBFD3-3CE6-4933-A580-C1FE3147ACB4}.Debug|x64.ActiveCfg = Debug|x64 + {814EBFD3-3CE6-4933-A580-C1FE3147ACB4}.Debug|x64.Build.0 = Debug|x64 + {814EBFD3-3CE6-4933-A580-C1FE3147ACB4}.Release|Win32.ActiveCfg = Release|Win32 + {814EBFD3-3CE6-4933-A580-C1FE3147ACB4}.Release|Win32.Build.0 = Release|Win32 + {814EBFD3-3CE6-4933-A580-C1FE3147ACB4}.Release|x64.ActiveCfg = Release|x64 + {814EBFD3-3CE6-4933-A580-C1FE3147ACB4}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/client/win_build/VS2008/seti_boinc.vcproj b/client/win_build/VS2008/seti_boinc.vcproj new file mode 100644 index 0000000..075c083 --- /dev/null +++ b/client/win_build/VS2008/seti_boinc.vcproj @@ -0,0 +1,758 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/win_build/VS2008/seti_graphics.vcproj b/client/win_build/VS2008/seti_graphics.vcproj new file mode 100644 index 0000000..900e083 --- /dev/null +++ b/client/win_build/VS2008/seti_graphics.vcproj @@ -0,0 +1,457 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/win_build/VS2008/setiboincdb.vcproj b/client/win_build/VS2008/setiboincdb.vcproj new file mode 100644 index 0000000..2aaa494 --- /dev/null +++ b/client/win_build/VS2008/setiboincdb.vcproj @@ -0,0 +1,351 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/win_build/boincglut.vcproj b/client/win_build/boincglut.vcproj new file mode 100755 index 0000000..1cb53aa --- /dev/null +++ b/client/win_build/boincglut.vcproj @@ -0,0 +1,202 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/win_build/fftw3.h b/client/win_build/fftw3.h new file mode 100644 index 0000000..7e5e21e --- /dev/null +++ b/client/win_build/fftw3.h @@ -0,0 +1,332 @@ +/* + * Copyright (c) 2003, 2006 Matteo Frigo + * Copyright (c) 2003, 2006 Massachusetts Institute of Technology + * + * The following statement of license applies *only* to this header file, + * and *not* to the other files distributed with FFTW or derived therefrom: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/***************************** NOTE TO USERS ********************************* + * + * THIS IS A HEADER FILE, NOT A MANUAL + * + * If you want to know how to use FFTW, please read the manual, + * online at http://www.fftw.org/doc/ and also included with FFTW. + * For a quick start, see the manual's tutorial section. + * + * (Reading header files to learn how to use a library is a habit + * stemming from code lacking a proper manual. Arguably, it's a + * *bad* habit in most cases, because header files can contain + * interfaces that are not part of the public, stable API.) + * + ****************************************************************************/ + +/* header file for fftw3 */ +/* (The following is the CVS ID for this file, *not* the version + number of FFTW:) */ +/* $Id: fftw3.h,v 1.90 2006-01-17 04:03:33 stevenj Exp $ */ + +#ifndef FFTW3_H +#define FFTW3_H + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* If is included, use the C99 complex type. Otherwise + define a type bit-compatible with C99 complex */ +#if !defined(FFTW_NO_Complex) && defined(_Complex_I) && defined(complex) && defined(I) +# define FFTW_DEFINE_COMPLEX(R, C) typedef R _Complex C +#else +# define FFTW_DEFINE_COMPLEX(R, C) typedef R C[2] +#endif + +#define FFTW_CONCAT(prefix, name) prefix ## name +#define FFTW_MANGLE_DOUBLE(name) FFTW_CONCAT(fftw_, name) +#define FFTW_MANGLE_FLOAT(name) FFTW_CONCAT(fftwf_, name) +#define FFTW_MANGLE_LONG_DOUBLE(name) FFTW_CONCAT(fftwl_, name) + +#define FFTW_DLL +/* IMPORTANT: for Windows compilers, you should add a line + #define FFTW_DLL + here and in kernel/ifftw.h if you are compiling/using FFTW as a + DLL, in order to do the proper importing/exporting, or + alternatively compile with -DFFTW_DLL or the equivalent + command-line flag. This is not necessary under MinGW/Cygwin, where + libtool does the imports/exports automatically. */ +#if defined(FFTW_DLL) && (defined(_WIN32) || defined(__WIN32__)) + /* annoying Windows syntax for shared-library declarations */ +# if defined(COMPILING_FFTW) /* defined in api.h when compiling FFTW */ +# define FFTW_EXTERN extern __declspec(dllexport) +# else /* user is calling FFTW; import symbol */ +# define FFTW_EXTERN extern __declspec(dllexport) +# endif +#else +# define FFTW_EXTERN extern +#endif + +enum fftw_r2r_kind_do_not_use_me { + FFTW_R2HC=0, FFTW_HC2R=1, FFTW_DHT=2, + FFTW_REDFT00=3, FFTW_REDFT01=4, FFTW_REDFT10=5, FFTW_REDFT11=6, + FFTW_RODFT00=7, FFTW_RODFT01=8, FFTW_RODFT10=9, FFTW_RODFT11=10 +}; + +struct fftw_iodim_do_not_use_me { + int n; /* dimension size */ + int is; /* input stride */ + int os; /* output stride */ +}; + +/* + huge second-order macro that defines prototypes for all API + functions. We expand this macro for each supported precision + + X: name-mangling macro + R: real data type + C: complex data type +*/ + +#define FFTW_DEFINE_API(X, R, C) \ + \ +FFTW_DEFINE_COMPLEX(R, C); \ + \ +typedef struct X(plan_s) *X(plan); \ + \ +typedef struct fftw_iodim_do_not_use_me X(iodim); \ + \ +typedef enum fftw_r2r_kind_do_not_use_me X(r2r_kind); \ + \ +FFTW_EXTERN void X(execute)(const X(plan) p); \ + \ +FFTW_EXTERN X(plan) X(plan_dft)(int rank, const int *n, \ + C *in, C *out, int sign, unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_dft_1d)(int n, C *in, C *out, int sign, \ + unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_dft_2d)(int nx, int ny, \ + C *in, C *out, int sign, unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_dft_3d)(int nx, int ny, int nz, \ + C *in, C *out, int sign, unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_many_dft)(int rank, const int *n, \ + int howmany, \ + C *in, const int *inembed, \ + int istride, int idist, \ + C *out, const int *onembed, \ + int ostride, int odist, \ + int sign, unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_guru_dft)(int rank, const X(iodim) *dims, \ + int howmany_rank, \ + const X(iodim) *howmany_dims, \ + C *in, C *out, \ + int sign, unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_guru_split_dft)(int rank, const X(iodim) *dims, \ + int howmany_rank, \ + const X(iodim) *howmany_dims, \ + R *ri, R *ii, R *ro, R *io, \ + unsigned flags); \ + \ +FFTW_EXTERN void X(execute_dft)(const X(plan) p, C *in, C *out); \ +FFTW_EXTERN void X(execute_split_dft)(const X(plan) p, R *ri, R *ii, \ + R *ro, R *io); \ + \ +FFTW_EXTERN X(plan) X(plan_many_dft_r2c)(int rank, const int *n, \ + int howmany, \ + R *in, const int *inembed, \ + int istride, int idist, \ + C *out, const int *onembed, \ + int ostride, int odist, \ + unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_dft_r2c)(int rank, const int *n, \ + R *in, C *out, unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_dft_r2c_1d)(int n,R *in,C *out,unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_dft_r2c_2d)(int nx, int ny, \ + R *in, C *out, unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_dft_r2c_3d)(int nx, int ny, \ + int nz, \ + R *in, C *out, unsigned flags); \ + \ + \ +FFTW_EXTERN X(plan) X(plan_many_dft_c2r)(int rank, const int *n, \ + int howmany, \ + C *in, const int *inembed, \ + int istride, int idist, \ + R *out, const int *onembed, \ + int ostride, int odist, \ + unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_dft_c2r)(int rank, const int *n, \ + C *in, R *out, unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_dft_c2r_1d)(int n,C *in,R *out,unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_dft_c2r_2d)(int nx, int ny, \ + C *in, R *out, unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_dft_c2r_3d)(int nx, int ny, \ + int nz, \ + C *in, R *out, unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_guru_dft_r2c)(int rank, const X(iodim) *dims, \ + int howmany_rank, \ + const X(iodim) *howmany_dims, \ + R *in, C *out, \ + unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_guru_dft_c2r)(int rank, const X(iodim) *dims, \ + int howmany_rank, \ + const X(iodim) *howmany_dims, \ + C *in, R *out, \ + unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_guru_split_dft_r2c)( \ + int rank, const X(iodim) *dims, \ + int howmany_rank, \ + const X(iodim) *howmany_dims, \ + R *in, R *ro, R *io, \ + unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_guru_split_dft_c2r)( \ + int rank, const X(iodim) *dims, \ + int howmany_rank, \ + const X(iodim) *howmany_dims, \ + R *ri, R *ii, R *out, \ + unsigned flags); \ + \ +FFTW_EXTERN void X(execute_dft_r2c)(const X(plan) p, R *in, C *out); \ +FFTW_EXTERN void X(execute_dft_c2r)(const X(plan) p, C *in, R *out); \ + \ +FFTW_EXTERN void X(execute_split_dft_r2c)(const X(plan) p, \ + R *in, R *ro, R *io); \ +FFTW_EXTERN void X(execute_split_dft_c2r)(const X(plan) p, \ + R *ri, R *ii, R *out); \ + \ +FFTW_EXTERN X(plan) X(plan_many_r2r)(int rank, const int *n, \ + int howmany, \ + R *in, const int *inembed, \ + int istride, int idist, \ + R *out, const int *onembed, \ + int ostride, int odist, \ + const X(r2r_kind) *kind, unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_r2r)(int rank, const int *n, R *in, R *out, \ + const X(r2r_kind) *kind, unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_r2r_1d)(int n, R *in, R *out, \ + X(r2r_kind) kind, unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_r2r_2d)(int nx, int ny, R *in, R *out, \ + X(r2r_kind) kindx, X(r2r_kind) kindy, \ + unsigned flags); \ +FFTW_EXTERN X(plan) X(plan_r2r_3d)(int nx, int ny, int nz, \ + R *in, R *out, X(r2r_kind) kindx, \ + X(r2r_kind) kindy, X(r2r_kind) kindz, \ + unsigned flags); \ + \ +FFTW_EXTERN X(plan) X(plan_guru_r2r)(int rank, const X(iodim) *dims, \ + int howmany_rank, \ + const X(iodim) *howmany_dims, \ + R *in, R *out, \ + const X(r2r_kind) *kind, unsigned flags); \ +FFTW_EXTERN void X(execute_r2r)(const X(plan) p, R *in, R *out); \ + \ +FFTW_EXTERN void X(destroy_plan)(X(plan) p); \ +FFTW_EXTERN void X(forget_wisdom)(void); \ +FFTW_EXTERN void X(cleanup)(void); \ + \ +FFTW_EXTERN void X(set_timelimit)(double); \ + \ +FFTW_EXTERN void X(plan_with_nthreads)(int nthreads); \ +FFTW_EXTERN int X(init_threads)(void); \ +FFTW_EXTERN void X(cleanup_threads)(void); \ + \ +FFTW_EXTERN void X(export_wisdom_to_file)(FILE *output_file); \ +FFTW_EXTERN char *X(export_wisdom_to_string)(void); \ +FFTW_EXTERN void X(export_wisdom)(void (*write_char)(char c, void *), \ + void *data); \ +FFTW_EXTERN int X(import_system_wisdom)(void); \ +FFTW_EXTERN int X(import_wisdom_from_file)(FILE *input_file); \ +FFTW_EXTERN int X(import_wisdom_from_string)(const char *input_string); \ +FFTW_EXTERN int X(import_wisdom)(int (*read_char)(void *), void *data); \ + \ +FFTW_EXTERN void X(fprint_plan)(const X(plan) p, FILE *output_file); \ +FFTW_EXTERN void X(print_plan)(const X(plan) p); \ + \ +FFTW_EXTERN void *X(malloc)(size_t n); \ +FFTW_EXTERN void X(free)(void *p); \ + \ +FFTW_EXTERN void X(flops)(const X(plan) p, \ + double *add, double *mul, double *fmas); \ +FFTW_EXTERN double X(estimate_cost)(const X(plan) p); \ + \ +FFTW_EXTERN const char X(version)[]; \ +FFTW_EXTERN const char X(cc)[]; \ +FFTW_EXTERN const char X(codelet_optim)[]; + + +/* end of FFTW_DEFINE_API macro */ + +FFTW_DEFINE_API(FFTW_MANGLE_DOUBLE, double, fftw_complex) +FFTW_DEFINE_API(FFTW_MANGLE_FLOAT, float, fftwf_complex) +FFTW_DEFINE_API(FFTW_MANGLE_LONG_DOUBLE, long double, fftwl_complex) + +#define FFTW_FORWARD (-1) +#define FFTW_BACKWARD (+1) + +#define FFTW_NO_TIMELIMIT (-1.0) + +/* documented flags */ +#define FFTW_MEASURE (0U) +#define FFTW_DESTROY_INPUT (1U << 0) +#define FFTW_UNALIGNED (1U << 1) +#define FFTW_CONSERVE_MEMORY (1U << 2) +#define FFTW_EXHAUSTIVE (1U << 3) /* NO_EXHAUSTIVE is default */ +#define FFTW_PRESERVE_INPUT (1U << 4) /* cancels FFTW_DESTROY_INPUT */ +#define FFTW_PATIENT (1U << 5) /* IMPATIENT is default */ +#define FFTW_ESTIMATE (1U << 6) + +/* undocumented beyond-guru flags */ +#define FFTW_ESTIMATE_PATIENT (1U << 7) +#define FFTW_BELIEVE_PCOST (1U << 8) +#define FFTW_NO_DFT_R2HC (1U << 9) +#define FFTW_NO_NONTHREADED (1U << 10) +#define FFTW_NO_BUFFERING (1U << 11) +#define FFTW_NO_INDIRECT_OP (1U << 12) +#define FFTW_ALLOW_LARGE_GENERIC (1U << 13) /* NO_LARGE_GENERIC is default */ +#define FFTW_NO_RANK_SPLITS (1U << 14) +#define FFTW_NO_VRANK_SPLITS (1U << 15) +#define FFTW_NO_VRECURSE (1U << 16) +#define FFTW_NO_SIMD (1U << 17) +#define FFTW_NO_SLOW (1U << 18) +#define FFTW_NO_FIXED_RADIX_LARGE_N (1U << 19) +#define FFTW_ALLOW_PRUNING (1U << 20) + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* FFTW3_H */ diff --git a/client/win_build/glut.vcproj b/client/win_build/glut.vcproj new file mode 100755 index 0000000..6c2b4dd --- /dev/null +++ b/client/win_build/glut.vcproj @@ -0,0 +1,458 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/win_build/image_libs.vcproj b/client/win_build/image_libs.vcproj new file mode 100755 index 0000000..910e535 --- /dev/null +++ b/client/win_build/image_libs.vcproj @@ -0,0 +1,320 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/win_build/jpeglib.vcproj b/client/win_build/jpeglib.vcproj new file mode 100755 index 0000000..10863e5 --- /dev/null +++ b/client/win_build/jpeglib.vcproj @@ -0,0 +1,574 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/win_build/libfftw3f.def b/client/win_build/libfftw3f.def new file mode 100644 index 0000000..e3538a5 --- /dev/null +++ b/client/win_build/libfftw3f.def @@ -0,0 +1,635 @@ +LIBRARY libfftw3f-3-1-1a_upx.dll +EXPORTS +fftwf_alignment_of +fftwf_assertion_failed +fftwf_check_alignment_of_sse_mpmp +fftwf_choose_radix +fftwf_cleanup +fftwf_cleanup_threads +fftwf_codelet_e01_8 +fftwf_codelet_e10_8 +fftwf_codelet_hb_10 +fftwf_codelet_hb_12 +fftwf_codelet_hb_15 +fftwf_codelet_hb_16 +fftwf_codelet_hb_2 +fftwf_codelet_hb_3 +fftwf_codelet_hb_32 +fftwf_codelet_hb_4 +fftwf_codelet_hb_5 +fftwf_codelet_hb_6 +fftwf_codelet_hb_64 +fftwf_codelet_hb_7 +fftwf_codelet_hb_8 +fftwf_codelet_hb_9 +fftwf_codelet_hc2r_10 +fftwf_codelet_hc2r_11 +fftwf_codelet_hc2r_12 +fftwf_codelet_hc2r_128 +fftwf_codelet_hc2r_13 +fftwf_codelet_hc2r_14 +fftwf_codelet_hc2r_15 +fftwf_codelet_hc2r_16 +fftwf_codelet_hc2r_3 +fftwf_codelet_hc2r_32 +fftwf_codelet_hc2r_4 +fftwf_codelet_hc2r_5 +fftwf_codelet_hc2r_6 +fftwf_codelet_hc2r_64 +fftwf_codelet_hc2r_7 +fftwf_codelet_hc2r_8 +fftwf_codelet_hc2r_9 +fftwf_codelet_hc2rIII_10 +fftwf_codelet_hc2rIII_12 +fftwf_codelet_hc2rIII_15 +fftwf_codelet_hc2rIII_16 +fftwf_codelet_hc2rIII_2 +fftwf_codelet_hc2rIII_3 +fftwf_codelet_hc2rIII_32 +fftwf_codelet_hc2rIII_4 +fftwf_codelet_hc2rIII_5 +fftwf_codelet_hc2rIII_6 +fftwf_codelet_hc2rIII_64 +fftwf_codelet_hc2rIII_7 +fftwf_codelet_hc2rIII_8 +fftwf_codelet_hc2rIII_9 +fftwf_codelet_hf_10 +fftwf_codelet_hf_12 +fftwf_codelet_hf_15 +fftwf_codelet_hf_16 +fftwf_codelet_hf_2 +fftwf_codelet_hf_3 +fftwf_codelet_hf_32 +fftwf_codelet_hf_4 +fftwf_codelet_hf_5 +fftwf_codelet_hf_6 +fftwf_codelet_hf_64 +fftwf_codelet_hf_7 +fftwf_codelet_hf_8 +fftwf_codelet_hf_9 +fftwf_codelet_hf2_16 +fftwf_codelet_hf2_32 +fftwf_codelet_hf2_4 +fftwf_codelet_hf2_64 +fftwf_codelet_hf2_8 +fftwf_codelet_n1_10 +fftwf_codelet_n1_11 +fftwf_codelet_n1_12 +fftwf_codelet_n1_13 +fftwf_codelet_n1_14 +fftwf_codelet_n1_15 +fftwf_codelet_n1_16 +fftwf_codelet_n1_2 +fftwf_codelet_n1_3 +fftwf_codelet_n1_32 +fftwf_codelet_n1_4 +fftwf_codelet_n1_5 +fftwf_codelet_n1_6 +fftwf_codelet_n1_64 +fftwf_codelet_n1_7 +fftwf_codelet_n1_8 +fftwf_codelet_n1_9 +fftwf_codelet_n1bv_10 +fftwf_codelet_n1bv_11 +fftwf_codelet_n1bv_12 +fftwf_codelet_n1bv_13 +fftwf_codelet_n1bv_14 +fftwf_codelet_n1bv_15 +fftwf_codelet_n1bv_16 +fftwf_codelet_n1bv_2 +fftwf_codelet_n1bv_3 +fftwf_codelet_n1bv_32 +fftwf_codelet_n1bv_4 +fftwf_codelet_n1bv_5 +fftwf_codelet_n1bv_6 +fftwf_codelet_n1bv_64 +fftwf_codelet_n1bv_7 +fftwf_codelet_n1bv_8 +fftwf_codelet_n1bv_9 +fftwf_codelet_n1fv_10 +fftwf_codelet_n1fv_11 +fftwf_codelet_n1fv_12 +fftwf_codelet_n1fv_13 +fftwf_codelet_n1fv_14 +fftwf_codelet_n1fv_15 +fftwf_codelet_n1fv_16 +fftwf_codelet_n1fv_2 +fftwf_codelet_n1fv_3 +fftwf_codelet_n1fv_32 +fftwf_codelet_n1fv_4 +fftwf_codelet_n1fv_5 +fftwf_codelet_n1fv_6 +fftwf_codelet_n1fv_64 +fftwf_codelet_n1fv_7 +fftwf_codelet_n1fv_8 +fftwf_codelet_n1fv_9 +fftwf_codelet_n2bv_10 +fftwf_codelet_n2bv_12 +fftwf_codelet_n2bv_14 +fftwf_codelet_n2bv_16 +fftwf_codelet_n2bv_2 +fftwf_codelet_n2bv_32 +fftwf_codelet_n2bv_4 +fftwf_codelet_n2bv_6 +fftwf_codelet_n2bv_64 +fftwf_codelet_n2bv_8 +fftwf_codelet_n2fv_10 +fftwf_codelet_n2fv_12 +fftwf_codelet_n2fv_14 +fftwf_codelet_n2fv_16 +fftwf_codelet_n2fv_2 +fftwf_codelet_n2fv_32 +fftwf_codelet_n2fv_4 +fftwf_codelet_n2fv_6 +fftwf_codelet_n2fv_64 +fftwf_codelet_n2fv_8 +fftwf_codelet_n2sv_16 +fftwf_codelet_n2sv_32 +fftwf_codelet_n2sv_4 +fftwf_codelet_n2sv_64 +fftwf_codelet_n2sv_8 +fftwf_codelet_q1_2 +fftwf_codelet_q1_3 +fftwf_codelet_q1_4 +fftwf_codelet_q1_5 +fftwf_codelet_q1_6 +fftwf_codelet_q1_8 +fftwf_codelet_q1bv_2 +fftwf_codelet_q1bv_4 +fftwf_codelet_q1bv_8 +fftwf_codelet_q1fv_2 +fftwf_codelet_q1fv_4 +fftwf_codelet_q1fv_8 +fftwf_codelet_r2hc_10 +fftwf_codelet_r2hc_11 +fftwf_codelet_r2hc_12 +fftwf_codelet_r2hc_128 +fftwf_codelet_r2hc_13 +fftwf_codelet_r2hc_14 +fftwf_codelet_r2hc_15 +fftwf_codelet_r2hc_16 +fftwf_codelet_r2hc_2 +fftwf_codelet_r2hc_3 +fftwf_codelet_r2hc_32 +fftwf_codelet_r2hc_4 +fftwf_codelet_r2hc_5 +fftwf_codelet_r2hc_6 +fftwf_codelet_r2hc_64 +fftwf_codelet_r2hc_7 +fftwf_codelet_r2hc_8 +fftwf_codelet_r2hc_9 +fftwf_codelet_r2hcII_10 +fftwf_codelet_r2hcII_12 +fftwf_codelet_r2hcII_15 +fftwf_codelet_r2hcII_16 +fftwf_codelet_r2hcII_2 +fftwf_codelet_r2hcII_3 +fftwf_codelet_r2hcII_32 +fftwf_codelet_r2hcII_4 +fftwf_codelet_r2hcII_5 +fftwf_codelet_r2hcII_6 +fftwf_codelet_r2hcII_64 +fftwf_codelet_r2hcII_7 +fftwf_codelet_r2hcII_8 +fftwf_codelet_r2hcII_9 +fftwf_codelet_t1_10 +fftwf_codelet_t1_12 +fftwf_codelet_t1_15 +fftwf_codelet_t1_16 +fftwf_codelet_t1_2 +fftwf_codelet_t1_3 +fftwf_codelet_t1_32 +fftwf_codelet_t1_4 +fftwf_codelet_t1_5 +fftwf_codelet_t1_6 +fftwf_codelet_t1_64 +fftwf_codelet_t1_7 +fftwf_codelet_t1_8 +fftwf_codelet_t1_9 +fftwf_codelet_t1bv_10 +fftwf_codelet_t1bv_12 +fftwf_codelet_t1bv_15 +fftwf_codelet_t1bv_16 +fftwf_codelet_t1bv_2 +fftwf_codelet_t1bv_3 +fftwf_codelet_t1bv_32 +fftwf_codelet_t1bv_4 +fftwf_codelet_t1bv_5 +fftwf_codelet_t1bv_6 +fftwf_codelet_t1bv_64 +fftwf_codelet_t1bv_7 +fftwf_codelet_t1bv_8 +fftwf_codelet_t1bv_9 +fftwf_codelet_t1fv_10 +fftwf_codelet_t1fv_12 +fftwf_codelet_t1fv_15 +fftwf_codelet_t1fv_16 +fftwf_codelet_t1fv_2 +fftwf_codelet_t1fv_3 +fftwf_codelet_t1fv_32 +fftwf_codelet_t1fv_4 +fftwf_codelet_t1fv_5 +fftwf_codelet_t1fv_6 +fftwf_codelet_t1fv_64 +fftwf_codelet_t1fv_7 +fftwf_codelet_t1fv_8 +fftwf_codelet_t1fv_9 +fftwf_codelet_t1sv_16 +fftwf_codelet_t1sv_2 +fftwf_codelet_t1sv_32 +fftwf_codelet_t1sv_4 +fftwf_codelet_t1sv_8 +fftwf_codelet_t2_16 +fftwf_codelet_t2_32 +fftwf_codelet_t2_4 +fftwf_codelet_t2_64 +fftwf_codelet_t2_8 +fftwf_codelet_t2bv_16 +fftwf_codelet_t2bv_2 +fftwf_codelet_t2bv_32 +fftwf_codelet_t2bv_4 +fftwf_codelet_t2bv_64 +fftwf_codelet_t2bv_8 +fftwf_codelet_t2fv_16 +fftwf_codelet_t2fv_2 +fftwf_codelet_t2fv_32 +fftwf_codelet_t2fv_4 +fftwf_codelet_t2fv_64 +fftwf_codelet_t2fv_8 +fftwf_codelet_t2sv_16 +fftwf_codelet_t2sv_32 +fftwf_codelet_t2sv_4 +fftwf_codelet_t2sv_8 +fftwf_codelet_t3bv_16 +fftwf_codelet_t3bv_32 +fftwf_codelet_t3bv_4 +fftwf_codelet_t3bv_8 +fftwf_codelet_t3fv_16 +fftwf_codelet_t3fv_32 +fftwf_codelet_t3fv_4 +fftwf_codelet_t3fv_8 +fftwf_compute_nbuf +fftwf_compute_tilesz +fftwf_configure_planner +fftwf_cpy1d +fftwf_cpy2d +fftwf_cpy2d_ci +fftwf_cpy2d_co +fftwf_cpy2d_pair +fftwf_cpy2d_pair_ci +fftwf_cpy2d_pair_co +fftwf_cpy2d_tiled +fftwf_cpy2d_tiledbuf +fftwf_ct_applicable +fftwf_ct_generic_register +fftwf_ct_genericbuf_register +fftwf_ct_uglyp +fftwf_destroy_plan +fftwf_dft_bluestein_register +fftwf_dft_buffered_register +fftwf_dft_conf_standard +fftwf_dft_generic_register +fftwf_dft_indirect_register +fftwf_dft_indirect_transpose_register +fftwf_dft_nop_register +fftwf_dft_r2hc_register +fftwf_dft_rader_register +fftwf_dft_rank_geq2_register +fftwf_dft_solve +fftwf_dft_thr_vrank_geq1_register +fftwf_dft_vrank_geq1_register +fftwf_dft_zerotens +fftwf_dht_r2hc_register +fftwf_dht_rader_register +fftwf_dimcmp +fftwf_elapsed_since +fftwf_estimate_cost +fftwf_execute +fftwf_execute_dft +fftwf_execute_dft_c2r +fftwf_execute_dft_r2c +fftwf_execute_r2r +fftwf_execute_split_dft +fftwf_execute_split_dft_c2r +fftwf_execute_split_dft_r2c +fftwf_export_wisdom +fftwf_export_wisdom_to_file +fftwf_export_wisdom_to_string +fftwf_extract_reim +fftwf_factors_into +fftwf_find_generator +fftwf_first_divisor +fftwf_flops +fftwf_forget_wisdom +fftwf_fprint_plan +fftwf_free +fftwf_get_crude_time +fftwf_guru_kosherp +fftwf_hash +fftwf_have_sse +fftwf_hc2hc_applicable +fftwf_hc2hc_generic_register +fftwf_hc2hc_mkcldrn +fftwf_iabs +fftwf_iestimate_cost +fftwf_ifree +fftwf_ifree0 +fftwf_imax +fftwf_imin +fftwf_import_system_wisdom +fftwf_import_wisdom +fftwf_import_wisdom_from_file +fftwf_import_wisdom_from_string +fftwf_init_threads +fftwf_is_prime +fftwf_isqrt +fftwf_ithreads_init +fftwf_join_taint +fftwf_kdft_dif_register +fftwf_kdft_difsq_register +fftwf_kdft_dit_register +fftwf_kdft_register +fftwf_kernel_free +fftwf_kernel_malloc +fftwf_khc2hc_register +fftwf_khc2r_register +fftwf_kr2hc_register +fftwf_kr2r_register +fftwf_malloc +fftwf_malloc_plain +fftwf_many_kosherp +fftwf_map_r2r_kind +fftwf_mapflags +fftwf_md5begin +fftwf_md5end +fftwf_md5int +fftwf_md5INT +fftwf_md5putb +fftwf_md5putc +fftwf_md5puts +fftwf_md5unsigned +fftwf_measure_execution_time +fftwf_mkapiplan +fftwf_mkplan +fftwf_mkplan_d +fftwf_mkplan_dft +fftwf_mkplan_dftw +fftwf_mkplan_f_d +fftwf_mkplan_hc2hc +fftwf_mkplan_rdft +fftwf_mkplan_rdft2 +fftwf_mkplanner +fftwf_mkprinter +fftwf_mkprinter_file +fftwf_mkproblem +fftwf_mkproblem_dft +fftwf_mkproblem_dft_d +fftwf_mkproblem_rdft +fftwf_mkproblem_rdft_0_d +fftwf_mkproblem_rdft_1 +fftwf_mkproblem_rdft_1_d +fftwf_mkproblem_rdft_d +fftwf_mkproblem_rdft2 +fftwf_mkproblem_rdft2_d +fftwf_mkscanner +fftwf_mksolver +fftwf_mksolver_ct +fftwf_mksolver_ct_threads +fftwf_mksolver_ctsq +fftwf_mksolver_dft_direct +fftwf_mksolver_dft_directbuf +fftwf_mksolver_hc2hc +fftwf_mksolver_hc2hc_threads +fftwf_mksolver_rdft_hc2r_direct +fftwf_mksolver_rdft_r2hc_direct +fftwf_mksolver_rdft_r2r_direct +fftwf_mksolver_rdft2_hc2r_direct +fftwf_mksolver_rdft2_r2hc_direct +fftwf_mkstride +fftwf_mktensor +fftwf_mktensor_0d +fftwf_mktensor_1d +fftwf_mktensor_2d +fftwf_mktensor_3d +fftwf_mktensor_iodims +fftwf_mktensor_rowmajor +fftwf_mktriggen +fftwf_next_prime +fftwf_null_awake +fftwf_ops_add +fftwf_ops_add2 +fftwf_ops_cpy +fftwf_ops_madd +fftwf_ops_madd2 +fftwf_ops_other +fftwf_ops_zero +fftwf_pickdim +fftwf_plan_awake +fftwf_plan_destroy_internal +fftwf_plan_dft +fftwf_plan_dft_1d +fftwf_plan_dft_2d +fftwf_plan_dft_3d +fftwf_plan_dft_c2r +fftwf_plan_dft_c2r_1d +fftwf_plan_dft_c2r_2d +fftwf_plan_dft_c2r_3d +fftwf_plan_dft_r2c +fftwf_plan_dft_r2c_1d +fftwf_plan_dft_r2c_2d +fftwf_plan_dft_r2c_3d +fftwf_plan_guru_dft +fftwf_plan_guru_dft_c2r +fftwf_plan_guru_dft_r2c +fftwf_plan_guru_r2r +fftwf_plan_guru_split_dft +fftwf_plan_guru_split_dft_c2r +fftwf_plan_guru_split_dft_r2c +fftwf_plan_many_dft +fftwf_plan_many_dft_c2r +fftwf_plan_many_dft_r2c +fftwf_plan_many_r2r +fftwf_plan_null_destroy +fftwf_plan_r2r +fftwf_plan_r2r_1d +fftwf_plan_r2r_2d +fftwf_plan_r2r_3d +fftwf_plan_with_nthreads +fftwf_planner_destroy +fftwf_power_mod +fftwf_print_plan +fftwf_printer_destroy +fftwf_problem_destroy +fftwf_rader_tl_delete +fftwf_rader_tl_find +fftwf_rader_tl_insert +fftwf_rdft_buffered_register +fftwf_rdft_conf_standard +fftwf_rdft_dht_register +fftwf_rdft_generic_register +fftwf_rdft_indirect_register +fftwf_rdft_kind_str +fftwf_rdft_nop_register +fftwf_rdft_rank_geq2_register +fftwf_rdft_rank0_register +fftwf_rdft_solve +fftwf_rdft_thr_vrank_geq1_register +fftwf_rdft_vrank_geq1_register +fftwf_rdft_vrank3_transpose_register +fftwf_rdft_zerotens +fftwf_rdft2_buffered_register +fftwf_rdft2_inplace_strides +fftwf_rdft2_nop_register +fftwf_rdft2_pad +fftwf_rdft2_radix2_register +fftwf_rdft2_rank_geq2_register +fftwf_rdft2_rank0_register +fftwf_rdft2_solve +fftwf_rdft2_strides +fftwf_rdft2_tensor_max_index +fftwf_rdft2_thr_vrank_geq1_register +fftwf_rdft2_vrank_geq1_register +fftwf_redft00e_r2hc_pad_register +fftwf_regsolver_ct_directw +fftwf_regsolver_hc2hc_direct +fftwf_regsolver_hc2hc_directbuf +fftwf_reodft_conf_standard +fftwf_reodft00e_splitradix_register +fftwf_reodft010e_r2hc_register +fftwf_reodft11e_r2hc_odd_register +fftwf_reodft11e_radix2_r2hc_register +fftwf_rodft00e_r2hc_pad_register +fftwf_safe_mulmod +fftwf_scanner_destroy +fftwf_set_timelimit +fftwf_solver_destroy +fftwf_solver_register +fftwf_solver_use +fftwf_solvtab_exec +fftwf_spawn_loop +fftwf_stride_destroy +fftwf_taint +fftwf_tensor_append +fftwf_tensor_compress +fftwf_tensor_compress_contiguous +fftwf_tensor_copy +fftwf_tensor_copy_except +fftwf_tensor_copy_inplace +fftwf_tensor_copy_sub +fftwf_tensor_destroy +fftwf_tensor_destroy2 +fftwf_tensor_destroy4 +fftwf_tensor_inplace_strides +fftwf_tensor_inplace_strides2 +fftwf_tensor_kosherp +fftwf_tensor_max_index +fftwf_tensor_md5 +fftwf_tensor_min_istride +fftwf_tensor_min_ostride +fftwf_tensor_min_stride +fftwf_tensor_print +fftwf_tensor_split +fftwf_tensor_strides_decrease +fftwf_tensor_sz +fftwf_tensor_tornk1 +fftwf_the_planner +fftwf_threads_cleanup +fftwf_threads_conf_standard +fftwf_threads_setmax +fftwf_tile2d +fftwf_transpose +fftwf_transpose_tiled +fftwf_transpose_tiledbuf +fftwf_triggen_destroy +fftwf_twiddle_awake +fftwf_twiddle_length +fftwf_twiddle_shift +sfftw_cleanup_ +sfftw_cleanup__ +sfftw_cleanup_threads__ +sfftw_destroy_plan_ +sfftw_destroy_plan__ +sfftw_execute_ +sfftw_execute__ +sfftw_execute_dft_ +sfftw_execute_dft__ +sfftw_execute_dft_c2r_ +sfftw_execute_dft_c2r__ +sfftw_execute_dft_r2c_ +sfftw_execute_dft_r2c__ +sfftw_execute_r2r_ +sfftw_execute_r2r__ +sfftw_execute_split_dft_ +sfftw_execute_split_dft__ +sfftw_execute_split_dft_c2r_ +sfftw_execute_split_dft_c2r__ +sfftw_execute_split_dft_r2c_ +sfftw_execute_split_dft_r2c__ +sfftw_export_wisdom_ +sfftw_export_wisdom__ +sfftw_flops_ +sfftw_flops__ +sfftw_forget_wisdom_ +sfftw_forget_wisdom__ +sfftw_import_system_wisdom_ +sfftw_import_system_wisdom__ +sfftw_import_wisdom_ +sfftw_import_wisdom__ +sfftw_init_threads__ +sfftw_plan_dft_ +sfftw_plan_dft__ +sfftw_plan_dft_1d_ +sfftw_plan_dft_1d__ +sfftw_plan_dft_2d_ +sfftw_plan_dft_2d__ +sfftw_plan_dft_3d_ +sfftw_plan_dft_3d__ +sfftw_plan_dft_c2r_ +sfftw_plan_dft_c2r__ +sfftw_plan_dft_c2r_1d_ +sfftw_plan_dft_c2r_1d__ +sfftw_plan_dft_c2r_2d_ +sfftw_plan_dft_c2r_2d__ +sfftw_plan_dft_c2r_3d_ +sfftw_plan_dft_c2r_3d__ +sfftw_plan_dft_r2c_ +sfftw_plan_dft_r2c__ +sfftw_plan_dft_r2c_1d_ +sfftw_plan_dft_r2c_1d__ +sfftw_plan_dft_r2c_2d_ +sfftw_plan_dft_r2c_2d__ +sfftw_plan_dft_r2c_3d_ +sfftw_plan_dft_r2c_3d__ +sfftw_plan_guru_dft_ +sfftw_plan_guru_dft__ +sfftw_plan_guru_dft_c2r_ +sfftw_plan_guru_dft_c2r__ +sfftw_plan_guru_dft_r2c_ +sfftw_plan_guru_dft_r2c__ +sfftw_plan_guru_r2r_ +sfftw_plan_guru_r2r__ +sfftw_plan_guru_split_dft_ +sfftw_plan_guru_split_dft__ +sfftw_plan_guru_split_dft_c2r_ +sfftw_plan_guru_split_dft_c2r__ +sfftw_plan_guru_split_dft_r2c_ +sfftw_plan_guru_split_dft_r2c__ +sfftw_plan_many_dft_ +sfftw_plan_many_dft__ +sfftw_plan_many_dft_c2r_ +sfftw_plan_many_dft_c2r__ +sfftw_plan_many_dft_r2c_ +sfftw_plan_many_dft_r2c__ +sfftw_plan_many_r2r_ +sfftw_plan_many_r2r__ +sfftw_plan_r2r_ +sfftw_plan_r2r__ +sfftw_plan_r2r_1d_ +sfftw_plan_r2r_1d__ +sfftw_plan_r2r_2d_ +sfftw_plan_r2r_2d__ +sfftw_plan_r2r_3d_ +sfftw_plan_r2r_3d__ +sfftw_plan_with_nthreads__ +sfftw_print_plan_ +sfftw_print_plan__ diff --git a/client/win_build/p004_640.jpg b/client/win_build/p004_640.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ebb0db38230a8e9eb6c37e976f2458fcf34cc6e6 GIT binary patch literal 73960 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

  • 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 +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=seti_boinc - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "seti_boinc.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "seti_boinc.mak" CFG="seti_boinc - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "seti_boinc - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "seti_boinc - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "seti_boinc - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I "../../../boinc/api" /I "../../../boinc/lib" /I ".." /I "glut" /I "../../../boinc/image_libs" /I "../../../boinc/jpeglib" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "BOINC_APP_GRAPHICS" /D "_MBCS" /D "CLIENT" /FR /FD /c /Tp +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 glut32.lib /nologo /subsystem:windows /machine:I386 /libpath:"glut" +# SUBTRACT LINK32 /nodefaultlib + +!ELSEIF "$(CFG)" == "seti_boinc - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "." /I "../../../boinc/api" /I "../../../boinc/client/win" /I "../../../boinc/lib" /I ".." /I "glut" /I "../../../boinc/image_libs" /I "../../../boinc/jpeglib" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "CLIENT" /D "BOINC_APP_GRAPHICS" /FR /FD /GZ /TP /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 glut32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /nodefaultlib:"libc.lib" /out:"Debug/setiathome_2.18_windows_intelx86.exe" /pdbtype:sept /libpath:"glut" +# SUBTRACT LINK32 /nodefaultlib + +!ENDIF + +# Begin Target + +# Name "seti_boinc - Win32 Release" +# Name "seti_boinc - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\amd64AnalyzeFuncs.cpp +# End Source File +# Begin Source File + +SOURCE=..\amd64fft8g.cpp +# End Source File +# Begin Source File + +SOURCE=..\analyzeFuncs.cpp +# End Source File +# Begin Source File + +SOURCE=..\analyzePoT.cpp +# End Source File +# Begin Source File + +SOURCE=..\analyzeReport.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\lib\app_ipc.C +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\image_libs\bmplib.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\api\boinc_api.C +# End Source File +# Begin Source File + +SOURCE=..\chirpfft.cpp +# End Source File +# Begin Source File + +SOURCE=..\fft8g.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\lib\filesys.C +# End Source File +# Begin Source File + +SOURCE=..\gaussfit.cpp +# End Source File +# Begin Source File + +SOURCE=..\gdata.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\api\graphics_api.C +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\api\graphics_data.C +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\api\gutil.C +# End Source File +# Begin Source File + +SOURCE=..\lcgamm.cpp +# End Source File +# Begin Source File + +SOURCE=..\main.cpp +# End Source File +# Begin Source File + +SOURCE=..\malloc_a.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\api\mfile.C +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\lib\parse.C +# End Source File +# Begin Source File + +SOURCE=..\pulsefind.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\api\reduce.C +# End Source File +# Begin Source File + +SOURCE=..\s_util.cpp +# End Source File +# Begin Source File + +SOURCE=..\sah_gfx.cpp +# End Source File +# Begin Source File + +SOURCE=..\sah_gfx_base.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\db\schema_master.cpp +# End Source File +# Begin Source File + +SOURCE=..\seti.cpp +# End Source File +# Begin Source File + +SOURCE=..\seti_header.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\lib\shmem.C +# End Source File +# Begin Source File + +SOURCE=..\spike.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\db\sqlblob.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\db\sqlrow.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\image_libs\tgalib.cpp +# End Source File +# Begin Source File + +SOURCE=..\timecvt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\lib\util.C +# End Source File +# Begin Source File + +SOURCE=..\version.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\api\windows_opengl.C +# End Source File +# Begin Source File + +SOURCE=..\worker.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\lib\xml_util.C +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\analyze.h +# End Source File +# Begin Source File + +SOURCE=..\analyzeFuncs.h +# End Source File +# Begin Source File + +SOURCE=..\analyzePoT.h +# End Source File +# Begin Source File + +SOURCE=..\analyzeReport.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\lib\app_ipc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\image_libs\bmplib.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\api\boinc_api.h +# End Source File +# Begin Source File + +SOURCE=..\chirpfft.h +# End Source File +# Begin Source File + +SOURCE=.\sah_config.h +# End Source File +# Begin Source File + +SOURCE=..\..\db\db_table.h +# End Source File +# Begin Source File + +SOURCE=..\fft8g.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\lib\filesys.h +# End Source File +# Begin Source File + +SOURCE=..\gaussfit.h +# End Source File +# Begin Source File + +SOURCE=..\gdata.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\api\graphics_api.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\api\graphics_data.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\api\gutil.h +# End Source File +# Begin Source File + +SOURCE=..\lcgamm.h +# End Source File +# Begin Source File + +SOURCE=..\malloc_a.h +# End Source File +# Begin Source File + +SOURCE=..\pulsefind.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\api\reduce.h +# End Source File +# Begin Source File + +SOURCE=..\s_util.h +# End Source File +# Begin Source File + +SOURCE=..\sah_gfx.h +# End Source File +# Begin Source File + +SOURCE=..\sah_gfx_base.h +# End Source File +# Begin Source File + +SOURCE=..\..\db\schema_master.h +# End Source File +# Begin Source File + +SOURCE=..\seti.h +# End Source File +# Begin Source File + +SOURCE=..\seti_header.h +# End Source File +# Begin Source File + +SOURCE=..\spike.h +# End Source File +# Begin Source File + +SOURCE=..\..\db\sqlblob.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\lib\std_fixes.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\image_libs\tgalib.h +# End Source File +# Begin Source File + +SOURCE=..\timecvt.h +# End Source File +# Begin Source File + +SOURCE=..\version.h +# End Source File +# Begin Source File + +SOURCE="..\win-sah_config.h" +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\client\win\win_idle_tracker.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\client\win\win_util.h +# End Source File +# Begin Source File + +SOURCE=..\worker.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\lib\xml_util.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Group "jpeglib" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\cderror.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\cdjpeg.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jcapimin.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jcapistd.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jccoefct.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jccolor.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jcdctmgr.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jchuff.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jchuff.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jcinit.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jcmainct.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jcmarker.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jcmaster.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jcomapi.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jconfig.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jcparam.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jcphuff.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jcprepct.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jcsample.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jctrans.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jdapimin.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jdapistd.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jdatadst.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jdatasrc.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jdcoefct.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jdcolor.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jdct.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jddctmgr.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jdhuff.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jdhuff.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jdinput.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jdmainct.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jdmarker.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jdmaster.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jdmerge.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jdphuff.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jdpostct.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jdsample.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jdtrans.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jerror.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jerror.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jfdctflt.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jfdctfst.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jfdctint.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jidctflt.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jidctfst.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jidctint.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jidctred.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jinclude.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jmemmgr.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jmemnobs.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jmemsys.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jmorecfg.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jpegint.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jpeglib.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jquant1.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jquant2.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jutils.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\jversion.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\rdbmp.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\rdcolmap.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\rdgif.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\rdppm.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\rdrle.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\rdswitch.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\boinc\jpeglib\rdtarga.c +# End Source File +# End Group +# End Target +# End Project diff --git a/client/win_build/seti_boinc.dsw b/client/win_build/seti_boinc.dsw new file mode 100644 index 0000000..6387a17 --- /dev/null +++ b/client/win_build/seti_boinc.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "seti_boinc"=".\seti_boinc.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/client/win_build/seti_boinc.sln b/client/win_build/seti_boinc.sln new file mode 100755 index 0000000..faac2da --- /dev/null +++ b/client/win_build/seti_boinc.sln @@ -0,0 +1,124 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "seti_boinc", "seti_boinc.vcproj", "{EE96AAE0-7D9F-48AA-8ECD-7EECED30289C}" + ProjectSection(ProjectDependencies) = postProject + {7E3EB322-3341-4821-90C3-EBD6E0D46D57} = {7E3EB322-3341-4821-90C3-EBD6E0D46D57} + {814EBFD3-3CE6-4933-A580-C1FE3147ACB4} = {814EBFD3-3CE6-4933-A580-C1FE3147ACB4} + {07BDA8F7-4AAF-4A3B-B96E-EA72A143C5AE} = {07BDA8F7-4AAF-4A3B-B96E-EA72A143C5AE} + {B00664BD-71EB-46C1-957E-CD851418D395} = {B00664BD-71EB-46C1-957E-CD851418D395} + {D3D21F11-A7E7-4EA2-8518-E24695133BFF} = {D3D21F11-A7E7-4EA2-8518-E24695133BFF} + {C4165626-F68F-4F66-A126-3B82DDBB7480} = {C4165626-F68F-4F66-A126-3B82DDBB7480} + {5F065EAC-B881-4E9A-9E34-7A21D7A01D98} = {5F065EAC-B881-4E9A-9E34-7A21D7A01D98} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "image_libs", "image_libs.vcproj", "{D3D21F11-A7E7-4EA2-8518-E24695133BFF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jpeglib", "jpeglib.vcproj", "{5F065EAC-B881-4E9A-9E34-7A21D7A01D98}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "setiboincdb", "setiboincdb.vcproj", "{7E3EB322-3341-4821-90C3-EBD6E0D46D57}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "glut", "glut.vcproj", "{C4165626-F68F-4F66-A126-3B82DDBB7480}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "seti_graphics", "seti_graphics.vcproj", "{3CF31288-A44D-4C78-A3AA-B05B6E32DF11}" + ProjectSection(ProjectDependencies) = postProject + {07BDA8F7-4AAF-4A3B-B96E-EA72A143C5AE} = {07BDA8F7-4AAF-4A3B-B96E-EA72A143C5AE} + {B00664BD-71EB-46C1-957E-CD851418D395} = {B00664BD-71EB-46C1-957E-CD851418D395} + {D3D21F11-A7E7-4EA2-8518-E24695133BFF} = {D3D21F11-A7E7-4EA2-8518-E24695133BFF} + {7E3EB322-3341-4821-90C3-EBD6E0D46D57} = {7E3EB322-3341-4821-90C3-EBD6E0D46D57} + {814EBFD3-3CE6-4933-A580-C1FE3147ACB4} = {814EBFD3-3CE6-4933-A580-C1FE3147ACB4} + {5F065EAC-B881-4E9A-9E34-7A21D7A01D98} = {5F065EAC-B881-4E9A-9E34-7A21D7A01D98} + {EE96AAE0-7D9F-48AA-8ECD-7EECED30289C} = {EE96AAE0-7D9F-48AA-8ECD-7EECED30289C} + {C4165626-F68F-4F66-A126-3B82DDBB7480} = {C4165626-F68F-4F66-A126-3B82DDBB7480} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libboinc_staticcrt", "..\..\..\boinc\win_build\libboinc_staticcrt.vcproj", "{B00664BD-71EB-46C1-957E-CD851418D395}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libboincapi_staticcrt", "..\..\..\boinc\win_build\libboincapi_staticcrt.vcproj", "{07BDA8F7-4AAF-4A3B-B96E-EA72A143C5AE}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libgraphics2", "..\..\..\boinc\win_build\libgraphics2.vcproj", "{814EBFD3-3CE6-4933-A580-C1FE3147ACB4}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {EE96AAE0-7D9F-48AA-8ECD-7EECED30289C}.Debug|Win32.ActiveCfg = Debug|Win32 + {EE96AAE0-7D9F-48AA-8ECD-7EECED30289C}.Debug|Win32.Build.0 = Debug|Win32 + {EE96AAE0-7D9F-48AA-8ECD-7EECED30289C}.Debug|x64.ActiveCfg = Debug|x64 + {EE96AAE0-7D9F-48AA-8ECD-7EECED30289C}.Debug|x64.Build.0 = Debug|x64 + {EE96AAE0-7D9F-48AA-8ECD-7EECED30289C}.Release|Win32.ActiveCfg = Release|Win32 + {EE96AAE0-7D9F-48AA-8ECD-7EECED30289C}.Release|Win32.Build.0 = Release|Win32 + {EE96AAE0-7D9F-48AA-8ECD-7EECED30289C}.Release|x64.ActiveCfg = Release|x64 + {EE96AAE0-7D9F-48AA-8ECD-7EECED30289C}.Release|x64.Build.0 = Release|x64 + {D3D21F11-A7E7-4EA2-8518-E24695133BFF}.Debug|Win32.ActiveCfg = Debug|Win32 + {D3D21F11-A7E7-4EA2-8518-E24695133BFF}.Debug|Win32.Build.0 = Debug|Win32 + {D3D21F11-A7E7-4EA2-8518-E24695133BFF}.Debug|x64.ActiveCfg = Debug|x64 + {D3D21F11-A7E7-4EA2-8518-E24695133BFF}.Debug|x64.Build.0 = Debug|x64 + {D3D21F11-A7E7-4EA2-8518-E24695133BFF}.Release|Win32.ActiveCfg = Release|Win32 + {D3D21F11-A7E7-4EA2-8518-E24695133BFF}.Release|Win32.Build.0 = Release|Win32 + {D3D21F11-A7E7-4EA2-8518-E24695133BFF}.Release|x64.ActiveCfg = Release|x64 + {D3D21F11-A7E7-4EA2-8518-E24695133BFF}.Release|x64.Build.0 = Release|x64 + {5F065EAC-B881-4E9A-9E34-7A21D7A01D98}.Debug|Win32.ActiveCfg = Debug|Win32 + {5F065EAC-B881-4E9A-9E34-7A21D7A01D98}.Debug|Win32.Build.0 = Debug|Win32 + {5F065EAC-B881-4E9A-9E34-7A21D7A01D98}.Debug|x64.ActiveCfg = Debug|x64 + {5F065EAC-B881-4E9A-9E34-7A21D7A01D98}.Debug|x64.Build.0 = Debug|x64 + {5F065EAC-B881-4E9A-9E34-7A21D7A01D98}.Release|Win32.ActiveCfg = Release|Win32 + {5F065EAC-B881-4E9A-9E34-7A21D7A01D98}.Release|Win32.Build.0 = Release|Win32 + {5F065EAC-B881-4E9A-9E34-7A21D7A01D98}.Release|x64.ActiveCfg = Release|x64 + {5F065EAC-B881-4E9A-9E34-7A21D7A01D98}.Release|x64.Build.0 = Release|x64 + {7E3EB322-3341-4821-90C3-EBD6E0D46D57}.Debug|Win32.ActiveCfg = Debug|Win32 + {7E3EB322-3341-4821-90C3-EBD6E0D46D57}.Debug|Win32.Build.0 = Debug|Win32 + {7E3EB322-3341-4821-90C3-EBD6E0D46D57}.Debug|x64.ActiveCfg = Debug|x64 + {7E3EB322-3341-4821-90C3-EBD6E0D46D57}.Debug|x64.Build.0 = Debug|x64 + {7E3EB322-3341-4821-90C3-EBD6E0D46D57}.Release|Win32.ActiveCfg = Release|Win32 + {7E3EB322-3341-4821-90C3-EBD6E0D46D57}.Release|Win32.Build.0 = Release|Win32 + {7E3EB322-3341-4821-90C3-EBD6E0D46D57}.Release|x64.ActiveCfg = Release|x64 + {7E3EB322-3341-4821-90C3-EBD6E0D46D57}.Release|x64.Build.0 = Release|x64 + {C4165626-F68F-4F66-A126-3B82DDBB7480}.Debug|Win32.ActiveCfg = Debug|Win32 + {C4165626-F68F-4F66-A126-3B82DDBB7480}.Debug|Win32.Build.0 = Debug|Win32 + {C4165626-F68F-4F66-A126-3B82DDBB7480}.Debug|x64.ActiveCfg = Debug|x64 + {C4165626-F68F-4F66-A126-3B82DDBB7480}.Debug|x64.Build.0 = Debug|x64 + {C4165626-F68F-4F66-A126-3B82DDBB7480}.Release|Win32.ActiveCfg = Release|Win32 + {C4165626-F68F-4F66-A126-3B82DDBB7480}.Release|Win32.Build.0 = Release|Win32 + {C4165626-F68F-4F66-A126-3B82DDBB7480}.Release|x64.ActiveCfg = Release|x64 + {C4165626-F68F-4F66-A126-3B82DDBB7480}.Release|x64.Build.0 = Release|x64 + {3CF31288-A44D-4C78-A3AA-B05B6E32DF11}.Debug|Win32.ActiveCfg = Debug|Win32 + {3CF31288-A44D-4C78-A3AA-B05B6E32DF11}.Debug|Win32.Build.0 = Debug|Win32 + {3CF31288-A44D-4C78-A3AA-B05B6E32DF11}.Debug|x64.ActiveCfg = Debug|x64 + {3CF31288-A44D-4C78-A3AA-B05B6E32DF11}.Debug|x64.Build.0 = Debug|x64 + {3CF31288-A44D-4C78-A3AA-B05B6E32DF11}.Release|Win32.ActiveCfg = Release|Win32 + {3CF31288-A44D-4C78-A3AA-B05B6E32DF11}.Release|Win32.Build.0 = Release|Win32 + {3CF31288-A44D-4C78-A3AA-B05B6E32DF11}.Release|x64.ActiveCfg = Release|x64 + {3CF31288-A44D-4C78-A3AA-B05B6E32DF11}.Release|x64.Build.0 = Release|x64 + {B00664BD-71EB-46C1-957E-CD851418D395}.Debug|Win32.ActiveCfg = Debug|Win32 + {B00664BD-71EB-46C1-957E-CD851418D395}.Debug|Win32.Build.0 = Debug|Win32 + {B00664BD-71EB-46C1-957E-CD851418D395}.Debug|x64.ActiveCfg = Debug|x64 + {B00664BD-71EB-46C1-957E-CD851418D395}.Debug|x64.Build.0 = Debug|x64 + {B00664BD-71EB-46C1-957E-CD851418D395}.Release|Win32.ActiveCfg = Release|Win32 + {B00664BD-71EB-46C1-957E-CD851418D395}.Release|Win32.Build.0 = Release|Win32 + {B00664BD-71EB-46C1-957E-CD851418D395}.Release|x64.ActiveCfg = Release|x64 + {B00664BD-71EB-46C1-957E-CD851418D395}.Release|x64.Build.0 = Release|x64 + {07BDA8F7-4AAF-4A3B-B96E-EA72A143C5AE}.Debug|Win32.ActiveCfg = Debug|Win32 + {07BDA8F7-4AAF-4A3B-B96E-EA72A143C5AE}.Debug|Win32.Build.0 = Debug|Win32 + {07BDA8F7-4AAF-4A3B-B96E-EA72A143C5AE}.Debug|x64.ActiveCfg = Debug|x64 + {07BDA8F7-4AAF-4A3B-B96E-EA72A143C5AE}.Debug|x64.Build.0 = Debug|x64 + {07BDA8F7-4AAF-4A3B-B96E-EA72A143C5AE}.Release|Win32.ActiveCfg = Release|Win32 + {07BDA8F7-4AAF-4A3B-B96E-EA72A143C5AE}.Release|Win32.Build.0 = Release|Win32 + {07BDA8F7-4AAF-4A3B-B96E-EA72A143C5AE}.Release|x64.ActiveCfg = Release|x64 + {07BDA8F7-4AAF-4A3B-B96E-EA72A143C5AE}.Release|x64.Build.0 = Release|x64 + {814EBFD3-3CE6-4933-A580-C1FE3147ACB4}.Debug|Win32.ActiveCfg = Debug|Win32 + {814EBFD3-3CE6-4933-A580-C1FE3147ACB4}.Debug|Win32.Build.0 = Debug|Win32 + {814EBFD3-3CE6-4933-A580-C1FE3147ACB4}.Debug|x64.ActiveCfg = Debug|x64 + {814EBFD3-3CE6-4933-A580-C1FE3147ACB4}.Debug|x64.Build.0 = Debug|x64 + {814EBFD3-3CE6-4933-A580-C1FE3147ACB4}.Release|Win32.ActiveCfg = Release|Win32 + {814EBFD3-3CE6-4933-A580-C1FE3147ACB4}.Release|Win32.Build.0 = Release|Win32 + {814EBFD3-3CE6-4933-A580-C1FE3147ACB4}.Release|x64.ActiveCfg = Release|x64 + {814EBFD3-3CE6-4933-A580-C1FE3147ACB4}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/client/win_build/seti_boinc.vcproj b/client/win_build/seti_boinc.vcproj new file mode 100755 index 0000000..6af0150 --- /dev/null +++ b/client/win_build/seti_boinc.vcproj @@ -0,0 +1,785 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/win_build/seti_boinc_gcc3.dev b/client/win_build/seti_boinc_gcc3.dev new file mode 100644 index 0000000..f39a9a2 --- /dev/null +++ b/client/win_build/seti_boinc_gcc3.dev @@ -0,0 +1,2119 @@ +[Project] +FileName=seti_boinc_gcc3.dev +Name=seti_boinc +UnitCount=129 +Type=0 +Ver=1 +ObjFiles= +Includes=Release;..;../..;../../db;../../../boinc;../../../boinc/lib;../../../boinc/incmore;../../../boinc/api;../../jpeglib;../../image_libs;../../glut;../../vector_lib;. +Libs=Release +PrivateResource=seti_boinc_private.rc +ResourceIncludes= +MakeIncludes= +Compiler=-DUSE_ASMLIB_@@_-DWIN32_@@_-D_WIN32_@@_-D_MT_@@_-DNDEBUG_@@_-D_WINDOWS _@@_-DBOINC_@@_-DCLIENT_@@_-DNODB_@@_-DBOINC_APP_GRAPHICS_@@_-D_CONSOLE_@@_-mtune=pentium-m_@@_-fomit-frame-pointer_@@_-malign-double_@@_-mpreferred-stack-boundary=4_@@_-fstrict-aliasing _@@_-ffast-math_@@_ +CppCompiler=-DUSE_ASMLIB_@@_-DWIN32_@@_-D_WIN32_@@_-D_MT_@@_-DNDEBUG_@@_-D_WINDOWS _@@_-DBOINC_@@_-DCLIENT_@@_-DNODB_@@_-DBOINC_APP_GRAPHICS_@@_-D_CONSOLE_@@_-mtune=pentium-m_@@_-fomit-frame-pointer_@@_-malign-double_@@_-mpreferred-stack-boundary=4_@@_-fstrict-aliasing _@@_-ffast-math_@@_ +Linker=libfftw3f.lib_@@_../vector/asmlibm.lib_@@_ +IsCpp=1 +Icon= +ExeOutput=. +ObjectOutput=.\Release +OverrideOutput=1 +OverrideOutputName=setiathome_6.97_windows_intelx86.exe +HostApplication= +Folders=fftw3,libboinc,libboinc/include,libboinc/src,libboincapi,libboincapi/include,libboincapi/src,libgraphics2,libgraphics2/include,libgraphics2/src,seti_boinc,seti_boinc/include,seti_boinc/src,setiboincdb,setiboincdb/include,setiboincdb/src +CommandLine=--verbose +UseCustomMakefile=0 +CustomMakefile=MakeS15.jws +IncludeVersionInfo=1 +SupportXPThemes=1 +CompilerSet=0 +CompilerSettings=0000001001001000000010 + +[Unit1] +FileName=..\worker.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=..\analyze.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=..\analyzeFuncs.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit4] +FileName=..\analyzeFuncs.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=..\analyzePoT.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit6] +FileName=..\analyzePoT.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit7] +FileName=..\analyzeReport.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit8] +FileName=..\analyzeReport.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit9] +FileName=..\chirpfft.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit10] +FileName=..\chirpfft.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit11] +FileName=..\fft8g.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit12] +FileName=..\fft8g.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit13] +FileName=..\gaussfit.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit14] +FileName=..\gaussfit.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit15] +FileName=..\gdata.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit16] +FileName=..\gdata.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit17] +FileName=..\lcgamm.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit18] +FileName=..\lcgamm.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit19] +FileName=..\main.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit20] +FileName=..\malloc_a.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit21] +FileName=..\malloc_a.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit22] +FileName=..\progress.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit23] +FileName=..\progress.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit24] +FileName=..\pulsefind.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit25] +FileName=..\pulsefind.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit26] +FileName=..\s_util.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit27] +FileName=..\s_util.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit31] +FileName=..\seti_header.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit32] +FileName=..\sincos.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit33] +FileName=..\spike.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit34] +FileName=..\spike.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit35] +FileName=..\timecvt.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit36] +FileName=..\timecvt.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit37] +FileName=..\sah_version.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit38] +FileName=..\sah_version.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit39] +FileName=..\win-sah_config.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit40] +FileName=..\worker.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit41] +FileName=..\..\db\track_mem.h +CompileCpp=1 +Folder=setiboincdb/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit42] +FileName=..\..\db\xml_util.h +CompileCpp=1 +Folder=setiboincdb/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit43] +FileName=..\..\db\db_table.h +CompileCpp=1 +Folder=setiboincdb/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit44] +FileName=..\..\db\sqlapi.h +CompileCpp=1 +Folder=setiboincdb/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[VersionInfo] +Major=6 +Minor=97 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName=Space Sciences Laboratory +FileVersion=6.97 +FileDescription=setiathome_v7 +InternalName=setiathome_v7 +LegalCopyright=Copyright 2011, Regents University of California +LegalTrademarks= +OriginalFilename= +ProductName=setiathome_v7 +ProductVersion=6.97 +AutoIncBuildNr=0 + +[Unit45] +FileName=..\..\db\sqlblob.h +CompileCpp=1 +Folder=setiboincdb/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit46] +FileName=..\..\db\sqldefs.h +CompileCpp=1 +Folder=setiboincdb/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit47] +FileName=..\..\db\sqlint8.h +CompileCpp=1 +Folder=setiboincdb/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit48] +FileName=..\..\db\sqlrow.h +CompileCpp=1 +Folder=setiboincdb/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit49] +FileName=..\..\db\xml_util.cpp +CompileCpp=1 +Folder=setiboincdb/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit50] +FileName=..\..\db\sqlblob.cpp +CompileCpp=1 +Folder=setiboincdb/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit51] +FileName=..\..\db\sqlint8.cpp +CompileCpp=1 +Folder=setiboincdb/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit52] +FileName=..\..\db\sqlrow.cpp +CompileCpp=1 +Folder=setiboincdb/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit60] +FileName=..\..\..\boinc\lib\mem_usage.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit63] +FileName=..\..\..\boinc\lib\parse.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit64] +FileName=..\..\..\boinc\lib\prefs.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit65] +FileName=..\..\..\boinc\lib\proxy_info.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit66] +FileName=..\..\..\boinc\lib\shmem.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit67] +FileName=..\..\..\boinc\lib\util.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit68] +FileName=..\..\..\boinc\lib\app_ipc.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit69] +FileName=..\..\..\boinc\lib\diagnostics.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit70] +FileName=..\..\..\boinc\lib\error_numbers.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit71] +FileName=..\..\..\boinc\lib\filesys.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit72] +FileName=..\..\..\boinc\lib\hostinfo.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit73] +FileName=..\..\..\boinc\lib\mem_usage.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit74] +FileName=..\..\..\boinc\lib\mfile.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit76] +FileName=..\..\..\boinc\lib\parse.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit77] +FileName=..\..\..\boinc\lib\std_fixes.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit78] +FileName=..\..\..\boinc\lib\boinc_win.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit79] +FileName=..\..\..\boinc\api\boinc_api.cpp +CompileCpp=1 +Folder=libboincapi/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit80] +FileName=..\..\..\boinc\api\graphics_data.cpp +CompileCpp=1 +Folder=libboincapi/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit81] +FileName=..\..\..\boinc\api\reduce_main.cpp +CompileCpp=1 +Folder=libboincapi/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit83] +FileName=..\..\..\boinc\api\texture.h +CompileCpp=1 +Folder=libboincapi/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit84] +FileName=..\..\..\boinc\api\boinc_api.h +CompileCpp=1 +Folder=libboincapi/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit86] +FileName=..\..\..\boinc\api\graphics_api.h +CompileCpp=1 +Folder=libboincapi/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit87] +FileName=..\..\..\boinc\api\graphics_data.h +CompileCpp=1 +Folder=libboincapi/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit90] +FileName=fftw3.h +CompileCpp=1 +Folder=fftw3 +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit91] +FileName=..\..\db\schema_master.cpp +CompileCpp=1 +Folder=setiboincdb/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit92] +FileName=..\..\db\schema_master.h +CompileCpp=1 +Folder=setiboincdb/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit93] +FileName=..\..\..\boinc\version.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit94] +FileName=..\..\..\boinc\lib\stackwalker_win.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit95] +FileName=..\..\..\boinc\lib\diagnostics_win.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit96] +FileName=..\..\..\boinc\lib\diagnostics_win.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit100] +FileName=..\vector\sighandler.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit101] +FileName=..\vector\hires_timer.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit102] +FileName=..\vector\hires_timer.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit103] +FileName=..\vector\analyzeFuncs_x86_64.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=1 +BuildCmd=$(CPP) -msse2 -DUSE_SSE -DUSE_SSE2 -c ../vector/analyzeFuncs_x86_64.cpp -o ./Release/analyzeFuncs_x86_64.o $(CXXFLAGS) + +[Unit104] +FileName=..\vector\analyzeFuncs_sse.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=1 +BuildCmd=$(CPP) -msse -DUSE_SSE -c ../vector/analyzeFuncs_sse.cpp -o ./Release/analyzeFuncs_sse.o $(CXXFLAGS) + +[Unit105] +FileName=..\vector\x86_float4.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=1 +BuildCmd=$(CPP) -msse -c ../vector/x86_float4.cpp -o ./Release/x86_float4.o $(CXXFLAGS) + +[Unit106] +FileName=..\vector\x86_float4.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit107] +FileName=..\vector\x86_ops.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit108] +FileName=..\..\..\boinc\lib\win_util.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit109] +FileName=..\..\..\boinc\lib\win_util.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit110] +FileName=..\..\..\boinc\lib\str_util.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit111] +FileName=..\..\..\boinc\lib\str_util.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit112] +FileName=..\vector\analyzeFuncs_sse3.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=1 +BuildCmd=$(CPP) -msse3 -DUSE_SSE -DUSE_SSE2 -DUSE_SSE3 -c ../vector/analyzeFuncs_sse3.cpp -o ./Release/analyzeFuncs_sse3.o $(CXXFLAGS) + +[Unit113] +FileName=..\vector\analyzeFuncs_sse2.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=1 +BuildCmd=$(CPP) -msse2 -DUSE_SSE -DUSE_SSE2 -c ../vector/analyzeFuncs_sse2.cpp -o ./Release/analyzeFuncs_sse2.o $(CXXFLAGS) + +[Unit114] +FileName=..\vector\analyzeFuncs_fpu.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit115] +FileName=..\sah_gfx_main.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit116] +FileName=..\sah_gfx_main.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit118] +FileName=..\..\..\boinc\api\graphics2.h +CompileCpp=1 +Folder=libgraphics2/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit122] +FileName=..\..\..\boinc\lib\str_replace.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit123] +FileName=..\autocorr.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit124] +FileName=..\autocorr.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit126] +FileName=..\..\..\boinc\lib\procinfo.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit127] +FileName=..\..\..\boinc\lib\procinfo_win.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit128] +FileName=..\vector\analyzeFuncs_avx.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd=$(CPP) -mavx -DUSE_SSE -DUSE_SSE2 -DUSE_SSE3 -DUSE_AVX -c ../vector/analyzeFuncs_avx.cpp -o ./Release/analyzeFuncs_avx.o $(CXXFLAGS) + +[Unit129] +FileName=..\..\sah_config.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit130] +FileName=..\..\jpeglib\jcomapi.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit131] +FileName=..\..\jpeglib\jcparam.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit132] +FileName=..\..\jpeglib\jcphuff.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit133] +FileName=..\..\jpeglib\jcprepct.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit134] +FileName=..\..\jpeglib\jcsample.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit135] +FileName=..\..\jpeglib\jctrans.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit136] +FileName=..\..\jpeglib\jdapimin.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit137] +FileName=..\..\jpeglib\jdapistd.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit138] +FileName=..\..\jpeglib\jdatadst.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit139] +FileName=..\..\jpeglib\jdatasrc.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit140] +FileName=..\..\jpeglib\jdcoefct.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit141] +FileName=..\..\jpeglib\jdcolor.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit143] +FileName=..\..\jpeglib\jdhuff.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit144] +FileName=..\..\jpeglib\jdinput.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit145] +FileName=..\..\jpeglib\jdmainct.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit146] +FileName=..\..\jpeglib\jdmarker.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit147] +FileName=..\..\jpeglib\jdmaster.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit148] +FileName=..\..\jpeglib\jdmerge.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit149] +FileName=..\..\jpeglib\jdphuff.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit150] +FileName=..\..\jpeglib\jdpostct.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit151] +FileName=..\..\jpeglib\jdsample.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit152] +FileName=..\..\jpeglib\jdtrans.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit153] +FileName=..\..\jpeglib\jerror.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit154] +FileName=..\..\jpeglib\jfdctflt.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit155] +FileName=..\..\jpeglib\jfdctfst.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit156] +FileName=..\..\jpeglib\jfdctint.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit157] +FileName=..\..\jpeglib\jidctflt.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit158] +FileName=..\..\jpeglib\jidctfst.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit159] +FileName=..\..\jpeglib\jidctint.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit160] +FileName=..\..\jpeglib\jidctred.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit161] +FileName=..\..\jpeglib\jmemmgr.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit162] +FileName=..\..\jpeglib\jmemnobs.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit163] +FileName=..\..\jpeglib\jquant1.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit164] +FileName=..\..\jpeglib\jquant2.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit165] +FileName=..\..\jpeglib\jutils.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit166] +FileName=..\..\jpeglib\rdbmp.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit167] +FileName=..\..\jpeglib\rdcolmap.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit168] +FileName=..\..\jpeglib\rdgif.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit169] +FileName=..\..\jpeglib\rdppm.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit170] +FileName=..\..\jpeglib\rdrle.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit171] +FileName=..\..\jpeglib\rdswitch.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit175] +FileName=..\..\jpeglib\jchuff.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit176] +FileName=..\..\jpeglib\jconfig.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit177] +FileName=..\..\jpeglib\jdct.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit178] +FileName=..\..\jpeglib\jdhuff.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit179] +FileName=..\..\jpeglib\jerror.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit180] +FileName=..\..\jpeglib\jinclude.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit181] +FileName=..\..\jpeglib\jmemsys.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit182] +FileName=..\..\jpeglib\jmorecfg.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit183] +FileName=..\..\jpeglib\jpegint.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit184] +FileName=..\..\jpeglib\jpeglib.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit185] +FileName=..\sah_gfx_main.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit186] +FileName=..\sah_gfx_main.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit142] +FileName=..\..\jpeglib\jddctmgr.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit187] +FileName=..\..\..\boinc\api\graphics2_util.cpp +CompileCpp=1 +Folder=libgraphics2/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit188] +FileName=..\..\..\boinc\api\graphics2.h +CompileCpp=1 +Folder=libgraphics2/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit189] +FileName=..\..\..\boinc\api\graphics2.h +CompileCpp=1 +Folder=libgraphics2/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit190] +FileName=..\..\..\boinc\api\graphics2.h +CompileCpp=1 +Folder=libgraphics2/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit191] +FileName=..\..\..\boinc\api\graphics2.h +CompileCpp=1 +Folder=libgraphics2/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit192] +FileName=..\..\jpeglib\jchuff.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit193] +FileName=..\..\jpeglib\jconfig.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit194] +FileName=..\..\jpeglib\jdct.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit195] +FileName=..\..\jpeglib\jdhuff.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit196] +FileName=..\..\jpeglib\jerror.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit197] +FileName=..\..\jpeglib\jinclude.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit198] +FileName=..\..\jpeglib\jmemsys.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit199] +FileName=..\..\jpeglib\jmorecfg.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit204] +FileName=..\..\..\boinc\api\graphics2_util.cpp +CompileCpp=1 +Folder=libgraphics2/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit205] +FileName=..\..\..\boinc\api\graphics2.h +CompileCpp=1 +Folder=libgraphics2/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit200] +FileName=..\..\jpeglib\jpegint.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit201] +FileName=..\..\jpeglib\jpeglib.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit202] +FileName=..\sah_gfx_main.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit203] +FileName=..\sah_gfx_main.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit206] +FileName=..\..\..\boinc\api\graphics2.h +CompileCpp=1 +Folder=libgraphics2/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit208] +FileName=..\..\jpeglib\jpegint.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit209] +FileName=..\..\jpeglib\jpeglib.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit210] +FileName=..\vector\analyzeFuncs_fpu.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit207] +FileName=..\sah_gfx_main.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit75] +FileName=..\..\..\boinc\lib\miofile.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit82] +FileName=..\..\..\boinc\api\texture.cpp +CompileCpp=1 +Folder=libboincapi/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit88] +FileName=..\..\..\boinc\api\graphics_impl.h +CompileCpp=1 +Folder=libboincapi/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit89] +FileName=..\..\..\boinc\api\gutil.h +CompileCpp=1 +Folder=libboincapi/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit28] +FileName=..\seti.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit29] +FileName=..\seti.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit30] +FileName=..\seti_header.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit117] +FileName=..\..\..\boinc\api\graphics2_util.cpp +CompileCpp=1 +Folder=libgraphics2/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit98] +FileName=..\vector\analyzeFuncs_vector.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=1 +BuildCmd=$(CPP) $(CXXFLAGS) -DUSE_SSE -DUSE_SSE2 -DUSE_SSE3 -DUSE_3DNOW -c ../vector/analyzeFuncs_vector.cpp -o ./Release/analyzeFuncs_vector.o + +[Unit99] +FileName=..\vector\analyzeFuncs_vector.h +CompileCpp=1 +Folder=seti_boinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit57] +FileName=..\..\..\boinc\lib\hostinfo.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit58] +FileName=..\..\..\boinc\lib\md5.c +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit59] +FileName=..\..\..\boinc\lib\md5_file.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit61] +FileName=..\..\..\boinc\lib\mfile.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit62] +FileName=..\..\..\boinc\lib\miofile.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit85] +FileName=..\..\..\boinc\api\boinc_gl.h +CompileCpp=1 +Folder=libboincapi/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit97] +FileName=..\vector\analyzeFuncs_altivec.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit119] +FileName=..\..\..\boinc\lib\url.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit120] +FileName=..\..\..\boinc\lib\coproc.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit121] +FileName=..\..\..\boinc\lib\coproc.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit53] +FileName=..\..\..\boinc\lib\util.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit54] +FileName=..\..\..\boinc\lib\app_ipc.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit55] +FileName=..\..\..\boinc\lib\diagnostics.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit56] +FileName=..\..\..\boinc\lib\filesys.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit125] +FileName=..\..\..\boinc\lib\procinfo.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/client/win_build/seti_boinc_private.h b/client/win_build/seti_boinc_private.h new file mode 100644 index 0000000..293402e --- /dev/null +++ b/client/win_build/seti_boinc_private.h @@ -0,0 +1,23 @@ +/* THIS FILE WILL BE OVERWRITTEN BY DEV-C++ */ +/* DO NOT EDIT ! */ + +#ifndef SETI_BOINC_PRIVATE_H +#define SETI_BOINC_PRIVATE_H + +/* VERSION DEFINITIONS */ +#define VER_STRING "6.97.0.0" +#define VER_MAJOR 6 +#define VER_MINOR 97 +#define VER_RELEASE 0 +#define VER_BUILD 0 +#define COMPANY_NAME "Space Sciences Laboratory" +#define FILE_VERSION "6.97" +#define FILE_DESCRIPTION "setiathome_v7" +#define INTERNAL_NAME "setiathome_v7" +#define LEGAL_COPYRIGHT "Copyright 2011, Regents University of California" +#define LEGAL_TRADEMARKS "" +#define ORIGINAL_FILENAME "" +#define PRODUCT_NAME "setiathome_v7" +#define PRODUCT_VERSION "6.97" + +#endif /*SETI_BOINC_PRIVATE_H*/ diff --git a/client/win_build/seti_boinc_private.rc b/client/win_build/seti_boinc_private.rc new file mode 100644 index 0000000..a9f2b20 --- /dev/null +++ b/client/win_build/seti_boinc_private.rc @@ -0,0 +1,42 @@ +/* THIS FILE WILL BE OVERWRITTEN BY DEV-C++ */ +/* DO NOT EDIT! */ + +#include // include for version info constants + + +// +// SUPPORT FOR WINDOWS XP THEMES: +// THIS WILL MAKE THE PROGRAM USE THE COMMON CONTROLS +// LIBRARY VERSION 6.0 (IF IT IS AVAILABLE) +// +1 24 "./setiathome_6.97_windows_intelx86.exe.Manifest" + +// +// TO CHANGE VERSION INFORMATION, EDIT PROJECT OPTIONS... +// +1 VERSIONINFO +FILEVERSION 6,97,0,0 +PRODUCTVERSION 6,97,0,0 +FILETYPE VFT_APP +{ + BLOCK "StringFileInfo" + { + BLOCK "040904E4" + { + VALUE "CompanyName", "Space Sciences Laboratory" + VALUE "FileVersion", "6.97" + VALUE "FileDescription", "setiathome_v7" + VALUE "InternalName", "setiathome_v7" + VALUE "LegalCopyright", "Copyright 2011, Regents University of California" + VALUE "LegalTrademarks", "" + VALUE "OriginalFilename", "" + VALUE "ProductName", "setiathome_v7" + VALUE "ProductVersion", "6.97" + } + } + BLOCK "VarFileInfo" + { + VALUE "Translation", 0x0409, 1252 + } +} + diff --git a/client/win_build/seti_graphics.dev b/client/win_build/seti_graphics.dev new file mode 100644 index 0000000..1f201e6 --- /dev/null +++ b/client/win_build/seti_graphics.dev @@ -0,0 +1,2149 @@ +[Project] +FileName=seti_graphics.dev +Name=seti_graphics +UnitCount=148 +Type=0 +Ver=1 +ObjFiles= +Includes=Release;..;../..;../../db;../../../boinc;../../../boinc/win_build;../../../boinc/lib;../../../boinc/api;../../jpeglib;../../image_libs;../../glut;../../vector_lib;. +Libs=Release +PrivateResource=seti_graphics_private.rc +ResourceIncludes= +MakeIncludes= +Compiler=-DUSE_ASMLIB_@@_-DWIN32_@@_-D_WIN32_@@_-D_MT_@@_-DNDEBUG_@@_-D_WINDOWS _@@_-DBOINC_@@_-DCLIENT_@@_-DNODB_@@_-DBOINC_APP_GRAPHICS_@@_-D_CONSOLE_@@_-mtune=pentium-m_@@_-fomit-frame-pointer_@@_-malign-double_@@_-mpreferred-stack-boundary=4_@@_-fstrict-aliasing _@@_-ffast-math_@@_ +CppCompiler=-DUSE_ASMLIB_@@_-DWIN32_@@_-D_WIN32_@@_-D_MT_@@_-DNDEBUG_@@_-D_WINDOWS _@@_-DBOINC_@@_-DCLIENT_@@_-DNODB_@@_-DBOINC_APP_GRAPHICS_@@_-D_CONSOLE_@@_-mtune=pentium-m_@@_-fomit-frame-pointer_@@_-malign-double_@@_-mpreferred-stack-boundary=4_@@_-fstrict-aliasing _@@_-ffast-math_@@_ +Linker=c:/MinGW/lib/libglu32.a_@@_c:/MinGW/lib/libglaux.a_@@_c:/MinGW/lib/libopengl32.a_@@_-static-libgcc_@@_-static-libstdc++_@@_-lmingw32_@@_ +IsCpp=1 +Icon= +ExeOutput=. +ObjectOutput=.\Release +OverrideOutput=1 +OverrideOutputName=setigraphics_6.97_windows_intelx86.exe +HostApplication= +Folders=glut,glut/include,glut/src,image_libs,image_libs/include,image_libs/src,jpeglib,jpeglib/include,jpeglib/src,libboinc,libboinc/include,libboinc/src,libgraphics2,libgraphics2/include,libgraphics2/src,seti_graphics,seti_graphics/include,seti_graphics/src +CommandLine= +UseCustomMakefile=0 +CustomMakefile= +IncludeVersionInfo=1 +SupportXPThemes=1 +CompilerSet=1 +CompilerSettings=00000010010010000001b0 + +[Unit15] +FileName=..\..\glut\win32_glx.c +CompileCpp=1 +Folder=glut/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit16] +FileName=..\..\glut\win32_util.c +CompileCpp=1 +Folder=glut/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit17] +FileName=..\..\image_libs\bmplib.h +CompileCpp=1 +Folder=image_libs/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit20] +FileName=..\..\jpeglib\jcapimin.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit21] +FileName=..\..\jpeglib\jcapistd.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit22] +FileName=..\..\jpeglib\jccoefct.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit23] +FileName=..\..\jpeglib\jccolor.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit27] +FileName=..\..\jpeglib\jcmainct.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit28] +FileName=..\..\jpeglib\jcmarker.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit30] +FileName=..\..\jpeglib\jcomapi.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit32] +FileName=..\..\jpeglib\jcphuff.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit37] +FileName=..\..\jpeglib\jdapistd.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit39] +FileName=..\..\jpeglib\jdatasrc.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit40] +FileName=..\..\jpeglib\jdcoefct.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit41] +FileName=..\..\jpeglib\jdcolor.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit42] +FileName=..\..\jpeglib\jddctmgr.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit44] +FileName=..\..\jpeglib\jdinput.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[VersionInfo] +Major=6 +Minor=97 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName=Space Sciences Laboratory +FileVersion=6.97 +FileDescription=setiathome_graphics +InternalName=setiathome_graphics +LegalCopyright=Copyright 2011, Regents University of California +LegalTrademarks= +OriginalFilename= +ProductName=setiathome_graphics +ProductVersion=6.97 +AutoIncBuildNr=0 + +[Unit46] +FileName=..\..\jpeglib\jdmarker.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit47] +FileName=..\..\jpeglib\jdmaster.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit48] +FileName=..\..\jpeglib\jdmerge.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit50] +FileName=..\..\jpeglib\jdpostct.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit51] +FileName=..\..\jpeglib\jdsample.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit52] +FileName=..\..\jpeglib\jdtrans.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit54] +FileName=..\..\jpeglib\jfdctflt.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit55] +FileName=..\..\jpeglib\jfdctfst.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit56] +FileName=..\..\jpeglib\jfdctint.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit57] +FileName=..\..\jpeglib\jidctflt.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit58] +FileName=..\..\jpeglib\jidctfst.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit62] +FileName=..\..\jpeglib\jmemnobs.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit63] +FileName=..\..\jpeglib\jquant1.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit64] +FileName=..\..\jpeglib\jquant2.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit66] +FileName=..\..\jpeglib\rdbmp.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit67] +FileName=..\..\jpeglib\rdcolmap.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit70] +FileName=..\..\jpeglib\rdrle.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit72] +FileName=..\..\jpeglib\jversion.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit73] +FileName=..\..\jpeglib\cderror.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit74] +FileName=..\..\jpeglib\cdjpeg.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit76] +FileName=..\..\jpeglib\jconfig.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit77] +FileName=..\..\jpeglib\jdct.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit78] +FileName=..\..\jpeglib\jdhuff.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit79] +FileName=..\..\jpeglib\jerror.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit80] +FileName=..\..\jpeglib\jinclude.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit81] +FileName=..\..\jpeglib\jmemsys.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit84] +FileName=..\..\jpeglib\jpeglib.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit85] +FileName=..\sah_gfx.h +CompileCpp=1 +Folder=seti_graphics/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit86] +FileName=..\sah_gfx_base.h +CompileCpp=1 +Folder=seti_graphics/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit87] +FileName=..\timecvt.cpp +CompileCpp=1 +Folder=seti_graphics/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit90] +FileName=..\..\..\boinc\api\graphics2.h +CompileCpp=1 +Folder=libgraphics2/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit91] +FileName=..\..\..\boinc\api\graphics_api.h +CompileCpp=1 +Folder=libgraphics2/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit92] +FileName=..\..\..\boinc\api\graphics_data.h +CompileCpp=1 +Folder=libgraphics2/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit93] +FileName=..\..\..\boinc\api\graphics_impl.h +CompileCpp=1 +Folder=libgraphics2/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit94] +FileName=..\..\..\boinc\api\gutil.h +CompileCpp=1 +Folder=libgraphics2/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit95] +FileName=..\..\..\boinc\api\texture.h +CompileCpp=1 +Folder=libgraphics2/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit96] +FileName=..\..\..\boinc\api\txf_util.h +CompileCpp=1 +Folder=libgraphics2/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit97] +FileName=..\..\..\boinc\api\boinc_api.cpp +CompileCpp=1 +Folder=libgraphics2/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit98] +FileName=..\..\..\boinc\api\graphics2.cpp +CompileCpp=1 +Folder=libgraphics2/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit100] +FileName=..\..\..\boinc\api\graphics2_util.cpp +CompileCpp=1 +Folder=libgraphics2/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit101] +FileName=..\..\..\boinc\api\graphics2_win.cpp +CompileCpp=1 +Folder=libgraphics2/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit102] +FileName=..\..\..\boinc\api\gutil.cpp +CompileCpp=1 +Folder=libgraphics2/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit103] +FileName=..\..\..\boinc\api\gutil_text.cpp +CompileCpp=1 +Folder=libgraphics2/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit105] +FileName=..\..\..\boinc\api\reduce_main.cpp +CompileCpp=1 +Folder=libgraphics2/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit106] +FileName=..\..\..\boinc\api\texfont.cpp +CompileCpp=1 +Folder=libgraphics2/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit107] +FileName=..\..\..\boinc\api\texture.cpp +CompileCpp=1 +Folder=libgraphics2/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit108] +FileName=..\..\..\boinc\api\tgalib.cpp +CompileCpp=1 +Folder=libgraphics2/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit109] +FileName=..\..\..\boinc\lib\str_util.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit110] +FileName=..\..\..\boinc\lib\str_util.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit111] +FileName=..\graphics_main.cpp +CompileCpp=1 +Folder=seti_graphics/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit112] +FileName=..\..\..\boinc\lib\app_ipc.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit113] +FileName=..\..\..\boinc\lib\app_ipc.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit114] +FileName=..\..\..\boinc\lib\filesys.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit115] +FileName=..\..\..\boinc\lib\filesys.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit116] +FileName=..\..\..\boinc\lib\parse.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit118] +FileName=..\..\..\boinc\lib\util.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit119] +FileName=..\..\..\boinc\lib\util.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit121] +FileName=..\..\..\boinc\lib\diagnostics.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit122] +FileName=..\..\..\boinc\lib\stackwalker_win.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit124] +FileName=..\..\..\boinc\lib\shmem.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit125] +FileName=..\..\..\boinc\lib\shmem.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit126] +FileName=..\..\..\boinc\lib\hostinfo.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit127] +FileName=..\..\..\boinc\lib\hostinfo.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit130] +FileName=..\..\..\boinc\lib\miofile.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit131] +FileName=..\..\..\boinc\lib\mfile.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit132] +FileName=..\..\..\boinc\lib\mfile.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit133] +FileName=..\..\..\boinc\lib\miofile.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit134] +FileName=..\..\..\boinc\lib\proxy_info.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit135] +FileName=..\..\..\boinc\lib\procinfo_win.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit138] +FileName=..\..\..\boinc\lib\win_util.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit140] +FileName=..\..\..\boinc\lib\md5_file.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit141] +FileName=..\..\..\boinc\lib\md5_file.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit143] +FileName=..\..\..\boinc\lib\md5.c +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit144] +FileName=..\..\..\boinc\lib\boinc_win.h +CompileCpp=1 +Folder=libgraphics2/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit145] +FileName=..\..\..\boinc\lib\coproc.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit146] +FileName=..\..\..\boinc\lib\url.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit148] +FileName=..\..\..\boinc\lib\procinfo.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit149] +FileName=..\..\jpeglib\jcdctmgr.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit150] +FileName=..\..\jpeglib\jchuff.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit151] +FileName=..\..\jpeglib\jcinit.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit152] +FileName=..\..\jpeglib\jcmainct.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit153] +FileName=..\..\jpeglib\jcmarker.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit154] +FileName=..\..\jpeglib\jcmaster.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit155] +FileName=..\..\jpeglib\jcomapi.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit156] +FileName=..\..\jpeglib\jcparam.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit157] +FileName=..\..\jpeglib\jcphuff.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit158] +FileName=..\..\jpeglib\jcprepct.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit159] +FileName=..\..\jpeglib\jcsample.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit160] +FileName=..\..\jpeglib\jctrans.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit161] +FileName=..\..\jpeglib\jdapimin.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit162] +FileName=..\..\jpeglib\jdapistd.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit163] +FileName=..\..\jpeglib\jdatadst.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit164] +FileName=..\..\jpeglib\jdatasrc.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit165] +FileName=..\..\jpeglib\jdcoefct.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit166] +FileName=..\..\jpeglib\jdcolor.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit167] +FileName=..\..\jpeglib\jddctmgr.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit168] +FileName=..\..\jpeglib\jdhuff.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit169] +FileName=..\..\jpeglib\jdinput.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit170] +FileName=..\..\jpeglib\jdmainct.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit171] +FileName=..\..\jpeglib\jdmarker.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit172] +FileName=..\..\jpeglib\jdmaster.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit173] +FileName=..\..\jpeglib\jdmerge.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit174] +FileName=..\..\jpeglib\jdphuff.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit175] +FileName=..\..\jpeglib\jdpostct.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit176] +FileName=..\..\jpeglib\jdsample.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit177] +FileName=..\..\jpeglib\jdtrans.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit178] +FileName=..\..\jpeglib\jerror.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit179] +FileName=..\..\jpeglib\jfdctflt.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit180] +FileName=..\..\jpeglib\jfdctfst.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit181] +FileName=..\..\jpeglib\jfdctint.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit182] +FileName=..\..\jpeglib\jidctflt.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit183] +FileName=..\..\jpeglib\jidctfst.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit184] +FileName=..\..\jpeglib\jidctint.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit185] +FileName=..\..\jpeglib\jidctred.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit186] +FileName=..\..\jpeglib\jmemmgr.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit142] +FileName=..\..\..\boinc\lib\md5.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit187] +FileName=..\..\jpeglib\jmemnobs.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit188] +FileName=..\..\jpeglib\jquant1.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit189] +FileName=..\..\jpeglib\jquant2.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit190] +FileName=..\..\jpeglib\jutils.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit191] +FileName=..\..\jpeglib\rdbmp.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit192] +FileName=..\..\jpeglib\rdcolmap.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit193] +FileName=..\..\jpeglib\rdgif.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit194] +FileName=..\..\jpeglib\rdppm.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit195] +FileName=..\..\jpeglib\rdrle.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit196] +FileName=..\..\jpeglib\rdswitch.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit197] +FileName=..\..\jpeglib\jversion.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit198] +FileName=..\..\jpeglib\cderror.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit199] +FileName=..\..\jpeglib\cdjpeg.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit204] +FileName=..\..\jpeglib\jerror.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit205] +FileName=..\..\jpeglib\jinclude.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit200] +FileName=..\..\jpeglib\jchuff.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit201] +FileName=..\..\jpeglib\jconfig.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit202] +FileName=..\..\jpeglib\jdct.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit203] +FileName=..\..\jpeglib\jdhuff.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit206] +FileName=..\..\jpeglib\jmemsys.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit208] +FileName=..\..\jpeglib\jpegint.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit209] +FileName=..\..\jpeglib\jpeglib.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit210] +FileName=..\vector\analyzeFuncs_fpu.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit207] +FileName=..\..\jpeglib\jmorecfg.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit75] +FileName=..\..\jpeglib\jchuff.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit82] +FileName=..\..\jpeglib\jmorecfg.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit89] +FileName=..\..\..\boinc\api\boinc_gl.h +CompileCpp=1 +Folder=libgraphics2/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=..\sah_gfx.cpp +CompileCpp=1 +Folder=seti_graphics/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=..\sah_gfx_base.cpp +CompileCpp=1 +Folder=seti_graphics/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=..\..\glut\win32_x11.h +CompileCpp=1 +Folder=glut/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit4] +FileName=..\..\glut\glut.h +CompileCpp=1 +Folder=glut/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=..\..\glut\glutbitmap.h +CompileCpp=1 +Folder=glut/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit6] +FileName=..\..\glut\glutint.h +CompileCpp=1 +Folder=glut/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit7] +FileName=..\..\glut\glutstroke.h +CompileCpp=1 +Folder=glut/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit8] +FileName=..\..\glut\glutwin32.h +CompileCpp=1 +Folder=glut/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit9] +FileName=..\..\glut\stroke.h +CompileCpp=1 +Folder=glut/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit10] +FileName=..\..\glut\win32_glx.h +CompileCpp=1 +Folder=glut/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit11] +FileName=..\..\glut\win32_x11.c +CompileCpp=1 +Folder=glut/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit12] +FileName=..\..\glut\glut_roman.c +CompileCpp=1 +Folder=glut/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit13] +FileName=..\..\glut\glut_stroke.c +CompileCpp=1 +Folder=glut/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit14] +FileName=..\..\glut\glut_swidth.c +CompileCpp=1 +Folder=glut/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit24] +FileName=..\..\jpeglib\jcdctmgr.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit25] +FileName=..\..\jpeglib\jchuff.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit26] +FileName=..\..\jpeglib\jcinit.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit29] +FileName=..\..\jpeglib\jcmaster.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit31] +FileName=..\..\jpeglib\jcparam.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit33] +FileName=..\..\jpeglib\jcprepct.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit34] +FileName=..\..\jpeglib\jcsample.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit35] +FileName=..\..\jpeglib\jctrans.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit36] +FileName=..\..\jpeglib\jdapimin.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit38] +FileName=..\..\jpeglib\jdatadst.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit43] +FileName=..\..\jpeglib\jdhuff.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit45] +FileName=..\..\jpeglib\jdmainct.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit49] +FileName=..\..\jpeglib\jdphuff.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit53] +FileName=..\..\jpeglib\jerror.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit59] +FileName=..\..\jpeglib\jidctint.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit60] +FileName=..\..\jpeglib\jidctred.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit61] +FileName=..\..\jpeglib\jmemmgr.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit65] +FileName=..\..\jpeglib\jutils.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit68] +FileName=..\..\jpeglib\rdgif.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit69] +FileName=..\..\jpeglib\rdppm.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit71] +FileName=..\..\jpeglib\rdswitch.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit83] +FileName=..\..\jpeglib\jpegint.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit88] +FileName=..\..\..\boinc\api\boinc_api.h +CompileCpp=1 +Folder=libgraphics2/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit99] +FileName=..\..\..\boinc\api\txf_util.cpp +CompileCpp=1 +Folder=libgraphics2/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit104] +FileName=..\..\..\boinc\api\reduce_lib.cpp +CompileCpp=1 +Folder=libgraphics2/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit18] +FileName=..\..\image_libs\bmplib.cpp +CompileCpp=1 +Folder=image_libs/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit19] +FileName=..\..\jpeglib\rdtarga.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit117] +FileName=..\..\..\boinc\lib\parse.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit120] +FileName=..\..\..\boinc\lib\diagnostics.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit123] +FileName=..\..\..\boinc\lib\stackwalker_win.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit128] +FileName=..\..\..\boinc\lib\prefs.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit129] +FileName=..\..\..\boinc\lib\prefs.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit136] +FileName=..\..\..\boinc\lib\proxy_info.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit137] +FileName=..\..\..\boinc\lib\win_util.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit139] +FileName=..\..\..\boinc\lib\diagnostics_win.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit147] +FileName=..\..\..\boinc\lib\procinfo.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/client/win_build/seti_graphics.vcproj b/client/win_build/seti_graphics.vcproj new file mode 100644 index 0000000..da97b19 --- /dev/null +++ b/client/win_build/seti_graphics.vcproj @@ -0,0 +1,462 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/win_build/seti_graphics_v3.dev b/client/win_build/seti_graphics_v3.dev new file mode 100644 index 0000000..767300f --- /dev/null +++ b/client/win_build/seti_graphics_v3.dev @@ -0,0 +1,2149 @@ +[Project] +FileName=seti_graphics.dev +Name=seti_graphics +UnitCount=146 +Type=0 +Ver=1 +ObjFiles= +Includes=Release;..;../..;../../db;../../../boinc;../../../boinc/win_build;../../../boinc/lib;../../../boinc/api;../../jpeglib;../../image_libs;../../glut;../../vector_lib;. +Libs=Release +PrivateResource=seti_graphics_private.rc +ResourceIncludes= +MakeIncludes= +Compiler=-DUSE_ASMLIB_@@_-DWIN32_@@_-D_WIN32_@@_-D_MT_@@_-DNDEBUG_@@_-D_WINDOWS _@@_-DBOINC_@@_-DCLIENT_@@_-DNODB_@@_-DBOINC_APP_GRAPHICS_@@_-D_CONSOLE_@@_-mtune=pentium-m_@@_-fomit-frame-pointer_@@_-malign-double_@@_-mpreferred-stack-boundary=4_@@_-fstrict-aliasing _@@_-ffast-math_@@_ +CppCompiler=-DUSE_ASMLIB_@@_-DWIN32_@@_-D_WIN32_@@_-D_MT_@@_-DNDEBUG_@@_-D_WINDOWS _@@_-DBOINC_@@_-DCLIENT_@@_-DNODB_@@_-DBOINC_APP_GRAPHICS_@@_-D_CONSOLE_@@_-mtune=pentium-m_@@_-fomit-frame-pointer_@@_-malign-double_@@_-mpreferred-stack-boundary=4_@@_-fstrict-aliasing _@@_-ffast-math_@@_ +Linker=c:/Dev-Cpp/lib/libglu32.a_@@_c:/Dev-Cpp/lib/libglaux.a_@@_c:/Dev-Cpp/lib/libopengl32.a_@@__@@_ +IsCpp=1 +Icon= +ExeOutput=. +ObjectOutput=.\Release +OverrideOutput=1 +OverrideOutputName=setigraphics_6.97_windows_intelx86.exe +HostApplication= +Folders=glut,glut/include,glut/src,image_libs,image_libs/include,image_libs/src,jpeglib,jpeglib/include,jpeglib/src,libboinc,libboinc/include,libboinc/src,libgraphics2,libgraphics2/include,libgraphics2/src,seti_graphics,seti_graphics/include,seti_graphics/src +CommandLine= +UseCustomMakefile=0 +CustomMakefile= +IncludeVersionInfo=1 +SupportXPThemes=1 +CompilerSet=0 +CompilerSettings=0000001001001000000010 + +[Unit15] +FileName=..\..\glut\win32_glx.c +CompileCpp=1 +Folder=glut/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit16] +FileName=..\..\glut\win32_util.c +CompileCpp=1 +Folder=glut/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit17] +FileName=..\..\image_libs\bmplib.h +CompileCpp=1 +Folder=image_libs/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit20] +FileName=..\..\jpeglib\jcapimin.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit21] +FileName=..\..\jpeglib\jcapistd.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit22] +FileName=..\..\jpeglib\jccoefct.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit23] +FileName=..\..\jpeglib\jccolor.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit27] +FileName=..\..\jpeglib\jcmainct.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit28] +FileName=..\..\jpeglib\jcmarker.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit30] +FileName=..\..\jpeglib\jcomapi.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit32] +FileName=..\..\jpeglib\jcphuff.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit37] +FileName=..\..\jpeglib\jdapistd.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit39] +FileName=..\..\jpeglib\jdatasrc.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit40] +FileName=..\..\jpeglib\jdcoefct.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit41] +FileName=..\..\jpeglib\jdcolor.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit42] +FileName=..\..\jpeglib\jddctmgr.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit44] +FileName=..\..\jpeglib\jdinput.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[VersionInfo] +Major=6 +Minor=97 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName=Space Sciences Laboratory +FileVersion=6.97 +FileDescription=setiathome_graphics +InternalName=setiathome_graphics +LegalCopyright=Copyright 2011, Regents University of California +LegalTrademarks= +OriginalFilename= +ProductName=setiathome_graphics +ProductVersion=6.97 +AutoIncBuildNr=0 + +[Unit46] +FileName=..\..\jpeglib\jdmarker.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit47] +FileName=..\..\jpeglib\jdmaster.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit48] +FileName=..\..\jpeglib\jdmerge.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit50] +FileName=..\..\jpeglib\jdpostct.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit51] +FileName=..\..\jpeglib\jdsample.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit52] +FileName=..\..\jpeglib\jdtrans.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit54] +FileName=..\..\jpeglib\jfdctflt.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit55] +FileName=..\..\jpeglib\jfdctfst.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit56] +FileName=..\..\jpeglib\jfdctint.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit57] +FileName=..\..\jpeglib\jidctflt.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit58] +FileName=..\..\jpeglib\jidctfst.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit62] +FileName=..\..\jpeglib\jmemnobs.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit63] +FileName=..\..\jpeglib\jquant1.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit64] +FileName=..\..\jpeglib\jquant2.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit66] +FileName=..\..\jpeglib\rdbmp.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit67] +FileName=..\..\jpeglib\rdcolmap.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit70] +FileName=..\..\jpeglib\rdrle.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit72] +FileName=..\..\jpeglib\jversion.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit73] +FileName=..\..\jpeglib\cderror.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit74] +FileName=..\..\jpeglib\cdjpeg.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit76] +FileName=..\..\jpeglib\jconfig.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit77] +FileName=..\..\jpeglib\jdct.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit78] +FileName=..\..\jpeglib\jdhuff.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit79] +FileName=..\..\jpeglib\jerror.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit80] +FileName=..\..\jpeglib\jinclude.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit81] +FileName=..\..\jpeglib\jmemsys.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit84] +FileName=..\..\jpeglib\jpeglib.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit85] +FileName=..\sah_gfx.h +CompileCpp=1 +Folder=seti_graphics/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit86] +FileName=..\sah_gfx_base.h +CompileCpp=1 +Folder=seti_graphics/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit87] +FileName=..\timecvt.cpp +CompileCpp=1 +Folder=seti_graphics/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit90] +FileName=..\..\..\boinc\api\graphics2.h +CompileCpp=1 +Folder=libgraphics2/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit91] +FileName=..\..\..\boinc\api\graphics_api.h +CompileCpp=1 +Folder=libgraphics2/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit92] +FileName=..\..\..\boinc\api\graphics_data.h +CompileCpp=1 +Folder=libgraphics2/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit93] +FileName=..\..\..\boinc\api\graphics_impl.h +CompileCpp=1 +Folder=libgraphics2/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit94] +FileName=..\..\..\boinc\api\gutil.h +CompileCpp=1 +Folder=libgraphics2/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit95] +FileName=..\..\..\boinc\api\texture.h +CompileCpp=1 +Folder=libgraphics2/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit96] +FileName=..\..\..\boinc\api\txf_util.h +CompileCpp=1 +Folder=libgraphics2/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit97] +FileName=..\..\..\boinc\api\boinc_api.cpp +CompileCpp=1 +Folder=libgraphics2/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit98] +FileName=..\..\..\boinc\api\graphics2.cpp +CompileCpp=1 +Folder=libgraphics2/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit100] +FileName=..\..\..\boinc\api\graphics2_util.cpp +CompileCpp=1 +Folder=libgraphics2/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit101] +FileName=..\..\..\boinc\api\graphics2_win.cpp +CompileCpp=1 +Folder=libgraphics2/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit102] +FileName=..\..\..\boinc\api\gutil.cpp +CompileCpp=1 +Folder=libgraphics2/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit103] +FileName=..\..\..\boinc\api\gutil_text.cpp +CompileCpp=1 +Folder=libgraphics2/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit105] +FileName=..\..\..\boinc\api\reduce_main.cpp +CompileCpp=1 +Folder=libgraphics2/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit106] +FileName=..\..\..\boinc\api\texfont.cpp +CompileCpp=1 +Folder=libgraphics2/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit107] +FileName=..\..\..\boinc\api\texture.cpp +CompileCpp=1 +Folder=libgraphics2/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit108] +FileName=..\..\..\boinc\api\tgalib.cpp +CompileCpp=1 +Folder=libgraphics2/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit109] +FileName=..\..\..\boinc\lib\str_util.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit110] +FileName=..\..\..\boinc\lib\str_util.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit111] +FileName=..\graphics_main.cpp +CompileCpp=1 +Folder=seti_graphics/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit112] +FileName=..\..\..\boinc\lib\app_ipc.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit113] +FileName=..\..\..\boinc\lib\app_ipc.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit114] +FileName=..\..\..\boinc\lib\filesys.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit115] +FileName=..\..\..\boinc\lib\filesys.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit116] +FileName=..\..\..\boinc\lib\parse.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit118] +FileName=..\..\..\boinc\lib\util.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit119] +FileName=..\..\..\boinc\lib\util.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit121] +FileName=..\..\..\boinc\lib\diagnostics.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit122] +FileName=..\..\..\boinc\lib\stackwalker_win.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit124] +FileName=..\..\..\boinc\lib\shmem.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit125] +FileName=..\..\..\boinc\lib\shmem.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit126] +FileName=..\..\..\boinc\lib\hostinfo.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit127] +FileName=..\..\..\boinc\lib\hostinfo.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit130] +FileName=..\..\..\boinc\lib\miofile.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit131] +FileName=..\..\..\boinc\lib\mfile.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit132] +FileName=..\..\..\boinc\lib\mfile.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit133] +FileName=..\..\..\boinc\lib\miofile.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit134] +FileName=..\..\..\boinc\lib\proxy_info.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit135] +FileName=..\..\..\boinc\lib\procinfo_win.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit138] +FileName=..\..\..\boinc\lib\win_util.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit140] +FileName=..\..\..\boinc\lib\md5_file.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit141] +FileName=..\..\..\boinc\lib\md5_file.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit143] +FileName=..\..\..\boinc\lib\md5.c +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit144] +FileName=..\..\..\boinc\lib\boinc_win.h +CompileCpp=1 +Folder=libgraphics2/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit145] +FileName=..\..\..\boinc\lib\coproc.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit146] +FileName=..\..\..\boinc\lib\url.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit147] +FileName=..\..\jpeglib\jccoefct.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit148] +FileName=..\..\jpeglib\jccolor.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit149] +FileName=..\..\jpeglib\jcdctmgr.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit150] +FileName=..\..\jpeglib\jchuff.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit151] +FileName=..\..\jpeglib\jcinit.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit152] +FileName=..\..\jpeglib\jcmainct.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit153] +FileName=..\..\jpeglib\jcmarker.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit154] +FileName=..\..\jpeglib\jcmaster.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit155] +FileName=..\..\jpeglib\jcomapi.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit156] +FileName=..\..\jpeglib\jcparam.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit157] +FileName=..\..\jpeglib\jcphuff.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit158] +FileName=..\..\jpeglib\jcprepct.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit159] +FileName=..\..\jpeglib\jcsample.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit160] +FileName=..\..\jpeglib\jctrans.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit161] +FileName=..\..\jpeglib\jdapimin.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit162] +FileName=..\..\jpeglib\jdapistd.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit163] +FileName=..\..\jpeglib\jdatadst.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit164] +FileName=..\..\jpeglib\jdatasrc.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit165] +FileName=..\..\jpeglib\jdcoefct.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit166] +FileName=..\..\jpeglib\jdcolor.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit167] +FileName=..\..\jpeglib\jddctmgr.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit168] +FileName=..\..\jpeglib\jdhuff.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit169] +FileName=..\..\jpeglib\jdinput.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit170] +FileName=..\..\jpeglib\jdmainct.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit171] +FileName=..\..\jpeglib\jdmarker.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit172] +FileName=..\..\jpeglib\jdmaster.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit173] +FileName=..\..\jpeglib\jdmerge.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit174] +FileName=..\..\jpeglib\jdphuff.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit175] +FileName=..\..\jpeglib\jdpostct.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit176] +FileName=..\..\jpeglib\jdsample.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit177] +FileName=..\..\jpeglib\jdtrans.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit178] +FileName=..\..\jpeglib\jerror.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit179] +FileName=..\..\jpeglib\jfdctflt.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit180] +FileName=..\..\jpeglib\jfdctfst.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit181] +FileName=..\..\jpeglib\jfdctint.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit182] +FileName=..\..\jpeglib\jidctflt.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit183] +FileName=..\..\jpeglib\jidctfst.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit184] +FileName=..\..\jpeglib\jidctint.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit185] +FileName=..\..\jpeglib\jidctred.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit186] +FileName=..\..\jpeglib\jmemmgr.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit142] +FileName=..\..\..\boinc\lib\md5.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit187] +FileName=..\..\jpeglib\jmemnobs.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit188] +FileName=..\..\jpeglib\jquant1.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit189] +FileName=..\..\jpeglib\jquant2.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit190] +FileName=..\..\jpeglib\jutils.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit191] +FileName=..\..\jpeglib\rdbmp.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit192] +FileName=..\..\jpeglib\rdcolmap.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit193] +FileName=..\..\jpeglib\rdgif.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit194] +FileName=..\..\jpeglib\rdppm.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit195] +FileName=..\..\jpeglib\rdrle.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit196] +FileName=..\..\jpeglib\rdswitch.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit197] +FileName=..\..\jpeglib\jversion.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit198] +FileName=..\..\jpeglib\cderror.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit199] +FileName=..\..\jpeglib\cdjpeg.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit204] +FileName=..\..\jpeglib\jerror.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit205] +FileName=..\..\jpeglib\jinclude.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit200] +FileName=..\..\jpeglib\jchuff.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit201] +FileName=..\..\jpeglib\jconfig.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit202] +FileName=..\..\jpeglib\jdct.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit203] +FileName=..\..\jpeglib\jdhuff.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit206] +FileName=..\..\jpeglib\jmemsys.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit208] +FileName=..\..\jpeglib\jpegint.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit209] +FileName=..\..\jpeglib\jpeglib.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit210] +FileName=..\vector\analyzeFuncs_fpu.cpp +CompileCpp=1 +Folder=seti_boinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit207] +FileName=..\..\jpeglib\jmorecfg.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit75] +FileName=..\..\jpeglib\jchuff.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit82] +FileName=..\..\jpeglib\jmorecfg.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit89] +FileName=..\..\..\boinc\api\boinc_gl.h +CompileCpp=1 +Folder=libgraphics2/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=..\sah_gfx.cpp +CompileCpp=1 +Folder=seti_graphics/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=..\sah_gfx_base.cpp +CompileCpp=1 +Folder=seti_graphics/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=..\..\glut\win32_x11.h +CompileCpp=1 +Folder=glut/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit4] +FileName=..\..\glut\glut.h +CompileCpp=1 +Folder=glut/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=..\..\glut\glutbitmap.h +CompileCpp=1 +Folder=glut/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit6] +FileName=..\..\glut\glutint.h +CompileCpp=1 +Folder=glut/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit7] +FileName=..\..\glut\glutstroke.h +CompileCpp=1 +Folder=glut/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit8] +FileName=..\..\glut\glutwin32.h +CompileCpp=1 +Folder=glut/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit9] +FileName=..\..\glut\stroke.h +CompileCpp=1 +Folder=glut/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit10] +FileName=..\..\glut\win32_glx.h +CompileCpp=1 +Folder=glut/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit11] +FileName=..\..\glut\win32_x11.c +CompileCpp=1 +Folder=glut/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit12] +FileName=..\..\glut\glut_roman.c +CompileCpp=1 +Folder=glut/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit13] +FileName=..\..\glut\glut_stroke.c +CompileCpp=1 +Folder=glut/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit14] +FileName=..\..\glut\glut_swidth.c +CompileCpp=1 +Folder=glut/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit24] +FileName=..\..\jpeglib\jcdctmgr.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit25] +FileName=..\..\jpeglib\jchuff.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit26] +FileName=..\..\jpeglib\jcinit.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit29] +FileName=..\..\jpeglib\jcmaster.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit31] +FileName=..\..\jpeglib\jcparam.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit33] +FileName=..\..\jpeglib\jcprepct.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit34] +FileName=..\..\jpeglib\jcsample.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit35] +FileName=..\..\jpeglib\jctrans.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit36] +FileName=..\..\jpeglib\jdapimin.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit38] +FileName=..\..\jpeglib\jdatadst.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit43] +FileName=..\..\jpeglib\jdhuff.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit45] +FileName=..\..\jpeglib\jdmainct.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit49] +FileName=..\..\jpeglib\jdphuff.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit53] +FileName=..\..\jpeglib\jerror.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit59] +FileName=..\..\jpeglib\jidctint.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit60] +FileName=..\..\jpeglib\jidctred.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit61] +FileName=..\..\jpeglib\jmemmgr.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit65] +FileName=..\..\jpeglib\jutils.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit68] +FileName=..\..\jpeglib\rdgif.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit69] +FileName=..\..\jpeglib\rdppm.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit71] +FileName=..\..\jpeglib\rdswitch.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit83] +FileName=..\..\jpeglib\jpegint.h +CompileCpp=1 +Folder=jpeglib/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit88] +FileName=..\..\..\boinc\api\boinc_api.h +CompileCpp=1 +Folder=libgraphics2/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit99] +FileName=..\..\..\boinc\api\txf_util.cpp +CompileCpp=1 +Folder=libgraphics2/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit104] +FileName=..\..\..\boinc\api\reduce_lib.cpp +CompileCpp=1 +Folder=libgraphics2/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit18] +FileName=..\..\image_libs\bmplib.cpp +CompileCpp=1 +Folder=image_libs/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit19] +FileName=..\..\jpeglib\rdtarga.c +CompileCpp=1 +Folder=jpeglib/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit117] +FileName=..\..\..\boinc\lib\parse.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit120] +FileName=..\..\..\boinc\lib\diagnostics.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit123] +FileName=..\..\..\boinc\lib\stackwalker_win.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit128] +FileName=..\..\..\boinc\lib\prefs.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit129] +FileName=..\..\..\boinc\lib\prefs.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit136] +FileName=..\..\..\boinc\lib\proxy_info.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit137] +FileName=..\..\..\boinc\lib\win_util.h +CompileCpp=1 +Folder=libboinc/include +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit139] +FileName=..\..\..\boinc\lib\diagnostics_win.cpp +CompileCpp=1 +Folder=libboinc/src +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/client/win_build/setiboincdb.vcproj b/client/win_build/setiboincdb.vcproj new file mode 100755 index 0000000..914cbf8 --- /dev/null +++ b/client/win_build/setiboincdb.vcproj @@ -0,0 +1,354 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/worker.cpp b/client/worker.cpp new file mode 100644 index 0000000..d9db3de --- /dev/null +++ b/client/worker.cpp @@ -0,0 +1,175 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +// worker.C: SETI-independent worker logic +// $Id: worker.cpp,v 1.32.2.14 2007/08/10 00:38:49 korpela Exp $ +// +#include "sah_config.h" + + +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#ifndef _WIN32 +#include +#endif + +#ifdef BOINC_APP_GRAPHICS +#include "sah_gfx_main.h" +#endif +#include "s_util.h" +#include "seti_header.h" +#include "seti.h" +#include "worker.h" +#include "chirpfft.h" +#include "analyzeFuncs.h" +#include "analyzeReport.h" + +#include "filesys.h" +#include "boinc_api.h" + +#include "worker.h" + +using std::string; + +bool verbose; + +// this gets called first on all platforms +int common_init() { + +#ifdef ALLOW_CFFT_FILE + FILE* f; + f = boinc_fopen(CFFT_FILENAME, "r"); + if (f) { + cfft_file = &debug_cfft_file[0]; + fclose(f); + } +#endif + + + return 0; +} + +// Do this when start on a work unit for the first time. +// Creates result header file. +static int initialize_for_wu() { + int retval = 0; + FILE* f; + string path; + + boinc_resolve_filename_s(OUTFILE_FILENAME, path); + f = boinc_fopen(path.c_str(), "wb"); + if (!f) SETIERROR(FOPEN_FAILED,"in initialize_for_wu()"); + xml_indent(2); + fprintf(f, "\n"); + retval = seti_write_wu_header(f, 1); + fclose(f); + + return retval; +} + +// parse input and state files +// +static int read_wu_state() { + FILE* f; + int retval=0; + string path; + FORCE_FRAME_POINTER; + + boinc_resolve_filename_s(WU_FILENAME, path); + f = boinc_fopen(path.c_str(), "rb"); + if (f) { +#ifdef BOINC_APP_GRAPHICS + if (sah_graphics) sprintf(sah_graphics->status, "Scanning data file\n"); +#endif + retval = seti_parse_wu(f, analysis_state); + fclose(f); + if (retval) SETIERROR(retval,"from seti_parse_wu() in read_wu_state()"); + } else { + char msg[1024]; + sprintf(msg,"(%s) in read_wu_state() errno=%d\n",path.c_str(),errno); + SETIERROR(FOPEN_FAILED,msg); + } + + retval = seti_init_state(); + if (retval) SETIERROR(retval,"from seti_init_state() in read_wu_state()"); + +#ifdef BOINC_APP_GRAPHICS + if (sah_graphics) sprintf(sah_graphics->status, "Scanning state file.\n"); +#endif + if (boinc_file_exists(STATE_FILENAME)) { + retval = parse_state_file(analysis_state); + } else { + retval = initialize_for_wu(); + if (retval) SETIERROR(retval,"from initialize_for_wu() in read_wu_state()"); + } + + boinc_fraction_done(progress*remaining+(1.0-remaining)*(1.0-remaining)); + return 0; +} + +void worker() { + int retval=0; + run_stage=POSTINIT; + FORCE_FRAME_POINTER; +#if defined(__GNUC__) && defined (__i386__) + __asm__ __volatile__ ("andl $-16, %esp"); +#endif + try { + retval = common_init(); + if (retval) SETIERROR(retval,"from common_init() in worker()"); + + retval = read_wu_state(); + if (retval) SETIERROR(retval,"from read_wu_state() in worker()"); + + retval = seti_do_work(); + if (retval) SETIERROR(retval,"from seti_do_work() in worker()"); + + boinc_finish(retval); + } + catch (seti_error e) { + if (e == RESULT_OVERFLOW) { + fprintf(stderr, "SETI@Home Informational message -9 result_overflow\n"); + fprintf(stderr, "NOTE: The number of results detected exceeds the storage space allocated.\n"); + final_report(); // add flop and signal counts + progress=1; + remaining=0; + boinc_fraction_done(progress); + checkpoint(true); // force a checkpoint + boinc_finish(0); + exit(0); // an overflow is not an app error + } else { + e.print(); + exit(static_cast(e)); + } + } +} + diff --git a/client/worker.h b/client/worker.h new file mode 100644 index 0000000..74fa489 --- /dev/null +++ b/client/worker.h @@ -0,0 +1,40 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +// $Id: worker.h,v 1.5.2.2 2007/06/01 20:24:43 korpela Exp $ + +extern int common_init(); +extern void worker(); + +extern char * cfft_file; +extern char debug_cfft_file[]; + +extern int run_stage; +#define PREGRX 0 +#define GRXINIT 1 +#define POSTINIT 2 + diff --git a/compile b/compile new file mode 100755 index 0000000..9bb997a --- /dev/null +++ b/compile @@ -0,0 +1,99 @@ +#! /bin/sh + +# Wrapper for compilers which do not understand `-c -o'. + +# Copyright 1999, 2000 Free Software Foundation, Inc. +# Written by Tom Tromey . +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Usage: +# compile PROGRAM [ARGS]... +# `-o FOO.o' is removed from the args passed to the actual compile. + +prog=$1 +shift + +ofile= +cfile= +args= +while test $# -gt 0; do + case "$1" in + -o) + # configure might choose to run compile as `compile cc -o foo foo.c'. + # So we do something ugly here. + ofile=$2 + shift + case "$ofile" in + *.o | *.obj) + ;; + *) + args="$args -o $ofile" + ofile= + ;; + esac + ;; + *.c) + cfile=$1 + args="$args $1" + ;; + *) + args="$args $1" + ;; + esac + shift +done + +if test -z "$ofile" || test -z "$cfile"; then + # If no `-o' option was seen then we might have been invoked from a + # pattern rule where we don't need one. That is ok -- this is a + # normal compilation that the losing compiler can handle. If no + # `.c' file was seen then we are probably linking. That is also + # ok. + exec "$prog" $args +fi + +# Name of file we expect compiler to create. +cofile=`echo $cfile | sed -e 's|^.*/||' -e 's/\.c$/.o/'` + +# Create the lock directory. +# Note: use `[/.-]' here to ensure that we don't use the same name +# that we are using for the .o file. Also, base the name on the expected +# object file name, since that is what matters with a parallel build. +lockdir=`echo $cofile | sed -e 's|[/.-]|_|g'`.d +while true; do + if mkdir $lockdir > /dev/null 2>&1; then + break + fi + sleep 1 +done +# FIXME: race condition here if user kills between mkdir and trap. +trap "rmdir $lockdir; exit 1" 1 2 15 + +# Run the compile. +"$prog" $args +status=$? + +if test -f "$cofile"; then + mv "$cofile" "$ofile" +fi + +rmdir $lockdir +exit $status diff --git a/config.guess b/config.guess new file mode 100755 index 0000000..45bee13 --- /dev/null +++ b/config.guess @@ -0,0 +1,1465 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + +timestamp='2005-04-22' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit 0 ;; + amd64:OpenBSD:*:*) + echo x86_64-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + cats:OpenBSD:*:*) + echo arm-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + luna88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + macppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvmeppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mips64-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sun3:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit 0 ;; + macppc:MirBSD:*:*) + echo powerppc-unknown-mirbsd${UNAME_RELEASE} + exit 0 ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit 0 ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit 0 ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit 0;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit 0 ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit 0 ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit 0 ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit 0 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit 0 ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7 && exit 0 ;; + esac ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit 0 ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c \ + && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && exit 0 + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit 0 ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit 0 ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + # avoid double evaluation of $set_cc_for_build + test -n "$CC_FOR_BUILD" || eval $set_cc_for_build + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit 0 ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit 0 ;; + x86:Interix*:[34]*) + echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//' + exit 0 ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit 0 ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit 0 ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit 0 ;; + amd64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit 0 ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit 0 ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit 0 ;; + crisv32:Linux:*:*) + echo crisv32-axis-linux-gnu + exit 0 ;; + frv:Linux:*:*) + echo frv-unknown-linux-gnu + exit 0 ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 + ;; + mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips64 + #undef mips64el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mips64el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips64 + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 + ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit 0 ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit 0 ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit 0 ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit 0 ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit 0 ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit 0 ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit 0 ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit 0 ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit 0 ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit 0 ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #ifdef __INTEL_COMPILER + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 + test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit 0 ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit 0 ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit 0 ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit 0 ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit 0 ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit 0 ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit 0 ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit 0 ;; + i*86:*:5:[78]*) + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit 0 ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit 0 ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit 0 ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit 0 ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3${OS_REL} && exit 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit 0 ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit 0 ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit 0 ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit 0 ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit 0 ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit 0 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit 0 ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + *86) UNAME_PROCESSOR=i686 ;; + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit 0 ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit 0 ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit 0 ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit 0 ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit 0 ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit 0 ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit 0 ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit 0 ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit 0 ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit 0 ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit 0 ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit 0 ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit 0 ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit 0 ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit 0 ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit 0 ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit 0 ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms && exit 0 ;; + I*) echo ia64-dec-vms && exit 0 ;; + V*) echo vax-dec-vms && exit 0 ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0 + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/config.sub b/config.sub new file mode 100755 index 0000000..87a1ee4 --- /dev/null +++ b/config.sub @@ -0,0 +1,1569 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + +timestamp='2005-04-22' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit 0;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \ + kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | m32r | m32rle | m68000 | m68k | m88k | maxq | mcore \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64vr | mips64vrel \ + | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | msp430 \ + | ns16k | ns32k \ + | openrisc | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b \ + | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | msp430-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \ + | xstormy16-* | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16c) + basic_machine=cr16c-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + or32 | or32-*) + basic_machine=or32-unknown + os=-coff + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..2e17b3f --- /dev/null +++ b/configure.ac @@ -0,0 +1,500 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. +# $Id: $ + + +AC_PREREQ(2.57) +AC_INIT(setiathome_v7, 6.97, korpela@ssl.berkeley.edu) +svnrev="`svn info | grep Revision:`" + +if test -n "${svnrev}" ; then + AC_REVISION("${svnrev}") + AC_DEFINE_UNQUOTED(SVN_REV,"${svnrev}", + [Define to be the subversion revision number]) +else + AC_REVISION([$Revision: 1146 $]) + AC_DEFINE(SVN_REV,"$Revision: 1146 $", + [Define to be the subversion revision number]) +fi + +AC_CANONICAL_TARGET +AM_INIT_AUTOMAKE(dist-zip) +AC_CONFIG_SRCDIR([client/analyze.h]) + +AC_CACHE_SAVE + +# Set up the prefix early. +if test "x$prefix" = "xNONE" ; then + prefix="${ac_default_prefix}" +fi +if test "x$exec_prefix" = "xNONE" ; then + exec_prefix="${ac_default_prefix}" +fi + + +# Make sure we use the same initial CFLAGS and CXXFLAGS unless otherwise told. +if test -z "${CXXFLAGS}" +then + CXXFLAGS="${CFLAGS}" +elif test -z "${CFLAGS}" +then + CFLAGS="${CXXFLAGS}" +fi + +# make sure $includedir is in CFLAGS and $libdir is in LDFLAGS. +tmpinc="`eval echo ${includedir}`" +tmplib="`eval echo ${libdir}`" +if test -z "`echo ${CFLAGS} | grep ${tmpinc}`" ; then + CFLAGS="${CFLAGS} -I${tmpinc}" +fi +if test -z "`echo ${CXXFLAGS} | grep ${tmpinc}`" ; then + CXXFLAGS="${CXXFLAGS} -I${tmpinc}" +fi +if test -z "`echo ${LDFLAGS} | grep ${tmplib}`" ; then + LDFLAGS="${LDFLAGS} -L${tmplib}" +fi + +# set posix source on linux +CFLAGS="-D_POSIX_C_SOURCE=1 ${CFLAGS}" +CXXFLAGS="-D_POSIX_C_SOURCE=1 ${CXXFLAGS}" + +AC_ARG_ENABLE(intrinsics, + AS_HELP_STRING([--disable-intrinsics], + [disable use of intrinsics in SIMD code])) + + +if test "x$enable_intrinsics" != xno ; then + enable_intrinsics=yes +fi + +AC_ARG_ENABLE(graphics, + AC_HELP_STRING([--disable-graphics], + [disable building the client graphics])) + +if test "x$enable_graphics" != xno ; then + enable_graphics=yes +else + enable_graphics=no +fi + + +AC_ARG_ENABLE(tests, + AC_HELP_STRING([--disable-tests], + [disable tests (fakedata and hires_timer_test)]), + [], + [enable_tests=yes]) + +AC_ARG_ENABLE(server, + AC_HELP_STRING([--disable-server], + [disable building the seti@home server components]), + [], + [enable_server=yes]) + + +AC_ARG_ENABLE(client, + AC_HELP_STRING([--disable-client], + [disable building the client]), + [], + [enable_client=yes]) + +AC_ARG_ENABLE(static-client, + AC_HELP_STRING([--disable-static-client], + [allow dynamic libraries to be used in the client]), + [enable_static_client=${enableval}], + [enable_static_client=yes]) + +m4_divert_once([HELP_ENABLE], + AC_HELP_STRING([], [Default: --enable-server --enable-client: + builds both server and client])) + +if test "${enable_server}" = yes ; then + if test "${enable_client}" = yes ; then + configured_to_build='server & client' + else + configured_to_build='server only' + fi +else + if test "${enable_client}" = yes ; then + configured_to_build='client only' + else + AC_MSG_WARN([Youve disabled both the server and the client. Nothing useful will be built]) + fi +fi + +AC_MSG_NOTICE(["--- Configuring SETI_BOINC AC_PACKAGE_VERSION (${configured_to_build}) ---"]) + + +AC_COPYRIGHT([ +Copyright (C) 2004 Regents of the University of California + +SETI_BOINC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 2, or (at your option) any later +version. + +SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +more details. + +You should have received a copy of the GNU General Public License along +with SETI_BOINC; see the file COPYING. If not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Contributor(s): +]) + +major_version=`echo AC_PACKAGE_VERSION | sed 's/\..*//'` +minor_version=`echo AC_PACKAGE_VERSION | sed 's/.*\.//' | sed 's/^0//'` +AC_SUBST([MAJOR_VERSION], [$major_version]) +AC_SUBST([MINOR_VERSION], [$minor_version]) +AC_DEFINE_UNQUOTED([VERSION_MAJOR],$major_version, [SETI@home major version number]) +AC_DEFINE_UNQUOTED([VERSION_MINOR],$minor_version, [SETI@home minor version number]) +AC_DEFINE_UNQUOTED([SAH_APP_NAME],["$PACKAGE_NAME"], [Define to the BOINC application name for setiathome]) +SAH_TOP_DIR=`pwd` +AC_SUBST([SAH_TOP_DIR]) + +AM_MAINTAINER_MODE + +# Checks for programs. +PATH="/usr/xpg4/bin:${PATH}" +AC_PROG_CXX +AC_PROG_CXXCPP +AM_PROG_CC_C_O +AC_PROG_AWK +AC_PROG_LN_S +AC_PATH_PROG(TR,[tr]) +AC_PATH_PROGS(AR,[ar lib]) +AC_PATH_PROG(GREP,[grep]) +AC_PATH_PROG(AUTOCONF,[autoconf]) +AC_PATH_PROG(AUTOHEADER,[autoheader]) +AC_PATH_PROGS(INDENT,[astyle indent]) +AC_PATH_PROGS(CP,[cp copy]) +AC_PATH_PROGS(LN,[ln cp copy]) +AC_PATH_PROG(SORT,[sort]) +AC_PATH_PROG(UNIQ,[uniq]) +AC_PATH_PROG(CAT,[cat type]) +AC_PATH_PROG(MV,[mv]) +AC_PATH_PROGS(RM,[rm Rm del erase delete]) + +AC_LIBTOOL_DLOPEN +AC_LIBTOOL_WIN32_DLL +AM_PROG_LIBTOOL +AC_SUBST(PICFLAGS,${lt_prog_compiler_pic}) +AC_SUBST(SED) +AC_C_BIGENDIAN +AX_C_FLOAT_WORDS_BIGENDIAN + +SAH_OPTION_BITNESS + +dnl Determine the BOINC platform given the target arch-platform-os. +BOINC_PLATFORM + +if test -n `echo $INDENT | grep astyle` +then + AC_SUBST([INDENT_FLAGS],["--c --indent-classes --indent-switches --brackets=attach --convert-tabs"]) +else + AC_SUBST([INDENT_FLAGS],["-kr"]) +fi +AC_PROG_MAKE_SET +SAH_DLLEXT +SAH_LIBEXT +if test -n "$EXEEXT" +then + DOTEXEEXT=".$EXEEXT" +fi +AC_SUBST(DOTEXEEXT) +AC_SYS_LARGEFILE +ACX_PTHREAD([AC_DEFINE(HAVE_PTHREAD,1, [Have pthread])]) + +if test "x$enable_client" = xyes ; then + +# find the right flag for building a static app +if test "x$enable_static_client" != xno ; then + svldflags="$LDFLAGS" + SAH_CHECK_LDFLAG([-static],[LDSTATIC=-static]) + LDFLAGS="$svldflags" +fi + +# Check libraries required or desired for seti_boinc app +# Checks for libraries. +APP_LDFLAGS="$LDSTATIC -L/usr/local/lib $LDFLAGS" +APP_CFLAGS="-I/usr/local/include $CFLAGS" +AC_CHECK_LIB([m], [sin],[ + AC_DEFINE([HAVE_LIBM],[1],[Define to 1 if you have the math library]) + APP_LIBS="-lm ${APP_LIBS}" +]) +SAH_CHECK_MATH_FUNCS([sqrt floor sinf cosf sincos sincosf atanf isnan _isnan __isnan __isnanf _isnanf isnanf]) +AC_CHECK_LIB([fftw3f], [fftwf_plan_dft_1d], [ + AC_DEFINE([HAVE_LIBFFTW3F],[1],[Define to 1 if you have the fftw3f library]) + APP_LIBS="-lfftw3f ${APP_LIBS}" +], +[], +[-lm]) +AC_CHECK_LIB([fftw3], [fftwf_plan_dft_1d], [ + AC_DEFINE([HAVE_LIBFFTW3F],[1],[Define to 1 if you have the fftw3f library]) + APP_LIBS="-lfftw3 ${APP_LIBS}" +], +[], +[-lm]) +SAH_CHECK_ASMLIB +APP_LIBS="${ASMLIB_LIBS} ${APP_LIBS}" +APP_CFLAGS="${ASMLIB_CFLAGS} ${APP_CFLAGS}" +APP_LDFLAGS="${ASMLIB_LDFLAGS} ${APP_LDFLAGS}" + +# Check for additional optimization flags +SAH_OPTIMIZATIONS + +# Check for intel performance primatives +SAH_CHECK_IPP +if test x$found_ipp = xyes ; then + APP_LDFLAGS="-L${IPPDIR}/lib ${APP_LDFLAGS}" + APP_LIBS="-lippcore -lippsmerged ${APP_LIBS}" + APP_CFLAGS="-I${IPPDIR}/include ${APP_CFLAGS}" +fi + +AC_SUBST([APP_LIBS]) +AC_SUBST([APP_LDFLAGS]) +AC_SUBST([APP_CFLAGS]) + +if test "$enable_graphics" = yes ; then + SAH_GRX_LIBS + AX_CHECK_GL + AX_CHECK_GLU + AX_CHECK_GLUT + if test "$no_gl" = yes -o "$no_glu" = yes -o "$no_glut" = yes ; then + have_glut=no + enable_graphics=no + AC_MSG_WARN([ +================================================================================ +WARNING: GL/GLU/GLUT not found. + +The GL, GLU, and GLUT libraries are required in order to build the graphical +parts of the BOINC application API library. + +==> only building non-graphical parts of the BOINC API Library for now. + +================================================================================ + ]) +else + AC_DEFINE([BOINC_APP_GRAPHICS],1,[Define to 1 to build a graphical application]) + SAH_GRX_INCLUDES + GRAPHICS_CFLAGS="${GRX_CFLAGS} ${GL_CFLAGS} ${GLU_CFLAGS} ${GLUT_CFLAGS}" + GRAPHICS_LIBS="${GL_LIBS} ${GLU_LIBS} ${GLUT_LIBS} ${GRX_LIBS} -ljpeg" + +case ${target} in + powerpc-apple*) GRAPHICS_LIBS="${GRAPHICS_LIBS} -framework AppKit -framework CoreServices" + ;; +esac + GRAPHICS_LIBS_RAW="${PTHREAD_CFLAGS} -L${BOINCDIR}/api -L${BOINCDIR}/lib -lboinc_graphics2 -lboinc ${GRAPHICS_LIBS}" +dnl SAH_RAW_LDFLAGS(["${PTHREAD_CFLAGS} -L${BOINCDIR}/api -L${BOINCDIR}/lib -lboinc_graphics2 -lboinc ${GRAPHICS_LIBS}"],[GRAPHICS_LIBS_RAW]) + have_glut=yes + enable_graphics=yes + fi +fi +AC_SUBST([LDSTATIC]) +AC_SUBST([GRAPHICS_CFLAGS]) +AC_SUBST([GRAPHICS_LIBS]) +AC_SUBST([GRAPHICS_LIBS_RAW]) + +AC_CACHE_SAVE + +fi + +dnl SAH_CHECK_LIB([c],[atexit], +dnl AC_DEFINE([HAVE_LIBC],[1],[Define to 1 if you have the c library])) +dnl SAH_CHECK_LIB([pthread],[pthread_join], +dnl AC_DEFINE([HAVE_LIBPTHREAD],[1],[Define to 1 if you have the pthread library])) +dnl AC_CHECK_LIB([gcc],[sscanf], +dnl AC_DEFINE([HAVE_LIBGCC],[1],[Define to 1 if you have the gcc library])) +dnl SAH_CHECK_LIB([gcc_eh],[_Unwind_Resume], +dnl AC_DEFINE([HAVE_LIBGCC_EH],[1],[Define to 1 if you have the gcc_eh library])) +dnl SAH_CHECK_LIB([gcc_s],[sscanf], +dnl AC_DEFINE([HAVE_LIBGCC_S],[1],[Define to 1 if you have the gcc_s library])) +dnl AC_CHECK_LIB([stdc++],[sscanf], +dnl AC_DEFINE([HAVE_LIBSTDC__],[1],[Define to 1 if you have the stdc++ library])) +dnl AC_CHECK_LIB([z], [uncompress], +dnl AC_DEFINE([HAVE_LIBZ],[1],[Define to 1 if you have the z library])) +dnl AC_CHECK_LIB([socket], [bind], +dnl AC_DEFINE([HAVE_LIBSOCKET],[1],[Define to 1 if you have the socket library])) +dnl AC_CHECK_LIB([rt], [sched_get_priority_min], +dnl AC_DEFINE([HAVE_LIBRT],[1],[Define to 1 if you have the rt library])) +dnl AC_CHECK_LIB([nsl], [gethostbyname], +dnl AC_DEFINE([HAVE_LIBNSL],[1],[Define to 1 if you have the nsl library])) +dnl AC_CHECK_LIB([elf], [elf_hash], +dnl AC_DEFINE([HAVE_LIBELF],[1],[Define to 1 if you have the elf library])) +dnl AC_CHECK_LIB([aio], [aio_fork], +dnl AC_DEFINE([HAVE_LIBAIO],[1],[Define to 1 if you have the aio library])) +CHECK_SSL +AC_CHECK_LIB([ssl], [fopen], + [BOINC_EXTRA_LIBS="${BOINC_EXTRA_LIBS} -L${SSLDIR}/lib ${sah_lib_last}"]) +AC_CHECK_LIB([crypto], [RSA_new], + [BOINC_EXTRA_LIBS="${BOINC_EXTRA_LIBS} -L${SSLDIR}/lib ${sah_lib_last}"]) + +dnl AC_CHECK_LIB([dl], [dlopen], +dnl AC_DEFINE([HAVE_LIBDL],[1],[Define to 1 if you have the dl library])) +AC_LANG(C++) + + +if test "${ac_cv_cxx_compiler_gnu}" = "yes" ; then + gcc_version_string="`g++ --version | head -1`" + AC_DEFINE_UNQUOTED([COMPILER_STRING],"$gcc_version_string",[Define to a string identifying your compiler]) +else if test -n "${CXX}" ; then + AC_DEFINE_UNQUOTED([COMPILER_STRING],"$CXX",[Define to a string identifying your compiler]) +else if test -n "${CC}" ; then + AC_DEFINE_UNQUOTED([COMPILER_STRING],"$CC",[Define to a string identifying your compiler]) +fi +fi +fi + +SAH_REQUIRES([boinc],[SAH_CHECK_BOINC],["${no_boinc}" = yes], +[ +ERROR: trying to build the seti_boinc client or server but BOINC was not +found. + +You can get boinc at http://boinc.ssl.berkeley.edu/ +], +[exit 1]) + +SAH_SERVER_REQUIRES([mysql],[SAH_CHECK_MYSQL],["${no_mysql}" = yes]) +SAH_SERVER_REQUIRES([informix],[SAH_CHECK_INFORMIX],["${no_informix}" = yes]) +SAH_SERVER_REQUIRES([setilib],[SAH_FIND_SETILIB],["${no_setilib}" = yes]) +SAH_SERVER_REQUIRES([healpix],[SAH_CHECK_HEALPIX],["${no_healpix}" = yes]) + + +# Checks for header files. +AC_HEADER_STDC +SAH_LARGEFILE_BREAKS_CXX +SAH_HEADER_STDCXX +AC_HEADER_SYS_WAIT +AC_CHECK_HEADERS([fcntl.h inttypes.h limits.h memory.h alloca.h malloc.h stdlib.h string.h strings.h errno.h sys/types.h sys/ioctl.h sys/statvfs.h sys/time.h unistd.h dirent.h math.h float.h ieeefp.h floatingpoint.h complex.h fftw3.h setjmp.h signal.h mach/mach_time.h sys/param.h sys/systm.h machine/cpu.h]) +save_cxxflags="${CXXFLAGS}" +save_cppflags="${CPPFLAGS}" +CXXFLAGS="${CXXFLAGS} -msse3" +CPPFLAGS="${CPPFLAGS} -msse3" +AC_CHECK_HEADERS([intrin.h x86intrin.h pmmintrin.h xmmintrin.h emmintrin.h]) +CXXFLAGS="${save_cxxflags} -mavx" +CPPFLAGS="${save_cppflags} -mavx" +AC_CHECK_HEADERS([immintrin.h avxintrin.h]) +CXXFLAGS="${save_cxxflags}" +CPPFLAGS="${save_cppflags}" +if test "x$enable_intrinsics" != "xno" ; then + if test "x$ac_cv_header_xmmintrin_h" != "xno" -o "x$ac_cv_header_emmintrin_h" != "xno" ; then + AC_DEFINE([USE_INTRINSICS],[1],[Define to 1 to use SIMD intrinsics rather than inline assembly]) + fi +fi +AC_CACHE_SAVE + +# Checks for typedefs, structures, and compiler characteristics. +AC_HEADER_STDBOOL +AC_C_CONST +AC_C_INLINE +AC_C_LONG_DOUBLE +AC_TYPE_OFF_T +AC_TYPE_SIZE_T +AC_STRUCT_ST_BLOCKS +AC_STRUCT_TM +AC_CHECK_SIZEOF([long int]) +AC_CHECK_SIZEOF([long double]) +AC_CHECK_TYPES([long long,_int64,int64_t,bool,_int32,int32_t, hrtime_t, uint_fast64_t, uint64_t, _uint64, u_int64_t, ptrdiff_t, ssize_t, off64_t]) +AC_CACHE_SAVE + +# Checks for library functions. +AC_LANG(C) +AC_FUNC_FORK +AC_HEADER_MAJOR +AC_FUNC_MALLOC +AC_FUNC_REALLOC +AC_FUNC_ALLOCA +if test "${ac_cv_func_alloca_works}" = "yes" ; then + ac_cv_func_alloca="yes" +fi +AC_FUNC_STAT +AC_FUNC_STRFTIME +AC_CHECK_FUNCS([ _aligned_malloc alloca _alloca __builtin_alloca memalign atexit exit _exit getcwd memset munmap putenv strchr strstr strcasestr atoll dlopen gethrtime mach_absolute_time get_cyclecount nanotime microtime gettimeofday sqrt floor sinf cosf sincos sincosf atanf isnan _isnan __isnan isnanf _isnanf __isnanf siglongjmp sigsetjmp sigaction sysv_signal bsd_signal ]) +SAH_CHECK_NAMESPACES +AH_TEMPLATE([HAVE_STD_MIN],[Define to 1 if min is in namespace std::]) +AH_TEMPLATE([HAVE_STD_MAX],[Define to 1 if max is in namespace std::]) +AH_TEMPLATE([HAVE_STD_TRANSFORM],[Define to 1 if transform is in namespace std::]) +SAH_FUNCS_IN_NAMESPACE([['min(0,0)'] ['max(0,0)'] ['transform((char *)0,(char *)0,(char *)0,(int(*)(int))malloc)']],std) + +SAH_AVX + +AM_CONDITIONAL(USE_MY_IMAGELIBS, [false]) +AM_CONDITIONAL(USE_MY_GLUT, [false]) +AM_CONDITIONAL(ENABLE_TESTS, [test "${enable_tests}" = yes]) +AM_CONDITIONAL(ENABLE_SERVER, [test "${enable_server}" = yes]) +AM_CONDITIONAL(ENABLE_CLIENT, [test "${enable_client}" = yes]) +AM_CONDITIONAL(ENABLE_GUI, [test "${enable_graphics}" = yes]) +AM_CONDITIONAL(LINUX, [test -n "`echo ${target} | grep linux`"]) +AM_CONDITIONAL(I386, [test -n "`echo ${target} | grep i.86`"]) +AM_CONDITIONAL(X86_64, [test -n "`echo ${target} | $EGREP 'x86_64|amd64'`"]) +AM_CONDITIONAL(PPC, [test -n "`echo ${target} | grep 'powerpc'`" -o -n "`echo ${target} | grep 'ppc'`" ]) +AM_CONDITIONAL(AVX, [test "x${have_avx}" = "xyes"]) +if test "x${avx_type}" != "x" ; then + AC_DEFINE_UNQUOTED([AVX_MASKSTORE_TYPECAST(x)],[reinterpret_cast<$avx_type>(x)], + [Define to the typecast required for arg 2 of _mm256_maskstore_ps()]) +else + AC_DEFINE_UNQUOTED([AVX_MASKSTORE_TYPECAST(x)],[(x)], + [Define to the typecast required for arg 2 of _mm256_maskstore_ps()]) +fi + +AC_CACHE_SAVE + +AH_TOP([ +#ifndef _SAH_CONFIG_H_ +#define _SAH_CONFIG_H_ + +#if defined(__linux__) +#define _POSIX_C_SOURCE 1 +#endif + +#ifdef _WIN32 +#include "win-sah_config.h" +#else +]) + + +AH_BOTTOM([ + +/* Define USE_NAMESPACES if you may access more than one database from the + * same program + */ + +#endif + +/* + * Use fftw if we have the library + */ +#if defined(HAVE_LIBFFTW3F) && defined(HAVE_FFTW3_H) +#define USE_FFTWF +#endif + +#if defined(USE_INFORMIX) && defined(USE_MYSQL) && defined(HAVE_NAMESPACES) +#define USE_NAMESPACES +#endif + +#if !defined(CUSTOM_STRING) && defined(COMPILER_STRING) +#define CUSTOM_STRING PACKAGE_STRING" "SVN_REV" "COMPILER_STRING +#endif + +#include "std_fixes.h" + +#endif +]) + +AC_CONFIG_FILES([Makefile + jpeglib/Makefile + client/Makefile + tools/Makefile + db/Makefile + db/tools/Makefile + db/schema_to_class + assimilator/Makefile + validate/Makefile + splitter/Makefile + ]) +AC_CONFIG_HEADERS([sah_config.h]) + +AC_OUTPUT +chmod +x db/schema_to_class diff --git a/configure.ac.public b/configure.ac.public new file mode 100644 index 0000000..c590496 --- /dev/null +++ b/configure.ac.public @@ -0,0 +1,141 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + + +AC_PREREQ(2.57) +AC_INIT(setiathome, 4.0, ports@setiathome.ssl.berkeley.edu) +AC_CONFIG_SRCDIR([client/analyze.h]) +AC_CONFIG_HEADER([config.h]) + +major_version=`echo AC_PACKAGE_VERSION | sed 's/\..*//'` +minor_version=`echo AC_PACKAGE_VERSION | sed 's/.*\.//' | sed 's/^0//'` +AC_SUBST([MAJOR_VERSION], [$major_version]) +AC_SUBST([MINOR_VERSION], [$minor_version]) +AC_DEFINE_UNQUOTED([VERSION_MAJOR],$major_version, [SETI@home major version number]) +AC_DEFINE_UNQUOTED([VERSION_MINOR],$minor_version, [SETI@home minor version number]) +AC_DEFINE_UNQUOTED([SAH_APP_NAME],["$PACKAGE_NAME"], [Define to the BOINC application name for setiathome]) + +AC_CANONICAL_HOST + +# Checks for programs. +AC_PROG_CXX +AC_PROG_CXXCPP +AC_PROG_AWK +AC_PROG_RANLIB +AC_PATH_PROG(SED,[sed]) +AC_PATH_PROG(TR,[tr]) +AC_PATH_PROGS(AR,[ar lib]) +AC_PATH_PROG(AUTOCONF,[autoconf]) +AC_PATH_PROG(AUTOHEADER,[autoheader]) +AC_PATH_PROGS(INDENT,[astyle indent]) +AC_PATH_PROG(SORT,[sort]) +AC_PATH_PROG(UNIQ,[uniq]) +AC_PATH_PROG(CAT,[cat type]) +AC_PATH_PROG(MV,[mv]) +AC_PATH_PROGS(RM,[rm Rm del erase delete]) +if test -n `echo $INDENT | grep astyle` +then + AC_SUBST([INDENT_FLAGS],["--c --indent-classes --indent-switches --brackets=attach --convert-tabs"]) +else + AC_SUBST([INDENT_FLAGS],["-kr"]) +fi +AC_PROG_MAKE_SET +SAH_DLLEXT +SAH_LIBEXT +if test -n "$EXEEXT" +then + DOTEXEEXT=".$EXEEXT" +fi +AC_SUBST(DOTEXEEXT) +AC_SYS_LARGEFILE + +# Checks for libraries. +AC_LANG(C++) +AC_CHECK_LIB([cygipc],[shmget]) +AC_CHECK_LIB([aio], [aio_fork]) +AC_CHECK_LIB([dl], [dlclose]) +AC_CHECK_LIB([elf], [elf_hash]) +AC_CHECK_LIB([fftw], [fftw_create_plan]) +AC_CHECK_LIB([m], [sin]) +AC_CHECK_LIB([nsl], [gethostbyname]) +AC_CHECK_LIB([socket], [bind]) +AC_CHECK_LIB([z], [uncompress]) +AC_CHECK_LIB([stdc++], [main]) +SAH_GRX_LIBS +SAH_CHECK_BOINC +SAH_CHECK_MYSQL +SAH_CHECK_INFORMIX +SAH_FIND_S4PATH +AC_CACHE_SAVE + +# Checks for header files. +AC_HEADER_STDC +SAH_LARGEFILE_BREAKS_CXX +SAH_HEADER_STDCXX +AC_HEADER_SYS_WAIT +AC_CHECK_HEADERS([fcntl.h inttypes.h limits.h memory.h stdlib.h string.h strings.h sys/ioctl.h sys/statvfs.h sys/time.h unistd.h dirent.h]) +SAH_GRX_INCLUDES +AC_CACHE_SAVE + +# Checks for typedefs, structures, and compiler characteristics. +AC_HEADER_STDBOOL +AC_C_CONST +AC_C_INLINE +AC_C_LONG_DOUBLE +AC_TYPE_OFF_T +AC_TYPE_SIZE_T +AC_STRUCT_ST_BLOCKS +AC_STRUCT_TM +AC_CHECK_SIZEOF([long int]) +AC_CHECK_SIZEOF([long double]) +AC_CHECK_TYPES([long long,_int64,bool]) +AC_CACHE_SAVE + +# Checks for library functions. +AC_LANG(C) +AC_FUNC_FORK +AC_HEADER_MAJOR +AC_FUNC_MALLOC +AC_FUNC_REALLOC +AC_FUNC_STAT +AC_FUNC_STRFTIME +AC_CHECK_FUNCS([atexit floor getcwd memset munmap putenv sqrt strchr strstr atoll]) +SAH_CHECK_NAMESPACES +AH_TEMPLATE([HAVE_STD_MIN],[Define to 1 if min is in namespace std::]) +AH_TEMPLATE([HAVE_STD_MAX],[Define to 1 if max is in namespace std::]) +AH_TEMPLATE([HAVE_STD_TRANSFORM],[Define to 1 if transform is in namespace std::]) +SAH_FUNCS_IN_NAMESPACE([['min(0,0)'] ['max(0,0)'] ['transform((char *)0,(char *)0,(char *)0,(int(*)(int))malloc)']],std) + +AC_CACHE_SAVE + +AH_TOP([ +#ifndef _SAH_CONFIG_H_ +#define _SAH_CONFIG_H_ + +#ifdef _WIN32 +#include "win-config.h" +#endif +]) + + +AH_BOTTOM([ + +/* Define USE_NAMESPACES if you may access more than one database from the + * same program + */ +#if defined(USE_INFORMIX) && defined(USE_MYSQL) && defined(HAVE_NAMESPACES) +#define USE_NAMESPACES +#endif + +#include "std_fixes.h" + +#endif +]) + +AC_CONFIG_FILES([Makefile + client/Makefile + db/Makefile + db/schema_to_class + ]) +AC_OUTPUT +chmod +x db/schema_to_class diff --git a/db/Makefile.in b/db/Makefile.in new file mode 100644 index 0000000..871fac5 --- /dev/null +++ b/db/Makefile.in @@ -0,0 +1,74 @@ +# $Id: Makefile.in,v 1.14.2.1 2007/03/13 17:41:27 vonkorff Exp $ +# +# + +@SET_MAKE@ + +EXEEXT = @EXEEXT@ +OBJEXT = @OBJEXT@ +LIBEXT = @LIBEXT@ +DLLEXT = @DLLEXT@ +DOTEXEEXT = @DOTEXEEXT@ + + +SUFFIXES = .ec .cpp .c .@OBJEXT@ .@DLLEXT@ .@LIBEXT@ @DOTEXEEXT@ + +BOINCDIR = @BOINCDIR@ +INFORMIXDIR = @INFORMIXDIR@ +MYSQL_LIBS = @MYSQL_LIBS@ +MYSQL_CFLAGS = @MYSQL_CFLAGS@ +INFORMIX_CFLAGS = @INFORMIX_CFLAGS@ + +DBLIBS=@INFORMIX_LIBS@ @MYSQL_LIBS@ -lsocket -lm -lstdc++ @PTHREAD_LIBS@ + +CC = @CC@ +CXX = @CXX@ +CFLAGS = @CFLAGS@ -I.. -I$(BOINCDIR) -I$(BOINCDIR)/lib -I$(BOINCDIR)/api $(INFORMIX_CFLAGS) $(MYSQL_CFLAGS) @PTHREAD_CFLAGS@ +CXXFLAGS = $(CFLAGS) + +.cpp.@OBJEXT@: + $(CXX) $(CXXFLAGS) -o $*.@OBJEXT@ -c $< + + +all: dependencies app_config.@OBJEXT@ schema_master_client.@OBJEXT@ sqlrow_client.@OBJEXT@ schema_master.@OBJEXT@ sqlrow.@OBJEXT@ sqlifx.@OBJEXT@ sqlblob.@OBJEXT@ sqlint8.@OBJEXT@ xml_util.@OBJEXT@ + +schema_master.cpp: schema_master.sql find_references.awk schema_to_class.awk + chmod +x schema_to_class + ./schema_to_class schema_master.sql + +schema_master.h: schema_master.sql find_references.awk schema_to_class.awk + chmod +x schema_to_class + ./schema_to_class schema_master.sql + + +schema_master_client.@OBJEXT@: schema_master.cpp schema_master.h db_table.h Makefile + $(CXX) $(CXXFLAGS) -DCLIENT -c -o schema_master_client.@OBJEXT@ schema_master.cpp + +sqlrow_client.@OBJEXT@: sqlrow.cpp sqlrow.h Makefile + $(CXX) $(CXXFLAGS) -DCLIENT -c -o sqlrow_client.@OBJEXT@ sqlrow.cpp + +schema_master.@OBJEXT@: schema_master.cpp schema_master.h db_table.h + +sqlifx.cpp: sqlifx.ec + $(INFORMIXDIR)/bin/esql -e $< + mv $*.c $*.cpp + +sqlifx.@OBJEXT@: sqlifx.cpp + +xml_util.@OBJEXT@: xml_util.cpp + +app_config.@OBJEXT@: app_config.cpp + +.ec.cpp: + $(INFORMIXDIR)/bin/esql -e $< + mv $*.c $*.cpp + +Makefile: Makefile.in ../config.status ../configure ../configure.ac + (cd ..; $(MAKE) config.status) + +dependencies: schema_master.cpp *.cpp *.h + $(CXX) $(CXXFLAGS) -M *.cpp > dependencies + + + +include dependencies diff --git a/db/app_config.cpp b/db/app_config.cpp new file mode 100644 index 0000000..0b808ef --- /dev/null +++ b/db/app_config.cpp @@ -0,0 +1,76 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#include "sah_config.h" +#include +#include +#include + +#ifdef HAVE_IEEEFP_H +#include +#endif + +#include "util.h" +#include "parse.h" +#include "error_numbers.h" + +#include "app_config.h" + +const char* APP_CONFIG_FILE = "sah_config.xml"; +//const char* APP_CONFIG_FILE = "sah_enhanced_config.xml"; + +int APP_CONFIG::parse(char* buf) { + + memset(this, 0, sizeof(APP_CONFIG)); + min_disk_free_pct=10; + parse_str(buf, "", scidb_name, sizeof(scidb_name)); + parse_int(buf, "", max_wus_ondisk); + parse_double(buf, "", min_disk_free_pct); + parse_int(buf, "", min_quorum ); + parse_int(buf, "", target_nresults); + parse_int(buf, "", max_error_results); + parse_int(buf, "", max_success_results); + parse_int(buf, "", max_total_results); + parse_bool(buf, "", assim_check_rfi); + if (match_tag(buf, "")) return 0; + return ERR_XML_PARSE; +} + +int APP_CONFIG::parse_file(char* dir) { + char* p; + char path[256]; + int retval; + + sprintf(path, "%s/%s", dir, APP_CONFIG_FILE); + retval = read_file_malloc(path, p); + if (retval) return retval; + return parse(p); +} + + +// main routine for testing +//int main(int argc, char** argv) { +// +// APP_CONFIG sah_config; +// int retval; +// +// retval = sah_config.parse_file(".."); +// if (retval) { +// fprintf(stderr, "Can't parse config file\n"); +// } else { +// fprintf(stderr, "db name is %s\n", sah_config.scidb_name); +// } +//} diff --git a/db/app_config.h b/db/app_config.h new file mode 100644 index 0000000..5823966 --- /dev/null +++ b/db/app_config.h @@ -0,0 +1,33 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +class APP_CONFIG { +public: + char scidb_name[256]; + int max_wus_ondisk; // actually the number of unsent results + double min_disk_free_pct; // Minimum free disk percent in download dir. + + // fields in the boinc DB workunit record + int min_quorum; // minimum quorum size + int target_nresults; // try to get this many successful results + int max_error_results; // WU error if < #error results + int max_total_results; // WU error if < #total results + int max_success_results; // WU error if < #success results + bool assim_check_rfi; // if true, assimilator will check each signal for rfi + + int parse(char*); + int parse_file(char* dir="."); +}; diff --git a/db/db_table.h b/db/db_table.h new file mode 100644 index 0000000..4a062db --- /dev/null +++ b/db/db_table.h @@ -0,0 +1,594 @@ +// $Id: db_table.h,v 1.45.2.10 2007/05/31 22:03:18 korpela Exp $ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#ifndef _DB_TABLE_H_ +#define _DB_TABLE_H_ + +#include "sah_config.h" +#include +#include +#include +#include +#include "track_mem.h" +#include "sqlrow.h" +#include "sqlblob.h" +#include "sqlint8.h" + +#ifndef CLIENT +#include "sqlapi.h" +#endif + +#include "row_cache.h" + +template +class db_type : public track_mem { + private: + static const char * const type_name; + static const char * const column_names[]; + public: + db_type(T &t); + ~db_type(); + db_type &operator =(const T &t); + db_type &operator =(const db_type &t); + void clear() { *me = T(); }; + std::string update_format() const; + std::string insert_format() const; + std::string select_format() const; + std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; + std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=1, + const char *tag=type_name) const; + const char *search_tag(const char *s=0); + operator T(); + static int nfields() { return _nfields; }; + private: + T *me; + static const char * _search_tag; + static const int _nfields; +}; + +template +class db_table; + +template +std::ostream &operator <<(std::ostream &o, const db_type &a) { + o << a.print_xml(); + return o; +} + + +template +std::ostream &operator <<(std::ostream &o, const db_table &a) { + o << a.me->print_xml(); + return o; +} + +template +std::istream &operator >>(std::istream &i, db_table &a) { + std::string s; + static std::string remainder(""); + std::string s_tag("<"); + std::string e_tag("> s; + if (!found && xml_match_tag(s,s_tag.c_str())) { + found=true; + a.clear(); + } + if (found) buffer+=(s+' '); + if (found && xml_match_tag(s,e_tag.c_str())) { + found=false; + done=true; + } + } + a.me->parse_xml(buffer); + std::string::size_type p=buffer.find(e_tag); + if (p != std::string::npos) { + p=buffer.find('>',p+1); + if (p != std::string::npos) { + remainder=buffer.substr(p,buffer.size()-p); + } else { + remainder=std::string(""); + } + } + return i; +} + +#ifdef _WIN32 +#undef DELETE +#endif + +template +class db_table : public track_mem { + public: + db_table(T &t, SQL_CURSOR c); + ~db_table(); +#ifndef CLIENT + sqlint8_t insert(sqlint8_t lid=0); + std::string update_format() const; + std::string insert_format() const; + std::string select_format() const; + bool update(); + bool fetch(sqlint8_t lid=0); + bool cached_fetch(sqlint8_t lid=0); + bool fetch(const std::string &where); + bool authorize_delete(bool auth) {return delete_flag=auth;}; + bool DELETE(sqlint8_t lid=0); + bool DELETE(const std::string &where); + bool open_query(const std::string &where="",const std::string &order="",const std::string &directives=""); + bool get_next(bool cache_result); + bool get_next() { return get_next(false); }; + bool close_query(); + static int nfields() { return _nfields; }; + sqlint8_t count(const std::string &where=""); + SQL_CURSOR get_cursor(); + int set_cache_size(int i) { cache.set_size(i); return(cache.get_size()); }; + time_t set_cache_ttl(time_t i) { cache.set_ttl(i); return(cache.get_ttl()); }; +#endif + const char *search_tag(const char *s=0); + operator T(); + db_table &operator =(const T &t); + db_table &operator =(const db_table &t); + void clear() { *me = T(); }; +#if !defined(_WIN32) || (_MSC_VER > 1300) || defined(__MINGW32__) + friend std::ostream &operator <<(std::ostream &o, const db_table &a); + friend std::istream &operator >>(std::istream &i, db_table &a); +#else + friend std::ostream &operator <<(std::ostream &o, const db_table &a); + friend std::istream &operator >>(std::istream &i, db_table &a); +#endif + static const char * const table_name; + private: + T *me; + static row_cache cache; + static const char *_search_tag; + static const int _nfields; + static const char * const column_names[]; + bool delete_flag; + SQL_CURSOR cursor; +}; + +template +row_cache db_table::cache; + +template +class db_reference { + private: + T r; + public: + ID_TYPE &id; + db_reference(ID_TYPE req_id=0); + db_reference(const db_reference &a) : r(a.r), id(*(ID_TYPE *)(&(r.id))) {}; + T &get(); + std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; + std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=1, + const char *tag=0) const; + void parse_xml(std::string &buf, const char *tag); + void parse(const std::string &buf); + void parse(const SQL_ROW &buf); + operator T() const; + T *operator ->(); + const T *operator ->() const; + db_reference &operator =(const T &t); + db_reference &operator =(const db_reference &t); +}; + +template +db_reference::db_reference(ID_TYPE req_id) : id(*(ID_TYPE *)(&(r.id))) { + id=req_id; +} + +template +db_type::db_type(T &t) : track_mem(T::type_name), me(&t) {} + +template +db_type::~db_type() {} + +template +db_table::db_table(T &t, SQL_CURSOR c) : track_mem(T::table_name), me(&t), delete_flag(false), cursor(c) {} + +template +db_table::~db_table() {} + +template +db_type::operator T() { + return *me; +} + +template +db_table::operator T() { + return *me; +} + +template +db_reference::operator T() const { + return r; +} + +template +T *db_reference::operator ->() { + return &r; +} + +template +const T *db_reference::operator ->() const { + return &r; +} + +#ifndef CLIENT +template +sqlint8_t db_table::insert(sqlint8_t lid) { + int rv=0; + std::string query=std::string("insert into ")+table_name+" values ("+me->insert_format()+");"; + // jeffc + me->id=lid; + std::string tmpstr(me->print()); + // old SQL_ROW valarr(tmpstr.c_str(),_nfields); + SQL_ROW valarr(&tmpstr,_nfields); + const char *q=query.c_str(); + while (*q) { + if (*(q++)=='?') rv++; + } + if ((int)valarr.argc() != rv) { + std::cout << "Error " << valarr.argc() << "!=" << rv << std::endl; + std::cout << query << std::endl; + for (int i=0; i<(int)valarr.argc(); i++) { + std::cout << i << " " << valarr[i] << std::endl; + } + } +#ifndef NODB + rv=sql_open(query.c_str(),valarr); + if (rv>=0 && sql_fetch(rv)) { + me->id=sql_insert_id(rv); + sql_close(rv); + return static_cast(me->id); + } +#else + std::cout << query << std::endl; +#endif + return 0; +} + +template +sqlint8_t db_new(T &t) { + return (static_cast *>(&t)->insert()); +} + +template +bool db_table::update() { + char buf[256]; + int rv,i; + sprintf(buf," where id=%"INT8_FMT,INT8_PRINT_CAST(sqlint8_t(me->id))); +#if 0 + std::string query=std::string("update ")+table_name+" set ("; + for (i=1;i<_nfields-1;i++) query+=std::string(column_names[i])+','; + query+=std::string(column_names[i])+")=("+me->update_format()+") "; +#else + std::string query=std::string("update ")+table_name+" set "; + for (i=1;i<_nfields-1;i++) query+=std::string(column_names[i])+"=?,"; + query+=std::string(column_names[i])+"=?"; +#endif + std::string tmpstr(me->print()); + // old SQL_ROW valarr(SQL_ROW(tmpstr.c_str(),_nfields)+1); + SQL_ROW valarr(SQL_ROW(&tmpstr,_nfields)+1); + query+=buf; +#ifndef NODB + rv=sql_run(query.c_str(),valarr); +#else + std::cout << query << std::endl; + rv=true; +#endif + return rv; +} + + +template +bool db_update(T &t) { + return (static_cast *>(&t)->update()); +} + +template +bool db_table::DELETE(sqlint8_t lid) { + bool rv; + char buf[256]; + if (!delete_flag) return false; + if (lid) me->id=lid; + sprintf(buf," where id=%"INT8_FMT,INT8_PRINT_CAST(sqlint8_t(me->id))); + std::string query=std::string("delete from ")+table_name+std::string(buf); + rv=sql_run(query.c_str()); + delete_flag=false; + return rv; +} + +template +bool db_table::DELETE(const std::string &where) { + bool rv; + if (!delete_flag) return false; + if (where.size() = 0) return false; + std::string query=std::string("delete from ")+table_name+std::string(" ")+where; + rv=sql_run(query.c_str()); + delete_flag=false; + return rv; +} + +template +bool db_table::cached_fetch(sqlint8_t lid) { + T *item; + if (!lid) { + lid=me->id; + } + if ((item=cache.find(lid)) != NULL) { + *this=*item; + return true; + } else { + bool rv=fetch(lid); + if (rv) cache.insert(*this); + return rv; + } +} + +template +bool db_table::fetch(sqlint8_t lid) { + char buf[1024]; + int tmp; + SQL_ROW values; + int rv; + bool rv2=false; + if (!lid) { + lid=me->id; + } + sprintf(buf,"select * from %s where id=%"INT8_FMT,table_name,lid); +#ifndef NODB + if (((rv=sql_open(buf))>=0) && + (rv2=sql_fetch(rv))) + { + values=sql_values(rv,&tmp); + me->parse(values); + } + if (rv>=0) sql_close(rv); +#else + std::cout << buf << std::endl; +#endif + return (rv2); +} + +template +bool db_table::fetch(const std::string &where) { + char buf[1024]; + int tmp; + SQL_ROW values; + int rv; + bool rv2=false; + sprintf(buf,"select * from %s %s",table_name,where.c_str()); +#ifndef NODB + if (((rv=sql_open(buf))>=0) && + (rv2=sql_fetch(rv))) + { + values=sql_values(rv,&tmp); + me->parse(values); + } + if (rv>=0) sql_close(rv); +#else + std::cout << buf << std::endl; + rv=0; +#endif + return (rv2); +} + +template +bool db_table::open_query(const std::string &where,const std::string &order,const std::string &directives) { + bool rv; + std::string query=std::string("select ")+directives+" * from "+table_name+" "+where+" "+order; +#ifndef NODB + if (cursor>=0) sql_close(cursor); + rv=(chk_cursor(cursor=sql_open(query.c_str()),"db_table<>::open_query")); + if (!rv) { + sql_close(cursor); + cursor=-1; + } + return (cursor>=0); +#else + std::cout << query << std::endl; + return true; +#endif +} + +template +bool db_table::get_next(bool cache) { + int rv; +#ifndef NODB + if ((rv=sql_fetch(cursor))) { + SQL_ROW r(sql_values(cursor,&rv)); + me->parse(r); + } else { + sql_close(cursor); + } + return (rv); +#else + static int i=30; + me->id=i; + return ((i--)>0); +#endif +} + +template +bool db_table::close_query() { +#ifndef NODB + if (cursor>=0) sql_close(cursor); +#endif + cursor=-1; + return cursor; +} + +template +sqlint8_t db_table::count(const std::string &where) { + std::string query=std::string("select count(*) from ")+table_name+" "+where; + int fd,rv=0; + sqlint8_t lrv=-1; +#ifndef NODB + if ((fd=sql_open(query.c_str()))>=0) { + if (sql_fetch(fd)) { + SQL_ROW r(sql_values(fd,&rv)); + if (rv) { + lrv=atoll(r[0]->c_str()); + } + } + sql_close(fd); + } + return lrv; +#else + return 30; +#endif +} + +#endif + +template +std::ostream &operator <<(std::ostream &o, const db_reference &a) { + o << a.print_xml(); + return o; +} + +template +const char *db_type::search_tag(const char *s) { + if (s) { + _search_tag=s; + } else { + _search_tag=type_name; + } + return _search_tag; +} + +template +const char *db_table::search_tag(const char *s) { + if (s) { + _search_tag=s; + } else { + _search_tag=table_name; + } + return _search_tag; +} + +template +std::string db_type::print(int full_subtables, int show_ids, int no_refs) const { + return me->print(full_subtables,show_ids,no_refs); +} + +template +std::string db_type::print_xml(int full_subtables, int show_ids, int no_refs, + const char *tag) const { + return me->print_xml(full_subtables,show_ids,no_refs,tag); +} + +template +std::string db_reference::print(int full_subtables, int show_ids, int no_refs) const { + if (full_subtables) { + return r.print(full_subtables,show_ids,no_refs); + } else { + char buf[256]; + sprintf(buf,"%"INT8_FMT,INT8_PRINT_CAST(sqlint8_t(r.id))); + return std::string(buf); + } +} + +template +std::string db_reference::print_xml(int full_subtables, int show_ids, int no_refs, const char *tag) const { + if (full_subtables) { + return r.print_xml(full_subtables,show_ids,no_refs,tag); + } else { + char buf[256]; + sprintf(buf,"%"INT8_FMT"",INT8_PRINT_CAST(sqlint8_t(r.id))); + return std::string(buf); + } +} + +template +void db_reference::parse(const std::string &buf) { + r.parse(buf); +} + +template +void db_reference::parse(const SQL_ROW &buf) { + r.parse(buf); +} + +template +void db_reference::parse_xml(std::string &buf, const char *tag) { + r.parse_xml(buf,tag); +} + +template +db_type &db_type::operator =(const T &t) { + if (me != &t) { + *me=t; + } + return *this; +} + +template +db_type &db_type::operator =(const db_type &t) { + if (this != &t) { + *me=*(t.me); + } + return *this; +} + +template +db_table &db_table::operator =(const T &t) { + if (me != &t) { + *me=t; + cursor=-1; + } + return *this; +} + +template +db_table &db_table::operator =(const db_table &t) { + if (this != &t) { + *me=*(t.me); + cursor=-1; + } + return *this; +} + +template +db_reference &db_reference::operator =(const T &t) { + if (&id != &(t.id)) { + r=t; + } + return *this; +} + +template +db_reference &db_reference::operator =(const db_reference &t) { + if (&id != &(t.id)) { + r=t.r; + } + return *this; +} + + +#endif diff --git a/db/find_references.awk b/db/find_references.awk new file mode 100644 index 0000000..38458d4 --- /dev/null +++ b/db/find_references.awk @@ -0,0 +1,59 @@ +# Copyright 2003 Regents of the University of California + +# SETI_BOINC is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2, or (at your option) any later +# version. + +# SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. + +# You should have received a copy of the GNU General Public License along +# with SETI_BOINC; see the file COPYING. If not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +/create table/ { n=split($3,a,"."); table=a[n]; } +/create table/,/\);/ { + for (i=1;i +#include +#include +#include +#include + +#include "db_table.h" +#include "schema_master.h" +#include "sqlhdr.h" + +const char * from_db = "sah2@sci_master_shm"; +const char * to_db = "t_sah@temp_master_tcp"; + +template +int read_and_compare_dbs (T& table, int modulo, int remainder, int maxnum, int minid, int maxid); + +int main(int argc, char ** argv) { + + receiver_config receiver_cfg; + recorder_config recorder_cfg; + splitter_config splitter_cfg; + analysis_config analysis_cfg; + tape tp; + settings set; + workunit_grp wug; + workunit_header wuh; + result res; + triplet trip; + gaussian gauss; + pulse pul; + spike sp; + + char type[32]; + int modulo, remainder, maxnum, minid, maxid; + + + if (argc != 7) { + fprintf(stderr, "Usage: migrate_test table_name modulo remainder maximum_number_of_elements minimum_id maximum_id\n"); + exit (1); + } else { + strcpy(type, argv[1]); + modulo = atoi(argv[2]); + remainder = atoi(argv[3]); + maxnum = atoi(argv[4]); + minid = atoi(argv[5]); + maxid = atoi(argv[6]); + } + + // how to call read_and_compare_dbs? + + if (strcmp(type,"receiver_config") == 0) { read_and_compare_dbs (receiver_cfg, modulo, remainder, maxnum, minid, maxid); } + else if (strcmp(type,"recorder_config") == 0) { read_and_compare_dbs (recorder_cfg, modulo, remainder, maxnum, minid, maxid); } + else if (strcmp(type,"splitter_config") == 0) { read_and_compare_dbs (splitter_cfg, modulo, remainder, maxnum, minid, maxid); } + else if (strcmp(type,"analysis_config") == 0) { read_and_compare_dbs (analysis_cfg, modulo, remainder, maxnum, minid, maxid); } + else if (strcmp(type,"tape") == 0) { read_and_compare_dbs (tp, modulo, remainder, maxnum, minid, maxid); } + else if (strcmp(type,"settings") == 0) { read_and_compare_dbs (set, modulo, remainder, maxnum, minid, maxid); } + else if (strcmp(type,"workunit_grp") == 0) { read_and_compare_dbs (wug, modulo, remainder, maxnum, minid, maxid); } + else if (strcmp(type,"workunit_header") == 0) { read_and_compare_dbs (wuh, modulo, remainder, maxnum, minid, maxid); } + else if (strcmp(type,"result") == 0) { read_and_compare_dbs (res, modulo, remainder, maxnum, minid, maxid); } + else if (strcmp(type,"triplet") == 0) { read_and_compare_dbs (trip, modulo, remainder, maxnum, minid, maxid); } + else if (strcmp(type,"gaussian") == 0) { read_and_compare_dbs (gauss, modulo, remainder, maxnum, minid, maxid); } + else if (strcmp(type,"pulse") == 0) { read_and_compare_dbs (pul, modulo, remainder, maxnum, minid, maxid); } + else if (strcmp(type,"spike") == 0) { read_and_compare_dbs (sp, modulo, remainder, maxnum, minid, maxid); } + else { + fprintf(stderr, "Don't recognize table: %s\n", type); + exit(1); + } + exit (0); +} + + +template +int read_and_compare_dbs (T& table, int modulo, int remainder, int maxnum, int minid, int maxid) { + + int retval, get_next_retval; + int i, match, dontmatch; + std::vector id_list; + + char c_string[256]; + std::string where_clause; + + if (remainder != 0) { + sprintf(c_string, "where id >= %d and id <= %d and MOD(id, %d) = %d", minid, maxid, modulo, remainder); + } else { + sprintf(c_string, "where id >= %d and id <= %d", minid, maxid); + } + where_clause = c_string; + std::cerr << "where clause: " << where_clause << "\n"; + + retval = db_change(from_db); + fprintf(stderr, "db_change(%s) returns %d\n", from_db, retval); + retval = table.open_query(where_clause); + fprintf(stderr, "open_query returns %d, %d\n", retval, sql_last_error_code()); + i = 0; + while (get_next_retval = table.get_next() && (i++) < maxnum) id_list.push_back (table.id); + table.close_query(); + + typename std::vector::iterator id_iter = id_list.begin(); + T from_thisrow; + T to_thisrow; + + match = dontmatch = 0; + while (id_iter != id_list.end()) { + sprintf(c_string, "where id = %d", (*id_iter)); + where_clause = c_string; + db_change(from_db); + table.open_query(where_clause); + table.get_next(); + from_thisrow = table; + db_change(to_db); + table.open_query(where_clause); + table.get_next(); + to_thisrow = table; + std::cerr << "FROM DATABASE:\n" << from_thisrow.print(0,1,0) << "\n\nTO DATABASE:\n" << to_thisrow.print(0,1,0) << "\n"; + if (from_thisrow.print(0,1,0) == to_thisrow.print(0,1,0)) { match++; } + else { + dontmatch++; + fprintf(stderr,"DON'T MATCH!!!\n"); + } + fprintf(stderr,"--------------------------\n"); + id_iter++; + } + fprintf(stderr,"num match: %d don't match: %d\n",match,dontmatch); + return 0; +} diff --git a/db/row_cache.h b/db/row_cache.h new file mode 100644 index 0000000..c5a3f75 --- /dev/null +++ b/db/row_cache.h @@ -0,0 +1,122 @@ +// $Id: db_table.h,v 1.45.2.10 2007/05/31 22:03:18 korpela Exp $ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#include +#include +#include + + +template +class row_cache { + private: + class cache_element { + public: + T item; + time_t insert_time; + cache_element(const T &val) : item(val), insert_time(time(0)) {}; + cache_element &operator =(const T &val) { + if (&item != &val) { + item=val; + insert_time=time(0); + } + return *this; + }; + }; + int size; + std::vector elements; + typedef typename std::vector::iterator element_iterator; + typedef typename std::map::iterator id_iterator; + typedef typename std::multimap::iterator time_iterator; + std::map id_index; + std::multimap time_index; + time_t ttl; + size_t hits; + size_t misses; + + public: + // constructors + row_cache(int newsize=1024, time_t newttl=3600) : + size(newsize), ttl(newttl), hits(0), misses(0) { invalidate_all(); }; + + ~row_cache() { +#ifndef _NDEBUG + print_stats(); +#endif + }; + + void print_stats() { + printf("Cache statistics on %s\n",T::table_name); + printf("%ld hits %ld misses %f percent hit rate\n", + misses, hits, (double)hits/(hits+misses)); + } + + void invalidate_all() { + elements.clear(); + elements.reserve(size); + time_index.clear(); + id_index.clear(); + }; + + void set_size(int newsize) { + size=newsize; + invalidate_all(); + } + + int get_size() { + return(size); + } + + void set_ttl(time_t newttl) { + ttl=newttl; + } + + time_t get_ttl() { + return(ttl); + } + + void insert(const T &val) { + element_iterator inserted; + if (elements.size() < size) { + // not full yet, just push_back() + elements.push_back(val); + inserted=elements.end()-1; + } else { + // We're full so we'll find the oldest element to overwrite. + time_iterator oldest=time_index.begin(); + inserted=oldest->second; + // remove it from the indexes + id_index.erase(id_index.find(inserted->item.id)); + time_index.erase(oldest); + // overwrite the old cache item with the new one. + *inserted=val; + } + // add the new item to the indexes. + id_index[inserted->item.id]=inserted; + time_index.insert(std::pair(inserted->insert_time,inserted)); + }; + + T *find(sqlint8_t id) { + id_iterator i=id_index.find(id); + if ((i == id_index.end()) || (i->second->insert_time+ttl < time(0))) { + misses++; + return NULL; + } + hits++; + return &(i->second->item); + }; +}; + diff --git a/db/schema_master.cpp b/db/schema_master.cpp new file mode 100644 index 0000000..79420a2 --- /dev/null +++ b/db/schema_master.cpp @@ -0,0 +1,13433 @@ +// This file is automatically generated. Do not edit +#include "sah_config.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "parse.h" +#include "xml_util.h" +#include "db_table.h" +#include "schema_master.h" + +#ifdef _WIN32 +#pragma warning( disable : 4355 ) +#endif + +#define found(x) ((x != std::string::npos)) + +#ifdef USE_NAMESPACE +using namespace ifx; +#endif + + +const char *db_name="sah2b@sah_master_tcp"; +int db_is_open; + +template <> const char *const db_type::type_name="coordinate_t"; +template <> const char *db_type::_search_tag=type_name; +template <> const int db_type::_nfields=3; +template <> const char *const db_type::column_names[3]= {"time","ra","dec"}; + +coordinate_t::coordinate_t() : + db_type(*this), + time(0), + ra(0), + dec(0) { + db_open(); +} + + +coordinate_t::coordinate_t(const coordinate_t &a) : + db_type(*this), + time(a.time), + ra(a.ra), + dec(a.dec) { + db_open(); +} + + +coordinate_t::coordinate_t(const SQL_ROW &a) : + db_type(*this) { + db_open(); + parse(a); +} + + +coordinate_t::coordinate_t(const std::string &s,const char *tag) : + db_type(*this) { + db_open(); + if (xml_match_tag(s,tag)) { + parse_xml(s,tag); + } else { + parse(s); + } +} + + +coordinate_t &coordinate_t::operator =(const coordinate_t &a) { + if (&a != this) { + time=a.time; + ra=a.ra; + dec=a.dec; + } + return (*this); +} + + +std::string coordinate_t::update_format() const { + std::ostringstream rv(""); + + rv << "ROW("; + for (int i=1; i<3; i++) { + rv << "?,"; + } + rv << "?"; + rv << ")"; + + return rv.str(); +} + + +std::string coordinate_t::insert_format() const { + return update_format(); +} + +std::string coordinate_t::select_format() const { + std::string rv(""); + for (int i=0; i<2; i++) { + rv+="?,"; + } + rv+="?"; + return rv; +} + +std::string coordinate_t::print(int full_subtables, int show_ids, int no_refs) const { + std::ostringstream rv(""); + + rv.precision(14); + rv << "ROW("; + rv << time; + rv << ','; + rv << ra; + rv << ','; + rv << dec; + rv << ")"; + return rv.str(); +} + + +std::string coordinate_t::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { + std::ostringstream rv(""); + + rv.precision(14); + rv << xml_indent() << '<' << tag << ">\n"; + xml_indent(2); + rv << xml_indent() << "\n"; + rv << xml_indent() << "" << ra << "\n"; + rv << xml_indent() << "" << dec << "\n"; + xml_indent(-2); + rv << xml_indent() << "\n"; + return rv.str(); +} + + +void coordinate_t::parse_xml(const std::string &s,const char *tag) { + std::string field,sub; + if (extract_xml_record(s,tag,field)) { + std::string::size_type pos=0; + if (extract_xml_record(field,"time",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> time; + } + if (extract_xml_record(field,"ra",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> ra; + } + if (extract_xml_record(field,"dec",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> dec; + } + } +} + +void coordinate_t::parse(const SQL_ROW &s) { + { + std::istringstream row(*(s[0])); + row >> time; + } + { + std::istringstream row(*(s[1])); + row >> ra; + } + { + std::istringstream row(*(s[2])); + row >> dec; + } +} + +void coordinate_t::parse(const std::string &s) { + SQL_ROW row(&s,3); + parse(row); +} + +template <> const char *const db_type::type_name="chirp_parameter_t"; +template <> const char *db_type::_search_tag=type_name; +template <> const int db_type::_nfields=2; +template <> const char *const db_type::column_names[2]= {"chirp_limit","fft_len_flags"}; + +chirp_parameter_t::chirp_parameter_t() : + db_type(*this), + chirp_limit(0), + fft_len_flags(0) { + db_open(); +} + + +chirp_parameter_t::chirp_parameter_t(const chirp_parameter_t &a) : + db_type(*this), + chirp_limit(a.chirp_limit), + fft_len_flags(a.fft_len_flags) { + db_open(); +} + + +chirp_parameter_t::chirp_parameter_t(const SQL_ROW &a) : + db_type(*this) { + db_open(); + parse(a); +} + + +chirp_parameter_t::chirp_parameter_t(const std::string &s,const char *tag) : + db_type(*this) { + db_open(); + if (xml_match_tag(s,tag)) { + parse_xml(s,tag); + } else { + parse(s); + } +} + + +chirp_parameter_t &chirp_parameter_t::operator =(const chirp_parameter_t &a) { + if (&a != this) { + chirp_limit=a.chirp_limit; + fft_len_flags=a.fft_len_flags; + } + return (*this); +} + + +std::string chirp_parameter_t::update_format() const { + std::ostringstream rv(""); + + rv << "ROW("; + for (int i=1; i<2; i++) { + rv << "?,"; + } + rv << "?"; + rv << ")"; + + return rv.str(); +} + + +std::string chirp_parameter_t::insert_format() const { + return update_format(); +} + +std::string chirp_parameter_t::select_format() const { + std::string rv(""); + for (int i=0; i<1; i++) { + rv+="?,"; + } + rv+="?"; + return rv; +} + +std::string chirp_parameter_t::print(int full_subtables, int show_ids, int no_refs) const { + std::ostringstream rv(""); + + rv.precision(14); + rv << "ROW("; + rv << chirp_limit; + rv << ','; + rv << fft_len_flags; + rv << ")"; + return rv.str(); +} + + +std::string chirp_parameter_t::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { + std::ostringstream rv(""); + + rv.precision(14); + rv << xml_indent() << '<' << tag << ">\n"; + xml_indent(2); + rv << xml_indent() << "" << chirp_limit << "\n"; + rv << xml_indent() << "" << fft_len_flags << "\n"; + xml_indent(-2); + rv << xml_indent() << "\n"; + return rv.str(); +} + + +void chirp_parameter_t::parse_xml(const std::string &s,const char *tag) { + std::string field,sub; + if (extract_xml_record(s,tag,field)) { + std::string::size_type pos=0; + if (extract_xml_record(field,"chirp_limit",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> chirp_limit; + } + if (extract_xml_record(field,"fft_len_flags",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> fft_len_flags; + } + } +} + +void chirp_parameter_t::parse(const SQL_ROW &s) { + { + std::istringstream row(*(s[0])); + row >> chirp_limit; + } + { + std::istringstream row(*(s[1])); + row >> fft_len_flags; + } +} + +void chirp_parameter_t::parse(const std::string &s) { + SQL_ROW row(&s,2); + parse(row); +} + +template <> const char *const db_type::type_name="subband_description_t"; +template <> const char *db_type::_search_tag=type_name; +template <> const int db_type::_nfields=4; +template <> const char *const db_type::column_names[4]= {"number","center","base","sample_rate"}; + +subband_description_t::subband_description_t() : + db_type(*this), + number(0), + center(0), + base(0), + sample_rate(0) { + db_open(); +} + + +subband_description_t::subband_description_t(const subband_description_t &a) : + db_type(*this), + number(a.number), + center(a.center), + base(a.base), + sample_rate(a.sample_rate) { + db_open(); +} + + +subband_description_t::subband_description_t(const SQL_ROW &a) : + db_type(*this) { + db_open(); + parse(a); +} + + +subband_description_t::subband_description_t(const std::string &s,const char *tag) : + db_type(*this) { + db_open(); + if (xml_match_tag(s,tag)) { + parse_xml(s,tag); + } else { + parse(s); + } +} + + +subband_description_t &subband_description_t::operator =(const subband_description_t &a) { + if (&a != this) { + number=a.number; + center=a.center; + base=a.base; + sample_rate=a.sample_rate; + } + return (*this); +} + + +std::string subband_description_t::update_format() const { + std::ostringstream rv(""); + + rv << "ROW("; + for (int i=1; i<4; i++) { + rv << "?,"; + } + rv << "?"; + rv << ")"; + + return rv.str(); +} + + +std::string subband_description_t::insert_format() const { + return update_format(); +} + +std::string subband_description_t::select_format() const { + std::string rv(""); + for (int i=0; i<3; i++) { + rv+="?,"; + } + rv+="?"; + return rv; +} + +std::string subband_description_t::print(int full_subtables, int show_ids, int no_refs) const { + std::ostringstream rv(""); + + rv.precision(14); + rv << "ROW("; + rv << number; + rv << ','; + rv << center; + rv << ','; + rv << base; + rv << ','; + rv << sample_rate; + rv << ")"; + return rv.str(); +} + + +std::string subband_description_t::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { + std::ostringstream rv(""); + + rv.precision(14); + rv << xml_indent() << '<' << tag << ">\n"; + xml_indent(2); + rv << xml_indent() << "" << number << "\n"; + rv << xml_indent() << "
    " << center << "
    \n"; + rv << xml_indent() << "" << base << "\n"; + rv << xml_indent() << "" << sample_rate << "\n"; + xml_indent(-2); + rv << xml_indent() << "\n"; + return rv.str(); +} + + +void subband_description_t::parse_xml(const std::string &s,const char *tag) { + std::string field,sub; + if (extract_xml_record(s,tag,field)) { + std::string::size_type pos=0; + if (extract_xml_record(field,"number",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> number; + } + if (extract_xml_record(field,"center",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> center; + } + if (extract_xml_record(field,"base",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> base; + } + if (extract_xml_record(field,"sample_rate",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> sample_rate; + } + } +} + +void subband_description_t::parse(const SQL_ROW &s) { + { + std::istringstream row(*(s[0])); + row >> number; + } + { + std::istringstream row(*(s[1])); + row >> center; + } + { + std::istringstream row(*(s[2])); + row >> base; + } + { + std::istringstream row(*(s[3])); + row >> sample_rate; + } +} + +void subband_description_t::parse(const std::string &s) { + SQL_ROW row(&s,4); + parse(row); +} + +template <> const char *const db_type::type_name="data_description_t"; +template <> const char *db_type::_search_tag=type_name; +template <> const int db_type::_nfields=9; +template <> const char *const db_type::column_names[9]= {"start_ra","start_dec","end_ra","end_dec","true_angle_range","time_recorded","time_recorded_jd","nsamples","coords"}; + +data_description_t::data_description_t() : + db_type(*this), + start_ra(0), + start_dec(0), + end_ra(0), + end_dec(0), + true_angle_range(0), + time_recorded_jd(0), + nsamples(0), + coords((coordinate_t *)0,0,_x_xml_values) { + db_open(); + time_recorded[0]=0; +} + + +data_description_t::data_description_t(const data_description_t &a) : + db_type(*this), + start_ra(a.start_ra), + start_dec(a.start_dec), + end_ra(a.end_ra), + end_dec(a.end_dec), + true_angle_range(a.true_angle_range), + time_recorded_jd(a.time_recorded_jd), + nsamples(a.nsamples), + coords(a.coords) { + db_open(); + strcpy(time_recorded,a.time_recorded); +} + + +data_description_t::data_description_t(const SQL_ROW &a) : + db_type(*this) { + db_open(); + parse(a); +} + + +data_description_t::data_description_t(const std::string &s,const char *tag) : + db_type(*this) { + db_open(); + if (xml_match_tag(s,tag)) { + parse_xml(s,tag); + } else { + parse(s); + } +} + + +data_description_t &data_description_t::operator =(const data_description_t &a) { + if (&a != this) { + start_ra=a.start_ra; + start_dec=a.start_dec; + end_ra=a.end_ra; + end_dec=a.end_dec; + true_angle_range=a.true_angle_range; + time_recorded_jd=a.time_recorded_jd; + nsamples=a.nsamples; + { + coords.clear(); + std::vector::const_iterator i(a.coords.begin()); + for (; i!=a.coords.end(); i++) { + coords.push_back(*i); + } + } + strcpy(time_recorded,a.time_recorded); + } + return (*this); +} + + +std::string data_description_t::update_format() const { + std::ostringstream rv(""); + + rv << "ROW("; + for (int i=1; i<9; i++) { + rv << "?,"; + } + rv << "?"; + rv << ")"; + + return rv.str(); +} + + +std::string data_description_t::insert_format() const { + return update_format(); +} + +std::string data_description_t::select_format() const { + std::string rv(""); + for (int i=0; i<8; i++) { + rv+="?,"; + } + rv+="?"; + return rv; +} + +std::string data_description_t::print(int full_subtables, int show_ids, int no_refs) const { + std::ostringstream rv(""); + + rv.precision(14); + rv << "ROW("; + rv << start_ra; + rv << ','; + rv << start_dec; + rv << ','; + rv << end_ra; + rv << ','; + rv << end_dec; + rv << ','; + rv << true_angle_range; + rv << ','; + rv << "'" << time_recorded << "'"; + rv << ','; + rv << time_recorded_jd; + rv << ','; + rv << nsamples; + rv << ','; + rv << "LIST {"; + { + std::vector::const_iterator p=coords.begin(); + for (; pprint(); + if (p != coords.end()-1) { + rv << ','; + } else { + rv << "}"; + } + } + } + rv << ")"; + return rv.str(); +} + + +std::string data_description_t::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { + std::ostringstream rv(""); + + rv.precision(14); + rv << xml_indent() << '<' << tag << ">\n"; + xml_indent(2); + rv << xml_indent() << "" << start_ra << "\n"; + rv << xml_indent() << "" << start_dec << "\n"; + rv << xml_indent() << "" << end_ra << "\n"; + rv << xml_indent() << "" << end_dec << "\n"; + rv << xml_indent() << "" << true_angle_range << "\n"; + { + std::string enc_field=xml_encode_string(time_recorded,std::min(strlen(time_recorded),sizeof(time_recorded))); + rv << xml_indent() << ""; + rv << enc_field << "\n"; + } + rv << xml_indent() << "" << time_recorded_jd << "\n"; + rv << xml_indent() << "" << nsamples << "\n"; + if (coords.size()) { + rv << xml_indent() << "\n" ; + rv << enc_string; + } + } + rv << xml_indent(-2); + rv << "\n"; + xml_indent(-2); + rv << xml_indent() << "\n"; + return rv.str(); +} + + +void data_description_t::parse_xml(const std::string &s,const char *tag) { + std::string field,sub; + if (extract_xml_record(s,tag,field)) { + std::string::size_type pos=0; + if (extract_xml_record(field,"start_ra",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> start_ra; + } + if (extract_xml_record(field,"start_dec",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> start_dec; + } + if (extract_xml_record(field,"end_ra",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> end_ra; + } + if (extract_xml_record(field,"end_dec",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> end_dec; + } + if (extract_xml_record(field,"true_angle_range",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> true_angle_range; + } + if (extract_xml_record(field,"time_recorded",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::string::size_type epos=sub.find("<",pos); + if (epos==std::string::npos) { + epos=sub.find('\n',pos); + } + if (epos==std::string::npos) { + epos=pos+strlen(sub.c_str()+pos); + } + std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); + strncpy(time_recorded,(const char *)&(in.front()),std::min(in.size(),(size_t)255)); + time_recorded[std::min(in.size(),(size_t)254)]=0; + } + if (extract_xml_record(field,"time_recorded_jd",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> time_recorded_jd; + } + if (extract_xml_record(field,"nsamples",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> nsamples; + } + coords.clear(); + if (extract_xml_record(field,"coords",sub)) { + pos=0; + while ((pos=sub.find("",pos); + } + } + } +} + +void data_description_t::parse(const SQL_ROW &s) { + { + std::istringstream row(*(s[0])); + row >> start_ra; + } + { + std::istringstream row(*(s[1])); + row >> start_dec; + } + { + std::istringstream row(*(s[2])); + row >> end_ra; + } + { + std::istringstream row(*(s[3])); + row >> end_dec; + } + { + std::istringstream row(*(s[4])); + row >> true_angle_range; + } + { + strncpy(time_recorded,s[5]->c_str(),255); + time_recorded[254]=0; + } + { + std::istringstream row(*(s[6])); + row >> time_recorded_jd; + } + { + std::istringstream row(*(s[7])); + row >> nsamples; + } + { + std::string::size_type p,q; + int i; + coords.clear(); + SQL_ROW tmp(s[8]); + for (i=0; i const char *const db_table::table_name="receiver_config"; +template <> const char *db_table::_search_tag=table_name; +template <> const int db_table::_nfields=16; +template <> const char *const db_table::column_names[16]= {"id","s4_id","name","beam_width","center_freq","latitude","longitude","elevation","diameter","az_orientation","az_corr_coeff","zen_corr_coeff","array_az_ellipse","array_za_ellipse","array_angle","min_vgc"}; + +receiver_config::receiver_config() : + db_table(*this,-1), + id(0), + s4_id(0), + beam_width(0), + center_freq(0), + latitude(0), + longitude(0), + elevation(0), + diameter(0), + az_orientation(0), + az_corr_coeff((float *)0,0,_x_csv), + zen_corr_coeff((float *)0,0,_x_csv), + array_az_ellipse(0), + array_za_ellipse(0), + array_angle(0), + min_vgc(0) { + db_open(); + name[0]=0; +} + + +receiver_config::receiver_config(const receiver_config &a) : + db_table(*this,-1), + id(a.id), + s4_id(a.s4_id), + beam_width(a.beam_width), + center_freq(a.center_freq), + latitude(a.latitude), + longitude(a.longitude), + elevation(a.elevation), + diameter(a.diameter), + az_orientation(a.az_orientation), + az_corr_coeff(a.az_corr_coeff), + zen_corr_coeff(a.zen_corr_coeff), + array_az_ellipse(a.array_az_ellipse), + array_za_ellipse(a.array_za_ellipse), + array_angle(a.array_angle), + min_vgc(a.min_vgc) { + db_open(); + strcpy(name,a.name); +} + + +receiver_config::receiver_config(const SQL_ROW &a) : + db_table(*this,-1) { + db_open(); + parse(a); +} + + +receiver_config::receiver_config(const std::string &s,const char *tag) : + db_table(*this,-1) { + db_open(); + if (xml_match_tag(s,tag)) { + parse_xml(s,tag); + } else { + parse(s); + } +} + + +receiver_config &receiver_config::operator =(const receiver_config &a) { + if (&a != this) { + id=a.id; + s4_id=a.s4_id; + beam_width=a.beam_width; + center_freq=a.center_freq; + latitude=a.latitude; + longitude=a.longitude; + elevation=a.elevation; + diameter=a.diameter; + az_orientation=a.az_orientation; + { + az_corr_coeff.clear(); + std::vector::const_iterator i(a.az_corr_coeff.begin()); + for (; i!=a.az_corr_coeff.end(); i++) { + az_corr_coeff.push_back(*i); + } + } + { + zen_corr_coeff.clear(); + std::vector::const_iterator i(a.zen_corr_coeff.begin()); + for (; i!=a.zen_corr_coeff.end(); i++) { + zen_corr_coeff.push_back(*i); + } + } + array_az_ellipse=a.array_az_ellipse; + array_za_ellipse=a.array_za_ellipse; + array_angle=a.array_angle; + min_vgc=a.min_vgc; + strcpy(name,a.name); + } + return (*this); +} + + +std::string receiver_config::update_format() const { + std::ostringstream rv(""); + + for (int i=2; i<16; i++) { + rv << "?,"; + } + rv << "?"; + return rv.str(); +} + + +std::string receiver_config::insert_format() const { + return std::string("?,")+update_format(); +} + +std::string receiver_config::select_format() const { + std::string rv(""); + for (int i=0; i<15; i++) { + rv+="?,"; + } + rv+="?"; + return rv; +} + +std::string receiver_config::print(int full_subtables, int show_ids, int no_refs) const { + std::ostringstream rv(""); + + rv.precision(14); + if (show_ids) { + rv << id; + } + rv << ','; + rv << s4_id; + rv << ','; + rv << "'" << name << "'"; + rv << ','; + rv << beam_width; + rv << ','; + rv << center_freq; + rv << ','; + rv << latitude; + rv << ','; + rv << longitude; + rv << ','; + rv << elevation; + rv << ','; + rv << diameter; + rv << ','; + rv << az_orientation; + rv << ','; + rv << "LIST {"; + { + std::vector::const_iterator p=az_corr_coeff.begin(); + for (; p::const_iterator p=zen_corr_coeff.begin(); + for (; p\n"; + xml_indent(2); + if (show_ids) { + rv << xml_indent() << "" << id << "\n"; + } + rv << xml_indent() << "" << s4_id << "\n"; + { + std::string enc_field=xml_encode_string(name,std::min(strlen(name),sizeof(name))); + rv << xml_indent() << ""; + rv << enc_field << "\n"; + } + rv << xml_indent() << "" << beam_width << "\n"; + rv << xml_indent() << "" << center_freq << "\n"; + rv << xml_indent() << "" << latitude << "\n"; + rv << xml_indent() << "" << longitude << "\n"; + rv << xml_indent() << "" << elevation << "\n"; + rv << xml_indent() << "" << diameter << "\n"; + rv << xml_indent() << "" << az_orientation << "\n"; + if (az_corr_coeff.size()) { + rv << xml_indent() << "" ; + rv << enc_string; + } + } + rv << "\n"; + if (zen_corr_coeff.size()) { + rv << xml_indent() << "" ; + rv << enc_string; + } + } + rv << "\n"; + rv << xml_indent() << "" << array_az_ellipse << "\n"; + rv << xml_indent() << "" << array_za_ellipse << "\n"; + rv << xml_indent() << "" << array_angle << "\n"; + rv << xml_indent() << "" << min_vgc << "\n"; + xml_indent(-2); + rv << xml_indent() << "\n"; + return rv.str(); +} + + +void receiver_config::parse_xml(const std::string &s,const char *tag) { + std::string field,sub; + if (extract_xml_record(s,tag,field)) { + std::string::size_type pos=0; + if (extract_xml_record(field,"id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> id; + } + if (extract_xml_record(field,"s4_id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> s4_id; + } + if (extract_xml_record(field,"name",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::string::size_type epos=sub.find("<",pos); + if (epos==std::string::npos) { + epos=sub.find('\n',pos); + } + if (epos==std::string::npos) { + epos=pos+strlen(sub.c_str()+pos); + } + std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); + strncpy(name,(const char *)&(in.front()),std::min(in.size(),(size_t)255)); + name[std::min(in.size(),(size_t)254)]=0; + } + if (extract_xml_record(field,"beam_width",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> beam_width; + } + if (extract_xml_record(field,"center_freq",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> center_freq; + } + if (extract_xml_record(field,"latitude",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> latitude; + } + if (extract_xml_record(field,"longitude",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> longitude; + } + if (extract_xml_record(field,"elevation",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> elevation; + } + if (extract_xml_record(field,"diameter",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> diameter; + } + if (extract_xml_record(field,"az_orientation",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> az_orientation; + } + az_corr_coeff.clear(); + if (extract_xml_record(field,"az_corr_coeff",sub)) { + pos=sub.find(">"); + do { + if (pos!=std::string::npos) { + do { + pos++; + } while ((sub[pos]=='\n') || (sub[pos]==',')); + std::istringstream in(std::string(sub.c_str()+pos)); + float tmp; + in >> tmp; + az_corr_coeff.push_back(tmp); + } + } while ((pos=sub.find(",",pos)) != std::string::npos); + } + zen_corr_coeff.clear(); + if (extract_xml_record(field,"zen_corr_coeff",sub)) { + pos=sub.find(">"); + do { + if (pos!=std::string::npos) { + do { + pos++; + } while ((sub[pos]=='\n') || (sub[pos]==',')); + std::istringstream in(std::string(sub.c_str()+pos)); + float tmp; + in >> tmp; + zen_corr_coeff.push_back(tmp); + } + } while ((pos=sub.find(",",pos)) != std::string::npos); + } + if (extract_xml_record(field,"array_az_ellipse",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> array_az_ellipse; + } + if (extract_xml_record(field,"array_za_ellipse",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> array_za_ellipse; + } + if (extract_xml_record(field,"array_angle",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> array_angle; + } + if (extract_xml_record(field,"min_vgc",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> min_vgc; + } + } +} + +void receiver_config::parse(const SQL_ROW &s) { + { + std::istringstream row(*(s[0])); + row >> id; + } + { + std::istringstream row(*(s[1])); + row >> s4_id; + } + { + strncpy(name,s[2]->c_str(),255); + name[254]=0; + } + { + std::istringstream row(*(s[3])); + row >> beam_width; + } + { + std::istringstream row(*(s[4])); + row >> center_freq; + } + { + std::istringstream row(*(s[5])); + row >> latitude; + } + { + std::istringstream row(*(s[6])); + row >> longitude; + } + { + std::istringstream row(*(s[7])); + row >> elevation; + } + { + std::istringstream row(*(s[8])); + row >> diameter; + } + { + std::istringstream row(*(s[9])); + row >> az_orientation; + } + { + std::string::size_type p,q; + int i; + az_corr_coeff.clear(); + SQL_ROW tmp(s[10]); + for (i=0; i> tmp0; + az_corr_coeff.push_back(tmp0); + } + } + { + std::string::size_type p,q; + int i; + zen_corr_coeff.clear(); + SQL_ROW tmp(s[11]); + for (i=0; i> tmp0; + zen_corr_coeff.push_back(tmp0); + } + } + { + std::istringstream row(*(s[12])); + row >> array_az_ellipse; + } + { + std::istringstream row(*(s[13])); + row >> array_za_ellipse; + } + { + std::istringstream row(*(s[14])); + row >> array_angle; + } + { + std::istringstream row(*(s[15])); + row >> min_vgc; + } +} + +void receiver_config::parse(const std::string &s) { + SQL_ROW row(&s,16); + parse(row); +} + +template <> const char *const db_table::table_name="recorder_config"; +template <> const char *db_table::_search_tag=table_name; +template <> const int db_table::_nfields=6; +template <> const char *const db_table::column_names[6]= {"id","name","bits_per_sample","sample_rate","beams","version"}; + +recorder_config::recorder_config() : + db_table(*this,-1), + id(0), + bits_per_sample(0), + sample_rate(0), + beams(0), + version(0) { + db_open(); + name[0]=0; +} + + +recorder_config::recorder_config(const recorder_config &a) : + db_table(*this,-1), + id(a.id), + bits_per_sample(a.bits_per_sample), + sample_rate(a.sample_rate), + beams(a.beams), + version(a.version) { + db_open(); + strcpy(name,a.name); +} + + +recorder_config::recorder_config(const SQL_ROW &a) : + db_table(*this,-1) { + db_open(); + parse(a); +} + + +recorder_config::recorder_config(const std::string &s,const char *tag) : + db_table(*this,-1) { + db_open(); + if (xml_match_tag(s,tag)) { + parse_xml(s,tag); + } else { + parse(s); + } +} + + +recorder_config &recorder_config::operator =(const recorder_config &a) { + if (&a != this) { + id=a.id; + bits_per_sample=a.bits_per_sample; + sample_rate=a.sample_rate; + beams=a.beams; + version=a.version; + strcpy(name,a.name); + } + return (*this); +} + + +std::string recorder_config::update_format() const { + std::ostringstream rv(""); + + for (int i=2; i<6; i++) { + rv << "?,"; + } + rv << "?"; + return rv.str(); +} + + +std::string recorder_config::insert_format() const { + return std::string("?,")+update_format(); +} + +std::string recorder_config::select_format() const { + std::string rv(""); + for (int i=0; i<5; i++) { + rv+="?,"; + } + rv+="?"; + return rv; +} + +std::string recorder_config::print(int full_subtables, int show_ids, int no_refs) const { + std::ostringstream rv(""); + + rv.precision(14); + if (show_ids) { + rv << id; + } + rv << ','; + rv << "'" << name << "'"; + rv << ','; + rv << bits_per_sample; + rv << ','; + rv << sample_rate; + rv << ','; + rv << beams; + rv << ','; + rv << version; + return rv.str(); +} + + +std::string recorder_config::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { + std::ostringstream rv(""); + + rv.precision(14); + rv << xml_indent() << '<' << tag << ">\n"; + xml_indent(2); + if (show_ids) { + rv << xml_indent() << "" << id << "\n"; + } + { + std::string enc_field=xml_encode_string(name,std::min(strlen(name),sizeof(name))); + rv << xml_indent() << ""; + rv << enc_field << "\n"; + } + rv << xml_indent() << "" << bits_per_sample << "\n"; + rv << xml_indent() << "" << sample_rate << "\n"; + rv << xml_indent() << "" << beams << "\n"; + rv << xml_indent() << "" << version << "\n"; + xml_indent(-2); + rv << xml_indent() << "\n"; + return rv.str(); +} + + +void recorder_config::parse_xml(const std::string &s,const char *tag) { + std::string field,sub; + if (extract_xml_record(s,tag,field)) { + std::string::size_type pos=0; + if (extract_xml_record(field,"id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> id; + } + if (extract_xml_record(field,"name",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::string::size_type epos=sub.find("<",pos); + if (epos==std::string::npos) { + epos=sub.find('\n',pos); + } + if (epos==std::string::npos) { + epos=pos+strlen(sub.c_str()+pos); + } + std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); + strncpy(name,(const char *)&(in.front()),std::min(in.size(),(size_t)64)); + name[std::min(in.size(),(size_t)63)]=0; + } + if (extract_xml_record(field,"bits_per_sample",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> bits_per_sample; + } + if (extract_xml_record(field,"sample_rate",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> sample_rate; + } + if (extract_xml_record(field,"beams",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> beams; + } + if (extract_xml_record(field,"version",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> version; + } + } +} + +void recorder_config::parse(const SQL_ROW &s) { + { + std::istringstream row(*(s[0])); + row >> id; + } + { + strncpy(name,s[1]->c_str(),64); + name[63]=0; + } + { + std::istringstream row(*(s[2])); + row >> bits_per_sample; + } + { + std::istringstream row(*(s[3])); + row >> sample_rate; + } + { + std::istringstream row(*(s[4])); + row >> beams; + } + { + std::istringstream row(*(s[5])); + row >> version; + } +} + +void recorder_config::parse(const std::string &s) { + SQL_ROW row(&s,6); + parse(row); +} + +template <> const char *const db_table::table_name="splitter_config"; +template <> const char *db_table::_search_tag=table_name; +template <> const int db_table::_nfields=10; +template <> const char *const db_table::column_names[10]= {"id","version","data_type","fft_len","ifft_len","filter","window","samples_per_wu","highpass""blanker_filter"}; + +splitter_config::splitter_config() : + db_table(*this,-1), + id(0), + version(0), + fft_len(0), + ifft_len(0), + samples_per_wu(0), + highpass(0) { + db_open(); + data_type[0]=0; + filter[0]=0; + window[0]=0; + blanker_filter[0]=0; +} + + +splitter_config::splitter_config(const splitter_config &a) : + db_table(*this,-1), + id(a.id), + version(a.version), + fft_len(a.fft_len), + ifft_len(a.ifft_len), + samples_per_wu(a.samples_per_wu), + highpass(a.highpass) { + db_open(); + strcpy(data_type,a.data_type); + strcpy(filter,a.filter); + strcpy(window,a.window); + strcpy(blanker_filter,a.blanker_filter); +} + + +splitter_config::splitter_config(const SQL_ROW &a) : + db_table(*this,-1) { + db_open(); + parse(a); +} + + +splitter_config::splitter_config(const std::string &s,const char *tag) : + db_table(*this,-1) { + db_open(); + if (xml_match_tag(s,tag)) { + parse_xml(s,tag); + } else { + parse(s); + } +} + + +splitter_config &splitter_config::operator =(const splitter_config &a) { + if (&a != this) { + id=a.id; + version=a.version; + fft_len=a.fft_len; + ifft_len=a.ifft_len; + samples_per_wu=a.samples_per_wu; + highpass=a.highpass; + strcpy(data_type,a.data_type); + strcpy(filter,a.filter); + strcpy(window,a.window); + strcpy(blanker_filter,a.blanker_filter); + } + return (*this); +} + + +std::string splitter_config::update_format() const { + std::ostringstream rv(""); + + for (int i=2; i<10; i++) { + rv << "?,"; + } + rv << "?"; + return rv.str(); +} + + +std::string splitter_config::insert_format() const { + return std::string("?,")+update_format(); +} + +std::string splitter_config::select_format() const { + std::string rv(""); + for (int i=0; i<9; i++) { + rv+="?,"; + } + rv+="?"; + return rv; +} + +std::string splitter_config::print(int full_subtables, int show_ids, int no_refs) const { + std::ostringstream rv(""); + + rv.precision(14); + if (show_ids) { + rv << id; + } + rv << ','; + rv << version; + rv << ','; + rv << "'" << data_type << "'"; + rv << ','; + rv << fft_len; + rv << ','; + rv << ifft_len; + rv << ','; + rv << "'" << filter << "'"; + rv << ','; + rv << "'" << window << "'"; + rv << ','; + rv << samples_per_wu; + rv << ','; + rv << highpass; + rv << ','; + rv << "'" << blanker_filter << "'"; + return rv.str(); +} + + +std::string splitter_config::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { + std::ostringstream rv(""); + + rv.precision(14); + rv << xml_indent() << '<' << tag << ">\n"; + xml_indent(2); + if (show_ids) { + rv << xml_indent() << "" << id << "\n"; + } + rv << xml_indent() << "" << version << "\n"; + { + std::string enc_field=xml_encode_string(data_type,std::min(strlen(data_type),sizeof(data_type))); + rv << xml_indent() << ""; + rv << enc_field << "\n"; + } + rv << xml_indent() << "" << fft_len << "\n"; + rv << xml_indent() << "" << ifft_len << "\n"; + { + std::string enc_field=xml_encode_string(filter,std::min(strlen(filter),sizeof(filter))); + rv << xml_indent() << ""; + rv << enc_field << "\n"; + } + { + std::string enc_field=xml_encode_string(window,std::min(strlen(window),sizeof(window))); + rv << xml_indent() << ""; + rv << enc_field << "\n"; + } + rv << xml_indent() << "" << samples_per_wu << "\n"; + rv << xml_indent() << "" << highpass << "\n"; + { + std::string enc_field=xml_encode_string(blanker_filter,std::min(strlen(blanker_filter),sizeof(blanker_filter))); + rv << xml_indent() << ""; + rv << enc_field << "\n"; + } + xml_indent(-2); + rv << xml_indent() << "\n"; + return rv.str(); +} + + +void splitter_config::parse_xml(const std::string &s,const char *tag) { + std::string field,sub; + if (extract_xml_record(s,tag,field)) { + std::string::size_type pos=0; + if (extract_xml_record(field,"id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> id; + } + if (extract_xml_record(field,"version",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> version; + } + if (extract_xml_record(field,"data_type",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::string::size_type epos=sub.find("<",pos); + if (epos==std::string::npos) { + epos=sub.find('\n',pos); + } + if (epos==std::string::npos) { + epos=pos+strlen(sub.c_str()+pos); + } + std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); + strncpy(data_type,(const char *)&(in.front()),std::min(in.size(),(size_t)64)); + data_type[std::min(in.size(),(size_t)63)]=0; + } + if (extract_xml_record(field,"fft_len",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> fft_len; + } + if (extract_xml_record(field,"ifft_len",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> ifft_len; + } + if (extract_xml_record(field,"filter",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::string::size_type epos=sub.find("<",pos); + if (epos==std::string::npos) { + epos=sub.find('\n',pos); + } + if (epos==std::string::npos) { + epos=pos+strlen(sub.c_str()+pos); + } + std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); + strncpy(filter,(const char *)&(in.front()),std::min(in.size(),(size_t)64)); + filter[std::min(in.size(),(size_t)63)]=0; + } + if (extract_xml_record(field,"window",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::string::size_type epos=sub.find("<",pos); + if (epos==std::string::npos) { + epos=sub.find('\n',pos); + } + if (epos==std::string::npos) { + epos=pos+strlen(sub.c_str()+pos); + } + std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); + strncpy(window,(const char *)&(in.front()),std::min(in.size(),(size_t)64)); + window[std::min(in.size(),(size_t)63)]=0; + } + if (extract_xml_record(field,"samples_per_wu",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> samples_per_wu; + } + if (extract_xml_record(field,"highpass",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> highpass; + } + if (extract_xml_record(field,"blanker_filter",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::string::size_type epos=sub.find("<",pos); + if (epos==std::string::npos) { + epos=sub.find('\n',pos); + } + if (epos==std::string::npos) { + epos=pos+strlen(sub.c_str()+pos); + } + std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); + strncpy(blanker_filter,(const char *)&(in.front()),std::min(in.size(),(size_t)64)); + blanker_filter[std::min(in.size(),(size_t)63)]=0; + } + } +} + +void splitter_config::parse(const SQL_ROW &s) { + { + std::istringstream row(*(s[0])); + row >> id; + } + { + std::istringstream row(*(s[1])); + row >> version; + } + { + strncpy(data_type,s[2]->c_str(),64); + data_type[63]=0; + } + { + std::istringstream row(*(s[3])); + row >> fft_len; + } + { + std::istringstream row(*(s[4])); + row >> ifft_len; + } + { + strncpy(filter,s[5]->c_str(),64); + filter[63]=0; + } + { + strncpy(window,s[6]->c_str(),64); + window[63]=0; + } + { + std::istringstream row(*(s[7])); + row >> samples_per_wu; + } + { + std::istringstream row(*(s[8])); + row >> highpass; + } + { + strncpy(blanker_filter,s[9]->c_str(),64); + blanker_filter[63]=0; + } +} + +void splitter_config::parse(const std::string &s) { + SQL_ROW row(&s,10); + parse(row); +} + +template <> const char *const db_table::table_name="analysis_config"; +template <> const char *db_table::_search_tag=table_name; +template <> const int db_table::_nfields=39; +template <> const char *const db_table::column_names[39]= {"id","spike_thresh","spikes_per_spectrum","autocorr_thresh","autocorr_per_spectrum","autocorr_fftlen","gauss_null_chi_sq_thresh","gauss_chi_sq_thresh","gauss_power_thresh","gauss_peak_power_thresh","gauss_pot_length","pulse_thresh","pulse_display_thresh","pulse_max","pulse_min","pulse_fft_max","pulse_pot_length","triplet_thresh","triplet_max","triplet_min","triplet_pot_length","pot_overlap_factor","pot_t_offset","pot_min_slew","pot_max_slew","chirp_resolution","analysis_fft_lengths","bsmooth_boxcar_length","bsmooth_chunk_size","chirps","pulse_beams","max_signals","max_spikes","max_autocorr","max_gaussians","max_pulses","max_triplets","keyuniq","credit_rate"}; + +analysis_config::analysis_config() : + db_table(*this,-1), + id(0), + spike_thresh(0), + spikes_per_spectrum(0), + autocorr_thresh(0), + autocorr_per_spectrum(0), + autocorr_fftlen(0), + gauss_null_chi_sq_thresh(0), + gauss_chi_sq_thresh(0), + gauss_power_thresh(0), + gauss_peak_power_thresh(0), + gauss_pot_length(0), + pulse_thresh(0), + pulse_display_thresh(0), + pulse_max(0), + pulse_min(0), + pulse_fft_max(0), + pulse_pot_length(0), + triplet_thresh(0), + triplet_max(0), + triplet_min(0), + triplet_pot_length(0), + pot_overlap_factor(0), + pot_t_offset(0), + pot_min_slew(0), + pot_max_slew(0), + chirp_resolution(0), + analysis_fft_lengths(0), + bsmooth_boxcar_length(0), + bsmooth_chunk_size(0), + chirps((chirp_parameter_t *)0,0,_x_xml_values), + pulse_beams(0), + max_signals(0), + max_spikes(0), + max_autocorr(0), + max_gaussians(0), + max_pulses(0), + max_triplets(0), + keyuniq(0), + credit_rate(0) { + db_open(); +} + + +analysis_config::analysis_config(const analysis_config &a) : + db_table(*this,-1), + id(a.id), + spike_thresh(a.spike_thresh), + spikes_per_spectrum(a.spikes_per_spectrum), + autocorr_thresh(a.autocorr_thresh), + autocorr_per_spectrum(a.autocorr_per_spectrum), + autocorr_fftlen(a.autocorr_fftlen), + gauss_null_chi_sq_thresh(a.gauss_null_chi_sq_thresh), + gauss_chi_sq_thresh(a.gauss_chi_sq_thresh), + gauss_power_thresh(a.gauss_power_thresh), + gauss_peak_power_thresh(a.gauss_peak_power_thresh), + gauss_pot_length(a.gauss_pot_length), + pulse_thresh(a.pulse_thresh), + pulse_display_thresh(a.pulse_display_thresh), + pulse_max(a.pulse_max), + pulse_min(a.pulse_min), + pulse_fft_max(a.pulse_fft_max), + pulse_pot_length(a.pulse_pot_length), + triplet_thresh(a.triplet_thresh), + triplet_max(a.triplet_max), + triplet_min(a.triplet_min), + triplet_pot_length(a.triplet_pot_length), + pot_overlap_factor(a.pot_overlap_factor), + pot_t_offset(a.pot_t_offset), + pot_min_slew(a.pot_min_slew), + pot_max_slew(a.pot_max_slew), + chirp_resolution(a.chirp_resolution), + analysis_fft_lengths(a.analysis_fft_lengths), + bsmooth_boxcar_length(a.bsmooth_boxcar_length), + bsmooth_chunk_size(a.bsmooth_chunk_size), + chirps(a.chirps), + pulse_beams(a.pulse_beams), + max_signals(a.max_signals), + max_spikes(a.max_spikes), + max_autocorr(a.max_autocorr), + max_gaussians(a.max_gaussians), + max_pulses(a.max_pulses), + max_triplets(a.max_triplets), + keyuniq(a.keyuniq), + credit_rate(a.credit_rate) { + db_open(); +} + + +analysis_config::analysis_config(const SQL_ROW &a) : + db_table(*this,-1) { + db_open(); + parse(a); +} + + +analysis_config::analysis_config(const std::string &s,const char *tag) : + db_table(*this,-1) { + db_open(); + if (xml_match_tag(s,tag)) { + parse_xml(s,tag); + } else { + parse(s); + } +} + + +analysis_config &analysis_config::operator =(const analysis_config &a) { + if (&a != this) { + id=a.id; + spike_thresh=a.spike_thresh; + spikes_per_spectrum=a.spikes_per_spectrum; + autocorr_thresh=a.autocorr_thresh; + autocorr_per_spectrum=a.autocorr_per_spectrum; + autocorr_fftlen=a.autocorr_fftlen; + gauss_null_chi_sq_thresh=a.gauss_null_chi_sq_thresh; + gauss_chi_sq_thresh=a.gauss_chi_sq_thresh; + gauss_power_thresh=a.gauss_power_thresh; + gauss_peak_power_thresh=a.gauss_peak_power_thresh; + gauss_pot_length=a.gauss_pot_length; + pulse_thresh=a.pulse_thresh; + pulse_display_thresh=a.pulse_display_thresh; + pulse_max=a.pulse_max; + pulse_min=a.pulse_min; + pulse_fft_max=a.pulse_fft_max; + pulse_pot_length=a.pulse_pot_length; + triplet_thresh=a.triplet_thresh; + triplet_max=a.triplet_max; + triplet_min=a.triplet_min; + triplet_pot_length=a.triplet_pot_length; + pot_overlap_factor=a.pot_overlap_factor; + pot_t_offset=a.pot_t_offset; + pot_min_slew=a.pot_min_slew; + pot_max_slew=a.pot_max_slew; + chirp_resolution=a.chirp_resolution; + analysis_fft_lengths=a.analysis_fft_lengths; + bsmooth_boxcar_length=a.bsmooth_boxcar_length; + bsmooth_chunk_size=a.bsmooth_chunk_size; + { + chirps.clear(); + std::vector::const_iterator i(a.chirps.begin()); + for (; i!=a.chirps.end(); i++) { + chirps.push_back(*i); + } + } + pulse_beams=a.pulse_beams; + max_signals=a.max_signals; + max_spikes=a.max_spikes; + max_autocorr=a.max_autocorr; + max_gaussians=a.max_gaussians; + max_pulses=a.max_pulses; + max_triplets=a.max_triplets; + keyuniq=a.keyuniq; + credit_rate=a.credit_rate; + } + return (*this); +} + + +std::string analysis_config::update_format() const { + std::ostringstream rv(""); + + for (int i=2; i<39; i++) { + rv << "?,"; + } + rv << "?"; + return rv.str(); +} + + +std::string analysis_config::insert_format() const { + return std::string("?,")+update_format(); +} + +std::string analysis_config::select_format() const { + std::string rv(""); + for (int i=0; i<38; i++) { + rv+="?,"; + } + rv+="?"; + return rv; +} + +std::string analysis_config::print(int full_subtables, int show_ids, int no_refs) const { + std::ostringstream rv(""); + + rv.precision(14); + if (show_ids) { + rv << id; + } + rv << ','; + rv << spike_thresh; + rv << ','; + rv << spikes_per_spectrum; + rv << ','; + rv << autocorr_thresh; + rv << ','; + rv << autocorr_per_spectrum; + rv << ','; + rv << autocorr_fftlen; + rv << ','; + rv << gauss_null_chi_sq_thresh; + rv << ','; + rv << gauss_chi_sq_thresh; + rv << ','; + rv << gauss_power_thresh; + rv << ','; + rv << gauss_peak_power_thresh; + rv << ','; + rv << gauss_pot_length; + rv << ','; + rv << pulse_thresh; + rv << ','; + rv << pulse_display_thresh; + rv << ','; + rv << pulse_max; + rv << ','; + rv << pulse_min; + rv << ','; + rv << pulse_fft_max; + rv << ','; + rv << pulse_pot_length; + rv << ','; + rv << triplet_thresh; + rv << ','; + rv << triplet_max; + rv << ','; + rv << triplet_min; + rv << ','; + rv << triplet_pot_length; + rv << ','; + rv << pot_overlap_factor; + rv << ','; + rv << pot_t_offset; + rv << ','; + rv << pot_min_slew; + rv << ','; + rv << pot_max_slew; + rv << ','; + rv << chirp_resolution; + rv << ','; + rv << analysis_fft_lengths; + rv << ','; + rv << bsmooth_boxcar_length; + rv << ','; + rv << bsmooth_chunk_size; + rv << ','; + rv << "LIST {"; + { + std::vector::const_iterator p=chirps.begin(); + for (; pprint(); + if (p != chirps.end()-1) { + rv << ','; + } else { + rv << "}"; + } + } + } + rv << ','; + rv << pulse_beams; + rv << ','; + rv << max_signals; + rv << ','; + rv << max_spikes; + rv << ','; + rv << max_autocorr; + rv << ','; + rv << max_gaussians; + rv << ','; + rv << max_pulses; + rv << ','; + rv << max_triplets; + rv << ','; + rv << keyuniq; + rv << ','; + rv << credit_rate; + return rv.str(); +} + + +std::string analysis_config::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { + std::ostringstream rv(""); + + rv.precision(14); + rv << xml_indent() << '<' << tag << ">\n"; + xml_indent(2); + if (show_ids) { + rv << xml_indent() << "" << id << "\n"; + } + rv << xml_indent() << "" << spike_thresh << "\n"; + rv << xml_indent() << "" << spikes_per_spectrum << "\n"; + rv << xml_indent() << "" << autocorr_thresh << "\n"; + rv << xml_indent() << "" << autocorr_per_spectrum << "\n"; + rv << xml_indent() << "" << autocorr_fftlen << "\n"; + rv << xml_indent() << "" << gauss_null_chi_sq_thresh << "\n"; + rv << xml_indent() << "" << gauss_chi_sq_thresh << "\n"; + rv << xml_indent() << "" << gauss_power_thresh << "\n"; + rv << xml_indent() << "" << gauss_peak_power_thresh << "\n"; + rv << xml_indent() << "" << gauss_pot_length << "\n"; + rv << xml_indent() << "" << pulse_thresh << "\n"; + rv << xml_indent() << "" << pulse_display_thresh << "\n"; + rv << xml_indent() << "" << pulse_max << "\n"; + rv << xml_indent() << "" << pulse_min << "\n"; + rv << xml_indent() << "" << pulse_fft_max << "\n"; + rv << xml_indent() << "" << pulse_pot_length << "\n"; + rv << xml_indent() << "" << triplet_thresh << "\n"; + rv << xml_indent() << "" << triplet_max << "\n"; + rv << xml_indent() << "" << triplet_min << "\n"; + rv << xml_indent() << "" << triplet_pot_length << "\n"; + rv << xml_indent() << "" << pot_overlap_factor << "\n"; + rv << xml_indent() << "" << pot_t_offset << "\n"; + rv << xml_indent() << "" << pot_min_slew << "\n"; + rv << xml_indent() << "" << pot_max_slew << "\n"; + rv << xml_indent() << "" << chirp_resolution << "\n"; + rv << xml_indent() << "" << analysis_fft_lengths << "\n"; + rv << xml_indent() << "" << bsmooth_boxcar_length << "\n"; + rv << xml_indent() << "" << bsmooth_chunk_size << "\n"; + if (chirps.size()) { + rv << xml_indent() << "\n" ; + rv << enc_string; + } + } + rv << xml_indent(-2); + rv << "\n"; + rv << xml_indent() << "" << pulse_beams << "\n"; + rv << xml_indent() << "" << max_signals << "\n"; + rv << xml_indent() << "" << max_spikes << "\n"; + rv << xml_indent() << "" << max_autocorr << "\n"; + rv << xml_indent() << "" << max_gaussians << "\n"; + rv << xml_indent() << "" << max_pulses << "\n"; + rv << xml_indent() << "" << max_triplets << "\n"; + rv << xml_indent() << "" << keyuniq << "\n"; + rv << xml_indent() << "" << credit_rate << "\n"; + xml_indent(-2); + rv << xml_indent() << "\n"; + return rv.str(); +} + + +void analysis_config::parse_xml(const std::string &s,const char *tag) { + std::string field,sub; + if (extract_xml_record(s,tag,field)) { + std::string::size_type pos=0; + if (extract_xml_record(field,"id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> id; + } + if (extract_xml_record(field,"spike_thresh",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> spike_thresh; + } + if (extract_xml_record(field,"spikes_per_spectrum",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> spikes_per_spectrum; + } + if (extract_xml_record(field,"autocorr_thresh",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> autocorr_thresh; + } + if (extract_xml_record(field,"autocorr_per_spectrum",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> autocorr_per_spectrum; + } + if (extract_xml_record(field,"autocorr_fftlen",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> autocorr_fftlen; + } + if (extract_xml_record(field,"gauss_null_chi_sq_thresh",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> gauss_null_chi_sq_thresh; + } + if (extract_xml_record(field,"gauss_chi_sq_thresh",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> gauss_chi_sq_thresh; + } + if (extract_xml_record(field,"gauss_power_thresh",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> gauss_power_thresh; + } + if (extract_xml_record(field,"gauss_peak_power_thresh",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> gauss_peak_power_thresh; + } + if (extract_xml_record(field,"gauss_pot_length",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> gauss_pot_length; + } + if (extract_xml_record(field,"pulse_thresh",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> pulse_thresh; + } + if (extract_xml_record(field,"pulse_display_thresh",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> pulse_display_thresh; + } + if (extract_xml_record(field,"pulse_max",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> pulse_max; + } + if (extract_xml_record(field,"pulse_min",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> pulse_min; + } + if (extract_xml_record(field,"pulse_fft_max",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> pulse_fft_max; + } + if (extract_xml_record(field,"pulse_pot_length",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> pulse_pot_length; + } + if (extract_xml_record(field,"triplet_thresh",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> triplet_thresh; + } + if (extract_xml_record(field,"triplet_max",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> triplet_max; + } + if (extract_xml_record(field,"triplet_min",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> triplet_min; + } + if (extract_xml_record(field,"triplet_pot_length",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> triplet_pot_length; + } + if (extract_xml_record(field,"pot_overlap_factor",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> pot_overlap_factor; + } + if (extract_xml_record(field,"pot_t_offset",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> pot_t_offset; + } + if (extract_xml_record(field,"pot_min_slew",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> pot_min_slew; + } + if (extract_xml_record(field,"pot_max_slew",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> pot_max_slew; + } + if (extract_xml_record(field,"chirp_resolution",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> chirp_resolution; + } + if (extract_xml_record(field,"analysis_fft_lengths",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> analysis_fft_lengths; + } + if (extract_xml_record(field,"bsmooth_boxcar_length",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> bsmooth_boxcar_length; + } + if (extract_xml_record(field,"bsmooth_chunk_size",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> bsmooth_chunk_size; + } + chirps.clear(); + if (extract_xml_record(field,"chirps",sub)) { + pos=0; + while ((pos=sub.find("",pos); + } + } + if (extract_xml_record(field,"pulse_beams",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> pulse_beams; + } + if (extract_xml_record(field,"max_signals",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> max_signals; + } + if (extract_xml_record(field,"max_spikes",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> max_spikes; + } + if (extract_xml_record(field,"max_autocorr",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> max_autocorr; + } + if (extract_xml_record(field,"max_gaussians",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> max_gaussians; + } + if (extract_xml_record(field,"max_pulses",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> max_pulses; + } + if (extract_xml_record(field,"max_triplets",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> max_triplets; + } + if (extract_xml_record(field,"keyuniq",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> keyuniq; + } + if (extract_xml_record(field,"credit_rate",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> credit_rate; + } + } +} + +void analysis_config::parse(const SQL_ROW &s) { + { + std::istringstream row(*(s[0])); + row >> id; + } + { + std::istringstream row(*(s[1])); + row >> spike_thresh; + } + { + std::istringstream row(*(s[2])); + row >> spikes_per_spectrum; + } + { + std::istringstream row(*(s[3])); + row >> autocorr_thresh; + } + { + std::istringstream row(*(s[4])); + row >> autocorr_per_spectrum; + } + { + std::istringstream row(*(s[5])); + row >> autocorr_fftlen; + } + { + std::istringstream row(*(s[6])); + row >> gauss_null_chi_sq_thresh; + } + { + std::istringstream row(*(s[7])); + row >> gauss_chi_sq_thresh; + } + { + std::istringstream row(*(s[8])); + row >> gauss_power_thresh; + } + { + std::istringstream row(*(s[9])); + row >> gauss_peak_power_thresh; + } + { + std::istringstream row(*(s[10])); + row >> gauss_pot_length; + } + { + std::istringstream row(*(s[11])); + row >> pulse_thresh; + } + { + std::istringstream row(*(s[12])); + row >> pulse_display_thresh; + } + { + std::istringstream row(*(s[13])); + row >> pulse_max; + } + { + std::istringstream row(*(s[14])); + row >> pulse_min; + } + { + std::istringstream row(*(s[15])); + row >> pulse_fft_max; + } + { + std::istringstream row(*(s[16])); + row >> pulse_pot_length; + } + { + std::istringstream row(*(s[17])); + row >> triplet_thresh; + } + { + std::istringstream row(*(s[18])); + row >> triplet_max; + } + { + std::istringstream row(*(s[19])); + row >> triplet_min; + } + { + std::istringstream row(*(s[20])); + row >> triplet_pot_length; + } + { + std::istringstream row(*(s[21])); + row >> pot_overlap_factor; + } + { + std::istringstream row(*(s[22])); + row >> pot_t_offset; + } + { + std::istringstream row(*(s[23])); + row >> pot_min_slew; + } + { + std::istringstream row(*(s[24])); + row >> pot_max_slew; + } + { + std::istringstream row(*(s[25])); + row >> chirp_resolution; + } + { + std::istringstream row(*(s[26])); + row >> analysis_fft_lengths; + } + { + std::istringstream row(*(s[27])); + row >> bsmooth_boxcar_length; + } + { + std::istringstream row(*(s[28])); + row >> bsmooth_chunk_size; + } + { + std::string::size_type p,q; + int i; + chirps.clear(); + SQL_ROW tmp(s[29]); + for (i=0; i> pulse_beams; + } + { + std::istringstream row(*(s[31])); + row >> max_signals; + } + { + std::istringstream row(*(s[32])); + row >> max_spikes; + } + { + std::istringstream row(*(s[33])); + row >> max_autocorr; + } + { + std::istringstream row(*(s[34])); + row >> max_gaussians; + } + { + std::istringstream row(*(s[35])); + row >> max_pulses; + } + { + std::istringstream row(*(s[36])); + row >> max_triplets; + } + { + std::istringstream row(*(s[37])); + row >> keyuniq; + } + { + std::istringstream row(*(s[38])); + row >> credit_rate; + } +} + +void analysis_config::parse(const std::string &s) { + SQL_ROW row(&s,39); + parse(row); +} + +template <> const char *const db_table::table_name="science_config"; +template <> const char *db_table::_search_tag=table_name; +template <> const int db_table::_nfields=29; +template <> const char *const db_table::column_names[29]= {"id","active","qpix_scheme","qpix_nside","fpix_width","total_bandwidth","freq_uncertainty","fwhm_beamwidth","sky_disc_radius","observable_sky","epoch","bary_chirp_window","bary_freq_window","nonbary_freq_window","spike_obs_duration","spike_obs_interval","gauss_obs_duration","gauss_obs_interval","pulse_obs_duration","pulse_obs_interval","triplet_obs_duration","triplet_obs_interval","min_spike_id","min_autocorr_id","min_gaussian_id","min_pulse_id","min_triplet_id","min_app_version""info_xml"}; + +science_config::science_config() : + db_table(*this,-1), + id(0), + active(0), + qpix_nside(0), + fpix_width(0), + total_bandwidth(0), + freq_uncertainty(0), + fwhm_beamwidth(0), + sky_disc_radius(0), + observable_sky(0), + epoch(0), + bary_chirp_window(0), + bary_freq_window(0), + nonbary_freq_window(0), + spike_obs_duration(0), + spike_obs_interval(0), + gauss_obs_duration(0), + gauss_obs_interval(0), + pulse_obs_duration(0), + pulse_obs_interval(0), + triplet_obs_duration(0), + triplet_obs_interval(0), + min_spike_id(0), + min_autocorr_id(0), + min_gaussian_id(0), + min_pulse_id(0), + min_triplet_id(0), + min_app_version(0) { + db_open(); + qpix_scheme[0]=0; + info_xml[0]=0; +} + + +science_config::science_config(const science_config &a) : + db_table(*this,-1), + id(a.id), + active(a.active), + qpix_nside(a.qpix_nside), + fpix_width(a.fpix_width), + total_bandwidth(a.total_bandwidth), + freq_uncertainty(a.freq_uncertainty), + fwhm_beamwidth(a.fwhm_beamwidth), + sky_disc_radius(a.sky_disc_radius), + observable_sky(a.observable_sky), + epoch(a.epoch), + bary_chirp_window(a.bary_chirp_window), + bary_freq_window(a.bary_freq_window), + nonbary_freq_window(a.nonbary_freq_window), + spike_obs_duration(a.spike_obs_duration), + spike_obs_interval(a.spike_obs_interval), + gauss_obs_duration(a.gauss_obs_duration), + gauss_obs_interval(a.gauss_obs_interval), + pulse_obs_duration(a.pulse_obs_duration), + pulse_obs_interval(a.pulse_obs_interval), + triplet_obs_duration(a.triplet_obs_duration), + triplet_obs_interval(a.triplet_obs_interval), + min_spike_id(a.min_spike_id), + min_autocorr_id(a.min_autocorr_id), + min_gaussian_id(a.min_gaussian_id), + min_pulse_id(a.min_pulse_id), + min_triplet_id(a.min_triplet_id), + min_app_version(a.min_app_version) { + db_open(); + strcpy(qpix_scheme,a.qpix_scheme); + strcpy(info_xml,a.info_xml); +} + + +science_config::science_config(const SQL_ROW &a) : + db_table(*this,-1) { + db_open(); + parse(a); +} + + +science_config::science_config(const std::string &s,const char *tag) : + db_table(*this,-1) { + db_open(); + if (xml_match_tag(s,tag)) { + parse_xml(s,tag); + } else { + parse(s); + } +} + + +science_config &science_config::operator =(const science_config &a) { + if (&a != this) { + id=a.id; + active=a.active; + qpix_nside=a.qpix_nside; + fpix_width=a.fpix_width; + total_bandwidth=a.total_bandwidth; + freq_uncertainty=a.freq_uncertainty; + fwhm_beamwidth=a.fwhm_beamwidth; + sky_disc_radius=a.sky_disc_radius; + observable_sky=a.observable_sky; + epoch=a.epoch; + bary_chirp_window=a.bary_chirp_window; + bary_freq_window=a.bary_freq_window; + nonbary_freq_window=a.nonbary_freq_window; + spike_obs_duration=a.spike_obs_duration; + spike_obs_interval=a.spike_obs_interval; + gauss_obs_duration=a.gauss_obs_duration; + gauss_obs_interval=a.gauss_obs_interval; + pulse_obs_duration=a.pulse_obs_duration; + pulse_obs_interval=a.pulse_obs_interval; + triplet_obs_duration=a.triplet_obs_duration; + triplet_obs_interval=a.triplet_obs_interval; + min_spike_id=a.min_spike_id; + min_autocorr_id=a.min_autocorr_id; + min_gaussian_id=a.min_gaussian_id; + min_pulse_id=a.min_pulse_id; + min_triplet_id=a.min_triplet_id; + min_app_version=a.min_app_version; + strcpy(qpix_scheme,a.qpix_scheme); + strcpy(info_xml,a.info_xml); + } + return (*this); +} + + +std::string science_config::update_format() const { + std::ostringstream rv(""); + + for (int i=2; i<29; i++) { + rv << "?,"; + } + rv << "?"; + return rv.str(); +} + + +std::string science_config::insert_format() const { + return std::string("?,")+update_format(); +} + +std::string science_config::select_format() const { + std::string rv(""); + for (int i=0; i<28; i++) { + rv+="?,"; + } + rv+="?"; + return rv; +} + +std::string science_config::print(int full_subtables, int show_ids, int no_refs) const { + std::ostringstream rv(""); + + rv.precision(14); + if (show_ids) { + rv << id; + } + rv << ','; + rv << active; + rv << ','; + rv << "'" << qpix_scheme << "'"; + rv << ','; + rv << qpix_nside; + rv << ','; + rv << fpix_width; + rv << ','; + rv << total_bandwidth; + rv << ','; + rv << freq_uncertainty; + rv << ','; + rv << fwhm_beamwidth; + rv << ','; + rv << sky_disc_radius; + rv << ','; + rv << observable_sky; + rv << ','; + rv << epoch; + rv << ','; + rv << bary_chirp_window; + rv << ','; + rv << bary_freq_window; + rv << ','; + rv << nonbary_freq_window; + rv << ','; + rv << spike_obs_duration; + rv << ','; + rv << spike_obs_interval; + rv << ','; + rv << gauss_obs_duration; + rv << ','; + rv << gauss_obs_interval; + rv << ','; + rv << pulse_obs_duration; + rv << ','; + rv << pulse_obs_interval; + rv << ','; + rv << triplet_obs_duration; + rv << ','; + rv << triplet_obs_interval; + rv << ','; + rv << min_spike_id; + rv << ','; + rv << min_autocorr_id; + rv << ','; + rv << min_gaussian_id; + rv << ','; + rv << min_pulse_id; + rv << ','; + rv << min_triplet_id; + rv << ','; + rv << min_app_version; + rv << ','; + rv << "'" << info_xml << "'"; + return rv.str(); +} + + +std::string science_config::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { + std::ostringstream rv(""); + + rv.precision(14); + rv << xml_indent() << '<' << tag << ">\n"; + xml_indent(2); + if (show_ids) { + rv << xml_indent() << "" << id << "\n"; + } + rv << xml_indent() << "" << active << "\n"; + { + std::string enc_field=xml_encode_string(qpix_scheme,std::min(strlen(qpix_scheme),sizeof(qpix_scheme))); + rv << xml_indent() << ""; + rv << enc_field << "\n"; + } + rv << xml_indent() << "" << qpix_nside << "\n"; + rv << xml_indent() << "" << fpix_width << "\n"; + rv << xml_indent() << "" << total_bandwidth << "\n"; + rv << xml_indent() << "" << freq_uncertainty << "\n"; + rv << xml_indent() << "" << fwhm_beamwidth << "\n"; + rv << xml_indent() << "" << sky_disc_radius << "\n"; + rv << xml_indent() << "" << observable_sky << "\n"; + rv << xml_indent() << "" << epoch << "\n"; + rv << xml_indent() << "" << bary_chirp_window << "\n"; + rv << xml_indent() << "" << bary_freq_window << "\n"; + rv << xml_indent() << "" << nonbary_freq_window << "\n"; + rv << xml_indent() << "" << spike_obs_duration << "\n"; + rv << xml_indent() << "" << spike_obs_interval << "\n"; + rv << xml_indent() << "" << gauss_obs_duration << "\n"; + rv << xml_indent() << "" << gauss_obs_interval << "\n"; + rv << xml_indent() << "" << pulse_obs_duration << "\n"; + rv << xml_indent() << "" << pulse_obs_interval << "\n"; + rv << xml_indent() << "" << triplet_obs_duration << "\n"; + rv << xml_indent() << "" << triplet_obs_interval << "\n"; + rv << xml_indent() << "" << min_spike_id << "\n"; + rv << xml_indent() << "" << min_autocorr_id << "\n"; + rv << xml_indent() << "" << min_gaussian_id << "\n"; + rv << xml_indent() << "" << min_pulse_id << "\n"; + rv << xml_indent() << "" << min_triplet_id << "\n"; + rv << xml_indent() << "" << min_app_version << "\n"; + { + std::string enc_field=xml_encode_string(info_xml,std::min(strlen(info_xml),sizeof(info_xml))); + rv << xml_indent() << ""; + rv << enc_field << "\n"; + } + xml_indent(-2); + rv << xml_indent() << "\n"; + return rv.str(); +} + + +void science_config::parse_xml(const std::string &s,const char *tag) { + std::string field,sub; + if (extract_xml_record(s,tag,field)) { + std::string::size_type pos=0; + if (extract_xml_record(field,"id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> id; + } + if (extract_xml_record(field,"active",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> active; + } + if (extract_xml_record(field,"qpix_scheme",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::string::size_type epos=sub.find("<",pos); + if (epos==std::string::npos) { + epos=sub.find('\n',pos); + } + if (epos==std::string::npos) { + epos=pos+strlen(sub.c_str()+pos); + } + std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); + strncpy(qpix_scheme,(const char *)&(in.front()),std::min(in.size(),(size_t)16)); + qpix_scheme[std::min(in.size(),(size_t)15)]=0; + } + if (extract_xml_record(field,"qpix_nside",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> qpix_nside; + } + if (extract_xml_record(field,"fpix_width",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> fpix_width; + } + if (extract_xml_record(field,"total_bandwidth",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> total_bandwidth; + } + if (extract_xml_record(field,"freq_uncertainty",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> freq_uncertainty; + } + if (extract_xml_record(field,"fwhm_beamwidth",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> fwhm_beamwidth; + } + if (extract_xml_record(field,"sky_disc_radius",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> sky_disc_radius; + } + if (extract_xml_record(field,"observable_sky",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> observable_sky; + } + if (extract_xml_record(field,"epoch",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> epoch; + } + if (extract_xml_record(field,"bary_chirp_window",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> bary_chirp_window; + } + if (extract_xml_record(field,"bary_freq_window",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> bary_freq_window; + } + if (extract_xml_record(field,"nonbary_freq_window",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> nonbary_freq_window; + } + if (extract_xml_record(field,"spike_obs_duration",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> spike_obs_duration; + } + if (extract_xml_record(field,"spike_obs_interval",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> spike_obs_interval; + } + if (extract_xml_record(field,"gauss_obs_duration",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> gauss_obs_duration; + } + if (extract_xml_record(field,"gauss_obs_interval",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> gauss_obs_interval; + } + if (extract_xml_record(field,"pulse_obs_duration",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> pulse_obs_duration; + } + if (extract_xml_record(field,"pulse_obs_interval",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> pulse_obs_interval; + } + if (extract_xml_record(field,"triplet_obs_duration",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> triplet_obs_duration; + } + if (extract_xml_record(field,"triplet_obs_interval",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> triplet_obs_interval; + } + if (extract_xml_record(field,"min_spike_id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> min_spike_id; + } + if (extract_xml_record(field,"min_autocorr_id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> min_autocorr_id; + } + if (extract_xml_record(field,"min_gaussian_id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> min_gaussian_id; + } + if (extract_xml_record(field,"min_pulse_id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> min_pulse_id; + } + if (extract_xml_record(field,"min_triplet_id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> min_triplet_id; + } + if (extract_xml_record(field,"min_app_version",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> min_app_version; + } + if (extract_xml_record(field,"info_xml",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::string::size_type epos=sub.find("<",pos); + if (epos==std::string::npos) { + epos=sub.find('\n',pos); + } + if (epos==std::string::npos) { + epos=pos+strlen(sub.c_str()+pos); + } + std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); + strncpy(info_xml,(const char *)&(in.front()),std::min(in.size(),(size_t)255)); + info_xml[std::min(in.size(),(size_t)254)]=0; + } + } +} + +void science_config::parse(const SQL_ROW &s) { + { + std::istringstream row(*(s[0])); + row >> id; + } + { + std::istringstream row(*(s[1])); + row >> active; + } + { + strncpy(qpix_scheme,s[2]->c_str(),16); + qpix_scheme[15]=0; + } + { + std::istringstream row(*(s[3])); + row >> qpix_nside; + } + { + std::istringstream row(*(s[4])); + row >> fpix_width; + } + { + std::istringstream row(*(s[5])); + row >> total_bandwidth; + } + { + std::istringstream row(*(s[6])); + row >> freq_uncertainty; + } + { + std::istringstream row(*(s[7])); + row >> fwhm_beamwidth; + } + { + std::istringstream row(*(s[8])); + row >> sky_disc_radius; + } + { + std::istringstream row(*(s[9])); + row >> observable_sky; + } + { + std::istringstream row(*(s[10])); + row >> epoch; + } + { + std::istringstream row(*(s[11])); + row >> bary_chirp_window; + } + { + std::istringstream row(*(s[12])); + row >> bary_freq_window; + } + { + std::istringstream row(*(s[13])); + row >> nonbary_freq_window; + } + { + std::istringstream row(*(s[14])); + row >> spike_obs_duration; + } + { + std::istringstream row(*(s[15])); + row >> spike_obs_interval; + } + { + std::istringstream row(*(s[16])); + row >> gauss_obs_duration; + } + { + std::istringstream row(*(s[17])); + row >> gauss_obs_interval; + } + { + std::istringstream row(*(s[18])); + row >> pulse_obs_duration; + } + { + std::istringstream row(*(s[19])); + row >> pulse_obs_interval; + } + { + std::istringstream row(*(s[20])); + row >> triplet_obs_duration; + } + { + std::istringstream row(*(s[21])); + row >> triplet_obs_interval; + } + { + std::istringstream row(*(s[22])); + row >> min_spike_id; + } + { + std::istringstream row(*(s[23])); + row >> min_autocorr_id; + } + { + std::istringstream row(*(s[24])); + row >> min_gaussian_id; + } + { + std::istringstream row(*(s[25])); + row >> min_pulse_id; + } + { + std::istringstream row(*(s[26])); + row >> min_triplet_id; + } + { + std::istringstream row(*(s[27])); + row >> min_app_version; + } + { + strncpy(info_xml,s[28]->c_str(),255); + info_xml[254]=0; + } +} + +void science_config::parse(const std::string &s) { + SQL_ROW row(&s,29); + parse(row); +} + +template <> const char *const db_type::type_name="candidate_t"; +template <> const char *db_type::_search_tag=type_name; +template <> const int db_type::_nfields=5; +template <> const char *const db_type::column_names[5]= {"type","id","num_obs","score","is_rfi"}; + +candidate_t::candidate_t() : + db_type(*this), + type(0), + id(0), + num_obs(0), + score(0), + is_rfi(0) { + db_open(); +} + + +candidate_t::candidate_t(const candidate_t &a) : + db_type(*this), + type(a.type), + id(a.id), + num_obs(a.num_obs), + score(a.score), + is_rfi(a.is_rfi) { + db_open(); +} + + +candidate_t::candidate_t(const SQL_ROW &a) : + db_type(*this) { + db_open(); + parse(a); +} + + +candidate_t::candidate_t(const std::string &s,const char *tag) : + db_type(*this) { + db_open(); + if (xml_match_tag(s,tag)) { + parse_xml(s,tag); + } else { + parse(s); + } +} + + +candidate_t &candidate_t::operator =(const candidate_t &a) { + if (&a != this) { + type=a.type; + id=a.id; + num_obs=a.num_obs; + score=a.score; + is_rfi=a.is_rfi; + } + return (*this); +} + + +std::string candidate_t::update_format() const { + std::ostringstream rv(""); + + rv << "ROW("; + for (int i=1; i<5; i++) { + rv << "?,"; + } + rv << "?"; + rv << ")"; + + return rv.str(); +} + + +std::string candidate_t::insert_format() const { + return update_format(); +} + +std::string candidate_t::select_format() const { + std::string rv(""); + for (int i=0; i<4; i++) { + rv+="?,"; + } + rv+="?"; + return rv; +} + +std::string candidate_t::print(int full_subtables, int show_ids, int no_refs) const { + std::ostringstream rv(""); + + rv.precision(14); + rv << "ROW("; + rv << type; + rv << ','; + rv << id; + rv << ','; + rv << num_obs; + rv << ','; + rv << score; + rv << ','; + rv << is_rfi; + rv << ")"; + return rv.str(); +} + + +std::string candidate_t::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { + std::ostringstream rv(""); + + rv.precision(14); + rv << xml_indent() << '<' << tag << ">\n"; + xml_indent(2); + rv << xml_indent() << "" << type << "\n"; + rv << xml_indent() << "" << id << "\n"; + rv << xml_indent() << "" << num_obs << "\n"; + rv << xml_indent() << "" << score << "\n"; + rv << xml_indent() << "" << is_rfi << "\n"; + xml_indent(-2); + rv << xml_indent() << "\n"; + return rv.str(); +} + + +void candidate_t::parse_xml(const std::string &s,const char *tag) { + std::string field,sub; + if (extract_xml_record(s,tag,field)) { + std::string::size_type pos=0; + if (extract_xml_record(field,"type",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> type; + } + if (extract_xml_record(field,"id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> id; + } + if (extract_xml_record(field,"num_obs",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> num_obs; + } + if (extract_xml_record(field,"score",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> score; + } + if (extract_xml_record(field,"is_rfi",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> is_rfi; + } + } +} + +void candidate_t::parse(const SQL_ROW &s) { + { + std::istringstream row(*(s[0])); + row >> type; + } + { + std::istringstream row(*(s[1])); + row >> id; + } + { + std::istringstream row(*(s[2])); + row >> num_obs; + } + { + std::istringstream row(*(s[3])); + row >> score; + } + { + std::istringstream row(*(s[4])); + row >> is_rfi; + } +} + +void candidate_t::parse(const std::string &s) { + SQL_ROW row(&s,5); + parse(row); +} + +template <> const char *const db_table::table_name="meta_candidate"; +template <> const char *db_table::_search_tag=table_name; +template <> const int db_table::_nfields=32; +template <> const char *const db_table::column_names[32]= {"id","version","time_last_updated","num_spikes","num_spike_b_multiplets","best_spike_b_mp_score","num_spike_nb_multiplets","best_spike_nb_mp_score","spike_high_id","num_gaussians","num_gaussian_b_multiplets","best_gaussian_b_mp_score","num_gaussian_nb_multiplets","best_gaussian_nb_mp_score","gaussian_high_id","num_pulses","num_pulse_b_multiplets","best_pulse_b_mp_score","num_pulse_nb_multiplets","best_pulse_nb_mp_score","pulse_high_id","num_triplets","num_triplet_b_multiplets","best_triplet_b_mp_score","num_triplet_nb_multiplets","best_triplet_nb_mp_score","triplet_high_id","num_stars","best_star_score","meta_score","rfi_clean","state"}; + +meta_candidate::meta_candidate() : + db_table(*this,-1), + id(0), + version(0), + time_last_updated(0), + num_spikes(0), + num_spike_b_multiplets(0), + best_spike_b_mp_score(0), + num_spike_nb_multiplets(0), + best_spike_nb_mp_score(0), + spike_high_id(0), + num_gaussians(0), + num_gaussian_b_multiplets(0), + best_gaussian_b_mp_score(0), + num_gaussian_nb_multiplets(0), + best_gaussian_nb_mp_score(0), + gaussian_high_id(0), + num_pulses(0), + num_pulse_b_multiplets(0), + best_pulse_b_mp_score(0), + num_pulse_nb_multiplets(0), + best_pulse_nb_mp_score(0), + pulse_high_id(0), + num_triplets(0), + num_triplet_b_multiplets(0), + best_triplet_b_mp_score(0), + num_triplet_nb_multiplets(0), + best_triplet_nb_mp_score(0), + triplet_high_id(0), + num_stars(0), + best_star_score(0), + meta_score(0), + rfi_clean(0), + state(0) { + db_open(); +} + + +meta_candidate::meta_candidate(const meta_candidate &a) : + db_table(*this,-1), + id(a.id), + version(a.version), + time_last_updated(a.time_last_updated), + num_spikes(a.num_spikes), + num_spike_b_multiplets(a.num_spike_b_multiplets), + best_spike_b_mp_score(a.best_spike_b_mp_score), + num_spike_nb_multiplets(a.num_spike_nb_multiplets), + best_spike_nb_mp_score(a.best_spike_nb_mp_score), + spike_high_id(a.spike_high_id), + num_gaussians(a.num_gaussians), + num_gaussian_b_multiplets(a.num_gaussian_b_multiplets), + best_gaussian_b_mp_score(a.best_gaussian_b_mp_score), + num_gaussian_nb_multiplets(a.num_gaussian_nb_multiplets), + best_gaussian_nb_mp_score(a.best_gaussian_nb_mp_score), + gaussian_high_id(a.gaussian_high_id), + num_pulses(a.num_pulses), + num_pulse_b_multiplets(a.num_pulse_b_multiplets), + best_pulse_b_mp_score(a.best_pulse_b_mp_score), + num_pulse_nb_multiplets(a.num_pulse_nb_multiplets), + best_pulse_nb_mp_score(a.best_pulse_nb_mp_score), + pulse_high_id(a.pulse_high_id), + num_triplets(a.num_triplets), + num_triplet_b_multiplets(a.num_triplet_b_multiplets), + best_triplet_b_mp_score(a.best_triplet_b_mp_score), + num_triplet_nb_multiplets(a.num_triplet_nb_multiplets), + best_triplet_nb_mp_score(a.best_triplet_nb_mp_score), + triplet_high_id(a.triplet_high_id), + num_stars(a.num_stars), + best_star_score(a.best_star_score), + meta_score(a.meta_score), + rfi_clean(a.rfi_clean), + state(a.state) { + db_open(); +} + + +meta_candidate::meta_candidate(const SQL_ROW &a) : + db_table(*this,-1) { + db_open(); + parse(a); +} + + +meta_candidate::meta_candidate(const std::string &s,const char *tag) : + db_table(*this,-1) { + db_open(); + if (xml_match_tag(s,tag)) { + parse_xml(s,tag); + } else { + parse(s); + } +} + + +meta_candidate &meta_candidate::operator =(const meta_candidate &a) { + if (&a != this) { + id=a.id; + version=a.version; + time_last_updated=a.time_last_updated; + num_spikes=a.num_spikes; + num_spike_b_multiplets=a.num_spike_b_multiplets; + best_spike_b_mp_score=a.best_spike_b_mp_score; + num_spike_nb_multiplets=a.num_spike_nb_multiplets; + best_spike_nb_mp_score=a.best_spike_nb_mp_score; + spike_high_id=a.spike_high_id; + num_gaussians=a.num_gaussians; + num_gaussian_b_multiplets=a.num_gaussian_b_multiplets; + best_gaussian_b_mp_score=a.best_gaussian_b_mp_score; + num_gaussian_nb_multiplets=a.num_gaussian_nb_multiplets; + best_gaussian_nb_mp_score=a.best_gaussian_nb_mp_score; + gaussian_high_id=a.gaussian_high_id; + num_pulses=a.num_pulses; + num_pulse_b_multiplets=a.num_pulse_b_multiplets; + best_pulse_b_mp_score=a.best_pulse_b_mp_score; + num_pulse_nb_multiplets=a.num_pulse_nb_multiplets; + best_pulse_nb_mp_score=a.best_pulse_nb_mp_score; + pulse_high_id=a.pulse_high_id; + num_triplets=a.num_triplets; + num_triplet_b_multiplets=a.num_triplet_b_multiplets; + best_triplet_b_mp_score=a.best_triplet_b_mp_score; + num_triplet_nb_multiplets=a.num_triplet_nb_multiplets; + best_triplet_nb_mp_score=a.best_triplet_nb_mp_score; + triplet_high_id=a.triplet_high_id; + num_stars=a.num_stars; + best_star_score=a.best_star_score; + meta_score=a.meta_score; + rfi_clean=a.rfi_clean; + state=a.state; + } + return (*this); +} + + +std::string meta_candidate::update_format() const { + std::ostringstream rv(""); + + for (int i=2; i<32; i++) { + rv << "?,"; + } + rv << "?"; + return rv.str(); +} + + +std::string meta_candidate::insert_format() const { + return std::string("?,")+update_format(); +} + +std::string meta_candidate::select_format() const { + std::string rv(""); + for (int i=0; i<31; i++) { + rv+="?,"; + } + rv+="?"; + return rv; +} + +std::string meta_candidate::print(int full_subtables, int show_ids, int no_refs) const { + std::ostringstream rv(""); + + rv.precision(14); + if (show_ids) { + rv << id; + } + rv << ','; + rv << version; + rv << ','; + rv << time_last_updated; + rv << ','; + rv << num_spikes; + rv << ','; + rv << num_spike_b_multiplets; + rv << ','; + rv << best_spike_b_mp_score; + rv << ','; + rv << num_spike_nb_multiplets; + rv << ','; + rv << best_spike_nb_mp_score; + rv << ','; + rv << spike_high_id; + rv << ','; + rv << num_gaussians; + rv << ','; + rv << num_gaussian_b_multiplets; + rv << ','; + rv << best_gaussian_b_mp_score; + rv << ','; + rv << num_gaussian_nb_multiplets; + rv << ','; + rv << best_gaussian_nb_mp_score; + rv << ','; + rv << gaussian_high_id; + rv << ','; + rv << num_pulses; + rv << ','; + rv << num_pulse_b_multiplets; + rv << ','; + rv << best_pulse_b_mp_score; + rv << ','; + rv << num_pulse_nb_multiplets; + rv << ','; + rv << best_pulse_nb_mp_score; + rv << ','; + rv << pulse_high_id; + rv << ','; + rv << num_triplets; + rv << ','; + rv << num_triplet_b_multiplets; + rv << ','; + rv << best_triplet_b_mp_score; + rv << ','; + rv << num_triplet_nb_multiplets; + rv << ','; + rv << best_triplet_nb_mp_score; + rv << ','; + rv << triplet_high_id; + rv << ','; + rv << num_stars; + rv << ','; + rv << best_star_score; + rv << ','; + rv << meta_score; + rv << ','; + rv << rfi_clean; + rv << ','; + rv << state; + return rv.str(); +} + + +std::string meta_candidate::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { + std::ostringstream rv(""); + + rv.precision(14); + rv << xml_indent() << '<' << tag << ">\n"; + xml_indent(2); + if (show_ids) { + rv << xml_indent() << "" << id << "\n"; + } + rv << xml_indent() << "" << version << "\n"; + rv << xml_indent() << "" << time_last_updated << "\n"; + rv << xml_indent() << "" << num_spikes << "\n"; + rv << xml_indent() << "" << num_spike_b_multiplets << "\n"; + rv << xml_indent() << "" << best_spike_b_mp_score << "\n"; + rv << xml_indent() << "" << num_spike_nb_multiplets << "\n"; + rv << xml_indent() << "" << best_spike_nb_mp_score << "\n"; + rv << xml_indent() << "" << spike_high_id << "\n"; + rv << xml_indent() << "" << num_gaussians << "\n"; + rv << xml_indent() << "" << num_gaussian_b_multiplets << "\n"; + rv << xml_indent() << "" << best_gaussian_b_mp_score << "\n"; + rv << xml_indent() << "" << num_gaussian_nb_multiplets << "\n"; + rv << xml_indent() << "" << best_gaussian_nb_mp_score << "\n"; + rv << xml_indent() << "" << gaussian_high_id << "\n"; + rv << xml_indent() << "" << num_pulses << "\n"; + rv << xml_indent() << "" << num_pulse_b_multiplets << "\n"; + rv << xml_indent() << "" << best_pulse_b_mp_score << "\n"; + rv << xml_indent() << "" << num_pulse_nb_multiplets << "\n"; + rv << xml_indent() << "" << best_pulse_nb_mp_score << "\n"; + rv << xml_indent() << "" << pulse_high_id << "\n"; + rv << xml_indent() << "" << num_triplets << "\n"; + rv << xml_indent() << "" << num_triplet_b_multiplets << "\n"; + rv << xml_indent() << "" << best_triplet_b_mp_score << "\n"; + rv << xml_indent() << "" << num_triplet_nb_multiplets << "\n"; + rv << xml_indent() << "" << best_triplet_nb_mp_score << "\n"; + rv << xml_indent() << "" << triplet_high_id << "\n"; + rv << xml_indent() << "" << num_stars << "\n"; + rv << xml_indent() << "" << best_star_score << "\n"; + rv << xml_indent() << "" << meta_score << "\n"; + rv << xml_indent() << "" << rfi_clean << "\n"; + rv << xml_indent() << "" << state << "\n"; + xml_indent(-2); + rv << xml_indent() << "\n"; + return rv.str(); +} + + +void meta_candidate::parse_xml(const std::string &s,const char *tag) { + std::string field,sub; + if (extract_xml_record(s,tag,field)) { + std::string::size_type pos=0; + if (extract_xml_record(field,"id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> id; + } + if (extract_xml_record(field,"version",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> version; + } + if (extract_xml_record(field,"time_last_updated",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> time_last_updated; + } + if (extract_xml_record(field,"num_spikes",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> num_spikes; + } + if (extract_xml_record(field,"num_spike_b_multiplets",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> num_spike_b_multiplets; + } + if (extract_xml_record(field,"best_spike_b_mp_score",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> best_spike_b_mp_score; + } + if (extract_xml_record(field,"num_spike_nb_multiplets",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> num_spike_nb_multiplets; + } + if (extract_xml_record(field,"best_spike_nb_mp_score",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> best_spike_nb_mp_score; + } + if (extract_xml_record(field,"spike_high_id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> spike_high_id; + } + if (extract_xml_record(field,"num_gaussians",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> num_gaussians; + } + if (extract_xml_record(field,"num_gaussian_b_multiplets",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> num_gaussian_b_multiplets; + } + if (extract_xml_record(field,"best_gaussian_b_mp_score",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> best_gaussian_b_mp_score; + } + if (extract_xml_record(field,"num_gaussian_nb_multiplets",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> num_gaussian_nb_multiplets; + } + if (extract_xml_record(field,"best_gaussian_nb_mp_score",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> best_gaussian_nb_mp_score; + } + if (extract_xml_record(field,"gaussian_high_id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> gaussian_high_id; + } + if (extract_xml_record(field,"num_pulses",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> num_pulses; + } + if (extract_xml_record(field,"num_pulse_b_multiplets",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> num_pulse_b_multiplets; + } + if (extract_xml_record(field,"best_pulse_b_mp_score",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> best_pulse_b_mp_score; + } + if (extract_xml_record(field,"num_pulse_nb_multiplets",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> num_pulse_nb_multiplets; + } + if (extract_xml_record(field,"best_pulse_nb_mp_score",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> best_pulse_nb_mp_score; + } + if (extract_xml_record(field,"pulse_high_id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> pulse_high_id; + } + if (extract_xml_record(field,"num_triplets",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> num_triplets; + } + if (extract_xml_record(field,"num_triplet_b_multiplets",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> num_triplet_b_multiplets; + } + if (extract_xml_record(field,"best_triplet_b_mp_score",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> best_triplet_b_mp_score; + } + if (extract_xml_record(field,"num_triplet_nb_multiplets",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> num_triplet_nb_multiplets; + } + if (extract_xml_record(field,"best_triplet_nb_mp_score",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> best_triplet_nb_mp_score; + } + if (extract_xml_record(field,"triplet_high_id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> triplet_high_id; + } + if (extract_xml_record(field,"num_stars",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> num_stars; + } + if (extract_xml_record(field,"best_star_score",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> best_star_score; + } + if (extract_xml_record(field,"meta_score",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> meta_score; + } + if (extract_xml_record(field,"rfi_clean",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> rfi_clean; + } + if (extract_xml_record(field,"state",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> state; + } + } +} + +void meta_candidate::parse(const SQL_ROW &s) { + { + std::istringstream row(*(s[0])); + row >> id; + } + { + std::istringstream row(*(s[1])); + row >> version; + } + { + std::istringstream row(*(s[2])); + row >> time_last_updated; + } + { + std::istringstream row(*(s[3])); + row >> num_spikes; + } + { + std::istringstream row(*(s[4])); + row >> num_spike_b_multiplets; + } + { + std::istringstream row(*(s[5])); + row >> best_spike_b_mp_score; + } + { + std::istringstream row(*(s[6])); + row >> num_spike_nb_multiplets; + } + { + std::istringstream row(*(s[7])); + row >> best_spike_nb_mp_score; + } + { + std::istringstream row(*(s[8])); + row >> spike_high_id; + } + { + std::istringstream row(*(s[9])); + row >> num_gaussians; + } + { + std::istringstream row(*(s[10])); + row >> num_gaussian_b_multiplets; + } + { + std::istringstream row(*(s[11])); + row >> best_gaussian_b_mp_score; + } + { + std::istringstream row(*(s[12])); + row >> num_gaussian_nb_multiplets; + } + { + std::istringstream row(*(s[13])); + row >> best_gaussian_nb_mp_score; + } + { + std::istringstream row(*(s[14])); + row >> gaussian_high_id; + } + { + std::istringstream row(*(s[15])); + row >> num_pulses; + } + { + std::istringstream row(*(s[16])); + row >> num_pulse_b_multiplets; + } + { + std::istringstream row(*(s[17])); + row >> best_pulse_b_mp_score; + } + { + std::istringstream row(*(s[18])); + row >> num_pulse_nb_multiplets; + } + { + std::istringstream row(*(s[19])); + row >> best_pulse_nb_mp_score; + } + { + std::istringstream row(*(s[20])); + row >> pulse_high_id; + } + { + std::istringstream row(*(s[21])); + row >> num_triplets; + } + { + std::istringstream row(*(s[22])); + row >> num_triplet_b_multiplets; + } + { + std::istringstream row(*(s[23])); + row >> best_triplet_b_mp_score; + } + { + std::istringstream row(*(s[24])); + row >> num_triplet_nb_multiplets; + } + { + std::istringstream row(*(s[25])); + row >> best_triplet_nb_mp_score; + } + { + std::istringstream row(*(s[26])); + row >> triplet_high_id; + } + { + std::istringstream row(*(s[27])); + row >> num_stars; + } + { + std::istringstream row(*(s[28])); + row >> best_star_score; + } + { + std::istringstream row(*(s[29])); + row >> meta_score; + } + { + std::istringstream row(*(s[30])); + row >> rfi_clean; + } + { + std::istringstream row(*(s[31])); + row >> state; + } +} + +void meta_candidate::parse(const std::string &s) { + SQL_ROW row(&s,32); + parse(row); +} + +template <> const char *const db_table::table_name="multiplet"; +template <> const char *db_table::_search_tag=table_name; +template <> const int db_table::_nfields=25; +template <> const char *const db_table::column_names[25]= {"id","version","signal_type","mp_type","qpix","freq_win","mean_ra","mean_decl","ra_stddev","decl_stddev","mean_angular_distance","angular_distance_stddev","mean_frequency","frequency_stddev","mean_chirp","chirp_stddev","mean_period","period_stddev","mean_snr","snr_stddev","mean_threshold","threshold_stddev","score","num_detections","signal_ids"}; + +multiplet::multiplet() : + db_table(*this,-1), + id(0), + version(0), + signal_type(0), + mp_type(0), + qpix(0), + freq_win(0), + mean_ra(0), + mean_decl(0), + ra_stddev(0), + decl_stddev(0), + mean_angular_distance(0), + angular_distance_stddev(0), + mean_frequency(0), + frequency_stddev(0), + mean_chirp(0), + chirp_stddev(0), + mean_period(0), + period_stddev(0), + mean_snr(0), + snr_stddev(0), + mean_threshold(0), + threshold_stddev(0), + score(0), + num_detections(0), + signal_ids((sqlint8_t *)0,0,_x_csv) { + db_open(); +} + + +multiplet::multiplet(const multiplet &a) : + db_table(*this,-1), + id(a.id), + version(a.version), + signal_type(a.signal_type), + mp_type(a.mp_type), + qpix(a.qpix), + freq_win(a.freq_win), + mean_ra(a.mean_ra), + mean_decl(a.mean_decl), + ra_stddev(a.ra_stddev), + decl_stddev(a.decl_stddev), + mean_angular_distance(a.mean_angular_distance), + angular_distance_stddev(a.angular_distance_stddev), + mean_frequency(a.mean_frequency), + frequency_stddev(a.frequency_stddev), + mean_chirp(a.mean_chirp), + chirp_stddev(a.chirp_stddev), + mean_period(a.mean_period), + period_stddev(a.period_stddev), + mean_snr(a.mean_snr), + snr_stddev(a.snr_stddev), + mean_threshold(a.mean_threshold), + threshold_stddev(a.threshold_stddev), + score(a.score), + num_detections(a.num_detections), + signal_ids(a.signal_ids) { + db_open(); +} + + +multiplet::multiplet(const SQL_ROW &a) : + db_table(*this,-1) { + db_open(); + parse(a); +} + + +multiplet::multiplet(const std::string &s,const char *tag) : + db_table(*this,-1) { + db_open(); + if (xml_match_tag(s,tag)) { + parse_xml(s,tag); + } else { + parse(s); + } +} + + +multiplet &multiplet::operator =(const multiplet &a) { + if (&a != this) { + id=a.id; + version=a.version; + signal_type=a.signal_type; + mp_type=a.mp_type; + qpix=a.qpix; + freq_win=a.freq_win; + mean_ra=a.mean_ra; + mean_decl=a.mean_decl; + ra_stddev=a.ra_stddev; + decl_stddev=a.decl_stddev; + mean_angular_distance=a.mean_angular_distance; + angular_distance_stddev=a.angular_distance_stddev; + mean_frequency=a.mean_frequency; + frequency_stddev=a.frequency_stddev; + mean_chirp=a.mean_chirp; + chirp_stddev=a.chirp_stddev; + mean_period=a.mean_period; + period_stddev=a.period_stddev; + mean_snr=a.mean_snr; + snr_stddev=a.snr_stddev; + mean_threshold=a.mean_threshold; + threshold_stddev=a.threshold_stddev; + score=a.score; + num_detections=a.num_detections; + { + signal_ids.clear(); + std::vector::const_iterator i(a.signal_ids.begin()); + for (; i!=a.signal_ids.end(); i++) { + signal_ids.push_back(*i); + } + } + } + return (*this); +} + + +std::string multiplet::update_format() const { + std::ostringstream rv(""); + + for (int i=2; i<25; i++) { + rv << "?,"; + } + rv << "?"; + return rv.str(); +} + + +std::string multiplet::insert_format() const { + return std::string("?,")+update_format(); +} + +std::string multiplet::select_format() const { + std::string rv(""); + for (int i=0; i<24; i++) { + rv+="?,"; + } + rv+="?"; + return rv; +} + +std::string multiplet::print(int full_subtables, int show_ids, int no_refs) const { + std::ostringstream rv(""); + + rv.precision(14); + if (show_ids) { + rv << id; + } + rv << ','; + rv << version; + rv << ','; + rv << signal_type; + rv << ','; + rv << mp_type; + rv << ','; + rv << qpix; + rv << ','; + rv << freq_win; + rv << ','; + rv << mean_ra; + rv << ','; + rv << mean_decl; + rv << ','; + rv << ra_stddev; + rv << ','; + rv << decl_stddev; + rv << ','; + rv << mean_angular_distance; + rv << ','; + rv << angular_distance_stddev; + rv << ','; + rv << mean_frequency; + rv << ','; + rv << frequency_stddev; + rv << ','; + rv << mean_chirp; + rv << ','; + rv << chirp_stddev; + rv << ','; + rv << mean_period; + rv << ','; + rv << period_stddev; + rv << ','; + rv << mean_snr; + rv << ','; + rv << snr_stddev; + rv << ','; + rv << mean_threshold; + rv << ','; + rv << threshold_stddev; + rv << ','; + rv << score; + rv << ','; + rv << num_detections; + rv << ','; + rv << "LIST {"; + { + std::vector::const_iterator p=signal_ids.begin(); + for (; p\n"; + xml_indent(2); + if (show_ids) { + rv << xml_indent() << "" << id << "\n"; + } + rv << xml_indent() << "" << version << "\n"; + rv << xml_indent() << "" << signal_type << "\n"; + rv << xml_indent() << "" << mp_type << "\n"; + rv << xml_indent() << "" << qpix << "\n"; + rv << xml_indent() << "" << freq_win << "\n"; + rv << xml_indent() << "" << mean_ra << "\n"; + rv << xml_indent() << "" << mean_decl << "\n"; + rv << xml_indent() << "" << ra_stddev << "\n"; + rv << xml_indent() << "" << decl_stddev << "\n"; + rv << xml_indent() << "" << mean_angular_distance << "\n"; + rv << xml_indent() << "" << angular_distance_stddev << "\n"; + rv << xml_indent() << "" << mean_frequency << "\n"; + rv << xml_indent() << "" << frequency_stddev << "\n"; + rv << xml_indent() << "" << mean_chirp << "\n"; + rv << xml_indent() << "" << chirp_stddev << "\n"; + rv << xml_indent() << "" << mean_period << "\n"; + rv << xml_indent() << "" << period_stddev << "\n"; + rv << xml_indent() << "" << mean_snr << "\n"; + rv << xml_indent() << "" << snr_stddev << "\n"; + rv << xml_indent() << "" << mean_threshold << "\n"; + rv << xml_indent() << "" << threshold_stddev << "\n"; + rv << xml_indent() << "" << score << "\n"; + rv << xml_indent() << "" << num_detections << "\n"; + if (signal_ids.size()) { + rv << xml_indent() << "" ; + rv << enc_string; + } + } + rv << "\n"; + xml_indent(-2); + rv << xml_indent() << "\n"; + return rv.str(); +} + + +void multiplet::parse_xml(const std::string &s,const char *tag) { + std::string field,sub; + if (extract_xml_record(s,tag,field)) { + std::string::size_type pos=0; + if (extract_xml_record(field,"id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> id; + } + if (extract_xml_record(field,"version",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> version; + } + if (extract_xml_record(field,"signal_type",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> signal_type; + } + if (extract_xml_record(field,"mp_type",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> mp_type; + } + if (extract_xml_record(field,"qpix",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> qpix; + } + if (extract_xml_record(field,"freq_win",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> freq_win; + } + if (extract_xml_record(field,"mean_ra",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> mean_ra; + } + if (extract_xml_record(field,"mean_decl",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> mean_decl; + } + if (extract_xml_record(field,"ra_stddev",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> ra_stddev; + } + if (extract_xml_record(field,"decl_stddev",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> decl_stddev; + } + if (extract_xml_record(field,"mean_angular_distance",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> mean_angular_distance; + } + if (extract_xml_record(field,"angular_distance_stddev",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> angular_distance_stddev; + } + if (extract_xml_record(field,"mean_frequency",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> mean_frequency; + } + if (extract_xml_record(field,"frequency_stddev",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> frequency_stddev; + } + if (extract_xml_record(field,"mean_chirp",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> mean_chirp; + } + if (extract_xml_record(field,"chirp_stddev",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> chirp_stddev; + } + if (extract_xml_record(field,"mean_period",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> mean_period; + } + if (extract_xml_record(field,"period_stddev",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> period_stddev; + } + if (extract_xml_record(field,"mean_snr",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> mean_snr; + } + if (extract_xml_record(field,"snr_stddev",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> snr_stddev; + } + if (extract_xml_record(field,"mean_threshold",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> mean_threshold; + } + if (extract_xml_record(field,"threshold_stddev",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> threshold_stddev; + } + if (extract_xml_record(field,"score",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> score; + } + if (extract_xml_record(field,"num_detections",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> num_detections; + } + signal_ids.clear(); + if (extract_xml_record(field,"signal_ids",sub)) { + pos=sub.find(">"); + do { + if (pos!=std::string::npos) { + do { + pos++; + } while ((sub[pos]=='\n') || (sub[pos]==',')); + std::istringstream in(std::string(sub.c_str()+pos)); + sqlint8_t tmp; + in >> tmp; + signal_ids.push_back(tmp); + } + } while ((pos=sub.find(",",pos)) != std::string::npos); + } + } +} + +void multiplet::parse(const SQL_ROW &s) { + { + std::istringstream row(*(s[0])); + row >> id; + } + { + std::istringstream row(*(s[1])); + row >> version; + } + { + std::istringstream row(*(s[2])); + row >> signal_type; + } + { + std::istringstream row(*(s[3])); + row >> mp_type; + } + { + std::istringstream row(*(s[4])); + row >> qpix; + } + { + std::istringstream row(*(s[5])); + row >> freq_win; + } + { + std::istringstream row(*(s[6])); + row >> mean_ra; + } + { + std::istringstream row(*(s[7])); + row >> mean_decl; + } + { + std::istringstream row(*(s[8])); + row >> ra_stddev; + } + { + std::istringstream row(*(s[9])); + row >> decl_stddev; + } + { + std::istringstream row(*(s[10])); + row >> mean_angular_distance; + } + { + std::istringstream row(*(s[11])); + row >> angular_distance_stddev; + } + { + std::istringstream row(*(s[12])); + row >> mean_frequency; + } + { + std::istringstream row(*(s[13])); + row >> frequency_stddev; + } + { + std::istringstream row(*(s[14])); + row >> mean_chirp; + } + { + std::istringstream row(*(s[15])); + row >> chirp_stddev; + } + { + std::istringstream row(*(s[16])); + row >> mean_period; + } + { + std::istringstream row(*(s[17])); + row >> period_stddev; + } + { + std::istringstream row(*(s[18])); + row >> mean_snr; + } + { + std::istringstream row(*(s[19])); + row >> snr_stddev; + } + { + std::istringstream row(*(s[20])); + row >> mean_threshold; + } + { + std::istringstream row(*(s[21])); + row >> threshold_stddev; + } + { + std::istringstream row(*(s[22])); + row >> score; + } + { + std::istringstream row(*(s[23])); + row >> num_detections; + } + { + std::string::size_type p,q; + int i; + signal_ids.clear(); + SQL_ROW tmp(s[24]); + for (i=0; i> tmp0; + signal_ids.push_back(tmp0); + } + } +} + +void multiplet::parse(const std::string &s) { + SQL_ROW row(&s,25); + parse(row); +} + +template <> const char *const db_table::table_name="star"; +template <> const char *db_table::_search_tag=table_name; +template <> const int db_table::_nfields=14; +template <> const char *const db_table::column_names[14]= {"id","object_type","catalog_name","catalog_number","object_name","ra","decl","qpix","v_mag","b_minus_v","parallax","stellar_type","planets","score"}; + +star::star() : + db_table(*this,-1), + id(0), + catalog_number(0), + ra(0), + decl(0), + qpix(0), + v_mag(0), + b_minus_v(0), + parallax(0), + planets(0), + score(0) { + db_open(); + object_type[0]=0; + catalog_name[0]=0; + object_name[0]=0; + stellar_type[0]=0; +} + + +star::star(const star &a) : + db_table(*this,-1), + id(a.id), + catalog_number(a.catalog_number), + ra(a.ra), + decl(a.decl), + qpix(a.qpix), + v_mag(a.v_mag), + b_minus_v(a.b_minus_v), + parallax(a.parallax), + planets(a.planets), + score(a.score) { + db_open(); + strcpy(object_type,a.object_type); + strcpy(catalog_name,a.catalog_name); + strcpy(object_name,a.object_name); + strcpy(stellar_type,a.stellar_type); +} + + +star::star(const SQL_ROW &a) : + db_table(*this,-1) { + db_open(); + parse(a); +} + + +star::star(const std::string &s,const char *tag) : + db_table(*this,-1) { + db_open(); + if (xml_match_tag(s,tag)) { + parse_xml(s,tag); + } else { + parse(s); + } +} + + +star &star::operator =(const star &a) { + if (&a != this) { + id=a.id; + catalog_number=a.catalog_number; + ra=a.ra; + decl=a.decl; + qpix=a.qpix; + v_mag=a.v_mag; + b_minus_v=a.b_minus_v; + parallax=a.parallax; + planets=a.planets; + score=a.score; + strcpy(object_type,a.object_type); + strcpy(catalog_name,a.catalog_name); + strcpy(object_name,a.object_name); + strcpy(stellar_type,a.stellar_type); + } + return (*this); +} + + +std::string star::update_format() const { + std::ostringstream rv(""); + + for (int i=2; i<14; i++) { + rv << "?,"; + } + rv << "?"; + return rv.str(); +} + + +std::string star::insert_format() const { + return std::string("?,")+update_format(); +} + +std::string star::select_format() const { + std::string rv(""); + for (int i=0; i<13; i++) { + rv+="?,"; + } + rv+="?"; + return rv; +} + +std::string star::print(int full_subtables, int show_ids, int no_refs) const { + std::ostringstream rv(""); + + rv.precision(14); + if (show_ids) { + rv << id; + } + rv << ','; + rv << "'" << object_type << "'"; + rv << ','; + rv << "'" << catalog_name << "'"; + rv << ','; + rv << catalog_number; + rv << ','; + rv << "'" << object_name << "'"; + rv << ','; + rv << ra; + rv << ','; + rv << decl; + rv << ','; + rv << qpix; + rv << ','; + rv << v_mag; + rv << ','; + rv << b_minus_v; + rv << ','; + rv << parallax; + rv << ','; + rv << "'" << stellar_type << "'"; + rv << ','; + rv << planets; + rv << ','; + rv << score; + return rv.str(); +} + + +std::string star::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { + std::ostringstream rv(""); + + rv.precision(14); + rv << xml_indent() << '<' << tag << ">\n"; + xml_indent(2); + if (show_ids) { + rv << xml_indent() << "" << id << "\n"; + } + { + std::string enc_field=xml_encode_string(object_type,std::min(strlen(object_type),sizeof(object_type))); + rv << xml_indent() << ""; + rv << enc_field << "\n"; + } + { + std::string enc_field=xml_encode_string(catalog_name,std::min(strlen(catalog_name),sizeof(catalog_name))); + rv << xml_indent() << ""; + rv << enc_field << "\n"; + } + rv << xml_indent() << "" << catalog_number << "\n"; + { + std::string enc_field=xml_encode_string(object_name,std::min(strlen(object_name),sizeof(object_name))); + rv << xml_indent() << ""; + rv << enc_field << "\n"; + } + rv << xml_indent() << "" << ra << "\n"; + rv << xml_indent() << "" << decl << "\n"; + rv << xml_indent() << "" << qpix << "\n"; + rv << xml_indent() << "" << v_mag << "\n"; + rv << xml_indent() << "" << b_minus_v << "\n"; + rv << xml_indent() << "" << parallax << "\n"; + { + std::string enc_field=xml_encode_string(stellar_type,std::min(strlen(stellar_type),sizeof(stellar_type))); + rv << xml_indent() << ""; + rv << enc_field << "\n"; + } + rv << xml_indent() << "" << planets << "\n"; + rv << xml_indent() << "" << score << "\n"; + xml_indent(-2); + rv << xml_indent() << "\n"; + return rv.str(); +} + + +void star::parse_xml(const std::string &s,const char *tag) { + std::string field,sub; + if (extract_xml_record(s,tag,field)) { + std::string::size_type pos=0; + if (extract_xml_record(field,"id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> id; + } + if (extract_xml_record(field,"object_type",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::string::size_type epos=sub.find("<",pos); + if (epos==std::string::npos) { + epos=sub.find('\n',pos); + } + if (epos==std::string::npos) { + epos=pos+strlen(sub.c_str()+pos); + } + std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); + strncpy(object_type,(const char *)&(in.front()),std::min(in.size(),(size_t)16)); + object_type[std::min(in.size(),(size_t)15)]=0; + } + if (extract_xml_record(field,"catalog_name",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::string::size_type epos=sub.find("<",pos); + if (epos==std::string::npos) { + epos=sub.find('\n',pos); + } + if (epos==std::string::npos) { + epos=pos+strlen(sub.c_str()+pos); + } + std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); + strncpy(catalog_name,(const char *)&(in.front()),std::min(in.size(),(size_t)64)); + catalog_name[std::min(in.size(),(size_t)63)]=0; + } + if (extract_xml_record(field,"catalog_number",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> catalog_number; + } + if (extract_xml_record(field,"object_name",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::string::size_type epos=sub.find("<",pos); + if (epos==std::string::npos) { + epos=sub.find('\n',pos); + } + if (epos==std::string::npos) { + epos=pos+strlen(sub.c_str()+pos); + } + std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); + strncpy(object_name,(const char *)&(in.front()),std::min(in.size(),(size_t)64)); + object_name[std::min(in.size(),(size_t)63)]=0; + } + if (extract_xml_record(field,"ra",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> ra; + } + if (extract_xml_record(field,"decl",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> decl; + } + if (extract_xml_record(field,"qpix",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> qpix; + } + if (extract_xml_record(field,"v_mag",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> v_mag; + } + if (extract_xml_record(field,"b_minus_v",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> b_minus_v; + } + if (extract_xml_record(field,"parallax",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> parallax; + } + if (extract_xml_record(field,"stellar_type",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::string::size_type epos=sub.find("<",pos); + if (epos==std::string::npos) { + epos=sub.find('\n',pos); + } + if (epos==std::string::npos) { + epos=pos+strlen(sub.c_str()+pos); + } + std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); + strncpy(stellar_type,(const char *)&(in.front()),std::min(in.size(),(size_t)32)); + stellar_type[std::min(in.size(),(size_t)31)]=0; + } + if (extract_xml_record(field,"planets",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> planets; + } + if (extract_xml_record(field,"score",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> score; + } + } +} + +void star::parse(const SQL_ROW &s) { + { + std::istringstream row(*(s[0])); + row >> id; + } + { + strncpy(object_type,s[1]->c_str(),16); + object_type[15]=0; + } + { + strncpy(catalog_name,s[2]->c_str(),64); + catalog_name[63]=0; + } + { + std::istringstream row(*(s[3])); + row >> catalog_number; + } + { + strncpy(object_name,s[4]->c_str(),64); + object_name[63]=0; + } + { + std::istringstream row(*(s[5])); + row >> ra; + } + { + std::istringstream row(*(s[6])); + row >> decl; + } + { + std::istringstream row(*(s[7])); + row >> qpix; + } + { + std::istringstream row(*(s[8])); + row >> v_mag; + } + { + std::istringstream row(*(s[9])); + row >> b_minus_v; + } + { + std::istringstream row(*(s[10])); + row >> parallax; + } + { + strncpy(stellar_type,s[11]->c_str(),32); + stellar_type[31]=0; + } + { + std::istringstream row(*(s[12])); + row >> planets; + } + { + std::istringstream row(*(s[13])); + row >> score; + } +} + +void star::parse(const std::string &s) { + SQL_ROW row(&s,14); + parse(row); +} + +template <> const char *const db_table::table_name="candidate_count"; +template <> const char *db_table::_search_tag=table_name; +template <> const int db_table::_nfields=15; +template <> const char *const db_table::column_names[15]= {"id","spikes","gaussians","pulses","triplets","spike_barycentric_multiplets","gaussian_barycentric_multiplets","pulse_barycentric_multiplets","triplet_barycentric_multiplets","spike_nonbarycentric_multiplets","gaussian_nonbarycentric_multiplets","pulse_nonbarycentric_multiplets","triplet_nonbarycentric_multiplets","stars","time_last_updated"}; + +candidate_count::candidate_count() : + db_table(*this,-1), + id(0), + spikes(0), + gaussians(0), + pulses(0), + triplets(0), + spike_barycentric_multiplets(0), + gaussian_barycentric_multiplets(0), + pulse_barycentric_multiplets(0), + triplet_barycentric_multiplets(0), + spike_nonbarycentric_multiplets(0), + gaussian_nonbarycentric_multiplets(0), + pulse_nonbarycentric_multiplets(0), + triplet_nonbarycentric_multiplets(0), + stars(0), + time_last_updated(0) { + db_open(); +} + + +candidate_count::candidate_count(const candidate_count &a) : + db_table(*this,-1), + id(a.id), + spikes(a.spikes), + gaussians(a.gaussians), + pulses(a.pulses), + triplets(a.triplets), + spike_barycentric_multiplets(a.spike_barycentric_multiplets), + gaussian_barycentric_multiplets(a.gaussian_barycentric_multiplets), + pulse_barycentric_multiplets(a.pulse_barycentric_multiplets), + triplet_barycentric_multiplets(a.triplet_barycentric_multiplets), + spike_nonbarycentric_multiplets(a.spike_nonbarycentric_multiplets), + gaussian_nonbarycentric_multiplets(a.gaussian_nonbarycentric_multiplets), + pulse_nonbarycentric_multiplets(a.pulse_nonbarycentric_multiplets), + triplet_nonbarycentric_multiplets(a.triplet_nonbarycentric_multiplets), + stars(a.stars), + time_last_updated(a.time_last_updated) { + db_open(); +} + + +candidate_count::candidate_count(const SQL_ROW &a) : + db_table(*this,-1) { + db_open(); + parse(a); +} + + +candidate_count::candidate_count(const std::string &s,const char *tag) : + db_table(*this,-1) { + db_open(); + if (xml_match_tag(s,tag)) { + parse_xml(s,tag); + } else { + parse(s); + } +} + + +candidate_count &candidate_count::operator =(const candidate_count &a) { + if (&a != this) { + id=a.id; + spikes=a.spikes; + gaussians=a.gaussians; + pulses=a.pulses; + triplets=a.triplets; + spike_barycentric_multiplets=a.spike_barycentric_multiplets; + gaussian_barycentric_multiplets=a.gaussian_barycentric_multiplets; + pulse_barycentric_multiplets=a.pulse_barycentric_multiplets; + triplet_barycentric_multiplets=a.triplet_barycentric_multiplets; + spike_nonbarycentric_multiplets=a.spike_nonbarycentric_multiplets; + gaussian_nonbarycentric_multiplets=a.gaussian_nonbarycentric_multiplets; + pulse_nonbarycentric_multiplets=a.pulse_nonbarycentric_multiplets; + triplet_nonbarycentric_multiplets=a.triplet_nonbarycentric_multiplets; + stars=a.stars; + time_last_updated=a.time_last_updated; + } + return (*this); +} + + +std::string candidate_count::update_format() const { + std::ostringstream rv(""); + + for (int i=2; i<15; i++) { + rv << "?,"; + } + rv << "?"; + return rv.str(); +} + + +std::string candidate_count::insert_format() const { + return std::string("?,")+update_format(); +} + +std::string candidate_count::select_format() const { + std::string rv(""); + for (int i=0; i<14; i++) { + rv+="?,"; + } + rv+="?"; + return rv; +} + +std::string candidate_count::print(int full_subtables, int show_ids, int no_refs) const { + std::ostringstream rv(""); + + rv.precision(14); + if (show_ids) { + rv << id; + } + rv << ','; + rv << spikes; + rv << ','; + rv << gaussians; + rv << ','; + rv << pulses; + rv << ','; + rv << triplets; + rv << ','; + rv << spike_barycentric_multiplets; + rv << ','; + rv << gaussian_barycentric_multiplets; + rv << ','; + rv << pulse_barycentric_multiplets; + rv << ','; + rv << triplet_barycentric_multiplets; + rv << ','; + rv << spike_nonbarycentric_multiplets; + rv << ','; + rv << gaussian_nonbarycentric_multiplets; + rv << ','; + rv << pulse_nonbarycentric_multiplets; + rv << ','; + rv << triplet_nonbarycentric_multiplets; + rv << ','; + rv << stars; + rv << ','; + rv << time_last_updated; + return rv.str(); +} + + +std::string candidate_count::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { + std::ostringstream rv(""); + + rv.precision(14); + rv << xml_indent() << '<' << tag << ">\n"; + xml_indent(2); + if (show_ids) { + rv << xml_indent() << "" << id << "\n"; + } + rv << xml_indent() << "" << spikes << "\n"; + rv << xml_indent() << "" << gaussians << "\n"; + rv << xml_indent() << "" << pulses << "\n"; + rv << xml_indent() << "" << triplets << "\n"; + rv << xml_indent() << "" << spike_barycentric_multiplets << "\n"; + rv << xml_indent() << "" << gaussian_barycentric_multiplets << "\n"; + rv << xml_indent() << "" << pulse_barycentric_multiplets << "\n"; + rv << xml_indent() << "" << triplet_barycentric_multiplets << "\n"; + rv << xml_indent() << "" << spike_nonbarycentric_multiplets << "\n"; + rv << xml_indent() << "" << gaussian_nonbarycentric_multiplets << "\n"; + rv << xml_indent() << "" << pulse_nonbarycentric_multiplets << "\n"; + rv << xml_indent() << "" << triplet_nonbarycentric_multiplets << "\n"; + rv << xml_indent() << "" << stars << "\n"; + rv << xml_indent() << "" << time_last_updated << "\n"; + xml_indent(-2); + rv << xml_indent() << "\n"; + return rv.str(); +} + + +void candidate_count::parse_xml(const std::string &s,const char *tag) { + std::string field,sub; + if (extract_xml_record(s,tag,field)) { + std::string::size_type pos=0; + if (extract_xml_record(field,"id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> id; + } + if (extract_xml_record(field,"spikes",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> spikes; + } + if (extract_xml_record(field,"gaussians",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> gaussians; + } + if (extract_xml_record(field,"pulses",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> pulses; + } + if (extract_xml_record(field,"triplets",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> triplets; + } + if (extract_xml_record(field,"spike_barycentric_multiplets",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> spike_barycentric_multiplets; + } + if (extract_xml_record(field,"gaussian_barycentric_multiplets",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> gaussian_barycentric_multiplets; + } + if (extract_xml_record(field,"pulse_barycentric_multiplets",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> pulse_barycentric_multiplets; + } + if (extract_xml_record(field,"triplet_barycentric_multiplets",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> triplet_barycentric_multiplets; + } + if (extract_xml_record(field,"spike_nonbarycentric_multiplets",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> spike_nonbarycentric_multiplets; + } + if (extract_xml_record(field,"gaussian_nonbarycentric_multiplets",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> gaussian_nonbarycentric_multiplets; + } + if (extract_xml_record(field,"pulse_nonbarycentric_multiplets",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> pulse_nonbarycentric_multiplets; + } + if (extract_xml_record(field,"triplet_nonbarycentric_multiplets",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> triplet_nonbarycentric_multiplets; + } + if (extract_xml_record(field,"stars",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> stars; + } + if (extract_xml_record(field,"time_last_updated",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> time_last_updated; + } + } +} + +void candidate_count::parse(const SQL_ROW &s) { + { + std::istringstream row(*(s[0])); + row >> id; + } + { + std::istringstream row(*(s[1])); + row >> spikes; + } + { + std::istringstream row(*(s[2])); + row >> gaussians; + } + { + std::istringstream row(*(s[3])); + row >> pulses; + } + { + std::istringstream row(*(s[4])); + row >> triplets; + } + { + std::istringstream row(*(s[5])); + row >> spike_barycentric_multiplets; + } + { + std::istringstream row(*(s[6])); + row >> gaussian_barycentric_multiplets; + } + { + std::istringstream row(*(s[7])); + row >> pulse_barycentric_multiplets; + } + { + std::istringstream row(*(s[8])); + row >> triplet_barycentric_multiplets; + } + { + std::istringstream row(*(s[9])); + row >> spike_nonbarycentric_multiplets; + } + { + std::istringstream row(*(s[10])); + row >> gaussian_nonbarycentric_multiplets; + } + { + std::istringstream row(*(s[11])); + row >> pulse_nonbarycentric_multiplets; + } + { + std::istringstream row(*(s[12])); + row >> triplet_nonbarycentric_multiplets; + } + { + std::istringstream row(*(s[13])); + row >> stars; + } + { + std::istringstream row(*(s[14])); + row >> time_last_updated; + } +} + +void candidate_count::parse(const std::string &s) { + SQL_ROW row(&s,15); + parse(row); +} + +template <> const char *const db_table::table_name="tape"; +template <> const char *db_table::_search_tag=table_name; +template <> const int db_table::_nfields=8; +template <> const char *const db_table::column_names[8]= {"id","name","start_time","last_block_time","last_block_done","missed","tape_quality","beam"}; + +tape::tape() : + db_table(*this,-1), + id(0), + start_time(0), + last_block_time(0), + last_block_done(0), + missed(0), + tape_quality(0), + beam(0) { + db_open(); + name[0]=0; +} + + +tape::tape(const tape &a) : + db_table(*this,-1), + id(a.id), + start_time(a.start_time), + last_block_time(a.last_block_time), + last_block_done(a.last_block_done), + missed(a.missed), + tape_quality(a.tape_quality), + beam(a.beam) { + db_open(); + strcpy(name,a.name); +} + + +tape::tape(const SQL_ROW &a) : + db_table(*this,-1) { + db_open(); + parse(a); +} + + +tape::tape(const std::string &s,const char *tag) : + db_table(*this,-1) { + db_open(); + if (xml_match_tag(s,tag)) { + parse_xml(s,tag); + } else { + parse(s); + } +} + + +tape &tape::operator =(const tape &a) { + if (&a != this) { + id=a.id; + start_time=a.start_time; + last_block_time=a.last_block_time; + last_block_done=a.last_block_done; + missed=a.missed; + tape_quality=a.tape_quality; + beam=a.beam; + strcpy(name,a.name); + } + return (*this); +} + + +std::string tape::update_format() const { + std::ostringstream rv(""); + + for (int i=2; i<8; i++) { + rv << "?,"; + } + rv << "?"; + return rv.str(); +} + + +std::string tape::insert_format() const { + return std::string("?,")+update_format(); +} + +std::string tape::select_format() const { + std::string rv(""); + for (int i=0; i<7; i++) { + rv+="?,"; + } + rv+="?"; + return rv; +} + +std::string tape::print(int full_subtables, int show_ids, int no_refs) const { + std::ostringstream rv(""); + + rv.precision(14); + if (show_ids) { + rv << id; + } + rv << ','; + rv << "'" << name << "'"; + rv << ','; + rv << start_time; + rv << ','; + rv << last_block_time; + rv << ','; + rv << last_block_done; + rv << ','; + rv << missed; + rv << ','; + rv << tape_quality; + rv << ','; + rv << beam; + return rv.str(); +} + + +std::string tape::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { + std::ostringstream rv(""); + + rv.precision(14); + rv << xml_indent() << '<' << tag << ">\n"; + xml_indent(2); + if (show_ids) { + rv << xml_indent() << "" << id << "\n"; + } + { + std::string enc_field=xml_encode_string(name,std::min(strlen(name),sizeof(name))); + rv << xml_indent() << ""; + rv << enc_field << "\n"; + } + rv << xml_indent() << "" << start_time << "\n"; + rv << xml_indent() << "" << last_block_time << "\n"; + rv << xml_indent() << "" << last_block_done << "\n"; + rv << xml_indent() << "" << missed << "\n"; + rv << xml_indent() << "" << tape_quality << "\n"; + rv << xml_indent() << "" << beam << "\n"; + xml_indent(-2); + rv << xml_indent() << "\n"; + return rv.str(); +} + + +void tape::parse_xml(const std::string &s,const char *tag) { + std::string field,sub; + if (extract_xml_record(s,tag,field)) { + std::string::size_type pos=0; + if (extract_xml_record(field,"id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> id; + } + if (extract_xml_record(field,"name",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::string::size_type epos=sub.find("<",pos); + if (epos==std::string::npos) { + epos=sub.find('\n',pos); + } + if (epos==std::string::npos) { + epos=pos+strlen(sub.c_str()+pos); + } + std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); + strncpy(name,(const char *)&(in.front()),std::min(in.size(),(size_t)20)); + name[std::min(in.size(),(size_t)19)]=0; + } + if (extract_xml_record(field,"start_time",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> start_time; + } + if (extract_xml_record(field,"last_block_time",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> last_block_time; + } + if (extract_xml_record(field,"last_block_done",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> last_block_done; + } + if (extract_xml_record(field,"missed",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> missed; + } + if (extract_xml_record(field,"tape_quality",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> tape_quality; + } + if (extract_xml_record(field,"beam",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> beam; + } + } +} + +void tape::parse(const SQL_ROW &s) { + { + std::istringstream row(*(s[0])); + row >> id; + } + { + strncpy(name,s[1]->c_str(),20); + name[19]=0; + } + { + std::istringstream row(*(s[2])); + row >> start_time; + } + { + std::istringstream row(*(s[3])); + row >> last_block_time; + } + { + std::istringstream row(*(s[4])); + row >> last_block_done; + } + { + std::istringstream row(*(s[5])); + row >> missed; + } + { + std::istringstream row(*(s[6])); + row >> tape_quality; + } + { + std::istringstream row(*(s[7])); + row >> beam; + } +} + +void tape::parse(const std::string &s) { + SQL_ROW row(&s,8); + parse(row); +} + +template <> const char *const db_table::table_name="settings"; +template <> const char *db_table::_search_tag=table_name; +template <> const int db_table::_nfields=6; +template <> const char *const db_table::column_names[6]= {"id","active","recorder_cfg","splitter_cfg","analysis_cfg","receiver_cfg"}; + +settings::settings() : + db_table(*this,-1), + id(0), + active(0), + recorder_cfg(), + splitter_cfg(), + analysis_cfg(), + receiver_cfg() { + db_open(); +} + + +settings::settings(const settings &a) : + db_table(*this,-1), + id(a.id), + active(a.active), + recorder_cfg(a.recorder_cfg), + splitter_cfg(a.splitter_cfg), + analysis_cfg(a.analysis_cfg), + receiver_cfg(a.receiver_cfg) { + db_open(); +} + + +settings::settings(const SQL_ROW &a) : + db_table(*this,-1) { + db_open(); + parse(a); +} + + +settings::settings(const std::string &s,const char *tag) : + db_table(*this,-1) { + db_open(); + if (xml_match_tag(s,tag)) { + parse_xml(s,tag); + } else { + parse(s); + } +} + + +settings &settings::operator =(const settings &a) { + if (&a != this) { + id=a.id; + active=a.active; + recorder_cfg=a.recorder_cfg; + splitter_cfg=a.splitter_cfg; + analysis_cfg=a.analysis_cfg; + receiver_cfg=a.receiver_cfg; + } + return (*this); +} + + +std::string settings::update_format() const { + std::ostringstream rv(""); + + for (int i=2; i<6; i++) { + rv << "?,"; + } + rv << "?"; + return rv.str(); +} + + +std::string settings::insert_format() const { + return std::string("?,")+update_format(); +} + +std::string settings::select_format() const { + std::string rv(""); + for (int i=0; i<5; i++) { + rv+="?,"; + } + rv+="?"; + return rv; +} + +std::string settings::print(int full_subtables, int show_ids, int no_refs) const { + std::ostringstream rv(""); + + rv.precision(14); + if (show_ids) { + rv << id; + } + rv << ','; + rv << active; + rv << ','; + if (!no_refs) { + if (full_subtables) { + rv << recorder_cfg.print(full_subtables,show_ids,no_refs); + } else { + rv << recorder_cfg.id; + } + } + rv << ','; + if (!no_refs) { + if (full_subtables) { + rv << splitter_cfg.print(full_subtables,show_ids,no_refs); + } else { + rv << splitter_cfg.id; + } + } + rv << ','; + if (!no_refs) { + if (full_subtables) { + rv << analysis_cfg.print(full_subtables,show_ids,no_refs); + } else { + rv << analysis_cfg.id; + } + } + rv << ','; + if (!no_refs) { + if (full_subtables) { + rv << receiver_cfg.print(full_subtables,show_ids,no_refs); + } else { + rv << receiver_cfg.id; + } + } + return rv.str(); +} + + +std::string settings::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { + std::ostringstream rv(""); + + rv.precision(14); + rv << xml_indent() << '<' << tag << ">\n"; + xml_indent(2); + if (show_ids) { + rv << xml_indent() << "" << id << "\n"; + } + rv << xml_indent() << "" << active << "\n"; + if (!no_refs) { + if (full_subtables) { + rv << recorder_cfg.print_xml(full_subtables,show_ids,no_refs,"recorder_cfg"); + } else { + rv << xml_indent() << "" << recorder_cfg.id << "\n"; + } + } + if (!no_refs) { + if (full_subtables) { + rv << splitter_cfg.print_xml(full_subtables,show_ids,no_refs,"splitter_cfg"); + } else { + rv << xml_indent() << "" << splitter_cfg.id << "\n"; + } + } + if (!no_refs) { + if (full_subtables) { + rv << analysis_cfg.print_xml(full_subtables,show_ids,no_refs,"analysis_cfg"); + } else { + rv << xml_indent() << "" << analysis_cfg.id << "\n"; + } + } + if (!no_refs) { + if (full_subtables) { + rv << receiver_cfg.print_xml(full_subtables,show_ids,no_refs,"receiver_cfg"); + } else { + rv << xml_indent() << "" << receiver_cfg.id << "\n"; + } + } + xml_indent(-2); + rv << xml_indent() << "\n"; + return rv.str(); +} + + +void settings::parse_xml(const std::string &s,const char *tag) { + std::string field,sub; + if (extract_xml_record(s,tag,field)) { + std::string::size_type pos=0; + if (extract_xml_record(field,"id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> id; + } + if (extract_xml_record(field,"active",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> active; + } + if (extract_xml_record(field,"recorder_cfg",sub)) { + recorder_cfg.parse_xml(sub,"recorder_cfg"); + } + if (extract_xml_record(field,"splitter_cfg",sub)) { + splitter_cfg.parse_xml(sub,"splitter_cfg"); + } + if (extract_xml_record(field,"analysis_cfg",sub)) { + analysis_cfg.parse_xml(sub,"analysis_cfg"); + } + if (extract_xml_record(field,"receiver_cfg",sub)) { + receiver_cfg.parse_xml(sub,"receiver_cfg"); + } + } +} + +void settings::parse(const SQL_ROW &s) { + { + std::istringstream row(*(s[0])); + row >> id; + } + { + std::istringstream row(*(s[1])); + row >> active; + } + { + recorder_cfg.parse(SQL_ROW(s[2],0)); + } + { + splitter_cfg.parse(SQL_ROW(s[3],0)); + } + { + analysis_cfg.parse(SQL_ROW(s[4],0)); + } + { + receiver_cfg.parse(SQL_ROW(s[5],0)); + } +} + +void settings::parse(const std::string &s) { + SQL_ROW row(&s,6); + parse(row); +} + +template <> const char *const db_table::table_name="workunit_grp"; +template <> const char *db_table::_search_tag=table_name; +template <> const int db_table::_nfields=9; +template <> const char *const db_table::column_names[9]= {"id","tape_info","name","data_desc","receiver_cfg","recorder_cfg","splitter_cfg","analysis_cfg","sb_id"}; + +workunit_grp::workunit_grp() : + db_table(*this,-1), + id(0), + tape_info(), + data_desc(), + receiver_cfg(), + recorder_cfg(), + splitter_cfg(), + analysis_cfg(), + sb_id(0) { + db_open(); + name[0]=0; +} + + +workunit_grp::workunit_grp(const workunit_grp &a) : + db_table(*this,-1), + id(a.id), + tape_info(a.tape_info), + data_desc(a.data_desc), + receiver_cfg(a.receiver_cfg), + recorder_cfg(a.recorder_cfg), + splitter_cfg(a.splitter_cfg), + analysis_cfg(a.analysis_cfg), + sb_id(a.sb_id) { + db_open(); + strcpy(name,a.name); +} + + +workunit_grp::workunit_grp(const SQL_ROW &a) : + db_table(*this,-1) { + db_open(); + parse(a); +} + + +workunit_grp::workunit_grp(const std::string &s,const char *tag) : + db_table(*this,-1) { + db_open(); + if (xml_match_tag(s,tag)) { + parse_xml(s,tag); + } else { + parse(s); + } +} + + +workunit_grp &workunit_grp::operator =(const workunit_grp &a) { + if (&a != this) { + id=a.id; + tape_info=a.tape_info; + data_desc=a.data_desc; + receiver_cfg=a.receiver_cfg; + recorder_cfg=a.recorder_cfg; + splitter_cfg=a.splitter_cfg; + analysis_cfg=a.analysis_cfg; + sb_id=a.sb_id; + strcpy(name,a.name); + } + return (*this); +} + + +std::string workunit_grp::update_format() const { + std::ostringstream rv(""); + + for (int i=2; i<9; i++) { + rv << "?,"; + } + rv << "?"; + return rv.str(); +} + + +std::string workunit_grp::insert_format() const { + return std::string("?,")+update_format(); +} + +std::string workunit_grp::select_format() const { + std::string rv(""); + for (int i=0; i<8; i++) { + rv+="?,"; + } + rv+="?"; + return rv; +} + +std::string workunit_grp::print(int full_subtables, int show_ids, int no_refs) const { + std::ostringstream rv(""); + + rv.precision(14); + if (show_ids) { + rv << id; + } + rv << ','; + if (!no_refs) { + if (full_subtables) { + rv << tape_info.print(full_subtables,show_ids,no_refs); + } else { + rv << tape_info.id; + } + } + rv << ','; + rv << "'" << name << "'"; + rv << ','; + rv << data_desc.print(full_subtables,show_ids,no_refs); + rv << ','; + if (!no_refs) { + if (full_subtables) { + rv << receiver_cfg.print(full_subtables,show_ids,no_refs); + } else { + rv << receiver_cfg.id; + } + } + rv << ','; + if (!no_refs) { + if (full_subtables) { + rv << recorder_cfg.print(full_subtables,show_ids,no_refs); + } else { + rv << recorder_cfg.id; + } + } + rv << ','; + if (!no_refs) { + if (full_subtables) { + rv << splitter_cfg.print(full_subtables,show_ids,no_refs); + } else { + rv << splitter_cfg.id; + } + } + rv << ','; + if (!no_refs) { + if (full_subtables) { + rv << analysis_cfg.print(full_subtables,show_ids,no_refs); + } else { + rv << analysis_cfg.id; + } + } + rv << ','; + rv << sb_id; + return rv.str(); +} + + +std::string workunit_grp::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { + std::ostringstream rv(""); + + rv.precision(14); + rv << xml_indent() << '<' << tag << ">\n"; + xml_indent(2); + if (show_ids) { + rv << xml_indent() << "" << id << "\n"; + } + if (!no_refs) { + if (full_subtables) { + rv << tape_info.print_xml(full_subtables,show_ids,no_refs,"tape_info"); + } else { + rv << xml_indent() << "" << tape_info.id << "\n"; + } + } + { + std::string enc_field=xml_encode_string(name,std::min(strlen(name),sizeof(name))); + rv << xml_indent() << ""; + rv << enc_field << "\n"; + } + rv << data_desc.print_xml(full_subtables,show_ids,no_refs,"data_desc"); + if (!no_refs) { + if (full_subtables) { + rv << receiver_cfg.print_xml(full_subtables,show_ids,no_refs,"receiver_cfg"); + } else { + rv << xml_indent() << "" << receiver_cfg.id << "\n"; + } + } + if (!no_refs) { + if (full_subtables) { + rv << recorder_cfg.print_xml(full_subtables,show_ids,no_refs,"recorder_cfg"); + } else { + rv << xml_indent() << "" << recorder_cfg.id << "\n"; + } + } + if (!no_refs) { + if (full_subtables) { + rv << splitter_cfg.print_xml(full_subtables,show_ids,no_refs,"splitter_cfg"); + } else { + rv << xml_indent() << "" << splitter_cfg.id << "\n"; + } + } + if (!no_refs) { + if (full_subtables) { + rv << analysis_cfg.print_xml(full_subtables,show_ids,no_refs,"analysis_cfg"); + } else { + rv << xml_indent() << "" << analysis_cfg.id << "\n"; + } + } + rv << xml_indent() << "" << sb_id << "\n"; + xml_indent(-2); + rv << xml_indent() << "\n"; + return rv.str(); +} + + +void workunit_grp::parse_xml(const std::string &s,const char *tag) { + std::string field,sub; + if (extract_xml_record(s,tag,field)) { + std::string::size_type pos=0; + if (extract_xml_record(field,"id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> id; + } + if (extract_xml_record(field,"tape_info",sub)) { + tape_info.parse_xml(sub,"tape_info"); + } + if (extract_xml_record(field,"name",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::string::size_type epos=sub.find("<",pos); + if (epos==std::string::npos) { + epos=sub.find('\n',pos); + } + if (epos==std::string::npos) { + epos=pos+strlen(sub.c_str()+pos); + } + std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); + strncpy(name,(const char *)&(in.front()),std::min(in.size(),(size_t)64)); + name[std::min(in.size(),(size_t)63)]=0; + } + if (extract_xml_record(field,"data_desc",sub)) { + data_desc.parse_xml(sub,"data_desc"); + } + if (extract_xml_record(field,"receiver_cfg",sub)) { + receiver_cfg.parse_xml(sub,"receiver_cfg"); + } + if (extract_xml_record(field,"recorder_cfg",sub)) { + recorder_cfg.parse_xml(sub,"recorder_cfg"); + } + if (extract_xml_record(field,"splitter_cfg",sub)) { + splitter_cfg.parse_xml(sub,"splitter_cfg"); + } + if (extract_xml_record(field,"analysis_cfg",sub)) { + analysis_cfg.parse_xml(sub,"analysis_cfg"); + } + if (extract_xml_record(field,"sb_id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> sb_id; + } + } +} + +void workunit_grp::parse(const SQL_ROW &s) { + { + std::istringstream row(*(s[0])); + row >> id; + } + { + tape_info.parse(SQL_ROW(s[1],0)); + } + { + strncpy(name,s[2]->c_str(),64); + name[63]=0; + } + { + data_desc.parse(SQL_ROW(s[3],0)); + } + { + receiver_cfg.parse(SQL_ROW(s[4],0)); + } + { + recorder_cfg.parse(SQL_ROW(s[5],0)); + } + { + splitter_cfg.parse(SQL_ROW(s[6],0)); + } + { + analysis_cfg.parse(SQL_ROW(s[7],0)); + } + { + std::istringstream row(*(s[8])); + row >> sb_id; + } +} + +void workunit_grp::parse(const std::string &s) { + SQL_ROW row(&s,9); + parse(row); +} + +template <> const char *const db_table::table_name="workunit_header"; +template <> const char *db_table::_search_tag=table_name; +template <> const int db_table::_nfields=5; +template <> const char *const db_table::column_names[5]= {"id","name","group_info","subband_desc","sb_id"}; + +workunit_header::workunit_header() : + db_table(*this,-1), + id(0), + group_info(), + subband_desc(), + sb_id(0) { + db_open(); + name[0]=0; +} + + +workunit_header::workunit_header(const workunit_header &a) : + db_table(*this,-1), + id(a.id), + group_info(a.group_info), + subband_desc(a.subband_desc), + sb_id(a.sb_id) { + db_open(); + strcpy(name,a.name); +} + + +workunit_header::workunit_header(const SQL_ROW &a) : + db_table(*this,-1) { + db_open(); + parse(a); +} + + +workunit_header::workunit_header(const std::string &s,const char *tag) : + db_table(*this,-1) { + db_open(); + if (xml_match_tag(s,tag)) { + parse_xml(s,tag); + } else { + parse(s); + } +} + + +workunit_header &workunit_header::operator =(const workunit_header &a) { + if (&a != this) { + id=a.id; + group_info=a.group_info; + subband_desc=a.subband_desc; + sb_id=a.sb_id; + strcpy(name,a.name); + } + return (*this); +} + + +std::string workunit_header::update_format() const { + std::ostringstream rv(""); + + for (int i=2; i<5; i++) { + rv << "?,"; + } + rv << "?"; + return rv.str(); +} + + +std::string workunit_header::insert_format() const { + return std::string("?,")+update_format(); +} + +std::string workunit_header::select_format() const { + std::string rv(""); + for (int i=0; i<4; i++) { + rv+="?,"; + } + rv+="?"; + return rv; +} + +std::string workunit_header::print(int full_subtables, int show_ids, int no_refs) const { + std::ostringstream rv(""); + + rv.precision(14); + if (show_ids) { + rv << id; + } + rv << ','; + rv << "'" << name << "'"; + rv << ','; + if (!no_refs) { + if (full_subtables) { + rv << group_info.print(full_subtables,show_ids,no_refs); + } else { + rv << group_info.id; + } + } + rv << ','; + rv << subband_desc.print(full_subtables,show_ids,no_refs); + rv << ','; + rv << sb_id; + return rv.str(); +} + + +std::string workunit_header::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { + std::ostringstream rv(""); + + rv.precision(14); + rv << xml_indent() << '<' << tag << ">\n"; + xml_indent(2); + if (show_ids) { + rv << xml_indent() << "" << id << "\n"; + } + { + std::string enc_field=xml_encode_string(name,std::min(strlen(name),sizeof(name))); + rv << xml_indent() << ""; + rv << enc_field << "\n"; + } + if (!no_refs) { + if (full_subtables) { + rv << group_info.print_xml(full_subtables,show_ids,no_refs,"group_info"); + } else { + rv << xml_indent() << "" << group_info.id << "\n"; + } + } + rv << subband_desc.print_xml(full_subtables,show_ids,no_refs,"subband_desc"); + rv << xml_indent() << "" << sb_id << "\n"; + xml_indent(-2); + rv << xml_indent() << "\n"; + return rv.str(); +} + + +void workunit_header::parse_xml(const std::string &s,const char *tag) { + std::string field,sub; + if (extract_xml_record(s,tag,field)) { + std::string::size_type pos=0; + if (extract_xml_record(field,"id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> id; + } + if (extract_xml_record(field,"name",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::string::size_type epos=sub.find("<",pos); + if (epos==std::string::npos) { + epos=sub.find('\n',pos); + } + if (epos==std::string::npos) { + epos=pos+strlen(sub.c_str()+pos); + } + std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); + strncpy(name,(const char *)&(in.front()),std::min(in.size(),(size_t)64)); + name[std::min(in.size(),(size_t)63)]=0; + } + if (extract_xml_record(field,"group_info",sub)) { + group_info.parse_xml(sub,"group_info"); + } + if (extract_xml_record(field,"subband_desc",sub)) { + subband_desc.parse_xml(sub,"subband_desc"); + } + if (extract_xml_record(field,"sb_id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> sb_id; + } + } +} + +void workunit_header::parse(const SQL_ROW &s) { + { + std::istringstream row(*(s[0])); + row >> id; + } + { + strncpy(name,s[1]->c_str(),64); + name[63]=0; + } + { + group_info.parse(SQL_ROW(s[2],0)); + } + { + subband_desc.parse(SQL_ROW(s[3],0)); + } + { + std::istringstream row(*(s[4])); + row >> sb_id; + } +} + +void workunit_header::parse(const std::string &s) { + SQL_ROW row(&s,5); + parse(row); +} + +template <> const char *const db_table::table_name="result"; +template <> const char *db_table::_search_tag=table_name; +template <> const int db_table::_nfields=10; +template <> const char *const db_table::column_names[10]= {"id","boinc_result","wuid","received","hostid","versionid","return_code","overflow","reserved","sb_id"}; + +result::result() : + db_table(*this,-1), + id(0), + boinc_result(0), + wuid(), + received(0), + hostid(0), + versionid(0), + return_code(0), + overflow(0), + reserved(0), + sb_id(0) { + db_open(); +} + + +result::result(const result &a) : + db_table(*this,-1), + id(a.id), + boinc_result(a.boinc_result), + wuid(a.wuid), + received(a.received), + hostid(a.hostid), + versionid(a.versionid), + return_code(a.return_code), + overflow(a.overflow), + reserved(a.reserved), + sb_id(a.sb_id) { + db_open(); +} + + +result::result(const SQL_ROW &a) : + db_table(*this,-1) { + db_open(); + parse(a); +} + + +result::result(const std::string &s,const char *tag) : + db_table(*this,-1) { + db_open(); + if (xml_match_tag(s,tag)) { + parse_xml(s,tag); + } else { + parse(s); + } +} + + +result &result::operator =(const result &a) { + if (&a != this) { + id=a.id; + boinc_result=a.boinc_result; + wuid=a.wuid; + received=a.received; + hostid=a.hostid; + versionid=a.versionid; + return_code=a.return_code; + overflow=a.overflow; + reserved=a.reserved; + sb_id=a.sb_id; + } + return (*this); +} + + +std::string result::update_format() const { + std::ostringstream rv(""); + + for (int i=2; i<10; i++) { + rv << "?,"; + } + rv << "?"; + return rv.str(); +} + + +std::string result::insert_format() const { + return std::string("?,")+update_format(); +} + +std::string result::select_format() const { + std::string rv(""); + for (int i=0; i<9; i++) { + rv+="?,"; + } + rv+="?"; + return rv; +} + +std::string result::print(int full_subtables, int show_ids, int no_refs) const { + std::ostringstream rv(""); + + rv.precision(14); + if (show_ids) { + rv << id; + } + rv << ','; + rv << boinc_result; + rv << ','; + if (!no_refs) { + if (full_subtables) { + rv << wuid.print(full_subtables,show_ids,no_refs); + } else { + rv << wuid.id; + } + } + rv << ','; + rv << received; + rv << ','; + rv << hostid; + rv << ','; + rv << versionid; + rv << ','; + rv << return_code; + rv << ','; + rv << overflow; + rv << ','; + rv << reserved; + rv << ','; + rv << sb_id; + return rv.str(); +} + + +std::string result::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { + std::ostringstream rv(""); + + rv.precision(14); + rv << xml_indent() << '<' << tag << ">\n"; + xml_indent(2); + if (show_ids) { + rv << xml_indent() << "" << id << "\n"; + } + rv << xml_indent() << "" << boinc_result << "\n"; + if (!no_refs) { + if (full_subtables) { + rv << wuid.print_xml(full_subtables,show_ids,no_refs,"wuid"); + } else { + rv << xml_indent() << "" << wuid.id << "\n"; + } + } + rv << xml_indent() << "" << received << "\n"; + rv << xml_indent() << "" << hostid << "\n"; + rv << xml_indent() << "" << versionid << "\n"; + rv << xml_indent() << "" << return_code << "\n"; + rv << xml_indent() << "" << overflow << "\n"; + rv << xml_indent() << "" << reserved << "\n"; + rv << xml_indent() << "" << sb_id << "\n"; + xml_indent(-2); + rv << xml_indent() << "\n"; + return rv.str(); +} + + +void result::parse_xml(const std::string &s,const char *tag) { + std::string field,sub; + if (extract_xml_record(s,tag,field)) { + std::string::size_type pos=0; + if (extract_xml_record(field,"id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> id; + } + if (extract_xml_record(field,"boinc_result",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> boinc_result; + } + if (extract_xml_record(field,"wuid",sub)) { + wuid.parse_xml(sub,"wuid"); + } + if (extract_xml_record(field,"received",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> received; + } + if (extract_xml_record(field,"hostid",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> hostid; + } + if (extract_xml_record(field,"versionid",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> versionid; + } + if (extract_xml_record(field,"return_code",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> return_code; + } + if (extract_xml_record(field,"overflow",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> overflow; + } + if (extract_xml_record(field,"reserved",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> reserved; + } + if (extract_xml_record(field,"sb_id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> sb_id; + } + } +} + +void result::parse(const SQL_ROW &s) { + { + std::istringstream row(*(s[0])); + row >> id; + } + { + std::istringstream row(*(s[1])); + row >> boinc_result; + } + { + wuid.parse(SQL_ROW(s[2],0)); + } + { + std::istringstream row(*(s[3])); + row >> received; + } + { + std::istringstream row(*(s[4])); + row >> hostid; + } + { + std::istringstream row(*(s[5])); + row >> versionid; + } + { + std::istringstream row(*(s[6])); + row >> return_code; + } + { + std::istringstream row(*(s[7])); + row >> overflow; + } + { + std::istringstream row(*(s[8])); + row >> reserved; + } + { + std::istringstream row(*(s[9])); + row >> sb_id; + } +} + +void result::parse(const std::string &s) { + SQL_ROW row(&s,10); + parse(row); +} + +template <> const char *const db_table::table_name="triplet"; +template <> const char *db_table::_search_tag=table_name; +template <> const int db_table::_nfields=17; +template <> const char *const db_table::column_names[17]= {"id","result_id","peak_power","mean_power","time","ra","decl","q_pix","freq","detection_freq","barycentric_freq","fft_len","chirp_rate","rfi_checked","rfi_found","reserved","period"}; + +triplet::triplet() : + db_table(*this,-1), + id(0), + result_id(), + peak_power(0), + mean_power(0), + time(0), + ra(0), + decl(0), + q_pix(0), + freq(0), + detection_freq(0), + barycentric_freq(0), + fft_len(0), + chirp_rate(0), + rfi_checked(0), + rfi_found(0), + reserved(0), + period(0) { + db_open(); +} + + +triplet::triplet(const triplet &a) : + db_table(*this,-1), + id(a.id), + result_id(a.result_id), + peak_power(a.peak_power), + mean_power(a.mean_power), + time(a.time), + ra(a.ra), + decl(a.decl), + q_pix(a.q_pix), + freq(a.freq), + detection_freq(a.detection_freq), + barycentric_freq(a.barycentric_freq), + fft_len(a.fft_len), + chirp_rate(a.chirp_rate), + rfi_checked(a.rfi_checked), + rfi_found(a.rfi_found), + reserved(a.reserved), + period(a.period) { + db_open(); +} + + +triplet::triplet(const SQL_ROW &a) : + db_table(*this,-1) { + db_open(); + parse(a); +} + + +triplet::triplet(const std::string &s,const char *tag) : + db_table(*this,-1) { + db_open(); + if (xml_match_tag(s,tag)) { + parse_xml(s,tag); + } else { + parse(s); + } +} + + +triplet &triplet::operator =(const triplet &a) { + if (&a != this) { + id=a.id; + result_id=a.result_id; + peak_power=a.peak_power; + mean_power=a.mean_power; + time=a.time; + ra=a.ra; + decl=a.decl; + q_pix=a.q_pix; + freq=a.freq; + detection_freq=a.detection_freq; + barycentric_freq=a.barycentric_freq; + fft_len=a.fft_len; + chirp_rate=a.chirp_rate; + rfi_checked=a.rfi_checked; + rfi_found=a.rfi_found; + reserved=a.reserved; + period=a.period; + } + return (*this); +} + + +std::string triplet::update_format() const { + std::ostringstream rv(""); + + for (int i=2; i<17; i++) { + rv << "?,"; + } + rv << "?"; + return rv.str(); +} + + +std::string triplet::insert_format() const { + return std::string("?,")+update_format(); +} + +std::string triplet::select_format() const { + std::string rv(""); + for (int i=0; i<16; i++) { + rv+="?,"; + } + rv+="?"; + return rv; +} + +std::string triplet::print(int full_subtables, int show_ids, int no_refs) const { + std::ostringstream rv(""); + + rv.precision(14); + if (show_ids) { + rv << id; + } + rv << ','; + if (!no_refs) { + if (full_subtables) { + rv << result_id.print(full_subtables,show_ids,no_refs); + } else { + rv << result_id.id; + } + } + rv << ','; + rv << peak_power; + rv << ','; + rv << mean_power; + rv << ','; + rv << time; + rv << ','; + rv << ra; + rv << ','; + rv << decl; + rv << ','; + rv << q_pix; + rv << ','; + rv << freq; + rv << ','; + rv << detection_freq; + rv << ','; + rv << barycentric_freq; + rv << ','; + rv << fft_len; + rv << ','; + rv << chirp_rate; + rv << ','; + rv << rfi_checked; + rv << ','; + rv << rfi_found; + rv << ','; + rv << reserved; + rv << ','; + rv << period; + return rv.str(); +} + + +std::string triplet::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { + std::ostringstream rv(""); + + rv.precision(14); + rv << xml_indent() << '<' << tag << ">\n"; + xml_indent(2); + if (show_ids) { + rv << xml_indent() << "" << id << "\n"; + } + if (!no_refs) { + if (full_subtables) { + rv << result_id.print_xml(full_subtables,show_ids,no_refs,"result_id"); + } else { + rv << xml_indent() << "" << result_id.id << "\n"; + } + } + rv << xml_indent() << "" << peak_power << "\n"; + rv << xml_indent() << "" << mean_power << "\n"; + rv << xml_indent() << "\n"; + rv << xml_indent() << "" << ra << "\n"; + rv << xml_indent() << "" << decl << "\n"; + rv << xml_indent() << "" << q_pix << "\n"; + rv << xml_indent() << "" << freq << "\n"; + rv << xml_indent() << "" << detection_freq << "\n"; + rv << xml_indent() << "" << barycentric_freq << "\n"; + rv << xml_indent() << "" << fft_len << "\n"; + rv << xml_indent() << "" << chirp_rate << "\n"; + rv << xml_indent() << "" << rfi_checked << "\n"; + rv << xml_indent() << "" << rfi_found << "\n"; + rv << xml_indent() << "" << reserved << "\n"; + rv << xml_indent() << "" << period << "\n"; + xml_indent(-2); + rv << xml_indent() << "\n"; + return rv.str(); +} + + +void triplet::parse_xml(const std::string &s,const char *tag) { + std::string field,sub; + if (extract_xml_record(s,tag,field)) { + std::string::size_type pos=0; + if (extract_xml_record(field,"id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> id; + } + if (extract_xml_record(field,"result_id",sub)) { + result_id.parse_xml(sub,"result_id"); + } + if (extract_xml_record(field,"peak_power",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> peak_power; + } + if (extract_xml_record(field,"mean_power",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> mean_power; + } + if (extract_xml_record(field,"time",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> time; + } + if (extract_xml_record(field,"ra",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> ra; + } + if (extract_xml_record(field,"decl",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> decl; + } + if (extract_xml_record(field,"q_pix",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> q_pix; + } + if (extract_xml_record(field,"freq",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> freq; + } + if (extract_xml_record(field,"detection_freq",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> detection_freq; + } + if (extract_xml_record(field,"barycentric_freq",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> barycentric_freq; + } + if (extract_xml_record(field,"fft_len",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> fft_len; + } + if (extract_xml_record(field,"chirp_rate",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> chirp_rate; + } + if (extract_xml_record(field,"rfi_checked",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> rfi_checked; + } + if (extract_xml_record(field,"rfi_found",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> rfi_found; + } + if (extract_xml_record(field,"reserved",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> reserved; + } + if (extract_xml_record(field,"period",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> period; + } + } +} + +void triplet::parse(const SQL_ROW &s) { + { + std::istringstream row(*(s[0])); + row >> id; + } + { + result_id.parse(SQL_ROW(s[1],0)); + } + { + std::istringstream row(*(s[2])); + row >> peak_power; + } + { + std::istringstream row(*(s[3])); + row >> mean_power; + } + { + std::istringstream row(*(s[4])); + row >> time; + } + { + std::istringstream row(*(s[5])); + row >> ra; + } + { + std::istringstream row(*(s[6])); + row >> decl; + } + { + std::istringstream row(*(s[7])); + row >> q_pix; + } + { + std::istringstream row(*(s[8])); + row >> freq; + } + { + std::istringstream row(*(s[9])); + row >> detection_freq; + } + { + std::istringstream row(*(s[10])); + row >> barycentric_freq; + } + { + std::istringstream row(*(s[11])); + row >> fft_len; + } + { + std::istringstream row(*(s[12])); + row >> chirp_rate; + } + { + std::istringstream row(*(s[13])); + row >> rfi_checked; + } + { + std::istringstream row(*(s[14])); + row >> rfi_found; + } + { + std::istringstream row(*(s[15])); + row >> reserved; + } + { + std::istringstream row(*(s[16])); + row >> period; + } +} + +void triplet::parse(const std::string &s) { + SQL_ROW row(&s,17); + parse(row); +} + +template <> const char *const db_table::table_name="triplet_small"; +template <> const char *db_table::_search_tag=table_name; +template <> const int db_table::_nfields=17; +template <> const char *const db_table::column_names[17]= {"id","result_id","peak_power","mean_power","time","ra","decl","q_pix","freq","detection_freq","barycentric_freq","fft_len","chirp_rate","rfi_checked","rfi_found","reserved","period"}; + +triplet_small::triplet_small() : + db_table(*this,-1), + id(0), + result_id(), + peak_power(0), + mean_power(0), + time(0), + ra(0), + decl(0), + q_pix(0), + freq(0), + detection_freq(0), + barycentric_freq(0), + fft_len(0), + chirp_rate(0), + rfi_checked(0), + rfi_found(0), + reserved(0), + period(0) { + db_open(); +} + + +triplet_small::triplet_small(const triplet_small &a) : + db_table(*this,-1), + id(a.id), + result_id(a.result_id), + peak_power(a.peak_power), + mean_power(a.mean_power), + time(a.time), + ra(a.ra), + decl(a.decl), + q_pix(a.q_pix), + freq(a.freq), + detection_freq(a.detection_freq), + barycentric_freq(a.barycentric_freq), + fft_len(a.fft_len), + chirp_rate(a.chirp_rate), + rfi_checked(a.rfi_checked), + rfi_found(a.rfi_found), + reserved(a.reserved), + period(a.period) { + db_open(); +} + + +triplet_small::triplet_small(const SQL_ROW &a) : + db_table(*this,-1) { + db_open(); + parse(a); +} + + +triplet_small::triplet_small(const std::string &s,const char *tag) : + db_table(*this,-1) { + db_open(); + if (xml_match_tag(s,tag)) { + parse_xml(s,tag); + } else { + parse(s); + } +} + + +triplet_small &triplet_small::operator =(const triplet_small &a) { + if (&a != this) { + id=a.id; + result_id=a.result_id; + peak_power=a.peak_power; + mean_power=a.mean_power; + time=a.time; + ra=a.ra; + decl=a.decl; + q_pix=a.q_pix; + freq=a.freq; + detection_freq=a.detection_freq; + barycentric_freq=a.barycentric_freq; + fft_len=a.fft_len; + chirp_rate=a.chirp_rate; + rfi_checked=a.rfi_checked; + rfi_found=a.rfi_found; + reserved=a.reserved; + period=a.period; + } + return (*this); +} + + +std::string triplet_small::update_format() const { + std::ostringstream rv(""); + + for (int i=2; i<17; i++) { + rv << "?,"; + } + rv << "?"; + return rv.str(); +} + + +std::string triplet_small::insert_format() const { + return std::string("?,")+update_format(); +} + +std::string triplet_small::select_format() const { + std::string rv(""); + for (int i=0; i<16; i++) { + rv+="?,"; + } + rv+="?"; + return rv; +} + +std::string triplet_small::print(int full_subtables, int show_ids, int no_refs) const { + std::ostringstream rv(""); + + rv.precision(14); + if (show_ids) { + rv << id; + } + rv << ','; + if (!no_refs) { + if (full_subtables) { + rv << result_id.print(full_subtables,show_ids,no_refs); + } else { + rv << result_id.id; + } + } + rv << ','; + rv << peak_power; + rv << ','; + rv << mean_power; + rv << ','; + rv << time; + rv << ','; + rv << ra; + rv << ','; + rv << decl; + rv << ','; + rv << q_pix; + rv << ','; + rv << freq; + rv << ','; + rv << detection_freq; + rv << ','; + rv << barycentric_freq; + rv << ','; + rv << fft_len; + rv << ','; + rv << chirp_rate; + rv << ','; + rv << rfi_checked; + rv << ','; + rv << rfi_found; + rv << ','; + rv << reserved; + rv << ','; + rv << period; + return rv.str(); +} + + +std::string triplet_small::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { + std::ostringstream rv(""); + + rv.precision(14); + rv << xml_indent() << '<' << tag << ">\n"; + xml_indent(2); + if (show_ids) { + rv << xml_indent() << "" << id << "\n"; + } + if (!no_refs) { + if (full_subtables) { + rv << result_id.print_xml(full_subtables,show_ids,no_refs,"result_id"); + } else { + rv << xml_indent() << "" << result_id.id << "\n"; + } + } + rv << xml_indent() << "" << peak_power << "\n"; + rv << xml_indent() << "" << mean_power << "\n"; + rv << xml_indent() << "\n"; + rv << xml_indent() << "" << ra << "\n"; + rv << xml_indent() << "" << decl << "\n"; + rv << xml_indent() << "" << q_pix << "\n"; + rv << xml_indent() << "" << freq << "\n"; + rv << xml_indent() << "" << detection_freq << "\n"; + rv << xml_indent() << "" << barycentric_freq << "\n"; + rv << xml_indent() << "" << fft_len << "\n"; + rv << xml_indent() << "" << chirp_rate << "\n"; + rv << xml_indent() << "" << rfi_checked << "\n"; + rv << xml_indent() << "" << rfi_found << "\n"; + rv << xml_indent() << "" << reserved << "\n"; + rv << xml_indent() << "" << period << "\n"; + xml_indent(-2); + rv << xml_indent() << "\n"; + return rv.str(); +} + + +void triplet_small::parse_xml(const std::string &s,const char *tag) { + std::string field,sub; + if (extract_xml_record(s,tag,field)) { + std::string::size_type pos=0; + if (extract_xml_record(field,"id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> id; + } + if (extract_xml_record(field,"result_id",sub)) { + result_id.parse_xml(sub,"result_id"); + } + if (extract_xml_record(field,"peak_power",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> peak_power; + } + if (extract_xml_record(field,"mean_power",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> mean_power; + } + if (extract_xml_record(field,"time",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> time; + } + if (extract_xml_record(field,"ra",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> ra; + } + if (extract_xml_record(field,"decl",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> decl; + } + if (extract_xml_record(field,"q_pix",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> q_pix; + } + if (extract_xml_record(field,"freq",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> freq; + } + if (extract_xml_record(field,"detection_freq",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> detection_freq; + } + if (extract_xml_record(field,"barycentric_freq",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> barycentric_freq; + } + if (extract_xml_record(field,"fft_len",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> fft_len; + } + if (extract_xml_record(field,"chirp_rate",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> chirp_rate; + } + if (extract_xml_record(field,"rfi_checked",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> rfi_checked; + } + if (extract_xml_record(field,"rfi_found",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> rfi_found; + } + if (extract_xml_record(field,"reserved",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> reserved; + } + if (extract_xml_record(field,"period",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> period; + } + } +} + +void triplet_small::parse(const SQL_ROW &s) { + { + std::istringstream row(*(s[0])); + row >> id; + } + { + result_id.parse(SQL_ROW(s[1],0)); + } + { + std::istringstream row(*(s[2])); + row >> peak_power; + } + { + std::istringstream row(*(s[3])); + row >> mean_power; + } + { + std::istringstream row(*(s[4])); + row >> time; + } + { + std::istringstream row(*(s[5])); + row >> ra; + } + { + std::istringstream row(*(s[6])); + row >> decl; + } + { + std::istringstream row(*(s[7])); + row >> q_pix; + } + { + std::istringstream row(*(s[8])); + row >> freq; + } + { + std::istringstream row(*(s[9])); + row >> detection_freq; + } + { + std::istringstream row(*(s[10])); + row >> barycentric_freq; + } + { + std::istringstream row(*(s[11])); + row >> fft_len; + } + { + std::istringstream row(*(s[12])); + row >> chirp_rate; + } + { + std::istringstream row(*(s[13])); + row >> rfi_checked; + } + { + std::istringstream row(*(s[14])); + row >> rfi_found; + } + { + std::istringstream row(*(s[15])); + row >> reserved; + } + { + std::istringstream row(*(s[16])); + row >> period; + } +} + +void triplet_small::parse(const std::string &s) { + SQL_ROW row(&s,17); + parse(row); +} + +template <> const char *const db_table::table_name="gaussian"; +template <> const char *db_table::_search_tag=table_name; +template <> const int db_table::_nfields=22; +template <> const char *const db_table::column_names[22]= {"id","result_id","peak_power","mean_power","time","ra","decl","q_pix","freq","detection_freq","barycentric_freq","fft_len","chirp_rate","rfi_checked","rfi_found","reserved","sigma","chisqr","null_chisqr","score","max_power","pot"}; + +gaussian::gaussian() : + db_table(*this,-1), + id(0), + result_id(), + peak_power(0), + mean_power(0), + time(0), + ra(0), + decl(0), + q_pix(0), + freq(0), + detection_freq(0), + barycentric_freq(0), + fft_len(0), + chirp_rate(0), + rfi_checked(0), + rfi_found(0), + reserved(0), + sigma(0), + chisqr(0), + null_chisqr(0), + score(0), + max_power(0), + pot((unsigned char *)0,0,_x_csv) { + db_open(); +} + + +gaussian::gaussian(const gaussian &a) : + db_table(*this,-1), + id(a.id), + result_id(a.result_id), + peak_power(a.peak_power), + mean_power(a.mean_power), + time(a.time), + ra(a.ra), + decl(a.decl), + q_pix(a.q_pix), + freq(a.freq), + detection_freq(a.detection_freq), + barycentric_freq(a.barycentric_freq), + fft_len(a.fft_len), + chirp_rate(a.chirp_rate), + rfi_checked(a.rfi_checked), + rfi_found(a.rfi_found), + reserved(a.reserved), + sigma(a.sigma), + chisqr(a.chisqr), + null_chisqr(a.null_chisqr), + score(a.score), + max_power(a.max_power), + pot(a.pot) { + db_open(); +} + + +gaussian::gaussian(const SQL_ROW &a) : + db_table(*this,-1) { + db_open(); + parse(a); +} + + +gaussian::gaussian(const std::string &s,const char *tag) : + db_table(*this,-1) { + db_open(); + if (xml_match_tag(s,tag)) { + parse_xml(s,tag); + } else { + parse(s); + } +} + + +gaussian &gaussian::operator =(const gaussian &a) { + if (&a != this) { + id=a.id; + result_id=a.result_id; + peak_power=a.peak_power; + mean_power=a.mean_power; + time=a.time; + ra=a.ra; + decl=a.decl; + q_pix=a.q_pix; + freq=a.freq; + detection_freq=a.detection_freq; + barycentric_freq=a.barycentric_freq; + fft_len=a.fft_len; + chirp_rate=a.chirp_rate; + rfi_checked=a.rfi_checked; + rfi_found=a.rfi_found; + reserved=a.reserved; + sigma=a.sigma; + chisqr=a.chisqr; + null_chisqr=a.null_chisqr; + score=a.score; + max_power=a.max_power; + pot=a.pot; + } + return (*this); +} + + +std::string gaussian::update_format() const { + std::ostringstream rv(""); + + for (int i=2; i<22; i++) { + rv << "?,"; + } + rv << "?"; + return rv.str(); +} + + +std::string gaussian::insert_format() const { + return std::string("?,")+update_format(); +} + +std::string gaussian::select_format() const { + std::string rv(""); + for (int i=0; i<21; i++) { + rv+="?,"; + } + rv+="?"; + return rv; +} + +std::string gaussian::print(int full_subtables, int show_ids, int no_refs) const { + std::ostringstream rv(""); + + rv.precision(14); + if (show_ids) { + rv << id; + } + rv << ','; + if (!no_refs) { + if (full_subtables) { + rv << result_id.print(full_subtables,show_ids,no_refs); + } else { + rv << result_id.id; + } + } + rv << ','; + rv << peak_power; + rv << ','; + rv << mean_power; + rv << ','; + rv << time; + rv << ','; + rv << ra; + rv << ','; + rv << decl; + rv << ','; + rv << q_pix; + rv << ','; + rv << freq; + rv << ','; + rv << detection_freq; + rv << ','; + rv << barycentric_freq; + rv << ','; + rv << fft_len; + rv << ','; + rv << chirp_rate; + rv << ','; + rv << rfi_checked; + rv << ','; + rv << rfi_found; + rv << ','; + rv << reserved; + rv << ','; + rv << sigma; + rv << ','; + rv << chisqr; + rv << ','; + rv << null_chisqr; + rv << ','; + rv << score; + rv << ','; + rv << max_power; + rv << ','; + rv << "" << pot.print_hex() ; + return rv.str(); +} + + +std::string gaussian::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { + std::ostringstream rv(""); + + rv.precision(14); + rv << xml_indent() << '<' << tag << ">\n"; + xml_indent(2); + if (show_ids) { + rv << xml_indent() << "" << id << "\n"; + } + if (!no_refs) { + if (full_subtables) { + rv << result_id.print_xml(full_subtables,show_ids,no_refs,"result_id"); + } else { + rv << xml_indent() << "" << result_id.id << "\n"; + } + } + rv << xml_indent() << "" << peak_power << "\n"; + rv << xml_indent() << "" << mean_power << "\n"; + rv << xml_indent() << "\n"; + rv << xml_indent() << "" << ra << "\n"; + rv << xml_indent() << "" << decl << "\n"; + rv << xml_indent() << "" << q_pix << "\n"; + rv << xml_indent() << "" << freq << "\n"; + rv << xml_indent() << "" << detection_freq << "\n"; + rv << xml_indent() << "" << barycentric_freq << "\n"; + rv << xml_indent() << "" << fft_len << "\n"; + rv << xml_indent() << "" << chirp_rate << "\n"; + rv << xml_indent() << "" << rfi_checked << "\n"; + rv << xml_indent() << "" << rfi_found << "\n"; + rv << xml_indent() << "" << reserved << "\n"; + rv << xml_indent() << "" << sigma << "\n"; + rv << xml_indent() << "" << chisqr << "\n"; + rv << xml_indent() << "" << null_chisqr << "\n"; + rv << xml_indent() << "" << score << "\n"; + rv << xml_indent() << "" << max_power << "\n"; + if (pot.size()) { + std::string enc_field=xml_encode_string(pot,pot.encoding); + rv << xml_indent() << ""; + rv << enc_field << "\n"; + } + xml_indent(-2); + rv << xml_indent() << "\n"; + return rv.str(); +} + + +void gaussian::parse_xml(const std::string &s,const char *tag) { + std::string field,sub; + if (extract_xml_record(s,tag,field)) { + std::string::size_type pos=0; + if (extract_xml_record(field,"id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> id; + } + if (extract_xml_record(field,"result_id",sub)) { + result_id.parse_xml(sub,"result_id"); + } + if (extract_xml_record(field,"peak_power",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> peak_power; + } + if (extract_xml_record(field,"mean_power",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> mean_power; + } + if (extract_xml_record(field,"time",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> time; + } + if (extract_xml_record(field,"ra",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> ra; + } + if (extract_xml_record(field,"decl",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> decl; + } + if (extract_xml_record(field,"q_pix",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> q_pix; + } + if (extract_xml_record(field,"freq",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> freq; + } + if (extract_xml_record(field,"detection_freq",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> detection_freq; + } + if (extract_xml_record(field,"barycentric_freq",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> barycentric_freq; + } + if (extract_xml_record(field,"fft_len",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> fft_len; + } + if (extract_xml_record(field,"chirp_rate",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> chirp_rate; + } + if (extract_xml_record(field,"rfi_checked",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> rfi_checked; + } + if (extract_xml_record(field,"rfi_found",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> rfi_found; + } + if (extract_xml_record(field,"reserved",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> reserved; + } + if (extract_xml_record(field,"sigma",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> sigma; + } + if (extract_xml_record(field,"chisqr",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> chisqr; + } + if (extract_xml_record(field,"null_chisqr",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> null_chisqr; + } + if (extract_xml_record(field,"score",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> score; + } + if (extract_xml_record(field,"max_power",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> max_power; + } + if (extract_xml_record(field,"pot",sub)) { + std::istringstream in(sub.c_str()); + in >> pot; + } + } +} + +void gaussian::parse(const SQL_ROW &s) { + { + std::istringstream row(*(s[0])); + row >> id; + } + { + result_id.parse(SQL_ROW(s[1],0)); + } + { + std::istringstream row(*(s[2])); + row >> peak_power; + } + { + std::istringstream row(*(s[3])); + row >> mean_power; + } + { + std::istringstream row(*(s[4])); + row >> time; + } + { + std::istringstream row(*(s[5])); + row >> ra; + } + { + std::istringstream row(*(s[6])); + row >> decl; + } + { + std::istringstream row(*(s[7])); + row >> q_pix; + } + { + std::istringstream row(*(s[8])); + row >> freq; + } + { + std::istringstream row(*(s[9])); + row >> detection_freq; + } + { + std::istringstream row(*(s[10])); + row >> barycentric_freq; + } + { + std::istringstream row(*(s[11])); + row >> fft_len; + } + { + std::istringstream row(*(s[12])); + row >> chirp_rate; + } + { + std::istringstream row(*(s[13])); + row >> rfi_checked; + } + { + std::istringstream row(*(s[14])); + row >> rfi_found; + } + { + std::istringstream row(*(s[15])); + row >> reserved; + } + { + std::istringstream row(*(s[16])); + row >> sigma; + } + { + std::istringstream row(*(s[17])); + row >> chisqr; + } + { + std::istringstream row(*(s[18])); + row >> null_chisqr; + } + { + std::istringstream row(*(s[19])); + row >> score; + } + { + std::istringstream row(*(s[20])); + row >> max_power; + } + { + pot=sqlblob(*(s[21])); + } +} + +void gaussian::parse(const std::string &s) { + SQL_ROW row(&s,22); + parse(row); +} + +template <> const char *const db_table::table_name="gaussian_small"; +template <> const char *db_table::_search_tag=table_name; +template <> const int db_table::_nfields=21; +template <> const char *const db_table::column_names[21]= {"id","result_id","peak_power","mean_power","time","ra","decl","q_pix","freq","detection_freq","barycentric_freq","fft_len","chirp_rate","rfi_checked","rfi_found","reserved","sigma","chisqr","null_chisqr","score","max_power"}; + +gaussian_small::gaussian_small() : + db_table(*this,-1), + id(0), + result_id(), + peak_power(0), + mean_power(0), + time(0), + ra(0), + decl(0), + q_pix(0), + freq(0), + detection_freq(0), + barycentric_freq(0), + fft_len(0), + chirp_rate(0), + rfi_checked(0), + rfi_found(0), + reserved(0), + sigma(0), + chisqr(0), + null_chisqr(0), + score(0), + max_power(0) { + db_open(); +} + + +gaussian_small::gaussian_small(const gaussian_small &a) : + db_table(*this,-1), + id(a.id), + result_id(a.result_id), + peak_power(a.peak_power), + mean_power(a.mean_power), + time(a.time), + ra(a.ra), + decl(a.decl), + q_pix(a.q_pix), + freq(a.freq), + detection_freq(a.detection_freq), + barycentric_freq(a.barycentric_freq), + fft_len(a.fft_len), + chirp_rate(a.chirp_rate), + rfi_checked(a.rfi_checked), + rfi_found(a.rfi_found), + reserved(a.reserved), + sigma(a.sigma), + chisqr(a.chisqr), + null_chisqr(a.null_chisqr), + score(a.score), + max_power(a.max_power) { + db_open(); +} + + +gaussian_small::gaussian_small(const SQL_ROW &a) : + db_table(*this,-1) { + db_open(); + parse(a); +} + + +gaussian_small::gaussian_small(const std::string &s,const char *tag) : + db_table(*this,-1) { + db_open(); + if (xml_match_tag(s,tag)) { + parse_xml(s,tag); + } else { + parse(s); + } +} + + +gaussian_small &gaussian_small::operator =(const gaussian_small &a) { + if (&a != this) { + id=a.id; + result_id=a.result_id; + peak_power=a.peak_power; + mean_power=a.mean_power; + time=a.time; + ra=a.ra; + decl=a.decl; + q_pix=a.q_pix; + freq=a.freq; + detection_freq=a.detection_freq; + barycentric_freq=a.barycentric_freq; + fft_len=a.fft_len; + chirp_rate=a.chirp_rate; + rfi_checked=a.rfi_checked; + rfi_found=a.rfi_found; + reserved=a.reserved; + sigma=a.sigma; + chisqr=a.chisqr; + null_chisqr=a.null_chisqr; + score=a.score; + max_power=a.max_power; + } + return (*this); +} + + +std::string gaussian_small::update_format() const { + std::ostringstream rv(""); + + for (int i=2; i<21; i++) { + rv << "?,"; + } + rv << "?"; + return rv.str(); +} + + +std::string gaussian_small::insert_format() const { + return std::string("?,")+update_format(); +} + +std::string gaussian_small::select_format() const { + std::string rv(""); + for (int i=0; i<20; i++) { + rv+="?,"; + } + rv+="?"; + return rv; +} + +std::string gaussian_small::print(int full_subtables, int show_ids, int no_refs) const { + std::ostringstream rv(""); + + rv.precision(14); + if (show_ids) { + rv << id; + } + rv << ','; + if (!no_refs) { + if (full_subtables) { + rv << result_id.print(full_subtables,show_ids,no_refs); + } else { + rv << result_id.id; + } + } + rv << ','; + rv << peak_power; + rv << ','; + rv << mean_power; + rv << ','; + rv << time; + rv << ','; + rv << ra; + rv << ','; + rv << decl; + rv << ','; + rv << q_pix; + rv << ','; + rv << freq; + rv << ','; + rv << detection_freq; + rv << ','; + rv << barycentric_freq; + rv << ','; + rv << fft_len; + rv << ','; + rv << chirp_rate; + rv << ','; + rv << rfi_checked; + rv << ','; + rv << rfi_found; + rv << ','; + rv << reserved; + rv << ','; + rv << sigma; + rv << ','; + rv << chisqr; + rv << ','; + rv << null_chisqr; + rv << ','; + rv << score; + rv << ','; + rv << max_power; + return rv.str(); +} + + +std::string gaussian_small::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { + std::ostringstream rv(""); + + rv.precision(14); + rv << xml_indent() << '<' << tag << ">\n"; + xml_indent(2); + if (show_ids) { + rv << xml_indent() << "" << id << "\n"; + } + if (!no_refs) { + if (full_subtables) { + rv << result_id.print_xml(full_subtables,show_ids,no_refs,"result_id"); + } else { + rv << xml_indent() << "" << result_id.id << "\n"; + } + } + rv << xml_indent() << "" << peak_power << "\n"; + rv << xml_indent() << "" << mean_power << "\n"; + rv << xml_indent() << "\n"; + rv << xml_indent() << "" << ra << "\n"; + rv << xml_indent() << "" << decl << "\n"; + rv << xml_indent() << "" << q_pix << "\n"; + rv << xml_indent() << "" << freq << "\n"; + rv << xml_indent() << "" << detection_freq << "\n"; + rv << xml_indent() << "" << barycentric_freq << "\n"; + rv << xml_indent() << "" << fft_len << "\n"; + rv << xml_indent() << "" << chirp_rate << "\n"; + rv << xml_indent() << "" << rfi_checked << "\n"; + rv << xml_indent() << "" << rfi_found << "\n"; + rv << xml_indent() << "" << reserved << "\n"; + rv << xml_indent() << "" << sigma << "\n"; + rv << xml_indent() << "" << chisqr << "\n"; + rv << xml_indent() << "" << null_chisqr << "\n"; + rv << xml_indent() << "" << score << "\n"; + rv << xml_indent() << "" << max_power << "\n"; + xml_indent(-2); + rv << xml_indent() << "\n"; + return rv.str(); +} + + +void gaussian_small::parse_xml(const std::string &s,const char *tag) { + std::string field,sub; + if (extract_xml_record(s,tag,field)) { + std::string::size_type pos=0; + if (extract_xml_record(field,"id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> id; + } + if (extract_xml_record(field,"result_id",sub)) { + result_id.parse_xml(sub,"result_id"); + } + if (extract_xml_record(field,"peak_power",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> peak_power; + } + if (extract_xml_record(field,"mean_power",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> mean_power; + } + if (extract_xml_record(field,"time",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> time; + } + if (extract_xml_record(field,"ra",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> ra; + } + if (extract_xml_record(field,"decl",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> decl; + } + if (extract_xml_record(field,"q_pix",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> q_pix; + } + if (extract_xml_record(field,"freq",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> freq; + } + if (extract_xml_record(field,"detection_freq",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> detection_freq; + } + if (extract_xml_record(field,"barycentric_freq",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> barycentric_freq; + } + if (extract_xml_record(field,"fft_len",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> fft_len; + } + if (extract_xml_record(field,"chirp_rate",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> chirp_rate; + } + if (extract_xml_record(field,"rfi_checked",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> rfi_checked; + } + if (extract_xml_record(field,"rfi_found",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> rfi_found; + } + if (extract_xml_record(field,"reserved",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> reserved; + } + if (extract_xml_record(field,"sigma",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> sigma; + } + if (extract_xml_record(field,"chisqr",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> chisqr; + } + if (extract_xml_record(field,"null_chisqr",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> null_chisqr; + } + if (extract_xml_record(field,"score",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> score; + } + if (extract_xml_record(field,"max_power",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> max_power; + } + } +} + +void gaussian_small::parse(const SQL_ROW &s) { + { + std::istringstream row(*(s[0])); + row >> id; + } + { + result_id.parse(SQL_ROW(s[1],0)); + } + { + std::istringstream row(*(s[2])); + row >> peak_power; + } + { + std::istringstream row(*(s[3])); + row >> mean_power; + } + { + std::istringstream row(*(s[4])); + row >> time; + } + { + std::istringstream row(*(s[5])); + row >> ra; + } + { + std::istringstream row(*(s[6])); + row >> decl; + } + { + std::istringstream row(*(s[7])); + row >> q_pix; + } + { + std::istringstream row(*(s[8])); + row >> freq; + } + { + std::istringstream row(*(s[9])); + row >> detection_freq; + } + { + std::istringstream row(*(s[10])); + row >> barycentric_freq; + } + { + std::istringstream row(*(s[11])); + row >> fft_len; + } + { + std::istringstream row(*(s[12])); + row >> chirp_rate; + } + { + std::istringstream row(*(s[13])); + row >> rfi_checked; + } + { + std::istringstream row(*(s[14])); + row >> rfi_found; + } + { + std::istringstream row(*(s[15])); + row >> reserved; + } + { + std::istringstream row(*(s[16])); + row >> sigma; + } + { + std::istringstream row(*(s[17])); + row >> chisqr; + } + { + std::istringstream row(*(s[18])); + row >> null_chisqr; + } + { + std::istringstream row(*(s[19])); + row >> score; + } + { + std::istringstream row(*(s[20])); + row >> max_power; + } +} + +void gaussian_small::parse(const std::string &s) { + SQL_ROW row(&s,21); + parse(row); +} + +template <> const char *const db_table::table_name="pulse"; +template <> const char *db_table::_search_tag=table_name; +template <> const int db_table::_nfields=22; +template <> const char *const db_table::column_names[22]= {"id","result_id","peak_power","mean_power","time","ra","decl","q_pix","freq","detection_freq","barycentric_freq","fft_len","chirp_rate","rfi_checked","rfi_found","reserved","period","snr","thresh","score","len_prof","pot"}; + +pulse::pulse() : + db_table(*this,-1), + id(0), + result_id(), + peak_power(0), + mean_power(0), + time(0), + ra(0), + decl(0), + q_pix(0), + freq(0), + detection_freq(0), + barycentric_freq(0), + fft_len(0), + chirp_rate(0), + rfi_checked(0), + rfi_found(0), + reserved(0), + period(0), + snr(0), + thresh(0), + score(0), + len_prof(0), + pot((unsigned char *)0,0,_x_csv) { + db_open(); +} + + +pulse::pulse(const pulse &a) : + db_table(*this,-1), + id(a.id), + result_id(a.result_id), + peak_power(a.peak_power), + mean_power(a.mean_power), + time(a.time), + ra(a.ra), + decl(a.decl), + q_pix(a.q_pix), + freq(a.freq), + detection_freq(a.detection_freq), + barycentric_freq(a.barycentric_freq), + fft_len(a.fft_len), + chirp_rate(a.chirp_rate), + rfi_checked(a.rfi_checked), + rfi_found(a.rfi_found), + reserved(a.reserved), + period(a.period), + snr(a.snr), + thresh(a.thresh), + score(a.score), + len_prof(a.len_prof), + pot(a.pot) { + db_open(); +} + + +pulse::pulse(const SQL_ROW &a) : + db_table(*this,-1) { + db_open(); + parse(a); +} + + +pulse::pulse(const std::string &s,const char *tag) : + db_table(*this,-1) { + db_open(); + if (xml_match_tag(s,tag)) { + parse_xml(s,tag); + } else { + parse(s); + } +} + + +pulse &pulse::operator =(const pulse &a) { + if (&a != this) { + id=a.id; + result_id=a.result_id; + peak_power=a.peak_power; + mean_power=a.mean_power; + time=a.time; + ra=a.ra; + decl=a.decl; + q_pix=a.q_pix; + freq=a.freq; + detection_freq=a.detection_freq; + barycentric_freq=a.barycentric_freq; + fft_len=a.fft_len; + chirp_rate=a.chirp_rate; + rfi_checked=a.rfi_checked; + rfi_found=a.rfi_found; + reserved=a.reserved; + period=a.period; + snr=a.snr; + thresh=a.thresh; + score=a.score; + len_prof=a.len_prof; + pot=a.pot; + } + return (*this); +} + + +std::string pulse::update_format() const { + std::ostringstream rv(""); + + for (int i=2; i<22; i++) { + rv << "?,"; + } + rv << "?"; + return rv.str(); +} + + +std::string pulse::insert_format() const { + return std::string("?,")+update_format(); +} + +std::string pulse::select_format() const { + std::string rv(""); + for (int i=0; i<21; i++) { + rv+="?,"; + } + rv+="?"; + return rv; +} + +std::string pulse::print(int full_subtables, int show_ids, int no_refs) const { + std::ostringstream rv(""); + + rv.precision(14); + if (show_ids) { + rv << id; + } + rv << ','; + if (!no_refs) { + if (full_subtables) { + rv << result_id.print(full_subtables,show_ids,no_refs); + } else { + rv << result_id.id; + } + } + rv << ','; + rv << peak_power; + rv << ','; + rv << mean_power; + rv << ','; + rv << time; + rv << ','; + rv << ra; + rv << ','; + rv << decl; + rv << ','; + rv << q_pix; + rv << ','; + rv << freq; + rv << ','; + rv << detection_freq; + rv << ','; + rv << barycentric_freq; + rv << ','; + rv << fft_len; + rv << ','; + rv << chirp_rate; + rv << ','; + rv << rfi_checked; + rv << ','; + rv << rfi_found; + rv << ','; + rv << reserved; + rv << ','; + rv << period; + rv << ','; + rv << snr; + rv << ','; + rv << thresh; + rv << ','; + rv << score; + rv << ','; + rv << len_prof; + rv << ','; + rv << "" << pot.print_hex() ; + return rv.str(); +} + + +std::string pulse::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { + std::ostringstream rv(""); + + rv.precision(14); + rv << xml_indent() << '<' << tag << ">\n"; + xml_indent(2); + if (show_ids) { + rv << xml_indent() << "" << id << "\n"; + } + if (!no_refs) { + if (full_subtables) { + rv << result_id.print_xml(full_subtables,show_ids,no_refs,"result_id"); + } else { + rv << xml_indent() << "" << result_id.id << "\n"; + } + } + rv << xml_indent() << "" << peak_power << "\n"; + rv << xml_indent() << "" << mean_power << "\n"; + rv << xml_indent() << "\n"; + rv << xml_indent() << "" << ra << "\n"; + rv << xml_indent() << "" << decl << "\n"; + rv << xml_indent() << "" << q_pix << "\n"; + rv << xml_indent() << "" << freq << "\n"; + rv << xml_indent() << "" << detection_freq << "\n"; + rv << xml_indent() << "" << barycentric_freq << "\n"; + rv << xml_indent() << "" << fft_len << "\n"; + rv << xml_indent() << "" << chirp_rate << "\n"; + rv << xml_indent() << "" << rfi_checked << "\n"; + rv << xml_indent() << "" << rfi_found << "\n"; + rv << xml_indent() << "" << reserved << "\n"; + rv << xml_indent() << "" << period << "\n"; + rv << xml_indent() << "" << snr << "\n"; + rv << xml_indent() << "" << thresh << "\n"; + rv << xml_indent() << "" << score << "\n"; + rv << xml_indent() << "" << len_prof << "\n"; + if (pot.size()) { + std::string enc_field=xml_encode_string(pot,pot.encoding); + rv << xml_indent() << ""; + rv << enc_field << "\n"; + } + xml_indent(-2); + rv << xml_indent() << "\n"; + return rv.str(); +} + + +void pulse::parse_xml(const std::string &s,const char *tag) { + std::string field,sub; + if (extract_xml_record(s,tag,field)) { + std::string::size_type pos=0; + if (extract_xml_record(field,"id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> id; + } + if (extract_xml_record(field,"result_id",sub)) { + result_id.parse_xml(sub,"result_id"); + } + if (extract_xml_record(field,"peak_power",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> peak_power; + } + if (extract_xml_record(field,"mean_power",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> mean_power; + } + if (extract_xml_record(field,"time",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> time; + } + if (extract_xml_record(field,"ra",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> ra; + } + if (extract_xml_record(field,"decl",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> decl; + } + if (extract_xml_record(field,"q_pix",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> q_pix; + } + if (extract_xml_record(field,"freq",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> freq; + } + if (extract_xml_record(field,"detection_freq",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> detection_freq; + } + if (extract_xml_record(field,"barycentric_freq",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> barycentric_freq; + } + if (extract_xml_record(field,"fft_len",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> fft_len; + } + if (extract_xml_record(field,"chirp_rate",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> chirp_rate; + } + if (extract_xml_record(field,"rfi_checked",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> rfi_checked; + } + if (extract_xml_record(field,"rfi_found",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> rfi_found; + } + if (extract_xml_record(field,"reserved",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> reserved; + } + if (extract_xml_record(field,"period",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> period; + } + if (extract_xml_record(field,"snr",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> snr; + } + if (extract_xml_record(field,"thresh",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> thresh; + } + if (extract_xml_record(field,"score",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> score; + } + if (extract_xml_record(field,"len_prof",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> len_prof; + } + if (extract_xml_record(field,"pot",sub)) { + std::istringstream in(sub.c_str()); + in >> pot; + } + } +} + +void pulse::parse(const SQL_ROW &s) { + { + std::istringstream row(*(s[0])); + row >> id; + } + { + result_id.parse(SQL_ROW(s[1],0)); + } + { + std::istringstream row(*(s[2])); + row >> peak_power; + } + { + std::istringstream row(*(s[3])); + row >> mean_power; + } + { + std::istringstream row(*(s[4])); + row >> time; + } + { + std::istringstream row(*(s[5])); + row >> ra; + } + { + std::istringstream row(*(s[6])); + row >> decl; + } + { + std::istringstream row(*(s[7])); + row >> q_pix; + } + { + std::istringstream row(*(s[8])); + row >> freq; + } + { + std::istringstream row(*(s[9])); + row >> detection_freq; + } + { + std::istringstream row(*(s[10])); + row >> barycentric_freq; + } + { + std::istringstream row(*(s[11])); + row >> fft_len; + } + { + std::istringstream row(*(s[12])); + row >> chirp_rate; + } + { + std::istringstream row(*(s[13])); + row >> rfi_checked; + } + { + std::istringstream row(*(s[14])); + row >> rfi_found; + } + { + std::istringstream row(*(s[15])); + row >> reserved; + } + { + std::istringstream row(*(s[16])); + row >> period; + } + { + std::istringstream row(*(s[17])); + row >> snr; + } + { + std::istringstream row(*(s[18])); + row >> thresh; + } + { + std::istringstream row(*(s[19])); + row >> score; + } + { + std::istringstream row(*(s[20])); + row >> len_prof; + } + { + pot=sqlblob(*(s[21])); + } +} + +void pulse::parse(const std::string &s) { + SQL_ROW row(&s,22); + parse(row); +} + +template <> const char *const db_table::table_name="pulse_small"; +template <> const char *db_table::_search_tag=table_name; +template <> const int db_table::_nfields=20; +template <> const char *const db_table::column_names[20]= {"id","result_id","peak_power","mean_power","time","ra","decl","q_pix","freq","detection_freq","barycentric_freq","fft_len","chirp_rate","rfi_checked","rfi_found","reserved","period","snr","thresh","score"}; + +pulse_small::pulse_small() : + db_table(*this,-1), + id(0), + result_id(), + peak_power(0), + mean_power(0), + time(0), + ra(0), + decl(0), + q_pix(0), + freq(0), + detection_freq(0), + barycentric_freq(0), + fft_len(0), + chirp_rate(0), + rfi_checked(0), + rfi_found(0), + reserved(0), + period(0), + snr(0), + thresh(0), + score(0) { + db_open(); +} + + +pulse_small::pulse_small(const pulse_small &a) : + db_table(*this,-1), + id(a.id), + result_id(a.result_id), + peak_power(a.peak_power), + mean_power(a.mean_power), + time(a.time), + ra(a.ra), + decl(a.decl), + q_pix(a.q_pix), + freq(a.freq), + detection_freq(a.detection_freq), + barycentric_freq(a.barycentric_freq), + fft_len(a.fft_len), + chirp_rate(a.chirp_rate), + rfi_checked(a.rfi_checked), + rfi_found(a.rfi_found), + reserved(a.reserved), + period(a.period), + snr(a.snr), + thresh(a.thresh), + score(a.score) { + db_open(); +} + + +pulse_small::pulse_small(const SQL_ROW &a) : + db_table(*this,-1) { + db_open(); + parse(a); +} + + +pulse_small::pulse_small(const std::string &s,const char *tag) : + db_table(*this,-1) { + db_open(); + if (xml_match_tag(s,tag)) { + parse_xml(s,tag); + } else { + parse(s); + } +} + + +pulse_small &pulse_small::operator =(const pulse_small &a) { + if (&a != this) { + id=a.id; + result_id=a.result_id; + peak_power=a.peak_power; + mean_power=a.mean_power; + time=a.time; + ra=a.ra; + decl=a.decl; + q_pix=a.q_pix; + freq=a.freq; + detection_freq=a.detection_freq; + barycentric_freq=a.barycentric_freq; + fft_len=a.fft_len; + chirp_rate=a.chirp_rate; + rfi_checked=a.rfi_checked; + rfi_found=a.rfi_found; + reserved=a.reserved; + period=a.period; + snr=a.snr; + thresh=a.thresh; + score=a.score; + } + return (*this); +} + + +std::string pulse_small::update_format() const { + std::ostringstream rv(""); + + for (int i=2; i<20; i++) { + rv << "?,"; + } + rv << "?"; + return rv.str(); +} + + +std::string pulse_small::insert_format() const { + return std::string("?,")+update_format(); +} + +std::string pulse_small::select_format() const { + std::string rv(""); + for (int i=0; i<19; i++) { + rv+="?,"; + } + rv+="?"; + return rv; +} + +std::string pulse_small::print(int full_subtables, int show_ids, int no_refs) const { + std::ostringstream rv(""); + + rv.precision(14); + if (show_ids) { + rv << id; + } + rv << ','; + if (!no_refs) { + if (full_subtables) { + rv << result_id.print(full_subtables,show_ids,no_refs); + } else { + rv << result_id.id; + } + } + rv << ','; + rv << peak_power; + rv << ','; + rv << mean_power; + rv << ','; + rv << time; + rv << ','; + rv << ra; + rv << ','; + rv << decl; + rv << ','; + rv << q_pix; + rv << ','; + rv << freq; + rv << ','; + rv << detection_freq; + rv << ','; + rv << barycentric_freq; + rv << ','; + rv << fft_len; + rv << ','; + rv << chirp_rate; + rv << ','; + rv << rfi_checked; + rv << ','; + rv << rfi_found; + rv << ','; + rv << reserved; + rv << ','; + rv << period; + rv << ','; + rv << snr; + rv << ','; + rv << thresh; + rv << ','; + rv << score; + return rv.str(); +} + + +std::string pulse_small::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { + std::ostringstream rv(""); + + rv.precision(14); + rv << xml_indent() << '<' << tag << ">\n"; + xml_indent(2); + if (show_ids) { + rv << xml_indent() << "" << id << "\n"; + } + if (!no_refs) { + if (full_subtables) { + rv << result_id.print_xml(full_subtables,show_ids,no_refs,"result_id"); + } else { + rv << xml_indent() << "" << result_id.id << "\n"; + } + } + rv << xml_indent() << "" << peak_power << "\n"; + rv << xml_indent() << "" << mean_power << "\n"; + rv << xml_indent() << "\n"; + rv << xml_indent() << "" << ra << "\n"; + rv << xml_indent() << "" << decl << "\n"; + rv << xml_indent() << "" << q_pix << "\n"; + rv << xml_indent() << "" << freq << "\n"; + rv << xml_indent() << "" << detection_freq << "\n"; + rv << xml_indent() << "" << barycentric_freq << "\n"; + rv << xml_indent() << "" << fft_len << "\n"; + rv << xml_indent() << "" << chirp_rate << "\n"; + rv << xml_indent() << "" << rfi_checked << "\n"; + rv << xml_indent() << "" << rfi_found << "\n"; + rv << xml_indent() << "" << reserved << "\n"; + rv << xml_indent() << "" << period << "\n"; + rv << xml_indent() << "" << snr << "\n"; + rv << xml_indent() << "" << thresh << "\n"; + rv << xml_indent() << "" << score << "\n"; + xml_indent(-2); + rv << xml_indent() << "\n"; + return rv.str(); +} + + +void pulse_small::parse_xml(const std::string &s,const char *tag) { + std::string field,sub; + if (extract_xml_record(s,tag,field)) { + std::string::size_type pos=0; + if (extract_xml_record(field,"id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> id; + } + if (extract_xml_record(field,"result_id",sub)) { + result_id.parse_xml(sub,"result_id"); + } + if (extract_xml_record(field,"peak_power",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> peak_power; + } + if (extract_xml_record(field,"mean_power",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> mean_power; + } + if (extract_xml_record(field,"time",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> time; + } + if (extract_xml_record(field,"ra",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> ra; + } + if (extract_xml_record(field,"decl",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> decl; + } + if (extract_xml_record(field,"q_pix",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> q_pix; + } + if (extract_xml_record(field,"freq",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> freq; + } + if (extract_xml_record(field,"detection_freq",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> detection_freq; + } + if (extract_xml_record(field,"barycentric_freq",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> barycentric_freq; + } + if (extract_xml_record(field,"fft_len",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> fft_len; + } + if (extract_xml_record(field,"chirp_rate",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> chirp_rate; + } + if (extract_xml_record(field,"rfi_checked",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> rfi_checked; + } + if (extract_xml_record(field,"rfi_found",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> rfi_found; + } + if (extract_xml_record(field,"reserved",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> reserved; + } + if (extract_xml_record(field,"period",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> period; + } + if (extract_xml_record(field,"snr",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> snr; + } + if (extract_xml_record(field,"thresh",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> thresh; + } + if (extract_xml_record(field,"score",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> score; + } + } +} + +void pulse_small::parse(const SQL_ROW &s) { + { + std::istringstream row(*(s[0])); + row >> id; + } + { + result_id.parse(SQL_ROW(s[1],0)); + } + { + std::istringstream row(*(s[2])); + row >> peak_power; + } + { + std::istringstream row(*(s[3])); + row >> mean_power; + } + { + std::istringstream row(*(s[4])); + row >> time; + } + { + std::istringstream row(*(s[5])); + row >> ra; + } + { + std::istringstream row(*(s[6])); + row >> decl; + } + { + std::istringstream row(*(s[7])); + row >> q_pix; + } + { + std::istringstream row(*(s[8])); + row >> freq; + } + { + std::istringstream row(*(s[9])); + row >> detection_freq; + } + { + std::istringstream row(*(s[10])); + row >> barycentric_freq; + } + { + std::istringstream row(*(s[11])); + row >> fft_len; + } + { + std::istringstream row(*(s[12])); + row >> chirp_rate; + } + { + std::istringstream row(*(s[13])); + row >> rfi_checked; + } + { + std::istringstream row(*(s[14])); + row >> rfi_found; + } + { + std::istringstream row(*(s[15])); + row >> reserved; + } + { + std::istringstream row(*(s[16])); + row >> period; + } + { + std::istringstream row(*(s[17])); + row >> snr; + } + { + std::istringstream row(*(s[18])); + row >> thresh; + } + { + std::istringstream row(*(s[19])); + row >> score; + } +} + +void pulse_small::parse(const std::string &s) { + SQL_ROW row(&s,20); + parse(row); +} + +template <> const char *const db_table::table_name="sah_pointing"; +template <> const char *db_table::_search_tag=table_name; +template <> const int db_table::_nfields=7; +template <> const char *const db_table::column_names[7]= {"time_id","time","ra","dec","q_pix","angle_range","bad"}; + +sah_pointing::sah_pointing() : + db_table(*this,-1), + time_id(0), + time(0), + ra(0), + dec(0), + q_pix(0), + angle_range(0), + bad(0) { + db_open(); +} + + +sah_pointing::sah_pointing(const sah_pointing &a) : + db_table(*this,-1), + time_id(a.time_id), + time(a.time), + ra(a.ra), + dec(a.dec), + q_pix(a.q_pix), + angle_range(a.angle_range), + bad(a.bad) { + db_open(); +} + + +sah_pointing::sah_pointing(const SQL_ROW &a) : + db_table(*this,-1) { + db_open(); + parse(a); +} + + +sah_pointing::sah_pointing(const std::string &s,const char *tag) : + db_table(*this,-1) { + db_open(); + if (xml_match_tag(s,tag)) { + parse_xml(s,tag); + } else { + parse(s); + } +} + + +sah_pointing &sah_pointing::operator =(const sah_pointing &a) { + if (&a != this) { + time_id=a.time_id; + time=a.time; + ra=a.ra; + dec=a.dec; + q_pix=a.q_pix; + angle_range=a.angle_range; + bad=a.bad; + } + return (*this); +} + + +std::string sah_pointing::update_format() const { + std::ostringstream rv(""); + + for (int i=2; i<7; i++) { + rv << "?,"; + } + rv << "?"; + return rv.str(); +} + + +std::string sah_pointing::insert_format() const { + return std::string("?,")+update_format(); +} + +std::string sah_pointing::select_format() const { + std::string rv(""); + for (int i=0; i<6; i++) { + rv+="?,"; + } + rv+="?"; + return rv; +} + +std::string sah_pointing::print(int full_subtables, int show_ids, int no_refs) const { + std::ostringstream rv(""); + + rv.precision(14); + if (show_ids) { + rv << time_id; + } + rv << ','; + rv << time; + rv << ','; + rv << ra; + rv << ','; + rv << dec; + rv << ','; + rv << q_pix; + rv << ','; + rv << angle_range; + rv << ','; + rv << bad; + return rv.str(); +} + + +std::string sah_pointing::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { + std::ostringstream rv(""); + + rv.precision(14); + rv << xml_indent() << '<' << tag << ">\n"; + xml_indent(2); + if (show_ids) { + rv << xml_indent() << "" << time_id << "\n"; + } + rv << xml_indent() << "\n"; + rv << xml_indent() << "" << ra << "\n"; + rv << xml_indent() << "" << dec << "\n"; + rv << xml_indent() << "" << q_pix << "\n"; + rv << xml_indent() << "" << angle_range << "\n"; + rv << xml_indent() << "" << bad << "\n"; + xml_indent(-2); + rv << xml_indent() << "\n"; + return rv.str(); +} + + +void sah_pointing::parse_xml(const std::string &s,const char *tag) { + std::string field,sub; + if (extract_xml_record(s,tag,field)) { + std::string::size_type pos=0; + if (extract_xml_record(field,"time_id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> time_id; + } + if (extract_xml_record(field,"time",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> time; + } + if (extract_xml_record(field,"ra",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> ra; + } + if (extract_xml_record(field,"dec",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> dec; + } + if (extract_xml_record(field,"q_pix",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> q_pix; + } + if (extract_xml_record(field,"angle_range",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> angle_range; + } + if (extract_xml_record(field,"bad",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> bad; + } + } +} + +void sah_pointing::parse(const SQL_ROW &s) { + { + std::istringstream row(*(s[0])); + row >> time_id; + } + { + std::istringstream row(*(s[1])); + row >> time; + } + { + std::istringstream row(*(s[2])); + row >> ra; + } + { + std::istringstream row(*(s[3])); + row >> dec; + } + { + std::istringstream row(*(s[4])); + row >> q_pix; + } + { + std::istringstream row(*(s[5])); + row >> angle_range; + } + { + std::istringstream row(*(s[6])); + row >> bad; + } +} + +void sah_pointing::parse(const std::string &s) { + SQL_ROW row(&s,7); + parse(row); +} + +template <> const char *const db_table::table_name="sky_map"; +template <> const char *db_table::_search_tag=table_name; +template <> const int db_table::_nfields=13; +template <> const char *const db_table::column_names[13]= {"npix","qpix","fpix","spike_max_id","gaussian_max_id","pulse_max_id","triplet_max_id","spike_count","gaussian_count","pulse_count","triplet_count","new_data","score"}; + +sky_map::sky_map() : + db_table(*this,-1), + npix(0), + qpix(0), + fpix(0), + spike_max_id(0), + gaussian_max_id(0), + pulse_max_id(0), + triplet_max_id(0), + spike_count(0), + gaussian_count(0), + pulse_count(0), + triplet_count(0), + new_data(0), + score(0) { + db_open(); +} + + +sky_map::sky_map(const sky_map &a) : + db_table(*this,-1), + npix(a.npix), + qpix(a.qpix), + fpix(a.fpix), + spike_max_id(a.spike_max_id), + gaussian_max_id(a.gaussian_max_id), + pulse_max_id(a.pulse_max_id), + triplet_max_id(a.triplet_max_id), + spike_count(a.spike_count), + gaussian_count(a.gaussian_count), + pulse_count(a.pulse_count), + triplet_count(a.triplet_count), + new_data(a.new_data), + score(a.score) { + db_open(); +} + + +sky_map::sky_map(const SQL_ROW &a) : + db_table(*this,-1) { + db_open(); + parse(a); +} + + +sky_map::sky_map(const std::string &s,const char *tag) : + db_table(*this,-1) { + db_open(); + if (xml_match_tag(s,tag)) { + parse_xml(s,tag); + } else { + parse(s); + } +} + + +sky_map &sky_map::operator =(const sky_map &a) { + if (&a != this) { + npix=a.npix; + qpix=a.qpix; + fpix=a.fpix; + spike_max_id=a.spike_max_id; + gaussian_max_id=a.gaussian_max_id; + pulse_max_id=a.pulse_max_id; + triplet_max_id=a.triplet_max_id; + spike_count=a.spike_count; + gaussian_count=a.gaussian_count; + pulse_count=a.pulse_count; + triplet_count=a.triplet_count; + new_data=a.new_data; + score=a.score; + } + return (*this); +} + + +std::string sky_map::update_format() const { + std::ostringstream rv(""); + + for (int i=2; i<13; i++) { + rv << "?,"; + } + rv << "?"; + return rv.str(); +} + + +std::string sky_map::insert_format() const { + return std::string("?,")+update_format(); +} + +std::string sky_map::select_format() const { + std::string rv(""); + for (int i=0; i<12; i++) { + rv+="?,"; + } + rv+="?"; + return rv; +} + +std::string sky_map::print(int full_subtables, int show_ids, int no_refs) const { + std::ostringstream rv(""); + + rv.precision(14); + if (show_ids) { + rv << npix; + } + rv << ','; + rv << qpix; + rv << ','; + rv << fpix; + rv << ','; + rv << spike_max_id; + rv << ','; + rv << gaussian_max_id; + rv << ','; + rv << pulse_max_id; + rv << ','; + rv << triplet_max_id; + rv << ','; + rv << spike_count; + rv << ','; + rv << gaussian_count; + rv << ','; + rv << pulse_count; + rv << ','; + rv << triplet_count; + rv << ','; + rv << new_data; + rv << ','; + rv << score; + return rv.str(); +} + + +std::string sky_map::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { + std::ostringstream rv(""); + + rv.precision(14); + rv << xml_indent() << '<' << tag << ">\n"; + xml_indent(2); + if (show_ids) { + rv << xml_indent() << "" << npix << "\n"; + } + rv << xml_indent() << "" << qpix << "\n"; + rv << xml_indent() << "" << fpix << "\n"; + rv << xml_indent() << "" << spike_max_id << "\n"; + rv << xml_indent() << "" << gaussian_max_id << "\n"; + rv << xml_indent() << "" << pulse_max_id << "\n"; + rv << xml_indent() << "" << triplet_max_id << "\n"; + rv << xml_indent() << "" << spike_count << "\n"; + rv << xml_indent() << "" << gaussian_count << "\n"; + rv << xml_indent() << "" << pulse_count << "\n"; + rv << xml_indent() << "" << triplet_count << "\n"; + rv << xml_indent() << "" << new_data << "\n"; + rv << xml_indent() << "" << score << "\n"; + xml_indent(-2); + rv << xml_indent() << "\n"; + return rv.str(); +} + + +void sky_map::parse_xml(const std::string &s,const char *tag) { + std::string field,sub; + if (extract_xml_record(s,tag,field)) { + std::string::size_type pos=0; + if (extract_xml_record(field,"npix",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> npix; + } + if (extract_xml_record(field,"qpix",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> qpix; + } + if (extract_xml_record(field,"fpix",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> fpix; + } + if (extract_xml_record(field,"spike_max_id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> spike_max_id; + } + if (extract_xml_record(field,"gaussian_max_id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> gaussian_max_id; + } + if (extract_xml_record(field,"pulse_max_id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> pulse_max_id; + } + if (extract_xml_record(field,"triplet_max_id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> triplet_max_id; + } + if (extract_xml_record(field,"spike_count",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> spike_count; + } + if (extract_xml_record(field,"gaussian_count",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> gaussian_count; + } + if (extract_xml_record(field,"pulse_count",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> pulse_count; + } + if (extract_xml_record(field,"triplet_count",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> triplet_count; + } + if (extract_xml_record(field,"new_data",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> new_data; + } + if (extract_xml_record(field,"score",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> score; + } + } +} + +void sky_map::parse(const SQL_ROW &s) { + { + std::istringstream row(*(s[0])); + row >> npix; + } + { + std::istringstream row(*(s[1])); + row >> qpix; + } + { + std::istringstream row(*(s[2])); + row >> fpix; + } + { + std::istringstream row(*(s[3])); + row >> spike_max_id; + } + { + std::istringstream row(*(s[4])); + row >> gaussian_max_id; + } + { + std::istringstream row(*(s[5])); + row >> pulse_max_id; + } + { + std::istringstream row(*(s[6])); + row >> triplet_max_id; + } + { + std::istringstream row(*(s[7])); + row >> spike_count; + } + { + std::istringstream row(*(s[8])); + row >> gaussian_count; + } + { + std::istringstream row(*(s[9])); + row >> pulse_count; + } + { + std::istringstream row(*(s[10])); + row >> triplet_count; + } + { + std::istringstream row(*(s[11])); + row >> new_data; + } + { + std::istringstream row(*(s[12])); + row >> score; + } +} + +void sky_map::parse(const std::string &s) { + SQL_ROW row(&s,13); + parse(row); +} + +template <> const char *const db_table::table_name="hotpix"; +template <> const char *db_table::_search_tag=table_name; +template <> const int db_table::_nfields=2; +template <> const char *const db_table::column_names[2]= {"id","last_hit_time"}; + +hotpix::hotpix() : + db_table(*this,-1), + id(0), + last_hit_time(0) { + db_open(); +} + + +hotpix::hotpix(const hotpix &a) : + db_table(*this,-1), + id(a.id), + last_hit_time(a.last_hit_time) { + db_open(); +} + + +hotpix::hotpix(const SQL_ROW &a) : + db_table(*this,-1) { + db_open(); + parse(a); +} + + +hotpix::hotpix(const std::string &s,const char *tag) : + db_table(*this,-1) { + db_open(); + if (xml_match_tag(s,tag)) { + parse_xml(s,tag); + } else { + parse(s); + } +} + + +hotpix &hotpix::operator =(const hotpix &a) { + if (&a != this) { + id=a.id; + last_hit_time=a.last_hit_time; + } + return (*this); +} + + +std::string hotpix::update_format() const { + std::ostringstream rv(""); + + for (int i=2; i<2; i++) { + rv << "?,"; + } + rv << "?"; + return rv.str(); +} + + +std::string hotpix::insert_format() const { + return std::string("?,")+update_format(); +} + +std::string hotpix::select_format() const { + std::string rv(""); + for (int i=0; i<1; i++) { + rv+="?,"; + } + rv+="?"; + return rv; +} + +std::string hotpix::print(int full_subtables, int show_ids, int no_refs) const { + std::ostringstream rv(""); + + rv.precision(14); + if (show_ids) { + rv << id; + } + rv << ','; + rv << last_hit_time; + return rv.str(); +} + + +std::string hotpix::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { + std::ostringstream rv(""); + + rv.precision(14); + rv << xml_indent() << '<' << tag << ">\n"; + xml_indent(2); + if (show_ids) { + rv << xml_indent() << "" << id << "\n"; + } + rv << xml_indent() << "" << last_hit_time << "\n"; + xml_indent(-2); + rv << xml_indent() << "\n"; + return rv.str(); +} + + +void hotpix::parse_xml(const std::string &s,const char *tag) { + std::string field,sub; + if (extract_xml_record(s,tag,field)) { + std::string::size_type pos=0; + if (extract_xml_record(field,"id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> id; + } + if (extract_xml_record(field,"last_hit_time",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> last_hit_time; + } + } +} + +void hotpix::parse(const SQL_ROW &s) { + { + std::istringstream row(*(s[0])); + row >> id; + } + { + std::istringstream row(*(s[1])); + row >> last_hit_time; + } +} + +void hotpix::parse(const std::string &s) { + SQL_ROW row(&s,2); + parse(row); +} + +template <> const char *const db_table::table_name="spike"; +template <> const char *db_table::_search_tag=table_name; +template <> const int db_table::_nfields=16; +template <> const char *const db_table::column_names[16]= {"id","result_id","peak_power","mean_power","time","ra","decl","q_pix","freq","detection_freq","barycentric_freq","fft_len","chirp_rate","rfi_checked","rfi_found","reserved"}; + +spike::spike() : + db_table(*this,-1), + id(0), + result_id(), + peak_power(0), + mean_power(0), + time(0), + ra(0), + decl(0), + q_pix(0), + freq(0), + detection_freq(0), + barycentric_freq(0), + fft_len(0), + chirp_rate(0), + rfi_checked(0), + rfi_found(0), + reserved(0) { + db_open(); +} + + +spike::spike(const spike &a) : + db_table(*this,-1), + id(a.id), + result_id(a.result_id), + peak_power(a.peak_power), + mean_power(a.mean_power), + time(a.time), + ra(a.ra), + decl(a.decl), + q_pix(a.q_pix), + freq(a.freq), + detection_freq(a.detection_freq), + barycentric_freq(a.barycentric_freq), + fft_len(a.fft_len), + chirp_rate(a.chirp_rate), + rfi_checked(a.rfi_checked), + rfi_found(a.rfi_found), + reserved(a.reserved) { + db_open(); +} + + +spike::spike(const SQL_ROW &a) : + db_table(*this,-1) { + db_open(); + parse(a); +} + + +spike::spike(const std::string &s,const char *tag) : + db_table(*this,-1) { + db_open(); + if (xml_match_tag(s,tag)) { + parse_xml(s,tag); + } else { + parse(s); + } +} + + +spike &spike::operator =(const spike &a) { + if (&a != this) { + id=a.id; + result_id=a.result_id; + peak_power=a.peak_power; + mean_power=a.mean_power; + time=a.time; + ra=a.ra; + decl=a.decl; + q_pix=a.q_pix; + freq=a.freq; + detection_freq=a.detection_freq; + barycentric_freq=a.barycentric_freq; + fft_len=a.fft_len; + chirp_rate=a.chirp_rate; + rfi_checked=a.rfi_checked; + rfi_found=a.rfi_found; + reserved=a.reserved; + } + return (*this); +} + + +std::string spike::update_format() const { + std::ostringstream rv(""); + + for (int i=2; i<16; i++) { + rv << "?,"; + } + rv << "?"; + return rv.str(); +} + + +std::string spike::insert_format() const { + return std::string("?,")+update_format(); +} + +std::string spike::select_format() const { + std::string rv(""); + for (int i=0; i<15; i++) { + rv+="?,"; + } + rv+="?"; + return rv; +} + +std::string spike::print(int full_subtables, int show_ids, int no_refs) const { + std::ostringstream rv(""); + + rv.precision(14); + if (show_ids) { + rv << id; + } + rv << ','; + if (!no_refs) { + if (full_subtables) { + rv << result_id.print(full_subtables,show_ids,no_refs); + } else { + rv << result_id.id; + } + } + rv << ','; + rv << peak_power; + rv << ','; + rv << mean_power; + rv << ','; + rv << time; + rv << ','; + rv << ra; + rv << ','; + rv << decl; + rv << ','; + rv << q_pix; + rv << ','; + rv << freq; + rv << ','; + rv << detection_freq; + rv << ','; + rv << barycentric_freq; + rv << ','; + rv << fft_len; + rv << ','; + rv << chirp_rate; + rv << ','; + rv << rfi_checked; + rv << ','; + rv << rfi_found; + rv << ','; + rv << reserved; + return rv.str(); +} + + +std::string spike::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { + std::ostringstream rv(""); + + rv.precision(14); + rv << xml_indent() << '<' << tag << ">\n"; + xml_indent(2); + if (show_ids) { + rv << xml_indent() << "" << id << "\n"; + } + if (!no_refs) { + if (full_subtables) { + rv << result_id.print_xml(full_subtables,show_ids,no_refs,"result_id"); + } else { + rv << xml_indent() << "" << result_id.id << "\n"; + } + } + rv << xml_indent() << "" << peak_power << "\n"; + rv << xml_indent() << "" << mean_power << "\n"; + rv << xml_indent() << "\n"; + rv << xml_indent() << "" << ra << "\n"; + rv << xml_indent() << "" << decl << "\n"; + rv << xml_indent() << "" << q_pix << "\n"; + rv << xml_indent() << "" << freq << "\n"; + rv << xml_indent() << "" << detection_freq << "\n"; + rv << xml_indent() << "" << barycentric_freq << "\n"; + rv << xml_indent() << "" << fft_len << "\n"; + rv << xml_indent() << "" << chirp_rate << "\n"; + rv << xml_indent() << "" << rfi_checked << "\n"; + rv << xml_indent() << "" << rfi_found << "\n"; + rv << xml_indent() << "" << reserved << "\n"; + xml_indent(-2); + rv << xml_indent() << "\n"; + return rv.str(); +} + + +void spike::parse_xml(const std::string &s,const char *tag) { + std::string field,sub; + if (extract_xml_record(s,tag,field)) { + std::string::size_type pos=0; + if (extract_xml_record(field,"id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> id; + } + if (extract_xml_record(field,"result_id",sub)) { + result_id.parse_xml(sub,"result_id"); + } + if (extract_xml_record(field,"peak_power",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> peak_power; + } + if (extract_xml_record(field,"mean_power",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> mean_power; + } + if (extract_xml_record(field,"time",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> time; + } + if (extract_xml_record(field,"ra",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> ra; + } + if (extract_xml_record(field,"decl",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> decl; + } + if (extract_xml_record(field,"q_pix",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> q_pix; + } + if (extract_xml_record(field,"freq",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> freq; + } + if (extract_xml_record(field,"detection_freq",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> detection_freq; + } + if (extract_xml_record(field,"barycentric_freq",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> barycentric_freq; + } + if (extract_xml_record(field,"fft_len",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> fft_len; + } + if (extract_xml_record(field,"chirp_rate",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> chirp_rate; + } + if (extract_xml_record(field,"rfi_checked",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> rfi_checked; + } + if (extract_xml_record(field,"rfi_found",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> rfi_found; + } + if (extract_xml_record(field,"reserved",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> reserved; + } + } +} + +void spike::parse(const SQL_ROW &s) { + { + std::istringstream row(*(s[0])); + row >> id; + } + { + result_id.parse(SQL_ROW(s[1],0)); + } + { + std::istringstream row(*(s[2])); + row >> peak_power; + } + { + std::istringstream row(*(s[3])); + row >> mean_power; + } + { + std::istringstream row(*(s[4])); + row >> time; + } + { + std::istringstream row(*(s[5])); + row >> ra; + } + { + std::istringstream row(*(s[6])); + row >> decl; + } + { + std::istringstream row(*(s[7])); + row >> q_pix; + } + { + std::istringstream row(*(s[8])); + row >> freq; + } + { + std::istringstream row(*(s[9])); + row >> detection_freq; + } + { + std::istringstream row(*(s[10])); + row >> barycentric_freq; + } + { + std::istringstream row(*(s[11])); + row >> fft_len; + } + { + std::istringstream row(*(s[12])); + row >> chirp_rate; + } + { + std::istringstream row(*(s[13])); + row >> rfi_checked; + } + { + std::istringstream row(*(s[14])); + row >> rfi_found; + } + { + std::istringstream row(*(s[15])); + row >> reserved; + } +} + +void spike::parse(const std::string &s) { + SQL_ROW row(&s,16); + parse(row); +} + +template <> const char *const db_table::table_name="spike_small"; +template <> const char *db_table::_search_tag=table_name; +template <> const int db_table::_nfields=16; +template <> const char *const db_table::column_names[16]= {"id","result_id","peak_power","mean_power","time","ra","decl","q_pix","freq","detection_freq","barycentric_freq","fft_len","chirp_rate","rfi_checked","rfi_found","reserved"}; + +spike_small::spike_small() : + db_table(*this,-1), + id(0), + result_id(), + peak_power(0), + mean_power(0), + time(0), + ra(0), + decl(0), + q_pix(0), + freq(0), + detection_freq(0), + barycentric_freq(0), + fft_len(0), + chirp_rate(0), + rfi_checked(0), + rfi_found(0), + reserved(0) { + db_open(); +} + + +spike_small::spike_small(const spike_small &a) : + db_table(*this,-1), + id(a.id), + result_id(a.result_id), + peak_power(a.peak_power), + mean_power(a.mean_power), + time(a.time), + ra(a.ra), + decl(a.decl), + q_pix(a.q_pix), + freq(a.freq), + detection_freq(a.detection_freq), + barycentric_freq(a.barycentric_freq), + fft_len(a.fft_len), + chirp_rate(a.chirp_rate), + rfi_checked(a.rfi_checked), + rfi_found(a.rfi_found), + reserved(a.reserved) { + db_open(); +} + + +spike_small::spike_small(const SQL_ROW &a) : + db_table(*this,-1) { + db_open(); + parse(a); +} + + +spike_small::spike_small(const std::string &s,const char *tag) : + db_table(*this,-1) { + db_open(); + if (xml_match_tag(s,tag)) { + parse_xml(s,tag); + } else { + parse(s); + } +} + + +spike_small &spike_small::operator =(const spike_small &a) { + if (&a != this) { + id=a.id; + result_id=a.result_id; + peak_power=a.peak_power; + mean_power=a.mean_power; + time=a.time; + ra=a.ra; + decl=a.decl; + q_pix=a.q_pix; + freq=a.freq; + detection_freq=a.detection_freq; + barycentric_freq=a.barycentric_freq; + fft_len=a.fft_len; + chirp_rate=a.chirp_rate; + rfi_checked=a.rfi_checked; + rfi_found=a.rfi_found; + reserved=a.reserved; + } + return (*this); +} + + +std::string spike_small::update_format() const { + std::ostringstream rv(""); + + for (int i=2; i<16; i++) { + rv << "?,"; + } + rv << "?"; + return rv.str(); +} + + +std::string spike_small::insert_format() const { + return std::string("?,")+update_format(); +} + +std::string spike_small::select_format() const { + std::string rv(""); + for (int i=0; i<15; i++) { + rv+="?,"; + } + rv+="?"; + return rv; +} + +std::string spike_small::print(int full_subtables, int show_ids, int no_refs) const { + std::ostringstream rv(""); + + rv.precision(14); + if (show_ids) { + rv << id; + } + rv << ','; + if (!no_refs) { + if (full_subtables) { + rv << result_id.print(full_subtables,show_ids,no_refs); + } else { + rv << result_id.id; + } + } + rv << ','; + rv << peak_power; + rv << ','; + rv << mean_power; + rv << ','; + rv << time; + rv << ','; + rv << ra; + rv << ','; + rv << decl; + rv << ','; + rv << q_pix; + rv << ','; + rv << freq; + rv << ','; + rv << detection_freq; + rv << ','; + rv << barycentric_freq; + rv << ','; + rv << fft_len; + rv << ','; + rv << chirp_rate; + rv << ','; + rv << rfi_checked; + rv << ','; + rv << rfi_found; + rv << ','; + rv << reserved; + return rv.str(); +} + + +std::string spike_small::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { + std::ostringstream rv(""); + + rv.precision(14); + rv << xml_indent() << '<' << tag << ">\n"; + xml_indent(2); + if (show_ids) { + rv << xml_indent() << "" << id << "\n"; + } + if (!no_refs) { + if (full_subtables) { + rv << result_id.print_xml(full_subtables,show_ids,no_refs,"result_id"); + } else { + rv << xml_indent() << "" << result_id.id << "\n"; + } + } + rv << xml_indent() << "" << peak_power << "\n"; + rv << xml_indent() << "" << mean_power << "\n"; + rv << xml_indent() << "\n"; + rv << xml_indent() << "" << ra << "\n"; + rv << xml_indent() << "" << decl << "\n"; + rv << xml_indent() << "" << q_pix << "\n"; + rv << xml_indent() << "" << freq << "\n"; + rv << xml_indent() << "" << detection_freq << "\n"; + rv << xml_indent() << "" << barycentric_freq << "\n"; + rv << xml_indent() << "" << fft_len << "\n"; + rv << xml_indent() << "" << chirp_rate << "\n"; + rv << xml_indent() << "" << rfi_checked << "\n"; + rv << xml_indent() << "" << rfi_found << "\n"; + rv << xml_indent() << "" << reserved << "\n"; + xml_indent(-2); + rv << xml_indent() << "\n"; + return rv.str(); +} + + +void spike_small::parse_xml(const std::string &s,const char *tag) { + std::string field,sub; + if (extract_xml_record(s,tag,field)) { + std::string::size_type pos=0; + if (extract_xml_record(field,"id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> id; + } + if (extract_xml_record(field,"result_id",sub)) { + result_id.parse_xml(sub,"result_id"); + } + if (extract_xml_record(field,"peak_power",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> peak_power; + } + if (extract_xml_record(field,"mean_power",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> mean_power; + } + if (extract_xml_record(field,"time",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> time; + } + if (extract_xml_record(field,"ra",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> ra; + } + if (extract_xml_record(field,"decl",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> decl; + } + if (extract_xml_record(field,"q_pix",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> q_pix; + } + if (extract_xml_record(field,"freq",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> freq; + } + if (extract_xml_record(field,"detection_freq",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> detection_freq; + } + if (extract_xml_record(field,"barycentric_freq",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> barycentric_freq; + } + if (extract_xml_record(field,"fft_len",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> fft_len; + } + if (extract_xml_record(field,"chirp_rate",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> chirp_rate; + } + if (extract_xml_record(field,"rfi_checked",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> rfi_checked; + } + if (extract_xml_record(field,"rfi_found",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> rfi_found; + } + if (extract_xml_record(field,"reserved",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> reserved; + } + } +} + +void spike_small::parse(const SQL_ROW &s) { + { + std::istringstream row(*(s[0])); + row >> id; + } + { + result_id.parse(SQL_ROW(s[1],0)); + } + { + std::istringstream row(*(s[2])); + row >> peak_power; + } + { + std::istringstream row(*(s[3])); + row >> mean_power; + } + { + std::istringstream row(*(s[4])); + row >> time; + } + { + std::istringstream row(*(s[5])); + row >> ra; + } + { + std::istringstream row(*(s[6])); + row >> decl; + } + { + std::istringstream row(*(s[7])); + row >> q_pix; + } + { + std::istringstream row(*(s[8])); + row >> freq; + } + { + std::istringstream row(*(s[9])); + row >> detection_freq; + } + { + std::istringstream row(*(s[10])); + row >> barycentric_freq; + } + { + std::istringstream row(*(s[11])); + row >> fft_len; + } + { + std::istringstream row(*(s[12])); + row >> chirp_rate; + } + { + std::istringstream row(*(s[13])); + row >> rfi_checked; + } + { + std::istringstream row(*(s[14])); + row >> rfi_found; + } + { + std::istringstream row(*(s[15])); + row >> reserved; + } +} + +void spike_small::parse(const std::string &s) { + SQL_ROW row(&s,16); + parse(row); +} + +template <> const char *const db_table::table_name="autocorr"; +template <> const char *db_table::_search_tag=table_name; +template <> const int db_table::_nfields=17; +template <> const char *const db_table::column_names[17]= {"id","result_id","peak_power","mean_power","time","ra","decl","q_pix","delay","freq","detection_freq","barycentric_freq","fft_len","chirp_rate","rfi_checked","rfi_found","reserved"}; + +autocorr::autocorr() : + db_table(*this,-1), + id(0), + result_id(), + peak_power(0), + mean_power(0), + time(0), + ra(0), + decl(0), + q_pix(0), + delay(0), + freq(0), + detection_freq(0), + barycentric_freq(0), + fft_len(0), + chirp_rate(0), + rfi_checked(0), + rfi_found(0), + reserved(0) { + db_open(); +} + + +autocorr::autocorr(const autocorr &a) : + db_table(*this,-1), + id(a.id), + result_id(a.result_id), + peak_power(a.peak_power), + mean_power(a.mean_power), + time(a.time), + ra(a.ra), + decl(a.decl), + q_pix(a.q_pix), + delay(a.delay), + freq(a.freq), + detection_freq(a.detection_freq), + barycentric_freq(a.barycentric_freq), + fft_len(a.fft_len), + chirp_rate(a.chirp_rate), + rfi_checked(a.rfi_checked), + rfi_found(a.rfi_found), + reserved(a.reserved) { + db_open(); +} + + +autocorr::autocorr(const SQL_ROW &a) : + db_table(*this,-1) { + db_open(); + parse(a); +} + + +autocorr::autocorr(const std::string &s,const char *tag) : + db_table(*this,-1) { + db_open(); + if (xml_match_tag(s,tag)) { + parse_xml(s,tag); + } else { + parse(s); + } +} + + +autocorr &autocorr::operator =(const autocorr &a) { + if (&a != this) { + id=a.id; + result_id=a.result_id; + peak_power=a.peak_power; + mean_power=a.mean_power; + time=a.time; + ra=a.ra; + decl=a.decl; + q_pix=a.q_pix; + delay=a.delay; + freq=a.freq; + detection_freq=a.detection_freq; + barycentric_freq=a.barycentric_freq; + fft_len=a.fft_len; + chirp_rate=a.chirp_rate; + rfi_checked=a.rfi_checked; + rfi_found=a.rfi_found; + reserved=a.reserved; + } + return (*this); +} + + +std::string autocorr::update_format() const { + std::ostringstream rv(""); + + for (int i=2; i<17; i++) { + rv << "?,"; + } + rv << "?"; + return rv.str(); +} + + +std::string autocorr::insert_format() const { + return std::string("?,")+update_format(); +} + +std::string autocorr::select_format() const { + std::string rv(""); + for (int i=0; i<16; i++) { + rv+="?,"; + } + rv+="?"; + return rv; +} + +std::string autocorr::print(int full_subtables, int show_ids, int no_refs) const { + std::ostringstream rv(""); + + rv.precision(14); + if (show_ids) { + rv << id; + } + rv << ','; + if (!no_refs) { + if (full_subtables) { + rv << result_id.print(full_subtables,show_ids,no_refs); + } else { + rv << result_id.id; + } + } + rv << ','; + rv << peak_power; + rv << ','; + rv << mean_power; + rv << ','; + rv << time; + rv << ','; + rv << ra; + rv << ','; + rv << decl; + rv << ','; + rv << q_pix; + rv << ','; + rv << delay; + rv << ','; + rv << freq; + rv << ','; + rv << detection_freq; + rv << ','; + rv << barycentric_freq; + rv << ','; + rv << fft_len; + rv << ','; + rv << chirp_rate; + rv << ','; + rv << rfi_checked; + rv << ','; + rv << rfi_found; + rv << ','; + rv << reserved; + return rv.str(); +} + + +std::string autocorr::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { + std::ostringstream rv(""); + + rv.precision(14); + rv << xml_indent() << '<' << tag << ">\n"; + xml_indent(2); + if (show_ids) { + rv << xml_indent() << "" << id << "\n"; + } + if (!no_refs) { + if (full_subtables) { + rv << result_id.print_xml(full_subtables,show_ids,no_refs,"result_id"); + } else { + rv << xml_indent() << "" << result_id.id << "\n"; + } + } + rv << xml_indent() << "" << peak_power << "\n"; + rv << xml_indent() << "" << mean_power << "\n"; + rv << xml_indent() << "\n"; + rv << xml_indent() << "" << ra << "\n"; + rv << xml_indent() << "" << decl << "\n"; + rv << xml_indent() << "" << q_pix << "\n"; + rv << xml_indent() << "" << delay << "\n"; + rv << xml_indent() << "" << freq << "\n"; + rv << xml_indent() << "" << detection_freq << "\n"; + rv << xml_indent() << "" << barycentric_freq << "\n"; + rv << xml_indent() << "" << fft_len << "\n"; + rv << xml_indent() << "" << chirp_rate << "\n"; + rv << xml_indent() << "" << rfi_checked << "\n"; + rv << xml_indent() << "" << rfi_found << "\n"; + rv << xml_indent() << "" << reserved << "\n"; + xml_indent(-2); + rv << xml_indent() << "\n"; + return rv.str(); +} + + +void autocorr::parse_xml(const std::string &s,const char *tag) { + std::string field,sub; + if (extract_xml_record(s,tag,field)) { + std::string::size_type pos=0; + if (extract_xml_record(field,"id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> id; + } + if (extract_xml_record(field,"result_id",sub)) { + result_id.parse_xml(sub,"result_id"); + } + if (extract_xml_record(field,"peak_power",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> peak_power; + } + if (extract_xml_record(field,"mean_power",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> mean_power; + } + if (extract_xml_record(field,"time",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> time; + } + if (extract_xml_record(field,"ra",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> ra; + } + if (extract_xml_record(field,"decl",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> decl; + } + if (extract_xml_record(field,"q_pix",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> q_pix; + } + if (extract_xml_record(field,"delay",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> delay; + } + if (extract_xml_record(field,"freq",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> freq; + } + if (extract_xml_record(field,"detection_freq",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> detection_freq; + } + if (extract_xml_record(field,"barycentric_freq",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> barycentric_freq; + } + if (extract_xml_record(field,"fft_len",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> fft_len; + } + if (extract_xml_record(field,"chirp_rate",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> chirp_rate; + } + if (extract_xml_record(field,"rfi_checked",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> rfi_checked; + } + if (extract_xml_record(field,"rfi_found",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> rfi_found; + } + if (extract_xml_record(field,"reserved",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> reserved; + } + } +} + +void autocorr::parse(const SQL_ROW &s) { + { + std::istringstream row(*(s[0])); + row >> id; + } + { + result_id.parse(SQL_ROW(s[1],0)); + } + { + std::istringstream row(*(s[2])); + row >> peak_power; + } + { + std::istringstream row(*(s[3])); + row >> mean_power; + } + { + std::istringstream row(*(s[4])); + row >> time; + } + { + std::istringstream row(*(s[5])); + row >> ra; + } + { + std::istringstream row(*(s[6])); + row >> decl; + } + { + std::istringstream row(*(s[7])); + row >> q_pix; + } + { + std::istringstream row(*(s[8])); + row >> delay; + } + { + std::istringstream row(*(s[9])); + row >> freq; + } + { + std::istringstream row(*(s[10])); + row >> detection_freq; + } + { + std::istringstream row(*(s[11])); + row >> barycentric_freq; + } + { + std::istringstream row(*(s[12])); + row >> fft_len; + } + { + std::istringstream row(*(s[13])); + row >> chirp_rate; + } + { + std::istringstream row(*(s[14])); + row >> rfi_checked; + } + { + std::istringstream row(*(s[15])); + row >> rfi_found; + } + { + std::istringstream row(*(s[16])); + row >> reserved; + } +} + +void autocorr::parse(const std::string &s) { + SQL_ROW row(&s,17); + parse(row); +} + +template <> const char *const db_table::table_name="autocorr_small"; +template <> const char *db_table::_search_tag=table_name; +template <> const int db_table::_nfields=17; +template <> const char *const db_table::column_names[17]= {"id","result_id","peak_power","mean_power","time","ra","decl","q_pix","delay","freq","detection_freq","barycentric_freq","fft_len","chirp_rate","rfi_checked","rfi_found","reserved"}; + +autocorr_small::autocorr_small() : + db_table(*this,-1), + id(0), + result_id(), + peak_power(0), + mean_power(0), + time(0), + ra(0), + decl(0), + q_pix(0), + delay(0), + freq(0), + detection_freq(0), + barycentric_freq(0), + fft_len(0), + chirp_rate(0), + rfi_checked(0), + rfi_found(0), + reserved(0) { + db_open(); +} + + +autocorr_small::autocorr_small(const autocorr_small &a) : + db_table(*this,-1), + id(a.id), + result_id(a.result_id), + peak_power(a.peak_power), + mean_power(a.mean_power), + time(a.time), + ra(a.ra), + decl(a.decl), + q_pix(a.q_pix), + delay(a.delay), + freq(a.freq), + detection_freq(a.detection_freq), + barycentric_freq(a.barycentric_freq), + fft_len(a.fft_len), + chirp_rate(a.chirp_rate), + rfi_checked(a.rfi_checked), + rfi_found(a.rfi_found), + reserved(a.reserved) { + db_open(); +} + + +autocorr_small::autocorr_small(const SQL_ROW &a) : + db_table(*this,-1) { + db_open(); + parse(a); +} + + +autocorr_small::autocorr_small(const std::string &s,const char *tag) : + db_table(*this,-1) { + db_open(); + if (xml_match_tag(s,tag)) { + parse_xml(s,tag); + } else { + parse(s); + } +} + + +autocorr_small &autocorr_small::operator =(const autocorr_small &a) { + if (&a != this) { + id=a.id; + result_id=a.result_id; + peak_power=a.peak_power; + mean_power=a.mean_power; + time=a.time; + ra=a.ra; + decl=a.decl; + q_pix=a.q_pix; + delay=a.delay; + freq=a.freq; + detection_freq=a.detection_freq; + barycentric_freq=a.barycentric_freq; + fft_len=a.fft_len; + chirp_rate=a.chirp_rate; + rfi_checked=a.rfi_checked; + rfi_found=a.rfi_found; + reserved=a.reserved; + } + return (*this); +} + + +std::string autocorr_small::update_format() const { + std::ostringstream rv(""); + + for (int i=2; i<17; i++) { + rv << "?,"; + } + rv << "?"; + return rv.str(); +} + + +std::string autocorr_small::insert_format() const { + return std::string("?,")+update_format(); +} + +std::string autocorr_small::select_format() const { + std::string rv(""); + for (int i=0; i<16; i++) { + rv+="?,"; + } + rv+="?"; + return rv; +} + +std::string autocorr_small::print(int full_subtables, int show_ids, int no_refs) const { + std::ostringstream rv(""); + + rv.precision(14); + if (show_ids) { + rv << id; + } + rv << ','; + if (!no_refs) { + if (full_subtables) { + rv << result_id.print(full_subtables,show_ids,no_refs); + } else { + rv << result_id.id; + } + } + rv << ','; + rv << peak_power; + rv << ','; + rv << mean_power; + rv << ','; + rv << time; + rv << ','; + rv << ra; + rv << ','; + rv << decl; + rv << ','; + rv << q_pix; + rv << ','; + rv << delay; + rv << ','; + rv << freq; + rv << ','; + rv << detection_freq; + rv << ','; + rv << barycentric_freq; + rv << ','; + rv << fft_len; + rv << ','; + rv << chirp_rate; + rv << ','; + rv << rfi_checked; + rv << ','; + rv << rfi_found; + rv << ','; + rv << reserved; + return rv.str(); +} + + +std::string autocorr_small::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { + std::ostringstream rv(""); + + rv.precision(14); + rv << xml_indent() << '<' << tag << ">\n"; + xml_indent(2); + if (show_ids) { + rv << xml_indent() << "" << id << "\n"; + } + if (!no_refs) { + if (full_subtables) { + rv << result_id.print_xml(full_subtables,show_ids,no_refs,"result_id"); + } else { + rv << xml_indent() << "" << result_id.id << "\n"; + } + } + rv << xml_indent() << "" << peak_power << "\n"; + rv << xml_indent() << "" << mean_power << "\n"; + rv << xml_indent() << "\n"; + rv << xml_indent() << "" << ra << "\n"; + rv << xml_indent() << "" << decl << "\n"; + rv << xml_indent() << "" << q_pix << "\n"; + rv << xml_indent() << "" << delay << "\n"; + rv << xml_indent() << "" << freq << "\n"; + rv << xml_indent() << "" << detection_freq << "\n"; + rv << xml_indent() << "" << barycentric_freq << "\n"; + rv << xml_indent() << "" << fft_len << "\n"; + rv << xml_indent() << "" << chirp_rate << "\n"; + rv << xml_indent() << "" << rfi_checked << "\n"; + rv << xml_indent() << "" << rfi_found << "\n"; + rv << xml_indent() << "" << reserved << "\n"; + xml_indent(-2); + rv << xml_indent() << "\n"; + return rv.str(); +} + + +void autocorr_small::parse_xml(const std::string &s,const char *tag) { + std::string field,sub; + if (extract_xml_record(s,tag,field)) { + std::string::size_type pos=0; + if (extract_xml_record(field,"id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> id; + } + if (extract_xml_record(field,"result_id",sub)) { + result_id.parse_xml(sub,"result_id"); + } + if (extract_xml_record(field,"peak_power",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> peak_power; + } + if (extract_xml_record(field,"mean_power",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> mean_power; + } + if (extract_xml_record(field,"time",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> time; + } + if (extract_xml_record(field,"ra",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> ra; + } + if (extract_xml_record(field,"decl",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> decl; + } + if (extract_xml_record(field,"q_pix",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> q_pix; + } + if (extract_xml_record(field,"delay",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> delay; + } + if (extract_xml_record(field,"freq",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> freq; + } + if (extract_xml_record(field,"detection_freq",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> detection_freq; + } + if (extract_xml_record(field,"barycentric_freq",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> barycentric_freq; + } + if (extract_xml_record(field,"fft_len",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> fft_len; + } + if (extract_xml_record(field,"chirp_rate",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> chirp_rate; + } + if (extract_xml_record(field,"rfi_checked",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> rfi_checked; + } + if (extract_xml_record(field,"rfi_found",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> rfi_found; + } + if (extract_xml_record(field,"reserved",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> reserved; + } + } +} + +void autocorr_small::parse(const SQL_ROW &s) { + { + std::istringstream row(*(s[0])); + row >> id; + } + { + result_id.parse(SQL_ROW(s[1],0)); + } + { + std::istringstream row(*(s[2])); + row >> peak_power; + } + { + std::istringstream row(*(s[3])); + row >> mean_power; + } + { + std::istringstream row(*(s[4])); + row >> time; + } + { + std::istringstream row(*(s[5])); + row >> ra; + } + { + std::istringstream row(*(s[6])); + row >> decl; + } + { + std::istringstream row(*(s[7])); + row >> q_pix; + } + { + std::istringstream row(*(s[8])); + row >> delay; + } + { + std::istringstream row(*(s[9])); + row >> freq; + } + { + std::istringstream row(*(s[10])); + row >> detection_freq; + } + { + std::istringstream row(*(s[11])); + row >> barycentric_freq; + } + { + std::istringstream row(*(s[12])); + row >> fft_len; + } + { + std::istringstream row(*(s[13])); + row >> chirp_rate; + } + { + std::istringstream row(*(s[14])); + row >> rfi_checked; + } + { + std::istringstream row(*(s[15])); + row >> rfi_found; + } + { + std::istringstream row(*(s[16])); + row >> reserved; + } +} + +void autocorr_small::parse(const std::string &s) { + SQL_ROW row(&s,17); + parse(row); +} + +template <> const char *const db_table::table_name="classic_versions"; +template <> const char *db_table::_search_tag=table_name; +template <> const int db_table::_nfields=10; +template <> const char *const db_table::column_names[10]= {"id","ver_major","ver_minor","platformid","comment","filename","md5_cksum","sum_cksum","cksum_cksum","file_cksum"}; + +classic_versions::classic_versions() : + db_table(*this,-1), + id(0), + ver_major(0), + ver_minor(0), + platformid(0), + file_cksum(0) { + db_open(); + comment[0]=0; + filename[0]=0; + md5_cksum[0]=0; + sum_cksum[0]=0; + cksum_cksum[0]=0; +} + + +classic_versions::classic_versions(const classic_versions &a) : + db_table(*this,-1), + id(a.id), + ver_major(a.ver_major), + ver_minor(a.ver_minor), + platformid(a.platformid), + file_cksum(a.file_cksum) { + db_open(); + strcpy(comment,a.comment); + strcpy(filename,a.filename); + strcpy(md5_cksum,a.md5_cksum); + strcpy(sum_cksum,a.sum_cksum); + strcpy(cksum_cksum,a.cksum_cksum); +} + + +classic_versions::classic_versions(const SQL_ROW &a) : + db_table(*this,-1) { + db_open(); + parse(a); +} + + +classic_versions::classic_versions(const std::string &s,const char *tag) : + db_table(*this,-1) { + db_open(); + if (xml_match_tag(s,tag)) { + parse_xml(s,tag); + } else { + parse(s); + } +} + + +classic_versions &classic_versions::operator =(const classic_versions &a) { + if (&a != this) { + id=a.id; + ver_major=a.ver_major; + ver_minor=a.ver_minor; + platformid=a.platformid; + file_cksum=a.file_cksum; + strcpy(comment,a.comment); + strcpy(filename,a.filename); + strcpy(md5_cksum,a.md5_cksum); + strcpy(sum_cksum,a.sum_cksum); + strcpy(cksum_cksum,a.cksum_cksum); + } + return (*this); +} + + +std::string classic_versions::update_format() const { + std::ostringstream rv(""); + + for (int i=2; i<10; i++) { + rv << "?,"; + } + rv << "?"; + return rv.str(); +} + + +std::string classic_versions::insert_format() const { + return std::string("?,")+update_format(); +} + +std::string classic_versions::select_format() const { + std::string rv(""); + for (int i=0; i<9; i++) { + rv+="?,"; + } + rv+="?"; + return rv; +} + +std::string classic_versions::print(int full_subtables, int show_ids, int no_refs) const { + std::ostringstream rv(""); + + rv.precision(14); + if (show_ids) { + rv << id; + } + rv << ','; + rv << ver_major; + rv << ','; + rv << ver_minor; + rv << ','; + rv << platformid; + rv << ','; + rv << "'" << comment << "'"; + rv << ','; + rv << "'" << filename << "'"; + rv << ','; + rv << "'" << md5_cksum << "'"; + rv << ','; + rv << "'" << sum_cksum << "'"; + rv << ','; + rv << "'" << cksum_cksum << "'"; + rv << ','; + rv << file_cksum; + return rv.str(); +} + + +std::string classic_versions::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { + std::ostringstream rv(""); + + rv.precision(14); + rv << xml_indent() << '<' << tag << ">\n"; + xml_indent(2); + if (show_ids) { + rv << xml_indent() << "" << id << "\n"; + } + rv << xml_indent() << "" << ver_major << "\n"; + rv << xml_indent() << "" << ver_minor << "\n"; + rv << xml_indent() << "" << platformid << "\n"; + { + std::string enc_field=xml_encode_string(comment,std::min(strlen(comment),sizeof(comment))); + rv << xml_indent() << ""; + rv << enc_field << "\n"; + } + { + std::string enc_field=xml_encode_string(filename,std::min(strlen(filename),sizeof(filename))); + rv << xml_indent() << ""; + rv << enc_field << "\n"; + } + { + std::string enc_field=xml_encode_string(md5_cksum,std::min(strlen(md5_cksum),sizeof(md5_cksum))); + rv << xml_indent() << ""; + rv << enc_field << "\n"; + } + { + std::string enc_field=xml_encode_string(sum_cksum,std::min(strlen(sum_cksum),sizeof(sum_cksum))); + rv << xml_indent() << ""; + rv << enc_field << "\n"; + } + { + std::string enc_field=xml_encode_string(cksum_cksum,std::min(strlen(cksum_cksum),sizeof(cksum_cksum))); + rv << xml_indent() << ""; + rv << enc_field << "\n"; + } + rv << xml_indent() << "" << file_cksum << "\n"; + xml_indent(-2); + rv << xml_indent() << "\n"; + return rv.str(); +} + + +void classic_versions::parse_xml(const std::string &s,const char *tag) { + std::string field,sub; + if (extract_xml_record(s,tag,field)) { + std::string::size_type pos=0; + if (extract_xml_record(field,"id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> id; + } + if (extract_xml_record(field,"ver_major",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> ver_major; + } + if (extract_xml_record(field,"ver_minor",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> ver_minor; + } + if (extract_xml_record(field,"platformid",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> platformid; + } + if (extract_xml_record(field,"comment",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::string::size_type epos=sub.find("<",pos); + if (epos==std::string::npos) { + epos=sub.find('\n',pos); + } + if (epos==std::string::npos) { + epos=pos+strlen(sub.c_str()+pos); + } + std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); + strncpy(comment,(const char *)&(in.front()),std::min(in.size(),(size_t)254)); + comment[std::min(in.size(),(size_t)253)]=0; + } + if (extract_xml_record(field,"filename",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::string::size_type epos=sub.find("<",pos); + if (epos==std::string::npos) { + epos=sub.find('\n',pos); + } + if (epos==std::string::npos) { + epos=pos+strlen(sub.c_str()+pos); + } + std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); + strncpy(filename,(const char *)&(in.front()),std::min(in.size(),(size_t)254)); + filename[std::min(in.size(),(size_t)253)]=0; + } + if (extract_xml_record(field,"md5_cksum",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::string::size_type epos=sub.find("<",pos); + if (epos==std::string::npos) { + epos=sub.find('\n',pos); + } + if (epos==std::string::npos) { + epos=pos+strlen(sub.c_str()+pos); + } + std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); + strncpy(md5_cksum,(const char *)&(in.front()),std::min(in.size(),(size_t)254)); + md5_cksum[std::min(in.size(),(size_t)253)]=0; + } + if (extract_xml_record(field,"sum_cksum",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::string::size_type epos=sub.find("<",pos); + if (epos==std::string::npos) { + epos=sub.find('\n',pos); + } + if (epos==std::string::npos) { + epos=pos+strlen(sub.c_str()+pos); + } + std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); + strncpy(sum_cksum,(const char *)&(in.front()),std::min(in.size(),(size_t)254)); + sum_cksum[std::min(in.size(),(size_t)253)]=0; + } + if (extract_xml_record(field,"cksum_cksum",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::string::size_type epos=sub.find("<",pos); + if (epos==std::string::npos) { + epos=sub.find('\n',pos); + } + if (epos==std::string::npos) { + epos=pos+strlen(sub.c_str()+pos); + } + std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); + strncpy(cksum_cksum,(const char *)&(in.front()),std::min(in.size(),(size_t)254)); + cksum_cksum[std::min(in.size(),(size_t)253)]=0; + } + if (extract_xml_record(field,"file_cksum",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> file_cksum; + } + } +} + +void classic_versions::parse(const SQL_ROW &s) { + { + std::istringstream row(*(s[0])); + row >> id; + } + { + std::istringstream row(*(s[1])); + row >> ver_major; + } + { + std::istringstream row(*(s[2])); + row >> ver_minor; + } + { + std::istringstream row(*(s[3])); + row >> platformid; + } + { + strncpy(comment,s[4]->c_str(),254); + comment[253]=0; + } + { + strncpy(filename,s[5]->c_str(),254); + filename[253]=0; + } + { + strncpy(md5_cksum,s[6]->c_str(),254); + md5_cksum[253]=0; + } + { + strncpy(sum_cksum,s[7]->c_str(),254); + sum_cksum[253]=0; + } + { + strncpy(cksum_cksum,s[8]->c_str(),254); + cksum_cksum[253]=0; + } + { + std::istringstream row(*(s[9])); + row >> file_cksum; + } +} + +void classic_versions::parse(const std::string &s) { + SQL_ROW row(&s,10); + parse(row); +} + +template <> const char *const db_table::table_name="classic_active_versions"; +template <> const char *db_table::_search_tag=table_name; +template <> const int db_table::_nfields=4; +template <> const char *const db_table::column_names[4]= {"id","versionid","ver_major","ver_minor"}; + +classic_active_versions::classic_active_versions() : + db_table(*this,-1), + id(0), + versionid(0), + ver_major(0), + ver_minor(0) { + db_open(); +} + + +classic_active_versions::classic_active_versions(const classic_active_versions &a) : + db_table(*this,-1), + id(a.id), + versionid(a.versionid), + ver_major(a.ver_major), + ver_minor(a.ver_minor) { + db_open(); +} + + +classic_active_versions::classic_active_versions(const SQL_ROW &a) : + db_table(*this,-1) { + db_open(); + parse(a); +} + + +classic_active_versions::classic_active_versions(const std::string &s,const char *tag) : + db_table(*this,-1) { + db_open(); + if (xml_match_tag(s,tag)) { + parse_xml(s,tag); + } else { + parse(s); + } +} + + +classic_active_versions &classic_active_versions::operator =(const classic_active_versions &a) { + if (&a != this) { + id=a.id; + versionid=a.versionid; + ver_major=a.ver_major; + ver_minor=a.ver_minor; + } + return (*this); +} + + +std::string classic_active_versions::update_format() const { + std::ostringstream rv(""); + + for (int i=2; i<4; i++) { + rv << "?,"; + } + rv << "?"; + return rv.str(); +} + + +std::string classic_active_versions::insert_format() const { + return std::string("?,")+update_format(); +} + +std::string classic_active_versions::select_format() const { + std::string rv(""); + for (int i=0; i<3; i++) { + rv+="?,"; + } + rv+="?"; + return rv; +} + +std::string classic_active_versions::print(int full_subtables, int show_ids, int no_refs) const { + std::ostringstream rv(""); + + rv.precision(14); + if (show_ids) { + rv << id; + } + rv << ','; + rv << versionid; + rv << ','; + rv << ver_major; + rv << ','; + rv << ver_minor; + return rv.str(); +} + + +std::string classic_active_versions::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { + std::ostringstream rv(""); + + rv.precision(14); + rv << xml_indent() << '<' << tag << ">\n"; + xml_indent(2); + if (show_ids) { + rv << xml_indent() << "" << id << "\n"; + } + rv << xml_indent() << "" << versionid << "\n"; + rv << xml_indent() << "" << ver_major << "\n"; + rv << xml_indent() << "" << ver_minor << "\n"; + xml_indent(-2); + rv << xml_indent() << "\n"; + return rv.str(); +} + + +void classic_active_versions::parse_xml(const std::string &s,const char *tag) { + std::string field,sub; + if (extract_xml_record(s,tag,field)) { + std::string::size_type pos=0; + if (extract_xml_record(field,"id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> id; + } + if (extract_xml_record(field,"versionid",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> versionid; + } + if (extract_xml_record(field,"ver_major",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> ver_major; + } + if (extract_xml_record(field,"ver_minor",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> ver_minor; + } + } +} + +void classic_active_versions::parse(const SQL_ROW &s) { + { + std::istringstream row(*(s[0])); + row >> id; + } + { + std::istringstream row(*(s[1])); + row >> versionid; + } + { + std::istringstream row(*(s[2])); + row >> ver_major; + } + { + std::istringstream row(*(s[3])); + row >> ver_minor; + } +} + +void classic_active_versions::parse(const std::string &s) { + SQL_ROW row(&s,4); + parse(row); +} + +template <> const char *const db_table::table_name="classic_active_versionids"; +template <> const char *db_table::_search_tag=table_name; +template <> const int db_table::_nfields=2; +template <> const char *const db_table::column_names[2]= {"id","versionid"}; + +classic_active_versionids::classic_active_versionids() : + db_table(*this,-1), + id(0), + versionid(0) { + db_open(); +} + + +classic_active_versionids::classic_active_versionids(const classic_active_versionids &a) : + db_table(*this,-1), + id(a.id), + versionid(a.versionid) { + db_open(); +} + + +classic_active_versionids::classic_active_versionids(const SQL_ROW &a) : + db_table(*this,-1) { + db_open(); + parse(a); +} + + +classic_active_versionids::classic_active_versionids(const std::string &s,const char *tag) : + db_table(*this,-1) { + db_open(); + if (xml_match_tag(s,tag)) { + parse_xml(s,tag); + } else { + parse(s); + } +} + + +classic_active_versionids &classic_active_versionids::operator =(const classic_active_versionids &a) { + if (&a != this) { + id=a.id; + versionid=a.versionid; + } + return (*this); +} + + +std::string classic_active_versionids::update_format() const { + std::ostringstream rv(""); + + for (int i=2; i<2; i++) { + rv << "?,"; + } + rv << "?"; + return rv.str(); +} + + +std::string classic_active_versionids::insert_format() const { + return std::string("?,")+update_format(); +} + +std::string classic_active_versionids::select_format() const { + std::string rv(""); + for (int i=0; i<1; i++) { + rv+="?,"; + } + rv+="?"; + return rv; +} + +std::string classic_active_versionids::print(int full_subtables, int show_ids, int no_refs) const { + std::ostringstream rv(""); + + rv.precision(14); + if (show_ids) { + rv << id; + } + rv << ','; + rv << versionid; + return rv.str(); +} + + +std::string classic_active_versionids::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { + std::ostringstream rv(""); + + rv.precision(14); + rv << xml_indent() << '<' << tag << ">\n"; + xml_indent(2); + if (show_ids) { + rv << xml_indent() << "" << id << "\n"; + } + rv << xml_indent() << "" << versionid << "\n"; + xml_indent(-2); + rv << xml_indent() << "\n"; + return rv.str(); +} + + +void classic_active_versionids::parse_xml(const std::string &s,const char *tag) { + std::string field,sub; + if (extract_xml_record(s,tag,field)) { + std::string::size_type pos=0; + if (extract_xml_record(field,"id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> id; + } + if (extract_xml_record(field,"versionid",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> versionid; + } + } +} + +void classic_active_versionids::parse(const SQL_ROW &s) { + { + std::istringstream row(*(s[0])); + row >> id; + } + { + std::istringstream row(*(s[1])); + row >> versionid; + } +} + +void classic_active_versionids::parse(const std::string &s) { + SQL_ROW row(&s,2); + parse(row); +} + +template <> const char *const db_table::table_name="rfi_zone"; +template <> const char *db_table::_search_tag=table_name; +template <> const int db_table::_nfields=26; +template <> const char *const db_table::column_names[26]= {"id","min_receiver_s4id","max_receiver_s4id","min_splitter_config","max_splitter_config","min_analysis_config","max_analysis_config","min_tape_id","max_tape_id","min_workunit_id","max_workunit_id","min_result_id","max_result_id","min_time","max_time","central_baseband_freq","baseband_freq_width","central_detection_freq","detection_freq_width","central_period","period_width","fft_len_flags","signal_type_flags","ra","dec","angular_distance"}; + +rfi_zone::rfi_zone() : + db_table(*this,-1), + id(0), + min_receiver_s4id(0), + max_receiver_s4id(0), + min_splitter_config(0), + max_splitter_config(0), + min_analysis_config(0), + max_analysis_config(0), + min_tape_id(0), + max_tape_id(0), + min_workunit_id(0), + max_workunit_id(0), + min_result_id(0), + max_result_id(0), + min_time(0), + max_time(0), + central_baseband_freq(0), + baseband_freq_width(0), + central_detection_freq(0), + detection_freq_width(0), + central_period(0), + period_width(0), + fft_len_flags(0), + signal_type_flags(0), + ra(0), + dec(0), + angular_distance(0) { + db_open(); +} + + +rfi_zone::rfi_zone(const rfi_zone &a) : + db_table(*this,-1), + id(a.id), + min_receiver_s4id(a.min_receiver_s4id), + max_receiver_s4id(a.max_receiver_s4id), + min_splitter_config(a.min_splitter_config), + max_splitter_config(a.max_splitter_config), + min_analysis_config(a.min_analysis_config), + max_analysis_config(a.max_analysis_config), + min_tape_id(a.min_tape_id), + max_tape_id(a.max_tape_id), + min_workunit_id(a.min_workunit_id), + max_workunit_id(a.max_workunit_id), + min_result_id(a.min_result_id), + max_result_id(a.max_result_id), + min_time(a.min_time), + max_time(a.max_time), + central_baseband_freq(a.central_baseband_freq), + baseband_freq_width(a.baseband_freq_width), + central_detection_freq(a.central_detection_freq), + detection_freq_width(a.detection_freq_width), + central_period(a.central_period), + period_width(a.period_width), + fft_len_flags(a.fft_len_flags), + signal_type_flags(a.signal_type_flags), + ra(a.ra), + dec(a.dec), + angular_distance(a.angular_distance) { + db_open(); +} + + +rfi_zone::rfi_zone(const SQL_ROW &a) : + db_table(*this,-1) { + db_open(); + parse(a); +} + + +rfi_zone::rfi_zone(const std::string &s,const char *tag) : + db_table(*this,-1) { + db_open(); + if (xml_match_tag(s,tag)) { + parse_xml(s,tag); + } else { + parse(s); + } +} + + +rfi_zone &rfi_zone::operator =(const rfi_zone &a) { + if (&a != this) { + id=a.id; + min_receiver_s4id=a.min_receiver_s4id; + max_receiver_s4id=a.max_receiver_s4id; + min_splitter_config=a.min_splitter_config; + max_splitter_config=a.max_splitter_config; + min_analysis_config=a.min_analysis_config; + max_analysis_config=a.max_analysis_config; + min_tape_id=a.min_tape_id; + max_tape_id=a.max_tape_id; + min_workunit_id=a.min_workunit_id; + max_workunit_id=a.max_workunit_id; + min_result_id=a.min_result_id; + max_result_id=a.max_result_id; + min_time=a.min_time; + max_time=a.max_time; + central_baseband_freq=a.central_baseband_freq; + baseband_freq_width=a.baseband_freq_width; + central_detection_freq=a.central_detection_freq; + detection_freq_width=a.detection_freq_width; + central_period=a.central_period; + period_width=a.period_width; + fft_len_flags=a.fft_len_flags; + signal_type_flags=a.signal_type_flags; + ra=a.ra; + dec=a.dec; + angular_distance=a.angular_distance; + } + return (*this); +} + + +std::string rfi_zone::update_format() const { + std::ostringstream rv(""); + + for (int i=2; i<26; i++) { + rv << "?,"; + } + rv << "?"; + return rv.str(); +} + + +std::string rfi_zone::insert_format() const { + return std::string("?,")+update_format(); +} + +std::string rfi_zone::select_format() const { + std::string rv(""); + for (int i=0; i<25; i++) { + rv+="?,"; + } + rv+="?"; + return rv; +} + +std::string rfi_zone::print(int full_subtables, int show_ids, int no_refs) const { + std::ostringstream rv(""); + + rv.precision(14); + if (show_ids) { + rv << id; + } + rv << ','; + rv << min_receiver_s4id; + rv << ','; + rv << max_receiver_s4id; + rv << ','; + rv << min_splitter_config; + rv << ','; + rv << max_splitter_config; + rv << ','; + rv << min_analysis_config; + rv << ','; + rv << max_analysis_config; + rv << ','; + rv << min_tape_id; + rv << ','; + rv << max_tape_id; + rv << ','; + rv << min_workunit_id; + rv << ','; + rv << max_workunit_id; + rv << ','; + rv << min_result_id; + rv << ','; + rv << max_result_id; + rv << ','; + rv << min_time; + rv << ','; + rv << max_time; + rv << ','; + rv << central_baseband_freq; + rv << ','; + rv << baseband_freq_width; + rv << ','; + rv << central_detection_freq; + rv << ','; + rv << detection_freq_width; + rv << ','; + rv << central_period; + rv << ','; + rv << period_width; + rv << ','; + rv << fft_len_flags; + rv << ','; + rv << signal_type_flags; + rv << ','; + rv << ra; + rv << ','; + rv << dec; + rv << ','; + rv << angular_distance; + return rv.str(); +} + + +std::string rfi_zone::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { + std::ostringstream rv(""); + + rv.precision(14); + rv << xml_indent() << '<' << tag << ">\n"; + xml_indent(2); + if (show_ids) { + rv << xml_indent() << "" << id << "\n"; + } + rv << xml_indent() << "" << min_receiver_s4id << "\n"; + rv << xml_indent() << "" << max_receiver_s4id << "\n"; + rv << xml_indent() << "" << min_splitter_config << "\n"; + rv << xml_indent() << "" << max_splitter_config << "\n"; + rv << xml_indent() << "" << min_analysis_config << "\n"; + rv << xml_indent() << "" << max_analysis_config << "\n"; + rv << xml_indent() << "" << min_tape_id << "\n"; + rv << xml_indent() << "" << max_tape_id << "\n"; + rv << xml_indent() << "" << min_workunit_id << "\n"; + rv << xml_indent() << "" << max_workunit_id << "\n"; + rv << xml_indent() << "" << min_result_id << "\n"; + rv << xml_indent() << "" << max_result_id << "\n"; + rv << xml_indent() << "" << min_time << "\n"; + rv << xml_indent() << "" << max_time << "\n"; + rv << xml_indent() << "" << central_baseband_freq << "\n"; + rv << xml_indent() << "" << baseband_freq_width << "\n"; + rv << xml_indent() << "" << central_detection_freq << "\n"; + rv << xml_indent() << "" << detection_freq_width << "\n"; + rv << xml_indent() << "" << central_period << "\n"; + rv << xml_indent() << "" << period_width << "\n"; + rv << xml_indent() << "" << fft_len_flags << "\n"; + rv << xml_indent() << "" << signal_type_flags << "\n"; + rv << xml_indent() << "" << ra << "\n"; + rv << xml_indent() << "" << dec << "\n"; + rv << xml_indent() << "" << angular_distance << "\n"; + xml_indent(-2); + rv << xml_indent() << "\n"; + return rv.str(); +} + + +void rfi_zone::parse_xml(const std::string &s,const char *tag) { + std::string field,sub; + if (extract_xml_record(s,tag,field)) { + std::string::size_type pos=0; + if (extract_xml_record(field,"id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> id; + } + if (extract_xml_record(field,"min_receiver_s4id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> min_receiver_s4id; + } + if (extract_xml_record(field,"max_receiver_s4id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> max_receiver_s4id; + } + if (extract_xml_record(field,"min_splitter_config",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> min_splitter_config; + } + if (extract_xml_record(field,"max_splitter_config",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> max_splitter_config; + } + if (extract_xml_record(field,"min_analysis_config",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> min_analysis_config; + } + if (extract_xml_record(field,"max_analysis_config",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> max_analysis_config; + } + if (extract_xml_record(field,"min_tape_id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> min_tape_id; + } + if (extract_xml_record(field,"max_tape_id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> max_tape_id; + } + if (extract_xml_record(field,"min_workunit_id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> min_workunit_id; + } + if (extract_xml_record(field,"max_workunit_id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> max_workunit_id; + } + if (extract_xml_record(field,"min_result_id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> min_result_id; + } + if (extract_xml_record(field,"max_result_id",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> max_result_id; + } + if (extract_xml_record(field,"min_time",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> min_time; + } + if (extract_xml_record(field,"max_time",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> max_time; + } + if (extract_xml_record(field,"central_baseband_freq",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> central_baseband_freq; + } + if (extract_xml_record(field,"baseband_freq_width",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> baseband_freq_width; + } + if (extract_xml_record(field,"central_detection_freq",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> central_detection_freq; + } + if (extract_xml_record(field,"detection_freq_width",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> detection_freq_width; + } + if (extract_xml_record(field,"central_period",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> central_period; + } + if (extract_xml_record(field,"period_width",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> period_width; + } + if (extract_xml_record(field,"fft_len_flags",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> fft_len_flags; + } + if (extract_xml_record(field,"signal_type_flags",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> signal_type_flags; + } + if (extract_xml_record(field,"ra",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> ra; + } + if (extract_xml_record(field,"dec",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> dec; + } + if (extract_xml_record(field,"angular_distance",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> angular_distance; + } + } +} + +void rfi_zone::parse(const SQL_ROW &s) { + { + std::istringstream row(*(s[0])); + row >> id; + } + { + std::istringstream row(*(s[1])); + row >> min_receiver_s4id; + } + { + std::istringstream row(*(s[2])); + row >> max_receiver_s4id; + } + { + std::istringstream row(*(s[3])); + row >> min_splitter_config; + } + { + std::istringstream row(*(s[4])); + row >> max_splitter_config; + } + { + std::istringstream row(*(s[5])); + row >> min_analysis_config; + } + { + std::istringstream row(*(s[6])); + row >> max_analysis_config; + } + { + std::istringstream row(*(s[7])); + row >> min_tape_id; + } + { + std::istringstream row(*(s[8])); + row >> max_tape_id; + } + { + std::istringstream row(*(s[9])); + row >> min_workunit_id; + } + { + std::istringstream row(*(s[10])); + row >> max_workunit_id; + } + { + std::istringstream row(*(s[11])); + row >> min_result_id; + } + { + std::istringstream row(*(s[12])); + row >> max_result_id; + } + { + std::istringstream row(*(s[13])); + row >> min_time; + } + { + std::istringstream row(*(s[14])); + row >> max_time; + } + { + std::istringstream row(*(s[15])); + row >> central_baseband_freq; + } + { + std::istringstream row(*(s[16])); + row >> baseband_freq_width; + } + { + std::istringstream row(*(s[17])); + row >> central_detection_freq; + } + { + std::istringstream row(*(s[18])); + row >> detection_freq_width; + } + { + std::istringstream row(*(s[19])); + row >> central_period; + } + { + std::istringstream row(*(s[20])); + row >> period_width; + } + { + std::istringstream row(*(s[21])); + row >> fft_len_flags; + } + { + std::istringstream row(*(s[22])); + row >> signal_type_flags; + } + { + std::istringstream row(*(s[23])); + row >> ra; + } + { + std::istringstream row(*(s[24])); + row >> dec; + } + { + std::istringstream row(*(s[25])); + row >> angular_distance; + } +} + +void rfi_zone::parse(const std::string &s) { + SQL_ROW row(&s,26); + parse(row); +} + +template <> const char *const db_table::table_name="bad_data"; +template <> const char *db_table::_search_tag=table_name; +template <> const int db_table::_nfields=3; +template <> const char *const db_table::column_names[3]= {"name","beam""reason"}; + +bad_data::bad_data() : + db_table(*this,-1), + beam(0) { + db_open(); + name[0]=0; + reason[0]=0; +} + + +bad_data::bad_data(const bad_data &a) : + db_table(*this,-1), + beam(a.beam) { + db_open(); + strcpy(name,a.name); + strcpy(reason,a.reason); +} + + +bad_data::bad_data(const SQL_ROW &a) : + db_table(*this,-1) { + db_open(); + parse(a); +} + + +bad_data::bad_data(const std::string &s,const char *tag) : + db_table(*this,-1) { + db_open(); + if (xml_match_tag(s,tag)) { + parse_xml(s,tag); + } else { + parse(s); + } +} + + +bad_data &bad_data::operator =(const bad_data &a) { + if (&a != this) { + beam=a.beam; + strcpy(name,a.name); + strcpy(reason,a.reason); + } + return (*this); +} + + +std::string bad_data::update_format() const { + std::ostringstream rv(""); + + for (int i=2; i<3; i++) { + rv << "?,"; + } + rv << "?"; + return rv.str(); +} + + +std::string bad_data::insert_format() const { + return std::string("?,")+update_format(); +} + +std::string bad_data::select_format() const { + std::string rv(""); + for (int i=0; i<2; i++) { + rv+="?,"; + } + rv+="?"; + return rv; +} + +std::string bad_data::print(int full_subtables, int show_ids, int no_refs) const { + std::ostringstream rv(""); + + rv.precision(14); + rv << "'" << name << "'"; + rv << ','; + rv << beam; + rv << ','; + rv << "'" << reason << "'"; + return rv.str(); +} + + +std::string bad_data::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const { + std::ostringstream rv(""); + + rv.precision(14); + rv << xml_indent() << '<' << tag << ">\n"; + xml_indent(2); + { + std::string enc_field=xml_encode_string(name,std::min(strlen(name),sizeof(name))); + rv << xml_indent() << ""; + rv << enc_field << "\n"; + } + rv << xml_indent() << "" << beam << "\n"; + { + std::string enc_field=xml_encode_string(reason,std::min(strlen(reason),sizeof(reason))); + rv << xml_indent() << ""; + rv << enc_field << "\n"; + } + xml_indent(-2); + rv << xml_indent() << "\n"; + return rv.str(); +} + + +void bad_data::parse_xml(const std::string &s,const char *tag) { + std::string field,sub; + if (extract_xml_record(s,tag,field)) { + std::string::size_type pos=0; + if (extract_xml_record(field,"name",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::string::size_type epos=sub.find("<",pos); + if (epos==std::string::npos) { + epos=sub.find('\n',pos); + } + if (epos==std::string::npos) { + epos=pos+strlen(sub.c_str()+pos); + } + std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); + strncpy(name,(const char *)&(in.front()),std::min(in.size(),(size_t)20)); + name[std::min(in.size(),(size_t)19)]=0; + } + if (extract_xml_record(field,"beam",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::istringstream in(sub.c_str()+pos); + in >> beam; + } + if (extract_xml_record(field,"reason",sub)) { + pos=sub.find(">"); + do { + pos++; + } while (sub[pos]=='\n'); + std::string::size_type epos=sub.find("<",pos); + if (epos==std::string::npos) { + epos=sub.find('\n',pos); + } + if (epos==std::string::npos) { + epos=pos+strlen(sub.c_str()+pos); + } + std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos)); + strncpy(reason,(const char *)&(in.front()),std::min(in.size(),(size_t)255)); + reason[std::min(in.size(),(size_t)254)]=0; + } + } +} + +void bad_data::parse(const SQL_ROW &s) { + { + strncpy(name,s[0]->c_str(),20); + name[19]=0; + } + { + std::istringstream row(*(s[1])); + row >> beam; + } + { + strncpy(reason,s[2]->c_str(),255); + reason[254]=0; + } +} + +void bad_data::parse(const std::string &s) { + SQL_ROW row(&s,3); + parse(row); +} + diff --git a/db/schema_master.h b/db/schema_master.h new file mode 100644 index 0000000..164d7ce --- /dev/null +++ b/db/schema_master.h @@ -0,0 +1,1242 @@ +// This file is automatically generated. Do not edit +#ifndef _H_schema_master_H +#define _H_schema_master_H +extern const char *db_name; +extern int db_is_open; + +#ifndef CLIENT +inline int db_open() { + if (!db_is_open) { + db_is_open=sql_database(db_name); + } + return db_is_open; +} +inline int db_close() { + if (db_is_open) { + db_is_open=!sql_finish(); + } + return !db_is_open; +} +inline int db_change(const char *name) { + if (strcmp(db_name, name) || !db_is_open) { + db_close(); + db_name=name; + db_open(); + } return(db_is_open); +} +#else +inline int db_open() { + return (db_is_open=1); +} +inline int db_close() { + return !(db_is_open=0); +} +inline int db_change() { + return (db_is_open=1); +} +#endif + +class coordinate_t : public db_type { + public: + double time; + double ra; + double dec; + coordinate_t(); + coordinate_t(const coordinate_t &a); + coordinate_t(const SQL_ROW &a); + coordinate_t(const std::string &s,const char *tag="coordinate_t"); + coordinate_t &operator =(const coordinate_t &a); + std::string update_format() const; + std::string insert_format() const; + std::string select_format() const; + std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; + std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="coordinate_t") const; + void parse(const SQL_ROW &s); + void parse(const std::string &s); + void parse_xml(const std::string &s,const char *tag="coordinate_t"); + private: +}; + + +class chirp_parameter_t : public db_type { + public: + double chirp_limit; + long fft_len_flags; + chirp_parameter_t(); + chirp_parameter_t(const chirp_parameter_t &a); + chirp_parameter_t(const SQL_ROW &a); + chirp_parameter_t(const std::string &s,const char *tag="chirp_parameter_t"); + chirp_parameter_t &operator =(const chirp_parameter_t &a); + std::string update_format() const; + std::string insert_format() const; + std::string select_format() const; + std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; + std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="chirp_parameter_t") const; + void parse(const SQL_ROW &s); + void parse(const std::string &s); + void parse_xml(const std::string &s,const char *tag="chirp_parameter_t"); + private: +}; + + +class subband_description_t : public db_type { + public: + long number; + double center; + double base; + double sample_rate; + subband_description_t(); + subband_description_t(const subband_description_t &a); + subband_description_t(const SQL_ROW &a); + subband_description_t(const std::string &s,const char *tag="subband_description_t"); + subband_description_t &operator =(const subband_description_t &a); + std::string update_format() const; + std::string insert_format() const; + std::string select_format() const; + std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; + std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="subband_description_t") const; + void parse(const SQL_ROW &s); + void parse(const std::string &s); + void parse_xml(const std::string &s,const char *tag="subband_description_t"); + private: +}; + + +class data_description_t : public db_type { + public: + double start_ra; + double start_dec; + double end_ra; + double end_dec; + double true_angle_range; + char time_recorded[255]; + double time_recorded_jd; + long nsamples; + sqlblob coords ; + data_description_t(); + data_description_t(const data_description_t &a); + data_description_t(const SQL_ROW &a); + data_description_t(const std::string &s,const char *tag="data_description_t"); + data_description_t &operator =(const data_description_t &a); + std::string update_format() const; + std::string insert_format() const; + std::string select_format() const; + std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; + std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="data_description_t") const; + void parse(const SQL_ROW &s); + void parse(const std::string &s); + void parse_xml(const std::string &s,const char *tag="data_description_t"); + private: +}; + + +class receiver_config : public db_table { + public: + long id; + long s4_id; + char name[255]; + double beam_width; + double center_freq; + double latitude; + double longitude; + double elevation; + double diameter; + double az_orientation; + sqlblob az_corr_coeff ; + sqlblob zen_corr_coeff ; + double array_az_ellipse; + double array_za_ellipse; + double array_angle; + long min_vgc; + receiver_config(); + receiver_config(const receiver_config &a); + receiver_config(const SQL_ROW &a); + receiver_config(const std::string &s,const char *tag="receiver_config"); + receiver_config &operator =(const receiver_config &a); + std::string update_format() const; + std::string insert_format() const; + std::string select_format() const; + std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; + std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="receiver_config") const; + void parse(const SQL_ROW &s); + void parse(const std::string &s); + void parse_xml(const std::string &s,const char *tag="receiver_config"); + private: +}; + + +class recorder_config : public db_table { + public: + long id; + char name[64]; + long bits_per_sample; + double sample_rate; + long beams; + double version; + recorder_config(); + recorder_config(const recorder_config &a); + recorder_config(const SQL_ROW &a); + recorder_config(const std::string &s,const char *tag="recorder_config"); + recorder_config &operator =(const recorder_config &a); + std::string update_format() const; + std::string insert_format() const; + std::string select_format() const; + std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; + std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="recorder_config") const; + void parse(const SQL_ROW &s); + void parse(const std::string &s); + void parse_xml(const std::string &s,const char *tag="recorder_config"); + private: +}; + + +class splitter_config : public db_table { + public: + long id; + double version; + char data_type[64]; + long fft_len; + long ifft_len; + char filter[64]; + char window[64]; + long samples_per_wu; + double highpass; + char blanker_filter[64]; + splitter_config(); + splitter_config(const splitter_config &a); + splitter_config(const SQL_ROW &a); + splitter_config(const std::string &s,const char *tag="splitter_config"); + splitter_config &operator =(const splitter_config &a); + std::string update_format() const; + std::string insert_format() const; + std::string select_format() const; + std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; + std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="splitter_config") const; + void parse(const SQL_ROW &s); + void parse(const std::string &s); + void parse_xml(const std::string &s,const char *tag="splitter_config"); + private: +}; + + +class analysis_config : public db_table { + public: + long id; + double spike_thresh; + long spikes_per_spectrum; + double autocorr_thresh; + long autocorr_per_spectrum; + long autocorr_fftlen; + double gauss_null_chi_sq_thresh; + double gauss_chi_sq_thresh; + double gauss_power_thresh; + double gauss_peak_power_thresh; + long gauss_pot_length; + double pulse_thresh; + double pulse_display_thresh; + long pulse_max; + long pulse_min; + long pulse_fft_max; + long pulse_pot_length; + double triplet_thresh; + long triplet_max; + long triplet_min; + long triplet_pot_length; + double pot_overlap_factor; + double pot_t_offset; + double pot_min_slew; + double pot_max_slew; + double chirp_resolution; + long analysis_fft_lengths; + long bsmooth_boxcar_length; + long bsmooth_chunk_size; + sqlblob chirps ; + double pulse_beams; + long max_signals; + long max_spikes; + long max_autocorr; + long max_gaussians; + long max_pulses; + long max_triplets; + long keyuniq; + double credit_rate; + analysis_config(); + analysis_config(const analysis_config &a); + analysis_config(const SQL_ROW &a); + analysis_config(const std::string &s,const char *tag="analysis_config"); + analysis_config &operator =(const analysis_config &a); + std::string update_format() const; + std::string insert_format() const; + std::string select_format() const; + std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; + std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="analysis_config") const; + void parse(const SQL_ROW &s); + void parse(const std::string &s); + void parse_xml(const std::string &s,const char *tag="analysis_config"); + private: +}; + + +class science_config : public db_table { + public: + long id; + long active; + char qpix_scheme[16]; + long qpix_nside; + double fpix_width; + double total_bandwidth; + double freq_uncertainty; + double fwhm_beamwidth; + double sky_disc_radius; + double observable_sky; + long epoch; + double bary_chirp_window; + long bary_freq_window; + long nonbary_freq_window; + double spike_obs_duration; + double spike_obs_interval; + double gauss_obs_duration; + double gauss_obs_interval; + double pulse_obs_duration; + double pulse_obs_interval; + double triplet_obs_duration; + double triplet_obs_interval; + sqlint8_t min_spike_id; + sqlint8_t min_autocorr_id; + sqlint8_t min_gaussian_id; + sqlint8_t min_pulse_id; + sqlint8_t min_triplet_id; + double min_app_version; + char info_xml[255]; + science_config(); + science_config(const science_config &a); + science_config(const SQL_ROW &a); + science_config(const std::string &s,const char *tag="science_config"); + science_config &operator =(const science_config &a); + std::string update_format() const; + std::string insert_format() const; + std::string select_format() const; + std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; + std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="science_config") const; + void parse(const SQL_ROW &s); + void parse(const std::string &s); + void parse_xml(const std::string &s,const char *tag="science_config"); + private: +}; + + +class candidate_t : public db_type { + public: + long type; + sqlint8_t id; + long num_obs; + double score; + long is_rfi; + candidate_t(); + candidate_t(const candidate_t &a); + candidate_t(const SQL_ROW &a); + candidate_t(const std::string &s,const char *tag="candidate_t"); + candidate_t &operator =(const candidate_t &a); + std::string update_format() const; + std::string insert_format() const; + std::string select_format() const; + std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; + std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="candidate_t") const; + void parse(const SQL_ROW &s); + void parse(const std::string &s); + void parse_xml(const std::string &s,const char *tag="candidate_t"); + private: +}; + + +class meta_candidate : public db_table { + public: + sqlint8_t id; + long version; + double time_last_updated; + long num_spikes; + long num_spike_b_multiplets; + double best_spike_b_mp_score; + long num_spike_nb_multiplets; + double best_spike_nb_mp_score; + sqlint8_t spike_high_id; + long num_gaussians; + long num_gaussian_b_multiplets; + double best_gaussian_b_mp_score; + long num_gaussian_nb_multiplets; + double best_gaussian_nb_mp_score; + sqlint8_t gaussian_high_id; + long num_pulses; + long num_pulse_b_multiplets; + double best_pulse_b_mp_score; + long num_pulse_nb_multiplets; + double best_pulse_nb_mp_score; + sqlint8_t pulse_high_id; + long num_triplets; + long num_triplet_b_multiplets; + double best_triplet_b_mp_score; + long num_triplet_nb_multiplets; + double best_triplet_nb_mp_score; + sqlint8_t triplet_high_id; + long num_stars; + double best_star_score; + double meta_score; + long rfi_clean; + long state; + meta_candidate(); + meta_candidate(const meta_candidate &a); + meta_candidate(const SQL_ROW &a); + meta_candidate(const std::string &s,const char *tag="meta_candidate"); + meta_candidate &operator =(const meta_candidate &a); + std::string update_format() const; + std::string insert_format() const; + std::string select_format() const; + std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; + std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="meta_candidate") const; + void parse(const SQL_ROW &s); + void parse(const std::string &s); + void parse_xml(const std::string &s,const char *tag="meta_candidate"); + private: +}; + + +class multiplet : public db_table { + public: + long id; + long version; + long signal_type; + long mp_type; + long qpix; + double freq_win; + double mean_ra; + double mean_decl; + double ra_stddev; + double decl_stddev; + double mean_angular_distance; + double angular_distance_stddev; + double mean_frequency; + double frequency_stddev; + double mean_chirp; + double chirp_stddev; + double mean_period; + double period_stddev; + double mean_snr; + double snr_stddev; + double mean_threshold; + double threshold_stddev; + double score; + long num_detections; + sqlblob signal_ids ; + multiplet(); + multiplet(const multiplet &a); + multiplet(const SQL_ROW &a); + multiplet(const std::string &s,const char *tag="multiplet"); + multiplet &operator =(const multiplet &a); + std::string update_format() const; + std::string insert_format() const; + std::string select_format() const; + std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; + std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="multiplet") const; + void parse(const SQL_ROW &s); + void parse(const std::string &s); + void parse_xml(const std::string &s,const char *tag="multiplet"); + private: +}; + + +class star : public db_table { + public: + long id; + char object_type[16]; + char catalog_name[64]; + long catalog_number; + char object_name[64]; + double ra; + double decl; + long qpix; + double v_mag; + double b_minus_v; + double parallax; + char stellar_type[32]; + long planets; + double score; + star(); + star(const star &a); + star(const SQL_ROW &a); + star(const std::string &s,const char *tag="star"); + star &operator =(const star &a); + std::string update_format() const; + std::string insert_format() const; + std::string select_format() const; + std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; + std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="star") const; + void parse(const SQL_ROW &s); + void parse(const std::string &s); + void parse_xml(const std::string &s,const char *tag="star"); + private: +}; + + +class candidate_count : public db_table { + public: + long id; + sqlint8_t spikes; + sqlint8_t gaussians; + sqlint8_t pulses; + sqlint8_t triplets; + sqlint8_t spike_barycentric_multiplets; + sqlint8_t gaussian_barycentric_multiplets; + sqlint8_t pulse_barycentric_multiplets; + sqlint8_t triplet_barycentric_multiplets; + sqlint8_t spike_nonbarycentric_multiplets; + sqlint8_t gaussian_nonbarycentric_multiplets; + sqlint8_t pulse_nonbarycentric_multiplets; + sqlint8_t triplet_nonbarycentric_multiplets; + sqlint8_t stars; + long time_last_updated; + candidate_count(); + candidate_count(const candidate_count &a); + candidate_count(const SQL_ROW &a); + candidate_count(const std::string &s,const char *tag="candidate_count"); + candidate_count &operator =(const candidate_count &a); + std::string update_format() const; + std::string insert_format() const; + std::string select_format() const; + std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; + std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="candidate_count") const; + void parse(const SQL_ROW &s); + void parse(const std::string &s); + void parse_xml(const std::string &s,const char *tag="candidate_count"); + private: +}; + + +class tape : public db_table { + public: + long id; + char name[20]; + double start_time; + double last_block_time; + long last_block_done; + long missed; + long tape_quality; + long beam; + tape(); + tape(const tape &a); + tape(const SQL_ROW &a); + tape(const std::string &s,const char *tag="tape"); + tape &operator =(const tape &a); + std::string update_format() const; + std::string insert_format() const; + std::string select_format() const; + std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; + std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="tape") const; + void parse(const SQL_ROW &s); + void parse(const std::string &s); + void parse_xml(const std::string &s,const char *tag="tape"); + private: +}; + + +class settings : public db_table { + public: + long id; + long active; + db_reference recorder_cfg; + db_reference splitter_cfg; + db_reference analysis_cfg; + db_reference receiver_cfg; + settings(); + settings(const settings &a); + settings(const SQL_ROW &a); + settings(const std::string &s,const char *tag="settings"); + settings &operator =(const settings &a); + std::string update_format() const; + std::string insert_format() const; + std::string select_format() const; + std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; + std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="settings") const; + void parse(const SQL_ROW &s); + void parse(const std::string &s); + void parse_xml(const std::string &s,const char *tag="settings"); + private: +}; + + +class workunit_grp : public db_table { + public: + long id; + db_reference tape_info; + char name[64]; + data_description_t data_desc; + db_reference receiver_cfg; + db_reference recorder_cfg; + db_reference splitter_cfg; + db_reference analysis_cfg; + long sb_id; + workunit_grp(); + workunit_grp(const workunit_grp &a); + workunit_grp(const SQL_ROW &a); + workunit_grp(const std::string &s,const char *tag="workunit_grp"); + workunit_grp &operator =(const workunit_grp &a); + std::string update_format() const; + std::string insert_format() const; + std::string select_format() const; + std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; + std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="workunit_grp") const; + void parse(const SQL_ROW &s); + void parse(const std::string &s); + void parse_xml(const std::string &s,const char *tag="workunit_grp"); + private: +}; + + +class workunit_header : public db_table { + public: + sqlint8_t id; + char name[64]; + db_reference group_info; + subband_description_t subband_desc; + sqlint8_t sb_id; + workunit_header(); + workunit_header(const workunit_header &a); + workunit_header(const SQL_ROW &a); + workunit_header(const std::string &s,const char *tag="workunit_header"); + workunit_header &operator =(const workunit_header &a); + std::string update_format() const; + std::string insert_format() const; + std::string select_format() const; + std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; + std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="workunit_header") const; + void parse(const SQL_ROW &s); + void parse(const std::string &s); + void parse_xml(const std::string &s,const char *tag="workunit_header"); + private: +}; + + +typedef workunit_header workunit; +class result : public db_table { + public: + sqlint8_t id; + sqlint8_t boinc_result; + db_reference wuid; + double received; + long hostid; + long versionid; + long return_code; + long overflow; + long reserved; + sqlint8_t sb_id; + result(); + result(const result &a); + result(const SQL_ROW &a); + result(const std::string &s,const char *tag="result"); + result &operator =(const result &a); + std::string update_format() const; + std::string insert_format() const; + std::string select_format() const; + std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; + std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="result") const; + void parse(const SQL_ROW &s); + void parse(const std::string &s); + void parse_xml(const std::string &s,const char *tag="result"); + private: +}; + + +class triplet : public db_table { + public: + sqlint8_t id; + db_reference result_id; + double peak_power; + double mean_power; + double time; + double ra; + double decl; + sqlint8_t q_pix; + double freq; + double detection_freq; + double barycentric_freq; + long fft_len; + double chirp_rate; + long rfi_checked; + long rfi_found; + long reserved; + double period; + triplet(); + triplet(const triplet &a); + triplet(const SQL_ROW &a); + triplet(const std::string &s,const char *tag="triplet"); + triplet &operator =(const triplet &a); + std::string update_format() const; + std::string insert_format() const; + std::string select_format() const; + std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; + std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="triplet") const; + void parse(const SQL_ROW &s); + void parse(const std::string &s); + void parse_xml(const std::string &s,const char *tag="triplet"); + private: +}; + + +class triplet_small : public db_table { + public: + sqlint8_t id; + db_reference result_id; + double peak_power; + double mean_power; + double time; + double ra; + double decl; + sqlint8_t q_pix; + double freq; + double detection_freq; + double barycentric_freq; + long fft_len; + double chirp_rate; + long rfi_checked; + long rfi_found; + long reserved; + double period; + triplet_small(); + triplet_small(const triplet_small &a); + triplet_small(const SQL_ROW &a); + triplet_small(const std::string &s,const char *tag="triplet_small"); + triplet_small &operator =(const triplet_small &a); + std::string update_format() const; + std::string insert_format() const; + std::string select_format() const; + std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; + std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="triplet_small") const; + void parse(const SQL_ROW &s); + void parse(const std::string &s); + void parse_xml(const std::string &s,const char *tag="triplet_small"); + private: +}; + + +class gaussian : public db_table { + public: + sqlint8_t id; + db_reference result_id; + double peak_power; + double mean_power; + double time; + double ra; + double decl; + sqlint8_t q_pix; + double freq; + double detection_freq; + double barycentric_freq; + long fft_len; + double chirp_rate; + long rfi_checked; + long rfi_found; + long reserved; + double sigma; + double chisqr; + double null_chisqr; + double score; + double max_power; + sqlblob pot; + gaussian(); + gaussian(const gaussian &a); + gaussian(const SQL_ROW &a); + gaussian(const std::string &s,const char *tag="gaussian"); + gaussian &operator =(const gaussian &a); + std::string update_format() const; + std::string insert_format() const; + std::string select_format() const; + std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; + std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="gaussian") const; + void parse(const SQL_ROW &s); + void parse(const std::string &s); + void parse_xml(const std::string &s,const char *tag="gaussian"); + private: +}; + + +class gaussian_small : public db_table { + public: + sqlint8_t id; + db_reference result_id; + double peak_power; + double mean_power; + double time; + double ra; + double decl; + sqlint8_t q_pix; + double freq; + double detection_freq; + double barycentric_freq; + long fft_len; + double chirp_rate; + long rfi_checked; + long rfi_found; + long reserved; + double sigma; + double chisqr; + double null_chisqr; + double score; + double max_power; + gaussian_small(); + gaussian_small(const gaussian_small &a); + gaussian_small(const SQL_ROW &a); + gaussian_small(const std::string &s,const char *tag="gaussian_small"); + gaussian_small &operator =(const gaussian_small &a); + std::string update_format() const; + std::string insert_format() const; + std::string select_format() const; + std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; + std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="gaussian_small") const; + void parse(const SQL_ROW &s); + void parse(const std::string &s); + void parse_xml(const std::string &s,const char *tag="gaussian_small"); + private: +}; + + +class pulse : public db_table { + public: + sqlint8_t id; + db_reference result_id; + double peak_power; + double mean_power; + double time; + double ra; + double decl; + sqlint8_t q_pix; + double freq; + double detection_freq; + double barycentric_freq; + long fft_len; + double chirp_rate; + long rfi_checked; + long rfi_found; + long reserved; + double period; + double snr; + double thresh; + double score; + long len_prof; + sqlblob pot; + pulse(); + pulse(const pulse &a); + pulse(const SQL_ROW &a); + pulse(const std::string &s,const char *tag="pulse"); + pulse &operator =(const pulse &a); + std::string update_format() const; + std::string insert_format() const; + std::string select_format() const; + std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; + std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="pulse") const; + void parse(const SQL_ROW &s); + void parse(const std::string &s); + void parse_xml(const std::string &s,const char *tag="pulse"); + private: +}; + + +class pulse_small : public db_table { + public: + sqlint8_t id; + db_reference result_id; + double peak_power; + double mean_power; + double time; + double ra; + double decl; + sqlint8_t q_pix; + double freq; + double detection_freq; + double barycentric_freq; + long fft_len; + double chirp_rate; + long rfi_checked; + long rfi_found; + long reserved; + double period; + double snr; + double thresh; + double score; + pulse_small(); + pulse_small(const pulse_small &a); + pulse_small(const SQL_ROW &a); + pulse_small(const std::string &s,const char *tag="pulse_small"); + pulse_small &operator =(const pulse_small &a); + std::string update_format() const; + std::string insert_format() const; + std::string select_format() const; + std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; + std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="pulse_small") const; + void parse(const SQL_ROW &s); + void parse(const std::string &s); + void parse_xml(const std::string &s,const char *tag="pulse_small"); + private: +}; + + +class sah_pointing : public db_table { + public: + long time_id; + double time; + double ra; + double dec; + long q_pix; + double angle_range; + long bad; + sah_pointing(); + sah_pointing(const sah_pointing &a); + sah_pointing(const SQL_ROW &a); + sah_pointing(const std::string &s,const char *tag="sah_pointing"); + sah_pointing &operator =(const sah_pointing &a); + std::string update_format() const; + std::string insert_format() const; + std::string select_format() const; + std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; + std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="sah_pointing") const; + void parse(const SQL_ROW &s); + void parse(const std::string &s); + void parse_xml(const std::string &s,const char *tag="sah_pointing"); + private: +}; + + +class sky_map : public db_table { + public: + sqlint8_t npix; + long qpix; + long fpix; + sqlint8_t spike_max_id; + sqlint8_t gaussian_max_id; + sqlint8_t pulse_max_id; + sqlint8_t triplet_max_id; + long spike_count; + long gaussian_count; + long pulse_count; + long triplet_count; + long new_data; + double score; + sky_map(); + sky_map(const sky_map &a); + sky_map(const SQL_ROW &a); + sky_map(const std::string &s,const char *tag="sky_map"); + sky_map &operator =(const sky_map &a); + std::string update_format() const; + std::string insert_format() const; + std::string select_format() const; + std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; + std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="sky_map") const; + void parse(const SQL_ROW &s); + void parse(const std::string &s); + void parse_xml(const std::string &s,const char *tag="sky_map"); + private: +}; + + +class hotpix : public db_table { + public: + long id; + long last_hit_time; + hotpix(); + hotpix(const hotpix &a); + hotpix(const SQL_ROW &a); + hotpix(const std::string &s,const char *tag="hotpix"); + hotpix &operator =(const hotpix &a); + std::string update_format() const; + std::string insert_format() const; + std::string select_format() const; + std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; + std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="hotpix") const; + void parse(const SQL_ROW &s); + void parse(const std::string &s); + void parse_xml(const std::string &s,const char *tag="hotpix"); + private: +}; + + +class spike : public db_table { + public: + sqlint8_t id; + db_reference result_id; + double peak_power; + double mean_power; + double time; + double ra; + double decl; + sqlint8_t q_pix; + double freq; + double detection_freq; + double barycentric_freq; + long fft_len; + double chirp_rate; + long rfi_checked; + long rfi_found; + long reserved; + spike(); + spike(const spike &a); + spike(const SQL_ROW &a); + spike(const std::string &s,const char *tag="spike"); + spike &operator =(const spike &a); + std::string update_format() const; + std::string insert_format() const; + std::string select_format() const; + std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; + std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="spike") const; + void parse(const SQL_ROW &s); + void parse(const std::string &s); + void parse_xml(const std::string &s,const char *tag="spike"); + private: +}; + + +class spike_small : public db_table { + public: + sqlint8_t id; + db_reference result_id; + double peak_power; + double mean_power; + double time; + double ra; + double decl; + sqlint8_t q_pix; + double freq; + double detection_freq; + double barycentric_freq; + long fft_len; + double chirp_rate; + long rfi_checked; + long rfi_found; + long reserved; + spike_small(); + spike_small(const spike_small &a); + spike_small(const SQL_ROW &a); + spike_small(const std::string &s,const char *tag="spike_small"); + spike_small &operator =(const spike_small &a); + std::string update_format() const; + std::string insert_format() const; + std::string select_format() const; + std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; + std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="spike_small") const; + void parse(const SQL_ROW &s); + void parse(const std::string &s); + void parse_xml(const std::string &s,const char *tag="spike_small"); + private: +}; + + +class autocorr : public db_table { + public: + sqlint8_t id; + db_reference result_id; + double peak_power; + double mean_power; + double time; + double ra; + double decl; + sqlint8_t q_pix; + double delay; + double freq; + double detection_freq; + double barycentric_freq; + long fft_len; + double chirp_rate; + long rfi_checked; + long rfi_found; + long reserved; + autocorr(); + autocorr(const autocorr &a); + autocorr(const SQL_ROW &a); + autocorr(const std::string &s,const char *tag="autocorr"); + autocorr &operator =(const autocorr &a); + std::string update_format() const; + std::string insert_format() const; + std::string select_format() const; + std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; + std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="autocorr") const; + void parse(const SQL_ROW &s); + void parse(const std::string &s); + void parse_xml(const std::string &s,const char *tag="autocorr"); + private: +}; + + +class autocorr_small : public db_table { + public: + sqlint8_t id; + db_reference result_id; + double peak_power; + double mean_power; + double time; + double ra; + double decl; + sqlint8_t q_pix; + double delay; + double freq; + double detection_freq; + double barycentric_freq; + long fft_len; + double chirp_rate; + long rfi_checked; + long rfi_found; + long reserved; + autocorr_small(); + autocorr_small(const autocorr_small &a); + autocorr_small(const SQL_ROW &a); + autocorr_small(const std::string &s,const char *tag="autocorr_small"); + autocorr_small &operator =(const autocorr_small &a); + std::string update_format() const; + std::string insert_format() const; + std::string select_format() const; + std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; + std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="autocorr_small") const; + void parse(const SQL_ROW &s); + void parse(const std::string &s); + void parse_xml(const std::string &s,const char *tag="autocorr_small"); + private: +}; + + +class classic_versions : public db_table { + public: + long id; + long ver_major; + long ver_minor; + long platformid; + char comment[254]; + char filename[254]; + char md5_cksum[254]; + char sum_cksum[254]; + char cksum_cksum[254]; + long file_cksum; + classic_versions(); + classic_versions(const classic_versions &a); + classic_versions(const SQL_ROW &a); + classic_versions(const std::string &s,const char *tag="classic_versions"); + classic_versions &operator =(const classic_versions &a); + std::string update_format() const; + std::string insert_format() const; + std::string select_format() const; + std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; + std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="classic_versions") const; + void parse(const SQL_ROW &s); + void parse(const std::string &s); + void parse_xml(const std::string &s,const char *tag="classic_versions"); + private: +}; + + +class classic_active_versions : public db_table { + public: + long id; + long versionid; + long ver_major; + long ver_minor; + classic_active_versions(); + classic_active_versions(const classic_active_versions &a); + classic_active_versions(const SQL_ROW &a); + classic_active_versions(const std::string &s,const char *tag="classic_active_versions"); + classic_active_versions &operator =(const classic_active_versions &a); + std::string update_format() const; + std::string insert_format() const; + std::string select_format() const; + std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; + std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="classic_active_versions") const; + void parse(const SQL_ROW &s); + void parse(const std::string &s); + void parse_xml(const std::string &s,const char *tag="classic_active_versions"); + private: +}; + + +class classic_active_versionids : public db_table { + public: + long id; + long versionid; + classic_active_versionids(); + classic_active_versionids(const classic_active_versionids &a); + classic_active_versionids(const SQL_ROW &a); + classic_active_versionids(const std::string &s,const char *tag="classic_active_versionids"); + classic_active_versionids &operator =(const classic_active_versionids &a); + std::string update_format() const; + std::string insert_format() const; + std::string select_format() const; + std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; + std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="classic_active_versionids") const; + void parse(const SQL_ROW &s); + void parse(const std::string &s); + void parse_xml(const std::string &s,const char *tag="classic_active_versionids"); + private: +}; + + +class rfi_zone : public db_table { + public: + long id; + long min_receiver_s4id; + long max_receiver_s4id; + long min_splitter_config; + long max_splitter_config; + long min_analysis_config; + long max_analysis_config; + long min_tape_id; + long max_tape_id; + sqlint8_t min_workunit_id; + sqlint8_t max_workunit_id; + sqlint8_t min_result_id; + sqlint8_t max_result_id; + double min_time; + double max_time; + double central_baseband_freq; + double baseband_freq_width; + double central_detection_freq; + double detection_freq_width; + double central_period; + double period_width; + long fft_len_flags; + long signal_type_flags; + double ra; + double dec; + double angular_distance; + rfi_zone(); + rfi_zone(const rfi_zone &a); + rfi_zone(const SQL_ROW &a); + rfi_zone(const std::string &s,const char *tag="rfi_zone"); + rfi_zone &operator =(const rfi_zone &a); + std::string update_format() const; + std::string insert_format() const; + std::string select_format() const; + std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; + std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="rfi_zone") const; + void parse(const SQL_ROW &s); + void parse(const std::string &s); + void parse_xml(const std::string &s,const char *tag="rfi_zone"); + private: +}; + + +class bad_data : public db_table { + public: + char name[20]; + long beam; + char reason[255]; + bad_data(); + bad_data(const bad_data &a); + bad_data(const SQL_ROW &a); + bad_data(const std::string &s,const char *tag="bad_data"); + bad_data &operator =(const bad_data &a); + std::string update_format() const; + std::string insert_format() const; + std::string select_format() const; + std::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const; + std::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag="bad_data") const; + void parse(const SQL_ROW &s); + void parse(const std::string &s); + void parse_xml(const std::string &s,const char *tag="bad_data"); + private: +}; + + +#endif diff --git a/db/schema_master.sql b/db/schema_master.sql new file mode 100644 index 0000000..8f0a448 --- /dev/null +++ b/db/schema_master.sql @@ -0,0 +1,854 @@ +-- Copyright 2003 Regents of the University of California + +-- SETI_BOINC is free software; you can redistribute it and/or modify it under +-- the terms of the GNU General Public License as published by the Free +-- Software Foundation; either version 2, or (at your option) any later +-- version. + +-- SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +-- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +-- more details. + +-- You should have received a copy of the GNU General Public License along +-- with SETI_BOINC; see the file COPYING. If not, write to the Free Software +-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +-- In addition, as a special exception, the Regents of the University of +-- California give permission to link the code of this program with libraries +-- that provide specific optimized fast Fourier transform (FFT) functions and +-- distribute a linked executable. You must obey the GNU General Public +-- License in all respects for all of the code used other than the FFT library +-- itself. Any modification required to support these libraries must be +-- distributed in source code form. If you modify this file, you may extend +-- this exception to your version of the file, but you are not obligated to +-- do so. If you do not wish to do so, delete this exception statement from +-- your version. + + +create database sah2b@sah_master_tcp in sah2dbs; -- informix + + +create row type coordinate_t +( + time float, + ra float, + dec float +); + + + +create row type chirp_parameter_t + ( + chirp_limit smallfloat, + fft_len_flags integer -- bitfield + ); + + + +create row type subband_description_t + ( + number integer, + center float, + base float, + sample_rate float + ); + + + +create row type data_description_t + ( + start_ra float, + start_dec float, + end_ra float, + end_dec float, + true_angle_range smallfloat, + time_recorded varchar(255), + time_recorded_jd float, + nsamples integer, + coords list(coordinate_t not null) + ); + + +create table receiver_config + ( + id serial primary key, + s4_id integer unique, + name varchar(255) unique, + beam_width smallfloat, -- degrees + center_freq float, -- MHz + latitude float, + longitude float, + elevation float, + diameter smallfloat, + az_orientation float, + az_corr_coeff list(float not null), + zen_corr_coeff list(float not null), + array_az_ellipse float default 0 not null, + array_za_ellipse float default 0 not null, + array_angle float default 0 not null, + min_vgc integer default 0 + ); + + + +create table recorder_config + ( + id serial primary key, + name char(64), + bits_per_sample integer, + sample_rate float, + beams integer, + version smallfloat unique + ); + + + +create table splitter_config + ( + id serial primary key, + version smallfloat, + data_type char(64), + fft_len integer, + ifft_len integer, + filter char(64), + window char(64), + samples_per_wu integer default 1048576 not null, + highpass smallfloat default 0 not null, + blanker_filter char(64) default "none" not null + ); + + + + +create table analysis_config + ( + id serial primary key, + spike_thresh smallfloat, + spikes_per_spectrum integer, + autocorr_thresh smallfloat, + autocorr_per_spectrum integer, + autocorr_fftlen integer, + gauss_null_chi_sq_thresh smallfloat, + gauss_chi_sq_thresh smallfloat, + gauss_power_thresh smallfloat, + gauss_peak_power_thresh smallfloat, + gauss_pot_length integer, + pulse_thresh smallfloat, + pulse_display_thresh smallfloat, + pulse_max integer, + pulse_min integer, + pulse_fft_max integer, + pulse_pot_length integer, + triplet_thresh smallfloat, + triplet_max integer, + triplet_min integer, + triplet_pot_length integer, + pot_overlap_factor smallfloat, + pot_t_offset smallfloat, + pot_min_slew smallfloat, + pot_max_slew smallfloat, + chirp_resolution float, + analysis_fft_lengths integer, -- bitfield + bsmooth_boxcar_length integer, + bsmooth_chunk_size integer, + chirps list(chirp_parameter_t not null), + pulse_beams smallfloat, + max_signals integer, + max_spikes integer, + max_autocorr integer, + max_gaussians integer, + max_pulses integer, + max_triplets integer, + keyuniq integer, + credit_rate smallfloat + ); + +create table science_config + ( + id serial primary key, + active integer not null, + qpix_scheme char(16) not null, + qpix_nside integer not null, + fpix_width float not null, + total_bandwidth float not null, + freq_uncertainty float not null, + fwhm_beamwidth float not null, + sky_disc_radius float not null, + observable_sky float not null, + epoch integer not null, + bary_chirp_window float not null, + bary_freq_window integer not null, + nonbary_freq_window integer not null, + spike_obs_duration float not null, + spike_obs_interval float not null, + gauss_obs_duration float not null, + gauss_obs_interval float not null, + pulse_obs_duration float not null, + pulse_obs_interval float not null, + triplet_obs_duration float not null, + triplet_obs_interval float not null, + min_spike_id int8, + min_autocorr_id int8, + min_gaussian_id int8, + min_pulse_id int8, + min_triplet_id int8, + min_app_version float not null, + info_xml varchar(255) + ); + + +create row type candidate_t + ( + type integer not null, + id int8 not null, + num_obs integer not null, + score float not null, + is_rfi integer not null -- bitfield + ); + + +create table meta_candidate + ( + id serial8 not null, + version integer not null, + time_last_updated float not null, + num_spikes integer not null, + num_spike_b_multiplets integer not null, + best_spike_b_mp_score float not null, + num_spike_nb_multiplets integer not null, + best_spike_nb_mp_score float not null, + spike_high_id int8 not null, + num_gaussians integer not null, + num_gaussian_b_multiplets integer not null, + best_gaussian_b_mp_score float not null, + num_gaussian_nb_multiplets integer not null, + best_gaussian_nb_mp_score float not null, + gaussian_high_id int8 not null, + num_pulses integer not null, + num_pulse_b_multiplets integer not null, + best_pulse_b_mp_score float not null, + num_pulse_nb_multiplets integer not null, + best_pulse_nb_mp_score float not null, + pulse_high_id int8 not null, + num_triplets integer not null, + num_triplet_b_multiplets integer not null, + best_triplet_b_mp_score float not null, + num_triplet_nb_multiplets integer not null, + best_triplet_nb_mp_score float not null, + triplet_high_id int8 not null, + num_stars integer not null, + best_star_score float not null, + meta_score float not null, + rfi_clean integer, + state smallint -- 0 : the ntpckr has (re)scored this MC - rfi should look at it + -- 1 : the signal set has changed - ntpckr should look at it + -- 2 : this is a stable and clean candidate + ); + + +create table multiplet + ( + id serial primary key, + version integer not null, + signal_type int not null, + mp_type int not null, + qpix integer not null, + freq_win float not null, + mean_ra float not null, + mean_decl float not null, + ra_stddev float not null, + decl_stddev float not null, + mean_angular_distance float not null, + angular_distance_stddev float not null, + mean_frequency float not null, + frequency_stddev float not null, + mean_chirp float not null, + chirp_stddev float not null, + mean_period float not null, + period_stddev float not null, + mean_snr float not null, + snr_stddev float not null, + mean_threshold float not null, + threshold_stddev float not null, + score float not null, + num_detections integer not null, + signal_ids list(int8 not null) + ); + +create table star + ( + id integer not null, + object_type varchar(16) not null, + catalog_name varchar(64), + catalog_number integer, + object_name varchar(64), + ra smallfloat not null, + decl smallfloat not null, + qpix integer, + v_mag smallfloat, + b_minus_v smallfloat, + parallax smallfloat, + stellar_type varchar(32), + planets integer, + score smallfloat + ); + +create table candidate_count + ( + id integer not null, + spikes int8 not null, + gaussians int8 not null, + pulses int8 not null, + triplets int8 not null, + spike_barycentric_multiplets int8 not null, + gaussian_barycentric_multiplets int8 not null, + pulse_barycentric_multiplets int8 not null, + triplet_barycentric_multiplets int8 not null, + spike_nonbarycentric_multiplets int8 not null, + gaussian_nonbarycentric_multiplets int8 not null, + pulse_nonbarycentric_multiplets int8 not null, + triplet_nonbarycentric_multiplets int8 not null, + stars int8 not null, + time_last_updated integer not null + ); + +create table tape + ( + id serial primary key, + name char(20) not null , + start_time float not null , + last_block_time float not null , + last_block_done integer not null , + missed integer not null , + tape_quality integer, + beam integer default 0 not null +-- , + -- unique (name,beam) constraint uniq_namebeam + ); + + + +create table settings ( + id serial primary key, + active integer, + recorder_cfg integer references recorder_config, + splitter_cfg integer references splitter_config, + analysis_cfg integer references analysis_config, + receiver_cfg integer references receiver_config +); + + + + +create table workunit_grp + ( + id serial primary key, + tape_info integer not null , --references tape + name char(64) not null , + data_desc data_description_t, + receiver_cfg integer references receiver_config, + recorder_cfg integer references recorder_config, + splitter_cfg integer references splitter_config, + analysis_cfg integer references analysis_config, + sb_id integer + ); + + + +create table workunit_header + ( + id serial8 primary key, + name char(64) not null , + group_info integer not null , -- references workunit_grp + subband_desc subband_description_t, + sb_id int8 + ) + fragment by expression + (mod(id,4)=0) in other_dbs001, + (mod(id,4)=1) in other_dbs002, + (mod(id,4)=2) in other_dbs003, + (mod(id,4)=3) in other_dbs004 + extent size 209714 next size 204714; + +create synonym workunit for workunit_header; + + + +create table result + ( + id serial8 primary key, + boinc_result int8 not null, + wuid int8 not null , -- references workunit_header + received float not null, + hostid integer not null, + versionid integer not null, + return_code integer not null, + overflow smallint not null, + reserved integer not null, + sb_id int8 + ) + fragment by expression + (mod(id,4)=0) in other_dbs001, + (mod(id,4)=1) in other_dbs002, + (mod(id,4)=2) in other_dbs003, + (mod(id,4)=3) in other_dbs004 + extent size 209714 next size 204714; + + + +create table triplet + ( + id serial8 not null , + result_id int8, -- references result + peak_power smallfloat not null , + mean_power smallfloat not null , + time float not null , + ra smallfloat not null , + decl smallfloat not null , + q_pix int8 not null , + freq float not null , + detection_freq float not null, + barycentric_freq float not null, + fft_len integer not null , + chirp_rate smallfloat not null , + rfi_checked int, + rfi_found int, + reserved integer, + period smallfloat not null + ) + fragment by expression + (mod(id,4)=0) in page_16k_dbs1, + (mod(id,4)=1) in page_16k_dbs2, + (mod(id,4)=2) in page_16k_dbs3, + (mod(id,4)=3) in page_16k_dbs4 + extent size 1048576 next size 1048576; + +create table triplet_small + ( + id serial8 not null , + result_id int8, -- references result + peak_power smallfloat not null , + mean_power smallfloat not null , + time float not null , + ra smallfloat not null , + decl smallfloat not null , + q_pix int8 not null , + freq float not null , + detection_freq float not null, + barycentric_freq float not null, + fft_len integer not null , + chirp_rate smallfloat not null , + rfi_checked int, + rfi_found int, + reserved integer, + period smallfloat not null + ) + fragment by expression + (mod(id,4)=0) in small_sig_dbs1, + (mod(id,4)=1) in small_sig_dbs2, + (mod(id,4)=2) in small_sig_dbs3, + (mod(id,4)=3) in small_sig_dbs4 + extent size 209714 next size 204714; + + +create table gaussian + ( + id serial8 not null , + result_id int8, -- references result + peak_power smallfloat not null , + mean_power smallfloat not null , + time float not null , + ra smallfloat not null , + decl smallfloat not null , + q_pix int8 not null , + freq float not null , + detection_freq float not null, + barycentric_freq float not null, + fft_len integer not null , + chirp_rate smallfloat not null , + rfi_checked int, + rfi_found int, + reserved integer, + sigma smallfloat not null , + chisqr smallfloat not null , + null_chisqr smallfloat not null , + score smallfloat not null , + max_power smallfloat, + pot byte -- binary + ) + fragment by expression + (mod(id,4)=0) in page_16k_dbs5, + (mod(id,4)=1) in page_16k_dbs6, + (mod(id,4)=2) in page_16k_dbs7, + (mod(id,4)=3) in page_16k_dbs8 + extent size 1048576 next size 1048576; + +create table gaussian_small + ( + id serial8 not null , + result_id int8, -- references result + peak_power smallfloat not null , + mean_power smallfloat not null , + time float not null , + ra smallfloat not null , + decl smallfloat not null , + q_pix int8 not null , + freq float not null , + detection_freq float not null, + barycentric_freq float not null, + fft_len integer not null , + chirp_rate smallfloat not null , + rfi_checked int, + rfi_found int, + reserved integer, + sigma smallfloat not null , + chisqr smallfloat not null , + null_chisqr smallfloat not null , + score smallfloat not null , + max_power smallfloat + ) + fragment by expression + (mod(id,4)=0) in small_sig_dbs1, + (mod(id,4)=1) in small_sig_dbs2, + (mod(id,4)=2) in small_sig_dbs3, + (mod(id,4)=3) in small_sig_dbs4 + extent size 209714 next size 204714; + + +create table pulse + ( + id serial8 not null , + result_id int8, -- references result + peak_power smallfloat not null , + mean_power smallfloat not null , + time float not null , + ra smallfloat not null , + decl smallfloat not null , + q_pix int8 not null , + freq float not null , + detection_freq float not null, + barycentric_freq float not null, + fft_len integer not null , + chirp_rate smallfloat not null , + rfi_checked int, + rfi_found int, + reserved integer, + period smallfloat not null , + snr smallfloat not null , + thresh smallfloat not null , + score smallfloat not null , + len_prof smallint not null , + pot byte -- binary + ) + fragment by expression + (mod(id,4)=0) in other_dbs001, + (mod(id,4)=1) in other_dbs002, + (mod(id,4)=2) in other_dbs003, + (mod(id,4)=3) in other_dbs004 + extent size 209714 next size 204714; + +create table pulse_small + ( + id serial8 not null , + result_id int8, -- references result + peak_power smallfloat not null , + mean_power smallfloat not null , + time float not null , + ra smallfloat not null , + decl smallfloat not null , + q_pix int8 not null , + freq float not null , + detection_freq float not null, + barycentric_freq float not null, + fft_len integer not null , + chirp_rate smallfloat not null , + rfi_checked int, + rfi_found int, + reserved integer, + period smallfloat not null , + snr smallfloat not null , + thresh smallfloat not null , + score smallfloat not null + ) + fragment by expression + (mod(id,4)=0) in small_sig_dbs1, + (mod(id,4)=1) in small_sig_dbs2, + (mod(id,4)=2) in small_sig_dbs3, + (mod(id,4)=3) in small_sig_dbs4 + extent size 209714 next size 204714; + +create table sah_pointing + ( + time_id integer not null , + time float not null , + ra float not null , + dec float not null , + q_pix integer not null, + angle_range float not null , + bad smallint + ); + + +create table sky_map + ( + npix int8, -- the primary search key + qpix int, -- for fast spatial maps + fpix int, -- for fast frequency maps + spike_max_id int8 , + gaussian_max_id int8, + pulse_max_id int8, + triplet_max_id int8, + spike_count int, + gaussian_count int, + pulse_count int, + triplet_count int, + new_data smallint, -- a boolean + score float + ); + +create table hotpix + ( + id int, -- qpix + last_hit_time int + ); + + +create table spike + ( + id serial8 not null , + result_id int8, -- references result + peak_power smallfloat not null , + mean_power smallfloat not null , + time float not null , + ra smallfloat not null , + decl smallfloat not null , + q_pix int8 not null , + freq float not null , + detection_freq float not null, + barycentric_freq float not null, + fft_len integer not null , + chirp_rate smallfloat not null , + rfi_checked int, + rfi_found int, + reserved integer + ) + fragment by expression + (mod(id,4)=0) in spike21_dbs, + (mod(id,4)=1) in spike22_dbs, + (mod(id,4)=2) in spike23_dbs, + (mod(id,4)=3) in spike24_dbs + extent size 2047100 next size 2047100; + +create table spike_small + ( + id serial8 not null , + result_id int8, -- references result + peak_power smallfloat not null , + mean_power smallfloat not null , + time float not null , + ra smallfloat not null , + decl smallfloat not null , + q_pix int8 not null , + freq float not null , + detection_freq float not null, + barycentric_freq float not null, + fft_len integer not null , + chirp_rate smallfloat not null , + rfi_checked int, + rfi_found int, + reserved integer + ) + fragment by expression + (mod(id,4)=0) in small_sig_dbs1, + (mod(id,4)=1) in small_sig_dbs2, + (mod(id,4)=2) in small_sig_dbs3, + (mod(id,4)=3) in small_sig_dbs4 + extent size 209714 next size 204714; + + +create table autocorr + ( + id serial8 not null , + result_id int8, -- references result + peak_power smallfloat not null , + mean_power smallfloat not null , + time float not null , + ra smallfloat not null , + decl smallfloat not null , + q_pix int8 not null , + delay float not null , + freq float not null , + detection_freq float not null, + barycentric_freq float not null, + fft_len integer not null , + chirp_rate smallfloat not null , + rfi_checked int, + rfi_found int, + reserved integer + ) + fragment by expression + (mod(id,4)=0) in page_16k_dbs9, + (mod(id,4)=1) in page_16k_dbs10, + (mod(id,4)=2) in page_16k_dbs11, + (mod(id,4)=3) in page_16k_dbs12 + extent size 1048576 next size 1048576; + +create table autocorr_small + ( + id serial8 not null , + result_id int8, -- references result + peak_power smallfloat not null , + mean_power smallfloat not null , + time float not null , + ra smallfloat not null , + decl smallfloat not null , + q_pix int8 not null , + delay float not null , + freq float not null , + detection_freq float not null, + barycentric_freq float not null, + fft_len integer not null , + chirp_rate smallfloat not null , + rfi_checked int, + rfi_found int, + reserved integer, + ) + fragment by expression + (mod(id,4)=0) in small_sig_dbs1, + (mod(id,4)=1) in small_sig_dbs2, + (mod(id,4)=2) in small_sig_dbs3, + (mod(id,4)=3) in small_sig_dbs4 + extent size 209714 next size 204714; + + +create table classic_versions + ( + id serial not null, + ver_major integer not null, + ver_minor integer not null, + platformid integer not null, + comment char(254), + filename char(254), + md5_cksum char(254), + sum_cksum char(254), + cksum_cksum char(254), + file_cksum integer not null + ); + + + +create table classic_active_versions + ( + id integer, + versionid integer, + ver_major integer, + ver_minor integer + ); + + + +create table classic_active_versionids + ( + id integer, + versionid integer + ); + +create table rfi_zone + ( + id serial not null, + min_receiver_s4id integer not null, + max_receiver_s4id integer not null, + min_splitter_config integer not null, + max_splitter_config integer not null, + min_analysis_config integer not null, + max_analysis_config integer not null, + min_tape_id integer not null, + max_tape_id integer not null, + min_workunit_id int8 not null, + max_workunit_id int8 not null, + min_result_id int8 not null, + max_result_id int8 not null, + min_time float not null, + max_time float not null, + central_baseband_freq float not null, + baseband_freq_width float not null, + central_detection_freq float not null, + detection_freq_width float not null, + central_period float not null, + period_width float not null, + fft_len_flags int not null, + signal_type_flags int not null, + ra float not null, + dec float not null, + angular_distance float not null + ); + +create table bad_data + ( + name char(20) not null, + beam integer default 0 not null, + reason varchar(255) + ); + + +create index spike_res on spike(result_id); + + +create index autocorr_res on autocorr(result_id); + + +create index gaussian_res on gaussian(result_id); + + +create index pulse_res on pulse(result_id); + + +create index triplet_res on triplet(result_id); + + +create index result_wu on result(wuid); + + +create index workunit_wu_grp on workunit(group_info); + + + +create index wugrp_tapenum on workunit(tape_info); +alter table workunit_grp add constraint (foreign key + (tape_info) references tape (id)); + + +create index wu_grpnum on workunit(group_info); +alter table workunit add constraint (foreign key (group_info) + references workunit_grp (id)); + + +create index res_wuid on result(wuid); +alter table result add constraint (foreign key (wuid) + references workunit_header (id)), + add constraint unique(boinc_result); + + +create index trip_res on triplet(result_id); +alter table triplet add constraint (foreign key (result_id) + references result (id)); + + +crete index gauss-res on gaussian(result_id); +alter table gaussian add constraint (foreign key (result_id) + references result (id)); + + +create index pulse_res on pulse(result_id); +alter table pulse add constraint (foreign key (result_id) + references result (id)); + + +create index spike_res on spike(result_id); +alter table spike add constraint (foreign key (result_id) + references result (id) constraint result_spike); + +create unique index namebeam on tape (name, beam); + + diff --git a/db/schema_to_class.awk b/db/schema_to_class.awk new file mode 100644 index 0000000..a806330 --- /dev/null +++ b/db/schema_to_class.awk @@ -0,0 +1,742 @@ +# Copyright 2003-2005 Regents of the University of California + +# SETI_BOINC is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2, or (at your option) any later +# version. + +# SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. + +# You should have received a copy of the GNU General Public License along +# with SETI_BOINC; see the file COPYING. If not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# Copyright 2003-2005 Regents, University of California +# All rights reserved +# +# $Id: schema_to_class.awk,v 1.57.2.5 2007/03/29 01:08:22 korpela Exp $ +# +BEGIN { + print "processing BEGIN" + # Work around gawk FILENAME bug. + if ((FILENAME=="") || (FILENAME=="-")) { + tmpfilename=ARGV[ARGC-1] + headerfile=ARGV[ARGC-1]".h" + sourcefile=ARGV[ARGC-1]".cpp" + } else { + tmpfilename=FILENAME + headerfile=FILENAME".h" + sourcefile=FILENAME".cpp" + } + print "// This file is automatically generated. Do not edit" > sourcefile + print "// This file is automatically generated. Do not edit" > headerfile + print "#include \"sah_config.h\"" > sourcefile + print "" > sourcefile + print "#include " > sourcefile + print "#include " >sourcefile + print "#include " >sourcefile + print "#include " >sourcefile + print "#include " >sourcefile + print "#include " >sourcefile + print "#include " > sourcefile + print "" > sourcefile + print "#include \"parse.h\"" > sourcefile + print "#include \"xml_util.h\"" > sourcefile + print "#include \"db_table.h\"" >sourcefile + n=split(tmpfilename,a,"/") + print "#include \""a[n]".h\"" >sourcefile + print "\n#ifdef _WIN32" >sourcefile + print "#pragma warning( disable : 4355 )" >sourcefile + print "#endif\n" >sourcefile + print "#ifndef _H_"a[n]"_H" >headerfile + print "#define _H_"a[n]"_H" >headerfile + print "#define found(x) ((x != std::string::npos))" >sourcefile + print "" > sourcefile + nrefs=1 + nfields=1 + ref_table[1]="" + ref_row[1]="" + ref_rtable[1]="" + def_types[1]="no_types_defined" + ndef_types=1 + } +/^begin_refs/,/^end_refs/ \ + { + print "processing refs" + ref_table[nrefs]=$1 + ref_row[nrefs]=$2 + ref_rtable[nrefs++]=$3 + } + +/synonym/,/;/ \ + { + print "processing synonym" + if (index($5,";")) { + split($5,a,";") + tt=a[1] + } else { + tt=$5 + } + print "typedef "tt" "$3";" >headerfile + next + } +/database/,/;/ \ + { + dbtype="" + print "processing database" + for (i=0;isourcefile + print "using namespace "dbtype";" >sourcefile + print "#endif\n\n" >sourcefile + } + if (index(db_name,";")) { + split(db_name,a,";") + db_name=a[1] + } + print "extern const char *db_name;" >headerfile + print "const char *db_name=\""db_name"\";" >sourcefile + print "extern int db_is_open;\n" >headerfile + print "int db_is_open;\n" >sourcefile + print "#ifndef CLIENT" >headerfile + print "inline int db_open() { \n\t if (!db_is_open) db_is_open=sql_database(db_name);\n\t return db_is_open; }" >headerfile + print "inline int db_close() { \n\t if (db_is_open) db_is_open=!sql_finish();\n\t return !db_is_open; }" >headerfile + print "inline int db_change(const char *name) { \n\t if(strcmp(db_name, name) || !db_is_open) { \n\t\t db_close();\n\t\t db_name=name;\n\t\t db_open(); } return(db_is_open); }" >headerfile + print "#else" >headerfile + print "inline int db_open() { return (db_is_open=1); }" >headerfile + print "inline int db_close() { return !(db_is_open=0); }" >headerfile + print "inline int db_change() { return (db_is_open=1); }" >headerfile + print "#endif\n" >headerfile + next + } + +/{/ { + print "// "$0 > headerfile + print "// "$0 > sourcefile + while (!index($0,"}")) { + getline + print "// "$0 > headerfile + print "// "$0 > sourcefile + } + print "\n" >headerfile + print "\n" >sourcefile + next + } +/deprecated/ { next } +/alter/ { while (!index($0,";")) { getline } next } +/revoke/ { while (!index($0,";")) { getline } next } +/index/ { while (!index($0,";")) { getline } next } +/create[ \t]/ { + print "processing create" + if ($2 == "table") { + if (index($3,"\.")) { + n=split($3,a,"\.") + } else { + n=1 + a[n]=$3 + } + is_typedef=0 + } else { + if (index($4,"\.")) { + n=split($4,a,"\.") + } else { + n=1 + a[n]=$4 + } + is_typedef=1 + } + nfields=1 + fields[1]="" + type[1]="" + nsf=1 + sf[1]="" + sfz[1]=0 + table=a[n] + if (is_typedef) { + def_types[ndef_types++]=a[n] + print "class ",a[n], \ + " : public db_type<"a[n]"> {\n public:" \ + > headerfile + } else { + print "class ",a[n], \ + " : public db_table<"a[n]"> {\n public:" \ + > headerfile + } + } +/list\(/ { + print "processing list" + isref=0 + islist=1 + n=split($2,a,"(") + if (a[n] == "int8" || a[n] == "bigint" || a[n] == "integer8") { + a[n]="sqlint8_t" + } + type[nfields]="v "a[n] + fields[nfields++]=$1 + print "\tsqlblob<"a[n]"> ",$1,";" > headerfile + next + } +/integer8|bigint|int8/ { + print "processing integer8" + isref=0 + type[nfields]="ld" + if (index($NF,"bitfield")) type[nfields]="lb" + fields[nfields++]=$1 + for (i=1;i "ref_row[i]";" >headerfile + type[nfields-1]="r" + } + } + if (!isref) print "\tsqlint8_t ",$1";" > headerfile + if ($1=="id") { + id_type[table]="sqlint8_t " + id_name[table]=$1 + } + next + } +/[ \t]integer|[ \t]int/ { + print "processing integer" + isref=0 + type[nfields]="d" + fields[nfields++]=$1 + for (i=1;i "ref_row[i]";" >headerfile + type[nfields-1]="r" + } + } + if (!isref) print "\tlong ",$1";" > headerfile + if ($1=="id") { + id_type[table]="long" + id_name[table]=$1 + } + next + } +/[ \t]smallint|[ \t]mediumint/ { + print "processing smallint" + isref=0 + type[nfields]="d" + fields[nfields++]=$1 + for (i=1;i "ref_row[i]";" >headerfile + print ref_rtable[i],table"."ref_row[i] + type[nfields-1]="r" + } + } + if (!isref) print "\tlong ",$1";" > headerfile + if ($1=="id") { + id_type[table]="long" + id_name[table]=$1 + } + next + } +/serial8|bigint*auto_increment/ { + print "processing serial8" + key=$1 + type[nfields]="ld" + id_type[table]="sqlint8_t" + id_name[table]=$1 + fields[nfields++]=$1 + print "\tsqlint8_t ",$1";" > headerfile + next + } +/serial|auto_increment/ { + print "processing serial" + key=$1 + type[nfields]="d" + id_type[table]="long" + id_name[table]=$1 + fields[nfields++]=$1 + print "\tlong ",$1";" > headerfile + next + } +/smallfloat/ { + print "processing smallfloat" + type[nfields]="f" + fields[nfields++]=$1 + print "\tdouble ",$1";" > headerfile + next + } +/[ \t]float|[ \t]double/ { + print "processing float" + type[nfields]="f" + fields[nfields++]=$1 + print "\tdouble ",$1";" > headerfile + next + } +/char[ \t\(]|[ \t]byte/ { + print "processing char" + type[nfields]="s" + for (i=0;i headerfile + } else { + print "\tsqlblob ",$1";" >headerfile; + } + next + } +/,/ { + print "processing ," + for (i=1;iheaderfile + next + } + } + } +/./ { + print "processing ." + for (i=1;iheaderfile + next + } + } + } +/;/ { + print "processing ; nfields=",nfields + if (nfields!=1) { + firstcomma=0 + for (i=(nfields-1);i;i--) { + if (firstcomma) { + comma[i]="," + } else { + comma[i]="" + } + if (type[i]!="s") firstcomma=1 + } + print "\t"table"();" >headerfile + print "\t"table"(const "table" &a);" >headerfile + print "\t"table"(const SQL_ROW &a);" >headerfile + print "\t"table"(const std::string &s,const char *tag=\""table"\");" >headerfile + print "\t"table" &operator =(const "table" &a);" >headerfile + print "\tstd::string update_format() const;" >headerfile + print "\tstd::string insert_format() const;" >headerfile + print "\tstd::string select_format() const;" >headerfile + print "\tstd::string print(int full_subtables=0, int show_ids=1, int no_refs=0) const;" >headerfile + print "\tstd::string print_xml(int full_subtables=1, int show_ids=0, int no_refs=0,const char *tag=\""table"\") const;" >headerfile + print "\tvoid parse(const SQL_ROW &s);" >headerfile + print "\tvoid parse(const std::string &s);" >headerfile + print "\tvoid parse_xml(const std::string &s,const char *tag=\""table"\");" >headerfile + print " private:\n};\n\n" >headerfile + if (is_typedef) { + print "template <> const char * const db_type<"table">::type_name=\""table"\";" >sourcefile + print "template <> const char * db_type<"table">::_search_tag=type_name;" >sourcefile + print "template <> const int db_type<"table">::_nfields="nfields-1";" >sourcefile + printf("template <> const char * const db_type<%s>::column_names[%d]={",table,nfields-1) >sourcefile + } else { + print "template <> const char * const db_table<"table">::table_name=\""table"\";" >sourcefile + print "template <> const char * db_table<"table">::_search_tag=table_name;" >sourcefile + print "template <> const int db_table<"table">::_nfields="nfields-1";" >sourcefile + printf("template <> const char * const db_table<%s>::column_names[%d]={",table,nfields-1) >sourcefile + } + for (i=1;isourcefile + print "};\n" >sourcefile + print table"::"table"() : " >sourcefile + if (is_typedef) { + print "\tdb_type<"table">(*this)," > sourcefile + } else { + print "\tdb_table<"table">(*this,-1)," > sourcefile + } + for (i=1;isourcefile + } else if ((type[i]=="r")||(type[i]=="t")) { + printf("\t%s()%s\n",fields[i],comma[i]) >sourcefile + } else if (type[i]=="b") { + printf("\t%s((unsigned char *)0,%d,_x_csv)%s\n",fields[i],arrlen[i],comma[i]) >sourcefile + } else if (index(type[i],"v")==1) { + n=split(type[i],a," ") + stype=a[n] + n=split(stype,a,"(") + stype=a[n] + sis_deftype=0 + for (n=1;nsourcefile + } else { + printf("\t%s((%s *)0,%d,_x_xml_values)%s\n",fields[i],stype,arrlen[i],comma[i]) >sourcefile + } + } + } + print "{\n\tdb_open();" >sourcefile + for (i=1;isourcefile + } + print "}\n\n" >sourcefile + + print table"::"table"(const "table" &a) : " >sourcefile + if (is_typedef) { + print "\tdb_type<"table">(*this)," > sourcefile + } else { + print "\tdb_table<"table">(*this,-1)," > sourcefile + } + for (i=1;isourcefile + } + print "{\n\tdb_open();" >sourcefile + for (i=1;isourcefile + } + print "}\n\n" >sourcefile + print table"::"table"(const SQL_ROW &a) : " >sourcefile + if (is_typedef) { + print "\tdb_type<"table">(*this)" > sourcefile + } else { + print "\tdb_table<"table">(*this,-1)" > sourcefile + } + print "{\n\tdb_open();" >sourcefile + print "\tparse(a);\n}\n\n" >sourcefile + print table"::"table"(const std::string &s,const char *tag) : " >sourcefile + #for (i=1;isourcefile + # } else if ((type[i]=="r")||(type[i]=="t")) { + # printf("\t%s(),\n",fields[i]) >sourcefile + # } + #} + if (is_typedef) { + print "\tdb_type<"table">(*this)" > sourcefile + } else { + print "\tdb_table<"table">(*this,-1)" > sourcefile + } + print "{\n\tdb_open();" >sourcefile + print "\tif (xml_match_tag(s,tag)) {" >sourcefile + print "\t parse_xml(s,tag);" >sourcefile + print "\t} else {\n\t parse(s);\n\t}\n}\n\n" >sourcefile + + print table" &"table"::operator =(const "table" &a) {" >sourcefile + print "\tif (&a != this) {" >sourcefile + for (i=1;isourcefile + } else { + if (index(type[i],"v") == 1) { + n=split(type[i],a," ") + stype=a[n] + n=split(stype,a,"(") + stype=a[n] + print "\t\t{" >sourcefile + print "\t\t "fields[i]".clear();" > sourcefile + print "\t\t std::vector<"stype">::const_iterator i(a."fields[i]".begin());" > sourcefile + print "\t\t for (;i!=a."fields[i]".end();i++) {" >sourcefile + print "\t\t "fields[i]".push_back(*i); " >sourcefile + print "\t\t }\n\t\t}" >sourcefile + } + } + } + for (i=1;isourcefile + } + print "\t}\n\treturn (*this);\n}\n\n" >sourcefile + + print "std::string "table"::update_format() const" >sourcefile + if (is_typedef) { + print "{\tstd::ostringstream rv(\"\");\n" >sourcefile + print "\trv << \"ROW(\";" >sourcefile + i=1 + } else { + print "{\tstd::ostringstream rv(\"\");\n" >sourcefile + i=2 + } + print "\tfor (int i="i";i<"nfields-1";i++) rv << \"?,\";" >sourcefile + print "\trv << \"?\";" >sourcefile + if (is_typedef) { + print "rv << \")\";\n" >sourcefile + } + print "\treturn rv.str();\n}\n\n" >sourcefile + + print "std::string "table"::insert_format() const" >sourcefile + if (is_typedef) { + print "{\treturn update_format();\n}\n" >sourcefile + } else { + print "{\treturn std::string(\"?,\")+update_format();\n}\n" >sourcefile + } + print "std::string "table"::select_format() const" >sourcefile + print "{\nstd::string rv(\"\");" >sourcefile + print "for (int i=0; i<"nfields-2";i++) rv+=\"?,\";" >sourcefile + print "rv+=\"?\";\nreturn rv;\n}\n" >sourcefile + + + + print "std::string "table"::print(int full_subtables, int show_ids, int no_refs) const" >sourcefile + print "{\tstd::ostringstream rv(\"\");\n" >sourcefile + print "\trv.precision(14);" >sourcefile + if (is_typedef) { + print "\trv << \"ROW(\";" >> sourcefile + } + for (i=1;isourcefile + print "\t if (full_subtables) {" > sourcefile + print "\t rv << "fields[i]".print(full_subtables,show_ids,no_refs);" > sourcefile + print "\t} else {" > sourcefile + print "\t rv << "fields[i]".id;" > sourcefile + + print "\t }\n\t}" > sourcefile + } else if (type[i] == "t") { + print "\trv << "fields[i]".print(full_subtables,show_ids,no_refs);" > sourcefile + } else if (index(type[i],"v")==1) { + n=split(type[i],a," ") + stype=a[n] + n=split(stype,a,"(") + stype=a[n] + print "\trv << \"LIST {\";" > sourcefile + print "\t{\n\tstd::vector<"stype">::const_iterator p="fields[i]".begin();" > sourcefile + print "\tfor (;p<"fields[i]".end();p++) {" > sourcefile + sis_deftype=0 + for (n=1;n sourcefile + } else { + print "\t rv << p->print();" >sourcefile + } + print "\t if (p != "fields[i]".end()-1) {" >sourcefile + print "\t rv << ',';" >sourcefile + print "\t } else {" >sourcefile + print "\t rv << \"}\";" >sourcefile + print "\t }" >sourcefile + print "\t}\n\t}" >sourcefile + } else if ((type[i]=="s")) { + print "\trv << \"'\" << "fields[i]" << \"'\";" >sourcefile + } else if ((type[i]=="b")) { + if (dbtype == "ifx") { + print "\trv << \"\" << "fields[i]".print_hex() ;" >sourcefile + } else { + print "\trv << \"\" << "fields[i]".print_raw() ;" >sourcefile + } + } else { + printf("\t") > sourcefile + if ((i==1) && (!is_typedef)) { + printf("if (show_ids) ") > sourcefile + } + print "rv << "fields[i]";" > sourcefile + } + if (i!=(nfields-1)) print "\trv << ',';" >sourcefile + } + if (is_typedef) { + print "\trv << \")\";" > sourcefile + } + print "\treturn rv.str();\n}\n\n" >sourcefile + + print "std::string "table"::print_xml(int full_subtables, int show_ids, int no_refs,const char *tag) const " >sourcefile + print "{\n\tstd::ostringstream rv(\"\");\n" >sourcefile + print "\trv.precision(14);" >sourcefile + print "\trv << xml_indent() << '<' << tag << \">\\n\";" >sourcefile + print "\txml_indent(2);" >sourcefile + for (i=1;isourcefile + print "\t if (full_subtables) {" > sourcefile + print "\t rv << "fields[i]".print_xml(full_subtables,show_ids,no_refs,\""fields[i]"\");" > sourcefile + print "\t} else {" > sourcefile + print "\t rv << xml_indent() << \"<"fields[i]">\" << "fields[i]".id << \"\\n\";" > sourcefile + print "\t }\n\t}" > sourcefile + } else if (type[i] == "t") { + print "\trv << "fields[i]".print_xml(full_subtables,show_ids,no_refs,\""fields[i]"\");" > sourcefile + } else if (index(type[i],"v")==1) { + n=split(type[i],a," ") + stype=a[n] + n=split(stype,a,"(") + stype=a[n] + sis_deftype=0 + for (n=1;nsourcefile + print "\t rv << xml_indent() << \"<"fields[i]"\";" >sourcefile + print "\t {\n\t std::string enc_string="fields[i]".print_xml();" >sourcefile + if (!sis_deftype) { + print "\t rv << \" length=\" << enc_string.size() << \" encoding=\\\"\" << xml_encoding_names["fields[i]".encoding] << \"\\\">\" ;" >sourcefile + } else { + print "\t rv << \">\\n\" ;" >sourcefile + } + print "\t rv << enc_string;" >sourcefile + print "\t }\n}" >sourcefile + if (sis_deftype) print "\trv << xml_indent(-2);" > sourcefile + print "\trv << \"\\n\"; " >sourcefile + } else if (type[i]=="s") { + print "\t{\n\t std::string enc_field=xml_encode_string("fields[i]",std::min(strlen("fields[i]"),sizeof("fields[i]")));" > sourcefile + print "\t rv << xml_indent() << \"<"fields[i]">\";" > sourcefile + print "\t rv << enc_field << \"\\n\";" >sourcefile + print "\t}" >> sourcefile + } else if (type[i]=="b") { + print "\tif ("fields[i]".size()) {\n\t std::string enc_field=xml_encode_string("fields[i]","fields[i]".encoding);" > sourcefile + print "\t rv << xml_indent() << \"<"fields[i]" length=\" << enc_field.size() << \" encoding=\\\"\" << xml_encoding_names["fields[i]".encoding] << \"\\\">\"; "> sourcefile + print "\t rv << enc_field << \"\\n\";" >sourcefile + print "\t}" >> sourcefile + } else { + printf("\t") > sourcefile + if ((i==1) && (!is_typedef)) { + printf("if (show_ids) ") > sourcefile + } + print "rv << xml_indent() << \"<"fields[i]">\" << "fields[i]" << \"\\n\";" > sourcefile + } + } + print "\txml_indent(-2);" >sourcefile + print "\trv << xml_indent() << \"\\n\";" >sourcefile + print "\treturn rv.str();\n}\n\n" >sourcefile + print "\tvoid "table"::parse_xml(const std::string &s,const char *tag) {" >sourcefile + print "\t std::string field,sub;" > sourcefile + print "\t if (extract_xml_record(s,tag,field)) {" >sourcefile + print "\t std::string::size_type pos=0;" >sourcefile + for (i=1;i sourcefile + print "\t "fields[i]".parse_xml(sub,\""fields[i]"\");" >sourcefile + print "\t }" > sourcefile + } else if (index(type[i],"v")==1) { + n=split(type[i],a," ") + stype=a[n] + n=split(stype,a,"(") + stype=a[n] + sis_deftype=0 + for (n=1;nsourcefile + print "\t if (extract_xml_record(field,\""fields[i]"\",sub)) {" >sourcefile + if (sis_deftype) { + print "\t pos=0;" >sourcefile + print "\t while ((pos=sub.find(\"<"stype"\",pos)) != std::string::npos) { " >sourcefile + print "\t "fields[i]".push_back("stype"(std::string(sub.c_str()+pos))); " >sourcefile + print "\t pos=sub.find(\"sourcefile + print "\t pos=sub.find(\">\",pos);" >sourcefile + print "\t }" > sourcefile + } else { + print "\t pos=sub.find(\">\");" >sourcefile + print "\t do {" > sourcefile + print "\t if (pos!=std::string::npos) {" >sourcefile + print "\t do { pos++; } while ((sub[pos]=='\\n') || (sub[pos]==','));" >sourcefile + print "\t std::istringstream in(std::string(sub.c_str()+pos)); " >sourcefile + print "\t "stype" tmp;" >sourcefile + print "\t in >> tmp;" >sourcefile + print "\t "fields[i]".push_back(tmp);" >sourcefile + print "\t }" >sourcefile + print "\t } while ((pos=sub.find(\",\",pos)) != std::string::npos); " >sourcefile + } + print "\t }" > sourcefile + } else { + print "\t if (extract_xml_record(field,\""fields[i]"\",sub)) {" > sourcefile + if ((type[i] != "s") && (type[i] != "b")) { + print "\t pos=sub.find(\">\");" >sourcefile + print "\t do { pos++; } while(sub[pos]=='\\n');" >sourcefile + print "\t std::istringstream in(sub.c_str()+pos);" >sourcefile + print "\t in >> "fields[i]";" > sourcefile + } else if (type[i] == "b") { + print "\t std::istringstream in(sub.c_str());" >sourcefile + print "\t in >> "fields[i]";" >sourcefile + } else { + print "\t pos=sub.find(\">\");" >sourcefile + print "\t do { pos++; } while(sub[pos]=='\\n');" >sourcefile + print "\t std::string::size_type epos=sub.find(\"<\",pos);" >sourcefile + print "\t if (epos==std::string::npos) epos=sub.find('\\n',pos);" > sourcefile + print "\t if (epos==std::string::npos) epos=pos+strlen(sub.c_str()+pos);" > sourcefile + print "\t std::vector in(xml_decode_string((const char *)sub.c_str()+pos,epos-pos));" >sourcefile + print "\t strncpy("fields[i]",(const char *)&(in.front()),std::min(in.size(),(size_t)"arrlen[i]"));" >sourcefile + print "\t "fields[i]"[std::min(in.size(),(size_t)"arrlen[i]-1")]=0;" > sourcefile + } + print "\t }" >sourcefile + } + } + print "\t }" >sourcefile + print "\t }\n" >sourcefile + print "\tvoid "table"::parse(const SQL_ROW &s) {" >sourcefile + for (i=1;isourcefile + if (type[i]=="r" || type[i]=="t") { + print "\t "fields[i]".parse(SQL_ROW(s["i-1"],0));" >sourcefile + } else if (index(type[i],"v")==1) { + n=split(type[i],a," ") + stype=a[n] + n=split(stype,a,"(") + stype=a[n] + sis_deftype=0 + for (n=1;nsourcefile + print "\t int i;" >sourcefile + print "\t "fields[i]".clear();" >sourcefile + print "\t SQL_ROW tmp(s["i-1"]); ">sourcefile + if (sis_deftype) { + print "\t for (i=0;isourcefile + print "\t "fields[i]".push_back("stype"(SQL_ROW(tmp[i])));" >sourcefile + } else { + print "\t for (i=0;isourcefile + print "\t std::istringstream in(*(tmp[i]));" >sourcefile + print "\t "stype" tmp0;" >sourcefile + print "\t in >> tmp0;" >sourcefile + print "\t "fields[i]".push_back(tmp0);" >sourcefile + } + print "\t }" >sourcefile + } else { + if ((type[i] != "s") && (type[i] != "b")) { + print "\t std::istringstream row(*(s["i-1"]));" >sourcefile + print "\t row >> "fields[i]";" > sourcefile + } else if (type[i] == "b") { + print "\t "fields[i]"=sqlblob(*(s["i-1"]));" >sourcefile + } else { + print "\t strncpy("fields[i]",s["i-1"]->c_str(),"arrlen[i]");">sourcefile + print "\t "fields[i]"["arrlen[i]-1"]=0;" > sourcefile + } + } + print "\t }" >sourcefile + } + print "\t }\n" >sourcefile + print "\tvoid "table"::parse(const std::string &s) {" >sourcefile + print "\t SQL_ROW row(&s,"nfields-1");" >sourcefile + print "\t parse(row);" >sourcefile + print "\t }\n" >sourcefile + nfields=1 + } + } +END { + print "processing END" + print "#endif"> headerfile + } diff --git a/db/schema_to_class.in b/db/schema_to_class.in new file mode 100755 index 0000000..6edd68a --- /dev/null +++ b/db/schema_to_class.in @@ -0,0 +1,34 @@ +#!/bin/sh +# Copyright 2003 Regents of the University of California + +# SETI_BOINC is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2, or (at your option) any later +# version. + +# SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. + +# You should have received a copy of the GNU General Public License along +# with SETI_BOINC; see the file COPYING. If not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +filename=/tmp/`echo $1 | @SED@ 's/\.sql//'` +echo begin_refs > $filename +@AWK@ -f @SAH_TOP_DIR@/db/find_references.awk $1 | @SED@ 's/[(),;]//g' | @SORT@ | @UNIQ@ >> $filename +echo end_refs >> $filename +@CAT@ $1 | @TR@ "[A-Z]" "[a-z]" | @SED@ 's/\`//g' >>$filename + +@AWK@ -f @SAH_TOP_DIR@/db/schema_to_class.awk $filename +INDENT=@INDENT@ +if test -n "$INDENT" +then + @INDENT@ @INDENT_FLAGS@ $filename.h + @INDENT@ @INDENT_FLAGS@ $filename.cpp +fi + +@MV@ $filename.cpp . +@MV@ $filename.h . +@RM@ $filename* diff --git a/db/sqlapi.h b/db/sqlapi.h new file mode 100644 index 0000000..65ed67b --- /dev/null +++ b/db/sqlapi.h @@ -0,0 +1,138 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +/* Release 4.0 */ +/* Fri Feb 27 09:06:50 EST 1998 */ + +#ifndef _SQLAPI_H_ +#define _SQLAPI_H_ +#ifdef __cplusplus + +#include "sqlrow.h" +#include "sqlblob.h" +#include "sqlint8.h" + +#ifdef USE_NAMESPACE +#if defined(USE_INFORMIX) +namespace ifx { +#elif defined(USE_MYSQL) +namespace mysql { +#endif +#endif + +sqlint8_t sql_insert_id(SQL_CURSOR c); +/* + * Returns the serial value (if any) of the last insert. + */ + +int sql_error_code(); // returns the current error code. +int sql_last_error_code(); // returns the last nonzero error code +void sql_reset_error_code(); // resets the last nonzero error code + +const char *sql_error_message(); +/* + * Return SQL error information + */ + +bool sql_database(const char *dbname, const char *password=0, int exclusive=0); +/* connects to the database specified by dbname + * or if dbname is "" or cannot be opened uses + * the DATABASE environ variable. + * Parses "dbname@host" syntax. + * returns true if sucessful + */ + +bool sql_finish(); +/* closes the database opened earlier + */ + +char *sql_getdatabase(); +/* returns the database name opened by sql_database() + */ + +bool sql_exists(const char *table, const char *field, const char *value, const char *where); +/* check for existence of field in table optionally with value and + * optionally with a where clause where + */ + +SQL_CURSOR sql_open(const char *stmt, SQL_ROW &argv=const_cast(empty_row)); +/* open the query specified by statement and substitute all ? with + * parameters specified + * compiles the query and allocates space for return values + */ + +extern "C" { +#endif +int begin_work(); +/* starts a transaction + */ + +int commit_work(); +/* commits a transaction + */ + +int rollback_work(); +/* rolls backs a transaction + */ +#ifdef __cplusplus +} +bool sql_close(SQL_CURSOR); +/* close the compiled query and release all memory allocated for it + */ + +bool sql_fetch(SQL_CURSOR); +/* fetch a single row into the allocated space + * use sql_values to retrieve it + * (there is no need to free the sql_values return value! + * the program manages this space efficiently by reallocating more + * space if needed and does not do repeated malloc and free.) + */ + +bool sql_run(const char *stmt, SQL_ROW &argv=const_cast(empty_row)); +/* calls sql_open, sql_fetch and then sql_close + */ + +bool sql_explain(int); +/* sets debug on for all queries if int is not 0 else turns off + */ + +bool sql_reopen(SQL_CURSOR fd, SQL_ROW &argv); +/* reopen the cursor so that fetches may be done from the + * start again. uses the old parameters for the open + * if argc is specified bind the variables again + */ + +SQL_ROW sql_values(SQL_CURSOR fd, int *numvalues=0, int dostrip=1); +/* if dostrip is 1, it will strip all trailing blanks + */ + + +bool chk_cursor(SQL_CURSOR fd,const char *s); +/* + * performs an error check on the cursor + * if NDEBUG is not defined then an error message is printed + */ + +bool sql_print(SQL_CURSOR fd); +/* + * prints implementation defined info about the query in process + */ + +#ifdef USE_NAMESPACE +} +#endif +#endif +#endif diff --git a/db/sqlblob.cpp b/db/sqlblob.cpp new file mode 100644 index 0000000..c368ceb --- /dev/null +++ b/db/sqlblob.cpp @@ -0,0 +1,76 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#include "sah_config.h" + + +#include +#include +#include +#include +#include +#include + +#include "sqldefs.h" +#include "sqlrow.h" +#include "sqlblob.h" + +#ifndef CLIENT +#include "sqlapi.h" +#endif + + + +std::string escape_char(unsigned char c) { + std::string rv(""); + if (isprint(c)) { + switch (c) { + case '\\': rv="\\\\"; + break; + case '\'': rv="\\'"; + break; + case '"': rv="\\\""; + break; + case ',': rv="\\,"; + break; + default: rv+=c; + } + } else { + char buf[8]; + sprintf(buf,"\\%.4o",c); + rv=buf; + } + return rv; +} + +unsigned char unescape_char(const unsigned char *&s) { + unsigned char rv; + int i; + if (*s != '\\') return *s; + switch (*(s+1)) { + case '0': sscanf((const char *)(s+1),"%4o",&i); + rv=i&0xff; + s+=4; + break; + default: rv=*(++s); + } + return rv; +} + + + + + diff --git a/db/sqlblob.h b/db/sqlblob.h new file mode 100644 index 0000000..599e224 --- /dev/null +++ b/db/sqlblob.h @@ -0,0 +1,283 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#ifndef _SQLBLOB_H_ +#define _SQLBLOB_H_ + +#ifdef swap +#undef swap +#endif + +#include "sah_config.h" + +#ifndef _WIN32 +#include +#include +#include +#include +#endif + +#include "track_mem.h" +#include "sqldefs.h" +#include "sqlrow.h" +#include "xml_util.h" + +template +class sqlblob; + +template +std::ostream &operator <<(std::ostream &i, const sqlblob &b) { + i << xml_encode_string(*(b.mem),b.encoding); + return i; +} + + +template +std::istream &operator >>(std::istream &i, sqlblob &b) { + std::string buf(""),tmp; + std::string::size_type b_start=0,b_end=0,b_encoding=0; + const char *enc_string; + if (sizeof(T)==1) { + enc_string="x-xml-entity"; + } else { + enc_string="x-xml-values"; + } + while (!i.eof()) { + i >> tmp; + buf+=(tmp+' '); + } + b_start=buf.find('<'); + b_end=std::min(buf.find('>',b_start+1),buf.find(' ',b_start+1)); + std::string tag(std::string("',b_start+1); + b_encoding=buf.find("encoding=",b_start); + if (b_encoding < b_end) + enc_string=buf.c_str()+b_encoding+strlen("encoding="); + b_start=b_end+1; + b_end=buf.find(tag); + if (b.mem) { + delete(b.mem); +#ifdef DEBUG_ALLOCATIONS + fprintf(stderr,"sqlblob: deleted a vector at 0x%p\n",b.mem); + fflush(stderr); +#endif + } + b.mem=new std::vector(xml_decode_string(buf.c_str()+b_start,b_end-b_start,enc_string)); + b.encoding=(xml_encoding)xml_encoding_from_string(enc_string); +#ifdef DEBUG_ALLOCATIONS + fprintf(stderr,"sqlblob: allocated a vector at 0x%p\n",b.mem); + fflush(stderr); +#endif + return i; +} + + +template +std::string xml_encode_string(const sqlblob &input, + xml_encoding encoding=_x_xml_entity) { + return xml_encode_string(static_cast(&(*(input.mem))[0]),input.size(),encoding); +} + + +template +class sqlblob : track_mem > { + public: + sqlblob(const sqlblob &b); + explicit sqlblob(const T *p=0, size_t n_elements=0, xml_encoding e=_x_hex); + explicit sqlblob(const std::string &s,xml_encoding e=_x_hex); + explicit sqlblob(const std::vector &v, xml_encoding e=_x_hex); + ~sqlblob(); +// operator T *() { return &((*mem)[0]); }; +// operator const T *() const { return &((*mem)[0]); }; +// operator const char *() const { return (const char *)(&((*mem)[0])); }; + T &at(int i) { return mem->at(i); } + T &operator [](int i) { return (*mem)[i]; }; + const T operator [](int i) const { return (*mem)[i]; } ; + sqlblob &operator =(const sqlblob &b); + sqlblob &operator =(const std::vector &b); + size_t size() const { return mem->size(); }; + size_t set_size(size_t n_elements); + size_t resize(size_t n_elements); + std::string print_xml() const; + std::string print_hex() const; + std::string print_raw() const; + void parse_xml(std::string &field) { std::istringstream s(field); s >> *this; }; + typename std::vector::const_iterator begin() const { return mem->begin(); }; + typename std::vector::iterator begin() { return mem->begin(); }; + typename std::vector::const_iterator end() const { return mem->end(); }; + typename std::vector::iterator end() { return mem->end(); }; + void push_back(const T &t) { mem->push_back(t); } ; + void clear() { mem->clear(); } ; +#if !defined(WIN32) || ( _MSC_VER > 1300 ) || defined(__MINGW32__) // VC 7 or newer + friend std::ostream &operator << (std::ostream &o, const sqlblob &b); + friend std::istream &operator >> (std::istream &o, sqlblob &b); + friend std::string xml_encode_string(const sqlblob &b,xml_encoding encoding); +#else // VC6 or earlier + friend std::ostream &operator <<(std::ostream &o, const sqlblob &b); + friend std::istream &operator >>(std::istream &o, sqlblob &b); + friend std::string xml_encode_string(const sqlblob &b,xml_encoding encoding); +#endif + xml_encoding encoding; + private: + std::vector *mem; +}; + +template +std::string sqlblob::print_xml() const { + return xml_encode_string(*mem,encoding); +} + +template +std::string sqlblob::print_hex() const { + const char *hex="0123456789ABCDEF"; + char *p= new char [size()*sizeof(T)*2+1]; + size_t i,j; + + for (i = j = 0; i < size()*sizeof(T); i++) { + p[j++] = hex[((*mem)[i] & 0xF0) >> 4]; + p[j++] = hex[((*mem)[i] & 0x0F)]; + } + p[j]=0; + std::string rv(p); + delete p; + return rv; +} + +template +std::string sqlblob::print_raw() const { + return std::string(reinterpret_cast(&(*begin())),size()); +} + + +template +sqlblob::sqlblob(const T *p, size_t len, xml_encoding e) : + track_mem >("sqlblob"), encoding(e) { + if (p) { + mem=new std::vector(p,p+len); + } else if (len) { + mem=new std::vector(len); + } else { + mem=new std::vector(); + } +#ifdef DEBUG_ALLOCATIONS + fprintf(stderr,"sqlblob: allocated a vector at 0x%p\n",mem); + fflush(stderr); +#endif +} + +template +sqlblob::sqlblob(const std::string &s, xml_encoding e) : + encoding(e), mem(new std::vector(s.c_str(),s.c_str()+s.size())) +{ +#ifdef DEBUG_ALLOCATIONS + fprintf(stderr,"sqlblob: allocated a vector at 0x%p\n",mem); + fflush(stderr); +#endif +} + +template +sqlblob::sqlblob(const std::vector &v, xml_encoding e) : + encoding(e), + mem(new std::vector(v)) { +#ifdef DEBUG_ALLOCATIONS + fprintf(stderr,"sqlblob: allocated a vector at 0x%p\n",mem); + fflush(stderr); +#endif +} + +template +sqlblob::sqlblob(const sqlblob &b) : + encoding(b.encoding) , + mem(new std::vector(*(b.mem))) { +#ifdef DEBUG_ALLOCATIONS + fprintf(stderr,"sqlblob: allocated a vector at 0x%p\n",mem); + fflush(stderr); +#endif +} + +template +size_t sqlblob::resize(size_t len) { + mem->resize(len); + return mem->size(); +} + +template +size_t sqlblob::set_size(size_t len) { + mem->resize(len); + if (mem->size() < len) { + while (mem->size() != len) { + mem->push_back(static_cast(0)); + } + } + return mem->size(); +} + +template +sqlblob::~sqlblob() { + if (mem) { + delete mem; +#ifdef DEBUG_ALLOCATIONS + fprintf(stderr,"sqlblob: deleted a vector at 0x%p\n",mem); + fflush(stderr); +#endif + } +} + +template +sqlblob &sqlblob::operator =(const sqlblob &b) { + if (&b != this) { + if (mem && (mem != b.mem)) { + delete mem; +#ifdef DEBUG_ALLOCATIONS + fprintf(stderr,"sqlblob: deleted a vector at 0x%p\n",mem); + fflush(stderr); +#endif + } + mem=new std::vector(*(b.mem)); + encoding=b.encoding; +#ifdef DEBUG_ALLOCATIONS + fprintf(stderr,"sqlblob: allocated a vector at 0x%p\n",mem); + fflush(stderr); +#endif + } + return (*this); +} + +template +sqlblob &sqlblob::operator =(const std::vector &b) { + if (&b != mem) { + if (mem) { + delete mem; +#ifdef DEBUG_ALLOCATIONS + fprintf(stderr,"sqlblob: deleted a vector at 0x%p\n",mem); + fflush(stderr); +#endif + } + mem=new std::vector(b); +#ifdef DEBUG_ALLOCATIONS + fprintf(stderr,"sqlblob: allocated a vector at 0x%p\n",mem); + fflush(stderr); +#endif + } + return (*this); +} + + + + + + +#endif diff --git a/db/sqldefs.h b/db/sqldefs.h new file mode 100644 index 0000000..e5106bf --- /dev/null +++ b/db/sqldefs.h @@ -0,0 +1,47 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#ifndef _SQLDEFS_H_ +#define _SQLDEFS_H_ + +#ifndef CLIENT +#ifdef USE_INFORMIX +#include "int8.h" +#include "sqlca.h" +#include "sqlda.h" +#include "locator.h" +#include "sqltypes.h" +#include "sqlstype.h" +#ifdef MAX_QUERY_LEN +#undef MAX_QUERY_LEN +#endif +namespace sql { + static const int MAXBLOB=8192; + static const int MAXVARCHAR=255; + static const int MAXCURSORS=20; + static const int MAX_QUERY_LEN=8192; +} +#elif defined(USE_MYSQL) +#include "mysql.h" +namespace sql { + static const int MAXBLOB=4096; + static const int MAXVARCHAR=255; + static const int MAXCURSORS=20; + static const int MAX_QUERY_LEN=8192; +} +#endif +#endif +#endif diff --git a/db/sqlifx.ec b/db/sqlifx.ec new file mode 100644 index 0000000..b4fecad --- /dev/null +++ b/db/sqlifx.ec @@ -0,0 +1,1270 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#include "sah_config.h" +#undef USE_MYSQL +#define loc_t sys_loc_t +#include +#include +#include +#include +#include +#include +#include +#undef loc_t + +#include "sqlint8.h" +#include "sqlca.h" +#include "sqlda.h" +#include "sqlhdr.h" +#include "locator.h" +#include "sqltypes.h" +#include "sqlstype.h" +#include "sqldefs.h" +#include "sqlint8.h" +#include "sqlblob.h" +#include "sqlrow.h" +#include "sqlapi.h" + + +extern sqlca_s sqlca; + +#ifdef USE_NAMESPACE +namespace ifx { +#endif + +#define found(x) ((x != std::string::npos)) + +struct IFX_LOC_T : private track_mem, public loc_t { + IFX_LOC_T() : track_mem("IFX_LOC_T") { +// fprintf(stderr,"Creating IFX_LOC_T, this=%x\n",this); +// fflush(stderr); + memset(this,0,sizeof(IFX_LOC_T)); + }; + IFX_LOC_T(const IFX_LOC_T &s) : track_mem("IFX_LOC_T") { +// fprintf(stderr,"Creating IFX_LOC_T, this=%x\n",this); +// fflush(stderr); + memcpy(this,&s,sizeof(IFX_LOC_T)); + if (s.loc_buffer) { + if (s.loc_bufsize) { + loc_buffer=new char [s.loc_bufsize]; + } else { + loc_buffer=new char [strlen(s.loc_buffer)]; + loc_bufsize=strlen(s.loc_buffer)+1; + loc_size=loc_bufsize; + } + memcpy(loc_buffer,s.loc_buffer,loc_bufsize); + } + } + IFX_LOC_T(const std::string &s) : track_mem("IFX_LOC_T") { +// fprintf(stderr,"Creating IFX_LOC_T, this=%x\n",this); +// fflush(stderr); + memset(this,0,sizeof(IFX_LOC_T)); + loc_loctype=LOCMEMORY; + loc_buffer=new char [s.size()+1]; + loc_bufsize=s.size(); + loc_size=loc_bufsize; + memcpy(loc_buffer,s.c_str(),s.size()); + loc_buffer[s.size()]=0; + } + + IFX_LOC_T(const char *s, size_t l) : track_mem("IFX_LOC_T") { +// fprintf(stderr,"Creating IFX_LOC_T, this=%x\n",this); +// fflush(stderr); + memset(this,0,sizeof(IFX_LOC_T)); + loc_loctype=LOCMEMORY; + loc_buffer=new char [l+1]; + loc_bufsize=l; + loc_size=loc_bufsize; + memcpy(loc_buffer,s,l); + loc_buffer[l]=0; + } + + ~IFX_LOC_T() { +// fprintf(stderr,"In ~IFX_LOC_T()\n"); +// fflush(stderr); + if (loc_buffer) delete [] loc_buffer; + loc_buffer=NULL; + } +}; + +struct SQLVAR : private track_mem, public ifx_sqlvar_t { + static int ref_cnt; + void clear(); + bool is_blob() { + return ((sqltype == CLOCATORTYPE) || + ((sqltype & SQLTYPE) == SQLTEXT) || + ((sqltype & SQLTYPE) == SQLBYTES)); + } + SQLVAR &operator =(const SQLVAR &s); + SQLVAR(); + SQLVAR(const SQLVAR &s); + SQLVAR(const std::string &s); + SQLVAR(const IFX_LOC_T &s); + ~SQLVAR(); +}; + +int SQLVAR::ref_cnt; +SQLVAR::SQLVAR() { +// fprintf(stderr,"Creating SQLVAR, this=%x\n",this); +// fflush(stderr); + sqldata=0; + sqltype=0; + ref_cnt++; +} + +SQLVAR::SQLVAR(const SQLVAR &s) : track_mem("SQLVAR") { +// fprintf(stderr,"Creating SQLVAR, this=%x\n",this); +// fflush(stderr); + ref_cnt++; + memcpy(this,&s,sizeof(SQLVAR)); + if (sqltype == CLOCATORTYPE) { + IFX_LOC_T *sloc=(IFX_LOC_T *)s.sqldata; + IFX_LOC_T *loc=new IFX_LOC_T(*sloc); + sqldata=(char *)loc; + } else { + sqldata=new char [s.sqllen+1]; + memcpy(sqldata,s.sqldata,s.sqllen); + sqldata[s.sqllen]=0; + } +} + +SQLVAR::SQLVAR(const std::string &s) : track_mem("SQLVAR") { +// fprintf(stderr,"Creating SQLVAR, this=%x\n",this); +// fflush(stderr); + ref_cnt++; + memset(this,0,sizeof(SQLVAR)); + sqltype=CCHARTYPE; + sqllen=s.size(); + sqldata=new char [s.size()+1]; + memcpy(sqldata,s.c_str(),s.size()+1); + sqldata[s.size()]=0; +} + +SQLVAR::SQLVAR(const IFX_LOC_T &s) : track_mem("SQLVAR") { +// fprintf(stderr,"Creating SQLVAR, this=%x\n",this); +// fflush(stderr); + ref_cnt++; + memset(this,0,sizeof(SQLVAR)); + sqltype=CLOCATORTYPE; + IFX_LOC_T *loc=new IFX_LOC_T(s); + sqllen=sizeof(IFX_LOC_T); + sqldata=(char *)loc; +} + +SQLVAR &SQLVAR::operator =(const SQLVAR &s) { + if (this != &s) { + clear(); + memcpy(this,&s,sizeof(SQLVAR)); + if (sqltype == CLOCATORTYPE) { + IFX_LOC_T *sloc=(IFX_LOC_T *)s.sqldata; + IFX_LOC_T *loc=new IFX_LOC_T(*sloc); + sqldata=(char *)loc; + } else { + sqldata=new char [s.sqllen+1]; + memcpy(sqldata,s.sqldata,s.sqllen); + sqldata[s.sqllen]=0; + } + } + return *this; +} + + + +void SQLVAR::clear() { + if (sqldata) { + if (sqltype == CLOCATORTYPE) { + delete (IFX_LOC_T *)sqldata; + } else { + delete [] sqldata; + } + sqldata=NULL; + } +} + +SQLVAR::~SQLVAR() { + ref_cnt--; +// fprintf(stderr,"Destroying SQLVAR() this=%x\n",this); +// fflush(stderr); + clear(); +} + +struct SQLDA : public track_mem, public ifx_sqlda_t { + void resize(int argc) { + int i; + if (argc>sqld) { + SQLVAR *tmp=(SQLVAR *)sqlvar; + sqlvar=new SQLVAR [argc]; + if (tmp) { + for (i=0;i { + char *cmd; + unsigned int opened:1; + unsigned int is_select:1; + SQLDA *in; + SQLDA *out; + SQLDA *exec; + int *arr_sqltype; + int arr_sqltype_len; + int *arr_sqllen; + char p_name[19]; + char c_name[19]; + sqlint8_t insert_id; + SSQL() : cmd(0), opened(0), is_select(0), in(0), out(0), exec(0), + arr_sqltype(0), arr_sqltype_len(0), arr_sqllen(0), insert_id(0) { + p_name[0]=0; + c_name[0]=0; + } +}; + +static char *null_cmd=""; + +#define debug(s) s + +#define errmalloc(pointer, func, len) \ + if (!pointer) {\ + sprintf(errmsg, "Cannot malloc for %uld in %s errno %d",len,func,errno);\ + debug(fprintf(stderr, "%s\n", errmsg));\ + return false;\ + } + +#define is_hex_digit(c) \ + ((((c)>='0') && ((c)<='9')) || (((c)>='a') && ((c)<='f')) || (((c)>='A') && ((c)<='F'))) + + +#define make_into_char(arg) \ + (((arg) >= 'A' && (arg) <= 'F')?((arg) - 'A' + 10):\ + (((arg) >= 'a' && (arg) <= 'f')?((arg) - 'a' + 10):(arg-'0'))) + +bool print_status(const char *p1,const char *p2); + + +int chk_status(int fd, const char *p1, const char *p2) { + int sav=sql_error_code(); + if (sav != 0) { + if (sav < 0) { + sql_close(fd); + print_status(p1, p2); + return (sav); + } + print_status(p1,p2); + } + return 0; +} + + +static SSQL ssql[sql::MAXCURSORS+1]; +static char *database_name; +static char *connection_name; + +static char errmsg[1024+1]; + +#ifndef lint +static char const rcs[] = "@(#)$Id: sqlifx.ec,v 1.22.2.7 2007/04/23 22:04:07 jeffc Exp $"; +#endif + +sqlint8_t sql_insert_id() { + sqlint8_t rv(0); + ifx_int8_t val; + char a[256]; + a[0]=0; + ifx_getserial8(&val); + ifx_int8toasc(&val,&a[0],24); + a[255]=0; + sscanf(a,"%"INT8_FMT,&rv); + if (!rv) { + rv=static_cast(sqlca.sqlerrd[1]); + } + return rv; +} + +#define INSERT_ID sql_insert_id() + +sqlint8_t sql_insert_id(SQL_CURSOR fd) { + return ssql[fd].insert_id; +} + + +bool chk_cursor(SQL_CURSOR fd, const char *function) { + if (fd < 0 || fd >= sql::MAXCURSORS || !ssql[fd].cmd) { + sprintf(errmsg, "Invalid fd %d passed to %s()", fd, function); + debug(fprintf(stderr, "%s\n", errmsg)); + return false; + } + return true; +} + +/* removes trailing white spaces */ +static void strip(std::string &s) { + while (s.size() && isspace(s[s.size()-1])) { + s.erase(s.size()-1,1); + } +} + +static void strip(char *s, int len) { + while (len>=0 && s[len]) s[len--]=0; +} + +static void undelimit(std::string &s,char c_start,char c_end) { + while (s.size() && (isspace(s[0]) || (s[0]==c_start))) s.erase(0,1); + while (s.size() && (isspace(s[s.size()-1]) || (s[s.size()-1]==c_end))) s.erase(s.size()-1,1); +} + +/* Using the previous SQL error code, format the Informix error message */ +bool print_status(const char *p1, const char *p2) { + int retcode = sql_error_code(); + if (retcode < 0) { + int msglen; + errmsg[0] = '\0'; + rgetlmsg(sql_error_code(), errmsg, sizeof(errmsg), &msglen); + if (sqlca.sqlerrd[1]) { + int len = strlen(errmsg); + errmsg[len] = '\0'; + rgetlmsg(sqlca.sqlerrd[1], &errmsg[len], sizeof(errmsg) - len, &msglen); + } + strip(sqlca.sqlerrp,strlen(sqlca.sqlerrp)); + sprintf(&errmsg[strlen(errmsg)], + "%d:%ld:%s %s %s %s\n", + sql_error_code(), sqlca.sqlerrd[1], sqlca.sqlerrp, sqlca.sqlerrm, p1, p2); + debug(fprintf(stderr, "%s\n", errmsg)); + } + return (retcode>=0); +} + +/* Set explain on or off */ +bool sql_explain(int n) { + int fd=0; + if (n) { + $set explain on; + chk_status(fd,"sql_explain","set explain on"); + } else { + $set explain off; + chk_status(fd,"sql_explain","set explain off"); + } + return ((sql_error_code())==0); +} + +/* Return the error message stored in the buffer */ +const char *sql_error_message(void) { + return errmsg; +} + +/* +** Check whether column (field) exists in table with value specified by val +** subject to additional constraints specified in where. +** +** returns +** true if field exists in table, +** false otherwise +*/ +static int alloc_stmt(); + +bool sql_exists(const char *table, const char *field, const char *p_val, const char *where) { + $char *value = const_cast(p_val); + $char stmt[sql::MAXBLOB+1]; + $char result[2]; + int fetch_code = 0; /* NOTUSED */ + int fd=alloc_stmt(); + + if (value && *value != '\0') { + sprintf(stmt, "select '1' from %s where %s = ?", + table, field); + if (where && *where != '\0') + sprintf(&stmt[strlen(stmt)], " and %s", where); + } else { + sprintf(stmt, "select '1' from %s", + table); + if (where && *where != '\0') + sprintf(&stmt[strlen(stmt)], " where %s", where); + } + + $prepare pexist from $stmt; + if (chk_status(fd,"PREPARE(EXISTS)", stmt)) return false; + $declare pexist_cur cursor for pexist; +if (chk_status(fd,"DECLARE(EXISTS)", stmt)) return false; + if (value && *value != '\0') + $open pexist_cur using $value; + else + $open pexist_cur; + if (chk_status(fd,"OPEN(EXISTS)", stmt)) return false; + $fetch pexist_cur into $result; + fetch_code = sql_error_code(); + $close pexist_cur; + sql_close(fd); + return (fetch_code==0); +} + + + +std::string decode_hex(std::string input) { + std::string tgt; + int i,j; + + tgt.resize(input.size()/2); + + for (i = j = 0; i < input.size(); i += 2) { + if (!is_hex_digit(input[i]) || !is_hex_digit(input[i+1])) return input; + tgt[j++] = make_into_char(input[i])*16 + make_into_char(input[i+1]); + } + return tgt; +} + +static bool sql_set_values(SQL_CURSOR fd, SQL_ROW &argv) { + SQLVAR *col; + SQLVAR *ecol; + SQLDA *udesc; + SQLDA *edesc; + int i; + int argc=argv.argc(); + + udesc = ssql[fd].in; + edesc = ssql[fd].exec; + if (argc > 0) { + if (edesc && (argc > edesc->sqld)) { + edesc->resize(argc); + } + if (udesc && argc != udesc->sqld) { + sprintf(errmsg, + "Incorrect number (%d) of bind variables specified - %d required", + argc, udesc->sqld); + debug(fprintf(stderr, "%s\n", errmsg)); + return false; + } + if (udesc) delete (SQLDA *)udesc; + + udesc = ssql[fd].in = new SQLDA(argc); + + if (edesc && edesc->sqld <= 0) edesc = NULL; + if (edesc && edesc->sqlvar) ecol = (SQLVAR *)edesc->sqlvar; + else ecol = NULL; + + for (i = 0, col = (SQLVAR *)udesc->sqlvar; i < argc; i++, col++) { + int blob = 0; + /* Is our column a blob? */ + if (ecol) { + if (ecol->is_blob()) blob = 1; + } + + if (!argv.exists(i)) argv[i]=new std::string(""); + /* remove leading and trailing single quotes */ + undelimit(*(argv[i]),'\'','\''); + + /* Check for blobs */ + if (blob) { + /* Remove tags */ + if ((argv[i]->find("find("find('>'); + if (found(etag)) argv[i]->erase(0,etag+1); + } + std::string tmpstr=decode_hex(*(argv[i])); + IFX_LOC_T tmploc=IFX_LOC_T(tmpstr); + SQLVAR tmpvar=SQLVAR(tmploc); + *col=tmpvar; + } else { + SQLVAR tmpvar=SQLVAR(*(argv[i])); + *col=tmpvar; + } + col->sqlname = 0; + col->sqlind = 0; + if (ecol) ecol++; + } + } + return true; +} + +/* Returns + true on successful execution + sqlca.sqlcode otherwise +*/ +bool sql_run(const char *stmt, SQL_ROW &argv) { + SQL_CURSOR fd; + int ret; + + if (isdigit(stmt[0])) { + fd = atoi(stmt); + if (!chk_cursor(fd, "sql_run")) + sql_close(fd); + return false; + if (!sql_set_values(fd, argv)) + sql_close(fd); + return false; + return sql_fetch(fd); + } + fd = sql_open(stmt, argv); + if (fd < 0) { + sql_close(fd); + return false; + } + ret = sql_fetch(fd); + sql_close(fd); + return ret; +} + +/* +** Allocate a statement number +** Returns: +** -1: no available statements +** 0..sql::MAXCURSORS-1: new statement number +*/ +static int alloc_stmt() { + int i; + + for (i = 0; i < sql::MAXCURSORS; i++) { + if (!ssql[i].cmd) + break; + } + if (i >= sql::MAXCURSORS) { + sprintf(errmsg, + "FATAL ERROR: Too many open SQL statements (> %d) for sql operations\n", sql::MAXCURSORS); + debug(fprintf(stderr, "%s\n", errmsg)); + i = -1; + exit(1); + } else { + ssql[i].cmd=null_cmd; + sprintf(ssql[i].p_name, "p_%d", i); + sprintf(ssql[i].c_name, "c_%d", i); + } + return(i); +} + +SQL_CURSOR sql_open(const char *sql, SQL_ROW &argv) { + SQLVAR *col = 0L; + ifx_sqlda_t *udesc = 0L; + $char *stmt = const_cast(sql); + int i; + int fd; + int len; + char *save; + $char *p_name; + $char *c_name; + int rv; + + if ((fd = alloc_stmt()) < 0) + return(-1); + + len = strlen(stmt); + save = new char [len+1]; + strcpy(save, stmt); + ssql[fd].cmd = save; + + p_name = ssql[fd].p_name; + + $prepare $p_name from $stmt; + + if (rv=chk_status(fd,"PREPARE(OPEN)", stmt)) return rv; + + $describe $p_name into udesc; + + if (rv=chk_status(fd,"DESCRIBE(OPEN)", stmt)) return rv; + + /** + ** The cursory statements are: + ** -- EXECUTE PROCEDURE + ** -- SELECT without INTO TEMP + ** Fortunately, SELECT INTO TEMP is given code SQ_SELINTO + ** Unfortunately, SELECT is not given code SQ_SELECT (2) but 0 + ** Non-cursory statements need minimal extra attention. + */ + if ((sql_error_code()) != 0 && + ((sql_error_code()) != SQ_EXECPROC || udesc->sqld == 0) && + (sql_error_code()) != SQ_SELECT) { + ssql[fd].is_select = 0; + ssql[fd].exec = (SQLDA *)udesc; + if (!sql_set_values(fd, argv)) + return sql_close(fd), -1; + return fd; + } + + ssql[fd].is_select = 1; + ssql[fd].out = (SQLDA *)udesc; + + if (!udesc) { + sprintf(errmsg, "No columns selected !\n"); + fprintf(stderr, "No columns selected !\n"); + return -1; + } + + for (i = 0, col = (SQLVAR *)udesc->sqlvar; i < udesc->sqld; i++, col++) { + int blob = 0; + if ((col->sqltype & SQLTYPE) != SQLCHAR && + (col->sqltype & SQLTYPE) != SQLVCHAR) { + if (col->is_blob()) { + blob = 1; + } else if ((col->sqltype & SQLTYPE) == SQLROW) { + col->sqllen = sql::MAXBLOB; + } else if ((col->sqltype & SQLTYPE) == SQLLIST) { + col->sqllen = sql::MAXBLOB; + } else { + col->sqllen = rtypwidth(col->sqltype, col->sqllen); + } + /* Should allocate at least 12 characters for backward compat. ! */ + if (col->sqllen < 12) col->sqllen = 12; + } + if (blob) { + IFX_LOC_T tmploc; + tmploc.loc_loctype=LOCMEMORY; + tmploc.loc_bufsize=-1; + SQLVAR tmpvar(tmploc); + *col=tmpvar; + } else { + std::string tmpstr(col->sqllen+2,0); + col->sqllen++; + SQLVAR tmpvar(tmpstr); + *col=tmpvar; + } + col->sqlind = new short; + *(col->sqlind) = 0; + } + + c_name = ssql[fd].c_name; + + $declare $c_name cursor for $p_name; + + if (rv=chk_status(fd,"DECLARE(OPEN)", stmt)) return rv; + + if (!sql_reopen(fd,argv)) { + sql_close(fd); + fd=-1; + } + if (rv=chk_status(fd,"OPEN(OPEN)", stmt)) return rv; + + ssql[fd].opened = 1; + ssql[fd].insert_id=INSERT_ID; + return fd; +} + +static int LAST_NON_ZERO_SQLCODE; + +int sql_error_code() { + if (SQLCODE != 0) LAST_NON_ZERO_SQLCODE = SQLCODE; + return SQLCODE; +} + +int sql_last_error_code() { + return LAST_NON_ZERO_SQLCODE; +} + +void sql_reset_error_code() { + LAST_NON_ZERO_SQLCODE=0; +} + + +bool sql_reopen(SQL_CURSOR fd, SQL_ROW &argv) { + struct sqlda *udesc; + $ char *c_name; + + if (!chk_cursor(fd, "sql_reopen")) + return false; + + if (!sql_set_values(fd, argv)) + return false; + + udesc = ssql[fd].in; + c_name = ssql[fd].c_name; + + if (udesc && udesc->sqld) + $open $c_name using descriptor udesc; + else + $open $c_name; + + if (chk_status(fd,"OPEN","sql_reopen()")) return false; + + return (sql_error_code()>=0); +} + +/* +** If this is a non-cursory statement, sql_fetch() executes the statement. +** If this is a cursory statement, then it fetches a row of data. +*/ +bool sql_fetch(SQL_CURSOR fd) { + int ret; + SQLDA *udesc; + + if (!chk_cursor(fd, "sql_fetch")) + return false; + + if (!ssql[fd].is_select) { + $char *p_name = ssql[fd].p_name; + udesc = ssql[fd].in; + if (udesc) + $execute $p_name using descriptor udesc; + else + $execute $p_name; + ret = sql_error_code(); + if (chk_status(fd,"EXECUTE(RUN)", ssql[fd].cmd)) return false; + } else { + $char *c_name = ssql[fd].c_name; + udesc = ssql[fd].out; + if (udesc && udesc->sqld) + $fetch $c_name using descriptor udesc; + else + $fetch $c_name; + ret = sql_error_code(); + if (chk_status(fd,"FETCH(OPEN)", ssql[fd].cmd)) return false; + } + ssql[fd].insert_id=INSERT_ID; + return ((ret>=0) && (ret!=100)); +} + +/* Convert (blob) memory to hex encoding used in UNLOAD */ +static char *convert_ascii(const char *str, int len) { + int i; + int j; + char *hex = "0123456789ABCDEF"; + char *p; + + p = new char [len*2+1]; + if (!p) return p; + + /* BCD to ASCII legible ! */ + for (i = j = 0; i < len; i++) { + p[j++] = hex[((str[i] & 0xF0) >> 4)]; + p[j++] = hex[(str[i] & 0x0F)]; + } + p[j] = '\0'; + return p; +} + +SQL_ROW sql_values(SQL_CURSOR fd, int *num, int dostrip) { + static SQL_ROW argv; + static int maxnum; + SQLDA *udesc; + SQLVAR *col; + int i; + + if (!chk_cursor(fd, "sql_values")) + return SQL_ROW(NULL); + if (!ssql[fd].is_select) { + sprintf(errmsg, + "Cannot get values for a non-select statement " + "(fd %d) passed to sql_values", fd); + debug(fprintf(stderr, "%s\n", errmsg)); + return SQL_ROW(NULL); + } + if (!ssql[fd].opened) { + sprintf(errmsg, + "Cannot get values for unopened statement " + "(fd %d) passed to sql_values", fd); + debug(fprintf(stderr, "%s\n", errmsg)); + return SQL_ROW(NULL); + } + udesc = ssql[fd].out; + if (!udesc) + return SQL_ROW(NULL); + if (udesc->sqld > maxnum) { + argv.argc(udesc->sqld); + maxnum = udesc->sqld; + } + for (i = 0, col = (SQLVAR *)udesc->sqlvar; i < udesc->sqld; i++, col++) { + // if something is already there, free it + argv.clear(i); + // build our SQL_ROW entries from what we have. + if (col->is_blob()) { + IFX_LOC_T *loc = (IFX_LOC_T *)col->sqldata; + if (loc->loc_size >= 0) { + argv[i] = new std::string(loc->loc_buffer,loc->loc_size); + } else { + argv[i] = new std::string(loc->loc_buffer); + } + if (dostrip == 1) strip(*(argv[i])); + } else { + argv[i] = new std::string((col->sqldata)?col->sqldata:""); + if (dostrip == 1) strip(*(argv[i])); + } + } + if (num) *num = udesc->sqld; + return argv; +} + +char *sql_command(SQL_CURSOR fd) { + if (!chk_cursor(fd, "sql_command")) + return NULL; + return ssql[fd].cmd; +} + +bool sql_close(SQL_CURSOR fd) { + struct sqlda *udesc; + struct sqlvar_struct *col; + + if (!ssql[fd].cmd) return true; + + if (ssql[fd].is_select) { + /* XXX - Error handling? */ + $char *c_name = ssql[fd].c_name; + if (ssql[fd].opened) + $close $c_name; + $free $c_name; + } + + { + /* XXX - Error handling? */ + $char *p_name = ssql[fd].p_name; + $free $p_name; + } + + /* XXX - Valid to assert ssql[fd].cmd != 0 ? */ + if (ssql[fd].cmd && (ssql[fd].cmd != null_cmd)) + delete [] ssql[fd].cmd; + + ssql[fd].cmd = NULL; + + udesc = ssql[fd].in; + if (udesc) { + delete (SQLDA *)udesc; + udesc = NULL; + } + ssql[fd].in = NULL; + + udesc = ssql[fd].out; + if (udesc) { +#ifndef FIXBUG + // since the sqlvars for out and exec are allocated by describe + // we need to make sure they don't get freed by us. Lets hope informix + // is doing some garbage collecting. + udesc->sqlvar=NULL; +#endif + delete (SQLDA *)udesc; + udesc = NULL; + } + + udesc = ssql[fd].out; + ssql[fd].out = NULL; + /* If out and exec are the same then no need to the following */ + if (udesc != ssql[fd].exec && ssql[fd].exec) { + udesc = ssql[fd].exec; +#ifndef FIXBUG + // since the sqlvars for out and exec are allocated by describe + // we need to make sure they don't get freed by us. Lets hope informix + // is doing some garbage collecting. + udesc->sqlvar=NULL; +#endif + delete (SQLDA *)udesc; + udesc = NULL; + } + ssql[fd].exec = NULL; + + memset(&ssql[fd], 0, sizeof(SSQL)); + return (sql_error_code()>=0); +} + +bool sql_print(SQL_CURSOR fd) { + struct sqlda *udesc; + struct sqlvar_struct *col; + + if (fd < 0 || fd >= sql::MAXCURSORS) { + sprintf(errmsg, "Invalid fd %d passed to sql_print", fd); + debug(fprintf(stderr, "%s\n", errmsg)); + return false; + } + printf("Command string for fd %d: %s", fd, + (ssql[fd].cmd?ssql[fd].cmd:"null")); + if (!ssql[fd].opened) printf(" not "); + printf(" opened, "); + if (!ssql[fd].opened) printf(" not "); + printf(" selected\n"); + if (ssql[fd].in) { + int i; + udesc = ssql[fd].in; + printf("Input:"); + for (i = 0, col = udesc->sqlvar; i < udesc->sqld; i++, col++) { + if (!(col->sqlname)) col->sqlname="null"; + printf("(%s,%ld,%s)\n",col->sqlname, col->sqllen, col->sqldata); + } + } + if (ssql[fd].out) { + int i; + udesc = ssql[fd].out; + printf("Output:\n"); + for (i = 0, col = udesc->sqlvar; i < udesc->sqld; i++, col++) { + if (!(col->sqlname)) col->sqlname="null"; + printf("(%s,%ld,%s)\n",col->sqlname, col->sqllen, col->sqldata); + } + } + return true; +} + +bool sql_database(const char *dbname, const char *password, int exclusive) { + $char *p; + int len; + int fd=alloc_stmt(); + + if (!dbname || *dbname == '\0') { + p = getenv("DATABASE"); + if (!p) p = "NODATABASE"; + } else + p = const_cast(dbname); + if (exclusive) { + $database $p exclusive; + if (chk_status(fd,"DATABASE EXCLUSIVE", p)) return false; + $set lock mode to wait; + } else { + $database $p; + if (chk_status(fd,"DATABASE", p)) return false; + $set lock mode to wait; + } + if (database_name) { + delete database_name; + database_name = NULL; + } + len = strlen(p) + 1; + database_name = new char [len]; + errmalloc(database_name, "DATABASE", len); + strcpy(database_name, p); + sql_close(fd); + if (SQLCODE<0) { + return false; + } + return true; +} + +bool sql_connect(const char *dbname, const char *uid, const char *pw, const char *cname, int with_contrans) { + $char *p; + $char *username; + $char *password; + $char *conn_name; + int fd=alloc_stmt(); + + int len; + if (!dbname || *dbname == '\0') { + p = getenv("DATABASE"); + if (!p) p = "NODATABASE"; + } else p = const_cast(dbname); + conn_name = const_cast(cname); + username = const_cast(uid); + password = const_cast(pw); + if (cname && *cname != '\0') { + if (with_contrans) { + $connect to $p as $conn_name user $username using $password + with concurrent transaction; + } else { + $connect to $p as $conn_name user $username using $password; + } + } else { + if (with_contrans) { + $connect to $p user $username using $password + with concurrent transaction; + } else { + $connect to $p user $username using $password; + } + } + if (chk_status(fd,"CONNECT", p)) return false; + len = strlen(p) + 1; + if (connection_name) { + delete connection_name; + connection_name = NULL; + } + connection_name = new char [len]; + errmalloc(connection_name, "CONNECT", len); + strcpy(connection_name, p); + sql_close(fd); + return (SQLCODE>=0); +} + +bool sql_disconnect(const char *arg) { + $char *cname; + + cname = const_cast(arg); + if (!arg) { + sprintf(errmsg, "No argument passed to sql_disconnect"); + debug(fprintf(stderr, "%s\n", errmsg)); + return false; + } + if (strcmp(arg, "current") == 0) { + $disconnect current; + } else if (strcmp(arg, "default") == 0) { + $disconnect default; + } else if (strcmp(arg, "all") == 0) { + $disconnect all; + } else { + $disconnect $cname; + } + int fd=alloc_stmt(); + if (chk_status(fd,"DISCONNECT", arg)) return false; + sql_close(fd); + return true; +} + +bool sql_sigcmd(const char *arg) { + $char *cname; + + cname = const_cast(arg); + if (!arg) { + sprintf(errmsg, + "Argument must be one of sqlbreak, sqldetach, sqlexit, sqldone"); + debug(fprintf(stderr, "%s\n", errmsg)); + return false; + } + if (strcmp(arg, "sqlbreak") == 0) { + return (!sqlbreak()); + } else if (strcmp(arg, "sqldetach") == 0) { + return !sqldetach(); + } else if (strcmp(arg, "sqlexit") == 0) { + return !sqlexit(); + } else if (strcmp(arg, "sqldone") == 0) { + return !sqlexit(); + } else { + sprintf(errmsg, + "Argument must be one of sqlbreak, sqldetach, sqlexit, sqldone"); + debug(fprintf(stderr, "%s\n", errmsg)); + return false; + } +} + +bool sql_setconnection(const char *arg, int dormant) { + $char *cname; + + cname = const_cast(arg); + if (!arg) { + sprintf(errmsg, "No argument passed to sql_setconnection"); + debug(fprintf(stderr, "%s\n", errmsg)); + return false; + } + if (strcmp(arg, "current") == 0) { + if (dormant) + $set connection current dormant; + else + /* NOTE: COREDUMPs occur if dormant is removed and no connection is open !!!!*/ + /* HENCE DORMANT IS ALWAYS USED */ + $set connection current dormant; + } else if (strcmp(arg, "default") == 0) { + if (dormant) + $set connection default dormant; + else + $set connection default; + } else { + if (dormant) + $set connection $cname dormant; + else + $set connection $cname; + } + int fd=alloc_stmt(); + if (dormant) { + if (chk_status(fd,"SET CONNECTION DORMANT", arg)) return false; + } else { + if (chk_status(fd,"SET CONNECTION", arg)) return false; + } + sql_close(fd); + return true; +} + +bool sql_finish(void) { + if (database_name) { + delete [] database_name; + database_name = NULL; + } + $close database; + int fd=0; + if (chk_status(fd,"CLOSE", "DATABASE")) return false; + return true; +} + +bool sql_begin(void) { + $begin work; + int fd=alloc_stmt(); + if (chk_status(fd,"BEGIN", "WORK")) return false; + sql_close(fd); + return true; +} + +int sql_commit(void) { + $commit work; + int fd=alloc_stmt(); + if (chk_status(fd,"COMMIT", "WORK")) return false; + sql_close(fd); + return true; +} + +int sql_rollback(void) { + $rollback work; + int fd=alloc_stmt(); + if (chk_status(fd,"ROLLBACK", "WORK")) return false; + sql_close(fd); + return true; +} + +char *sql_getdatabase(void) { + return database_name; +} + +/* +sql readblob table column "rowid = NUM" intofilename [append] + if success (0) returns NULL or SIZE of blob written + else returns ERROR (-1) +sql writeblob table column "rowid = NUM" [fromfilename | null] [size|-1] + if success (0) returns SIZE of blob written + else returns ERROR (-1) +*/ +int sql_readblob(const char *table, const char *column, const char *rowidclause, const char *intofile, + int appendmode) { + $loc_t sloc; + $char stmt[sql::MAXBLOB+1]; + int fd=alloc_stmt(); + + if (atoi(rowidclause) > 0) + sprintf(stmt, "select %s from %s where rowid = %s", + column, table, rowidclause); + else + sprintf(stmt, "select %s from %s where %s", column, table, rowidclause); + + sloc.loc_loctype = LOCFNAME; + sloc.loc_fname = const_cast(intofile); + + if (appendmode) + sloc.loc_oflags = LOC_APPEND; + else + sloc.loc_oflags = LOC_WONLY; + + $prepare tcl_readblob from $stmt; + if (chk_status(fd,"PREPARE(READBLOB)", stmt)) return false; + + $declare tcl_readblob_cur cursor for tcl_readblob; +if (chk_status(fd,"DECLARE(READBLOB)", stmt)) return false; + + $open tcl_readblob_cur; + if (chk_status(fd,"OPEN(READBLOB)", stmt)) return false; + + $fetch tcl_readblob_cur into $sloc; + if (chk_status(fd,"FETCH(READBLOB)", stmt)) return false; + + if (sql_error_code() != 0) { + sprintf(errmsg, "No record found.\n"); + debug(fprintf(stderr, "%s\n", errmsg)); + sql_close(fd); + return -1; + } + + /* + After getting it + sloc.loc_size # of bytes, sloc.loc_indicator = -1 for null, + sloc.loc_status = 0 for success, -ve for error + */ + if (sql_error_code() == 0 && sloc.loc_status == 0) { + if (sloc.loc_indicator == -1) { + $close tcl_readblob_cur; + sql_close(fd); + return -2; + } + $close tcl_readblob_cur; + sql_close(fd); + return sloc.loc_size; + } + $close tcl_readblob_cur; + sql_close(fd); + + return -1; +} + +int sql_writeblob(const char *table, const char *column, const char *rowidclause, const char *fromfile, + int fromsize) { + $loc_t uloc; + $char stmt[sql::MAXBLOB+1]; + $char *colname; + int fd=alloc_stmt(); + + colname = const_cast(column); + + if (atoi(rowidclause) > 0) + sprintf(stmt, "update %s set %s = ? where rowid = %s", + table, column, rowidclause); + else + sprintf(stmt, "update %s set %s = ? where %s", + table, column, rowidclause); + + /* + sprintf(stmt, "select 1 from %s where %s FOR UPDATE OF %s", + table, rowidclause, column); + */ + + uloc.loc_loctype = LOCFNAME; + uloc.loc_fname = const_cast(fromfile); + uloc.loc_oflags = LOC_RONLY; + uloc.loc_size = fromsize; + uloc.loc_indicator = 0; + + if (fromfile) + if (strcmp(fromfile,"null") == 0 || strcmp(fromfile, "NULL") == 0) + uloc.loc_indicator = -1; + + $prepare tcl_writeblob from $stmt; + if (chk_status(fd,"PREPARE(WRITEBLOB)", stmt)) return false; + + $execute tcl_writeblob using $uloc; + if (chk_status(fd,"EXECUTE(WRITEBLOB)", stmt)) return false; + + /* + $declare tcl_writeblob_cur cursor for tcl_writeblob; + chk_status(fd,"DECLARE(WRITEBLOB)", stmt); + + $open tcl_writeblob_cur; + chk_status(fd,"OPEN(WRITEBLOB)", stmt); + + $fetch tcl_writeblob_cur into :found; + chk_status(fd,"FETCH(WRITEBLOB)", stmt); + + sprintf(stmt, "update %s set %s = ? where current of tcl_writeblob_cur", + table, column); + + $prepare tcl_writeblob_new from $stmt; + chk_status(fd,"PREPARE UPDATE(WRITEBLOB)", stmt); + + $execute tcl_writeblob_new using $uloc; + chk_status(fd,"EXECUTE UPDATE(WRITEBLOB)", stmt); + + */ + + /* + After updating it + uloc.loc_size # of bytes transferred + uloc.loc_status = 0 for success, -ve for error + */ + sql_close(fd); + if (sql_error_code() == 0 && uloc.loc_status == 0) + return uloc.loc_size; + + return -1; +} + +#ifdef USE_NAMESPACE +} +#endif + diff --git a/db/sqlint8.cpp b/db/sqlint8.cpp new file mode 100644 index 0000000..bf73081 --- /dev/null +++ b/db/sqlint8.cpp @@ -0,0 +1,39 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#include "sah_config.h" +#include +#include +#include +#include "sqlint8.h" + +#ifdef HAVE_INTTYPES_H + +#elif defined(LLONG_MAX) || defined(HAVE_LONG_LONG) + +#elif defined(USE_MYSQL) && defined(longlong_defined) + +#elif defined(USE_INFORMIX) + +char _ifx_int8::pval[20]; + +#elif defined(_INTEGRAL_MAX_BITS) && (_INTEGRAL_MAX_BITS >= 64) + +#elif defined(HAVE_LONG_DOUBLE) + +#else + +#endif diff --git a/db/sqlint8.h b/db/sqlint8.h new file mode 100644 index 0000000..3d7ab37 --- /dev/null +++ b/db/sqlint8.h @@ -0,0 +1,161 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#ifndef _SQLINT8_H_ +#define _SQLINT8_H_ + +#include "sah_config.h" +#include + +#ifdef HAVE_INTTYPES_H +#include +typedef int64_t sqlint8_t; +#ifdef PRIdLEAST64 + #define INT8_FMT PRIdLEAST64 +#else + #if SIZEOF_LONG_INT >=8 + #define INT8_FMT "ld" + #else + #define INT8_FMT "lld" + #endif +#endif +#define INT8_PRINT_CAST(x) x +#define INT8_USING_INT64_T + + +#elif SIZEOF_LONG_INT >= 8 +typedef long sqlint8_t; +#define INT8_FMT "ld" +#define INT8_PRINT_CAST(x) x +#define INT8_USING_LONG + +#elif defined(LLONG_MAX) || defined(HAVE_LONG_LONG) +typedef long long sqlint8_t; +#define INT8_FMT "lld" +#define INT8_PRINT_CAST(x) x +#define INT8_USING_LONG_LONG + +#elif defined(USE_MYSQL) && !defined(CLIENT) +#include "my_config.h" +#include "global.h" +typedef longlong sqlint8_t; +#define INT8_FMT "lld" +#define INT8_PRINT_CAST(x) x +#define INT8_USING_LONGLONG + +#elif defined(_INTEGRAL_MAX_BITS) && (_INTEGRAL_MAX_BITS >= 64) +typedef _int64 sqlint8_t; +#define INT8_FMT "lld" +#define INT8_PRINT_CAST(x) x +#define INT8_USING_INT64 + +#elif defined(USE_INFORMIX) +#include "int8.h" +#include "sqlhdr.h" +#include +#include + +class _ifx_int8 { + public: + _ifx_int8(ifx_int8 a) : val(a) {}; + _ifx_int8(const char *s) {ifx_int8cvasc(const_cast(s),strlen(s),&val);}; + _ifx_int8(double d) {ifx_int8cvdbl(d,&val);}; + _ifx_int8(long l) {ifx_int8cvlong(l,&val);}; + _ifx_int8(int l=0) {ifx_int8cvlong(static_cast(l),&val);}; + operator const char *() const ; + operator long() const ; + private: + ifx_int8 val; + static char pval[20]; +}; + + +inline _ifx_int8::operator const char *() const { + ifx_int8toasc(const_cast(&val),pval,20); + pval[19]=0; + return pval; +} + +inline _ifx_int8::operator long() const { + long l; + ifx_int8tolong(const_cast(&val),&l); + return l; +} + +typedef _ifx_int8 sqlint8_t; +#define INT8_FMT "s" +#define INT8_PRINT_CAST(x) static_cast(x) +#define INT8_USING_IFX + +#elif defined(HAVE_LONG_DOUBLE) +typedef long double sqlint8_t; +#define INT8_FMT "lf21.0" +#define INT8_PRINT_CAST(x) x +#define INT8_USING_LONG_DOUBLE + +#else +typedef double sqlint8_t; +#define INT8_FMT "f16.0" +#define INT8_PRINT_CAST(x) x +#define INT8_USING_DOUBLE +#endif + +#ifndef HAVE_ATOLL +inline sqlint8_t atoll(const char *p) { + sqlint8_t rv=0; + sqlint8_t sign=1; + while (isspace(*(p++))) /* do nothing */ ; + if (*p=='-') { + sign=-1; + p++; + } + while (isdigit(*(p++))) { + rv*=10; + rv+=(*(p-1)-'0'); + } + rv*=sign; + return rv; +} +#endif + +#if defined(INT8_USING_INT64) || defined(INT8_USING_IFX) +inline std::ostream &operator <<(std::ostream &o, const sqlint8_t &p) { + char buf[32]; + sprintf(buf,"%"INT8_FMT,INT8_PRINT_CAST(p)); + o << buf ; + return o; +} + +inline std::istream &operator >>(std::istream &i, sqlint8_t &p) { + char c=' '; + sqlint8_t sign=1; + p=0; + while (isspace(c) && !i.eof()) i.get(c); + if (c=='-') { + sign=-1; + if (!i.eof()) i.get(c); + } + while (isdigit(c) && !i.eof()) { + p*=10; + p+=(c-'0'); + i.get(c); + } + if (!i.eof()) i.putback(c); + p*=sign; + return i; +} +#endif +#endif diff --git a/db/sqlrow.cpp b/db/sqlrow.cpp new file mode 100644 index 0000000..68364c2 --- /dev/null +++ b/db/sqlrow.cpp @@ -0,0 +1,366 @@ +// Copyright 2003 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#include "sah_config.h" + +#include +#include +#include +#include +#include + +#include "sqlrow.h" + +const SQL_ROW empty_row; +const std::string empty_string(""); + +#define found(x) ((x != std::string::npos)) + +std::string *SQL_ROW::string_delimited(std::string &s, char c_start, char c_end) +{ + // return the substring of a string delimited by c_start and c_end. + // c_start and c_end. The substring returned will include everything from + // c_start and before the comma or end or string following c_end. + std::string::size_type open,cls,strt,comma; + std::string::size_type q(s.find(c_start)); // find the opening delimiter. + + if (found(q)) { + strt=q; + int nopen=1; + // since any of the items inside this type could be sql defined + // types themselves, we need to find the matching close delimiter + do { + open=s.find(c_start,q+1); + cls=s.find(c_end,q+1); + if (found(cls) && (cls SQL_ROW::parse_delimited(std::string &s,char c_start,char c_end) { + // parse a section of a comma separated string delimited by the characters + // c_start and c_end. The substring parsed will include everything after + // c_start and before the comma or end of string following c_end. This allows + // sql types of the format "ROW(a,b,c)::type_name" to be properly parsed + // to return a,b and c. + std::string *sub(string_delimited(s,c_start,c_end)); // Get delimited string + std::string tmp(*sub,1,sub->size()-1); // Remove opening delimiter + std::vector rv(parse_row(tmp)); + delete sub; +#ifdef DEBUG_ALLOCATIONS + fprintf(stderr,"std::string deleted at 0x%p\n",sub); + fflush(stderr); +#endif + return rv; +} + +std::vector SQL_ROW::parse_type(std::string &s) { + // Parses informix defined types of the format "ROW(a,b,c)::typename" + return parse_delimited(s,'(',')'); +} + +std::vector SQL_ROW::parse_list(std::string &s) { + // Parses informix lists of the format "LIST{a,b,c}" + return parse_delimited(s,'{','}'); +} + +std::string *SQL_ROW::parse_blob(std::string &s) { + // Parsed binary objects of the format "fasd874235vxzfdgas" + // or binary objects consisting of the entire string. + std::string *rv; + std::string::size_type etag=s.find('>'); + ssize_t length; + + if (found(etag)) { + std::string::size_type p(s.find('=')); + if (p SQL_ROW::parse_row(std::string &s) { + // parses a SQL row of the format "value,value,value,value", + // where value can be of the form: + // number (i.e. 10) + // "string" + // 'string' + // LIST{value,value,value} + // ROW(value,value,value)::typename + // the passed string is consumed by this routine. + // WARNING: NOT THREAD SAFE + std::string::size_type comma,dquote,quote,p; + std::vector::iterator i; + std::vector rv; + static bool outer=true; + + while (s.size()) { // While there's still bits of string left to process + // get rid of leading spaces and commas + while (isspace(s[0]) && s.size()) s.erase(0,1); + while (s[0]==',') s.erase(0,1); + + // Handle the special cases first... + if (s.find("LIST")==0) { + // only parse a LIST if the entire string passed to parse_row was a list + if (outer) { + outer=false; + std::vector tmprow(parse_list(s)); + for (i=tmprow.begin();i tmprow(parse_type(s)); + for (i=tmprow.begin();i("SQL_ROW") { + if (s) { + std::string tmp(*s); + pval=parse_row(tmp); + } else { + pval.clear(); + for (size_t i=0;i("SQL_ROW") { + ssize_t i; + std::string *p; + if (end_col<(ssize_t)start_col) end_col=(ssize_t)s.argc()-1; + for (i=start_col;i<(end_col+1);i++) { + if (s.exists(i)) { + p=new std::string(*(s[i])); +#ifdef DEBUG_ALLOCATIONS + fprintf(stderr,"std::string allocated at 0x%p\n",p); + fflush(stderr); +#endif + } else { + p=0; + } + pval.push_back(p); + } +} + +SQL_ROW &SQL_ROW::operator =(const SQL_ROW &s) { + if (this != &s) { + size_t i; + std::string *p; + for (i=0;i +#include +#include +#include +#include +#include +#include "track_mem.h" +#include "xml_util.h" + +typedef int SQL_CURSOR; + +class SQL_ROW; +extern const SQL_ROW empty_row; +extern const std::string empty_string; + +class SQL_ROW : track_mem { + public: + explicit SQL_ROW(const std::string *s=NULL,size_t i=0); + // explicit SQL_ROW(const char **arr, int nfields); + SQL_ROW(const SQL_ROW &r, size_t start_col=0, ssize_t end_col=-1); + ~SQL_ROW(); + SQL_ROW &operator=(const SQL_ROW &r); + std::vector pval; + size_t argc(size_t i); + size_t argc() const; + void clear(size_t i) { + if ((pval.size()>i) && pval[i]) { + delete pval[i]; +#ifdef DEBUG_ALLOCATIONS + fprintf(stderr,"std::string deleted at 0x%p\n",pval[i]); + fflush(stderr); +#endif + } + pval[i]=NULL; + }; + bool exists(size_t i) const { return ((pval.size()>i) && (pval[i])); } + void clear() { pval.resize(0); } + + // operator char **(); + SQL_ROW operator +(size_t i) const; + std::string *&operator [](size_t i); + const std::string *operator [](size_t i) const; + // const char *operator [](int i) const; + // char *operator *() const; + private: + std::string *string_delimited(std::string &s,char c_open,char c_close); + std::vector parse_delimited(std::string &s,char c_open,char c_close); + std::vector parse_type(std::string &s); + std::vector parse_list(std::string &s); + std::vector parse_row(std::string &s); + std::string *parse_blob(std::string &s); +}; + +//inline SQL_ROW::operator char **() {return static_cast(&(pval[0]));} + +inline std::string *&SQL_ROW::operator [](size_t i) {return pval[i];} +inline const std::string *SQL_ROW::operator [] (size_t i) const { + return (argc()>i)?pval[i]:&empty_string; +} + +/* +inline const char *SQL_ROW::operator [](int i) const { + if (((unsigned)i)c_str()); + } else { + return ""; + } +} +*/ + + +//inline char *SQL_ROW::operator *() const {return (pval[0]);} + +inline size_t SQL_ROW::argc(size_t i) { + if (i > pval.size()) { + while (pval.size() != i) { + pval.push_back(new std::string(empty_string)); +#ifdef DEBUG_ALLOCATIONS + fprintf(stderr,"std::string allocated at 0x%p\n",pval[pval.size()-1]); + fflush(stderr); +#endif + + } + } else { + while (pval.size() != i) { + if (pval[pval.size()-1]) { +#ifdef DEBUG_ALLOCATIONS + fprintf(stderr,"std::string deleted at 0x%p\n",pval[pval.size()-1]); + fflush(stderr); +#endif + delete pval[pval.size()-1]; + } + pval.pop_back(); + } + } + return pval.size(); +} + +inline size_t SQL_ROW::argc() const {return pval.size();} + +inline SQL_ROW SQL_ROW::operator +(size_t i) const { return SQL_ROW(*this,i); } + +#endif diff --git a/db/tools/Makefile.in b/db/tools/Makefile.in new file mode 100644 index 0000000..519acdc --- /dev/null +++ b/db/tools/Makefile.in @@ -0,0 +1,54 @@ +BOINCDIR = @BOINCDIR@ +INFORMIXDIR= @INFORMIXDIR@ +BOINCLIBS=-L$(BOINCDIR)/lib -lboinc +SETIHOME=../.. +DBLIBS=../xml_util.o ../sqlblob.o ../sqlrow.o ../sqlifx.o @INFORMIX_LIBS@ -ldl -lm -lstdc++ @PTHREAD_LIBS@ + +INCLUDE_DIRS= -I$(SETIHOME) -I$(SETIHOME)/client -I$(SETIHOME)/db \ + @MYSQL_CFLAGS@ \ + @INFORMIX_CFLAGS@ \ + @PTHREAD_CFLAGS@ \ + -I$(BOINCDIR) -I$(BOINCDIR)/lib -I$(BOINCDIR)/sched -I$(BOINCDIR)/db -I$(BOINCDIR)/tools + +LINKOPTIONS=-Xlinker -R -Xlinker $(LD_LIBRARY_PATH):$(INFORMIXDIR)/lib:$(INFORMIXDIR)/lib/esql + +SUFFIXES = .cpp .o + +.cpp.o: + $(CXX) $(CXXFLAGS) -c $< + +CC = @CC@ + +CFLAGS = @CFLAGS@ @DEFS@ $(INCLUDE_DIRS) -DUSE_INFORMIX + +CXX = @CXX@ + +CXXFLAGS = $(CFLAGS) + +dependencies: *.cpp + $(CC) $(CFLAGS) -M *.cpp > dependencies + +all: dependencies print_s4_receivers insert_analysis_config insert_splitter_config insert_receiver_config insert_rfi_zones + +insert_s4_receivers: insert_s4_receivers.o ../schema_master.o ../sqlifx.o ../sqlrow.o + $(CC) $(LINKOPTIONS) -o insert_s4_receivers insert_s4_receivers.o ../schema_master.o $(S4LIBS) $(DBLIBS) $(BOINCLIBS) + +insert_receiver_config: insert_receiver_config.o ../schema_master.o ../sqlifx.o ../sqlrow.o + $(CC) $(LINKOPTIONS) -o insert_receiver_config insert_receiver_config.o ../schema_master.o $(S4LIBS) $(DBLIBS) $(BOINCLIBS) + +insert_analysis_config: insert_analysis_config.o ../schema_master.o ../sqlifx.o ../sqlrow.o + $(CC) $(LINKOPTIONS) -o insert_analysis_config insert_analysis_config.o ../schema_master.o $(S4LIBS) $(DBLIBS) $(BOINCLIBS) + +insert_rfi_zones: insert_rfi_zones.o ../schema_master.o ../sqlifx.o ../sqlrow.o + $(CC) $(LINKOPTIONS) -o insert_rfi_zones insert_rfi_zones.o ../schema_master.o $(S4LIBS) $(DBLIBS) $(BOINCLIBS) + +insert_science_config: insert_science_config.o ../schema_master.o ../sqlifx.o ../sqlrow.o + $(CC) $(LINKOPTIONS) -o insert_science_config insert_science_config.o ../schema_master.o $(S4LIBS) $(DBLIBS) $(BOINCLIBS) + +insert_splitter_config: insert_splitter_config.o ../schema_master.o ../sqlifx.o ../sqlrow.o + $(CC) $(LINKOPTIONS) -o insert_splitter_config insert_splitter_config.o ../schema_master.o $(S4LIBS) $(DBLIBS) $(BOINCLIBS) + +print_s4_receivers: print_s4_receivers.o ../schema_master.o ../sqlifx.o ../sqlrow.o + $(CC) $(LINKOPTIONS) -o print_s4_receivers print_s4_receivers.o ../schema_master.o $(S4LIBS) $(DBLIBS) $(BOINCLIBS) + +include dependencies diff --git a/db/tools/analysis_configs.xml b/db/tools/analysis_configs.xml new file mode 100644 index 0000000..00c8ff2 --- /dev/null +++ b/db/tools/analysis_configs.xml @@ -0,0 +1,49 @@ + + 24.0 + 1 + 17.8 + 1 + 131072 + 2.225 + 1.42 + 3.0 + 3.2 + 64 + 19.5 + 0.5 + 40960 + 16 + 8192 + 256 + 8.50 + 131072 + 16 + 256 + 0.5 + 1 + 0.0021 # should be beams/s rather and degrees + 0.0105 # should be beams/s rather and degrees + 0.1665 + 262136 + 8192 # should be seconds + 32768 # should be seconds + + + 30.0 + 262136 + + + 100.0 + 65528 + + + 1.0 + 30 + 8 + 8 + 0 + 0 + 0 + 31 + 2.85 + diff --git a/db/tools/insert_analysis_config.cpp b/db/tools/insert_analysis_config.cpp new file mode 100644 index 0000000..96f3d20 --- /dev/null +++ b/db/tools/insert_analysis_config.cpp @@ -0,0 +1,61 @@ +#include "sah_config.h" +#include +#include +#include +#include +#include +#include +#include "parse.h" +#include "s_util.h" +#include "sqlapi.h" +#include "db_table.h" +#include "schema_master.h" + +analysis_config cfg; + +int main(int argc, char **argv) { + int i=0; + bool beta=false, sah=false; + + if (argc != 3) { + fprintf(stderr,"Usage:\n insert_analysis_config beta|sah filename\n"); + exit(1); + } + if (strcmp(argv[1], "beta") == 0) { + beta = true; + fprintf(stderr, "Inserting into the beta DB\n"); + } else if (strcmp(argv[1], "sah") == 0) { + sah = true; + fprintf(stderr, "Inserting into the sah DB\n"); + } else { + fprintf(stderr,"Usage:\n insert_analysis_config beta|sah filename\n"); + exit(1); + } + + std::ifstream f(argv[2]); + + if (!f.is_open()) { + fprintf(stderr,"File not found!\n"); + exit(1); + } + + if(beta) { + db_change("sah2b@sah_master_tcp"); + } else if(sah) { + db_change("sah2@sah_master_tcp"); + } else { + fprintf(stderr,"bad DB specification\n"); + } + + while (!f.eof()) { + f >> cfg; + if (!f.eof()) { + i++; + cfg.insert(); + fprintf(stderr, "SQLCODE is %d last SQLCODE is %d\n", sql_error_code(), sql_last_error_code()); + } + } + + std::cout << "Found " << i << " analysis configs." << std::endl; +} + diff --git a/db/tools/insert_receiver_config.cpp b/db/tools/insert_receiver_config.cpp new file mode 100644 index 0000000..1f52441 --- /dev/null +++ b/db/tools/insert_receiver_config.cpp @@ -0,0 +1,43 @@ +#include "sah_config.h" +#include +#include +#include +#include +#include +#include +#include "parse.h" +#include "s_util.h" +#include "sqlapi.h" +#include "db_table.h" +#include "schema_master.h" + +receiver_config cfg; + +int main(int argc, char **argv) { + int i=0; + + if (argc != 2) { + fprintf(stderr,"Usage:\n insert_receiver_config filename\n"); + exit(1); + } + + std::ifstream f(argv[1]); + + if (!f.is_open()) { + fprintf(stderr,"File not found!\n"); + exit(1); + } + + db_change("sah2@sci_master_tcp"); + + while (!f.eof()) { + f >> cfg; + if (!f.eof()) { + i++; + cfg.insert(); + } + } + + std::cout << "Found " << i << " receiver configs." << std::endl; +} + diff --git a/db/tools/insert_rfi_zones.cpp b/db/tools/insert_rfi_zones.cpp new file mode 100644 index 0000000..33f2685 --- /dev/null +++ b/db/tools/insert_rfi_zones.cpp @@ -0,0 +1,61 @@ +#include "sah_config.h" +#include +#include +#include +#include +#include +#include +#include "parse.h" +#include "s_util.h" +#include "sqlapi.h" +#include "db_table.h" +#include "schema_master.h" + +rfi_zone zone; + +int main(int argc, char **argv) { + int i=0; + bool beta=false, sah=false; + + if (argc != 3) { + fprintf(stderr,"Usage:\n insert_rfi_zones beta|sah filename\n"); + exit(1); + } + if (strcmp(argv[1], "beta") == 0) { + beta = true; + fprintf(stderr, "Inserting into the beta DB\n"); + } else if (strcmp(argv[1], "sah") == 0) { + sah = true; + fprintf(stderr, "Inserting into the sah DB\n"); + } else { + fprintf(stderr,"Usage:\n insert_rfi_zones beta|sah filename\n"); + exit(1); + } + + std::ifstream f(argv[2]); + + if (!f.is_open()) { + fprintf(stderr,"File not found!\n"); + exit(1); + } + + if(beta) { + db_change("sah2b@sci_master_tcp"); + } else if(sah) { + db_change("sah2@sci_master_tcp"); + } else { + fprintf(stderr,"bad DB specification\n"); + } + + while (!f.eof()) { + f >> zone; + if (!f.eof()) { + i++; + zone.insert(); + fprintf(stderr, "SQLCODE is %d last SQLCODE is %d\n", sql_error_code(), sql_last_error_code()); + } + } + + std::cout << "Found " << i << " rfi zones." << std::endl; +} + diff --git a/db/tools/insert_s4_receivers.cpp b/db/tools/insert_s4_receivers.cpp new file mode 100644 index 0000000..e850833 --- /dev/null +++ b/db/tools/insert_s4_receivers.cpp @@ -0,0 +1,54 @@ +#include "sah_config.h" +#include +#include +#include +#include +#include +#include "s_util.h" +#include "sqlapi.h" +#include "db_table.h" +#include "schema_master.h" + +#include +#include + +#define S4_RECEIVER_CONFIG_FILE "/usr/local/warez/projects/s4/siren/db/ReceiverConfig.tab" + +ReceiverConfig_t input; +receiver_config output; + +int main() { + int i,j; + if (!sql_database("sah2b@sci_master_tcp")) exit(1); + if (!getenv("S4_RECEIVER_CONFIG")) + putenv("S4_RECEIVER_CONFIG="S4_RECEIVER_CONFIG_FILE); + + for (i=0;i<3;i++) { + memset(&input,0,sizeof(input)); + s4cfg_GetReceiverConfig(i, &input); + output.s4_id=input.ReceiverID; + strncpy(output.name,input.ReceiverName,255); + output.name[254]=0; + output.beam_width=input.BeamWidth; + output.center_freq=input.CenterFreq; + output.latitude=input.Latitude; + output.longitude=input.Longitude; + output.elevation=input.Elevation; + output.diameter=input.Diameter; + output.az_orientation=input.AzOrientation; + output.zen_corr_coeff.clear(); + output.az_corr_coeff.clear(); + for (j=0;j<13;j++) { + output.zen_corr_coeff.push_back(input.ZenCorrCoeff[j]); + output.az_corr_coeff.push_back(input.AzCorrCoeff[j]); + } + db_change("sah2b@sci_master_tcp"); + output.id=0; + if (output.insert()) { + std::cout << "inserted row (id=" << output.id << ")" << std::endl; + } else { + std::cout << "insert failed, sql_error_code =" << sql_error_code() << " sql_last_error_code =" << sql_last_error_code() << std::endl; + } + } +} + diff --git a/db/tools/insert_science_config.cpp b/db/tools/insert_science_config.cpp new file mode 100644 index 0000000..e1e6e6a --- /dev/null +++ b/db/tools/insert_science_config.cpp @@ -0,0 +1,62 @@ +#include "sah_config.h" +#include +#include +#include +#include +#include +#include +#include "parse.h" +#include "s_util.h" +#include "sqlapi.h" +#include "db_table.h" +#include "schema_master.h" + +science_config cfg; + +int main(int argc, char **argv) { + int i=0; + bool beta=false, sah=false; + + if (argc != 3) { + fprintf(stderr,"Usage:\n insert_science_config beta|sah filename\n"); + exit(1); + } + if (strcmp(argv[1], "beta") == 0) { + beta = true; + fprintf(stderr, "Inserting into the beta DB\n"); + } else if (strcmp(argv[1], "sah") == 0) { + sah = true; + fprintf(stderr, "Inserting into the sah DB\n"); + } else { + fprintf(stderr,"Usage:\n insert_science_config beta|sah filename\n"); + exit(1); + } + + std::ifstream f(argv[2]); + + if (!f.is_open()) { + fprintf(stderr,"File not found!\n"); + exit(1); + } + + if(beta) { + db_change("sah2b@sci_master_tcp"); + } else if(sah) { + db_change("sah2@sci_master_tcp"); + } else { + fprintf(stderr,"bad DB specification\n"); + } + + while (!f.eof()) { + f >> cfg; + if (!f.eof()) { + i++; + fprintf(stderr, "%s\n", cfg.print_xml().c_str()); + cfg.insert(); + fprintf(stderr, "SQLCODE is %d last SQLCODE is %d\n", sql_error_code(), sql_last_error_code()); + } + } + + std::cout << "Found " << i << " science configs." << std::endl; +} + diff --git a/db/tools/insert_splitter_config.cpp b/db/tools/insert_splitter_config.cpp new file mode 100644 index 0000000..1afa32e --- /dev/null +++ b/db/tools/insert_splitter_config.cpp @@ -0,0 +1,43 @@ +#include "sah_config.h" +#include +#include +#include +#include +#include +#include +#include "parse.h" +#include "s_util.h" +#include "sqlapi.h" +#include "db_table.h" +#include "schema_master.h" + +splitter_config cfg; + +int main(int argc, char **argv) { + int i=0; + + if (argc != 2) { + fprintf(stderr,"Usage:\n insert_splitter_config filename\n"); + exit(1); + } + + std::ifstream f(argv[1]); + + if (!f.is_open()) { + fprintf(stderr,"File not found!\n"); + exit(1); + } + + db_change("sah2b@sci_master_tcp"); + + while (!f.eof()) { + f >> cfg; + if (!f.eof()) { + i++; + cfg.insert(); + } + } + + std::cout << "Found " << i << " splitter configs." << std::endl; +} + diff --git a/db/tools/print_s4_receivers.cpp b/db/tools/print_s4_receivers.cpp new file mode 100644 index 0000000..8c027d4 --- /dev/null +++ b/db/tools/print_s4_receivers.cpp @@ -0,0 +1,26 @@ +#include "sah_config.h" +#include +#include +#include +#include +#include +#include +#include "s_util.h" +#include "sqlapi.h" +#include "xml_util.h" +#include "db_table.h" +#include "schema_master.h" + +receiver_config input; + +int main() { + if (!sql_database("sah2b@sci_master_tcp")) exit(1); + std::cout << "\n"; + std::cout << xml_indent() << "" << input.count() << "\n" ; + if (input.open_query()) { + while (input.get_next()) { + std::cout << input.print_xml(); + } + } + std::cout << "\n"; +} diff --git a/db/tools/recorder_configs.sql b/db/tools/recorder_configs.sql new file mode 100644 index 0000000..a981c2f --- /dev/null +++ b/db/tools/recorder_configs.sql @@ -0,0 +1,3 @@ +database sah2@sci_master_tcp; + +insert into recorder_config values(0,"seti_dr2_ALFA",2,2500000,14,1.99); diff --git a/db/tools/rfi_zones_to_xml.pro b/db/tools/rfi_zones_to_xml.pro new file mode 100644 index 0000000..68460f5 --- /dev/null +++ b/db/tools/rfi_zones_to_xml.pro @@ -0,0 +1,23 @@ +pro zones_to_xml, zones, file + + unit = 1 + openw, unit, file + + n = n_elements(zones) + + for i=0,n-1 do begin + printf, unit, "" + printf, unit, " ", zones[i].min_time, "" + printf, unit, " ", zones[i].max_time, "" + printf, unit, " ", zones[i].CENTRAL_DETECTION_FREQ, "" + printf, unit, " ", zones[i].detection_freq_width, "" + printf, unit, " ", zones[i].central_period, "" + printf, unit, " ", zones[i].period_width, "" + printf, unit, " ", zones[i].fft_len_flags, "" + printf, unit, " ", zones[i].signal_type_flags, "" + printf, unit, "" + endfor + + close, unit + +end diff --git a/db/tools/s4_receivers.xml b/db/tools/s4_receivers.xml new file mode 100644 index 0000000..9b3e91c --- /dev/null +++ b/db/tools/s4_receivers.xml @@ -0,0 +1,357 @@ + + 0 + ao430 + 0.166999996 + 430 + 18.3538056 + -66.7552222 + 497 + 168 + 0 + + 7.4,5.4,-49.1,355,0,0,0,0,0,0,0,0,0 + + + -97.1,66.1,14.3,321.7,0,0,0,0,0,0,0,0,0 + + + + 1 + ao1420 + 0.0829999968 + 1420 + 18.3538056 + -66.7552222 + 497 + 168 + 0 + + 7.4,5.4,-49.1,-1091,0,0,0,0,0,0,0,0,0 + + + -5146.7,66.1,14.3,321.7,0,0,0,0,0,0,0,0,0 + + + + 2 + aogreg1420 + 0.0500000007 + 1420 + 18.3538056 + -66.7552222 + 497 + 168 + 180 + + -16.41,-6.41,99.16,-713.84,-1028.24,-22.2,-12.08,7.31,111.56,2.49,-0.69, + -1.93,0.91 + + + -90.48,-100.92,-5.74,175.81,489.81,-11.42,-7.8,4,1.25,0.43,-0.42,-0.3, + -0.19 + + + + 3 + Arecibo 1.4GHz Array, Beam 0, Pol 0 + 0.05 + 1420 + 18.3538056 + -66.7552222 + 497 + 168 + 180 + + -37,-6.05,92.35,-731.21,-1013.97,-24.53,-11.19,9.18,106.04,3.02,-1.74, + -3.46,1.29 + + + -57.55,-95.56,-4.13,141.69,677.51,-10.41,-7.71,-10.39,0.08,0.43,-0.62, + 0.03,-0.36 + + + + 4 + Arecibo 1.4GHz Array, Beam 0, Pol 1 + 0.05 + 1420 + 18.3538056 + -66.7552222 + 497 + 168 + 180 + + -37,-6.05,92.35,-731.21,-1013.97,-24.53,-11.19,9.18,106.04,3.02,-1.74, + -3.46,1.29 + + + -57.55,-95.56,-4.13,141.69,677.51,-10.41,-7.71,-10.39,0.08,0.43,-0.62, + 0.03,-0.36 + + + + 5 + Arecibo 1.4GHz Array, Beam 1, Pol 0 + 0.05 + 1420 + 18.3538056 + -66.7552222 + 497 + 168 + 180 + + -37,-6.05,92.35,-731.21,-1013.97,-24.53,-11.19,9.18,106.04,3.02,-1.74, + -3.46,1.29 + + + -57.55,-95.56,-4.13,141.69,677.51,-10.41,-7.71,-10.39,0.08,0.43,-0.62, + 0.03,-0.36 + + 329.06 + 384.005 + 120.0 + + + 6 + Arecibo 1.4GHz Array, Beam 1, Pol 1 + 0.05 + 1420 + 18.3538056 + -66.7552222 + 497 + 168 + 180 + + -37,-6.05,92.35,-731.21,-1013.97,-24.53,-11.19,9.18,106.04,3.02,-1.74, + -3.46,1.29 + + + -57.55,-95.56,-4.13,141.69,677.51,-10.41,-7.71,-10.39,0.08,0.43,-0.62, + 0.03,-0.36 + + 329.06 + 384.005 + 120.0 + + + 7 + Arecibo 1.4GHz Array, Beam 2, Pol 0 + 0.05 + 1420 + 18.3538056 + -66.7552222 + 497 + 168 + 180 + + -37,-6.05,92.35,-731.21,-1013.97,-24.53,-11.19,9.18,106.04,3.02,-1.74, + -3.46,1.29 + + + -57.55,-95.56,-4.13,141.69,677.51,-10.41,-7.71,-10.39,0.08,0.43,-0.62, + 0.03,-0.36 + + 329.06 + 384.005 + 180.0 + + + 8 + Arecibo 1.4GHz Array, Beam 2, Pol 1 + 0.05 + 1420 + 18.3538056 + -66.7552222 + 497 + 168 + 180 + + -37,-6.05,92.35,-731.21,-1013.97,-24.53,-11.19,9.18,106.04,3.02,-1.74, + -3.46,1.29 + + + -57.55,-95.56,-4.13,141.69,677.51,-10.41,-7.71,-10.39,0.08,0.43,-0.62, + 0.03,-0.36 + + 329.06 + 384.005 + 180.0 + + + 9 + Arecibo 1.4GHz Array, Beam 3, Pol 0 + 0.05 + 1420 + 18.3538056 + -66.7552222 + 497 + 168 + 180 + + -37,-6.05,92.35,-731.21,-1013.97,-24.53,-11.19,9.18,106.04,3.02,-1.74, + -3.46,1.29 + + + -57.55,-95.56,-4.13,141.69,677.51,-10.41,-7.71,-10.39,0.08,0.43,-0.62, + 0.03,-0.36 + + 329.06 + 384.005 + -120.0 + + + 10 + Arecibo 1.4GHz Array, Beam 3, Pol 1 + 0.05 + 1420 + 18.3538056 + -66.7552222 + 497 + 168 + 180 + + -37,-6.05,92.35,-731.21,-1013.97,-24.53,-11.19,9.18,106.04,3.02,-1.74, + -3.46,1.29 + + + -57.55,-95.56,-4.13,141.69,677.51,-10.41,-7.71,-10.39,0.08,0.43,-0.62, + 0.03,-0.36 + + 329.06 + 384.005 + -120.0 + + + 11 + Arecibo 1.4GHz Array, Beam 4, Pol 0 + 0.05 + 1420 + 18.3538056 + -66.7552222 + 497 + 168 + 180 + + -37,-6.05,92.35,-731.21,-1013.97,-24.53,-11.19,9.18,106.04,3.02,-1.74, + -3.46,1.29 + + + -57.55,-95.56,-4.13,141.69,677.51,-10.41,-7.71,-10.39,0.08,0.43,-0.62, + 0.03,-0.36 + + 329.06 + 384.005 + -60.0 + + + 12 + Arecibo 1.4GHz Array, Beam 4, Pol 1 + 0.05 + 1420 + 18.3538056 + -66.7552222 + 497 + 168 + 180 + + -37,-6.05,92.35,-731.21,-1013.97,-24.53,-11.19,9.18,106.04,3.02,-1.74, + -3.46,1.29 + + + -57.55,-95.56,-4.13,141.69,677.51,-10.41,-7.71,-10.39,0.08,0.43,-0.62, + 0.03,-0.36 + + 329.06 + 384.005 + -60.0 + + + 13 + Arecibo 1.4GHz Array, Beam 5, Pol 0 + 0.05 + 1420 + 18.3538056 + -66.7552222 + 497 + 168 + 180 + + -37,-6.05,92.35,-731.21,-1013.97,-24.53,-11.19,9.18,106.04,3.02,-1.74, + -3.46,1.29 + + + -57.55,-95.56,-4.13,141.69,677.51,-10.41,-7.71,-10.39,0.08,0.43,-0.62, + 0.03,-0.36 + + 329.06 + 384.005 + 0.0 + + + 14 + Arecibo 1.4GHz Array, Beam 5, Pol 1 + 0.05 + 1420 + 18.3538056 + -66.7552222 + 497 + 168 + 180 + + -37,-6.05,92.35,-731.21,-1013.97,-24.53,-11.19,9.18,106.04,3.02,-1.74, + -3.46,1.29 + + + -57.55,-95.56,-4.13,141.69,677.51,-10.41,-7.71,-10.39,0.08,0.43,-0.62, + 0.03,-0.36 + + 329.06 + 384.005 + 0.0 + + + 15 + Arecibo 1.4GHz Array, Beam 6, Pol 0 + 0.05 + 1420 + 18.3538056 + -66.7552222 + 497 + 168 + 180 + + -37,-6.05,92.35,-731.21,-1013.97,-24.53,-11.19,9.18,106.04,3.02,-1.74, + -3.46,1.29 + + + -57.55,-95.56,-4.13,141.69,677.51,-10.41,-7.71,-10.39,0.08,0.43,-0.62, + 0.03,-0.36 + + 329.06 + 384.005 + 60.0 + + + 16 + Arecibo 1.4GHz Array, Beam 6, Pol 1 + 0.05 + 1420 + 18.3538056 + -66.7552222 + 497 + 168 + 180 + + -37,-6.05,92.35,-731.21,-1013.97,-24.53,-11.19,9.18,106.04,3.02,-1.74, + -3.46,1.29 + + + -57.55,-95.56,-4.13,141.69,677.51,-10.41,-7.71,-10.39,0.08,0.43,-0.62, + 0.03,-0.36 + + 329.06 + 384.005 + 60.0 + + + diff --git a/db/tools/science_configs.xml b/db/tools/science_configs.xml new file mode 100644 index 0000000..d299d8d --- /dev/null +++ b/db/tools/science_configs.xml @@ -0,0 +1,48 @@ + + 0 + NEST + 2048 + 10.0 + 2500000.0 + 50.0 + 0.05 + 0.05 + 14400.0 + 2000 + 10.0 + 50000.0 + 0.0 + 0.0 + 107.0 + 0.010417 + 12.5 + 0.0 + 0.0 + 0.0 + 0.0 + place_holder + + + 1 + NEST + 2048 + 10.0 + 2500000.0 + 50.0 + 0.05 + 0.05 + 14400.0 + 2000 + 10. + 50000. + 0.0 + 0.000694 + 107.0 + 0.000694 + 12.5 + 0.000694 + 12.5 + 0.000694 + 0.0 + place_holder + diff --git a/db/tools/settings.sql b/db/tools/settings.sql new file mode 100644 index 0000000..f216e54 --- /dev/null +++ b/db/tools/settings.sql @@ -0,0 +1,6 @@ +database sah2b@sah_master_tcp; + +update settings set active=0 where 1 = 1 ; + +insert into settings values(0,8,3,4,1294,10); + diff --git a/db/tools/splitter_configs.xml b/db/tools/splitter_configs.xml new file mode 100644 index 0000000..e6c619a --- /dev/null +++ b/db/tools/splitter_configs.xml @@ -0,0 +1,11 @@ + + 0.20 + encoded + 2048 + 8 + fft + welsh + 1048576 + 0.0 + randomize + diff --git a/db/track_mem.h b/db/track_mem.h new file mode 100644 index 0000000..f629d9d --- /dev/null +++ b/db/track_mem.h @@ -0,0 +1,39 @@ + +#ifndef _TRACK_MEM_H_ +#define _TRACK_MEM_H_ + +#include +#include + +template +class track_mem { +#ifdef DEBUG_ALLOCATIONS + private: + static const char *name; + static int ref_count; + public: + track_mem(const char *n="unknown") { + name=n; + fprintf(stderr,"%s #%d: allocated 0x%lx bytes at 0x%p\n",name,++ref_count,sizeof(T),this); + fflush(stderr); + }; + ~track_mem() { + fprintf(stderr,"%s #%d: freed 0x%lx bytes at 0x%p\n",name,this->ref_count--,sizeof(T),this); + fflush(stderr); + }; +#else + public: + track_mem(const char *n=0) {}; + ~track_mem() {}; +#endif +}; + +#ifdef DEBUG_ALLOCATIONS +template +const char *track_mem::name; + +template +int track_mem::ref_count; +#endif + +#endif diff --git a/db/xml_util.cpp b/db/xml_util.cpp new file mode 100644 index 0000000..6b94de0 --- /dev/null +++ b/db/xml_util.cpp @@ -0,0 +1,838 @@ +// $Id: xml_util.cpp,v 1.3.2.8 2007/02/28 01:45:17 vonkorff Exp $ +// The contents of this file are subject to the BOINC Public License +// Version 1.0 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://boinc.berkeley.edu/license_1.0.txt +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations +// under the License. +// +// The Original Code is the Berkeley Open Infrastructure for Network Computing. +// +// The Initial Developer of the Original Code is the SETI@home project. +// Portions created by the SETI@home project are Copyright (C) 2002 +// University of California at Berkeley. All Rights Reserved. +// +// Contributor(s): +// +// Revision History +// $Log: xml_util.cpp,v $ +// Revision 1.3.2.8 2007/02/28 01:45:17 vonkorff +// +// stopped using BUFSIZ to size temporary buffers +// +// Revision 1.3.2.7 2007/02/22 02:27:23 vonkorff +// +// Added #include "str_util.h" +// +// Revision 1.3.2.6 2006/12/14 22:26:30 korpela +// *** empty log message *** +// +// Revision 1.3.2.5 2006/05/04 21:45:46 charlief +// *** empty log message *** +// +// Revision 1.3.2.4 2006/05/04 12:36:10 charlief +// *** empty log message *** +// +// Revision 1.3.2.3 2006/01/04 00:47:30 korpela +// Upped version to 5.0 +// Made it clear in graphics that this is SETI@home Enhanced +// +// Revision 1.3.2.2 2005/11/17 18:44:39 jeffc +// Fixed a problem with the << operator for db_table.h. +// Also altered << operator to stop looking for the start tag after it is found +// and to not look for the stop tag until after the start is found. +// Modified xml_match_tag() to not search zero length strings. +// +// Revision 1.3.2.1 2005/10/17 22:14:48 korpela +// Fixed bugs with XML formatting and CSV vector input. The XML formatting bug +// fixes were submitted by Tetsuji "Maverick" Rai. The CSV input problem was due +// to my misunderstanding of the istream::operator void *(). I had thought the +// operator returned NULL if the past operation had failed. Instead it returns +// NULL if the NEXT operation will fail. +// +// Revision 1.3 2004/07/02 21:21:16 korpela +// Removed include of stdafx.h where it was not necessary. +// +// Revision 1.2 2004/06/30 20:52:28 korpela +// *** empty log message *** +// +// Revision 1.1 2004/06/17 22:41:28 jeffc +// *** empty log message *** +// +// Revision 1.3 2004/06/12 18:38:30 rwalton +// *** empty log message *** +// +// Revision 1.2 2004/06/12 05:56:14 davea +// *** empty log message *** +// +// Revision 1.1 2004/06/11 17:43:22 davea +// *** empty log message *** +// +// Revision 1.29 2004/04/05 20:09:41 korpela +// Rewrote extract_xml_record() to solve some problems... +// +// Revision 1.28 2004/03/06 09:45:25 rwalton +// *** empty log message *** +// +// Revision 1.27 2004/01/22 17:57:41 davea +// *** empty log message *** +// +// Revision 1.26 2004/01/20 02:51:50 korpela +// VC 7 mods +// +// Revision 1.25 2003/12/01 23:42:05 korpela +// Under some compilers template parameters of type char [] weren't getting +// cast to char *. Template functions now use &(array[0]) to ensure correct +// type is used. +// +// +#include "sah_config.h" + +#include +#include +#include +#include +#include +#include + +#include "std_fixes.h" +#include "util.h" +#include "str_util.h" +#include "str_replace.h" +#include "xml_util.h" + +using std::string; +using std::min; + +int xml_indent_level=0; + +std::string xml_indent(int i) { + if (i) xml_indent_level+=i; + xml_indent_level = (xml_indent_level>0) ? xml_indent_level : 0; + return string(min(xml_indent_level,XML_MAX_INDENT),' '); +} +// Most of these entries are for reverse translation of poorly written HTML. +// Forward translation doesn't translate most printable characters. + +const xml_entity xml_trans[]= { + { 0x07, "&bel;" }, + { 0x0a, "&lf;" }, + { 0x0d, "&cr;" }, + { ' ', "&sp;" }, + { '!', "!" }, + { '\"', """ }, + { '\"', "&dquot;" }, + { '#', "#" }, + { '$', "$" }, + { '%', "%" }, + { '&', "&" }, + { '\'', "'" }, + { '(', "(" }, + { ')', ")" }, + { '*', "*" }, + { '+', "+" }, + { ',', "," }, + { '-', "‐" }, + { '-', "−" }, + { '.', "." }, + { '/', "/" }, + { ':', ":" }, + { ';', ";" }, + { '<', "<" }, + { '=', "=" }, + { '>', ">" }, + { '?', "?" }, + { '@', "@" }, + { '[', "[" }, + { '\\', "\" }, + { ']', "]" }, + { '^', "ˆ" }, + { '_', "_" }, + { '_', "―" }, + { '`', "`" }, + { '{', "{" }, + { '|', "|" }, + { '}', "}" }, + { '~', "˜" }, + { 0x82, "‚" }, + { 0x84, "„" }, + { 0x85, "&ldots;" }, + { 0x8a, "Š" }, + { 0x8b, "‹" }, + { 0x8c, "Œ" }, + { 0x91, "‘" }, + { 0x91, "’" }, + { 0x92, "’" }, + { 0x93, "“" }, + { 0x93, "”" }, + { 0x94, "”" }, + { 0x95, "•" }, + { 0x96, "–" }, + { 0x96, "&endash;" }, + { 0x97, "—" }, + { 0x97, "&emdash;" }, + { 0xa0, " " }, + { 0xa1, "¡" }, + { 0xa2, "¢" }, + { 0xa3, "£" }, + { 0xa4, "¤" }, + { 0xa5, "¥" }, + { 0xa6, "¦" }, + { 0xa7, "§" }, + { 0xa8, "¨" }, + { 0xa9, "©" }, + { 0xaa, "ª" }, + { 0xab, "«" }, + { 0xac, "¬" }, + { 0xad, "­" }, + { 0xae, "®" }, + { 0xaf, "¯" }, + { 0xb0, "°" }, + { 0xb1, "±" }, + { 0xb2, "²" }, + { 0xb3, "³" }, + { 0xb4, "´" }, + { 0xb5, "µ" }, + { 0xb6, "¶" }, + { 0xb7, "·" }, + { 0xb8, "¸" }, + { 0xb9, "¹" }, + { 0xba, "º" }, + { 0xbb, "»" }, + { 0xbc, "¼" }, + { 0xbd, "½" }, + { 0xbe, "¾" }, + { 0xbf, "¿" }, + { 0xc0, "À" }, + { 0xc1, "Á" }, + { 0xc2, "Â" }, + { 0xc3, "Ã" }, + { 0xc4, "Ä" }, + { 0xc5, "Å" }, + { 0xc6, "Æ" }, + { 0xc7, "Ç" }, + { 0xc8, "È" }, + { 0xc9, "É" }, + { 0xca, "Ê" }, + { 0xcb, "Ë" }, + { 0xcc, "Ì" }, + { 0xcd, "Í" }, + { 0xce, "Î" }, + { 0xcf, "Ï" }, + { 0xd0, "Ð" }, + { 0xd1, "Ñ" }, + { 0xd2, "Ò" }, + { 0xd3, "Ó" }, + { 0xd4, "Ô" }, + { 0xd5, "Õ" }, + { 0xd6, "Ö" }, + { 0xd7, "×" }, + { 0xd8, "Ø" }, + { 0xd9, "Ù" }, + { 0xda, "Ú" }, + { 0xdb, "Û" }, + { 0xdc, "Ü" }, + { 0xdd, "Ý" }, + { 0xde, "Þ" }, + { 0xdf, "ß" }, + { 0xe0, "à" }, + { 0xe1, "á" }, + { 0xe2, "â" }, + { 0xe3, "ã" }, + { 0xe4, "ä" }, + { 0xe5, "å" }, + { 0xe6, "æ" }, + { 0xe7, "ç" }, + { 0xe8, "è" }, + { 0xe9, "é" }, + { 0xea, "ê" }, + { 0xeb, "ë" }, + { 0xec, "ì" }, + { 0xed, "í" }, + { 0xee, "î" }, + { 0xef, "ï" }, + { 0xf0, "ð" }, + { 0xf1, "ñ" }, + { 0xf2, "ò" }, + { 0xf3, "ó" }, + { 0xf4, "ô" }, + { 0xf5, "õ" }, + { 0xf6, "ö" }, + { 0xf7, "÷" }, + { 0xf8, "ø" }, + { 0xf9, "ù" }, + { 0xfa, "ú" }, + { 0xfb, "û" }, + { 0xfc, "ü" }, + { 0xfd, "ý" }, + { 0xfe, "þ" }, + { 0xff, "ÿ" }, + { 0x00, 0 } +}; + +#if 0 +xml_ofstream::xml_ofstream() : my_tag(), os() {} + +xml_ofstream::xml_ofstream(const char *filename, const char *tag, + std::ios_base::openmode m) : , my_tag(tag), os(filename,m) +{ + if (is_open()) { + write_head(); + } +} + +xml_ostream::xml_ostream(std::ostream &o, const char *tag) + : my_tag(tag), os(o) +{ + write_head(); +} + +xml_ostream::~xml_ostream() { + write_foot(); +} + +xml_ofstream::~xml_ofstream() { + close(); +} + +void xml_ofstream::open(const char *filename, const char *tag, + std::ios_base::openmode m) { + my_tag=std::string(tag); + os.open(filename,m); + if (is_open()) { + write_head(); + } +} + +void xml_ofstream::close() { + write_foot(); + os.close(); +} + +void xml_ostream::write_head() { + xml_indent_level=0; + os << xml_header << std::endl; + os << '<' << my_tag << '>' << std::endl; + xml_indent(2); +} + +void xml_ofstream::write_head() { + xml_indent_level=0; + os << xml_header << std::endl; + os << '<' << my_tag << '>' << std::endl; + xml_indent(2); +} + +void xml_ostream::write_foot() { + xml_indent(-2); + os << "' << std::endl; +} + +void xml_ofstream::write_foot() { + xml_indent(-2); + os << "' << std::endl; +} + +xml_ifstream::xml_ifstream() : , my_tag(""), xml_start(0), ifs() + xml_end(0) {} + +xml_ifstream::xml_ifstream(const char *filename, const char *tag, + std::ios_base::openmode m) : std::ifstream(filename,m), my_tag(tag), + xml_start(0), xml_end(0) { + if (is_open()) { + seek_head(); + } +} + +xml_istream::xml_istream(std::istream &i, const char *tag) + : my_tag(tag), is(i) { +} + +xml_ifstream::~xml_ifstream() { + close(); +} + +void xml_ifstream::open(const char *filename, const char *tag, + std::ios_base::openmode m) { + my_tag=std::string(tag); + std::ifstream::open(filename,m); + if (is_open()) { + seek_head(); + } +} + +void xml_istream::seek_head() { + std::string tmp; + char c; + unsigned int i=0; + bool start_found=false; + if (my_tag.size()) { + while (is) { + is.get(c); + if (c=='<') { + do { + is.get(c); + i++; + } while (c == my_tag[i-1]); + if ((i==my_tag.size()) && !isalnum(c)) { + start_found=true; + break; + } + } + } + } else { + while (is) { + is.get(c); + if (c=='<') { + do { + is.get(c); + if (isalnum(c)) my_tag+=c; + } while (isalnum(c)); + } + if (my_tag.size()) { + start_found=true; + break; + } + } + } + if (start_found) { + while ((c != '>') && is) is.get(c); + } +} + + +void xml_ifstream::seek_head() { + if (!xml_start) { + std::string tmp; + std::string::size_type tag_start, tag_end; + bool start_found=false; + std::ifstream::seekg(0,std::ios::beg); + if (my_tag.size()) { + do { + *this >> tmp; + if ((tag_start=tmp.find(std::string("<")+my_tag)) != std::string::npos) { + tag_start=tmp.find('>'); + std::ifstream::seekg(tag_start-tmp.size()+my_tag.size()+2,std::ios::cur); + start_found=true; + } else { + if ((tag_start=tmp.find("<")) != std::string::npos) { + if (isalpha(tmp[tag_start+1])) { + while (isalnum(tmp[++tag_start])) my_tag+=tmp[tag_start]; + start_found=true; + tag_start=tmp.find(">",tag_start-1); + std::ifstream::seekg(tag_start-tmp.size(),std::ios::cur); + } + } + } + } while (!start_found && !std::ifstream::eof()); + xml_start=std::ifstream::tellg(); + } + if (my_tag.size()) { + int nstarts=1; + std::string start_tag(std::string("<")+my_tag); + std::string end_tag(std::string("> tmp; + if (tmp.find(start_tag)!=std::string::npos) { + nstarts++; + } + if ((tag_end=tmp.find(end_tag))!=std::string::npos) { + nstarts--; + } + } while (nstarts && !std::ifstream::eof()); + std::ifstream::seekg(tag_end-tmp.size(),std::ios::cur); + xml_end=std::ifstream::tellg(); + } + } + if (xml_start) std::ifstream::seekg(xml_start,std::ios::beg); +} + +xml_ifstream &xml_ifstream::seekg(pos_type p) { + if (xml_start) std::ifstream::seekg(xml_start+p); + return *this; +} + +xml_ifstream &xml_ifstream::seekg(off_type o, std::ios::seekdir d) { + switch (d) { + case std::ios::beg: + seekg(o); + break; + case std::ios::end: + std::ifstream::seekg(xml_end+o); + break; + default: + std::ifstream::seekg(o,d); + break; + } + return *this; +} + +std::ios::pos_type xml_ifstream::tellg() { + return std::ifstream::tellg()-xml_start; +} + +bool xml_ifstream::eof() { + if (std::ifstream::tellg() >= xml_end) { + return true; + } else { + return std::ifstream::tellg(); + } +} +#endif // 0 + +#ifdef HAVE_MAP +#include + +std::multimap encode_map; +std::map decode_map; + +void populate_encode_map() { + int i=0; + do { + encode_map.insert(std::make_pair(xml_trans[i].c,xml_trans[i].s)); + } while (xml_trans[++i].s); +} + +void populate_decode_map() { + int i=0; + do { + decode_map[xml_trans[i].s]=xml_trans[i].c; + } while (xml_trans[++i].s); +} +#endif + +const char * encode_arr="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +const char * encode_arr85= +"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxy!#$()*+,-./:;=?@^`{|}~z_"; + + +bool isencchar(char c) { + bool rv=((c>='A') && (c<='Z')); + rv|=((c>='a') && (c<='z')); + rv|=((c>='0') && (c<='9')); + rv|=((c=='+') || (c=='/') || (c=='=')); + return rv; +} + +bool isencchar85(char c) { + bool rv=((c>='A') && (c<='Z')); + rv|=((c>='a') && (c<='z')); + rv|=((c>='0') && (c<='9')); + switch (c) { + case '!': + case '#': + case '$': + case '(': + case ')': + case '*': + case '+': + case ',': + case '-': + case '.': + case '/': + case ':': + case ';': + case '=': + case '?': + case '@': + case '^': + case '`': + case '{': + case '|': + case '}': + case '~': + case '_': + rv=true; + break; + default: + break; + } + return rv; +} + + + + +std::string encode_char(unsigned char c) { +#ifdef HAVE_MAP + if (!(encode_map.size())) populate_encode_map(); + std::multimap::iterator p=encode_map.find(c); + if (p!=encode_map.end()) { + return (p->second); + } else { +#else + int i=0; + while (xml_trans[i].s) { + if (xml_trans[i].c == c) return std::string(xml_trans[i].s); + i++; + } + { +#endif + char buf[16]; + sprintf(buf,"&#%.3d;",static_cast(c)); +#ifdef HAVE_MAP + encode_map.insert(std::make_pair(c,&(buf[0]))); +#endif + return std::string(buf); + } +} + +unsigned char decode_char(const char *s) { + char code[32]; + int i=0; + code[31]=0; + while (*s && (*s != ';') && i<31) { + code[i]=*s; + s++; + i++; + } + code[i]=';'; + code[i+1]=0; +#ifdef HAVE_MAP + if (!(decode_map.size())) populate_decode_map(); + std::map::iterator p=decode_map.find(code); + if (p!=decode_map.end()) { + return (p->second); + } else { +#else + while (xml_trans[i].s) { + if (!strcmp(xml_trans[i].s,(const char *)(&code[0]))) return xml_trans[i].c; + i++; + } + { +#endif + if (code[1]=='#') { + sscanf((const char *)(code+2),"%d",&i); +#ifdef HAVE_MAP + decode_map.insert(std::make_pair(std::string(code),static_cast(i&0xff))); +#endif + } else { + fprintf(stderr,"Unknown XML entity \"%s\"\n",code); + i='&'; + } + return static_cast(i&0xff); + } +} + +std::string x_csv_encode_char(const unsigned char *bin, size_t nelements) { + std::ostringstream rv(""); + long lastlen,i,ival; + + rv << std::endl << xml_indent(2); + lastlen=(long)rv.str().size(); + for (i=0;i<(long)(nelements-1);i++) { + ival=bin[i]; + rv << ival << ','; + if ((static_cast(rv.str().size()) + -(lastlen-min(xml_indent_level,XML_MAX_INDENT)))>73) { // TMR + rv << std::endl << xml_indent(); + lastlen=(long)rv.str().size(); + } + } + ival=bin[i]; + rv << ival << std::endl << xml_indent(-2); + return rv.str(); +} + +// test if a character is an xml tag delimiter +bool isxmldelim(char c) { + return ((c==' ') || (c=='\n') || (c=='\r') || + (c==',') || (c=='<') || (c=='>') || + (c==0)); +} + +// return true if the tag appears in the line +// +bool xml_match_tag(const char* buf, const char* tag) { + char tmp_tag[8192]={'<',0}; + if (strlen(buf)==0) return false; + if (tag[0] == '<') { + strlcpy(tmp_tag,tag,8192); + } else { + strlcat(tmp_tag,tag,8192); + } + char *p=tmp_tag+strlen(tmp_tag); + do { + *(p--)=0; + } while (isxmldelim(*p)); + while ((buf=strstr(buf,tmp_tag))) { + if (isxmldelim(buf[strlen(tmp_tag)])) return true; + buf++; + } + return false; +} + +bool xml_match_tag(const std::string &s, const char* tag) { + return xml_match_tag(s.c_str(),tag); +} + +size_t xml_find_tag(const char* buf, const char* tag) { + const char *buf0=buf; + char tmp_tag[8192]={'<',0}; + if (tag[0] == '<') { + strlcpy(tmp_tag,tag,8192); + } else { + strlcat(tmp_tag,tag,8192); + } + char *p=tmp_tag+strlen(tmp_tag); + do { + *(p--)=0; + } while (isxmldelim(*p)); + while ((buf=strstr(buf,tmp_tag))) { + if (isxmldelim(buf[strlen(tmp_tag)])) return buf-buf0; + buf++; + } + return strlen(buf0); +} + +std::string::size_type xml_find_tag(const std::string &s, const char* tag) { + std::string::size_type p=xml_find_tag(s.c_str(),tag); + return (p!=strlen(s.c_str()))?p:(std::string::npos); +} + +bool extract_xml_record(const std::string &field, const char *tag, std::string &record) { + char end_tag[256]; + sprintf(end_tag,"/%s",tag); + std::string::size_type j,k; + + // find the start_tag + j=xml_find_tag(field,tag); + if (j==std::string::npos) return false; + // find the end tag + k=xml_find_tag(std::string(field,j,field.length()-j),end_tag); + if (k==std::string::npos) return false; + + record=std::string(field,j,k+strlen(end_tag)+1); + return true; +} + +// +// $Log: xml_util.cpp,v $ +// Revision 1.3.2.8 2007/02/28 01:45:17 vonkorff +// +// stopped using BUFSIZ to size temporary buffers +// +// Revision 1.3.2.7 2007/02/22 02:27:23 vonkorff +// +// Added #include "str_util.h" +// +// Revision 1.3.2.6 2006/12/14 22:26:30 korpela +// *** empty log message *** +// +// Revision 1.3.2.5 2006/05/04 21:45:46 charlief +// *** empty log message *** +// +// Revision 1.3.2.4 2006/05/04 12:36:10 charlief +// *** empty log message *** +// +// Revision 1.3.2.3 2006/01/04 00:47:30 korpela +// Upped version to 5.0 +// Made it clear in graphics that this is SETI@home Enhanced +// +// Revision 1.3.2.2 2005/11/17 18:44:39 jeffc +// Fixed a problem with the << operator for db_table.h. +// Also altered << operator to stop looking for the start tag after it is found +// and to not look for the stop tag until after the start is found. +// Modified xml_match_tag() to not search zero length strings. +// +// Revision 1.3.2.1 2005/10/17 22:14:48 korpela +// Fixed bugs with XML formatting and CSV vector input. The XML formatting bug +// fixes were submitted by Tetsuji "Maverick" Rai. The CSV input problem was due +// to my misunderstanding of the istream::operator void *(). I had thought the +// operator returned NULL if the past operation had failed. Instead it returns +// NULL if the NEXT operation will fail. +// +// Revision 1.3 2004/07/02 21:21:16 korpela +// Removed include of stdafx.h where it was not necessary. +// +// Revision 1.2 2004/06/30 20:52:28 korpela +// *** empty log message *** +// +// Revision 1.1 2004/06/17 22:41:28 jeffc +// *** empty log message *** +// +// Revision 1.3 2004/06/12 18:38:30 rwalton +// *** empty log message *** +// +// Revision 1.2 2004/06/12 05:56:14 davea +// *** empty log message *** +// +// Revision 1.1 2004/06/11 17:43:22 davea +// *** empty log message *** +// +// Revision 1.29 2004/04/05 20:09:41 korpela +// Rewrote extract_xml_record() to solve some problems... +// +// Revision 1.28 2004/03/06 09:45:25 rwalton +// *** empty log message *** +// +// Revision 1.27 2004/01/22 17:57:41 davea +// *** empty log message *** +// +// Revision 1.26 2004/01/20 02:51:50 korpela +// VC 7 mods +// +// Revision 1.25 2003/12/01 23:42:05 korpela +// Under some compilers template parameters of type char [] weren't getting +// cast to char *. Template functions now use &(array[0]) to ensure correct +// type is used. +// +// Revision 1.24 2003/11/11 17:29:01 quarl +// *** empty log message *** +// +// Revision 1.23 2003/10/29 20:08:49 korpela +// *** empty log message *** +// +// Revision 1.22 2003/10/27 23:07:34 korpela +// *** empty log message *** +// +// Revision 1.21 2003/10/27 20:07:11 korpela +// *** empty log message *** +// +// Revision 1.20 2003/10/27 19:41:23 korpela +// +// Fixed potential buffer overrun in decode_char() +// +// Revision 1.19 2003/10/27 17:52:49 korpela +// *** empty log message *** +// +// Revision 1.18 2003/10/24 16:58:10 korpela +// *** empty log message *** +// +// Revision 1.17 2003/10/24 00:05:02 davea +// *** empty log message *** +// +// Revision 1.16 2003/10/23 19:58:20 jeffc +// jeffc - bug fix in csv encode routine +// +// Revision 1.15 2003/10/23 19:18:38 jeffc +// jeffc - put back in line feeds - no longer using parese_str(). +// +// Revision 1.14 2003/10/23 15:39:54 korpela +// no message +// +// Revision 1.13 2003/10/23 00:25:15 jeffc +// jeffc - no line feeds in CSV encoding +// +// Revision 1.12 2003/10/22 18:23:23 korpela +// *** empty log message *** +// +// Revision 1.11 2003/10/22 18:01:41 korpela +// *** empty log message *** +// +// Revision 1.10 2003/10/22 15:24:10 korpela +// *** empty log message *** +// +// Revision 1.9 2003/10/21 18:14:36 korpela +// *** empty log message *** +// +// + + + + + diff --git a/db/xml_util.h b/db/xml_util.h new file mode 100644 index 0000000..f999c99 --- /dev/null +++ b/db/xml_util.h @@ -0,0 +1,1049 @@ +// $Id: xml_util.h,v 1.8.2.6 2007/05/31 22:03:31 korpela Exp $ +// The contents of this file are subject to the BOINC Public License +// Version 1.0 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://boinc.berkeley.edu/license_1.0.txt +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations +// under the License. +// +// The Original Code is the Berkeley Open Infrastructure for Network Computing. +// +// The Initial Developer of the Original Code is the SETI@home project. +// Portions created by the SETI@home project are Copyright (C) 2002 +// University of California at Berkeley. All Rights Reserved. +// +// Contributor(s): +// +// Additional routines to help maintain XML compliance. +// +// Revision History: +// $Log: xml_util.h,v $ +// Revision 1.8.2.6 2007/05/31 22:03:31 korpela +// *** empty log message *** +// +// Revision 1.8.2.5 2007/03/09 00:21:15 vonkorff +// Fixed missing trailing null in base64 encoding. +// +// Revision 1.8.2.4 2006/12/14 22:26:30 korpela +// *** empty log message *** +// +// Revision 1.8.2.3 2005/12/01 00:01:01 korpela +// Changed to an Intel compile of fftw3.dll. Hopefully this will fix the problem +// with crashes on Pentium-MMX and earlier. +// +// Added a Dev-C++ project and modified source files to allow seti_boinc to compile +// under MinGW. +// +// Revision 1.8.2.2 2005/10/17 22:33:33 korpela +// Continuing previous fix +// +// Revision 1.8.2.1 2005/10/17 22:14:49 korpela +// Fixed bugs with XML formatting and CSV vector input. The XML formatting bug +// fixes were submitted by Tetsuji "Maverick" Rai. The CSV input problem was due +// to my misunderstanding of the istream::operator void *(). I had thought the +// operator returned NULL if the past operation had failed. Instead it returns +// NULL if the NEXT operation will fail. +// +// Revision 1.8 2004/12/07 23:42:23 korpela +// Added undef of min and max in case they are defined in a previously included +// header file. +// +// Revision 1.7 2004/11/18 19:17:04 korpela +// Fixed base64 and base85 decoding. +// +// +// Revision 1.21 2004/04/05 22:07:08 korpela +// +// Segfault problem fixed? +// +// Revision 1.17 2003/12/01 23:42:05 korpela +// Under some compilers template parameters of type char [] weren't getting +// cast to char *. Template functions now use &(array[0]) to ensure correct +// type is used. +// +// + +#ifndef _XML_UTIL_H_ +#define _XML_UTIL_H_ + +#include "sah_config.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "error_numbers.h" + +// Just in case, undef min and max +#ifdef min +#undef min +#endif +#ifdef max +#undef max +#endif + + + +typedef enum tag_xml_encoding { + _x_xml_entity=0, + _x_xml_cdata, + _x_xml_values, + _quoted_printable, + _base64, + _x_base85, + _x_setiathome, + _x_hex, + _x_csv, + _x_uuencode, + _8bit, + _binary +} xml_encoding; + +const char * const xml_encoding_names[]= { + "x-xml-entity", + "x-xml-cdata", + "x-xml-values", + "quoted-printable", + "base64", + "x-base85", + "x-setiathome", + "x-hex", + "x-csv", + "x-uuencode", + "8bit", + "binary" + }; + +#if 0 + +// the xml_ostream class is an ostream, which can be constructed +// from an existing ostream (i.e. cout). When constructed, +// an xml header and the opening tag are written. When destructed, +// the closing tag is written. +class xml_ostream { + public: + xml_ostream(ostream &o, const char *tag); + ~xml_ostream(); + template + xml_ostream &operator <<(const T &t) { os << t; return *this; }; + private: + void write_head(); + void write_foot(); + std::string my_tag; + std::ostream &os; +}; + +// the xml_ofstream class is an ofstream. When the file is opened, +// an xml header and the opening tag are written. Upon close, +// the closing tag is written. +class xml_ofstream { + public: + xml_ofstream(); + explicit xml_ofstream(const char *filename, const char *tag, + ios_base::openmode m=ios_base::out|ios_base::binary); + ~xml_ofstream(); + void open(const char *p, const char *tag, + ios_base::openmode m=ios_base::out|ios_base::binary); + void close(); + private: + void write_head(); + void write_foot(); + std::string my_tag; + std::ofstream &os; +}; + +// the xml_istream class is an istream that can be constructed from +// an existing istream. When constructed, the stream is read until +// the opening tag or end of file is found. This is really only useful +// for reading XML from stdin. +class xml_istream { + public: + explicit xml_istream(istream &i, const char *tag=0); + ~xml_istream(); + operator istream &() {return is;}; + private: + void seek_head(); + std::string my_tag; + std::istream &is; +}; +// the xml_ifstream class is an ifstream. When the file is opened, +// the file pointer is set after the opening tag. An attempt to +// read past the closing tag will fail as if the end of the file has +// been reached. If no tag is given, it will assume the first tag +// found is the main tag. + +#ifndef HAVE_STD_POS_TYPE +typedef off_t pos_type; +#endif + +#ifndef HAVE_STD_OFF_TYPE +typedef off_t off_type; +#endif + +class xml_ifstream { + public: + xml_ifstream(); + explicit xml_ifstream(const char *filename, const char *tag=0, + ios_base::openmode m=ios_base::in|ios_base::binary); + ~xml_ifstream(); + void open(const char *filename, const char *tag=0, + ios_base::openmode m=ios_base::in|ios_base::binary); + xml_ifstream &seekg(pos_type p); + xml_ifstream &seekg(off_type o, ios_base::seekdir d); + pos_type tellg(); + bool eof(); + private: + void seek_head(); + std::string my_tag; + std::pos_type xml_start; + std::pos_type xml_end; + std::ifstream &ifs; +}; + +#endif // 0 + +#define XML_ENCODING "iso-8859-1" + +static const char * const xml_header= + "\n"; + +// XML entity for tranlation table (not wchar_t compatible) +struct xml_entity { + unsigned char c; + const char *s; +}; + +// change the xml indent level (number of spaces) by adding or subtracting +// "i" spaces. return a string of spaces corresponding to the current xml +// indent level. +std::string xml_indent(int i=0); +static const int XML_MAX_INDENT=40; +extern int xml_indent_level; + + +// decode an XML character string. Return a the decoded string in a vector +// (null not necessarily a terminator). +//template +//vector xml_decode_string(const char *input, size_t length=0, +// const char *encoding="x_xml_entity"); + +// do the same thing, but get the length and encoding type from the +// xml tag properties. +template +std::vector xml_decode_field(const std::string &input, const char *tag); + +// encode an XML character string. Return the encoded string. +//template +//string xml_encode_string(const T *input, size_t n_elements=0, +// xml_encoding encoding=_x_xml_entity); + +template +std::string xml_encode_string(const std::vector &input, + xml_encoding encoding=_x_xml_entity) { + return xml_encode_string(&(*(input.begin())),input.size(),encoding); +} + +#include +#include +#include +#include + +extern const char *encode_arr; +extern const char *encode_arr85; +bool isencchar(char c); +bool isencchar85(char c); + +template +std::string base64_encode(const T *tbin, size_t n_elements) { + size_t nbytes=n_elements*sizeof(T); + const unsigned char *bin=(const unsigned char *)(tbin); + int count=0, offset=0, nleft; + const char crlf[]= {0xa,0xd,0x0}; + std::string rv(""); + rv.reserve(nbytes*4/3+nbytes*2/57); + char c[5]; + for (nleft = (int)nbytes; nleft > 0; nleft -= 3) { + int i; + c[0] = (bin[offset]>>2) & 0x3f ; // 6 + c[1] = (bin[offset]<<4) & 0x3f | ((bin[offset+1]>>4)&0xf); // 2+4 + c[2] = ((bin[offset+1]<<2)&0x3f) | ((bin[offset+2]>>6)&0x3);// 4+2 + c[3] = bin[offset+2]&0x3f; // 6 + for (i=0;i<((nleft>3)?4:(nleft+1));i++) c[i]=encode_arr[c[i]]; + for (;i<4;i++) c[i]='='; + c[4]=0; + rv+=c; + offset += 3; + count += 4; + if (count == 76 ) { + count = 0; + rv+=crlf; + } + } + rv+=crlf; + return rv; +} + +template +std::vector base64_decode(const char *data, size_t nbytes) { + const char *p=data,*eol,*eol2,*eos; + const char cr=0xa,lf=0xd; + char in[4],c[3]; + int i; + std::vector rv; + rv.reserve(nbytes*3/4); + while (p<(data+nbytes)) { + while (*p && (p<(data+nbytes)) && !isencchar(*p)) { + *p++; + } + if (!(*p) || (p>=(data+nbytes))) break; + eol=strchr(p,cr); + eol2=strchr(p,lf); + eos=p+strlen(p); + if (eol) { + eol=std::min(eol,eos); + } else { + eol=eos; + } + if (eol && eol2) { + eol=std::min(eol,eol2); + } + for (;p<(eol-1);p+=4) { + for ( i=0;i<4;i++) { + if ((p[i]>='A') && (p[i]<='Z')) { + in[i]=p[i]-'A'; + } else if ((p[i]>='a') && (p[i]<='z')) { + in[i]=p[i]-'a'+26; + } else if ((p[i]>='0') && (p[i]<='9')) { + in[i]=p[i]-'0'+52; + } else { + switch (p[i]) { + case '+': in[i]=62; + break; + case '/': in[i]=63; + break; + default : in[i]=0; + } + } + } + c[0]=(in[0]<<2) | ((in[1] >> 4) & 0x3); + c[1]=(in[1]<<4) | ((in[2] >> 2) & 0xf); + c[2]=(in[2]<<6) | in[3]; + for ( i=0;i<3;i++) rv.push_back(c[i]); + } + } + return std::vector((T *)(&(rv[0])),(T *)(&(rv[0]))+rv.size()/sizeof(T)); +} + +template +std::string base85_encode(const T *tbin, size_t n_elements) { + size_t nbytes=n_elements*sizeof(T); + const unsigned char *bin=(const unsigned char *)(tbin); + int count=0; + const char crlf[]= {0xa,0xd,0x0}; + std::string rv(""); + rv.reserve(nbytes*4/3+nbytes*2/57); + char c[6]; + int n_pads; + unsigned int j=0; + while (j3)?4:(nbytes-j));i++) val=(val<<8)+bin[j+i]; + if (val) { + for (n_pads=4-i;i<4;i++) val*=((i==3)?84:85); + } + if (val == 0) { + c[0]='z'; // If the word is entirely zero use a single digit + c[1]=0; // zero pad of 'z' + } else { + for (i=4;i<5;i--) { + c[i]=(char)(val % ((i==4)?84:85)); // First division is by 84 to prevent + val/= ((i==4)?84:85); // having a pad in the final digit. + } + if (c[0]==83) { // need to change a high order 'z' into + c[0]=84; // an "_" so it won't look like a zero word. + } + for (i=0;i<5;i++) c[i]=encode_arr85[c[i]]; + for (i=5-n_pads;i<5;i++) c[i]='_'; // add pad characters + c[5]=0; + } + j+=4; + if (count>74) { + rv+=crlf; + count=0; + } + count+=(int)strlen(c); + rv+=c; + } + return rv; +} + +template +std::vector base85_decode(const char *data, size_t nbytes) { + const char *p=data,*eol,*eol2,*eos; + const char cr=0xa,lf=0xd; + unsigned long val; + int npads,i; + std::vector rv; + rv.reserve(nbytes*4/5); + while (p<(data+nbytes)) { + while (*p && (p<(data+nbytes)) && !isencchar85(*p)) { + *p++; + } + if (!(*p) || (p>=(data+nbytes))) break; + eol=strchr(p,cr); + eol2=strchr(p,lf); + eos=p+strlen(p); + + if (eol) { + eol=std::min(eol,eos); + } else { + eol=eos; + } + if (eol && eol2) { + eol=std::min(eol,eol2); + } + + while (p0) { + if (p[i]!='_') break; + npads++; + } + for (i=0;i='0') && (p[i]<='9')) { + val+=p[i]-'0'; + } else if ((p[i]>='A') && (p[i]<='Z')) { + val+=p[i]-'A'+10; + } else if ((p[i]>='a') && (p[i]<='y')) { + val+=p[i]-'a'+36; + } else { + for (int j=61; j<85; j++) { + if (p[i]==encode_arr85[j]) { + val+=j; + j=85; + } + } + if ((i==0) && (p[i]=='_')) val--; + } + } + } + val<<=(npads*8); + char c[5]; + c[4]=0; + for (int i=3;i>=0;i--) { + c[i]=(char)(val & 0xff); + val>>=8; + } + for (int i=0;i<4;i++) { + rv.push_back(c[i]); + } + p+=5; + } + } + return std::vector((T *)(&(rv[0])),(T *)(&(rv[0]))+rv.size()/sizeof(T)); +} + + +template +std::string x_setiathome_encode(const T *tbin, size_t n_elements) { + size_t nbytes=n_elements*sizeof(T); + const unsigned char *bin=(const unsigned char *)(tbin); + int count=0, offset=0, nleft; + const char cr=0xa; + std::string rv(""); + rv.reserve(nbytes*4/3+nbytes*2/48); + rv+="\n"; + char c[5]; + for (nleft = (int)nbytes; nleft > 0; nleft -= 3) { + c[0] = bin[offset]&0x3f; // 6 + c[1] = (bin[offset]>>6) | (bin[offset+1]<<2)&0x3f; // 2+4 + c[2] = ((bin[offset+1]>>4)&0xf) | (bin[offset+2]<<4)&0x3f;// 4+2 + c[3] = bin[offset+2]>>2; // 6 + for (int i=0;i<4;i++) c[i]+=0x20; + c[4]=0; + rv+=c; + offset += 3; + count += 4; + if (count == 64) { + count = 0; + rv+=cr; + } + } + rv+=cr; + return rv; +} + + +template +std::vector x_setiathome_decode(const char *data, size_t nbytes) { + const char *p=data,*eol,*eol2,*eos; + char in[4],c[3]; + int i; + std::vector rv; + rv.reserve(nbytes*3/4); + while (p<(data+nbytes)) { + while ((*p<0x20) || (*p>0x60)) { + *p++; + } + eol=strchr(p,'\n'); + eol2=strchr(p,'\r'); + eos=p+strlen(p); + if (eol) { + eol=std::min(eol,eos); + } else { + eol=eos; + } + if (eol && eol2) { + eol=std::min(eol,eol2); + } + for (;p<(eol-1);p+=4) { + memcpy(in,p,4); + for ( i=0;i<4;i++) in[i]-=0x20; + c[0]=in[0]&0x3f | in[1]<<6; + c[1]=in[1]>>2 | in[2]<<4; + c[2]=in[2]>>4 | in[3]<<2; + for ( i=0;i<3;i++) rv.push_back(c[i]); + } + } + return std::vector((T *)(&(rv[0])),(T *)(&(rv[0]))+rv.size()/sizeof(T)); +} + +template +std::string quoted_printable_encode(const T *tbin, size_t n_elements) { + size_t nbytes=n_elements*sizeof(T); + const unsigned char *bin=(const unsigned char *)(tbin); + int line_len=0; + const char crlf[]= {'=',0xa,0xd,0x0}; + std::string rv(""); + rv.reserve(nbytes*4/3+nbytes*2/48); + for (size_t i=0;i 74) { + rv+=crlf; + line_len=1; + } + rv+=bin[i]; + } else { + line_len+=3; + if (line_len>72) { + rv+=crlf; + line_len=3; + } + char buf[4]; + sprintf(buf,"=%.2X",bin[i]); + rv+=buf; + } + } + return rv; +} + +template +std::vector quoted_printable_decode(const char* data, size_t nbytes) { + std::vector rv; + rv.reserve(strlen(data)); + size_t i=0; + while (i((T *)(&(rv[0])),(T *)(&(rv[0]))+rv.size()/sizeof(T)); +} + +template +std::string x_hex_encode(const T *tbin, size_t n_elements) { + size_t nbytes=n_elements*sizeof(T); + const unsigned char *bin=(const unsigned char *)(tbin); + std::string rv; + int count=0; + rv.reserve(nbytes*2+nbytes*2/76); + for (unsigned int i=0; i +std::vector x_hex_decode(const char *data, size_t nbytes) { + std::vector rv; + rv.reserve(nbytes/2); + unsigned int i=0; + while (i(c)); + } + return std::vector((T *)(&(rv[0])),(T *)(&(rv[0]))+rv.size()/sizeof(T)); +} + + +std::string x_csv_encode_char(const unsigned char *bin, size_t nelements); + +template +std::string x_csv_encode(const T *bin, size_t nelements) { + std::ostringstream rv(""); + long lastlen,i; + + if (sizeof(T)==1) // if T is a char, print in another way + return x_csv_encode_char((const unsigned char *)bin,nelements); + + rv << std::endl << xml_indent(2); // TMR moved here to fix PoT format + lastlen=(long)rv.str().size(); // TMR + for (i=0;i<(static_cast(nelements)-1);i++) { + rv << bin[i] << ','; + if ((static_cast(rv.str().size()) + -(lastlen-std::min(xml_indent_level,XML_MAX_INDENT)))>73) { // TMR + rv << std::endl << xml_indent(); + lastlen=(long)rv.str().size(); + } + } + rv << bin[i] << "\n" << xml_indent(-2); + + return rv.str(); +} + + +template +std::vector x_csv_decode(const char *data, size_t nbytes) { + std::vector rv; + while (!isdigit(*data)) { + data++; + nbytes--; + } + std::istringstream in(std::string(data,nbytes)); + bool ischar=(sizeof(T)==1); + + while (in) { + T t; + if (!ischar) { + in >> t; + } else { + int i; + in >> i; + t=i & 0xff; + } + rv.push_back(t); + char c=' '; + while (in && !isdigit(c)) { + in.get(c); + } + if (isdigit(c)) in.putback(c); + } + return rv; +} + + +std::string encode_char(unsigned char c); +unsigned char decode_char(const char *s); + +template +std::vector x_xml_entity_decode(const char *input, size_t length) { + size_t i; + char c; + if (!length) { + // We're going to decode until we see a null. Including the null. + length=strlen((const char *)input); + } + std::vector rv; + char *p; + rv.reserve(length); + for (i=0; i((T *)(&(rv[0])),(T *)(&(rv[0]))+rv.size()/sizeof(T)); +} + +template +std::string x_xml_entity_encode(const T *tbin, size_t n_elements) { + size_t length=n_elements*sizeof(T); + const unsigned char *input=(const unsigned char *)(tbin); + unsigned int i; + std::string rv; + rv.reserve(length); + for (i=0; i': + case '<': + case '&': + case '\'': + case '"': + rv+=encode_char(input[i]); + break; + default: + rv+=input[i]; + } + } else { + char buf[16]; + sprintf(buf,"&#%.3d;",input[i]); + rv+=buf; + } + } + return rv; +} + +template +std::string x_xml_values_encode(const T *bin, size_t n_elements) { + std::ostringstream rv(""); + unsigned int i; + for (i=0;i +std::vector x_xml_values_decode(const char *data, size_t length) { + std::istringstream r(std::string(data,length)); + std::vector rv; + T t; + while (!r.eof()) { + r >> t ; + rv.push_back(t); + while ((isspace(r.peek()) || (r.peek() == ',')) && !r.eof()) { + char c; + r.get(c); + } + } + return rv; +} + +template +std::string x_xml_cdata_encode(const T *tbin, size_t n_elements) { + size_t length=n_elements*sizeof(T); + const unsigned char *input=(const unsigned char *)(tbin); + unsigned int i; + std::string rv("0x1f) { + switch (input[i]) { + case ']': + if (((length-i)>1) && (input[i+1]==']') && (input[i+2]=='>')) { + rv+="&&endcdt;"; + } else { + rv+=']'; + } + break; + default: + rv+=input[i]; + } + } else { + char buf[16]; + sprintf(buf,"&&#%.2d;",input[i]); + rv+=buf; + } + } + rv+="]]>"; + return rv; +} + +template +std::vector x_xml_cdata_decode(const char *input, size_t length) { + size_t i; + char c; + if (!length) { + // We're going to decode until we see a null. Including the null. + length=strlen(input); + } + std::vector rv; + char *p; + rv.reserve(length); + for (i=0; i8) && !strncmp((const char *)(input+i),"&&endcdt;",9)) { + rv.push_back(']'); + rv.push_back(']'); + rv.push_back('>'); + i+=8; + } else { + if (input[i+1]=='&') { + rv.push_back(c=decode_char(input+i+1)); + if ((c!='&') || !strncmp((const char *)(input+i+1),"&",5)) { + p=strchr((char *)(input+i+1),';'); + i=(p-input); + } + } else { + rv.push_back(input[i]); + } + } + } else { + rv.push_back(input[i]); + } + } + return std::vector((T *)(&(rv[0])),(T *)(&(rv[0]))+rv.size()/sizeof(T)); +} + +template +std::vector x_uudecode(const char *data, size_t nbytes) { + std::vector rv; + return rv; +} + +template +std::string x_uuencode(const T *data, size_t nbytes) { + std::string rv; + return rv; +} + +inline int xml_encoding_from_string(const char *enc_string) { + int i=_x_xml_entity; + const char *p="xqb8"; + // find the start to the encoding string (maybe prepended by + // quote or whitespace. + while (*enc_string && (strchr(p,*enc_string) == NULL)) enc_string++; + do { + if (!strncmp(enc_string,xml_encoding_names[i],strlen(xml_encoding_names[i]))) + break; + } while (i++ != _binary); + return i; +} + +template +std::vector xml_decode_string(const char *input, + size_t length=0, const char *encoding="x_xml_entity") { + int i=xml_encoding_from_string(encoding); + switch (i) { + case _x_xml_entity: + return x_xml_entity_decode(input,length); + case _x_xml_cdata: + return x_xml_cdata_decode(input,length); + case _x_xml_values: + return x_xml_values_decode(input,length); + case _quoted_printable: + return quoted_printable_decode(input,length); + case _base64: + return base64_decode(input,length); + case _x_base85: + return base85_decode(input,length); + case _x_setiathome: + return x_setiathome_decode(input,length); + case _x_hex: + return x_hex_decode(input,length); + case _x_csv: + return x_csv_decode(input,length); + case _x_uuencode: + return x_uudecode(input,length); + case _8bit: + case _binary: + return std::vector((const T *)input,(const T *)input+length/sizeof(T)); + default: + return x_xml_entity_decode(input,length); + } +} + +template +std::vector xml_decode_field(const std::string &input, const char *tag) { + std::string start_tag("<"),end_tag("',start)+1; + if (!length) { + length=(unsigned int)endt - (unsigned int)start; + } + return (xml_decode_string(&(input.c_str()[start]),length,encoding)); +} + + +template +std::string xml_encode_string(const T *input, + size_t length=0, xml_encoding encoding=_x_xml_entity) { + switch (encoding) { + case _x_xml_entity: + return x_xml_entity_encode(input,length); + case _x_xml_cdata: + return x_xml_cdata_encode(input,length); + case _x_xml_values: + return x_xml_values_encode(input,length); + case _quoted_printable: + return quoted_printable_encode(input,length); + case _base64: + return base64_encode(input,length); + case _x_base85: + return base85_encode(input,length); + case _x_setiathome: + return x_setiathome_encode(input,length); + case _x_hex: + return x_hex_encode(input,length); + case _x_csv: + return x_csv_encode(input,length); + case _x_uuencode: + return x_uuencode(input,length); + case _8bit: + case _binary: + return std::string((const char *)(input),length*sizeof(T)); + default: + return x_xml_entity_encode(input,length); + } +} + +extern bool xml_match_tag(const char*, const char*); +extern bool xml_match_tag(const std::string &, const char*); +extern bool extract_xml_record(const std::string &field, const char *tag, std::string &record); + +#endif +// +// $Log: xml_util.h,v $ +// Revision 1.8.2.6 2007/05/31 22:03:31 korpela +// *** empty log message *** +// +// Revision 1.8.2.5 2007/03/09 00:21:15 vonkorff +// Fixed missing trailing null in base64 encoding. +// +// Revision 1.8.2.4 2006/12/14 22:26:30 korpela +// *** empty log message *** +// +// Revision 1.8.2.3 2005/12/01 00:01:01 korpela +// Changed to an Intel compile of fftw3.dll. Hopefully this will fix the problem +// with crashes on Pentium-MMX and earlier. +// +// Added a Dev-C++ project and modified source files to allow seti_boinc to compile +// under MinGW. +// +// Revision 1.8.2.2 2005/10/17 22:33:33 korpela +// Continuing previous fix +// +// Revision 1.8.2.1 2005/10/17 22:14:49 korpela +// Fixed bugs with XML formatting and CSV vector input. The XML formatting bug +// fixes were submitted by Tetsuji "Maverick" Rai. The CSV input problem was due +// to my misunderstanding of the istream::operator void *(). I had thought the +// operator returned NULL if the past operation had failed. Instead it returns +// NULL if the NEXT operation will fail. +// +// Revision 1.8 2004/12/07 23:42:23 korpela +// Added undef of min and max in case they are defined in a previously included +// header file. +// +// Revision 1.7 2004/11/18 19:17:04 korpela +// Fixed base64 and base85 decoding. +// +// Revision 1.6 2004/10/29 04:35:21 korpela +// *** empty log message *** +// +// Revision 1.5 2004/10/21 22:02:48 korpela +// *** empty log message *** +// +// Revision 1.4 2004/06/30 20:52:29 korpela +// *** empty log message *** +// +// Revision 1.3 2004/06/24 08:55:29 quarl +// *** empty log message *** +// +// Revision 1.2 2004/06/12 18:38:30 rwalton +// *** empty log message *** +// +// Revision 1.1 2004/06/11 17:43:22 davea +// *** empty log message *** +// +// Revision 1.21 2004/04/05 22:07:08 korpela +// +// Segfault problem fixed? +// +// Revision 1.20 2004/03/06 09:45:25 rwalton +// *** empty log message *** +// +// Revision 1.19 2004/02/05 05:32:22 quarl +// *** empty log message *** +// +// Revision 1.18 2004/01/22 17:57:41 davea +// *** empty log message *** +// +// Revision 1.17 2003/12/01 23:42:05 korpela +// Under some compilers template parameters of type char [] weren't getting +// cast to char *. Template functions now use &(array[0]) to ensure correct +// type is used. +// +// Revision 1.16 2003/10/29 20:08:50 korpela +// *** empty log message *** +// +// Revision 1.15 2003/10/27 23:07:34 korpela +// *** empty log message *** +// +// Revision 1.14 2003/10/27 20:07:12 korpela +// *** empty log message *** +// +// Revision 1.13 2003/10/25 18:20:03 korpela +// *** empty log message *** +// +// Revision 1.12 2003/10/24 16:58:11 korpela +// *** empty log message *** +// +// Revision 1.11 2003/10/23 15:39:54 korpela +// no message +// +// Revision 1.10 2003/10/22 23:11:49 davea +// *** empty log message *** +// +// Revision 1.9 2003/10/22 22:36:52 jeffc +// jeffc - init xml_encode/decode_string in the definition, not the prototype +// +// Revision 1.8 2003/10/22 18:13:39 korpela +// *** empty log message *** +// +// Revision 1.7 2003/10/22 17:43:10 korpela +// *** empty log message *** +// +// Revision 1.6 2003/10/22 15:24:10 korpela +// *** empty log message *** +// +// Revision 1.5 2003/10/22 03:09:55 korpela +// *** empty log message *** +// +// Revision 1.4 2003/10/21 18:14:36 korpela +// *** empty log message *** +// +// diff --git a/depcomp b/depcomp new file mode 100755 index 0000000..51606f8 --- /dev/null +++ b/depcomp @@ -0,0 +1,464 @@ +#! /bin/sh + +# depcomp - compile a program generating dependencies as side-effects +# Copyright 1999, 2000 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi +# `libtool' can also be set to `yes' or `no'. + +if test -z "$depfile"; then + base=`echo "$object" | sed -e 's,^.*/,,' -e 's,\.\([^.]*\)$,.P\1,'` + dir=`echo "$object" | sed 's,/.*$,/,'` + if test "$dir" = "$object"; then + dir= + fi + # FIXME: should be _deps on DOS. + depfile="$dir.deps/$base" +fi + +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. + "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +## The second -e expression handles DOS-style file names with drive letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the `deleted header file' problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. + tr ' ' ' +' < "$tmpdepfile" | +## Some versions of gcc put a space before the `:'. On the theory +## that the space means something, we add a space to the output as +## well. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like `#:fec' to the end of the + # dependency line. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ + tr ' +' ' ' >> $depfile + echo >> $depfile + + # The second pass generates a dummy entry for each header file. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> $depfile + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. This file always lives in the current directory. + # Also, the AIX compiler puts `$object:' at the start of each line; + # $object doesn't have directory information. + stripped=`echo "$object" | sed -e 's,^.*/,,' -e 's/\(.*\)\..*$/\1/'` + tmpdepfile="$stripped.u" + outname="$stripped.o" + if test "$libtool" = yes; then + "$@" -Wc,-M + else + "$@" -M + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + + if test -f "$tmpdepfile"; then + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" + sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +icc) + # Must come before tru64. + + # Intel's C compiler understands `-MD -MF file'. However + # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c + # will fill foo.d with something like + # foo.o: sub/foo.c + # foo.o: sub/foo.h + # which is wrong. We want: + # sub/foo.o: sub/foo.c + # sub/foo.o: sub/foo.h + # sub/foo.c: + # sub/foo.h: + + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + sed -e "s,^[^:]*: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" + rm -f "$tmpdepfile" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in `foo.d' instead, so we check for that too. + # Subdirectories are respected. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + + if test "$libtool" = yes; then + tmpdepfile1="$dir.libs/$base.lo.d" + tmpdepfile2="$dir.libs/$base.d" + "$@" -Wc,-MD + else + tmpdepfile1="$dir$base.o.d" + tmpdepfile2="$dir$base.d" + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + if test -f "$tmpdepfile1"; then + tmpdepfile="$tmpdepfile1" + else + tmpdepfile="$tmpdepfile2" + fi + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a space and a tab in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the proprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for `:' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. + "$@" $dashmflag | + sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tr ' ' ' +' < "$tmpdepfile" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no + for arg in "$@"; do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix="`echo $object | sed 's/^.*\././'`" + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + sed '1,2d' "$tmpdepfile" | tr ' ' ' +' | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the proprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E | + sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the proprocessed file to stdout, regardless of -o, + # because we must use -o when running libtool. + "$@" || exit $? + IFS=" " + for arg + do + case "$arg" in + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" + echo " " >> "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 diff --git a/export-tarball b/export-tarball new file mode 100755 index 0000000..203c6f7 --- /dev/null +++ b/export-tarball @@ -0,0 +1,107 @@ +#!/bin/sh + +## $Id: export-tarball,v 1.1.2.1 2005/11/23 17:28:31 korpela Exp $ + +# Create a tarball from CVS or SVN export. + +# example usage: + +# CVSROOT=/usr/local/warez/cvsroot \ +# CHECKOUT='cvs export -r HEAD boinc' \ +# DIR='boinc' \ +# FILENAME_TGZ="boinc-cvs-TODAY.tar.gz" \ +# FILENAME_ZIP="boinc-cvs-TODAY.zip" \ +# DESTINATION="/disks/milkyway/a/users/anderson/boinc/doc/source/nightly/" \ +# /disks/philmor/a/users/quarl/bin/export-tarball + +# CHECKOUT='svn export http://svn.quarl.org/repos/coursesurvey/trunk/coursesurvey' \ +# DIR=coursesurvey \ +# FILENAME_TGZ="coursesurvey-rSVNREVISION.tar.gz" \ +# FILENAME_ZIP="coursesurvey-rSVNREVISION.zip" \ +# DESTINATION="ftp://upload.sourceforge.net/incoming" \ +# /home/quarl/bin/export-tarball + +# Note: requires GNU tar (if you want to use other tar need to separate gzip +# step) + +die() +{ + echo "ERROR in $0 on `hostname`:" + echo "$1" + [ "$2" ] && cat "$2" + exit 1 +} + +reqeval() +{ + test -n "$VERBOSE" && echo "Executing: $1" + eval "$1" || die "error executing: $1" +} + +reqeval_log() +{ + test -n "$VERBOSE" && echo "Executing: $1" + eval "$1" > $2 2>&1 || die "error executing: $1" $2 +} + +upload() +{ + if echo "$DESTINATION" | grep '^ftp://' >/dev/null ; then + ftp_upload "$1" + else + file_upload "$1" + fi +} + +file_upload() +{ + test -n "$VERBOSE" && echo "Putting $1 in $DESTINATION" + reqeval "mv $1 $DESTINATION" +} + +ftp_upload() +{ + SERVER=`echo "$DESTINATION" | sed 's,^ftp://,,' | sed 's,/.*,,'` + DIRECTORY=`echo "$DESTINATION" | sed 's,^ftp://[^/]*',,` + + test -n "$VERBOSE" && echo "Uploading $1 to ftp site $SERVER $DIRECTORY" + reqeval "ncftpput $SERVER $DIRECTORY $1" +} + +if [ -z "$USER" ]; then + USER=$LOGNAME +fi + +if ttyo 2>/dev/null ; then + VERBOSE=1 +fi + +test -n "$CHECKOUT" || die "No CHECKOUT specified" +test -n "$DIR" || die "No DIR specified" +test -n "$FILENAME_TGZ" -o -n "$FILENAME_ZIP" || die "No FILENAME_TGZ nor FILENAME_ZIP specified" +test -n "$DESTINATION" || die "No DESTINATION specified" + +TMPDIR=/tmp/export-tarball-$$ + +reqeval "rm -rf $TMPDIR" +reqeval "mkdir -p $TMPDIR" +reqeval "cd $TMPDIR" +reqeval_log "$CHECKOUT" checkout.log + +test -d "$DIR" || die "No DIR $DIR after CHECKOUT" + +TODAY=`date +%Y-%m-%d` +# SVNREVISION=`svnlastchangedversion "$DIR" 2>/dev/null` + +FILENAME_TGZ=`echo "$FILENAME_TGZ" | sed "s/TODAY/$TODAY/"` +FILENAME_ZIP=`echo "$FILENAME_ZIP" | sed "s/TODAY/$TODAY/"` + +# FILENAME_TGZ=`echo "$FILENAME_TGZ" | sed "s/SVNREVISION/$SVNREVISION/"` +# FILENAME_ZIP=`echo "$FILENAME_ZIP" | sed "s/SVNREVISION/$SVNREVISION/"` + +test -n "$FILENAME_TGZ" && reqeval_log "tar czvf $FILENAME_TGZ $DIR" tar.log +test -n "$FILENAME_ZIP" && reqeval_log "zip -r9 $FILENAME_ZIP $DIR" zip.log +upload $FILENAME_TGZ +upload $FILENAME_ZIP + +reqeval "rm -rf $TMPDIR" diff --git a/glut/Roman.stroke b/glut/Roman.stroke new file mode 100644 index 0000000..b67b55f --- /dev/null +++ b/glut/Roman.stroke @@ -0,0 +1,604 @@ +## +# $XConsortium: Roman.src,v 5.2 91/07/21 16:42:23 rws Exp $ +## +## Copyright (c) 1989,1990, 1991 by Sun Microsystems, Inc. and the X Consortium. +## +## All Rights Reserved +## +## Permission to use, copy, modify, and distribute this software and its +## documentation for any purpose and without fee is hereby granted, +## provided that the above copyright notice appear in all copies and that +## both that copyright notice and this permission notice appear in +## supporting documentation, and that the names of Sun Microsystems, +## the X Consortium, and MIT not be used in advertising or publicity +## pertaining to distribution of the software without specific, written +## prior permission. +## +## SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +## INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +## EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR +## CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF +## USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +## OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +## PERFORMANCE OF THIS SOFTWARE. + +# Roman Simplex font. + + FONTNAME Roman + TOP 119.0476 + BOTTOM -33.3333 + NUM_CH 128 + PROPERTIES 3 + + (CHARSET_REGISTRY ISO8859) + (CHARSET_ENCODING "1") + (SPACING P) + +INDEX 32 STROKE 0 CENTER 52.3810 RIGHT 104.7619 +INDEX 33 STROKE 2 CENTER 4.7619 RIGHT 9.5238 + OPEN 2 (4.7619 100.0000) (4.7619 33.3333) + OPEN 5 (4.7619 9.5238) (0.0000 4.7619) (4.7619 0.0000) + (9.5238 4.7619) (4.7619 9.5238) +INDEX 34 STROKE 2 CENTER 19.0476 RIGHT 38.0952 + OPEN 2 (0.0000 100.0000) (0.0000 66.6667) + OPEN 2 (38.0952 100.0000) (38.0952 66.6667) +INDEX 35 STROKE 4 CENTER 33.3333 RIGHT 71.4286 + OPEN 2 (38.0952 119.0476) (4.7619 -33.3333) + OPEN 2 (66.6667 119.0476) (33.3333 -33.3333) + OPEN 2 (4.7619 57.1429) (71.4286 57.1429) + OPEN 2 (0.0000 28.5714) (66.6667 28.5714) +INDEX 36 STROKE 3 CENTER 33.3333 RIGHT 66.6667 + OPEN 2 (23.8095 119.0476) (23.8095 -19.0476) + OPEN 2 (42.8571 119.0476) (42.8571 -19.0476) + OPEN 20 (66.6667 85.7143) (57.1429 95.2381) (42.8571 100.0000) + (23.8095 100.0000) (9.5238 95.2381) (0.0000 85.7143) (0.0000 76.1905) + (4.7619 66.6667) (9.5238 61.9048) (19.0476 57.1429) (47.6190 47.6190) + (57.1429 42.8571) (61.9048 38.0952) (66.6667 28.5714) (66.6667 14.2857) + (57.1429 4.7619) (42.8571 0.0000) (23.8095 0.0000) (9.5238 4.7619) + (0.0000 14.2857) +INDEX 37 STROKE 3 CENTER 42.8571 RIGHT 85.7143 + OPEN 2 (85.7143 100.0000) (0.0000 0.0000) + OPEN 16 (23.8095 100.0000) (33.3333 90.4762) (33.3333 80.9524) + (28.5714 71.4286) (19.0476 66.6667) (9.5238 66.6667) (0.0000 76.1905) + (0.0000 85.7143) (4.7619 95.2381) (14.2857 100.0000) (23.8095 100.0000) + (33.3333 95.2381) (47.6190 90.4762) (61.9048 90.4762) (76.1905 95.2381) + (85.7143 100.0000) + OPEN 11 (66.6667 33.3333) (57.1429 28.5714) (52.3810 19.0476) + (52.3810 9.5238) (61.9048 0.0000) (71.4286 0.0000) (80.9524 4.7619) + (85.7143 14.2857) (85.7143 23.8095) (76.1905 33.3333) (66.6667 33.3333) +INDEX 38 STROKE 1 CENTER 47.6190 RIGHT 95.2381 + OPEN 34 (95.2381 57.1429) (95.2381 61.9048) (90.4762 66.6667) + (85.7143 66.6667) (80.9524 61.9048) (76.1905 52.3810) (66.6667 28.5714) + (57.1429 14.2857) (47.6190 4.7619) (38.0952 0.0000) (19.0476 0.0000) + (9.5238 4.7619) (4.7619 9.5238) (0.0000 19.0476) (0.0000 28.5714) + (4.7619 38.0952) (9.5238 42.8571) (42.8571 61.9048) (47.6190 66.6667) + (52.3810 76.1905) (52.3810 85.7143) (47.6190 95.2381) (38.0952 100.0000) + (28.5714 95.2381) (23.8095 85.7143) (23.8095 76.1905) (28.5714 61.9048) + (38.0952 47.6190) (61.9048 14.2857) (71.4286 4.7619) (80.9524 0.0000) + (90.4762 0.0000) (95.2381 4.7619) (95.2381 9.5238) +INDEX 39 STROKE 1 CENTER 0.0000 RIGHT 0.0000 + OPEN 2 (0.0000 100.0000) (0.0000 66.6667) +INDEX 40 STROKE 1 CENTER 14.2857 RIGHT 33.3333 + OPEN 10 (33.3333 119.0476) (23.8095 109.5238) (14.2857 95.2381) + (4.7619 76.1905) (0.0000 52.3810) (0.0000 33.3333) (4.7619 9.5238) + (14.2857 -9.5238) (23.8095 -23.8095) (33.3333 -33.3333) +INDEX 41 STROKE 1 CENTER 19.0476 RIGHT 33.3333 + OPEN 10 (0.0000 119.0476) (9.5238 109.5238) (19.0476 95.2381) + (28.5714 76.1905) (33.3333 52.3810) (33.3333 33.3333) (28.5714 9.5238) + (19.0476 -9.5238) (9.5238 -23.8095) (0.0000 -33.3333) +INDEX 42 STROKE 3 CENTER 23.8095 RIGHT 47.6190 + OPEN 2 (23.8095 71.4286) (23.8095 14.2857) + OPEN 2 (0.0000 57.1429) (47.6190 28.5714) + OPEN 2 (47.6190 57.1429) (0.0000 28.5714) +INDEX 43 STROKE 2 CENTER 42.8571 RIGHT 85.7143 + OPEN 2 (42.8571 85.7143) (42.8571 0.0000) + OPEN 2 (0.0000 42.8571) (85.7143 42.8571) +INDEX 44 STROKE 1 CENTER 4.7619 RIGHT 9.5238 + OPEN 8 (9.5238 4.7619) (4.7619 0.0000) (0.0000 4.7619) + (4.7619 9.5238) (9.5238 4.7619) (9.5238 -4.7619) (4.7619 -14.2857) + (0.0000 -19.0476) +INDEX 45 STROKE 1 CENTER 42.8571 RIGHT 85.7143 + OPEN 2 (0.0000 42.8571) (85.7143 42.8571) +INDEX 46 STROKE 1 CENTER 4.7619 RIGHT 9.5238 + OPEN 5 (4.7619 9.5238) (0.0000 4.7619) (4.7619 0.0000) + (9.5238 4.7619) (4.7619 9.5238) +INDEX 47 STROKE 1 CENTER 33.3333 RIGHT 66.6667 + OPEN 2 (0.0000 -14.2857) (66.6667 100.0000) +INDEX 48 STROKE 1 CENTER 33.3333 RIGHT 66.6667 + OPEN 17 (28.5714 100.0000) (14.2857 95.2381) (4.7619 80.9524) + (0.0000 57.1429) (0.0000 42.8571) (4.7619 19.0476) (14.2857 4.7619) + (28.5714 0.0000) (38.0952 0.0000) (52.3810 4.7619) (61.9048 19.0476) + (66.6667 42.8571) (66.6667 57.1429) (61.9048 80.9524) (52.3810 95.2381) + (38.0952 100.0000) (28.5714 100.0000) +INDEX 49 STROKE 1 CENTER 19.0476 RIGHT 23.8095 + OPEN 4 (0.0000 80.9524) (9.5238 85.7143) (23.8095 100.0000) + (23.8095 0.0000) +INDEX 50 STROKE 1 CENTER 33.3333 RIGHT 66.6667 + OPEN 14 (4.7619 76.1905) (4.7619 80.9524) (9.5238 90.4762) + (14.2857 95.2381) (23.8095 100.0000) (42.8571 100.0000) (52.3810 95.2381) + (57.1429 90.4762) (61.9048 80.9524) (61.9048 71.4286) (57.1429 61.9048) + (47.6190 47.6190) (0.0000 0.0000) (66.6667 0.0000) +INDEX 51 STROKE 1 CENTER 33.3333 RIGHT 66.6667 + OPEN 15 (9.5238 100.0000) (61.9048 100.0000) (33.3333 61.9048) + (47.6190 61.9048) (57.1429 57.1429) (61.9048 52.3810) (66.6667 38.0952) + (66.6667 28.5714) (61.9048 14.2857) (52.3810 4.7619) (38.0952 0.0000) + (23.8095 0.0000) (9.5238 4.7619) (4.7619 9.5238) (0.0000 19.0476) +INDEX 52 STROKE 2 CENTER 33.3333 RIGHT 71.4286 + OPEN 3 (47.6190 100.0000) (0.0000 33.3333) (71.4286 33.3333) + OPEN 2 (47.6190 100.0000) (47.6190 0.0000) +INDEX 53 STROKE 1 CENTER 33.3333 RIGHT 66.6667 + OPEN 17 (57.1429 100.0000) (9.5238 100.0000) (4.7619 57.1429) + (9.5238 61.9048) (23.8095 66.6667) (38.0952 66.6667) (52.3810 61.9048) + (61.9048 52.3810) (66.6667 38.0952) (66.6667 28.5714) (61.9048 14.2857) + (52.3810 4.7619) (38.0952 0.0000) (23.8095 0.0000) (9.5238 4.7619) + (4.7619 9.5238) (0.0000 19.0476) +INDEX 54 STROKE 1 CENTER 28.5714 RIGHT 61.9048 + OPEN 23 (57.1429 85.7143) (52.3810 95.2381) (38.0952 100.0000) + (28.5714 100.0000) (14.2857 95.2381) (4.7619 80.9524) (0.0000 57.1429) + (0.0000 33.3333) (4.7619 14.2857) (14.2857 4.7619) (28.5714 0.0000) + (33.3333 0.0000) (47.6190 4.7619) (57.1429 14.2857) (61.9048 28.5714) + (61.9048 33.3333) (57.1429 47.6190) (47.6190 57.1429) (33.3333 61.9048) + (28.5714 61.9048) (14.2857 57.1429) (4.7619 47.6190) (0.0000 33.3333) +INDEX 55 STROKE 2 CENTER 33.3333 RIGHT 66.6667 + OPEN 2 (66.6667 100.0000) (19.0476 0.0000) + OPEN 2 (0.0000 100.0000) (66.6667 100.0000) +INDEX 56 STROKE 1 CENTER 33.3333 RIGHT 66.6667 + OPEN 29 (23.8095 100.0000) (9.5238 95.2381) (4.7619 85.7143) + (4.7619 76.1905) (9.5238 66.6667) (19.0476 61.9048) (38.0952 57.1429) + (52.3810 52.3810) (61.9048 42.8571) (66.6667 33.3333) (66.6667 19.0476) + (61.9048 9.5238) (57.1429 4.7619) (42.8571 0.0000) (23.8095 0.0000) + (9.5238 4.7619) (4.7619 9.5238) (0.0000 19.0476) (0.0000 33.3333) + (4.7619 42.8571) (14.2857 52.3810) (28.5714 57.1429) (47.6190 61.9048) + (57.1429 66.6667) (61.9048 76.1905) (61.9048 85.7143) (57.1429 95.2381) + (42.8571 100.0000) (23.8095 100.0000) +INDEX 57 STROKE 1 CENTER 33.3333 RIGHT 61.9048 + OPEN 23 (61.9048 66.6667) (57.1429 52.3810) (47.6190 42.8571) + (33.3333 38.0952) (28.5714 38.0952) (14.2857 42.8571) (4.7619 52.3810) + (0.0000 66.6667) (0.0000 71.4286) (4.7619 85.7143) (14.2857 95.2381) + (28.5714 100.0000) (33.3333 100.0000) (47.6190 95.2381) (57.1429 85.7143) + (61.9048 66.6667) (61.9048 42.8571) (57.1429 19.0476) (47.6190 4.7619) + (33.3333 0.0000) (23.8095 0.0000) (9.5238 4.7619) (4.7619 14.2857) +INDEX 58 STROKE 2 CENTER 4.7619 RIGHT 9.5238 + OPEN 5 (4.7619 66.6667) (0.0000 61.9048) (4.7619 57.1429) + (9.5238 61.9048) (4.7619 66.6667) + OPEN 5 (4.7619 9.5238) (0.0000 4.7619) (4.7619 0.0000) + (9.5238 4.7619) (4.7619 9.5238) +INDEX 59 STROKE 2 CENTER 4.7619 RIGHT 9.5238 + OPEN 5 (4.7619 66.6667) (0.0000 61.9048) (4.7619 57.1429) + (9.5238 61.9048) (4.7619 66.6667) + OPEN 8 (9.5238 4.7619) (4.7619 0.0000) (0.0000 4.7619) + (4.7619 9.5238) (9.5238 4.7619) (9.5238 -4.7619) (4.7619 -14.2857) + (0.0000 -19.0476) +INDEX 60 STROKE 1 CENTER 38.0952 RIGHT 76.1905 + OPEN 3 (76.1905 85.7143) (0.0000 42.8571) (76.1905 0.0000) +INDEX 61 STROKE 2 CENTER 42.8571 RIGHT 85.7143 + OPEN 2 (0.0000 57.1429) (85.7143 57.1429) + OPEN 2 (0.0000 28.5714) (85.7143 28.5714) +INDEX 62 STROKE 1 CENTER 38.0952 RIGHT 76.1905 + OPEN 3 (0.0000 85.7143) (76.1905 42.8571) (0.0000 0.0000) +INDEX 63 STROKE 2 CENTER 28.5714 RIGHT 57.1429 + OPEN 14 (0.0000 76.1905) (0.0000 80.9524) (4.7619 90.4762) + (9.5238 95.2381) (19.0476 100.0000) (38.0952 100.0000) (47.6190 95.2381) + (52.3810 90.4762) (57.1429 80.9524) (57.1429 71.4286) (52.3810 61.9048) + (47.6190 57.1429) (28.5714 47.6190) (28.5714 33.3333) + OPEN 5 (28.5714 9.5238) (23.8095 4.7619) (28.5714 0.0000) + (33.3333 4.7619) (28.5714 9.5238) +INDEX 64 STROKE 2 CENTER 28.5714 RIGHT 61.9048 + OPEN 8 (42.8571 52.3810) (33.3333 57.1429) (23.8095 57.1429) + (19.0476 47.6190) (19.0476 42.8571) (23.8095 33.3333) (33.3333 33.3333) + (42.8571 38.0952) + OPEN 19 (42.8571 57.1429) (42.8571 38.0952) (47.6190 33.3333) + (57.1429 33.3333) (61.9048 42.8571) (61.9048 47.6190) (57.1429 61.9048) + (47.6190 71.4286) (33.3333 76.1905) (28.5714 76.1905) (14.2857 71.4286) + (4.7619 61.9048) (0.0000 47.6190) (0.0000 42.8571) (4.7619 28.5714) + (14.2857 19.0476) (28.5714 14.2857) (33.3333 14.2857) (47.6190 19.0476) +INDEX 65 STROKE 3 CENTER 38.0952 RIGHT 76.1905 + OPEN 2 (38.0952 100.0000) (0.0000 0.0000) + OPEN 2 (38.0952 100.0000) (76.1905 0.0000) + OPEN 2 (14.2857 33.3333) (61.9048 33.3333) +INDEX 66 STROKE 3 CENTER 33.3333 RIGHT 66.6667 + OPEN 2 (0.0000 100.0000) (0.0000 0.0000) + OPEN 9 (0.0000 100.0000) (42.8571 100.0000) (57.1429 95.2381) + (61.9048 90.4762) (66.6667 80.9524) (66.6667 71.4286) (61.9048 61.9048) + (57.1429 57.1429) (42.8571 52.3810) + OPEN 10 (0.0000 52.3810) (42.8571 52.3810) (57.1429 47.6190) + (61.9048 42.8571) (66.6667 33.3333) (66.6667 19.0476) (61.9048 9.5238) + (57.1429 4.7619) (42.8571 0.0000) (0.0000 0.0000) +INDEX 67 STROKE 1 CENTER 33.3333 RIGHT 71.4286 + OPEN 18 (71.4286 76.1905) (66.6667 85.7143) (57.1429 95.2381) + (47.6190 100.0000) (28.5714 100.0000) (19.0476 95.2381) (9.5238 85.7143) + (4.7619 76.1905) (0.0000 61.9048) (0.0000 38.0952) (4.7619 23.8095) + (9.5238 14.2857) (19.0476 4.7619) (28.5714 0.0000) (47.6190 0.0000) + (57.1429 4.7619) (66.6667 14.2857) (71.4286 23.8095) +INDEX 68 STROKE 2 CENTER 33.3333 RIGHT 66.6667 + OPEN 2 (0.0000 100.0000) (0.0000 0.0000) + OPEN 12 (0.0000 100.0000) (33.3333 100.0000) (47.6190 95.2381) + (57.1429 85.7143) (61.9048 76.1905) (66.6667 61.9048) (66.6667 38.0952) + (61.9048 23.8095) (57.1429 14.2857) (47.6190 4.7619) (33.3333 0.0000) + (0.0000 0.0000) +INDEX 69 STROKE 4 CENTER 28.5714 RIGHT 61.9048 + OPEN 2 (0.0000 100.0000) (0.0000 0.0000) + OPEN 2 (0.0000 100.0000) (61.9048 100.0000) + OPEN 2 (0.0000 52.3810) (38.0952 52.3810) + OPEN 2 (0.0000 0.0000) (61.9048 0.0000) +INDEX 70 STROKE 3 CENTER 28.5714 RIGHT 61.9048 + OPEN 2 (0.0000 100.0000) (0.0000 0.0000) + OPEN 2 (0.0000 100.0000) (61.9048 100.0000) + OPEN 2 (0.0000 52.3810) (38.0952 52.3810) +INDEX 71 STROKE 2 CENTER 33.3333 RIGHT 71.4286 + OPEN 19 (71.4286 76.1905) (66.6667 85.7143) (57.1429 95.2381) + (47.6190 100.0000) (28.5714 100.0000) (19.0476 95.2381) (9.5238 85.7143) + (4.7619 76.1905) (0.0000 61.9048) (0.0000 38.0952) (4.7619 23.8095) + (9.5238 14.2857) (19.0476 4.7619) (28.5714 0.0000) (47.6190 0.0000) + (57.1429 4.7619) (66.6667 14.2857) (71.4286 23.8095) (71.4286 38.0952) + OPEN 2 (47.6190 38.0952) (71.4286 38.0952) +INDEX 72 STROKE 3 CENTER 33.3333 RIGHT 66.6667 + OPEN 2 (0.0000 100.0000) (0.0000 0.0000) + OPEN 2 (66.6667 100.0000) (66.6667 0.0000) + OPEN 2 (0.0000 52.3810) (66.6667 52.3810) +INDEX 73 STROKE 1 CENTER 0.0000 RIGHT 0.0000 + OPEN 2 (0.0000 100.0000) (0.0000 0.0000) +INDEX 74 STROKE 1 CENTER 28.5714 RIGHT 47.6190 + OPEN 10 (47.6190 100.0000) (47.6190 23.8095) (42.8571 9.5238) + (38.0952 4.7619) (28.5714 0.0000) (19.0476 0.0000) (9.5238 4.7619) + (4.7619 9.5238) (0.0000 23.8095) (0.0000 33.3333) +INDEX 75 STROKE 3 CENTER 33.3333 RIGHT 66.6667 + OPEN 2 (0.0000 100.0000) (0.0000 0.0000) + OPEN 2 (66.6667 100.0000) (0.0000 33.3333) + OPEN 2 (23.8095 57.1429) (66.6667 0.0000) +INDEX 76 STROKE 2 CENTER 28.5714 RIGHT 57.1429 + OPEN 2 (0.0000 100.0000) (0.0000 0.0000) + OPEN 2 (0.0000 0.0000) (57.1429 0.0000) +INDEX 77 STROKE 4 CENTER 38.0952 RIGHT 76.1905 + OPEN 2 (0.0000 100.0000) (0.0000 0.0000) + OPEN 2 (0.0000 100.0000) (38.0952 0.0000) + OPEN 2 (76.1905 100.0000) (38.0952 0.0000) + OPEN 2 (76.1905 100.0000) (76.1905 0.0000) +INDEX 78 STROKE 3 CENTER 33.3333 RIGHT 66.6667 + OPEN 2 (0.0000 100.0000) (0.0000 0.0000) + OPEN 2 (0.0000 100.0000) (66.6667 0.0000) + OPEN 2 (66.6667 100.0000) (66.6667 0.0000) +INDEX 79 STROKE 1 CENTER 38.0952 RIGHT 76.1905 + OPEN 21 (28.5714 100.0000) (19.0476 95.2381) (9.5238 85.7143) + (4.7619 76.1905) (0.0000 61.9048) (0.0000 38.0952) (4.7619 23.8095) + (9.5238 14.2857) (19.0476 4.7619) (28.5714 0.0000) (47.6190 0.0000) + (57.1429 4.7619) (66.6667 14.2857) (71.4286 23.8095) (76.1905 38.0952) + (76.1905 61.9048) (71.4286 76.1905) (66.6667 85.7143) (57.1429 95.2381) + (47.6190 100.0000) (28.5714 100.0000) +INDEX 80 STROKE 2 CENTER 33.3333 RIGHT 66.6667 + OPEN 2 (0.0000 100.0000) (0.0000 0.0000) + OPEN 10 (0.0000 100.0000) (42.8571 100.0000) (57.1429 95.2381) + (61.9048 90.4762) (66.6667 80.9524) (66.6667 66.6667) (61.9048 57.1429) + (57.1429 52.3810) (42.8571 47.6190) (0.0000 47.6190) +INDEX 81 STROKE 2 CENTER 38.0952 RIGHT 76.1905 + OPEN 21 (28.5714 100.0000) (19.0476 95.2381) (9.5238 85.7143) + (4.7619 76.1905) (0.0000 61.9048) (0.0000 38.0952) (4.7619 23.8095) + (9.5238 14.2857) (19.0476 4.7619) (28.5714 0.0000) (47.6190 0.0000) + (57.1429 4.7619) (66.6667 14.2857) (71.4286 23.8095) (76.1905 38.0952) + (76.1905 61.9048) (71.4286 76.1905) (66.6667 85.7143) (57.1429 95.2381) + (47.6190 100.0000) (28.5714 100.0000) + OPEN 2 (42.8571 19.0476) (71.4286 -9.5238) +INDEX 82 STROKE 3 CENTER 33.3333 RIGHT 66.6667 + OPEN 2 (0.0000 100.0000) (0.0000 0.0000) + OPEN 10 (0.0000 100.0000) (42.8571 100.0000) (57.1429 95.2381) + (61.9048 90.4762) (66.6667 80.9524) (66.6667 71.4286) (61.9048 61.9048) + (57.1429 57.1429) (42.8571 52.3810) (0.0000 52.3810) + OPEN 2 (33.3333 52.3810) (66.6667 0.0000) +INDEX 83 STROKE 1 CENTER 33.3333 RIGHT 66.6667 + OPEN 20 (66.6667 85.7143) (57.1429 95.2381) (42.8571 100.0000) + (23.8095 100.0000) (9.5238 95.2381) (0.0000 85.7143) (0.0000 76.1905) + (4.7619 66.6667) (9.5238 61.9048) (19.0476 57.1429) (47.6190 47.6190) + (57.1429 42.8571) (61.9048 38.0952) (66.6667 28.5714) (66.6667 14.2857) + (57.1429 4.7619) (42.8571 0.0000) (23.8095 0.0000) (9.5238 4.7619) + (0.0000 14.2857) +INDEX 84 STROKE 2 CENTER 33.3333 RIGHT 66.6667 + OPEN 2 (33.3333 100.0000) (33.3333 0.0000) + OPEN 2 (0.0000 100.0000) (66.6667 100.0000) +INDEX 85 STROKE 1 CENTER 33.3333 RIGHT 66.6667 + OPEN 10 (0.0000 100.0000) (0.0000 28.5714) (4.7619 14.2857) + (14.2857 4.7619) (28.5714 0.0000) (38.0952 0.0000) (52.3810 4.7619) + (61.9048 14.2857) (66.6667 28.5714) (66.6667 100.0000) +INDEX 86 STROKE 2 CENTER 38.0952 RIGHT 76.1905 + OPEN 2 (0.0000 100.0000) (38.0952 0.0000) + OPEN 2 (76.1905 100.0000) (38.0952 0.0000) +INDEX 87 STROKE 4 CENTER 47.6190 RIGHT 95.2381 + OPEN 2 (0.0000 100.0000) (23.8095 0.0000) + OPEN 2 (47.6190 100.0000) (23.8095 0.0000) + OPEN 2 (47.6190 100.0000) (71.4286 0.0000) + OPEN 2 (95.2381 100.0000) (71.4286 0.0000) +INDEX 88 STROKE 2 CENTER 33.3333 RIGHT 66.6667 + OPEN 2 (0.0000 100.0000) (66.6667 0.0000) + OPEN 2 (66.6667 100.0000) (0.0000 0.0000) +INDEX 89 STROKE 2 CENTER 38.0952 RIGHT 76.1905 + OPEN 3 (0.0000 100.0000) (38.0952 52.3810) (38.0952 0.0000) + OPEN 2 (76.1905 100.0000) (38.0952 52.3810) +INDEX 90 STROKE 3 CENTER 33.3333 RIGHT 66.6667 + OPEN 2 (66.6667 100.0000) (0.0000 0.0000) + OPEN 2 (0.0000 100.0000) (66.6667 100.0000) + OPEN 2 (0.0000 0.0000) (66.6667 0.0000) +INDEX 91 STROKE 4 CENTER 14.2857 RIGHT 33.3333 + OPEN 2 (0.0000 119.0476) (0.0000 -33.3333) + OPEN 2 (4.7619 119.0476) (4.7619 -33.3333) + OPEN 2 (0.0000 119.0476) (33.3333 119.0476) + OPEN 2 (0.0000 -33.3333) (33.3333 -33.3333) +INDEX 92 STROKE 1 CENTER 33.3333 RIGHT 66.6667 + OPEN 2 (0.0000 100.0000) (66.6667 -14.2857) +INDEX 93 STROKE 4 CENTER 19.0476 RIGHT 33.3333 + OPEN 2 (28.5714 119.0476) (28.5714 -33.3333) + OPEN 2 (33.3333 119.0476) (33.3333 -33.3333) + OPEN 2 (0.0000 119.0476) (33.3333 119.0476) + OPEN 2 (0.0000 -33.3333) (33.3333 -33.3333) +INDEX 94 STROKE 2 CENTER 38.0952 RIGHT 76.1905 + OPEN 2 (38.0952 109.5238) (0.0000 42.8571) + OPEN 2 (38.0952 109.5238) (76.1905 42.8571) +INDEX 95 STROKE 1 CENTER 52.3810 RIGHT 104.7619 + OPEN 5 (0.0000 -33.3333) (104.7619 -33.3333) (104.7619 -28.5714) + (0.0000 -28.5714) (0.0000 -33.3333) +INDEX 96 STROKE 2 CENTER 14.2857 RIGHT 28.5714 + OPEN 2 (4.7619 100.0000) (28.5714 71.4286) + OPEN 3 (4.7619 100.0000) (0.0000 95.2381) (28.5714 71.4286) +INDEX 97 STROKE 2 CENTER 28.5714 RIGHT 57.1429 + OPEN 2 (57.1429 66.6667) (57.1429 0.0000) + OPEN 14 (57.1429 52.3810) (47.6190 61.9048) (38.0952 66.6667) + (23.8095 66.6667) (14.2857 61.9048) (4.7619 52.3810) (0.0000 38.0952) + (0.0000 28.5714) (4.7619 14.2857) (14.2857 4.7619) (23.8095 0.0000) + (38.0952 0.0000) (47.6190 4.7619) (57.1429 14.2857) +INDEX 98 STROKE 2 CENTER 28.5714 RIGHT 57.1429 + OPEN 2 (0.0000 100.0000) (0.0000 0.0000) + OPEN 14 (0.0000 52.3810) (9.5238 61.9048) (19.0476 66.6667) + (33.3333 66.6667) (42.8571 61.9048) (52.3810 52.3810) (57.1429 38.0952) + (57.1429 28.5714) (52.3810 14.2857) (42.8571 4.7619) (33.3333 0.0000) + (19.0476 0.0000) (9.5238 4.7619) (0.0000 14.2857) +INDEX 99 STROKE 1 CENTER 28.5714 RIGHT 57.1429 + OPEN 14 (57.1429 52.3810) (47.6190 61.9048) (38.0952 66.6667) + (23.8095 66.6667) (14.2857 61.9048) (4.7619 52.3810) (0.0000 38.0952) + (0.0000 28.5714) (4.7619 14.2857) (14.2857 4.7619) (23.8095 0.0000) + (38.0952 0.0000) (47.6190 4.7619) (57.1429 14.2857) +INDEX 100 STROKE 2 CENTER 28.5714 RIGHT 57.1429 + OPEN 2 (57.1429 100.0000) (57.1429 0.0000) + OPEN 14 (57.1429 52.3810) (47.6190 61.9048) (38.0952 66.6667) + (23.8095 66.6667) (14.2857 61.9048) (4.7619 52.3810) (0.0000 38.0952) + (0.0000 28.5714) (4.7619 14.2857) (14.2857 4.7619) (23.8095 0.0000) + (38.0952 0.0000) (47.6190 4.7619) (57.1429 14.2857) +INDEX 101 STROKE 1 CENTER 28.5714 RIGHT 57.1429 + OPEN 17 (0.0000 38.0952) (57.1429 38.0952) (57.1429 47.6190) + (52.3810 57.1429) (47.6190 61.9048) (38.0952 66.6667) (23.8095 66.6667) + (14.2857 61.9048) (4.7619 52.3810) (0.0000 38.0952) (0.0000 28.5714) + (4.7619 14.2857) (14.2857 4.7619) (23.8095 0.0000) (38.0952 0.0000) + (47.6190 4.7619) (57.1429 14.2857) +INDEX 102 STROKE 2 CENTER 14.2857 RIGHT 38.0952 + OPEN 5 (38.0952 100.0000) (28.5714 100.0000) (19.0476 95.2381) + (14.2857 80.9524) (14.2857 0.0000) + OPEN 2 (0.0000 66.6667) (33.3333 66.6667) +INDEX 103 STROKE 2 CENTER 28.5714 RIGHT 57.1429 + OPEN 7 (57.1429 66.6667) (57.1429 -9.5238) (52.3810 -23.8095) + (47.6190 -28.5714) (38.0952 -33.3333) (23.8095 -33.3333) (14.2857 -28.5714) + OPEN 14 (57.1429 52.3810) (47.6190 61.9048) (38.0952 66.6667) + (23.8095 66.6667) (14.2857 61.9048) (4.7619 52.3810) (0.0000 38.0952) + (0.0000 28.5714) (4.7619 14.2857) (14.2857 4.7619) (23.8095 0.0000) + (38.0952 0.0000) (47.6190 4.7619) (57.1429 14.2857) +INDEX 104 STROKE 2 CENTER 23.8095 RIGHT 52.3810 + OPEN 2 (0.0000 100.0000) (0.0000 0.0000) + OPEN 7 (0.0000 47.6190) (14.2857 61.9048) (23.8095 66.6667) + (38.0952 66.6667) (47.6190 61.9048) (52.3810 47.6190) (52.3810 0.0000) +INDEX 105 STROKE 2 CENTER 4.7619 RIGHT 9.5238 + OPEN 5 (0.0000 100.0000) (4.7619 95.2381) (9.5238 100.0000) + (4.7619 104.7619) (0.0000 100.0000) + OPEN 2 (4.7619 66.6667) (4.7619 0.0000) +INDEX 106 STROKE 2 CENTER 19.0476 RIGHT 28.5714 + OPEN 5 (19.0476 100.0000) (23.8095 95.2381) (28.5714 100.0000) + (23.8095 104.7619) (19.0476 100.0000) + OPEN 5 (23.8095 66.6667) (23.8095 -14.2857) (19.0476 -28.5714) + (9.5238 -33.3333) (0.0000 -33.3333) +INDEX 107 STROKE 3 CENTER 23.8095 RIGHT 52.3810 + OPEN 2 (0.0000 100.0000) (0.0000 0.0000) + OPEN 2 (47.6190 66.6667) (0.0000 19.0476) + OPEN 2 (19.0476 38.0952) (52.3810 0.0000) +INDEX 108 STROKE 1 CENTER 0.0000 RIGHT 0.0000 + OPEN 2 (0.0000 100.0000) (0.0000 0.0000) +INDEX 109 STROKE 3 CENTER 52.3810 RIGHT 104.7619 + OPEN 2 (0.0000 66.6667) (0.0000 0.0000) + OPEN 7 (0.0000 47.6190) (14.2857 61.9048) (23.8095 66.6667) + (38.0952 66.6667) (47.6190 61.9048) (52.3810 47.6190) (52.3810 0.0000) + OPEN 7 (52.3810 47.6190) (66.6667 61.9048) (76.1905 66.6667) + (90.4762 66.6667) (100.0000 61.9048) (104.7619 47.6190) (104.7619 0.0000) +INDEX 110 STROKE 2 CENTER 23.8095 RIGHT 52.3810 + OPEN 2 (0.0000 66.6667) (0.0000 0.0000) + OPEN 7 (0.0000 47.6190) (14.2857 61.9048) (23.8095 66.6667) + (38.0952 66.6667) (47.6190 61.9048) (52.3810 47.6190) (52.3810 0.0000) +INDEX 111 STROKE 1 CENTER 28.5714 RIGHT 61.9048 + OPEN 17 (23.8095 66.6667) (14.2857 61.9048) (4.7619 52.3810) + (0.0000 38.0952) (0.0000 28.5714) (4.7619 14.2857) (14.2857 4.7619) + (23.8095 0.0000) (38.0952 0.0000) (47.6190 4.7619) (57.1429 14.2857) + (61.9048 28.5714) (61.9048 38.0952) (57.1429 52.3810) (47.6190 61.9048) + (38.0952 66.6667) (23.8095 66.6667) +INDEX 112 STROKE 2 CENTER 28.5714 RIGHT 57.1429 + OPEN 2 (0.0000 66.6667) (0.0000 -33.3333) + OPEN 14 (0.0000 52.3810) (9.5238 61.9048) (19.0476 66.6667) + (33.3333 66.6667) (42.8571 61.9048) (52.3810 52.3810) (57.1429 38.0952) + (57.1429 28.5714) (52.3810 14.2857) (42.8571 4.7619) (33.3333 0.0000) + (19.0476 0.0000) (9.5238 4.7619) (0.0000 14.2857) +INDEX 113 STROKE 2 CENTER 28.5714 RIGHT 57.1429 + OPEN 2 (57.1429 66.6667) (57.1429 -33.3333) + OPEN 14 (57.1429 52.3810) (47.6190 61.9048) (38.0952 66.6667) + (23.8095 66.6667) (14.2857 61.9048) (4.7619 52.3810) (0.0000 38.0952) + (0.0000 28.5714) (4.7619 14.2857) (14.2857 4.7619) (23.8095 0.0000) + (38.0952 0.0000) (47.6190 4.7619) (57.1429 14.2857) +INDEX 114 STROKE 2 CENTER 14.2857 RIGHT 38.0952 + OPEN 2 (0.0000 66.6667) (0.0000 0.0000) + OPEN 5 (0.0000 38.0952) (4.7619 52.3810) (14.2857 61.9048) + (23.8095 66.6667) (38.0952 66.6667) +INDEX 115 STROKE 1 CENTER 23.8095 RIGHT 52.3810 + OPEN 17 (52.3810 52.3810) (47.6190 61.9048) (33.3333 66.6667) + (19.0476 66.6667) (4.7619 61.9048) (0.0000 52.3810) (4.7619 42.8571) + (14.2857 38.0952) (38.0952 33.3333) (47.6190 28.5714) (52.3810 19.0476) + (52.3810 14.2857) (47.6190 4.7619) (33.3333 0.0000) (19.0476 0.0000) + (4.7619 4.7619) (0.0000 14.2857) +INDEX 116 STROKE 2 CENTER 14.2857 RIGHT 38.0952 + OPEN 5 (14.2857 100.0000) (14.2857 19.0476) (19.0476 4.7619) + (28.5714 0.0000) (38.0952 0.0000) + OPEN 2 (0.0000 66.6667) (33.3333 66.6667) +INDEX 117 STROKE 2 CENTER 23.8095 RIGHT 52.3810 + OPEN 7 (0.0000 66.6667) (0.0000 19.0476) (4.7619 4.7619) + (14.2857 0.0000) (28.5714 0.0000) (38.0952 4.7619) (52.3810 19.0476) + OPEN 2 (52.3810 66.6667) (52.3810 0.0000) +INDEX 118 STROKE 2 CENTER 28.5714 RIGHT 57.1429 + OPEN 2 (0.0000 66.6667) (28.5714 0.0000) + OPEN 2 (57.1429 66.6667) (28.5714 0.0000) +INDEX 119 STROKE 4 CENTER 38.0952 RIGHT 76.1905 + OPEN 2 (0.0000 66.6667) (19.0476 0.0000) + OPEN 2 (38.0952 66.6667) (19.0476 0.0000) + OPEN 2 (38.0952 66.6667) (57.1429 0.0000) + OPEN 2 (76.1905 66.6667) (57.1429 0.0000) +INDEX 120 STROKE 2 CENTER 23.8095 RIGHT 52.3810 + OPEN 2 (0.0000 66.6667) (52.3810 0.0000) + OPEN 2 (52.3810 66.6667) (0.0000 0.0000) +INDEX 121 STROKE 2 CENTER 33.3333 RIGHT 61.9048 + OPEN 2 (4.7619 66.6667) (33.3333 0.0000) + OPEN 6 (61.9048 66.6667) (33.3333 0.0000) (23.8095 -19.0476) + (14.2857 -28.5714) (4.7619 -33.3333) (0.0000 -33.3333) +INDEX 122 STROKE 3 CENTER 23.8095 RIGHT 52.3810 + OPEN 2 (52.3810 66.6667) (0.0000 0.0000) + OPEN 2 (0.0000 66.6667) (52.3810 66.6667) + OPEN 2 (0.0000 0.0000) (52.3810 0.0000) +INDEX 123 STROKE 3 CENTER 14.2857 RIGHT 23.8095 + OPEN 10 (23.8095 119.0476) (14.2857 114.2857) (9.5238 109.5238) + (4.7619 100.0000) (4.7619 90.4762) (9.5238 80.9524) (14.2857 76.1905) + (19.0476 66.6667) (19.0476 57.1429) (9.5238 47.6190) + OPEN 17 (14.2857 114.2857) (9.5238 104.7619) (9.5238 95.2381) + (14.2857 85.7143) (19.0476 80.9524) (23.8095 71.4286) (23.8095 61.9048) + (19.0476 52.3810) (0.0000 42.8571) (19.0476 33.3333) (23.8095 23.8095) + (23.8095 14.2857) (19.0476 4.7619) (14.2857 0.0000) (9.5238 -9.5238) + (9.5238 -19.0476) (14.2857 -28.5714) + OPEN 10 (9.5238 38.0952) (19.0476 28.5714) (19.0476 19.0476) + (14.2857 9.5238) (9.5238 4.7619) (4.7619 -4.7619) (4.7619 -14.2857) + (9.5238 -23.8095) (14.2857 -28.5714) (23.8095 -33.3333) +INDEX 124 STROKE 1 CENTER 0.0000 RIGHT 0.0000 + OPEN 2 (0.0000 119.0476) (0.0000 -33.3333) +INDEX 125 STROKE 3 CENTER 9.5238 RIGHT 23.8095 + OPEN 10 (0.0000 119.0476) (9.5238 114.2857) (14.2857 109.5238) + (19.0476 100.0000) (19.0476 90.4762) (14.2857 80.9524) (9.5238 76.1905) + (4.7619 66.6667) (4.7619 57.1429) (14.2857 47.6190) + OPEN 17 (9.5238 114.2857) (14.2857 104.7619) (14.2857 95.2381) + (9.5238 85.7143) (4.7619 80.9524) (0.0000 71.4286) (0.0000 61.9048) + (4.7619 52.3810) (23.8095 42.8571) (4.7619 33.3333) (0.0000 23.8095) + (0.0000 14.2857) (4.7619 4.7619) (9.5238 0.0000) (14.2857 -9.5238) + (14.2857 -19.0476) (9.5238 -28.5714) + OPEN 10 (14.2857 38.0952) (4.7619 28.5714) (4.7619 19.0476) + (9.5238 9.5238) (14.2857 4.7619) (19.0476 -4.7619) (19.0476 -14.2857) + (14.2857 -23.8095) (9.5238 -28.5714) (0.0000 -33.3333) +INDEX 126 STROKE 2 CENTER 42.8571 RIGHT 85.7143 + OPEN 11 (0.0000 28.5714) (0.0000 38.0952) (4.7619 52.3810) + (14.2857 57.1429) (23.8095 57.1429) (33.3333 52.3810) (52.3810 38.0952) + (61.9048 33.3333) (71.4286 33.3333) (80.9524 38.0952) (85.7143 47.6190) + OPEN 11 (0.0000 38.0952) (4.7619 47.6190) (14.2857 52.3810) + (23.8095 52.3810) (33.3333 47.6190) (52.3810 33.3333) (61.9048 28.5714) + (71.4286 28.5714) (80.9524 33.3333) (85.7143 47.6190) (85.7143 57.1429) +INDEX 127 STROKE 2 CENTER 33.3333 RIGHT 66.6667 + OPEN 2 (52.3810 100.0000) (14.2857 -33.3333) + OPEN 17 (28.5714 66.6667) (14.2857 61.9048) (4.7619 52.3810) + (0.0000 38.0952) (0.0000 23.8095) (4.7619 14.2857) (14.2857 4.7619) + (28.5714 0.0000) (38.0952 0.0000) (52.3810 4.7619) (61.9048 14.2857) + (66.6667 28.5714) (66.6667 42.8571) (61.9048 52.3810) (52.3810 61.9048) + (38.0952 66.6667) (28.5714 66.6667) + + + +#/* NCGA GRAFNET:SANS-SERIF NORMAL*/ + +BEARING 32 L_SPACE 0.0 WIDTH 20.0 R_SPACE 0.0 +BEARING 33 L_SPACE 8.62 WIDTH 13.64 R_SPACE 8.48 +BEARING 34 L_SPACE 4.02 WIDTH 32.86 R_SPACE 9.32 +BEARING 35 L_SPACE 3.2 WIDTH 68.94 R_SPACE 4.86 +BEARING 36 L_SPACE 4.82 WIDTH 67.44 R_SPACE 4.72 +BEARING 37 L_SPACE 6.36 WIDTH 112.38 R_SPACE 4.5 +BEARING 38 L_SPACE 5.98 WIDTH 82.02 R_SPACE 0.54 +BEARING 39 L_SPACE 4.44 WIDTH 13.36 R_SPACE 9.18 +BEARING 40 L_SPACE 7.58 WIDTH 24.72 R_SPACE 6.26 +BEARING 41 L_SPACE 5.28 WIDTH 24.34 R_SPACE 8.92 +BEARING 42 L_SPACE 6.96 WIDTH 42.06 R_SPACE 4.86 +BEARING 43 L_SPACE 5.98 WIDTH 96.36 R_SPACE 5.56 +BEARING 44 L_SPACE 8.76 WIDTH 14.2 R_SPACE 7.78 +BEARING 45 L_SPACE 7.38 WIDTH 38.84 R_SPACE 7.66 +BEARING 46 L_SPACE 8.34 WIDTH 13.78 R_SPACE 8.62 +BEARING 47 L_SPACE 7.24 WIDTH 38.44 R_SPACE 8.2 +BEARING 48 L_SPACE 4.98 WIDTH 66.58 R_SPACE 5.42 +BEARING 49 L_SPACE 11.82 WIDTH 34.26 R_SPACE 30.9 +BEARING 50 L_SPACE 5.42 WIDTH 66.0 R_SPACE 5.56 +BEARING 51 L_SPACE 5.0 WIDTH 66.62 R_SPACE 5.38 +BEARING 52 L_SPACE 3.88 WIDTH 68.24 R_SPACE 4.86 +BEARING 53 L_SPACE 4.86 WIDTH 65.96 R_SPACE 6.16 +BEARING 54 L_SPACE 5.58 WIDTH 65.08 R_SPACE 6.32 +BEARING 55 L_SPACE 5.56 WIDTH 66.42 R_SPACE 5.0 +BEARING 56 L_SPACE 5.6 WIDTH 65.98 R_SPACE 5.4 +BEARING 57 L_SPACE 6.6 WIDTH 64.82 R_SPACE 5.56 +BEARING 58 L_SPACE 9.32 WIDTH 14.06 R_SPACE 7.38 +BEARING 59 L_SPACE 8.2 WIDTH 13.96 R_SPACE 8.58 +BEARING 60 L_SPACE 3.06 WIDTH 102.5 R_SPACE 2.36 +BEARING 61 L_SPACE 5.7 WIDTH 96.36 R_SPACE 5.84 +BEARING 62 L_SPACE 2.78 WIDTH 102.5 R_SPACE 2.64 +BEARING 63 L_SPACE 8.42 WIDTH 60.22 R_SPACE 8.34 +BEARING 64 L_SPACE 6.36 WIDTH 126.24 R_SPACE 6.1 +BEARING 65 L_SPACE 2.5 WIDTH 88.16 R_SPACE 1.8 +BEARING 66 L_SPACE 11.42 WIDTH 75.5 R_SPACE 5.54 +BEARING 67 L_SPACE 6.66 WIDTH 87.06 R_SPACE 6.4 +BEARING 68 L_SPACE 11.96 WIDTH 81.48 R_SPACE 6.66 +BEARING 69 L_SPACE 11.42 WIDTH 72.28 R_SPACE 4.86 +BEARING 70 L_SPACE 11.42 WIDTH 67.96 R_SPACE 5.42 +BEARING 71 L_SPACE 7.06 WIDTH 89.56 R_SPACE 11.28 +BEARING 72 L_SPACE 11.42 WIDTH 77.7 R_SPACE 11.0 +BEARING 73 L_SPACE 10.86 WIDTH 13.36 R_SPACE 10.44 +BEARING 74 L_SPACE 2.5 WIDTH 56.96 R_SPACE 9.88 +BEARING 75 L_SPACE 11.28 WIDTH 79.8 R_SPACE 1.38 +BEARING 76 L_SPACE 11.68 WIDTH 62.8 R_SPACE 2.5 +BEARING 77 L_SPACE 10.86 WIDTH 94.56 R_SPACE 10.16 +BEARING 78 L_SPACE 11.14 WIDTH 77.98 R_SPACE 11.0 +BEARING 79 L_SPACE 6.24 WIDTH 95.28 R_SPACE 6.4 +BEARING 80 L_SPACE 12.1 WIDTH 73.44 R_SPACE 6.9 +BEARING 81 L_SPACE 5.3 WIDTH 96.0 R_SPACE 6.6 +BEARING 82 L_SPACE 11.68 WIDTH 80.64 R_SPACE 4.02 +BEARING 83 L_SPACE 8.0 WIDTH 78.28 R_SPACE 6.16 +BEARING 84 L_SPACE 2.36 WIDTH 79.52 R_SPACE 2.92 +BEARING 85 L_SPACE 11.54 WIDTH 77.28 R_SPACE 11.28 +BEARING 86 L_SPACE 2.36 WIDTH 87.04 R_SPACE 3.06 +BEARING 87 L_SPACE 2.22 WIDTH 125.76 R_SPACE 3.06 +BEARING 88 L_SPACE 2.5 WIDTH 86.76 R_SPACE 3.2 +BEARING 89 L_SPACE 1.52 WIDTH 88.98 R_SPACE 1.94 +BEARING 90 L_SPACE 2.5 WIDTH 77.7 R_SPACE 4.58 +BEARING 91 L_SPACE 7.78 WIDTH 25.76 R_SPACE 5.0 +BEARING 92 L_SPACE 5.84 WIDTH 73.24 R_SPACE 5.7 +BEARING 93 L_SPACE 4.44 WIDTH 25.48 R_SPACE 8.62 +BEARING 94 L_SPACE 5.98 WIDTH 55.28 R_SPACE 8.06 +BEARING 95 L_SPACE -1.1 WIDTH 70.04 R_SPACE 0.4 +BEARING 96 L_SPACE 28.26 WIDTH 25.9 R_SPACE 26.74 +BEARING 97 L_SPACE 6.68 WIDTH 67.54 R_SPACE 2.78 +BEARING 98 L_SPACE 8.76 WIDTH 63.66 R_SPACE 4.56 +BEARING 99 L_SPACE 5.52 WIDTH 61.46 R_SPACE 6.26 +BEARING 100 L_SPACE 4.64 WIDTH 63.88 R_SPACE 8.48 +BEARING 101 L_SPACE 5.72 WIDTH 65.62 R_SPACE 5.66 +BEARING 102 L_SPACE 0.68 WIDTH 34.12 R_SPACE -0.12 +BEARING 103 L_SPACE 5.36 WIDTH 63.16 R_SPACE 8.48 +BEARING 104 L_SPACE 9.6 WIDTH 58.34 R_SPACE 9.04 +BEARING 105 L_SPACE 10.02 WIDTH 11.42 R_SPACE 9.32 +BEARING 106 L_SPACE -1.66 WIDTH 23.1 R_SPACE 9.32 +BEARING 107 L_SPACE 9.6 WIDTH 59.18 R_SPACE 0.54 +BEARING 108 L_SPACE 10.02 WIDTH 11.42 R_SPACE 9.32 +BEARING 109 L_SPACE 9.6 WIDTH 96.36 R_SPACE 9.6 +BEARING 110 L_SPACE 9.18 WIDTH 58.48 R_SPACE 9.32 +BEARING 111 L_SPACE 4.98 WIDTH 67.14 R_SPACE 4.86 +BEARING 112 L_SPACE 9.46 WIDTH 63.34 R_SPACE 4.2 +BEARING 113 L_SPACE 4.84 WIDTH 63.38 R_SPACE 8.76 +BEARING 114 L_SPACE 9.46 WIDTH 34.8 R_SPACE 1.94 +BEARING 115 L_SPACE 4.7 WIDTH 59.4 R_SPACE 5.24 +BEARING 116 L_SPACE 0.54 WIDTH 33.42 R_SPACE 0.68 +BEARING 117 L_SPACE 9.46 WIDTH 58.2 R_SPACE 9.32 +BEARING 118 L_SPACE 1.8 WIDTH 65.86 R_SPACE 1.66 +BEARING 119 L_SPACE 2.5 WIDTH 95.82 R_SPACE 1.8 +BEARING 120 L_SPACE 1.66 WIDTH 65.32 R_SPACE 2.36 +BEARING 121 L_SPACE 1.8 WIDTH 65.18 R_SPACE 2.36 +BEARING 122 L_SPACE 4.44 WIDTH 59.88 R_SPACE 5.0 +BEARING 123 L_SPACE 7.38 WIDTH 36.06 R_SPACE 10.44 +BEARING 124 L_SPACE 11.54 WIDTH 6.96 R_SPACE 12.24 +BEARING 125 L_SPACE 9.18 WIDTH 36.2 R_SPACE 8.48 +BEARING 126 L_SPACE 2.92 WIDTH 102.36 R_SPACE 2.64 + diff --git a/glut/glut.h b/glut/glut.h new file mode 100644 index 0000000..709f6ed --- /dev/null +++ b/glut/glut.h @@ -0,0 +1,600 @@ +#ifndef __glut_h__ +#define __glut_h__ + +/* Copyright (c) Mark J. Kilgard, 1994, 1995, 1996, 1998. */ + +/* This program is freely distributable without licensing fees and is + provided without guarantee or warrantee expressed or implied. This + program is -not- in the public domain. */ + +#if defined(_WIN32) + +/* GLUT 3.7 now tries to avoid including + to avoid name space pollution, but Win32's + needs APIENTRY and WINGDIAPI defined properly. */ +# if 0 +# define WIN32_LEAN_AND_MEAN +# include +# else + /* XXX This is from Win32's */ +# ifndef APIENTRY +# define GLUT_APIENTRY_DEFINED +# if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED) +# define APIENTRY __stdcall +# else +# define APIENTRY +# endif +# endif + /* XXX This is from Win32's */ +# ifndef CALLBACK +# if (defined(_M_MRX000) || defined(_M_IX86) || defined(_M_ALPHA) || defined(_M_PPC)) && !defined(MIDL_PASS) +# define CALLBACK __stdcall +# else +# define CALLBACK +# endif +# endif + /* XXX This is from Win32's and */ +# ifndef WINGDIAPI +# define GLUT_WINGDIAPI_DEFINED +# define WINGDIAPI __declspec(dllimport) +# endif + /* XXX This is from Win32's */ +# ifndef _WCHAR_T_DEFINED +typedef unsigned short wchar_t; +# define _WCHAR_T_DEFINED +# endif +# endif + +#pragma comment (lib, "winmm.lib") /* link with Windows MultiMedia lib */ +#pragma comment (lib, "opengl32.lib") /* link with Microsoft OpenGL lib */ +#pragma comment (lib, "glu32.lib") /* link with OpenGL Utility lib */ + +#pragma warning (disable:4244) /* Disable bogus conversion warnings. */ +#pragma warning (disable:4305) /* VC++ 5.0 version of above warning. */ + +#endif + +#if defined(__APPLE__) || defined(MACOSX) +#include +#include +#else +#include +#include +#endif + +/* define APIENTRY and CALLBACK to null string if we aren't on Win32 */ +#if !defined(_WIN32) +#define APIENTRY +#define GLUT_APIENTRY_DEFINED +#define CALLBACK +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + GLUT API revision history: + + GLUT_API_VERSION is updated to reflect incompatible GLUT + API changes (interface changes, semantic changes, deletions, + or additions). + + GLUT_API_VERSION=1 First public release of GLUT. 11/29/94 + + GLUT_API_VERSION=2 Added support for OpenGL/GLX multisampling, + extension. Supports new input devices like tablet, dial and button + box, and Spaceball. Easy to query OpenGL extensions. + + GLUT_API_VERSION=3 glutMenuStatus added. + + GLUT_API_VERSION=4 glutInitDisplayString, glutWarpPointer, + glutBitmapLength, glutStrokeLength, glutWindowStatusFunc, dynamic + video resize subAPI, glutPostWindowRedisplay, glutKeyboardUpFunc, + glutSpecialUpFunc, glutIgnoreKeyRepeat, glutSetKeyRepeat, + glutJoystickFunc, glutForceJoystickFunc (NOT FINALIZED!). +**/ +#ifndef GLUT_API_VERSION /* allow this to be overriden */ +#define GLUT_API_VERSION 3 +#endif + +/** + GLUT implementation revision history: + + GLUT_XLIB_IMPLEMENTATION is updated to reflect both GLUT + API revisions and implementation revisions (ie, bug fixes). + + GLUT_XLIB_IMPLEMENTATION=1 mjk's first public release of + GLUT Xlib-based implementation. 11/29/94 + + GLUT_XLIB_IMPLEMENTATION=2 mjk's second public release of + GLUT Xlib-based implementation providing GLUT version 2 + interfaces. + + GLUT_XLIB_IMPLEMENTATION=3 mjk's GLUT 2.2 images. 4/17/95 + + GLUT_XLIB_IMPLEMENTATION=4 mjk's GLUT 2.3 images. 6/?/95 + + GLUT_XLIB_IMPLEMENTATION=5 mjk's GLUT 3.0 images. 10/?/95 + + GLUT_XLIB_IMPLEMENTATION=7 mjk's GLUT 3.1+ with glutWarpPoitner. 7/24/96 + + GLUT_XLIB_IMPLEMENTATION=8 mjk's GLUT 3.1+ with glutWarpPoitner + and video resize. 1/3/97 + + GLUT_XLIB_IMPLEMENTATION=9 mjk's GLUT 3.4 release with early GLUT 4 routines. + + GLUT_XLIB_IMPLEMENTATION=11 Mesa 2.5's GLUT 3.6 release. + + GLUT_XLIB_IMPLEMENTATION=12 mjk's GLUT 3.6 release with early GLUT 4 routines + signal handling. + + GLUT_XLIB_IMPLEMENTATION=13 mjk's GLUT 3.7 release with GameGLUT support. +**/ +#ifndef GLUT_XLIB_IMPLEMENTATION /* Allow this to be overriden. */ +#define GLUT_XLIB_IMPLEMENTATION 13 +#endif + +/* Display mode bit masks. */ +#define GLUT_RGB 0 +#define GLUT_RGBA GLUT_RGB +#define GLUT_INDEX 1 +#define GLUT_SINGLE 0 +#define GLUT_DOUBLE 2 +#define GLUT_ACCUM 4 +#define GLUT_ALPHA 8 +#define GLUT_DEPTH 16 +#define GLUT_STENCIL 32 +#if (GLUT_API_VERSION >= 2) +#define GLUT_MULTISAMPLE 128 +#define GLUT_STEREO 256 +#endif +#if (GLUT_API_VERSION >= 3) +#define GLUT_LUMINANCE 512 +#endif + +/* Mouse buttons. */ +#define GLUT_LEFT_BUTTON 0 +#define GLUT_MIDDLE_BUTTON 1 +#define GLUT_RIGHT_BUTTON 2 + +/* Mouse button state. */ +#define GLUT_DOWN 0 +#define GLUT_UP 1 + +#if (GLUT_API_VERSION >= 2) +/* function keys */ +#define GLUT_KEY_F1 1 +#define GLUT_KEY_F2 2 +#define GLUT_KEY_F3 3 +#define GLUT_KEY_F4 4 +#define GLUT_KEY_F5 5 +#define GLUT_KEY_F6 6 +#define GLUT_KEY_F7 7 +#define GLUT_KEY_F8 8 +#define GLUT_KEY_F9 9 +#define GLUT_KEY_F10 10 +#define GLUT_KEY_F11 11 +#define GLUT_KEY_F12 12 +/* directional keys */ +#define GLUT_KEY_LEFT 100 +#define GLUT_KEY_UP 101 +#define GLUT_KEY_RIGHT 102 +#define GLUT_KEY_DOWN 103 +#define GLUT_KEY_PAGE_UP 104 +#define GLUT_KEY_PAGE_DOWN 105 +#define GLUT_KEY_HOME 106 +#define GLUT_KEY_END 107 +#define GLUT_KEY_INSERT 108 +#endif + +/* Entry/exit state. */ +#define GLUT_LEFT 0 +#define GLUT_ENTERED 1 + +/* Menu usage state. */ +#define GLUT_MENU_NOT_IN_USE 0 +#define GLUT_MENU_IN_USE 1 + +/* Visibility state. */ +#define GLUT_NOT_VISIBLE 0 +#define GLUT_VISIBLE 1 + +/* Window status state. */ +#define GLUT_HIDDEN 0 +#define GLUT_FULLY_RETAINED 1 +#define GLUT_PARTIALLY_RETAINED 2 +#define GLUT_FULLY_COVERED 3 + +/* Color index component selection values. */ +#define GLUT_RED 0 +#define GLUT_GREEN 1 +#define GLUT_BLUE 2 + +/* Layers for use. */ +#define GLUT_NORMAL 0 +#define GLUT_OVERLAY 1 + +#if defined(_WIN32) +/* Stroke font constants (use these in GLUT program). */ +#define GLUT_STROKE_ROMAN ((void*)0) +#define GLUT_STROKE_MONO_ROMAN ((void*)1) + +/* Bitmap font constants (use these in GLUT program). */ +#define GLUT_BITMAP_9_BY_15 ((void*)2) +#define GLUT_BITMAP_8_BY_13 ((void*)3) +#define GLUT_BITMAP_TIMES_ROMAN_10 ((void*)4) +#define GLUT_BITMAP_TIMES_ROMAN_24 ((void*)5) +#if (GLUT_API_VERSION >= 3) +#define GLUT_BITMAP_HELVETICA_10 ((void*)6) +#define GLUT_BITMAP_HELVETICA_12 ((void*)7) +#define GLUT_BITMAP_HELVETICA_18 ((void*)8) +#endif +#else +/* Stroke font opaque addresses (use constants instead in source code). */ +extern void *glutStrokeRoman; +extern void *glutStrokeMonoRoman; + +/* Stroke font constants (use these in GLUT program). */ +#define GLUT_STROKE_ROMAN (&glutStrokeRoman) +#define GLUT_STROKE_MONO_ROMAN (&glutStrokeMonoRoman) + +/* Bitmap font opaque addresses (use constants instead in source code). */ +extern void *glutBitmap9By15; +extern void *glutBitmap8By13; +extern void *glutBitmapTimesRoman10; +extern void *glutBitmapTimesRoman24; +extern void *glutBitmapHelvetica10; +extern void *glutBitmapHelvetica12; +extern void *glutBitmapHelvetica18; + +/* Bitmap font constants (use these in GLUT program). */ +#define GLUT_BITMAP_9_BY_15 (&glutBitmap9By15) +#define GLUT_BITMAP_8_BY_13 (&glutBitmap8By13) +#define GLUT_BITMAP_TIMES_ROMAN_10 (&glutBitmapTimesRoman10) +#define GLUT_BITMAP_TIMES_ROMAN_24 (&glutBitmapTimesRoman24) +#if (GLUT_API_VERSION >= 3) +#define GLUT_BITMAP_HELVETICA_10 (&glutBitmapHelvetica10) +#define GLUT_BITMAP_HELVETICA_12 (&glutBitmapHelvetica12) +#define GLUT_BITMAP_HELVETICA_18 (&glutBitmapHelvetica18) +#endif +#endif + +/* glutGet parameters. */ +#define GLUT_WINDOW_X 100 +#define GLUT_WINDOW_Y 101 +#define GLUT_WINDOW_WIDTH 102 +#define GLUT_WINDOW_HEIGHT 103 +#define GLUT_WINDOW_BUFFER_SIZE 104 +#define GLUT_WINDOW_STENCIL_SIZE 105 +#define GLUT_WINDOW_DEPTH_SIZE 106 +#define GLUT_WINDOW_RED_SIZE 107 +#define GLUT_WINDOW_GREEN_SIZE 108 +#define GLUT_WINDOW_BLUE_SIZE 109 +#define GLUT_WINDOW_ALPHA_SIZE 110 +#define GLUT_WINDOW_ACCUM_RED_SIZE 111 +#define GLUT_WINDOW_ACCUM_GREEN_SIZE 112 +#define GLUT_WINDOW_ACCUM_BLUE_SIZE 113 +#define GLUT_WINDOW_ACCUM_ALPHA_SIZE 114 +#define GLUT_WINDOW_DOUBLEBUFFER 115 +#define GLUT_WINDOW_RGBA 116 +#define GLUT_WINDOW_PARENT 117 +#define GLUT_WINDOW_NUM_CHILDREN 118 +#define GLUT_WINDOW_COLORMAP_SIZE 119 +#if (GLUT_API_VERSION >= 2) +#define GLUT_WINDOW_NUM_SAMPLES 120 +#define GLUT_WINDOW_STEREO 121 +#endif +#if (GLUT_API_VERSION >= 3) +#define GLUT_WINDOW_CURSOR 122 +#endif +#define GLUT_SCREEN_WIDTH 200 +#define GLUT_SCREEN_HEIGHT 201 +#define GLUT_SCREEN_WIDTH_MM 202 +#define GLUT_SCREEN_HEIGHT_MM 203 +#define GLUT_MENU_NUM_ITEMS 300 +#define GLUT_DISPLAY_MODE_POSSIBLE 400 +#define GLUT_INIT_WINDOW_X 500 +#define GLUT_INIT_WINDOW_Y 501 +#define GLUT_INIT_WINDOW_WIDTH 502 +#define GLUT_INIT_WINDOW_HEIGHT 503 +#define GLUT_INIT_DISPLAY_MODE 504 +#if (GLUT_API_VERSION >= 2) +#define GLUT_ELAPSED_TIME 700 +#endif +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13) +#define GLUT_WINDOW_FORMAT_ID 123 +#endif + +#if (GLUT_API_VERSION >= 2) +/* glutDeviceGet parameters. */ +#define GLUT_HAS_KEYBOARD 600 +#define GLUT_HAS_MOUSE 601 +#define GLUT_HAS_SPACEBALL 602 +#define GLUT_HAS_DIAL_AND_BUTTON_BOX 603 +#define GLUT_HAS_TABLET 604 +#define GLUT_NUM_MOUSE_BUTTONS 605 +#define GLUT_NUM_SPACEBALL_BUTTONS 606 +#define GLUT_NUM_BUTTON_BOX_BUTTONS 607 +#define GLUT_NUM_DIALS 608 +#define GLUT_NUM_TABLET_BUTTONS 609 +#endif +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13) +#define GLUT_DEVICE_IGNORE_KEY_REPEAT 610 +#define GLUT_DEVICE_KEY_REPEAT 611 +#define GLUT_HAS_JOYSTICK 612 +#define GLUT_OWNS_JOYSTICK 613 +#define GLUT_JOYSTICK_BUTTONS 614 +#define GLUT_JOYSTICK_AXES 615 +#define GLUT_JOYSTICK_POLL_RATE 616 +#endif + +#if (GLUT_API_VERSION >= 3) +/* glutLayerGet parameters. */ +#define GLUT_OVERLAY_POSSIBLE 800 +#define GLUT_LAYER_IN_USE 801 +#define GLUT_HAS_OVERLAY 802 +#define GLUT_TRANSPARENT_INDEX 803 +#define GLUT_NORMAL_DAMAGED 804 +#define GLUT_OVERLAY_DAMAGED 805 + +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +/* glutVideoResizeGet parameters. */ +#define GLUT_VIDEO_RESIZE_POSSIBLE 900 +#define GLUT_VIDEO_RESIZE_IN_USE 901 +#define GLUT_VIDEO_RESIZE_X_DELTA 902 +#define GLUT_VIDEO_RESIZE_Y_DELTA 903 +#define GLUT_VIDEO_RESIZE_WIDTH_DELTA 904 +#define GLUT_VIDEO_RESIZE_HEIGHT_DELTA 905 +#define GLUT_VIDEO_RESIZE_X 906 +#define GLUT_VIDEO_RESIZE_Y 907 +#define GLUT_VIDEO_RESIZE_WIDTH 908 +#define GLUT_VIDEO_RESIZE_HEIGHT 909 +#endif + +/* glutUseLayer parameters. */ +#define GLUT_NORMAL 0 +#define GLUT_OVERLAY 1 + +/* glutGetModifiers return mask. */ +#define GLUT_ACTIVE_SHIFT 1 +#define GLUT_ACTIVE_CTRL 2 +#define GLUT_ACTIVE_ALT 4 + +/* glutSetCursor parameters. */ +/* Basic arrows. */ +#define GLUT_CURSOR_RIGHT_ARROW 0 +#define GLUT_CURSOR_LEFT_ARROW 1 +/* Symbolic cursor shapes. */ +#define GLUT_CURSOR_INFO 2 +#define GLUT_CURSOR_DESTROY 3 +#define GLUT_CURSOR_HELP 4 +#define GLUT_CURSOR_CYCLE 5 +#define GLUT_CURSOR_SPRAY 6 +#define GLUT_CURSOR_WAIT 7 +#define GLUT_CURSOR_TEXT 8 +#define GLUT_CURSOR_CROSSHAIR 9 +/* Directional cursors. */ +#define GLUT_CURSOR_UP_DOWN 10 +#define GLUT_CURSOR_LEFT_RIGHT 11 +/* Sizing cursors. */ +#define GLUT_CURSOR_TOP_SIDE 12 +#define GLUT_CURSOR_BOTTOM_SIDE 13 +#define GLUT_CURSOR_LEFT_SIDE 14 +#define GLUT_CURSOR_RIGHT_SIDE 15 +#define GLUT_CURSOR_TOP_LEFT_CORNER 16 +#define GLUT_CURSOR_TOP_RIGHT_CORNER 17 +#define GLUT_CURSOR_BOTTOM_RIGHT_CORNER 18 +#define GLUT_CURSOR_BOTTOM_LEFT_CORNER 19 +/* Inherit from parent window. */ +#define GLUT_CURSOR_INHERIT 100 +/* Blank cursor. */ +#define GLUT_CURSOR_NONE 101 +/* Fullscreen crosshair (if available). */ +#define GLUT_CURSOR_FULL_CROSSHAIR 102 +#endif + +/* GLUT initialization sub-API. */ +extern void APIENTRY glutInit(int *argcp, char **argv); +extern void APIENTRY glutInitDisplayMode(unsigned int mode); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +extern void APIENTRY glutInitDisplayString(const char *string); +#endif +extern void APIENTRY glutInitWindowPosition(int x, int y); +extern void APIENTRY glutInitWindowSize(int width, int height); +extern void APIENTRY glutMainLoop(void); + +/* GLUT window sub-API. */ +extern int APIENTRY glutCreateWindow(const char *title); +extern int APIENTRY glutCreateSubWindow(int win, int x, int y, int width, int height); +extern void APIENTRY glutDestroyWindow(int win); +extern void APIENTRY glutPostRedisplay(void); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 11) +extern void APIENTRY glutPostWindowRedisplay(int win); +#endif +extern void APIENTRY glutSwapBuffers(void); +extern int APIENTRY glutGetWindow(void); +extern void APIENTRY glutSetWindow(int win); +extern void APIENTRY glutSetWindowTitle(const char *title); +extern void APIENTRY glutSetIconTitle(const char *title); +extern void APIENTRY glutPositionWindow(int x, int y); +extern void APIENTRY glutReshapeWindow(int width, int height); +extern void APIENTRY glutPopWindow(void); +extern void APIENTRY glutPushWindow(void); +extern void APIENTRY glutIconifyWindow(void); +extern void APIENTRY glutShowWindow(void); +extern void APIENTRY glutHideWindow(void); +#if (GLUT_API_VERSION >= 3) +extern void APIENTRY glutFullScreen(void); +extern void APIENTRY glutSetCursor(int cursor); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +extern void APIENTRY glutWarpPointer(int x, int y); +#endif + +/* GLUT overlay sub-API. */ +extern void APIENTRY glutEstablishOverlay(void); +extern void APIENTRY glutRemoveOverlay(void); +extern void APIENTRY glutUseLayer(GLenum layer); +extern void APIENTRY glutPostOverlayRedisplay(void); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 11) +extern void APIENTRY glutPostWindowOverlayRedisplay(int win); +#endif +extern void APIENTRY glutShowOverlay(void); +extern void APIENTRY glutHideOverlay(void); +#endif + +/* GLUT menu sub-API. */ +extern int APIENTRY glutCreateMenu(void (*)(int)); +extern void APIENTRY glutDestroyMenu(int menu); +extern int APIENTRY glutGetMenu(void); +extern void APIENTRY glutSetMenu(int menu); +extern void APIENTRY glutAddMenuEntry(const char *label, int value); +extern void APIENTRY glutAddSubMenu(const char *label, int submenu); +extern void APIENTRY glutChangeToMenuEntry(int item, const char *label, int value); +extern void APIENTRY glutChangeToSubMenu(int item, const char *label, int submenu); +extern void APIENTRY glutRemoveMenuItem(int item); +extern void APIENTRY glutAttachMenu(int button); +extern void APIENTRY glutDetachMenu(int button); + +/* GLUT window callback sub-API. */ +extern void APIENTRY glutDisplayFunc(void (*func)(void)); +extern void APIENTRY glutReshapeFunc(void (*func)(int width, int height)); +extern void APIENTRY glutKeyboardFunc(void (*func)(unsigned char key, int x, int y)); +extern void APIENTRY glutMouseFunc(void (*func)(int button, int state, int x, int y)); +extern void APIENTRY glutMotionFunc(void (*func)(int x, int y)); +extern void APIENTRY glutPassiveMotionFunc(void (*func)(int x, int y)); +extern void APIENTRY glutEntryFunc(void (*func)(int state)); +extern void APIENTRY glutVisibilityFunc(void (*func)(int state)); +extern void APIENTRY glutIdleFunc(void (*func)(void)); +extern void APIENTRY glutTimerFunc(unsigned int millis, void (*func)(int value), int value); +extern void APIENTRY glutMenuStateFunc(void (*func)(int state)); +#if (GLUT_API_VERSION >= 2) +extern void APIENTRY glutSpecialFunc(void (*func)(int key, int x, int y)); +extern void APIENTRY glutSpaceballMotionFunc(void (*func)(int x, int y, int z)); +extern void APIENTRY glutSpaceballRotateFunc(void (*func)(int x, int y, int z)); +extern void APIENTRY glutSpaceballButtonFunc(void (*func)(int button, int state)); +extern void APIENTRY glutButtonBoxFunc(void (*func)(int button, int state)); +extern void APIENTRY glutDialsFunc(void (*func)(int dial, int value)); +extern void APIENTRY glutTabletMotionFunc(void (*func)(int x, int y)); +extern void APIENTRY glutTabletButtonFunc(void (*func)(int button, int state, int x, int y)); +#if (GLUT_API_VERSION >= 3) +extern void APIENTRY glutMenuStatusFunc(void (*func)(int status, int x, int y)); +extern void APIENTRY glutOverlayDisplayFunc(void (*func)(void)); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +extern void APIENTRY glutWindowStatusFunc(void (*func)(int state)); +#endif +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13) +extern void APIENTRY glutKeyboardUpFunc(void (*func)(unsigned char key, int x, int y)); +extern void APIENTRY glutSpecialUpFunc(void (*func)(int key, int x, int y)); +extern void APIENTRY glutJoystickFunc(void (*func)(unsigned int buttonMask, int x, int y, int z), int pollInterval); +#endif +#endif +#endif + +/* GLUT color index sub-API. */ +extern void APIENTRY glutSetColor(int, GLfloat red, GLfloat green, GLfloat blue); +extern GLfloat APIENTRY glutGetColor(int ndx, int component); +extern void APIENTRY glutCopyColormap(int win); + +/* GLUT state retrieval sub-API. */ +extern int APIENTRY glutGet(GLenum type); +extern int APIENTRY glutDeviceGet(GLenum type); +#if (GLUT_API_VERSION >= 2) +/* GLUT extension support sub-API */ +extern int APIENTRY glutExtensionSupported(const char *name); +#endif +#if (GLUT_API_VERSION >= 3) +extern int APIENTRY glutGetModifiers(void); +extern int APIENTRY glutLayerGet(GLenum type); +#endif + +/* GLUT font sub-API */ +extern void APIENTRY glutBitmapCharacter(void *font, int character); +extern int APIENTRY glutBitmapWidth(void *font, int character); +extern void APIENTRY glutStrokeCharacter(void *font, int character); +extern int APIENTRY glutStrokeWidth(void *font, int character); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +extern int APIENTRY glutBitmapLength(void *font, const unsigned char *string); +extern int APIENTRY glutStrokeLength(void *font, const unsigned char *string); +#endif + +/* GLUT pre-built models sub-API */ +extern void APIENTRY glutWireSphere(GLdouble radius, GLint slices, GLint stacks); +extern void APIENTRY glutSolidSphere(GLdouble radius, GLint slices, GLint stacks); +extern void APIENTRY glutWireCone(GLdouble base, GLdouble height, GLint slices, GLint stacks); +extern void APIENTRY glutSolidCone(GLdouble base, GLdouble height, GLint slices, GLint stacks); +extern void APIENTRY glutWireCube(GLdouble size); +extern void APIENTRY glutSolidCube(GLdouble size); +extern void APIENTRY glutWireTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings); +extern void APIENTRY glutSolidTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings); +extern void APIENTRY glutWireDodecahedron(void); +extern void APIENTRY glutSolidDodecahedron(void); +extern void APIENTRY glutWireTeapot(GLdouble size); +extern void APIENTRY glutSolidTeapot(GLdouble size); +extern void APIENTRY glutWireOctahedron(void); +extern void APIENTRY glutSolidOctahedron(void); +extern void APIENTRY glutWireTetrahedron(void); +extern void APIENTRY glutSolidTetrahedron(void); +extern void APIENTRY glutWireIcosahedron(void); +extern void APIENTRY glutSolidIcosahedron(void); + +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +/* GLUT video resize sub-API. */ +extern int APIENTRY glutVideoResizeGet(GLenum param); +extern void APIENTRY glutSetupVideoResizing(void); +extern void APIENTRY glutStopVideoResizing(void); +extern void APIENTRY glutVideoResize(int x, int y, int width, int height); +extern void APIENTRY glutVideoPan(int x, int y, int width, int height); + +/* GLUT debugging sub-API. */ +extern void APIENTRY glutReportErrors(void); +#endif + +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13) +/* GLUT device control sub-API. */ +/* glutSetKeyRepeat modes. */ +#define GLUT_KEY_REPEAT_OFF 0 +#define GLUT_KEY_REPEAT_ON 1 +#define GLUT_KEY_REPEAT_DEFAULT 2 + +/* Joystick button masks. */ +#define GLUT_JOYSTICK_BUTTON_A 1 +#define GLUT_JOYSTICK_BUTTON_B 2 +#define GLUT_JOYSTICK_BUTTON_C 4 +#define GLUT_JOYSTICK_BUTTON_D 8 + +extern void APIENTRY glutIgnoreKeyRepeat(int ignore); +extern void APIENTRY glutSetKeyRepeat(int repeatMode); +extern void APIENTRY glutForceJoystickFunc(void); + +/* GLUT game mode sub-API. */ +/* glutGameModeGet. */ +#define GLUT_GAME_MODE_ACTIVE 0 +#define GLUT_GAME_MODE_POSSIBLE 1 +#define GLUT_GAME_MODE_WIDTH 2 +#define GLUT_GAME_MODE_HEIGHT 3 +#define GLUT_GAME_MODE_PIXEL_DEPTH 4 +#define GLUT_GAME_MODE_REFRESH_RATE 5 +#define GLUT_GAME_MODE_DISPLAY_CHANGED 6 + +extern void APIENTRY glutGameModeString(const char *string); +extern int APIENTRY glutEnterGameMode(void); +extern void APIENTRY glutLeaveGameMode(void); +extern int APIENTRY glutGameModeGet(GLenum mode); +#endif + +#ifdef __cplusplus +} + +#endif + +#ifdef GLUT_APIENTRY_DEFINED +# undef GLUT_APIENTRY_DEFINED +# undef APIENTRY +#endif + +#ifdef GLUT_WINGDIAPI_DEFINED +# undef GLUT_WINGDIAPI_DEFINED +# undef WINGDIAPI +#endif + +#endif /* __glut_h__ */ diff --git a/glut/glut_roman.c b/glut/glut_roman.c new file mode 100644 index 0000000..af2b4ec --- /dev/null +++ b/glut/glut_roman.c @@ -0,0 +1,2451 @@ + +/* GENERATED FILE -- DO NOT MODIFY */ + +#include "glutstroke.h" + +/* char: 33 '!' */ + +static const CoordRec char33_stroke0[] = { + { 13.3819, 100 }, + { 13.3819, 33.3333 }, +}; + +static const CoordRec char33_stroke1[] = { + { 13.3819, 9.5238 }, + { 8.62, 4.7619 }, + { 13.3819, 0 }, + { 18.1438, 4.7619 }, + { 13.3819, 9.5238 }, +}; + +static const StrokeRec char33[] = { + { 2, char33_stroke0 }, + { 5, char33_stroke1 }, +}; + +/* char: 34 '"' */ + +static const CoordRec char34_stroke0[] = { + { 4.02, 100 }, + { 4.02, 66.6667 }, +}; + +static const CoordRec char34_stroke1[] = { + { 42.1152, 100 }, + { 42.1152, 66.6667 }, +}; + +static const StrokeRec char34[] = { + { 2, char34_stroke0 }, + { 2, char34_stroke1 }, +}; + +/* char: 35 '#' */ + +static const CoordRec char35_stroke0[] = { + { 41.2952, 119.048 }, + { 7.9619, -33.3333 }, +}; + +static const CoordRec char35_stroke1[] = { + { 69.8667, 119.048 }, + { 36.5333, -33.3333 }, +}; + +static const CoordRec char35_stroke2[] = { + { 7.9619, 57.1429 }, + { 74.6286, 57.1429 }, +}; + +static const CoordRec char35_stroke3[] = { + { 3.2, 28.5714 }, + { 69.8667, 28.5714 }, +}; + +static const StrokeRec char35[] = { + { 2, char35_stroke0 }, + { 2, char35_stroke1 }, + { 2, char35_stroke2 }, + { 2, char35_stroke3 }, +}; + +/* char: 36 '$' */ + +static const CoordRec char36_stroke0[] = { + { 28.6295, 119.048 }, + { 28.6295, -19.0476 }, +}; + +static const CoordRec char36_stroke1[] = { + { 47.6771, 119.048 }, + { 47.6771, -19.0476 }, +}; + +static const CoordRec char36_stroke2[] = { + { 71.4867, 85.7143 }, + { 61.9629, 95.2381 }, + { 47.6771, 100 }, + { 28.6295, 100 }, + { 14.3438, 95.2381 }, + { 4.82, 85.7143 }, + { 4.82, 76.1905 }, + { 9.5819, 66.6667 }, + { 14.3438, 61.9048 }, + { 23.8676, 57.1429 }, + { 52.439, 47.619 }, + { 61.9629, 42.8571 }, + { 66.7248, 38.0952 }, + { 71.4867, 28.5714 }, + { 71.4867, 14.2857 }, + { 61.9629, 4.7619 }, + { 47.6771, 0 }, + { 28.6295, 0 }, + { 14.3438, 4.7619 }, + { 4.82, 14.2857 }, +}; + +static const StrokeRec char36[] = { + { 2, char36_stroke0 }, + { 2, char36_stroke1 }, + { 20, char36_stroke2 }, +}; + +/* char: 37 '%' */ + +static const CoordRec char37_stroke0[] = { + { 92.0743, 100 }, + { 6.36, 0 }, +}; + +static const CoordRec char37_stroke1[] = { + { 30.1695, 100 }, + { 39.6933, 90.4762 }, + { 39.6933, 80.9524 }, + { 34.9314, 71.4286 }, + { 25.4076, 66.6667 }, + { 15.8838, 66.6667 }, + { 6.36, 76.1905 }, + { 6.36, 85.7143 }, + { 11.1219, 95.2381 }, + { 20.6457, 100 }, + { 30.1695, 100 }, + { 39.6933, 95.2381 }, + { 53.979, 90.4762 }, + { 68.2648, 90.4762 }, + { 82.5505, 95.2381 }, + { 92.0743, 100 }, +}; + +static const CoordRec char37_stroke2[] = { + { 73.0267, 33.3333 }, + { 63.5029, 28.5714 }, + { 58.741, 19.0476 }, + { 58.741, 9.5238 }, + { 68.2648, 0 }, + { 77.7886, 0 }, + { 87.3124, 4.7619 }, + { 92.0743, 14.2857 }, + { 92.0743, 23.8095 }, + { 82.5505, 33.3333 }, + { 73.0267, 33.3333 }, +}; + +static const StrokeRec char37[] = { + { 2, char37_stroke0 }, + { 16, char37_stroke1 }, + { 11, char37_stroke2 }, +}; + +/* char: 38 '&' */ + +static const CoordRec char38_stroke0[] = { + { 101.218, 57.1429 }, + { 101.218, 61.9048 }, + { 96.4562, 66.6667 }, + { 91.6943, 66.6667 }, + { 86.9324, 61.9048 }, + { 82.1705, 52.381 }, + { 72.6467, 28.5714 }, + { 63.1229, 14.2857 }, + { 53.599, 4.7619 }, + { 44.0752, 0 }, + { 25.0276, 0 }, + { 15.5038, 4.7619 }, + { 10.7419, 9.5238 }, + { 5.98, 19.0476 }, + { 5.98, 28.5714 }, + { 10.7419, 38.0952 }, + { 15.5038, 42.8571 }, + { 48.8371, 61.9048 }, + { 53.599, 66.6667 }, + { 58.361, 76.1905 }, + { 58.361, 85.7143 }, + { 53.599, 95.2381 }, + { 44.0752, 100 }, + { 34.5514, 95.2381 }, + { 29.7895, 85.7143 }, + { 29.7895, 76.1905 }, + { 34.5514, 61.9048 }, + { 44.0752, 47.619 }, + { 67.8848, 14.2857 }, + { 77.4086, 4.7619 }, + { 86.9324, 0 }, + { 96.4562, 0 }, + { 101.218, 4.7619 }, + { 101.218, 9.5238 }, +}; + +static const StrokeRec char38[] = { + { 34, char38_stroke0 }, +}; + +/* char: 39 ''' */ + +static const CoordRec char39_stroke0[] = { + { 4.44, 100 }, + { 4.44, 66.6667 }, +}; + +static const StrokeRec char39[] = { + { 2, char39_stroke0 }, +}; + +/* char: 40 '(' */ + +static const CoordRec char40_stroke0[] = { + { 40.9133, 119.048 }, + { 31.3895, 109.524 }, + { 21.8657, 95.2381 }, + { 12.3419, 76.1905 }, + { 7.58, 52.381 }, + { 7.58, 33.3333 }, + { 12.3419, 9.5238 }, + { 21.8657, -9.5238 }, + { 31.3895, -23.8095 }, + { 40.9133, -33.3333 }, +}; + +static const StrokeRec char40[] = { + { 10, char40_stroke0 }, +}; + +/* char: 41 ')' */ + +static const CoordRec char41_stroke0[] = { + { 5.28, 119.048 }, + { 14.8038, 109.524 }, + { 24.3276, 95.2381 }, + { 33.8514, 76.1905 }, + { 38.6133, 52.381 }, + { 38.6133, 33.3333 }, + { 33.8514, 9.5238 }, + { 24.3276, -9.5238 }, + { 14.8038, -23.8095 }, + { 5.28, -33.3333 }, +}; + +static const StrokeRec char41[] = { + { 10, char41_stroke0 }, +}; + +/* char: 42 '*' */ + +static const CoordRec char42_stroke0[] = { + { 30.7695, 71.4286 }, + { 30.7695, 14.2857 }, +}; + +static const CoordRec char42_stroke1[] = { + { 6.96, 57.1429 }, + { 54.579, 28.5714 }, +}; + +static const CoordRec char42_stroke2[] = { + { 54.579, 57.1429 }, + { 6.96, 28.5714 }, +}; + +static const StrokeRec char42[] = { + { 2, char42_stroke0 }, + { 2, char42_stroke1 }, + { 2, char42_stroke2 }, +}; + +/* char: 43 '+' */ + +static const CoordRec char43_stroke0[] = { + { 48.8371, 85.7143 }, + { 48.8371, 0 }, +}; + +static const CoordRec char43_stroke1[] = { + { 5.98, 42.8571 }, + { 91.6943, 42.8571 }, +}; + +static const StrokeRec char43[] = { + { 2, char43_stroke0 }, + { 2, char43_stroke1 }, +}; + +/* char: 44 ',' */ + +static const CoordRec char44_stroke0[] = { + { 18.2838, 4.7619 }, + { 13.5219, 0 }, + { 8.76, 4.7619 }, + { 13.5219, 9.5238 }, + { 18.2838, 4.7619 }, + { 18.2838, -4.7619 }, + { 13.5219, -14.2857 }, + { 8.76, -19.0476 }, +}; + +static const StrokeRec char44[] = { + { 8, char44_stroke0 }, +}; + +/* char: 45 '-' */ + +static const CoordRec char45_stroke0[] = { + { 7.38, 42.8571 }, + { 93.0943, 42.8571 }, +}; + +static const StrokeRec char45[] = { + { 2, char45_stroke0 }, +}; + +/* char: 46 '.' */ + +static const CoordRec char46_stroke0[] = { + { 13.1019, 9.5238 }, + { 8.34, 4.7619 }, + { 13.1019, 0 }, + { 17.8638, 4.7619 }, + { 13.1019, 9.5238 }, +}; + +static const StrokeRec char46[] = { + { 5, char46_stroke0 }, +}; + +/* char: 47 '/' */ + +static const CoordRec char47_stroke0[] = { + { 7.24, -14.2857 }, + { 73.9067, 100 }, +}; + +static const StrokeRec char47[] = { + { 2, char47_stroke0 }, +}; + +/* char: 48 '0' */ + +static const CoordRec char48_stroke0[] = { + { 33.5514, 100 }, + { 19.2657, 95.2381 }, + { 9.7419, 80.9524 }, + { 4.98, 57.1429 }, + { 4.98, 42.8571 }, + { 9.7419, 19.0476 }, + { 19.2657, 4.7619 }, + { 33.5514, 0 }, + { 43.0752, 0 }, + { 57.361, 4.7619 }, + { 66.8848, 19.0476 }, + { 71.6467, 42.8571 }, + { 71.6467, 57.1429 }, + { 66.8848, 80.9524 }, + { 57.361, 95.2381 }, + { 43.0752, 100 }, + { 33.5514, 100 }, +}; + +static const StrokeRec char48[] = { + { 17, char48_stroke0 }, +}; + +/* char: 49 '1' */ + +static const CoordRec char49_stroke0[] = { + { 11.82, 80.9524 }, + { 21.3438, 85.7143 }, + { 35.6295, 100 }, + { 35.6295, 0 }, +}; + +static const StrokeRec char49[] = { + { 4, char49_stroke0 }, +}; + +/* char: 50 '2' */ + +static const CoordRec char50_stroke0[] = { + { 10.1819, 76.1905 }, + { 10.1819, 80.9524 }, + { 14.9438, 90.4762 }, + { 19.7057, 95.2381 }, + { 29.2295, 100 }, + { 48.2771, 100 }, + { 57.801, 95.2381 }, + { 62.5629, 90.4762 }, + { 67.3248, 80.9524 }, + { 67.3248, 71.4286 }, + { 62.5629, 61.9048 }, + { 53.039, 47.619 }, + { 5.42, 0 }, + { 72.0867, 0 }, +}; + +static const StrokeRec char50[] = { + { 14, char50_stroke0 }, +}; + +/* char: 51 '3' */ + +static const CoordRec char51_stroke0[] = { + { 14.5238, 100 }, + { 66.9048, 100 }, + { 38.3333, 61.9048 }, + { 52.619, 61.9048 }, + { 62.1429, 57.1429 }, + { 66.9048, 52.381 }, + { 71.6667, 38.0952 }, + { 71.6667, 28.5714 }, + { 66.9048, 14.2857 }, + { 57.381, 4.7619 }, + { 43.0952, 0 }, + { 28.8095, 0 }, + { 14.5238, 4.7619 }, + { 9.7619, 9.5238 }, + { 5, 19.0476 }, +}; + +static const StrokeRec char51[] = { + { 15, char51_stroke0 }, +}; + +/* char: 52 '4' */ + +static const CoordRec char52_stroke0[] = { + { 51.499, 100 }, + { 3.88, 33.3333 }, + { 75.3086, 33.3333 }, +}; + +static const CoordRec char52_stroke1[] = { + { 51.499, 100 }, + { 51.499, 0 }, +}; + +static const StrokeRec char52[] = { + { 3, char52_stroke0 }, + { 2, char52_stroke1 }, +}; + +/* char: 53 '5' */ + +static const CoordRec char53_stroke0[] = { + { 62.0029, 100 }, + { 14.3838, 100 }, + { 9.6219, 57.1429 }, + { 14.3838, 61.9048 }, + { 28.6695, 66.6667 }, + { 42.9552, 66.6667 }, + { 57.241, 61.9048 }, + { 66.7648, 52.381 }, + { 71.5267, 38.0952 }, + { 71.5267, 28.5714 }, + { 66.7648, 14.2857 }, + { 57.241, 4.7619 }, + { 42.9552, 0 }, + { 28.6695, 0 }, + { 14.3838, 4.7619 }, + { 9.6219, 9.5238 }, + { 4.86, 19.0476 }, +}; + +static const StrokeRec char53[] = { + { 17, char53_stroke0 }, +}; + +/* char: 54 '6' */ + +static const CoordRec char54_stroke0[] = { + { 62.7229, 85.7143 }, + { 57.961, 95.2381 }, + { 43.6752, 100 }, + { 34.1514, 100 }, + { 19.8657, 95.2381 }, + { 10.3419, 80.9524 }, + { 5.58, 57.1429 }, + { 5.58, 33.3333 }, + { 10.3419, 14.2857 }, + { 19.8657, 4.7619 }, + { 34.1514, 0 }, + { 38.9133, 0 }, + { 53.199, 4.7619 }, + { 62.7229, 14.2857 }, + { 67.4848, 28.5714 }, + { 67.4848, 33.3333 }, + { 62.7229, 47.619 }, + { 53.199, 57.1429 }, + { 38.9133, 61.9048 }, + { 34.1514, 61.9048 }, + { 19.8657, 57.1429 }, + { 10.3419, 47.619 }, + { 5.58, 33.3333 }, +}; + +static const StrokeRec char54[] = { + { 23, char54_stroke0 }, +}; + +/* char: 55 '7' */ + +static const CoordRec char55_stroke0[] = { + { 72.2267, 100 }, + { 24.6076, 0 }, +}; + +static const CoordRec char55_stroke1[] = { + { 5.56, 100 }, + { 72.2267, 100 }, +}; + +static const StrokeRec char55[] = { + { 2, char55_stroke0 }, + { 2, char55_stroke1 }, +}; + +/* char: 56 '8' */ + +static const CoordRec char56_stroke0[] = { + { 29.4095, 100 }, + { 15.1238, 95.2381 }, + { 10.3619, 85.7143 }, + { 10.3619, 76.1905 }, + { 15.1238, 66.6667 }, + { 24.6476, 61.9048 }, + { 43.6952, 57.1429 }, + { 57.981, 52.381 }, + { 67.5048, 42.8571 }, + { 72.2667, 33.3333 }, + { 72.2667, 19.0476 }, + { 67.5048, 9.5238 }, + { 62.7429, 4.7619 }, + { 48.4571, 0 }, + { 29.4095, 0 }, + { 15.1238, 4.7619 }, + { 10.3619, 9.5238 }, + { 5.6, 19.0476 }, + { 5.6, 33.3333 }, + { 10.3619, 42.8571 }, + { 19.8857, 52.381 }, + { 34.1714, 57.1429 }, + { 53.219, 61.9048 }, + { 62.7429, 66.6667 }, + { 67.5048, 76.1905 }, + { 67.5048, 85.7143 }, + { 62.7429, 95.2381 }, + { 48.4571, 100 }, + { 29.4095, 100 }, +}; + +static const StrokeRec char56[] = { + { 29, char56_stroke0 }, +}; + +/* char: 57 '9' */ + +static const CoordRec char57_stroke0[] = { + { 68.5048, 66.6667 }, + { 63.7429, 52.381 }, + { 54.219, 42.8571 }, + { 39.9333, 38.0952 }, + { 35.1714, 38.0952 }, + { 20.8857, 42.8571 }, + { 11.3619, 52.381 }, + { 6.6, 66.6667 }, + { 6.6, 71.4286 }, + { 11.3619, 85.7143 }, + { 20.8857, 95.2381 }, + { 35.1714, 100 }, + { 39.9333, 100 }, + { 54.219, 95.2381 }, + { 63.7429, 85.7143 }, + { 68.5048, 66.6667 }, + { 68.5048, 42.8571 }, + { 63.7429, 19.0476 }, + { 54.219, 4.7619 }, + { 39.9333, 0 }, + { 30.4095, 0 }, + { 16.1238, 4.7619 }, + { 11.3619, 14.2857 }, +}; + +static const StrokeRec char57[] = { + { 23, char57_stroke0 }, +}; + +/* char: 58 ':' */ + +static const CoordRec char58_stroke0[] = { + { 14.0819, 66.6667 }, + { 9.32, 61.9048 }, + { 14.0819, 57.1429 }, + { 18.8438, 61.9048 }, + { 14.0819, 66.6667 }, +}; + +static const CoordRec char58_stroke1[] = { + { 14.0819, 9.5238 }, + { 9.32, 4.7619 }, + { 14.0819, 0 }, + { 18.8438, 4.7619 }, + { 14.0819, 9.5238 }, +}; + +static const StrokeRec char58[] = { + { 5, char58_stroke0 }, + { 5, char58_stroke1 }, +}; + +/* char: 59 ';' */ + +static const CoordRec char59_stroke0[] = { + { 12.9619, 66.6667 }, + { 8.2, 61.9048 }, + { 12.9619, 57.1429 }, + { 17.7238, 61.9048 }, + { 12.9619, 66.6667 }, +}; + +static const CoordRec char59_stroke1[] = { + { 17.7238, 4.7619 }, + { 12.9619, 0 }, + { 8.2, 4.7619 }, + { 12.9619, 9.5238 }, + { 17.7238, 4.7619 }, + { 17.7238, -4.7619 }, + { 12.9619, -14.2857 }, + { 8.2, -19.0476 }, +}; + +static const StrokeRec char59[] = { + { 5, char59_stroke0 }, + { 8, char59_stroke1 }, +}; + +/* char: 60 '<' */ + +static const CoordRec char60_stroke0[] = { + { 79.2505, 85.7143 }, + { 3.06, 42.8571 }, + { 79.2505, 0 }, +}; + +static const StrokeRec char60[] = { + { 3, char60_stroke0 }, +}; + +/* char: 61 '=' */ + +static const CoordRec char61_stroke0[] = { + { 5.7, 57.1429 }, + { 91.4143, 57.1429 }, +}; + +static const CoordRec char61_stroke1[] = { + { 5.7, 28.5714 }, + { 91.4143, 28.5714 }, +}; + +static const StrokeRec char61[] = { + { 2, char61_stroke0 }, + { 2, char61_stroke1 }, +}; + +/* char: 62 '>' */ + +static const CoordRec char62_stroke0[] = { + { 2.78, 85.7143 }, + { 78.9705, 42.8571 }, + { 2.78, 0 }, +}; + +static const StrokeRec char62[] = { + { 3, char62_stroke0 }, +}; + +/* char: 63 '?' */ + +static const CoordRec char63_stroke0[] = { + { 8.42, 76.1905 }, + { 8.42, 80.9524 }, + { 13.1819, 90.4762 }, + { 17.9438, 95.2381 }, + { 27.4676, 100 }, + { 46.5152, 100 }, + { 56.039, 95.2381 }, + { 60.801, 90.4762 }, + { 65.5629, 80.9524 }, + { 65.5629, 71.4286 }, + { 60.801, 61.9048 }, + { 56.039, 57.1429 }, + { 36.9914, 47.619 }, + { 36.9914, 33.3333 }, +}; + +static const CoordRec char63_stroke1[] = { + { 36.9914, 9.5238 }, + { 32.2295, 4.7619 }, + { 36.9914, 0 }, + { 41.7533, 4.7619 }, + { 36.9914, 9.5238 }, +}; + +static const StrokeRec char63[] = { + { 14, char63_stroke0 }, + { 5, char63_stroke1 }, +}; + +/* char: 64 '@' */ + +static const CoordRec char64_stroke0[] = { + { 49.2171, 52.381 }, + { 39.6933, 57.1429 }, + { 30.1695, 57.1429 }, + { 25.4076, 47.619 }, + { 25.4076, 42.8571 }, + { 30.1695, 33.3333 }, + { 39.6933, 33.3333 }, + { 49.2171, 38.0952 }, +}; + +static const CoordRec char64_stroke1[] = { + { 49.2171, 57.1429 }, + { 49.2171, 38.0952 }, + { 53.979, 33.3333 }, + { 63.5029, 33.3333 }, + { 68.2648, 42.8571 }, + { 68.2648, 47.619 }, + { 63.5029, 61.9048 }, + { 53.979, 71.4286 }, + { 39.6933, 76.1905 }, + { 34.9314, 76.1905 }, + { 20.6457, 71.4286 }, + { 11.1219, 61.9048 }, + { 6.36, 47.619 }, + { 6.36, 42.8571 }, + { 11.1219, 28.5714 }, + { 20.6457, 19.0476 }, + { 34.9314, 14.2857 }, + { 39.6933, 14.2857 }, + { 53.979, 19.0476 }, +}; + +static const StrokeRec char64[] = { + { 8, char64_stroke0 }, + { 19, char64_stroke1 }, +}; + +/* char: 65 'A' */ + +static const CoordRec char65_stroke0[] = { + { 40.5952, 100 }, + { 2.5, 0 }, +}; + +static const CoordRec char65_stroke1[] = { + { 40.5952, 100 }, + { 78.6905, 0 }, +}; + +static const CoordRec char65_stroke2[] = { + { 16.7857, 33.3333 }, + { 64.4048, 33.3333 }, +}; + +static const StrokeRec char65[] = { + { 2, char65_stroke0 }, + { 2, char65_stroke1 }, + { 2, char65_stroke2 }, +}; + +/* char: 66 'B' */ + +static const CoordRec char66_stroke0[] = { + { 11.42, 100 }, + { 11.42, 0 }, +}; + +static const CoordRec char66_stroke1[] = { + { 11.42, 100 }, + { 54.2771, 100 }, + { 68.5629, 95.2381 }, + { 73.3248, 90.4762 }, + { 78.0867, 80.9524 }, + { 78.0867, 71.4286 }, + { 73.3248, 61.9048 }, + { 68.5629, 57.1429 }, + { 54.2771, 52.381 }, +}; + +static const CoordRec char66_stroke2[] = { + { 11.42, 52.381 }, + { 54.2771, 52.381 }, + { 68.5629, 47.619 }, + { 73.3248, 42.8571 }, + { 78.0867, 33.3333 }, + { 78.0867, 19.0476 }, + { 73.3248, 9.5238 }, + { 68.5629, 4.7619 }, + { 54.2771, 0 }, + { 11.42, 0 }, +}; + +static const StrokeRec char66[] = { + { 2, char66_stroke0 }, + { 9, char66_stroke1 }, + { 10, char66_stroke2 }, +}; + +/* char: 67 'C' */ + +static const CoordRec char67_stroke0[] = { + { 78.0886, 76.1905 }, + { 73.3267, 85.7143 }, + { 63.8029, 95.2381 }, + { 54.279, 100 }, + { 35.2314, 100 }, + { 25.7076, 95.2381 }, + { 16.1838, 85.7143 }, + { 11.4219, 76.1905 }, + { 6.66, 61.9048 }, + { 6.66, 38.0952 }, + { 11.4219, 23.8095 }, + { 16.1838, 14.2857 }, + { 25.7076, 4.7619 }, + { 35.2314, 0 }, + { 54.279, 0 }, + { 63.8029, 4.7619 }, + { 73.3267, 14.2857 }, + { 78.0886, 23.8095 }, +}; + +static const StrokeRec char67[] = { + { 18, char67_stroke0 }, +}; + +/* char: 68 'D' */ + +static const CoordRec char68_stroke0[] = { + { 11.96, 100 }, + { 11.96, 0 }, +}; + +static const CoordRec char68_stroke1[] = { + { 11.96, 100 }, + { 45.2933, 100 }, + { 59.579, 95.2381 }, + { 69.1029, 85.7143 }, + { 73.8648, 76.1905 }, + { 78.6267, 61.9048 }, + { 78.6267, 38.0952 }, + { 73.8648, 23.8095 }, + { 69.1029, 14.2857 }, + { 59.579, 4.7619 }, + { 45.2933, 0 }, + { 11.96, 0 }, +}; + +static const StrokeRec char68[] = { + { 2, char68_stroke0 }, + { 12, char68_stroke1 }, +}; + +/* char: 69 'E' */ + +static const CoordRec char69_stroke0[] = { + { 11.42, 100 }, + { 11.42, 0 }, +}; + +static const CoordRec char69_stroke1[] = { + { 11.42, 100 }, + { 73.3248, 100 }, +}; + +static const CoordRec char69_stroke2[] = { + { 11.42, 52.381 }, + { 49.5152, 52.381 }, +}; + +static const CoordRec char69_stroke3[] = { + { 11.42, 0 }, + { 73.3248, 0 }, +}; + +static const StrokeRec char69[] = { + { 2, char69_stroke0 }, + { 2, char69_stroke1 }, + { 2, char69_stroke2 }, + { 2, char69_stroke3 }, +}; + +/* char: 70 'F' */ + +static const CoordRec char70_stroke0[] = { + { 11.42, 100 }, + { 11.42, 0 }, +}; + +static const CoordRec char70_stroke1[] = { + { 11.42, 100 }, + { 73.3248, 100 }, +}; + +static const CoordRec char70_stroke2[] = { + { 11.42, 52.381 }, + { 49.5152, 52.381 }, +}; + +static const StrokeRec char70[] = { + { 2, char70_stroke0 }, + { 2, char70_stroke1 }, + { 2, char70_stroke2 }, +}; + +/* char: 71 'G' */ + +static const CoordRec char71_stroke0[] = { + { 78.4886, 76.1905 }, + { 73.7267, 85.7143 }, + { 64.2029, 95.2381 }, + { 54.679, 100 }, + { 35.6314, 100 }, + { 26.1076, 95.2381 }, + { 16.5838, 85.7143 }, + { 11.8219, 76.1905 }, + { 7.06, 61.9048 }, + { 7.06, 38.0952 }, + { 11.8219, 23.8095 }, + { 16.5838, 14.2857 }, + { 26.1076, 4.7619 }, + { 35.6314, 0 }, + { 54.679, 0 }, + { 64.2029, 4.7619 }, + { 73.7267, 14.2857 }, + { 78.4886, 23.8095 }, + { 78.4886, 38.0952 }, +}; + +static const CoordRec char71_stroke1[] = { + { 54.679, 38.0952 }, + { 78.4886, 38.0952 }, +}; + +static const StrokeRec char71[] = { + { 19, char71_stroke0 }, + { 2, char71_stroke1 }, +}; + +/* char: 72 'H' */ + +static const CoordRec char72_stroke0[] = { + { 11.42, 100 }, + { 11.42, 0 }, +}; + +static const CoordRec char72_stroke1[] = { + { 78.0867, 100 }, + { 78.0867, 0 }, +}; + +static const CoordRec char72_stroke2[] = { + { 11.42, 52.381 }, + { 78.0867, 52.381 }, +}; + +static const StrokeRec char72[] = { + { 2, char72_stroke0 }, + { 2, char72_stroke1 }, + { 2, char72_stroke2 }, +}; + +/* char: 73 'I' */ + +static const CoordRec char73_stroke0[] = { + { 10.86, 100 }, + { 10.86, 0 }, +}; + +static const StrokeRec char73[] = { + { 2, char73_stroke0 }, +}; + +/* char: 74 'J' */ + +static const CoordRec char74_stroke0[] = { + { 50.119, 100 }, + { 50.119, 23.8095 }, + { 45.3571, 9.5238 }, + { 40.5952, 4.7619 }, + { 31.0714, 0 }, + { 21.5476, 0 }, + { 12.0238, 4.7619 }, + { 7.2619, 9.5238 }, + { 2.5, 23.8095 }, + { 2.5, 33.3333 }, +}; + +static const StrokeRec char74[] = { + { 10, char74_stroke0 }, +}; + +/* char: 75 'K' */ + +static const CoordRec char75_stroke0[] = { + { 11.28, 100 }, + { 11.28, 0 }, +}; + +static const CoordRec char75_stroke1[] = { + { 77.9467, 100 }, + { 11.28, 33.3333 }, +}; + +static const CoordRec char75_stroke2[] = { + { 35.0895, 57.1429 }, + { 77.9467, 0 }, +}; + +static const StrokeRec char75[] = { + { 2, char75_stroke0 }, + { 2, char75_stroke1 }, + { 2, char75_stroke2 }, +}; + +/* char: 76 'L' */ + +static const CoordRec char76_stroke0[] = { + { 11.68, 100 }, + { 11.68, 0 }, +}; + +static const CoordRec char76_stroke1[] = { + { 11.68, 0 }, + { 68.8229, 0 }, +}; + +static const StrokeRec char76[] = { + { 2, char76_stroke0 }, + { 2, char76_stroke1 }, +}; + +/* char: 77 'M' */ + +static const CoordRec char77_stroke0[] = { + { 10.86, 100 }, + { 10.86, 0 }, +}; + +static const CoordRec char77_stroke1[] = { + { 10.86, 100 }, + { 48.9552, 0 }, +}; + +static const CoordRec char77_stroke2[] = { + { 87.0505, 100 }, + { 48.9552, 0 }, +}; + +static const CoordRec char77_stroke3[] = { + { 87.0505, 100 }, + { 87.0505, 0 }, +}; + +static const StrokeRec char77[] = { + { 2, char77_stroke0 }, + { 2, char77_stroke1 }, + { 2, char77_stroke2 }, + { 2, char77_stroke3 }, +}; + +/* char: 78 'N' */ + +static const CoordRec char78_stroke0[] = { + { 11.14, 100 }, + { 11.14, 0 }, +}; + +static const CoordRec char78_stroke1[] = { + { 11.14, 100 }, + { 77.8067, 0 }, +}; + +static const CoordRec char78_stroke2[] = { + { 77.8067, 100 }, + { 77.8067, 0 }, +}; + +static const StrokeRec char78[] = { + { 2, char78_stroke0 }, + { 2, char78_stroke1 }, + { 2, char78_stroke2 }, +}; + +/* char: 79 'O' */ + +static const CoordRec char79_stroke0[] = { + { 34.8114, 100 }, + { 25.2876, 95.2381 }, + { 15.7638, 85.7143 }, + { 11.0019, 76.1905 }, + { 6.24, 61.9048 }, + { 6.24, 38.0952 }, + { 11.0019, 23.8095 }, + { 15.7638, 14.2857 }, + { 25.2876, 4.7619 }, + { 34.8114, 0 }, + { 53.859, 0 }, + { 63.3829, 4.7619 }, + { 72.9067, 14.2857 }, + { 77.6686, 23.8095 }, + { 82.4305, 38.0952 }, + { 82.4305, 61.9048 }, + { 77.6686, 76.1905 }, + { 72.9067, 85.7143 }, + { 63.3829, 95.2381 }, + { 53.859, 100 }, + { 34.8114, 100 }, +}; + +static const StrokeRec char79[] = { + { 21, char79_stroke0 }, +}; + +/* char: 80 'P' */ + +static const CoordRec char80_stroke0[] = { + { 12.1, 100 }, + { 12.1, 0 }, +}; + +static const CoordRec char80_stroke1[] = { + { 12.1, 100 }, + { 54.9571, 100 }, + { 69.2429, 95.2381 }, + { 74.0048, 90.4762 }, + { 78.7667, 80.9524 }, + { 78.7667, 66.6667 }, + { 74.0048, 57.1429 }, + { 69.2429, 52.381 }, + { 54.9571, 47.619 }, + { 12.1, 47.619 }, +}; + +static const StrokeRec char80[] = { + { 2, char80_stroke0 }, + { 10, char80_stroke1 }, +}; + +/* char: 81 'Q' */ + +static const CoordRec char81_stroke0[] = { + { 33.8714, 100 }, + { 24.3476, 95.2381 }, + { 14.8238, 85.7143 }, + { 10.0619, 76.1905 }, + { 5.3, 61.9048 }, + { 5.3, 38.0952 }, + { 10.0619, 23.8095 }, + { 14.8238, 14.2857 }, + { 24.3476, 4.7619 }, + { 33.8714, 0 }, + { 52.919, 0 }, + { 62.4429, 4.7619 }, + { 71.9667, 14.2857 }, + { 76.7286, 23.8095 }, + { 81.4905, 38.0952 }, + { 81.4905, 61.9048 }, + { 76.7286, 76.1905 }, + { 71.9667, 85.7143 }, + { 62.4429, 95.2381 }, + { 52.919, 100 }, + { 33.8714, 100 }, +}; + +static const CoordRec char81_stroke1[] = { + { 48.1571, 19.0476 }, + { 76.7286, -9.5238 }, +}; + +static const StrokeRec char81[] = { + { 21, char81_stroke0 }, + { 2, char81_stroke1 }, +}; + +/* char: 82 'R' */ + +static const CoordRec char82_stroke0[] = { + { 11.68, 100 }, + { 11.68, 0 }, +}; + +static const CoordRec char82_stroke1[] = { + { 11.68, 100 }, + { 54.5371, 100 }, + { 68.8229, 95.2381 }, + { 73.5848, 90.4762 }, + { 78.3467, 80.9524 }, + { 78.3467, 71.4286 }, + { 73.5848, 61.9048 }, + { 68.8229, 57.1429 }, + { 54.5371, 52.381 }, + { 11.68, 52.381 }, +}; + +static const CoordRec char82_stroke2[] = { + { 45.0133, 52.381 }, + { 78.3467, 0 }, +}; + +static const StrokeRec char82[] = { + { 2, char82_stroke0 }, + { 10, char82_stroke1 }, + { 2, char82_stroke2 }, +}; + +/* char: 83 'S' */ + +static const CoordRec char83_stroke0[] = { + { 74.6667, 85.7143 }, + { 65.1429, 95.2381 }, + { 50.8571, 100 }, + { 31.8095, 100 }, + { 17.5238, 95.2381 }, + { 8, 85.7143 }, + { 8, 76.1905 }, + { 12.7619, 66.6667 }, + { 17.5238, 61.9048 }, + { 27.0476, 57.1429 }, + { 55.619, 47.619 }, + { 65.1429, 42.8571 }, + { 69.9048, 38.0952 }, + { 74.6667, 28.5714 }, + { 74.6667, 14.2857 }, + { 65.1429, 4.7619 }, + { 50.8571, 0 }, + { 31.8095, 0 }, + { 17.5238, 4.7619 }, + { 8, 14.2857 }, +}; + +static const StrokeRec char83[] = { + { 20, char83_stroke0 }, +}; + +/* char: 84 'T' */ + +static const CoordRec char84_stroke0[] = { + { 35.6933, 100 }, + { 35.6933, 0 }, +}; + +static const CoordRec char84_stroke1[] = { + { 2.36, 100 }, + { 69.0267, 100 }, +}; + +static const StrokeRec char84[] = { + { 2, char84_stroke0 }, + { 2, char84_stroke1 }, +}; + +/* char: 85 'U' */ + +static const CoordRec char85_stroke0[] = { + { 11.54, 100 }, + { 11.54, 28.5714 }, + { 16.3019, 14.2857 }, + { 25.8257, 4.7619 }, + { 40.1114, 0 }, + { 49.6352, 0 }, + { 63.921, 4.7619 }, + { 73.4448, 14.2857 }, + { 78.2067, 28.5714 }, + { 78.2067, 100 }, +}; + +static const StrokeRec char85[] = { + { 10, char85_stroke0 }, +}; + +/* char: 86 'V' */ + +static const CoordRec char86_stroke0[] = { + { 2.36, 100 }, + { 40.4552, 0 }, +}; + +static const CoordRec char86_stroke1[] = { + { 78.5505, 100 }, + { 40.4552, 0 }, +}; + +static const StrokeRec char86[] = { + { 2, char86_stroke0 }, + { 2, char86_stroke1 }, +}; + +/* char: 87 'W' */ + +static const CoordRec char87_stroke0[] = { + { 2.22, 100 }, + { 26.0295, 0 }, +}; + +static const CoordRec char87_stroke1[] = { + { 49.839, 100 }, + { 26.0295, 0 }, +}; + +static const CoordRec char87_stroke2[] = { + { 49.839, 100 }, + { 73.6486, 0 }, +}; + +static const CoordRec char87_stroke3[] = { + { 97.4581, 100 }, + { 73.6486, 0 }, +}; + +static const StrokeRec char87[] = { + { 2, char87_stroke0 }, + { 2, char87_stroke1 }, + { 2, char87_stroke2 }, + { 2, char87_stroke3 }, +}; + +/* char: 88 'X' */ + +static const CoordRec char88_stroke0[] = { + { 2.5, 100 }, + { 69.1667, 0 }, +}; + +static const CoordRec char88_stroke1[] = { + { 69.1667, 100 }, + { 2.5, 0 }, +}; + +static const StrokeRec char88[] = { + { 2, char88_stroke0 }, + { 2, char88_stroke1 }, +}; + +/* char: 89 'Y' */ + +static const CoordRec char89_stroke0[] = { + { 1.52, 100 }, + { 39.6152, 52.381 }, + { 39.6152, 0 }, +}; + +static const CoordRec char89_stroke1[] = { + { 77.7105, 100 }, + { 39.6152, 52.381 }, +}; + +static const StrokeRec char89[] = { + { 3, char89_stroke0 }, + { 2, char89_stroke1 }, +}; + +/* char: 90 'Z' */ + +static const CoordRec char90_stroke0[] = { + { 69.1667, 100 }, + { 2.5, 0 }, +}; + +static const CoordRec char90_stroke1[] = { + { 2.5, 100 }, + { 69.1667, 100 }, +}; + +static const CoordRec char90_stroke2[] = { + { 2.5, 0 }, + { 69.1667, 0 }, +}; + +static const StrokeRec char90[] = { + { 2, char90_stroke0 }, + { 2, char90_stroke1 }, + { 2, char90_stroke2 }, +}; + +/* char: 91 '[' */ + +static const CoordRec char91_stroke0[] = { + { 7.78, 119.048 }, + { 7.78, -33.3333 }, +}; + +static const CoordRec char91_stroke1[] = { + { 12.5419, 119.048 }, + { 12.5419, -33.3333 }, +}; + +static const CoordRec char91_stroke2[] = { + { 7.78, 119.048 }, + { 41.1133, 119.048 }, +}; + +static const CoordRec char91_stroke3[] = { + { 7.78, -33.3333 }, + { 41.1133, -33.3333 }, +}; + +static const StrokeRec char91[] = { + { 2, char91_stroke0 }, + { 2, char91_stroke1 }, + { 2, char91_stroke2 }, + { 2, char91_stroke3 }, +}; + +/* char: 92 '\' */ + +static const CoordRec char92_stroke0[] = { + { 5.84, 100 }, + { 72.5067, -14.2857 }, +}; + +static const StrokeRec char92[] = { + { 2, char92_stroke0 }, +}; + +/* char: 93 ']' */ + +static const CoordRec char93_stroke0[] = { + { 33.0114, 119.048 }, + { 33.0114, -33.3333 }, +}; + +static const CoordRec char93_stroke1[] = { + { 37.7733, 119.048 }, + { 37.7733, -33.3333 }, +}; + +static const CoordRec char93_stroke2[] = { + { 4.44, 119.048 }, + { 37.7733, 119.048 }, +}; + +static const CoordRec char93_stroke3[] = { + { 4.44, -33.3333 }, + { 37.7733, -33.3333 }, +}; + +static const StrokeRec char93[] = { + { 2, char93_stroke0 }, + { 2, char93_stroke1 }, + { 2, char93_stroke2 }, + { 2, char93_stroke3 }, +}; + +/* char: 94 '^' */ + +static const CoordRec char94_stroke0[] = { + { 44.0752, 109.524 }, + { 5.98, 42.8571 }, +}; + +static const CoordRec char94_stroke1[] = { + { 44.0752, 109.524 }, + { 82.1705, 42.8571 }, +}; + +static const StrokeRec char94[] = { + { 2, char94_stroke0 }, + { 2, char94_stroke1 }, +}; + +/* char: 95 '_' */ + +static const CoordRec char95_stroke0[] = { + { -1.1, -33.3333 }, + { 103.662, -33.3333 }, + { 103.662, -28.5714 }, + { -1.1, -28.5714 }, + { -1.1, -33.3333 }, +}; + +static const StrokeRec char95[] = { + { 5, char95_stroke0 }, +}; + +/* char: 96 '`' */ + +static const CoordRec char96_stroke0[] = { + { 33.0219, 100 }, + { 56.8314, 71.4286 }, +}; + +static const CoordRec char96_stroke1[] = { + { 33.0219, 100 }, + { 28.26, 95.2381 }, + { 56.8314, 71.4286 }, +}; + +static const StrokeRec char96[] = { + { 2, char96_stroke0 }, + { 3, char96_stroke1 }, +}; + +/* char: 97 'a' */ + +static const CoordRec char97_stroke0[] = { + { 63.8229, 66.6667 }, + { 63.8229, 0 }, +}; + +static const CoordRec char97_stroke1[] = { + { 63.8229, 52.381 }, + { 54.299, 61.9048 }, + { 44.7752, 66.6667 }, + { 30.4895, 66.6667 }, + { 20.9657, 61.9048 }, + { 11.4419, 52.381 }, + { 6.68, 38.0952 }, + { 6.68, 28.5714 }, + { 11.4419, 14.2857 }, + { 20.9657, 4.7619 }, + { 30.4895, 0 }, + { 44.7752, 0 }, + { 54.299, 4.7619 }, + { 63.8229, 14.2857 }, +}; + +static const StrokeRec char97[] = { + { 2, char97_stroke0 }, + { 14, char97_stroke1 }, +}; + +/* char: 98 'b' */ + +static const CoordRec char98_stroke0[] = { + { 8.76, 100 }, + { 8.76, 0 }, +}; + +static const CoordRec char98_stroke1[] = { + { 8.76, 52.381 }, + { 18.2838, 61.9048 }, + { 27.8076, 66.6667 }, + { 42.0933, 66.6667 }, + { 51.6171, 61.9048 }, + { 61.141, 52.381 }, + { 65.9029, 38.0952 }, + { 65.9029, 28.5714 }, + { 61.141, 14.2857 }, + { 51.6171, 4.7619 }, + { 42.0933, 0 }, + { 27.8076, 0 }, + { 18.2838, 4.7619 }, + { 8.76, 14.2857 }, +}; + +static const StrokeRec char98[] = { + { 2, char98_stroke0 }, + { 14, char98_stroke1 }, +}; + +/* char: 99 'c' */ + +static const CoordRec char99_stroke0[] = { + { 62.6629, 52.381 }, + { 53.139, 61.9048 }, + { 43.6152, 66.6667 }, + { 29.3295, 66.6667 }, + { 19.8057, 61.9048 }, + { 10.2819, 52.381 }, + { 5.52, 38.0952 }, + { 5.52, 28.5714 }, + { 10.2819, 14.2857 }, + { 19.8057, 4.7619 }, + { 29.3295, 0 }, + { 43.6152, 0 }, + { 53.139, 4.7619 }, + { 62.6629, 14.2857 }, +}; + +static const StrokeRec char99[] = { + { 14, char99_stroke0 }, +}; + +/* char: 100 'd' */ + +static const CoordRec char100_stroke0[] = { + { 61.7829, 100 }, + { 61.7829, 0 }, +}; + +static const CoordRec char100_stroke1[] = { + { 61.7829, 52.381 }, + { 52.259, 61.9048 }, + { 42.7352, 66.6667 }, + { 28.4495, 66.6667 }, + { 18.9257, 61.9048 }, + { 9.4019, 52.381 }, + { 4.64, 38.0952 }, + { 4.64, 28.5714 }, + { 9.4019, 14.2857 }, + { 18.9257, 4.7619 }, + { 28.4495, 0 }, + { 42.7352, 0 }, + { 52.259, 4.7619 }, + { 61.7829, 14.2857 }, +}; + +static const StrokeRec char100[] = { + { 2, char100_stroke0 }, + { 14, char100_stroke1 }, +}; + +/* char: 101 'e' */ + +static const CoordRec char101_stroke0[] = { + { 5.72, 38.0952 }, + { 62.8629, 38.0952 }, + { 62.8629, 47.619 }, + { 58.101, 57.1429 }, + { 53.339, 61.9048 }, + { 43.8152, 66.6667 }, + { 29.5295, 66.6667 }, + { 20.0057, 61.9048 }, + { 10.4819, 52.381 }, + { 5.72, 38.0952 }, + { 5.72, 28.5714 }, + { 10.4819, 14.2857 }, + { 20.0057, 4.7619 }, + { 29.5295, 0 }, + { 43.8152, 0 }, + { 53.339, 4.7619 }, + { 62.8629, 14.2857 }, +}; + +static const StrokeRec char101[] = { + { 17, char101_stroke0 }, +}; + +/* char: 102 'f' */ + +static const CoordRec char102_stroke0[] = { + { 38.7752, 100 }, + { 29.2514, 100 }, + { 19.7276, 95.2381 }, + { 14.9657, 80.9524 }, + { 14.9657, 0 }, +}; + +static const CoordRec char102_stroke1[] = { + { 0.68, 66.6667 }, + { 34.0133, 66.6667 }, +}; + +static const StrokeRec char102[] = { + { 5, char102_stroke0 }, + { 2, char102_stroke1 }, +}; + +/* char: 103 'g' */ + +static const CoordRec char103_stroke0[] = { + { 62.5029, 66.6667 }, + { 62.5029, -9.5238 }, + { 57.741, -23.8095 }, + { 52.979, -28.5714 }, + { 43.4552, -33.3333 }, + { 29.1695, -33.3333 }, + { 19.6457, -28.5714 }, +}; + +static const CoordRec char103_stroke1[] = { + { 62.5029, 52.381 }, + { 52.979, 61.9048 }, + { 43.4552, 66.6667 }, + { 29.1695, 66.6667 }, + { 19.6457, 61.9048 }, + { 10.1219, 52.381 }, + { 5.36, 38.0952 }, + { 5.36, 28.5714 }, + { 10.1219, 14.2857 }, + { 19.6457, 4.7619 }, + { 29.1695, 0 }, + { 43.4552, 0 }, + { 52.979, 4.7619 }, + { 62.5029, 14.2857 }, +}; + +static const StrokeRec char103[] = { + { 7, char103_stroke0 }, + { 14, char103_stroke1 }, +}; + +/* char: 104 'h' */ + +static const CoordRec char104_stroke0[] = { + { 9.6, 100 }, + { 9.6, 0 }, +}; + +static const CoordRec char104_stroke1[] = { + { 9.6, 47.619 }, + { 23.8857, 61.9048 }, + { 33.4095, 66.6667 }, + { 47.6952, 66.6667 }, + { 57.219, 61.9048 }, + { 61.981, 47.619 }, + { 61.981, 0 }, +}; + +static const StrokeRec char104[] = { + { 2, char104_stroke0 }, + { 7, char104_stroke1 }, +}; + +/* char: 105 'i' */ + +static const CoordRec char105_stroke0[] = { + { 10.02, 100 }, + { 14.7819, 95.2381 }, + { 19.5438, 100 }, + { 14.7819, 104.762 }, + { 10.02, 100 }, +}; + +static const CoordRec char105_stroke1[] = { + { 14.7819, 66.6667 }, + { 14.7819, 0 }, +}; + +static const StrokeRec char105[] = { + { 5, char105_stroke0 }, + { 2, char105_stroke1 }, +}; + +/* char: 106 'j' */ + +static const CoordRec char106_stroke0[] = { + { 17.3876, 100 }, + { 22.1495, 95.2381 }, + { 26.9114, 100 }, + { 22.1495, 104.762 }, + { 17.3876, 100 }, +}; + +static const CoordRec char106_stroke1[] = { + { 22.1495, 66.6667 }, + { 22.1495, -14.2857 }, + { 17.3876, -28.5714 }, + { 7.8638, -33.3333 }, + { -1.66, -33.3333 }, +}; + +static const StrokeRec char106[] = { + { 5, char106_stroke0 }, + { 5, char106_stroke1 }, +}; + +/* char: 107 'k' */ + +static const CoordRec char107_stroke0[] = { + { 9.6, 100 }, + { 9.6, 0 }, +}; + +static const CoordRec char107_stroke1[] = { + { 57.219, 66.6667 }, + { 9.6, 19.0476 }, +}; + +static const CoordRec char107_stroke2[] = { + { 28.6476, 38.0952 }, + { 61.981, 0 }, +}; + +static const StrokeRec char107[] = { + { 2, char107_stroke0 }, + { 2, char107_stroke1 }, + { 2, char107_stroke2 }, +}; + +/* char: 108 'l' */ + +static const CoordRec char108_stroke0[] = { + { 10.02, 100 }, + { 10.02, 0 }, +}; + +static const StrokeRec char108[] = { + { 2, char108_stroke0 }, +}; + +/* char: 109 'm' */ + +static const CoordRec char109_stroke0[] = { + { 9.6, 66.6667 }, + { 9.6, 0 }, +}; + +static const CoordRec char109_stroke1[] = { + { 9.6, 47.619 }, + { 23.8857, 61.9048 }, + { 33.4095, 66.6667 }, + { 47.6952, 66.6667 }, + { 57.219, 61.9048 }, + { 61.981, 47.619 }, + { 61.981, 0 }, +}; + +static const CoordRec char109_stroke2[] = { + { 61.981, 47.619 }, + { 76.2667, 61.9048 }, + { 85.7905, 66.6667 }, + { 100.076, 66.6667 }, + { 109.6, 61.9048 }, + { 114.362, 47.619 }, + { 114.362, 0 }, +}; + +static const StrokeRec char109[] = { + { 2, char109_stroke0 }, + { 7, char109_stroke1 }, + { 7, char109_stroke2 }, +}; + +/* char: 110 'n' */ + +static const CoordRec char110_stroke0[] = { + { 9.18, 66.6667 }, + { 9.18, 0 }, +}; + +static const CoordRec char110_stroke1[] = { + { 9.18, 47.619 }, + { 23.4657, 61.9048 }, + { 32.9895, 66.6667 }, + { 47.2752, 66.6667 }, + { 56.799, 61.9048 }, + { 61.561, 47.619 }, + { 61.561, 0 }, +}; + +static const StrokeRec char110[] = { + { 2, char110_stroke0 }, + { 7, char110_stroke1 }, +}; + +/* char: 111 'o' */ + +static const CoordRec char111_stroke0[] = { + { 28.7895, 66.6667 }, + { 19.2657, 61.9048 }, + { 9.7419, 52.381 }, + { 4.98, 38.0952 }, + { 4.98, 28.5714 }, + { 9.7419, 14.2857 }, + { 19.2657, 4.7619 }, + { 28.7895, 0 }, + { 43.0752, 0 }, + { 52.599, 4.7619 }, + { 62.1229, 14.2857 }, + { 66.8848, 28.5714 }, + { 66.8848, 38.0952 }, + { 62.1229, 52.381 }, + { 52.599, 61.9048 }, + { 43.0752, 66.6667 }, + { 28.7895, 66.6667 }, +}; + +static const StrokeRec char111[] = { + { 17, char111_stroke0 }, +}; + +/* char: 112 'p' */ + +static const CoordRec char112_stroke0[] = { + { 9.46, 66.6667 }, + { 9.46, -33.3333 }, +}; + +static const CoordRec char112_stroke1[] = { + { 9.46, 52.381 }, + { 18.9838, 61.9048 }, + { 28.5076, 66.6667 }, + { 42.7933, 66.6667 }, + { 52.3171, 61.9048 }, + { 61.841, 52.381 }, + { 66.6029, 38.0952 }, + { 66.6029, 28.5714 }, + { 61.841, 14.2857 }, + { 52.3171, 4.7619 }, + { 42.7933, 0 }, + { 28.5076, 0 }, + { 18.9838, 4.7619 }, + { 9.46, 14.2857 }, +}; + +static const StrokeRec char112[] = { + { 2, char112_stroke0 }, + { 14, char112_stroke1 }, +}; + +/* char: 113 'q' */ + +static const CoordRec char113_stroke0[] = { + { 61.9829, 66.6667 }, + { 61.9829, -33.3333 }, +}; + +static const CoordRec char113_stroke1[] = { + { 61.9829, 52.381 }, + { 52.459, 61.9048 }, + { 42.9352, 66.6667 }, + { 28.6495, 66.6667 }, + { 19.1257, 61.9048 }, + { 9.6019, 52.381 }, + { 4.84, 38.0952 }, + { 4.84, 28.5714 }, + { 9.6019, 14.2857 }, + { 19.1257, 4.7619 }, + { 28.6495, 0 }, + { 42.9352, 0 }, + { 52.459, 4.7619 }, + { 61.9829, 14.2857 }, +}; + +static const StrokeRec char113[] = { + { 2, char113_stroke0 }, + { 14, char113_stroke1 }, +}; + +/* char: 114 'r' */ + +static const CoordRec char114_stroke0[] = { + { 9.46, 66.6667 }, + { 9.46, 0 }, +}; + +static const CoordRec char114_stroke1[] = { + { 9.46, 38.0952 }, + { 14.2219, 52.381 }, + { 23.7457, 61.9048 }, + { 33.2695, 66.6667 }, + { 47.5552, 66.6667 }, +}; + +static const StrokeRec char114[] = { + { 2, char114_stroke0 }, + { 5, char114_stroke1 }, +}; + +/* char: 115 's' */ + +static const CoordRec char115_stroke0[] = { + { 57.081, 52.381 }, + { 52.319, 61.9048 }, + { 38.0333, 66.6667 }, + { 23.7476, 66.6667 }, + { 9.4619, 61.9048 }, + { 4.7, 52.381 }, + { 9.4619, 42.8571 }, + { 18.9857, 38.0952 }, + { 42.7952, 33.3333 }, + { 52.319, 28.5714 }, + { 57.081, 19.0476 }, + { 57.081, 14.2857 }, + { 52.319, 4.7619 }, + { 38.0333, 0 }, + { 23.7476, 0 }, + { 9.4619, 4.7619 }, + { 4.7, 14.2857 }, +}; + +static const StrokeRec char115[] = { + { 17, char115_stroke0 }, +}; + +/* char: 116 't' */ + +static const CoordRec char116_stroke0[] = { + { 14.8257, 100 }, + { 14.8257, 19.0476 }, + { 19.5876, 4.7619 }, + { 29.1114, 0 }, + { 38.6352, 0 }, +}; + +static const CoordRec char116_stroke1[] = { + { 0.54, 66.6667 }, + { 33.8733, 66.6667 }, +}; + +static const StrokeRec char116[] = { + { 5, char116_stroke0 }, + { 2, char116_stroke1 }, +}; + +/* char: 117 'u' */ + +static const CoordRec char117_stroke0[] = { + { 9.46, 66.6667 }, + { 9.46, 19.0476 }, + { 14.2219, 4.7619 }, + { 23.7457, 0 }, + { 38.0314, 0 }, + { 47.5552, 4.7619 }, + { 61.841, 19.0476 }, +}; + +static const CoordRec char117_stroke1[] = { + { 61.841, 66.6667 }, + { 61.841, 0 }, +}; + +static const StrokeRec char117[] = { + { 7, char117_stroke0 }, + { 2, char117_stroke1 }, +}; + +/* char: 118 'v' */ + +static const CoordRec char118_stroke0[] = { + { 1.8, 66.6667 }, + { 30.3714, 0 }, +}; + +static const CoordRec char118_stroke1[] = { + { 58.9429, 66.6667 }, + { 30.3714, 0 }, +}; + +static const StrokeRec char118[] = { + { 2, char118_stroke0 }, + { 2, char118_stroke1 }, +}; + +/* char: 119 'w' */ + +static const CoordRec char119_stroke0[] = { + { 2.5, 66.6667 }, + { 21.5476, 0 }, +}; + +static const CoordRec char119_stroke1[] = { + { 40.5952, 66.6667 }, + { 21.5476, 0 }, +}; + +static const CoordRec char119_stroke2[] = { + { 40.5952, 66.6667 }, + { 59.6429, 0 }, +}; + +static const CoordRec char119_stroke3[] = { + { 78.6905, 66.6667 }, + { 59.6429, 0 }, +}; + +static const StrokeRec char119[] = { + { 2, char119_stroke0 }, + { 2, char119_stroke1 }, + { 2, char119_stroke2 }, + { 2, char119_stroke3 }, +}; + +/* char: 120 'x' */ + +static const CoordRec char120_stroke0[] = { + { 1.66, 66.6667 }, + { 54.041, 0 }, +}; + +static const CoordRec char120_stroke1[] = { + { 54.041, 66.6667 }, + { 1.66, 0 }, +}; + +static const StrokeRec char120[] = { + { 2, char120_stroke0 }, + { 2, char120_stroke1 }, +}; + +/* char: 121 'y' */ + +static const CoordRec char121_stroke0[] = { + { 6.5619, 66.6667 }, + { 35.1333, 0 }, +}; + +static const CoordRec char121_stroke1[] = { + { 63.7048, 66.6667 }, + { 35.1333, 0 }, + { 25.6095, -19.0476 }, + { 16.0857, -28.5714 }, + { 6.5619, -33.3333 }, + { 1.8, -33.3333 }, +}; + +static const StrokeRec char121[] = { + { 2, char121_stroke0 }, + { 6, char121_stroke1 }, +}; + +/* char: 122 'z' */ + +static const CoordRec char122_stroke0[] = { + { 56.821, 66.6667 }, + { 4.44, 0 }, +}; + +static const CoordRec char122_stroke1[] = { + { 4.44, 66.6667 }, + { 56.821, 66.6667 }, +}; + +static const CoordRec char122_stroke2[] = { + { 4.44, 0 }, + { 56.821, 0 }, +}; + +static const StrokeRec char122[] = { + { 2, char122_stroke0 }, + { 2, char122_stroke1 }, + { 2, char122_stroke2 }, +}; + +/* char: 123 '{' */ + +static const CoordRec char123_stroke0[] = { + { 31.1895, 119.048 }, + { 21.6657, 114.286 }, + { 16.9038, 109.524 }, + { 12.1419, 100 }, + { 12.1419, 90.4762 }, + { 16.9038, 80.9524 }, + { 21.6657, 76.1905 }, + { 26.4276, 66.6667 }, + { 26.4276, 57.1429 }, + { 16.9038, 47.619 }, +}; + +static const CoordRec char123_stroke1[] = { + { 21.6657, 114.286 }, + { 16.9038, 104.762 }, + { 16.9038, 95.2381 }, + { 21.6657, 85.7143 }, + { 26.4276, 80.9524 }, + { 31.1895, 71.4286 }, + { 31.1895, 61.9048 }, + { 26.4276, 52.381 }, + { 7.38, 42.8571 }, + { 26.4276, 33.3333 }, + { 31.1895, 23.8095 }, + { 31.1895, 14.2857 }, + { 26.4276, 4.7619 }, + { 21.6657, 0 }, + { 16.9038, -9.5238 }, + { 16.9038, -19.0476 }, + { 21.6657, -28.5714 }, +}; + +static const CoordRec char123_stroke2[] = { + { 16.9038, 38.0952 }, + { 26.4276, 28.5714 }, + { 26.4276, 19.0476 }, + { 21.6657, 9.5238 }, + { 16.9038, 4.7619 }, + { 12.1419, -4.7619 }, + { 12.1419, -14.2857 }, + { 16.9038, -23.8095 }, + { 21.6657, -28.5714 }, + { 31.1895, -33.3333 }, +}; + +static const StrokeRec char123[] = { + { 10, char123_stroke0 }, + { 17, char123_stroke1 }, + { 10, char123_stroke2 }, +}; + +/* char: 124 '|' */ + +static const CoordRec char124_stroke0[] = { + { 11.54, 119.048 }, + { 11.54, -33.3333 }, +}; + +static const StrokeRec char124[] = { + { 2, char124_stroke0 }, +}; + +/* char: 125 '}' */ + +static const CoordRec char125_stroke0[] = { + { 9.18, 119.048 }, + { 18.7038, 114.286 }, + { 23.4657, 109.524 }, + { 28.2276, 100 }, + { 28.2276, 90.4762 }, + { 23.4657, 80.9524 }, + { 18.7038, 76.1905 }, + { 13.9419, 66.6667 }, + { 13.9419, 57.1429 }, + { 23.4657, 47.619 }, +}; + +static const CoordRec char125_stroke1[] = { + { 18.7038, 114.286 }, + { 23.4657, 104.762 }, + { 23.4657, 95.2381 }, + { 18.7038, 85.7143 }, + { 13.9419, 80.9524 }, + { 9.18, 71.4286 }, + { 9.18, 61.9048 }, + { 13.9419, 52.381 }, + { 32.9895, 42.8571 }, + { 13.9419, 33.3333 }, + { 9.18, 23.8095 }, + { 9.18, 14.2857 }, + { 13.9419, 4.7619 }, + { 18.7038, 0 }, + { 23.4657, -9.5238 }, + { 23.4657, -19.0476 }, + { 18.7038, -28.5714 }, +}; + +static const CoordRec char125_stroke2[] = { + { 23.4657, 38.0952 }, + { 13.9419, 28.5714 }, + { 13.9419, 19.0476 }, + { 18.7038, 9.5238 }, + { 23.4657, 4.7619 }, + { 28.2276, -4.7619 }, + { 28.2276, -14.2857 }, + { 23.4657, -23.8095 }, + { 18.7038, -28.5714 }, + { 9.18, -33.3333 }, +}; + +static const StrokeRec char125[] = { + { 10, char125_stroke0 }, + { 17, char125_stroke1 }, + { 10, char125_stroke2 }, +}; + +/* char: 126 '~' */ + +static const CoordRec char126_stroke0[] = { + { 2.92, 28.5714 }, + { 2.92, 38.0952 }, + { 7.6819, 52.381 }, + { 17.2057, 57.1429 }, + { 26.7295, 57.1429 }, + { 36.2533, 52.381 }, + { 55.301, 38.0952 }, + { 64.8248, 33.3333 }, + { 74.3486, 33.3333 }, + { 83.8724, 38.0952 }, + { 88.6343, 47.619 }, +}; + +static const CoordRec char126_stroke1[] = { + { 2.92, 38.0952 }, + { 7.6819, 47.619 }, + { 17.2057, 52.381 }, + { 26.7295, 52.381 }, + { 36.2533, 47.619 }, + { 55.301, 33.3333 }, + { 64.8248, 28.5714 }, + { 74.3486, 28.5714 }, + { 83.8724, 33.3333 }, + { 88.6343, 47.619 }, + { 88.6343, 57.1429 }, +}; + +static const StrokeRec char126[] = { + { 11, char126_stroke0 }, + { 11, char126_stroke1 }, +}; + +/* char: 127 */ + +static const CoordRec char127_stroke0[] = { + { 52.381, 100 }, + { 14.2857, -33.3333 }, +}; + +static const CoordRec char127_stroke1[] = { + { 28.5714, 66.6667 }, + { 14.2857, 61.9048 }, + { 4.7619, 52.381 }, + { 0, 38.0952 }, + { 0, 23.8095 }, + { 4.7619, 14.2857 }, + { 14.2857, 4.7619 }, + { 28.5714, 0 }, + { 38.0952, 0 }, + { 52.381, 4.7619 }, + { 61.9048, 14.2857 }, + { 66.6667, 28.5714 }, + { 66.6667, 42.8571 }, + { 61.9048, 52.381 }, + { 52.381, 61.9048 }, + { 38.0952, 66.6667 }, + { 28.5714, 66.6667 }, +}; + +static const StrokeRec char127[] = { + { 2, char127_stroke0 }, + { 17, char127_stroke1 }, +}; + +static const StrokeCharRec chars[] = { + { 0, /* char0 */ 0, 0, 0 }, + { 0, /* char1 */ 0, 0, 0 }, + { 0, /* char2 */ 0, 0, 0 }, + { 0, /* char3 */ 0, 0, 0 }, + { 0, /* char4 */ 0, 0, 0 }, + { 0, /* char5 */ 0, 0, 0 }, + { 0, /* char6 */ 0, 0, 0 }, + { 0, /* char7 */ 0, 0, 0 }, + { 0, /* char8 */ 0, 0, 0 }, + { 0, /* char9 */ 0, 0, 0 }, + { 0, /* char10 */ 0, 0, 0 }, + { 0, /* char11 */ 0, 0, 0 }, + { 0, /* char12 */ 0, 0, 0 }, + { 0, /* char13 */ 0, 0, 0 }, + { 0, /* char14 */ 0, 0, 0 }, + { 0, /* char15 */ 0, 0, 0 }, + { 0, /* char16 */ 0, 0, 0 }, + { 0, /* char17 */ 0, 0, 0 }, + { 0, /* char18 */ 0, 0, 0 }, + { 0, /* char19 */ 0, 0, 0 }, + { 0, /* char20 */ 0, 0, 0 }, + { 0, /* char21 */ 0, 0, 0 }, + { 0, /* char22 */ 0, 0, 0 }, + { 0, /* char23 */ 0, 0, 0 }, + { 0, /* char24 */ 0, 0, 0 }, + { 0, /* char25 */ 0, 0, 0 }, + { 0, /* char26 */ 0, 0, 0 }, + { 0, /* char27 */ 0, 0, 0 }, + { 0, /* char28 */ 0, 0, 0 }, + { 0, /* char29 */ 0, 0, 0 }, + { 0, /* char30 */ 0, 0, 0 }, + { 0, /* char31 */ 0, 0, 0 }, + { 0, /* char32 */ 0, 52.381, 104.762 }, + { 2, char33, 13.3819, 26.6238 }, + { 2, char34, 23.0676, 51.4352 }, + { 4, char35, 36.5333, 79.4886 }, + { 3, char36, 38.1533, 76.2067 }, + { 3, char37, 49.2171, 96.5743 }, + { 1, char38, 53.599, 101.758 }, + { 1, char39, 4.44, 13.62 }, + { 1, char40, 21.8657, 47.1733 }, + { 1, char41, 24.3276, 47.5333 }, + { 3, char42, 30.7695, 59.439 }, + { 2, char43, 48.8371, 97.2543 }, + { 1, char44, 13.5219, 26.0638 }, + { 1, char45, 50.2371, 100.754 }, + { 1, char46, 13.1019, 26.4838 }, + { 1, char47, 40.5733, 82.1067 }, + { 1, char48, 38.3133, 77.0667 }, + { 1, char49, 30.8676, 66.5295 }, + { 1, char50, 38.7533, 77.6467 }, + { 1, char51, 38.3333, 77.0467 }, + { 2, char52, 37.2133, 80.1686 }, + { 1, char53, 38.1933, 77.6867 }, + { 1, char54, 34.1514, 73.8048 }, + { 2, char55, 38.8933, 77.2267 }, + { 1, char56, 38.9333, 77.6667 }, + { 1, char57, 39.9333, 74.0648 }, + { 2, char58, 14.0819, 26.2238 }, + { 2, char59, 12.9619, 26.3038 }, + { 1, char60, 41.1552, 81.6105 }, + { 2, char61, 48.5571, 97.2543 }, + { 1, char62, 40.8752, 81.6105 }, + { 2, char63, 36.9914, 73.9029 }, + { 2, char64, 34.9314, 74.3648 }, + { 3, char65, 40.5952, 80.4905 }, + { 3, char66, 44.7533, 83.6267 }, + { 1, char67, 39.9933, 84.4886 }, + { 2, char68, 45.2933, 85.2867 }, + { 4, char69, 39.9914, 78.1848 }, + { 3, char70, 39.9914, 78.7448 }, + { 2, char71, 40.3933, 89.7686 }, + { 3, char72, 44.7533, 89.0867 }, + { 1, char73, 10.86, 21.3 }, + { 1, char74, 31.0714, 59.999 }, + { 3, char75, 44.6133, 79.3267 }, + { 2, char76, 40.2514, 71.3229 }, + { 4, char77, 48.9552, 97.2105 }, + { 3, char78, 44.4733, 88.8067 }, + { 1, char79, 44.3352, 88.8305 }, + { 2, char80, 45.4333, 85.6667 }, + { 2, char81, 43.3952, 88.0905 }, + { 3, char82, 45.0133, 82.3667 }, + { 1, char83, 41.3333, 80.8267 }, + { 2, char84, 35.6933, 71.9467 }, + { 1, char85, 44.8733, 89.4867 }, + { 2, char86, 40.4552, 81.6105 }, + { 4, char87, 49.839, 100.518 }, + { 2, char88, 35.8333, 72.3667 }, + { 2, char89, 39.6152, 79.6505 }, + { 3, char90, 35.8333, 73.7467 }, + { 4, char91, 22.0657, 46.1133 }, + { 1, char92, 39.1733, 78.2067 }, + { 4, char93, 23.4876, 46.3933 }, + { 2, char94, 44.0752, 90.2305 }, + { 1, char95, 51.281, 104.062 }, + { 2, char96, 42.5457, 83.5714 }, + { 2, char97, 35.2514, 66.6029 }, + { 2, char98, 37.3314, 70.4629 }, + { 1, char99, 34.0914, 68.9229 }, + { 2, char100, 33.2114, 70.2629 }, + { 1, char101, 34.2914, 68.5229 }, + { 2, char102, 14.9657, 38.6552 }, + { 2, char103, 33.9314, 70.9829 }, + { 2, char104, 33.4095, 71.021 }, + { 2, char105, 14.7819, 28.8638 }, + { 2, char106, 17.3876, 36.2314 }, + { 3, char107, 33.4095, 62.521 }, + { 1, char108, 10.02, 19.34 }, + { 3, char109, 61.981, 123.962 }, + { 2, char110, 32.9895, 70.881 }, + { 1, char111, 33.5514, 71.7448 }, + { 2, char112, 38.0314, 70.8029 }, + { 2, char113, 33.4114, 70.7429 }, + { 2, char114, 23.7457, 49.4952 }, + { 1, char115, 28.5095, 62.321 }, + { 2, char116, 14.8257, 39.3152 }, + { 2, char117, 33.2695, 71.161 }, + { 2, char118, 30.3714, 60.6029 }, + { 4, char119, 40.5952, 80.4905 }, + { 2, char120, 25.4695, 56.401 }, + { 2, char121, 35.1333, 66.0648 }, + { 3, char122, 28.2495, 61.821 }, + { 3, char123, 21.6657, 41.6295 }, + { 1, char124, 11.54, 23.78 }, + { 3, char125, 18.7038, 41.4695 }, + { 2, char126, 45.7771, 91.2743 }, + { 2, char127, 33.3333, 66.6667 }, +}; + +StrokeFontRec glutStrokeRoman = { "Roman", 128, chars, 119.048, -33.3333 }; + diff --git a/glut/glut_stroke.c b/glut/glut_stroke.c new file mode 100644 index 0000000..2fe408b --- /dev/null +++ b/glut/glut_stroke.c @@ -0,0 +1,42 @@ + +/* Copyright (c) Mark J. Kilgard, 1994. */ + +/* This program is freely distributable without licensing fees + and is provided without guarantee or warrantee expressed or + implied. This program is -not- in the public domain. */ + +#include "glutint.h" +#include "glutstroke.h" + +void APIENTRY +glutStrokeCharacter(GLUTstrokeFont font, int c) +{ + const StrokeCharRec *ch; + const StrokeRec *stroke; + const CoordRec *coord; + StrokeFontPtr fontinfo; + int i, j; + + +#if defined(_WIN32) + fontinfo = (StrokeFontPtr) __glutFont(font); +#else + fontinfo = (StrokeFontPtr) font; +#endif + + if (c < 0 || c >= fontinfo->num_chars) + return; + ch = &(fontinfo->ch[c]); + if (ch) { + for (i = ch->num_strokes, stroke = ch->stroke; + i > 0; i--, stroke++) { + glBegin(GL_LINE_STRIP); + for (j = stroke->num_coords, coord = stroke->coord; + j > 0; j--, coord++) { + glVertex2f(coord->x, coord->y); + } + glEnd(); + } + glTranslatef(ch->right, 0.0, 0.0); + } +} diff --git a/glut/glut_swidth.c b/glut/glut_swidth.c new file mode 100644 index 0000000..3e4fe73 --- /dev/null +++ b/glut/glut_swidth.c @@ -0,0 +1,58 @@ + +/* Copyright (c) Mark J. Kilgard, 1995. */ + +/* This program is freely distributable without licensing fees + and is provided without guarantee or warrantee expressed or + implied. This program is -not- in the public domain. */ + +#include "glutint.h" +#include "glutstroke.h" + +/* CENTRY */ +int APIENTRY +glutStrokeWidth(GLUTstrokeFont font, int c) +{ + StrokeFontPtr fontinfo; + const StrokeCharRec *ch; + +#if defined(_WIN32) + fontinfo = (StrokeFontPtr) __glutFont(font); +#else + fontinfo = (StrokeFontPtr) font; +#endif + + if (c < 0 || c >= fontinfo->num_chars) + return 0; + ch = &(fontinfo->ch[c]); + if (ch) + return (int)(ch->right); + else + return 0; +} + +int APIENTRY +glutStrokeLength(GLUTstrokeFont font, const unsigned char *string) +{ + int c, length; + StrokeFontPtr fontinfo; + const StrokeCharRec *ch; + +#if defined(_WIN32) + fontinfo = (StrokeFontPtr) __glutFont(font); +#else + fontinfo = (StrokeFontPtr) font; +#endif + + length = 0; + for (; *string != '\0'; string++) { + c = *string; + if (c >= 0 && c < fontinfo->num_chars) { + ch = &(fontinfo->ch[c]); + if (ch) + length += (int)(ch->right); + } + } + return length; +} + +/* ENDCENTRY */ diff --git a/glut/glutbitmap.h b/glut/glutbitmap.h new file mode 100644 index 0000000..e29a016 --- /dev/null +++ b/glut/glutbitmap.h @@ -0,0 +1,30 @@ +#ifndef __glutbitmap_h__ +#define __glutbitmap_h__ + +/* Copyright (c) Mark J. Kilgard, 1994. */ + +/* This program is freely distributable without licensing fees + and is provided without guarantee or warrantee expressed or + implied. This program is -not- in the public domain. */ + +#include "glut.h" + +typedef struct { + const GLsizei width; + const GLsizei height; + const GLfloat xorig; + const GLfloat yorig; + const GLfloat advance; + const GLubyte *bitmap; +} BitmapCharRec, *BitmapCharPtr; + +typedef struct { + const char *name; + const int num_chars; + const int first; + const BitmapCharRec * const *ch; +} BitmapFontRec, *BitmapFontPtr; + +typedef void *GLUTbitmapFont; + +#endif /* __glutbitmap_h__ */ diff --git a/glut/glutint.h b/glut/glutint.h new file mode 100644 index 0000000..1afa6dd --- /dev/null +++ b/glut/glutint.h @@ -0,0 +1,24 @@ +#ifndef __glutint_h__ +#define __glutint_h__ + +/* Copyright (c) Mark J. Kilgard, 1994, 1997, 1998. */ + +/* This program is freely distributable without licensing fees + and is provided without guarantee or warrantee expressed or + implied. This program is -not- in the public domain. */ + +#if defined(_WIN32) +#include "glutwin32.h" +#else +#ifdef __sgi +#define SUPPORT_FORTRAN +#endif +#include +#include +#include +#endif + +#include "glut.h" + + +#endif /* __glutint_h__ */ diff --git a/glut/glutstroke.h b/glut/glutstroke.h new file mode 100644 index 0000000..40607d0 --- /dev/null +++ b/glut/glutstroke.h @@ -0,0 +1,42 @@ +#ifndef __glutstroke_h__ +#define __glutstroke_h__ + +/* Copyright (c) Mark J. Kilgard, 1994. */ + +/* This program is freely distributable without licensing fees + and is provided without guarantee or warrantee expressed or + implied. This program is -not- in the public domain. */ + +#if defined(_WIN32) && !defined(__MINGW32__) +#pragma warning (disable:4244) /* disable bogus conversion warnings */ +#pragma warning (disable:4305) /* VC++ 5.0 version of above warning. */ +#endif + +typedef struct { + float x; + float y; +} CoordRec, *CoordPtr; + +typedef struct { + int num_coords; + const CoordRec *coord; +} StrokeRec, *StrokePtr; + +typedef struct { + int num_strokes; + const StrokeRec *stroke; + float center; + float right; +} StrokeCharRec, *StrokeCharPtr; + +typedef struct { + const char *name; + int num_chars; + const StrokeCharRec *ch; + float top; + float bottom; +} StrokeFontRec, *StrokeFontPtr; + +typedef void *GLUTstrokeFont; + +#endif /* __glutstroke_h__ */ diff --git a/glut/glutwin32.h b/glut/glutwin32.h new file mode 100644 index 0000000..3d60c21 --- /dev/null +++ b/glut/glutwin32.h @@ -0,0 +1,18 @@ +#ifndef __glutwin32_h__ +#define __glutwin32_h__ + +/* Copyright (c) Nate Robins, 1997. */ + +/* This program is freely distributable without licensing fees + and is provided without guarantee or warrantee expressed or + implied. This program is -not- in the public domain. */ + +#include "win32_x11.h" +#include "win32_glx.h" + +/* Private routines from win32_util.c */ +extern void *__glutFont(void *font); +extern int __glutGetTransparentPixel(Display *dpy, XVisualInfo *vinfo); +extern void __glutAdjustCoords(Window parent, int *x, int *y, int *width, int *height); + +#endif /* __glutwin32_h__ */ diff --git a/glut/stroke.h b/glut/stroke.h new file mode 100644 index 0000000..fc29680 --- /dev/null +++ b/glut/stroke.h @@ -0,0 +1,134 @@ +/* $XConsortium: wfont.h,v 5.1 91/02/16 09:46:37 rws Exp $ */ + +/***************************************************************** +Copyright (c) 1989,1990, 1991 by Sun Microsystems, Inc. and the X Consortium. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the names of Sun Microsystems, +the X Consortium, and MIT not be used in advertising or publicity +pertaining to distribution of the software without specific, written +prior permission. + +SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT +SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL +DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifndef WFONT_INCLUDED +#define WFONT_INCLUDED + +#define WFONT_MAGIC 0x813 +#define WFONT_MAGIC_PLUS 0x715 +#define WFONT_MAGIC_PEX 0x70686e74 +#define START_PROPS 0x100 +#define START_DISPATCH(_num_props) (START_PROPS + 160 * _num_props) +#define START_PATH(_num_ch_, _num_props) (START_DISPATCH(_num_props) + sizeof(Dispatch) * _num_ch_) +#define NUM_DISPATCH 128 + +typedef struct { + unsigned short x; + unsigned short y; +} Path_point2dpx; + +typedef struct { + float x; + float y; +} Path_point2df; + +typedef struct { + int x; + int y; + int z; +} Path_point3di; + +typedef struct { + float x; + float y; + float z; +} Path_point3df; + +typedef struct { + float x; + float y; + float z; + float w; +} Path_point4df; + +typedef union { + Path_point2dpx *pt2dpx; + Path_point2df *pt2df; + Path_point3di *pt3di; + Path_point3df *pt3df; + Path_point4df *pt4df; +} Path_pt_ptr; + +typedef enum { + PATH_2DF, + PATH_2DPX, + PATH_3DF, + PATH_3DI, + PATH_4DF +} Path_type; + +typedef struct { + int n_pts; /* number of points in the subpath */ + Path_pt_ptr pts; /* pointer to them */ + int closed; /* true if the subpath is closed */ + int dcmp_flag; /* flag for pgon dcmp, pgon type + * and dcmped triangle type */ +} Path_subpath; + +typedef struct { + Path_type type; /* type of vertices in this path */ + int n_subpaths; /* number of subpaths */ + int n_vertices; /* total number of vertices */ + Path_subpath *subpaths; /* array of subpaths */ +} Path; + +typedef Path *Path_handle; + +typedef struct { + char propname[80]; /* font property name */ + char propvalue[80]; /* font property value */ +} Property; + +typedef struct { + int magic; /* magic number */ + char name[80]; /* name of this font */ + float top, /* extreme values */ + bottom, max_width; + int num_ch; /* no. of fonts in the set */ + int num_props; /* no. of font properties */ + Property *properties; /* array of properties */ +} Font_header; + +typedef struct { + float center, /* center of the character */ + right; /* right edge */ + long offset; /* offset in the file of the character + * * description */ +} Dispatch; + +typedef struct { + float center, right; + Path strokes; +} Ch_font; + +typedef struct { + char name[80]; + float top, bottom, max_width; + int num_ch; /* # characters in the font */ + Ch_font **ch_data; +} Phg_font; + +#endif /*WFONT_INCLUDED */ diff --git a/glut/win32_glx.c b/glut/win32_glx.c new file mode 100644 index 0000000..cc813a1 --- /dev/null +++ b/glut/win32_glx.c @@ -0,0 +1,255 @@ + +/* Copyright (c) Nate Robins, 1997. */ + +/* This program is freely distributable without licensing fees + and is provided without guarantee or warrantee expressed or + implied. This program is -not- in the public domain. */ + +#include +#include "win32_glx.h" + +/* global current HDC */ +extern HDC XHDC; + +GLXContext +glXCreateContext(Display * display, XVisualInfo * visinfo, + GLXContext share, Bool direct) +{ + /* KLUDGE: GLX really expects a display pointer to be passed + in as the first parameter, but Win32 needs an HDC instead, + so BE SURE that the global XHDC is set before calling this + routine. */ + HGLRC context; + + context = wglCreateContext(XHDC); + +#if 0 + /* XXX GLUT doesn't support it now, so don't worry about display list + and texture object sharing. */ + if (share) { + wglShareLists(share, context); + } +#endif + + /* Since direct rendering is implicit, the direct flag is + ignored. */ + + return context; +} + +int +glXGetConfig(Display * display, XVisualInfo * visual, int attrib, int *value) +{ + if (!visual) + return GLX_BAD_VISUAL; + + switch (attrib) { + case GLX_USE_GL: + if (visual->dwFlags & (PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW)) { + /* XXX Brad's Matrix Millenium II has problems creating + color index windows in 24-bit mode (lead to GDI crash) + and 32-bit mode (lead to black window). The cColorBits + filed of the PIXELFORMATDESCRIPTOR returned claims to + have 24 and 32 bits respectively of color indices. 2^24 + and 2^32 are ridiculously huge writable colormaps. + Assume that if we get back a color index + PIXELFORMATDESCRIPTOR with 24 or more bits, the + PIXELFORMATDESCRIPTOR doesn't really work and skip it. + -mjk */ + if (visual->iPixelType == PFD_TYPE_COLORINDEX + && visual->cColorBits >= 24) { + *value = 0; + } else { + *value = 1; + } + } else { + *value = 0; + } + break; + case GLX_BUFFER_SIZE: + /* KLUDGE: if we're RGBA, return the number of bits/pixel, + otherwise, return 8 (we guessed at 256 colors in CI + mode). */ + if (visual->iPixelType == PFD_TYPE_RGBA) + *value = visual->cColorBits; + else + *value = 8; + break; + case GLX_LEVEL: + /* The bReserved flag of the pfd contains the + overlay/underlay info. */ + *value = visual->bReserved; + break; + case GLX_RGBA: + *value = visual->iPixelType == PFD_TYPE_RGBA; + break; + case GLX_DOUBLEBUFFER: + *value = visual->dwFlags & PFD_DOUBLEBUFFER; + break; + case GLX_STEREO: + *value = visual->dwFlags & PFD_STEREO; + break; + case GLX_AUX_BUFFERS: + *value = visual->cAuxBuffers; + break; + case GLX_RED_SIZE: + *value = visual->cRedBits; + break; + case GLX_GREEN_SIZE: + *value = visual->cGreenBits; + break; + case GLX_BLUE_SIZE: + *value = visual->cBlueBits; + break; + case GLX_ALPHA_SIZE: + *value = visual->cAlphaBits; + break; + case GLX_DEPTH_SIZE: + *value = visual->cDepthBits; + break; + case GLX_STENCIL_SIZE: + *value = visual->cStencilBits; + break; + case GLX_ACCUM_RED_SIZE: + *value = visual->cAccumRedBits; + break; + case GLX_ACCUM_GREEN_SIZE: + *value = visual->cAccumGreenBits; + break; + case GLX_ACCUM_BLUE_SIZE: + *value = visual->cAccumBlueBits; + break; + case GLX_ACCUM_ALPHA_SIZE: + *value = visual->cAccumAlphaBits; + break; + default: + return GLX_BAD_ATTRIB; + } + return 0; +} + +XVisualInfo * +glXChooseVisual(Display * display, int screen, int *attribList) +{ + /* KLUDGE: since we need the HDC, MAKE SURE to set XHDC + before calling this routine. */ + + int *p = attribList; + int pf; + PIXELFORMATDESCRIPTOR pfd; + PIXELFORMATDESCRIPTOR *match = NULL; + int stereo = 0; + + /* Avoid seg-faults. */ + if (!p) + return NULL; + + memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); + pfd.nSize = (sizeof(PIXELFORMATDESCRIPTOR)); + pfd.nVersion = 1; + + /* Defaults. */ + pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW; + pfd.iPixelType = PFD_TYPE_COLORINDEX; + pfd.cColorBits = 32; + pfd.cDepthBits = 0; + + while (*p) { + switch (*p) { + case GLX_USE_GL: + pfd.dwFlags |= PFD_SUPPORT_OPENGL; + break; + case GLX_BUFFER_SIZE: + pfd.cColorBits = *(++p); + break; + case GLX_LEVEL: + /* the bReserved flag of the pfd contains the + overlay/underlay info. */ + pfd.bReserved = *(++p); + break; + case GLX_RGBA: + pfd.iPixelType = PFD_TYPE_RGBA; + break; + case GLX_DOUBLEBUFFER: + pfd.dwFlags |= PFD_DOUBLEBUFFER; + break; + case GLX_STEREO: + stereo = 1; + pfd.dwFlags |= PFD_STEREO; + break; + case GLX_AUX_BUFFERS: + pfd.cAuxBuffers = *(++p); + break; + case GLX_RED_SIZE: + pfd.cRedBits = 8; /* Try to get the maximum. */ + ++p; + break; + case GLX_GREEN_SIZE: + pfd.cGreenBits = 8; + ++p; + break; + case GLX_BLUE_SIZE: + pfd.cBlueBits = 8; + ++p; + break; + case GLX_ALPHA_SIZE: + pfd.cAlphaBits = 8; + ++p; + break; + case GLX_DEPTH_SIZE: + pfd.cDepthBits = 32; + ++p; + break; + case GLX_STENCIL_SIZE: + pfd.cStencilBits = *(++p); + break; + case GLX_ACCUM_RED_SIZE: + case GLX_ACCUM_GREEN_SIZE: + case GLX_ACCUM_BLUE_SIZE: + case GLX_ACCUM_ALPHA_SIZE: + /* I believe that WGL only used the cAccumRedBits, + cAccumBlueBits, cAccumGreenBits, and cAccumAlphaBits fields + when returning info about the accumulation buffer precision. + Only cAccumBits is used for requesting an accumulation + buffer. */ + pfd.cAccumBits = 1; + ++p; + break; + } + ++p; + } + + /* Let Win32 choose one for us. */ + pf = ChoosePixelFormat(XHDC, &pfd); + if (pf > 0) { + match = (PIXELFORMATDESCRIPTOR *) malloc(sizeof(PIXELFORMATDESCRIPTOR)); + DescribePixelFormat(XHDC, pf, sizeof(PIXELFORMATDESCRIPTOR), match); + + /* ChoosePixelFormat is dumb in that it will return a pixel + format that doesn't have stereo even if it was requested + so we need to make sure that if stereo was selected, we + got it. */ + if (stereo) { + if (!(match->dwFlags & PFD_STEREO)) { + free(match); + return NULL; + } + } + /* XXX Brad's Matrix Millenium II has problems creating + color index windows in 24-bit mode (lead to GDI crash) + and 32-bit mode (lead to black window). The cColorBits + filed of the PIXELFORMATDESCRIPTOR returned claims to + have 24 and 32 bits respectively of color indices. 2^24 + and 2^32 are ridiculously huge writable colormaps. + Assume that if we get back a color index + PIXELFORMATDESCRIPTOR with 24 or more bits, the + PIXELFORMATDESCRIPTOR doesn't really work and skip it. + -mjk */ + if (match->iPixelType == PFD_TYPE_COLORINDEX + && match->cColorBits >= 24) { + free(match); + return NULL; + } + } + return match; +} diff --git a/glut/win32_glx.h b/glut/win32_glx.h new file mode 100644 index 0000000..d3630e7 --- /dev/null +++ b/glut/win32_glx.h @@ -0,0 +1,58 @@ +#ifndef __win32_glx_h__ +#define __win32_glx_h__ + +/* Copyright (c) Nate Robins, 1997. */ + +/* This program is freely distributable without licensing fees + and is provided without guarantee or warrantee expressed or + implied. This program is -not- in the public domain. */ + +#include "win32_x11.h" + +/* Type definitions (conversions). */ +typedef HGLRC GLXContext; + +#define GLX_USE_GL 1 /* support GLX rendering */ +#define GLX_BUFFER_SIZE 2 /* depth of the color buffer */ +#define GLX_LEVEL 3 /* level in plane stacking */ +#define GLX_RGBA 4 /* true if RGBA mode */ +#define GLX_DOUBLEBUFFER 5 /* double buffering supported */ +#define GLX_STEREO 6 /* stereo buffering supported */ +#define GLX_AUX_BUFFERS 7 /* number of aux buffers */ +#define GLX_RED_SIZE 8 /* number of red component bits */ +#define GLX_GREEN_SIZE 9 /* number of green component bits */ +#define GLX_BLUE_SIZE 10 /* number of blue component bits */ +#define GLX_ALPHA_SIZE 11 /* number of alpha component bits */ +#define GLX_DEPTH_SIZE 12 /* number of depth bits */ +#define GLX_STENCIL_SIZE 13 /* number of stencil bits */ +#define GLX_ACCUM_RED_SIZE 14 /* number of red accum bits */ +#define GLX_ACCUM_GREEN_SIZE 15 /* number of green accum bits */ +#define GLX_ACCUM_BLUE_SIZE 16 /* number of blue accum bits */ +#define GLX_ACCUM_ALPHA_SIZE 17 /* number of alpha accum bits */ + +#define GLX_BAD_ATTRIB 2 +#define GLX_BAD_VISUAL 4 + +/* Functions emulated by macros. */ + +#define glXDestroyContext(display, context) \ + wglDeleteContext(context) + +/* Function prototypes. */ + +extern GLXContext glXCreateContext( + Display* display, + XVisualInfo* visinfo, + GLXContext share, + Bool direct); +extern int glXGetConfig( + Display* display, + XVisualInfo* visual, + int attrib, + int* value); +extern XVisualInfo* glXChooseVisual( + Display* display, + int screen, + int* attribList); + +#endif /* __win32_glx_h__ */ diff --git a/glut/win32_util.c b/glut/win32_util.c new file mode 100644 index 0000000..4a2580f --- /dev/null +++ b/glut/win32_util.c @@ -0,0 +1,84 @@ + +/* Copyright (c) Nate Robins, 1997. */ + +/* portions Copyright (c) Mark Kilgard, 1997, 1998. */ + +/* This program is freely distributable without licensing fees + and is provided without guarantee or warrantee expressed or + implied. This program is -not- in the public domain. */ + + +#include "glutint.h" +#include "glutstroke.h" +#include "glutbitmap.h" + +extern StrokeFontRec glutStrokeRoman; + +/* To get around the fact that Microsoft DLLs only allow functions + to be exported and now data addresses (as Unix DSOs support), the + GLUT API constants such as GLUT_STROKE_ROMAN have to get passed + through a case statement to get mapped to the actual data structure + address. */ +void* +__glutFont(void *font) +{ + switch (*reinterpret_cast(&font)) { +#ifdef __MINGW32__ + case 0: +#else + case (size_t)GLUT_STROKE_ROMAN: +#endif + return &glutStrokeRoman; + break; + default: + return &glutStrokeRoman; + } +} + +int +__glutGetTransparentPixel(Display * dpy, XVisualInfo * vinfo) +{ + /* the transparent pixel on Win32 is always index number 0. So if + we put this routine in this file, we can avoid compiling the + whole of layerutil.c which is where this routine normally comes + from. */ + return 0; +} + +void +__glutAdjustCoords(Window parent, int* x, int* y, int* width, int* height) +{ + RECT rect; + + /* adjust the window rectangle because Win32 thinks that the x, y, + width & height are the WHOLE window (including decorations), + whereas GLUT treats the x, y, width & height as only the CLIENT + area of the window. */ + rect.left = *x; rect.top = *y; + rect.right = *x + *width; rect.bottom = *y + *height; + + /* must adjust the coordinates according to the correct style + because depending on the style, there may or may not be + borders. */ + AdjustWindowRect(&rect, WS_CLIPSIBLINGS | WS_CLIPCHILDREN | + (parent ? WS_CHILD : WS_OVERLAPPEDWINDOW), + FALSE); + /* FALSE in the third parameter = window has no menu bar */ + + /* readjust if the x and y are offscreen */ + if(rect.left < 0) { + *x = 0; + } else { + *x = rect.left; + } + + if(rect.top < 0) { + *y = 0; + } else { + *y = rect.top; + } + + *width = rect.right - rect.left; /* adjusted width */ + *height = rect.bottom - rect.top; /* adjusted height */ +} + diff --git a/glut/win32_x11.c b/glut/win32_x11.c new file mode 100644 index 0000000..327522c --- /dev/null +++ b/glut/win32_x11.c @@ -0,0 +1,401 @@ + +/* Copyright (c) Nate Robins, 1997. */ +/* portions Copyright (c) Mark Kilgard, 1998. */ + +/* This program is freely distributable without licensing fees + and is provided without guarantee or warrantee expressed or + implied. This program is -not- in the public domain. */ + +#include +#include "win32_x11.h" + +/* global variable that must be set for some functions to operate + correctly. */ +HDC XHDC; + +XVisualInfo* +XGetVisualInfo(Display* display, long mask, XVisualInfo* xtemplate, int* nitems) +{ + /* KLUDGE: this function needs XHDC to be set to the HDC currently + being operated on before it is invoked! */ + + PIXELFORMATDESCRIPTOR* pfds; + int i, n; + + n = DescribePixelFormat(XHDC, 0, 0, NULL); + pfds = (PIXELFORMATDESCRIPTOR*)malloc(sizeof(PIXELFORMATDESCRIPTOR) * n); + memset(pfds, 0, sizeof(PIXELFORMATDESCRIPTOR) * n); + + for (i = 0; i < n; i++) { + DescribePixelFormat(XHDC, i, sizeof(PIXELFORMATDESCRIPTOR), &pfds[i]); + } + + *nitems = n; + return pfds; +} + +Colormap +XCreateColormap(Display* display, Window root, Visual* visual, int alloc) +{ + /* KLUDGE: this function needs XHDC to be set to the HDC currently + being operated on before it is invoked! */ + + PIXELFORMATDESCRIPTOR pfd; + LOGPALETTE *logical; + HPALETTE palette; + int n; + + /* grab the pixel format */ + memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); + DescribePixelFormat(XHDC, GetPixelFormat(XHDC), + sizeof(PIXELFORMATDESCRIPTOR), &pfd); + + if (!(pfd.dwFlags & PFD_NEED_PALETTE || + pfd.iPixelType == PFD_TYPE_COLORINDEX)) + { + return 0; + } + + n = 1 << pfd.cColorBits; + + /* allocate a bunch of memory for the logical palette (assume 256 + colors in a Win32 palette */ + logical = (LOGPALETTE*)malloc(sizeof(LOGPALETTE) + + sizeof(PALETTEENTRY) * n); + memset(logical, 0, sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * n); + + /* set the entries in the logical palette */ + logical->palVersion = 0x300; + logical->palNumEntries = n; + + /* start with a copy of the current system palette */ + GetSystemPaletteEntries(XHDC, 0, 256, &logical->palPalEntry[0]); + + if (pfd.iPixelType == PFD_TYPE_RGBA) { + int redMask = (1 << pfd.cRedBits) - 1; + int greenMask = (1 << pfd.cGreenBits) - 1; + int blueMask = (1 << pfd.cBlueBits) - 1; + int i; + + /* fill in an RGBA color palette */ + for (i = 0; i < n; ++i) { + logical->palPalEntry[i].peRed = + (((i >> pfd.cRedShift) & redMask) * 255) / redMask; + logical->palPalEntry[i].peGreen = + (((i >> pfd.cGreenShift) & greenMask) * 255) / greenMask; + logical->palPalEntry[i].peBlue = + (((i >> pfd.cBlueShift) & blueMask) * 255) / blueMask; + logical->palPalEntry[i].peFlags = 0; + } + } + + palette = CreatePalette(logical); + free(logical); + + SelectPalette(XHDC, palette, FALSE); + RealizePalette(XHDC); + + return palette; +} + +void +XAllocColorCells(Display* display, Colormap colormap, Bool contig, + unsigned long plane_masks_return[], unsigned int nplanes, + unsigned long pixels_return[], unsigned int npixels) +{ + /* NOP -- we did all the allocating in XCreateColormap! */ +} + +void +XStoreColor(Display* display, Colormap colormap, XColor* color) +{ + /* KLUDGE: set XHDC to 0 if the palette should NOT be realized after + setting the color. set XHDC to the correct HDC if it should. */ + + PALETTEENTRY pe; + + /* X11 stores color from 0-65535, Win32 expects them to be 0-256, so + twiddle the bits ( / 256). */ + pe.peRed = color->red / 256; + pe.peGreen = color->green / 256; + pe.peBlue = color->blue / 256; + + /* make sure we use this flag, otherwise the colors might get mapped + to another place in the colormap, and when we glIndex() that + color, it may have moved (argh!!) */ + pe.peFlags = PC_NOCOLLAPSE; + + /* the pixel field of the XColor structure is the index into the + colormap */ + SetPaletteEntries(colormap, color->pixel, 1, &pe); + + if (XHDC) { + UnrealizeObject(colormap); + SelectPalette(XHDC, colormap, FALSE); + RealizePalette(XHDC); + } +} + +void +XSetWindowColormap(Display* display, Window window, Colormap colormap) +{ + HDC hdc = GetDC(window); + + /* if the third parameter is FALSE, the logical colormap is copied + into the device palette when the application is in the + foreground, if it is TRUE, the colors are mapped into the current + palette in the best possible way. */ + SelectPalette(hdc, colormap, FALSE); + RealizePalette(hdc); + + /* note that we don't have to release the DC, since our window class + uses the WC_OWNDC flag! */ +} + +Bool +XTranslateCoordinates(Display *display, Window src, Window dst, + int src_x, int src_y, + int* dest_x_return, int* dest_y_return, + Window* child_return) +{ + /* KLUDGE: this isn't really a translate coordinates into some other + windows coordinate system...it only translates coordinates into the + root window (screen) coordinate system. */ + + POINT point; + + point.x = src_x; + point.y = src_y; + + ClientToScreen(src, &point); + + *dest_x_return = point.x; + *dest_y_return = point.y; + + /* just to make compilers happy...we don't use the return value. */ + return True; +} + +Status +XGetGeometry(Display* display, Window window, Window* root_return, + int* x_return, int* y_return, + unsigned int* width_return, unsigned int* height_return, + unsigned int *border_width_return, unsigned int* depth_return) +{ + /* KLUDGE: doesn't return the border_width or depth or root, x & y + are in screen coordinates. */ + + RECT rect; + POINT point; + + GetClientRect(window, &rect); + + point.x = 0; + point.y = 0; + ClientToScreen(window, &point); + + *x_return = point.x; + *y_return = point.y; + *width_return = rect.right; + *height_return = rect.bottom; + + /* just to make compilers happy...we don't use the return value. */ + return 1; +} + +int +DisplayWidthMM(Display* display, int screen) +{ + int width; + HWND hwnd = GetDesktopWindow(); + HDC hdc = GetDC(hwnd); + + width = GetDeviceCaps(hdc, HORZSIZE); + + /* make sure to release this DC (it's the desktops, not ours) */ + ReleaseDC(hwnd, hdc); + + return width; +} + +int +DisplayHeightMM(Display* display, int screen) +{ + int height; + HWND hwnd = GetDesktopWindow(); + HDC hdc = GetDC(hwnd); + + height = GetDeviceCaps(hdc, VERTSIZE); + + /* make sure to release this DC (it's the desktops, not ours) */ + ReleaseDC(hwnd, hdc); + + return height; +} + +void +XWarpPointer(Display* display, Window src, Window dst, + int src_x, int src_y, int src_width, int src_height, + int dst_x, int dst_y) +{ + /* KLUDGE: this isn't really a warp pointer into some other windows + coordinate system...it only warps the pointer into the root window + (screen) coordinate system. */ + + POINT point; + + point.x = dst_x; + point.y = dst_y; + ClientToScreen(dst, &point); + + SetCursorPos(point.x, point.y); +} + +int +XPending(Display* display) +{ + /* similar functionality...I don't think that it is exact, but this + will have to do. */ + MSG msg; + + return PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE); +} + +/* the following function was stolen from the X sources as indicated. */ + +/* Copyright Massachusetts Institute of Technology 1985, 1986, 1987 */ +/* $XConsortium: XParseGeom.c,v 11.18 91/02/21 17:23:05 rws Exp $ */ + +/* +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation, and that the name of M.I.T. not be used in advertising or +publicity pertaining to distribution of the software without specific, +written prior permission. M.I.T. makes no representations about the +suitability of this software for any purpose. It is provided "as is" +without express or implied warranty. +*/ + +/* + * XParseGeometry parses strings of the form + * "=x{+-}{+-}", where + * width, height, xoffset, and yoffset are unsigned integers. + * Example: "=80x24+300-49" + * The equal sign is optional. + * It returns a bitmask that indicates which of the four values + * were actually found in the string. For each value found, + * the corresponding argument is updated; for each value + * not found, the corresponding argument is left unchanged. + */ + +static int +ReadInteger(char *string, char **NextString) +{ + register int Result = 0; + int Sign = 1; + + if (*string == '+') + string++; + else if (*string == '-') + { + string++; + Sign = -1; + } + for (; (*string >= '0') && (*string <= '9'); string++) + { + Result = (Result * 10) + (*string - '0'); + } + *NextString = string; + if (Sign >= 0) + return (Result); + else + return (-Result); +} + +int XParseGeometry(char *string, int *x, int *y, unsigned int *width, unsigned int *height) +{ + int mask = NoValue; + register char *strind; + unsigned int tempWidth, tempHeight; + int tempX, tempY; + char *nextCharacter; + + if ( (string == NULL) || (*string == '\0')) return(mask); + if (*string == '=') + string++; /* ignore possible '=' at beg of geometry spec */ + + strind = (char *)string; + if (*strind != '+' && *strind != '-' && *strind != 'x') { + tempWidth = ReadInteger(strind, &nextCharacter); + if (strind == nextCharacter) + return (0); + strind = nextCharacter; + mask |= WidthValue; + } + + if (*strind == 'x' || *strind == 'X') { + strind++; + tempHeight = ReadInteger(strind, &nextCharacter); + if (strind == nextCharacter) + return (0); + strind = nextCharacter; + mask |= HeightValue; + } + + if ((*strind == '+') || (*strind == '-')) { + if (*strind == '-') { + strind++; + tempX = -ReadInteger(strind, &nextCharacter); + if (strind == nextCharacter) + return (0); + strind = nextCharacter; + mask |= XNegative; + + } + else + { strind++; + tempX = ReadInteger(strind, &nextCharacter); + if (strind == nextCharacter) + return(0); + strind = nextCharacter; + } + mask |= XValue; + if ((*strind == '+') || (*strind == '-')) { + if (*strind == '-') { + strind++; + tempY = -ReadInteger(strind, &nextCharacter); + if (strind == nextCharacter) + return(0); + strind = nextCharacter; + mask |= YNegative; + + } + else + { + strind++; + tempY = ReadInteger(strind, &nextCharacter); + if (strind == nextCharacter) + return(0); + strind = nextCharacter; + } + mask |= YValue; + } + } + + /* If strind isn't at the end of the string the it's an invalid + geometry specification. */ + + if (*strind != '\0') return (0); + + if (mask & XValue) + *x = tempX; + if (mask & YValue) + *y = tempY; + if (mask & WidthValue) + *width = tempWidth; + if (mask & HeightValue) + *height = tempHeight; + return (mask); +} diff --git a/glut/win32_x11.h b/glut/win32_x11.h new file mode 100644 index 0000000..bb49977 --- /dev/null +++ b/glut/win32_x11.h @@ -0,0 +1,319 @@ +#ifndef __win32_x11_h__ +#define __win32_x11_h__ + +/* Copyright (c) Nate Robins, 1997. */ + +/* This program is freely distributable without licensing fees + and is provided without guarantee or warrantee expressed or + implied. This program is -not- in the public domain. */ + +#include +#include + +/* Type definitions (conversions) */ +typedef int Visual; /* Win32 equivalent of X11 type */ +typedef HWND Window; +typedef HPALETTE Colormap; +typedef PIXELFORMATDESCRIPTOR XVisualInfo; +typedef BOOL Bool; +typedef MSG XEvent; +typedef HDC Display; +typedef HCURSOR Cursor; + +typedef int Atom; /* dummies */ +typedef int XDevice; +typedef int Status; + +#define True TRUE /* Win32 equivalents of X11 booleans */ +#define False FALSE + +#define None 0L /* universal null resource or null atom */ + +/* Input Event Masks. Used as event-mask window attribute and as arguments + to Grab requests. Not to be confused with event names. */ + +#define NoEventMask 0L +#define KeyPressMask (1L<<0) +#define KeyReleaseMask (1L<<1) +#define ButtonPressMask (1L<<2) +#define ButtonReleaseMask (1L<<3) +#define EnterWindowMask (1L<<4) +#define LeaveWindowMask (1L<<5) +#define PointerMotionMask (1L<<6) +#define PointerMotionHintMask (1L<<7) +#define Button1MotionMask (1L<<8) +#define Button2MotionMask (1L<<9) +#define Button3MotionMask (1L<<10) +#define Button4MotionMask (1L<<11) +#define Button5MotionMask (1L<<12) +#define ButtonMotionMask (1L<<13) +#define KeymapStateMask (1L<<14) +#define ExposureMask (1L<<15) +#define VisibilityChangeMask (1L<<16) +#define StructureNotifyMask (1L<<17) +#define ResizeRedirectMask (1L<<18) +#define SubstructureNotifyMask (1L<<19) +#define SubstructureRedirectMask (1L<<20) +#define FocusChangeMask (1L<<21) +#define PropertyChangeMask (1L<<22) +#define ColormapChangeMask (1L<<23) +#define OwnerGrabButtonMask (1L<<24) + +/* Key masks. Used as modifiers to GrabButton and GrabKey, results of + QueryPointer, state in various key-, mouse-, and button-related + events. */ + +#define ShiftMask (1<<0) +#define LockMask (1<<1) +#define ControlMask (1<<2) +#define Mod1Mask (1<<3) +#define Mod2Mask (1<<4) +#define Mod3Mask (1<<5) +#define Mod4Mask (1<<6) +#define Mod5Mask (1<<7) + +/* Window classes used by CreateWindow */ +/* Note that CopyFromParent is already defined as 0 above */ + +#define InputOutput 1 +#define InputOnly 2 + +/* Window attributes for CreateWindow and ChangeWindowAttributes */ + +#define CWBackPixmap (1L<<0) +#define CWBackPixel (1L<<1) +#define CWBorderPixmap (1L<<2) +#define CWBorderPixel (1L<<3) +#define CWBitGravity (1L<<4) +#define CWWinGravity (1L<<5) +#define CWBackingStore (1L<<6) +#define CWBackingPlanes (1L<<7) +#define CWBackingPixel (1L<<8) +#define CWOverrideRedirect (1L<<9) +#define CWSaveUnder (1L<<10) +#define CWEventMask (1L<<11) +#define CWDontPropagate (1L<<12) +#define CWColormap (1L<<13) +#define CWCursor (1L<<14) + +/* ConfigureWindow structure */ + +#define CWX (1<<0) +#define CWY (1<<1) +#define CWWidth (1<<2) +#define CWHeight (1<<3) +#define CWBorderWidth (1<<4) +#define CWSibling (1<<5) +#define CWStackMode (1<<6) + + +/* Used in GetWindowAttributes reply */ + +#define IsUnmapped 0 +#define IsUnviewable 1 +#define IsViewable 2 + +/* Window stacking method (in configureWindow) */ + +#define Above 0 +#define Below 1 +#define TopIf 2 +#define BottomIf 3 +#define Opposite 4 + +/* For CreateColormap */ + +#define AllocNone 0 /* create map with no entries */ +#define AllocAll 1 /* allocate entire map writeable */ + + +/* Flags used in StoreNamedColor, StoreColors */ + +#define DoRed (1<<0) +#define DoGreen (1<<1) +#define DoBlue (1<<2) + +/* + * Bitmask returned by XParseGeometry(). Each bit tells if the corresponding + * value (x, y, width, height) was found in the parsed string. + */ +#define NoValue 0x0000 +#define XValue 0x0001 +#define YValue 0x0002 +#define WidthValue 0x0004 +#define HeightValue 0x0008 +#define AllValues 0x000F +#define XNegative 0x0010 +#define YNegative 0x0020 + +/* flags argument in size hints */ +#define USPosition (1L << 0) /* user specified x, y */ +#define USSize (1L << 1) /* user specified width, height */ + +/* definitions for initial window state */ +#define WithdrawnState 0 /* for windows that are not mapped */ +#define NormalState 1 /* most applications want to start this way */ +#define IconicState 3 /* application wants to start as an icon */ +#define GameModeState 4 /* Win32 GLUT only (not in Xlib!). */ + +/* Type definitions */ + +typedef struct { + unsigned int background_pixmap; /* background pixmap */ + unsigned long background_pixel; /* background pixel */ + unsigned long border_pixel; /* border pixel value */ + long event_mask; /* set of events that should be saved */ + long do_not_propagate_mask; /* set of events that should not propagate */ + Bool override_redirect; /* boolean value for override-redirect */ + Colormap colormap; /* color map to be associated with window */ +} XSetWindowAttributes; + +typedef struct { + unsigned long pixel; + unsigned short red, green, blue; + char flags; /* do_red, do_green, do_blue */ +} XColor; + +typedef struct { + unsigned char *value; /* same as Property routines */ + Atom encoding; /* prop type */ + int format; /* prop data format: 8, 16, or 32 */ + unsigned long nitems; /* number of data items in value */ +} XTextProperty; + +typedef struct { + long flags; /* marks which fields in this structure are defined */ + int x, y; /* obsolete for new window mgrs, but clients */ + int width, height; /* should set so old wm's don't mess up */ +} XSizeHints; + +/* Functions emulated by macros. */ + +#define XFreeColormap(display, colormap) \ + DeleteObject(colormap) + +#define XCreateFontCursor(display, shape) \ + LoadCursor(NULL, shape) + +#define XDefineCursor(display, window, cursor) \ + SetCursor(cursor) + +#define XFlush(display) \ + /* Nothing. */ + +#define DisplayWidth(display, screen) \ + GetSystemMetrics(SM_CXSCREEN) + +#define DisplayHeight(display, screen) \ + GetSystemMetrics(SM_CYSCREEN) + +#define XMapWindow(display, window) \ + ShowWindow(window, SW_SHOWNORMAL) + +#define XUnmapWindow(display, window) \ + ShowWindow(window, SW_HIDE) + +#define XIconifyWindow(display, window, screen) \ + ShowWindow(window, SW_MINIMIZE) + +#define XWithdrawWindow(display, window, screen) \ + ShowWindow(window, SW_HIDE) + +#define XLowerWindow(display, window) \ + SetWindowPos(window, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE) + +#define XSetWMName(display, window, tp) \ + SetWindowText(window, (tp)->value) + +/* There really isn't a way to set the icon name separate from the + windows name in Win32, so, just set the windows name. */ +#define XSetWMIconName(display, window, tp) \ + XSetWMName(display, window, tp) + +#define XDestroyWindow(display, window) \ + DestroyWindow(window) + +/* Anything that needs to be freed was allocated with malloc in our + fake X windows library for Win32, so free it with plain old + free(). */ +#define XFree(data) \ + free(data) + +/* Nothing to be done for this...the pointer is always 'ungrabbed' + in Win32. */ +#define XUngrabPointer(display, time) \ + /* Nothing. */ + +/* Function prototypes. */ + +extern XVisualInfo* XGetVisualInfo( + Display* display, + long mask, + XVisualInfo* ttemplate, /* Avoid class with C++ keyword. */ + int*nitems); + +extern Colormap XCreateColormap( + Display* display, + Window root, + Visual* visual, + int alloc); + +extern void XAllocColorCells( + Display* display, + Colormap colormap, + Bool contig, + unsigned long plane_masks_return[], + unsigned int nplanes, + unsigned long pixels_return[], + unsigned int npixels); + +extern void XStoreColor( + Display* display, + Colormap colormap, + XColor* color); + +extern void XSetWindowColormap( + Display* display, + Window window, + Colormap colormap); + +extern Bool XTranslateCoordinates( + Display *display, + Window src, Window dst, + int src_x, int src_y, + int* dest_x_return, int* dest_y_return, + Window* child_return); + +extern Status XGetGeometry( + Display* display, + Window window, + Window* root_return, + int* x_return, int* y_return, + unsigned int* width_return, unsigned int* height_return, + unsigned int *border_width_return, + unsigned int* depth_return); + +extern int DisplayWidthMM( + Display* display, + int screen); + +extern int DisplayHeightMM( + Display* display, + int screen); + +extern void XWarpPointer( + Display* display, + Window src, Window dst, + int src_x, int src_y, + int src_width, int src_height, + int dst_x, int dst_y); + +extern int XParseGeometry( + char* string, + int* x, int* y, + unsigned int* width, unsigned int* height); + +extern int XPending( + Display* display); + +#endif /* __win32_x11_h__ */ diff --git a/hosts.make b/hosts.make new file mode 100644 index 0000000..fac8adc --- /dev/null +++ b/hosts.make @@ -0,0 +1,2 @@ +BOINCDIR = /disks/ellie/a/users/korpela/boinc + diff --git a/image_libs/bmplib.cpp b/image_libs/bmplib.cpp new file mode 100644 index 0000000..cf41d76 --- /dev/null +++ b/image_libs/bmplib.cpp @@ -0,0 +1,188 @@ +#include + +#ifdef _WIN32 +#include "windows.h" +#endif + +#include "bmplib.h" + +// Returns true for success -- false otherwise +bool DIB_BITMAP::set_size(int width, int height, int channels) +{ + + // If DIB_BITMAP has already been set -- clear it out first + FreeDIB_BMP(); + + // Create a temporary compatible device context + HDC temp_hdc = CreateCompatibleDC(NULL); + + // Error Check + if(!temp_hdc) + return false; + + bmp_width = width; // Set the width + bmp_height = height; // Set the height + bmp_channels = channels; // Set the channels (3 == 24-bit, 4 == 32-bit) + + // Set stride -- The stride is the TRUE number of bytes in a line of pixels + // Windows makes all the .bmps DWORD aligned (divisible evenly by 4) + // So if you bitmap say was 103x103 pixels, Windows would add 1 "padding byte" to it + // so in memory it would be 104x103 pixels. The "padding bytes" do not get blit (drawn) + // to the screen, they're just there so again everything is DWORD aligned which makes + // blitting (drawing to the screen) easier for the OS + bmp_stride = bmp_width * bmp_channels; + + while((bmp_stride % 4) != 0) // Ensure bmp_stride is DWORD aligned + bmp_stride++; + + BITMAPINFO bmp_info = {0}; + + // Initialize the parameters that we care about + bmp_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmp_info.bmiHeader.biWidth = width; + bmp_info.bmiHeader.biHeight = height; + bmp_info.bmiHeader.biPlanes = 1; // Always equal 1 + bmp_info.bmiHeader.biBitCount = channels * 8; + bmp_info.bmiHeader.biCompression = BI_RGB; // No compression + bmp_info.bmiHeader.biClrUsed = 0; // Always equals 0 with a 24 or 32-bit .bmp + + // Create a DIBSection -- This returns us two things, an HBITMAP handle and + // a memory pointer (pointer to the pixels) in surface_bits + hbitmap = CreateDIBSection(temp_hdc, &bmp_info, DIB_RGB_COLORS, + (void**)&surface_bits, 0, 0); + + // Release our temporary HDC + DeleteDC(temp_hdc); + + // Error Check -- Make sure the call to CreateDIBSection() DID NOT fail + if(!hbitmap) + return false; + + return true; // We're sized :) + +} // end of set_size(int width, int height, int channels) + +bool DIB_BITMAP::loadBMP(const char *file_name) +{ + // If DIB_BITMAP has already been set -- clear it out first + FreeDIB_BMP(); + + // Error Check -- Make sure they passed in a valid file name + if(!file_name) + return false; + + FILE *bmp_file = fopen(file_name, "rb"); + + // Error Check -- Make sure the file could be opened + if(!bmp_file) + return false; + + BITMAPFILEHEADER bmp_fileheader; + + // Read the BITMAPFILEHEADER + if(!fread(&bmp_fileheader, sizeof(BITMAPFILEHEADER), 1, bmp_file)) + { + fclose(bmp_file); + return false; + } + + // Check the type field to make sure we have a .bmp file + if(memcmp(&bmp_fileheader.bfType, "BM", 2)) + { + fclose(bmp_file); + return false; + } + + BITMAPINFOHEADER bmp_infoheader; + + // Read the BITMAPINFOHEADER. + if(!fread(&bmp_infoheader, sizeof(BITMAPINFOHEADER), 1, bmp_file)) + { + fclose(bmp_file); + return false; + } + + // We only support 24-bit and 32-bit .bmps so make sure that's what we have + if((bmp_infoheader.biBitCount != 24) && (bmp_infoheader.biBitCount != 32)) + { + fclose(bmp_file); + return false; + } + + // Set the size of our DIB_BITMAP, once we do this we're ready to store the pixel + // data in it + if(set_size(bmp_infoheader.biWidth,bmp_infoheader.biHeight,bmp_infoheader.biBitCount / 8) == false) + { + fclose(bmp_file); + return false; + } + + // Jump to the location where the pixel data is stored + if(fseek(bmp_file, bmp_fileheader.bfOffBits, SEEK_SET)) + { + fclose(bmp_file); + return false; + } + + unsigned int bytesPerLine = bmp_width * bmp_channels; // Bytes per line (number of bytes + // in a scan line) + + // Calculate how many "padding" bytes there are -- WE DO NOT want to read in the + // padding bytes (we will just skip over those) + // **Remember** Windows adds padding bytes to ensure ALL .bmps are DWORD aligned + // (divisible evenly by 4) + unsigned int padding = bmp_stride - bytesPerLine; + + // Loop over all the scan lines (all the rows of pixels in the image) + for(int y = bmp_height-1; y >= 0; y--) + { + // Get the "current" line pointer + uchar *LinePtr = getLinePtr(y); + + // Read the precise number of bytes that the scan line requires into the bitmap + if(!fread(LinePtr, bytesPerLine, 1, bmp_file)) + { + fclose(bmp_file); + return false; + } + + // Skip over any padding bytes. + if(fseek(bmp_file, padding, SEEK_CUR)) + { + fclose(bmp_file); + return false; + } + + } // end of for (int y = 0; y < bmp_infoheader.biHeight; y++) + + + fclose(bmp_file); + return true; // If we get here .bmp was read in successfully + +} // end of loadBMP(char *file_name, HDC hdc) + +// Returns the address in memory of the specified line. This gives you a pointer to at least +// width * channels bytes. Lines are numbered such that when the bitmap +// is displayed line zero is at the top. +uchar* DIB_BITMAP::getLinePtr(int which_line) +{ + return (surface_bits + bmp_stride * which_line); +} + +// Release the memory +void DIB_BITMAP::FreeDIB_BMP() +{ + // If we created an HBITMAP, delete it + if(hbitmap) + DeleteObject(hbitmap); + + // Zero out all data associated with DIB_BITMAP + hbitmap = NULL; + surface_bits = NULL; + bmp_width = bmp_height = bmp_channels = bmp_stride = 0; + return; +} + +// Deconstructor +DIB_BITMAP::~DIB_BITMAP() { FreeDIB_BMP(); } + diff --git a/image_libs/bmplib.h b/image_libs/bmplib.h new file mode 100644 index 0000000..02385dd --- /dev/null +++ b/image_libs/bmplib.h @@ -0,0 +1,57 @@ +#ifndef BITMAP_CLASS_H +#define BITMAP_CLASS_H + +typedef unsigned char uchar; // We're lazy so typedef "unsigned char" as "uchar" + +// We will use this class to load 24 and 32-bit .bmp for us +class DIB_BITMAP +{ + public: + + // Constructor() -- Zero's out DIB_BITMAP + DIB_BITMAP():hbitmap(NULL),surface_bits(NULL),bmp_width(0),bmp_height(0), + bmp_channels(0),bmp_stride(0) { GdiFlush(); /* Guarantee that writing to + DIB_BITMAP is okay */ } + + // Data Access Functions ************ + + inline int get_width() const { return bmp_width; } + inline int get_height() const { return bmp_height; } + inline int get_channels() const { return bmp_channels; } + inline int get_stride() const { return bmp_stride; } + + // ****** End of Data Access Functions + + // Creates a "empty" DIB_BITMAP with the "traits" of the parameters passed in + // Returns true for success -- false otherwise + // If set_size is called on a DIB_BITMAP that already has memory associated with it + // that memory is freed and the new size is implemented + bool set_size(int width, int height, int channels); + + // Loads a bmp with specified file_name -- Returns true on success, false otherwise + // If loadBMP() is called on a DIB_BITMAP that already has memory associated with + // it, that memory is freed and the .bmp is loaded + bool loadBMP(const char *file_name); + + uchar* getLinePtr(int which_line); // returns a pointer to the line passed in + + // Deconstructor(); + ~DIB_BITMAP(); + + + private: + + int bmp_width; // The width of the bitmap + int bmp_height; // The height of the bitmap + int bmp_channels; // How many channels is the bitmap (3 == 24-bit, 4 == 32-bit) + int bmp_stride; // The TRUE number of bytes in a scan line (in a line of pixels + // in memory) + + HBITMAP hbitmap; // This will be the handle to our bitmap + + uchar *surface_bits; // This is a pointer to the actual pixels of the bitmap + + void FreeDIB_BMP(); // Frees all memory associated with DIB_BITMAP +}; + +#endif diff --git a/image_libs/tgalib.cpp b/image_libs/tgalib.cpp new file mode 100644 index 0000000..8f1f81d --- /dev/null +++ b/image_libs/tgalib.cpp @@ -0,0 +1,239 @@ + + +#include "tgalib.h" + +tImageTGA *LoadTGA(const char *filename) +{ + tImageTGA *pImageData = NULL; // This stores our important image data + WORD width = 0, height = 0; // The dimensions of the image + byte length = 0; // The length in bytes to the pixels + byte imageType = 0; // The image type (RLE, RGB, Alpha...) + byte bits = 0; // The bits per pixel for the image (16, 24, 32) + FILE *pFile = NULL; // The file pointer + int channels = 0; // The channels of the image (3 = RGA : 4 = RGBA) + int stride = 0; // The stride (channels * width) + int i = 0; // A counter + + // This function loads in a TARGA (.TGA) file and returns its data to be + // used as a texture or what have you. This currently loads in a 16, 24 + // and 32-bit targa file, along with RLE compressed files. Eventually you + // will want to do more error checking to make it more robust. This is + // also a perfect start to go into a modular class for an engine. + // Basically, how it works is, you read in the header information, then + // move your file pointer to the pixel data. Before reading in the pixel + // data, we check to see the if it's an RLE compressed image. This is because + // we will handle it different. If it isn't compressed, then we need another + // check to see if we need to convert it from 16-bit to 24 bit. 24-bit and + // 32-bit textures are very similar, so there's no need to do anything special. + // We do, however, read in an extra bit for each color. + + // Open a file pointer to the targa file and check if it was found and opened + if((pFile = fopen(filename, "rb")) == NULL) + { + return NULL; + } + + // Allocate the structure that will hold our eventual image data (must free it!) + pImageData = (tImageTGA*)malloc(sizeof(tImageTGA)); + + // Read in the length in bytes from the header to the pixel data + fread(&length, sizeof(byte), 1, pFile); + + // Jump over one byte + fseek(pFile,1,SEEK_CUR); + + // Read in the imageType (RLE, RGB, etc...) + fread(&imageType, sizeof(byte), 1, pFile); + + // Skip past general information we don't care about + fseek(pFile, 9, SEEK_CUR); + + // Read the width, height and bits per pixel (16, 24 or 32) + fread(&width, sizeof(WORD), 1, pFile); + fread(&height, sizeof(WORD), 1, pFile); + fread(&bits, sizeof(byte), 1, pFile); + + // Now we move the file pointer to the pixel data + fseek(pFile, length + 1, SEEK_CUR); + + // Check if the image is RLE compressed or not + if(imageType != TGA_RLE) + { + // Check if the image is a 24 or 32-bit image + if(bits == 24 || bits == 32) + { + // Calculate the channels (3 or 4) - (use bits >> 3 for more speed). + // Next, we calculate the stride and allocate enough memory for the pixels. + channels = bits / 8; + stride = channels * width; + pImageData->data = new unsigned char[stride * height]; + + // Load in all the pixel data line by line + for(int y = 0; y < height; y++) + { + // Store a pointer to the current line of pixels + unsigned char *pLine = &(pImageData->data[stride * y]); + + // Read in the current line of pixels + fread(pLine, stride, 1, pFile); + + // Go through all of the pixels and swap the B and R values since TGA + // files are stored as BGR instead of RGB (or use GL_BGR_EXT verses GL_RGB) + for(i = 0; i < stride; i += channels) + { + int temp = pLine[i]; + pLine[i] = pLine[i + 2]; + pLine[i + 2] = temp; + } + } + } + // Check if the image is a 16 bit image (RGB stored in 1 unsigned short) + else if(bits == 16) + { + unsigned short pixels = 0; + int r=0, g=0, b=0; + + // Since we convert 16-bit images to 24 bit, we hardcode the channels to 3. + // We then calculate the stride and allocate memory for the pixels. + channels = 3; + stride = channels * width; + pImageData->data = new unsigned char[stride * height]; + + // Load in all the pixel data pixel by pixel + for(int i = 0; i < width*height; i++) + { + // Read in the current pixel + fread(&pixels, sizeof(unsigned short), 1, pFile); + + // To convert a 16-bit pixel into an R, G, B, we need to + // do some masking and such to isolate each color value. + // 0x1f = 11111 in binary, so since 5 bits are reserved in + // each unsigned short for the R, G and B, we bit shift and mask + // to find each value. We then bit shift up by 3 to get the full color. + b = (pixels & 0x1f) << 3; + g = ((pixels >> 5) & 0x1f) << 3; + r = ((pixels >> 10) & 0x1f) << 3; + + // This essentially assigns the color to our array and swaps the + // B and R values at the same time. + pImageData->data[i * 3 + 0] = r; + pImageData->data[i * 3 + 1] = g; + pImageData->data[i * 3 + 2] = b; + } + } + // Else return a NULL for a bad or unsupported pixel format + else + return NULL; + } + // Else, it must be Run-Length Encoded (RLE) + else + { + // First, let me explain real quickly what RLE is. + // For further information, check out Paul Bourke's intro article at: + // http://astronomy.swin.edu.au/~pbourke/dataformats/rle/ + // + // Anyway, we know that RLE is a basic type compression. It takes + // colors that are next to each other and then shrinks that info down + // into the color and a integer that tells how much of that color is used. + // For instance: + // aaaaabbcccccccc would turn into a5b2c8 + // Well, that's fine and dandy and all, but how is it down with RGB colors? + // Simple, you read in an color count (rleID), and if that number is less than 128, + // it does NOT have any optimization for those colors, so we just read the next + // pixels normally. Say, the color count was 28, we read in 28 colors like normal. + // If the color count is over 128, that means that the next color is optimized and + // we want to read in the same pixel color for a count of (colorCount - 127). + // It's 127 because we add 1 to the color count, as you'll notice in the code. + + // Create some variables to hold the rleID, current colors read, channels, & stride. + byte rleID = 0; + int colorsRead = 0; + channels = bits / 8; + stride = channels * width; + + // Next we want to allocate the memory for the pixels and create an array, + // depending on the channel count, to read in for each pixel. + pImageData->data = new unsigned char[stride * height]; + byte *pColors = new byte [channels]; + + // Load in all the pixel data + while(i < width*height) + { + // Read in the current color count + 1 + fread(&rleID, sizeof(byte), 1, pFile); + + // Check if we don't have an encoded string of colors + if(rleID < 128) + { + // Increase the count by 1 + rleID++; + + // Go through and read all the unique colors found + while(rleID) + { + // Read in the current color + fread(pColors, sizeof(byte) * channels, 1, pFile); + + // Store the current pixel in our image array + pImageData->data[colorsRead + 0] = pColors[2]; + pImageData->data[colorsRead + 1] = pColors[1]; + pImageData->data[colorsRead + 2] = pColors[0]; + + // If we have a 4 channel 32-bit image, assign one more for the alpha + if(bits == 32) + pImageData->data[colorsRead + 3] = pColors[3]; + + // Increase the current pixels read, decrease the amount + // of pixels left, and increase the starting index for the next pixel. + i++; + rleID--; + colorsRead += channels; + } + } + // Else, let's read in a string of the same character + else + { + // Minus the 128 ID + 1 (127) to get the color count that needs to be read + rleID -= 127; + + // Read in the current color, which is the same for a while + fread(pColors, sizeof(byte) * channels, 1, pFile); + + // Go and read as many pixels as are the same + while(rleID) + { + // Assign the current pixel to the current index in our pixel array + pImageData->data[colorsRead + 0] = pColors[2]; + pImageData->data[colorsRead + 1] = pColors[1]; + pImageData->data[colorsRead + 2] = pColors[0]; + + // If we have a 4 channel 32-bit image, assign one more for the alpha + if(bits == 32) + pImageData->data[colorsRead + 3] = pColors[3]; + + // Increase the current pixels read, decrease the amount + // of pixels left, and increase the starting index for the next pixel. + i++; + rleID--; + colorsRead += channels; + } + + } + + } + + // Free up pColors + delete[] pColors; + } + + // Close the file pointer that opened the file + fclose(pFile); + + // Fill in our tImageTGA structure to pass back + pImageData->channels = channels; + pImageData->sizeX = width; + pImageData->sizeY = height; + + // Return the TGA data (remember, you must free this data after you are done) + return pImageData; +} diff --git a/image_libs/tgalib.h b/image_libs/tgalib.h new file mode 100644 index 0000000..eeba871 --- /dev/null +++ b/image_libs/tgalib.h @@ -0,0 +1,22 @@ +#ifndef TGALIB_H +#define TGALIB_H + + +#include +#include + +#define TGA_RGB 2 // This tells us it's a normal RGB (really BGR) file +#define TGA_A 3 // This tells us it's a ALPHA file +#define TGA_RLE 10 // This tells us that the targa is Run-Length Encoded (RLE) + +struct tImageTGA +{ + int channels; // The channels in the image (3 = RGB : 4 = RGBA) + int sizeX; // The width of the image in pixels + int sizeY; // The height of the image in pixels + unsigned char *data; // The image pixel data +}; + +tImageTGA *LoadTGA(const char *filename); + +#endif diff --git a/install-sh b/install-sh new file mode 100644 index 0000000..e9de238 --- /dev/null +++ b/install-sh @@ -0,0 +1,251 @@ +#!/bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + chmodcmd="" + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/ltmain.sh b/ltmain.sh new file mode 100644 index 0000000..cefb69d --- /dev/null +++ b/ltmain.sh @@ -0,0 +1,6496 @@ +# ltmain.sh - Provide generalized library-building support services. +# NOTE: Changing this file will not affect anything until you rerun configure. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# Originally by Gordon Matzigkeit , 1996 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +basename="s,^.*/,,g" + +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath="$0" + +# The name of this program: +progname=`echo "$progpath" | $SED $basename` +modename="$progname" + +# Global variables: +EXIT_SUCCESS=0 +EXIT_FAILURE=1 + +PROGRAM=ltmain.sh +PACKAGE=libtool +VERSION=1.5.16 +TIMESTAMP=" (1.1220.2.234 2005/04/24 17:45:58)" + +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes. +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +# Check that we have a working $echo. +if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then + # Yippee, $echo works! + : +else + # Restart under the correct shell, and then maybe $echo will work. + exec $SHELL "$progpath" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat <&2 + $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit $EXIT_FAILURE +fi + +# Global variables. +mode=$default_mode +nonopt= +prev= +prevopt= +run= +show="$echo" +show_help= +execute_dlfiles= +lo2o="s/\\.lo\$/.${objext}/" +o2lo="s/\\.${objext}\$/.lo/" +quote_scanset='[[~#^*{};<>?'"'"' ]' + +##################################### +# Shell function definitions: +# This seems to be the best place for them + +# func_win32_libid arg +# return the library type of file 'arg' +# +# Need a lot of goo to handle *both* DLLs and import libs +# Has to be a shell function in order to 'eat' the argument +# that is supplied when $file_magic_command is called. +func_win32_libid () +{ + win32_libid_type="unknown" + win32_fileres=`file -L $1 2>/dev/null` + case $win32_fileres in + *ar\ archive\ import\ library*) # definitely import + win32_libid_type="x86 archive import" + ;; + *ar\ archive*) # could be an import, or static + if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | \ + $EGREP -e 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then + win32_nmres=`eval $NM -f posix -A $1 | \ + sed -n -e '1,100{/ I /{x;/import/!{s/^/import/;h;p;};x;};}'` + if test "X$win32_nmres" = "Ximport" ; then + win32_libid_type="x86 archive import" + else + win32_libid_type="x86 archive static" + fi + fi + ;; + *DLL*) + win32_libid_type="x86 DLL" + ;; + *executable*) # but shell scripts are "executable" too... + case $win32_fileres in + *MS\ Windows\ PE\ Intel*) + win32_libid_type="x86 DLL" + ;; + esac + ;; + esac + $echo $win32_libid_type +} + + +# func_infer_tag arg +# Infer tagged configuration to use if any are available and +# if one wasn't chosen via the "--tag" command line option. +# Only attempt this if the compiler in the base compile +# command doesn't match the default compiler. +# arg is usually of the form 'gcc ...' +func_infer_tag () +{ + if test -n "$available_tags" && test -z "$tagname"; then + CC_quoted= + for arg in $CC; do + case $arg in + *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") + arg="\"$arg\"" + ;; + esac + CC_quoted="$CC_quoted $arg" + done + case $@ in + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when configure was run. + " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) ;; + # Blanks at the start of $base_compile will cause this to fail + # if we don't check for them as well. + *) + for z in $available_tags; do + if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" + CC_quoted= + for arg in $CC; do + # Double-quote args containing other shell metacharacters. + case $arg in + *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") + arg="\"$arg\"" + ;; + esac + CC_quoted="$CC_quoted $arg" + done + case "$@ " in + " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) + # The compiler in the base compile command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + $echo "$modename: unable to infer tagged configuration" + $echo "$modename: specify a tag with \`--tag'" 1>&2 + exit $EXIT_FAILURE +# else +# $echo "$modename: using $tagname tagged configuration" + fi + ;; + esac + fi +} + + +# func_extract_an_archive dir oldlib +func_extract_an_archive () +{ + f_ex_an_ar_dir="$1"; shift + f_ex_an_ar_oldlib="$1" + + $show "(cd $f_ex_an_ar_dir && $AR x $f_ex_an_ar_oldlib)" + $run eval "(cd \$f_ex_an_ar_dir && $AR x \$f_ex_an_ar_oldlib)" || exit $? + if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then + : + else + $echo "$modename: ERROR: object name conflicts: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" 1>&2 + exit $EXIT_FAILURE + fi +} + +# func_extract_archives gentop oldlib ... +func_extract_archives () +{ + my_gentop="$1"; shift + my_oldlibs=${1+"$@"} + my_oldobjs="" + my_xlib="" + my_xabs="" + my_xdir="" + my_status="" + + $show "${rm}r $my_gentop" + $run ${rm}r "$my_gentop" + $show "$mkdir $my_gentop" + $run $mkdir "$my_gentop" + my_status=$? + if test "$my_status" -ne 0 && test ! -d "$my_gentop"; then + exit $my_status + fi + + for my_xlib in $my_oldlibs; do + # Extract the objects. + case $my_xlib in + [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; + *) my_xabs=`pwd`"/$my_xlib" ;; + esac + my_xlib=`$echo "X$my_xlib" | $Xsed -e 's%^.*/%%'` + my_xdir="$my_gentop/$my_xlib" + + $show "${rm}r $my_xdir" + $run ${rm}r "$my_xdir" + $show "$mkdir $my_xdir" + $run $mkdir "$my_xdir" + status=$? + if test "$status" -ne 0 && test ! -d "$my_xdir"; then + exit $status + fi + case $host in + *-darwin*) + $show "Extracting $my_xabs" + # Do not bother doing anything if just a dry run + if test -z "$run"; then + darwin_orig_dir=`pwd` + cd $my_xdir || exit $? + darwin_archive=$my_xabs + darwin_curdir=`pwd` + darwin_base_archive=`$echo "X$darwin_archive" | $Xsed -e 's%^.*/%%'` + darwin_arches=`lipo -info "$darwin_archive" 2>/dev/null | $EGREP Architectures 2>/dev/null` + if test -n "$darwin_arches"; then + darwin_arches=`echo "$darwin_arches" | $SED -e 's/.*are://'` + darwin_arch= + $show "$darwin_base_archive has multiple architectures $darwin_arches" + for darwin_arch in $darwin_arches ; do + mkdir -p "unfat-$$/${darwin_base_archive}-${darwin_arch}" + lipo -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" + cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" + func_extract_an_archive "`pwd`" "${darwin_base_archive}" + cd "$darwin_curdir" + $rm "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" + done # $darwin_arches + ## Okay now we have a bunch of thin objects, gotta fatten them up :) + darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print| xargs basename | sort -u | $NL2SP` + darwin_file= + darwin_files= + for darwin_file in $darwin_filelist; do + darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP` + lipo -create -output "$darwin_file" $darwin_files + done # $darwin_filelist + ${rm}r unfat-$$ + cd "$darwin_orig_dir" + else + cd "$darwin_orig_dir" + func_extract_an_archive "$my_xdir" "$my_xabs" + fi # $darwin_arches + fi # $run + ;; + *) + func_extract_an_archive "$my_xdir" "$my_xabs" + ;; + esac + my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP` + done + func_extract_archives_result="$my_oldobjs" +} +# End of Shell function definitions +##################################### + +# Darwin sucks +eval std_shrext=\"$shrext_cmds\" + +# Parse our command line options once, thoroughly. +while test "$#" -gt 0 +do + arg="$1" + shift + + case $arg in + -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + execute_dlfiles) + execute_dlfiles="$execute_dlfiles $arg" + ;; + tag) + tagname="$arg" + preserve_args="${preserve_args}=$arg" + + # Check whether tagname contains only valid characters + case $tagname in + *[!-_A-Za-z0-9,/]*) + $echo "$progname: invalid tag name: $tagname" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + case $tagname in + CC) + # Don't test for the "default" C tag, as we know, it's there, but + # not specially marked. + ;; + *) + if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "$progpath" > /dev/null; then + taglist="$taglist $tagname" + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$tagname'$/,/^# ### END LIBTOOL TAG CONFIG: '$tagname'$/p' < $progpath`" + else + $echo "$progname: ignoring unknown tag $tagname" 1>&2 + fi + ;; + esac + ;; + *) + eval "$prev=\$arg" + ;; + esac + + prev= + prevopt= + continue + fi + + # Have we seen a non-optional argument yet? + case $arg in + --help) + show_help=yes + ;; + + --version) + $echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP" + $echo + $echo "Copyright (C) 2005 Free Software Foundation, Inc." + $echo "This is free software; see the source for copying conditions. There is NO" + $echo "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + exit $? + ;; + + --config) + ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $progpath + # Now print the configurations for the tags. + for tagname in $taglist; do + ${SED} -n -e "/^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$/,/^# ### END LIBTOOL TAG CONFIG: $tagname$/p" < "$progpath" + done + exit $? + ;; + + --debug) + $echo "$progname: enabling shell trace mode" + set -x + preserve_args="$preserve_args $arg" + ;; + + --dry-run | -n) + run=: + ;; + + --features) + $echo "host: $host" + if test "$build_libtool_libs" = yes; then + $echo "enable shared libraries" + else + $echo "disable shared libraries" + fi + if test "$build_old_libs" = yes; then + $echo "enable static libraries" + else + $echo "disable static libraries" + fi + exit $? + ;; + + --finish) mode="finish" ;; + + --mode) prevopt="--mode" prev=mode ;; + --mode=*) mode="$optarg" ;; + + --preserve-dup-deps) duplicate_deps="yes" ;; + + --quiet | --silent) + show=: + preserve_args="$preserve_args $arg" + ;; + + --tag) prevopt="--tag" prev=tag ;; + --tag=*) + set tag "$optarg" ${1+"$@"} + shift + prev=tag + preserve_args="$preserve_args --tag" + ;; + + -dlopen) + prevopt="-dlopen" + prev=execute_dlfiles + ;; + + -*) + $echo "$modename: unrecognized option \`$arg'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; + + *) + nonopt="$arg" + break + ;; + esac +done + +if test -n "$prevopt"; then + $echo "$modename: option \`$prevopt' requires an argument" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE +fi + +# If this variable is set in any of the actions, the command in it +# will be execed at the end. This prevents here-documents from being +# left over by shells. +exec_cmd= + +if test -z "$show_help"; then + + # Infer the operation mode. + if test -z "$mode"; then + $echo "*** Warning: inferring the mode of operation is deprecated." 1>&2 + $echo "*** Future versions of Libtool will require --mode=MODE be specified." 1>&2 + case $nonopt in + *cc | cc* | *++ | gcc* | *-gcc* | g++* | xlc*) + mode=link + for arg + do + case $arg in + -c) + mode=compile + break + ;; + esac + done + ;; + *db | *dbx | *strace | *truss) + mode=execute + ;; + *install*|cp|mv) + mode=install + ;; + *rm) + mode=uninstall + ;; + *) + # If we have no mode, but dlfiles were specified, then do execute mode. + test -n "$execute_dlfiles" && mode=execute + + # Just use the default operation mode. + if test -z "$mode"; then + if test -n "$nonopt"; then + $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2 + else + $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2 + fi + fi + ;; + esac + fi + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$execute_dlfiles" && test "$mode" != execute; then + $echo "$modename: unrecognized option \`-dlopen'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Change the help message to a mode-specific one. + generic_help="$help" + help="Try \`$modename --help --mode=$mode' for more information." + + # These modes are in order of execution frequency so that they run quickly. + case $mode in + # libtool compile mode + compile) + modename="$modename: compile" + # Get the compilation command and the source file. + base_compile= + srcfile="$nonopt" # always keep a non-empty value in "srcfile" + suppress_opt=yes + suppress_output= + arg_mode=normal + libobj= + later= + + for arg + do + case "$arg_mode" in + arg ) + # do not "continue". Instead, add this to base_compile + lastarg="$arg" + arg_mode=normal + ;; + + target ) + libobj="$arg" + arg_mode=normal + continue + ;; + + normal ) + # Accept any command-line options. + case $arg in + -o) + if test -n "$libobj" ; then + $echo "$modename: you cannot specify \`-o' more than once" 1>&2 + exit $EXIT_FAILURE + fi + arg_mode=target + continue + ;; + + -static | -prefer-pic | -prefer-non-pic) + later="$later $arg" + continue + ;; + + -no-suppress) + suppress_opt=no + continue + ;; + + -Xcompiler) + arg_mode=arg # the next one goes into the "base_compile" arg list + continue # The current "srcfile" will either be retained or + ;; # replaced later. I would guess that would be a bug. + + -Wc,*) + args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"` + lastarg= + save_ifs="$IFS"; IFS=',' + for arg in $args; do + IFS="$save_ifs" + + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + case $arg in + *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") + arg="\"$arg\"" + ;; + esac + lastarg="$lastarg $arg" + done + IFS="$save_ifs" + lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"` + + # Add the arguments to base_compile. + base_compile="$base_compile $lastarg" + continue + ;; + + * ) + # Accept the current argument as the source file. + # The previous "srcfile" becomes the current argument. + # + lastarg="$srcfile" + srcfile="$arg" + ;; + esac # case $arg + ;; + esac # case $arg_mode + + # Aesthetically quote the previous argument. + lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"` + + case $lastarg in + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, and some SunOS ksh mistreat backslash-escaping + # in scan sets (worked around with variable expansion), + # and furthermore cannot handle '|' '&' '(' ')' in scan sets + # at all, so we specify them separately. + *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") + lastarg="\"$lastarg\"" + ;; + esac + + base_compile="$base_compile $lastarg" + done # for arg + + case $arg_mode in + arg) + $echo "$modename: you must specify an argument for -Xcompile" + exit $EXIT_FAILURE + ;; + target) + $echo "$modename: you must specify a target with \`-o'" 1>&2 + exit $EXIT_FAILURE + ;; + *) + # Get the name of the library object. + [ -z "$libobj" ] && libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'` + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + xform='[cCFSifmso]' + case $libobj in + *.ada) xform=ada ;; + *.adb) xform=adb ;; + *.ads) xform=ads ;; + *.asm) xform=asm ;; + *.c++) xform=c++ ;; + *.cc) xform=cc ;; + *.ii) xform=ii ;; + *.class) xform=class ;; + *.cpp) xform=cpp ;; + *.cxx) xform=cxx ;; + *.f90) xform=f90 ;; + *.for) xform=for ;; + *.java) xform=java ;; + esac + + libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"` + + case $libobj in + *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;; + *) + $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + func_infer_tag $base_compile + + for arg in $later; do + case $arg in + -static) + build_old_libs=yes + continue + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + esac + done + + qlibobj=`$echo "X$libobj" | $Xsed -e "$sed_quote_subst"` + case $qlibobj in + *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") + qlibobj="\"$qlibobj\"" ;; + esac + if test "X$libobj" != "X$qlibobj"; then + $echo "$modename: libobj name \`$libobj' may not contain shell special characters." + exit $EXIT_FAILURE + fi + objname=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` + xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$obj"; then + xdir= + else + xdir=$xdir/ + fi + lobj=${xdir}$objdir/$objname + + if test -z "$base_compile"; then + $echo "$modename: you must specify a compilation command" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Delete any leftover library objects. + if test "$build_old_libs" = yes; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + $run $rm $removelist + trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15 + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2*) + pic_mode=default + ;; + esac + if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test "$compiler_c_o" = no; then + output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} + lockfile="$output_obj.lock" + removelist="$removelist $output_obj $lockfile" + trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15 + else + output_obj= + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test "$need_locks" = yes; then + until $run ln "$progpath" "$lockfile" 2>/dev/null; do + $show "Waiting for $lockfile to be removed" + sleep 2 + done + elif test "$need_locks" = warn; then + if test -f "$lockfile"; then + $echo "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit $EXIT_FAILURE + fi + $echo "$srcfile" > "$lockfile" + fi + + if test -n "$fix_srcfile_path"; then + eval srcfile=\"$fix_srcfile_path\" + fi + qsrcfile=`$echo "X$srcfile" | $Xsed -e "$sed_quote_subst"` + case $qsrcfile in + *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") + qsrcfile="\"$qsrcfile\"" ;; + esac + + $run $rm "$libobj" "${libobj}T" + + # Create a libtool object file (analogous to a ".la" file), + # but don't create it if we're doing a dry run. + test -z "$run" && cat > ${libobj}T </dev/null`" != "X$srcfile"; then + $echo "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed, then go on to compile the next one + if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then + $show "$mv $output_obj $lobj" + if $run $mv $output_obj $lobj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Append the name of the PIC object to the libtool object file. + test -z "$run" && cat >> ${libobj}T <> ${libobj}T </dev/null`" != "X$srcfile"; then + $echo "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed + if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then + $show "$mv $output_obj $obj" + if $run $mv $output_obj $obj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Append the name of the non-PIC object the libtool object file. + # Only append if the libtool object file exists. + test -z "$run" && cat >> ${libobj}T <> ${libobj}T <&2 + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + else + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + fi + build_libtool_libs=no + build_old_libs=yes + prefer_static_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test "$#" -gt 0; do + arg="$1" + shift + case $arg in + *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") + qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test + ;; + *) qarg=$arg ;; + esac + libtool_args="$libtool_args $qarg" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + compile_command="$compile_command @OUTPUT@" + finalize_command="$finalize_command @OUTPUT@" + ;; + esac + + case $prev in + dlfiles|dlprefiles) + if test "$preload" = no; then + # Add the symbol object into the linking commands. + compile_command="$compile_command @SYMFILE@" + finalize_command="$finalize_command @SYMFILE@" + preload=yes + fi + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test "$dlself" = no; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test "$prev" = dlprefiles; then + dlself=yes + elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test "$prev" = dlfiles; then + dlfiles="$dlfiles $arg" + else + dlprefiles="$dlprefiles $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols="$arg" + if test ! -f "$arg"; then + $echo "$modename: symbol file \`$arg' does not exist" + exit $EXIT_FAILURE + fi + prev= + continue + ;; + expsyms_regex) + export_symbols_regex="$arg" + prev= + continue + ;; + inst_prefix) + inst_prefix_dir="$arg" + prev= + continue + ;; + precious_regex) + precious_files_regex="$arg" + prev= + continue + ;; + release) + release="-$arg" + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat $save_arg` + do +# moreargs="$moreargs $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + pic_object= + non_pic_object= + + # Read the .lo file + # If there is no directory component, then add one. + case $arg in + */* | *\\*) . $arg ;; + *) . ./$arg ;; + esac + + if test -z "$pic_object" || \ + test -z "$non_pic_object" || + test "$pic_object" = none && \ + test "$non_pic_object" = none; then + $echo "$modename: cannot find name of object for \`$arg'" 1>&2 + exit $EXIT_FAILURE + fi + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles $pic_object" + prev= + fi + + # A PIC object. + libobjs="$libobjs $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + non_pic_objects="$non_pic_objects $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + fi + else + # Only an error if not doing a dry-run. + if test -z "$run"; then + $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 + exit $EXIT_FAILURE + else + # Dry-run case. + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` + non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` + libobjs="$libobjs $pic_object" + non_pic_objects="$non_pic_objects $non_pic_object" + fi + fi + done + else + $echo "$modename: link input file \`$save_arg' does not exist" + exit $EXIT_FAILURE + fi + arg=$save_arg + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + $echo "$modename: only absolute run-paths are allowed" 1>&2 + exit $EXIT_FAILURE + ;; + esac + if test "$prev" = rpath; then + case "$rpath " in + *" $arg "*) ;; + *) rpath="$rpath $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) xrpath="$xrpath $arg" ;; + esac + fi + prev= + continue + ;; + xcompiler) + compiler_flags="$compiler_flags $qarg" + prev= + compile_command="$compile_command $qarg" + finalize_command="$finalize_command $qarg" + continue + ;; + xlinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $wl$qarg" + prev= + compile_command="$compile_command $wl$qarg" + finalize_command="$finalize_command $wl$qarg" + continue + ;; + xcclinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $qarg" + prev= + compile_command="$compile_command $qarg" + finalize_command="$finalize_command $qarg" + continue + ;; + shrext) + shrext_cmds="$arg" + prev= + continue + ;; + darwin_framework) + compiler_flags="$compiler_flags $arg" + prev= + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n "$prev" + + prevarg="$arg" + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + compile_command="$compile_command $link_static_flag" + finalize_command="$finalize_command $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2 + continue + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + $echo "$modename: more than one -exported-symbols argument is not allowed" + exit $EXIT_FAILURE + fi + if test "X$arg" = "X-export-symbols"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -framework) + prev=darwin_framework + compiler_flags="$compiler_flags $arg" + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | /*-*-irix*) + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + ;; + esac + continue + ;; + + -L*) + dir=`$echo "X$arg" | $Xsed -e 's/^-L//'` + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2 + exit $EXIT_FAILURE + fi + dir="$absdir" + ;; + esac + case "$deplibs " in + *" -L$dir "*) ;; + *) + deplibs="$deplibs -L$dir" + lib_search_path="$lib_search_path $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + case :$dllsearchpath: in + *":$dir:"*) ;; + *) dllsearchpath="$dllsearchpath:$dir";; + esac + ;; + esac + continue + ;; + + -l*) + if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then + case $host in + *-*-cygwin* | *-*-pw32* | *-*-beos*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-mingw* | *-*-os2*) + # These systems don't actually have a C library (as such) + test "X$arg" = "X-lc" && continue + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + test "X$arg" = "X-lc" && continue + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C and math libraries are in the System framework + deplibs="$deplibs -framework System" + continue + esac + elif test "X$arg" = "X-lc_r"; then + case $host in + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + deplibs="$deplibs $arg" + continue + ;; + + # Tru64 UNIX uses -model [arg] to determine the layout of C++ + # classes, name mangling, and exception handling. + -model) + compile_command="$compile_command $arg" + compiler_flags="$compiler_flags $arg" + finalize_command="$finalize_command $arg" + prev=xcompiler + continue + ;; + + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe) + compiler_flags="$compiler_flags $arg" + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + continue + ;; + + -module) + module=yes + continue + ;; + + # -64, -mips[0-9] enable 64-bit mode on the SGI compiler + # -r[0-9][0-9]* specifies the processor on the SGI compiler + # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler + # +DA*, +DD* enable 64-bit mode on the HP compiler + # -q* pass through compiler args for the IBM compiler + # -m* pass through architecture-specific compiler args for GCC + -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*) + + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") + arg="\"$arg\"" + ;; + esac + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + if test "$with_gcc" = "yes" ; then + compiler_flags="$compiler_flags $arg" + fi + continue + ;; + + -shrext) + prev=shrext + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + # The PATH hackery in wrapper scripts is required on Windows + # in order for the loader to find any dlls it needs. + $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2 + $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2 + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -o) prev=output ;; + + -precious-files-regex) + prev=precious_regex + continue + ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + dir=`$echo "X$arg" | $Xsed -e 's/^-R//'` + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + $echo "$modename: only absolute run-paths are allowed" 1>&2 + exit $EXIT_FAILURE + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + continue + ;; + + -static) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + -version-number) + prev=vinfo + vinfo_number=yes + continue + ;; + + -Wc,*) + args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'` + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + case $flag in + *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") + flag="\"$flag\"" + ;; + esac + arg="$arg $wl$flag" + compiler_flags="$compiler_flags $flag" + done + IFS="$save_ifs" + arg=`$echo "X$arg" | $Xsed -e "s/^ //"` + ;; + + -Wl,*) + args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'` + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + case $flag in + *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") + flag="\"$flag\"" + ;; + esac + arg="$arg $wl$flag" + compiler_flags="$compiler_flags $wl$flag" + linker_flags="$linker_flags $flag" + done + IFS="$save_ifs" + arg=`$echo "X$arg" | $Xsed -e "s/^ //"` + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + -XCClinker) + prev=xcclinker + continue + ;; + + # Some other compiler flag. + -* | +*) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") + arg="\"$arg\"" + ;; + esac + ;; + + *.$objext) + # A standard object. + objs="$objs $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + pic_object= + non_pic_object= + + # Read the .lo file + # If there is no directory component, then add one. + case $arg in + */* | *\\*) . $arg ;; + *) . ./$arg ;; + esac + + if test -z "$pic_object" || \ + test -z "$non_pic_object" || + test "$pic_object" = none && \ + test "$non_pic_object" = none; then + $echo "$modename: cannot find name of object for \`$arg'" 1>&2 + exit $EXIT_FAILURE + fi + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles $pic_object" + prev= + fi + + # A PIC object. + libobjs="$libobjs $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + non_pic_objects="$non_pic_objects $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + fi + else + # Only an error if not doing a dry-run. + if test -z "$run"; then + $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 + exit $EXIT_FAILURE + else + # Dry-run case. + + # Extract subdirectory from the argument. + xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$arg"; then + xdir= + else + xdir="$xdir/" + fi + + pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` + non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` + libobjs="$libobjs $pic_object" + non_pic_objects="$non_pic_objects $non_pic_object" + fi + fi + ;; + + *.$libext) + # An archive. + deplibs="$deplibs $arg" + old_deplibs="$old_deplibs $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + if test "$prev" = dlfiles; then + # This library was specified with -dlopen. + dlfiles="$dlfiles $arg" + prev= + elif test "$prev" = dlprefiles; then + # The library was specified with -dlpreopen. + dlprefiles="$dlprefiles $arg" + prev= + else + deplibs="$deplibs $arg" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") + arg="\"$arg\"" + ;; + esac + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + done # argument parsing loop + + if test -n "$prev"; then + $echo "$modename: the \`$prevarg' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'` + libobjs_save="$libobjs" + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` + if test "X$output_objdir" = "X$output"; then + output_objdir="$objdir" + else + output_objdir="$output_objdir/$objdir" + fi + # Create the object directory. + if test ! -d "$output_objdir"; then + $show "$mkdir $output_objdir" + $run $mkdir $output_objdir + status=$? + if test "$status" -ne 0 && test ! -d "$output_objdir"; then + exit $status + fi + fi + + # Determine the type of output + case $output in + "") + $echo "$modename: you must specify an output file" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + case $host in + *cygwin* | *mingw* | *pw32*) + # don't eliminate duplications in $postdeps and $predeps + duplicate_compiler_generated_deps=yes + ;; + *) + duplicate_compiler_generated_deps=$duplicate_deps + ;; + esac + specialdeplibs= + + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if test "X$duplicate_deps" = "Xyes" ; then + case "$libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + libs="$libs $deplib" + done + + if test "$linkmode" = lib; then + libs="$predeps $libs $compiler_lib_search_path $postdeps" + + # Compute libraries that are listed more than once in $predeps + # $postdeps and mark them as special (i.e., whose duplicates are + # not to be eliminated). + pre_post_deps= + if test "X$duplicate_compiler_generated_deps" = "Xyes" ; then + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;; + esac + pre_post_deps="$pre_post_deps $pre_post_dep" + done + fi + pre_post_deps= + fi + + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + notinst_path= # paths that contain not-installed libtool libraries + case $linkmode in + lib) + passes="conv link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2 + exit $EXIT_FAILURE + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=no + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + for pass in $passes; do + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan"; then + libs="$deplibs" + deplibs= + fi + if test "$linkmode" = prog; then + case $pass in + dlopen) libs="$dlfiles" ;; + dlpreopen) libs="$dlprefiles" ;; + link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; + esac + fi + if test "$pass" = dlopen; then + # Collect dlpreopened libraries + save_deplibs="$deplibs" + deplibs= + fi + for deplib in $libs; do + lib= + found=no + case $deplib in + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + compiler_flags="$compiler_flags $deplib" + fi + continue + ;; + -l*) + if test "$linkmode" != lib && test "$linkmode" != prog; then + $echo "$modename: warning: \`-l' is ignored for archives/objects" 1>&2 + continue + fi + name=`$echo "X$deplib" | $Xsed -e 's/^-l//'` + for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do + for search_ext in .la $std_shrext .so .a; do + # Search the libtool library + lib="$searchdir/lib${name}${search_ext}" + if test -f "$lib"; then + if test "$search_ext" = ".la"; then + found=yes + else + found=no + fi + break 2 + fi + done + done + if test "$found" != yes; then + # deplib doesn't seem to be a libtool library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + else # deplib is a libtool library + # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, + # We need to do some special things here, and not later. + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $deplib "*) + if (${SED} -e '2q' $lib | + grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + library_names= + old_library= + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + for l in $old_library $library_names; do + ll="$l" + done + if test "X$ll" = "X$old_library" ; then # only static version available + found=no + ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` + test "X$ladir" = "X$lib" && ladir="." + lib=$ladir/$old_library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + fi + ;; + *) ;; + esac + fi + fi + ;; # -l + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test "$pass" = conv && continue + newdependency_libs="$deplib $newdependency_libs" + newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` + ;; + prog) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + if test "$pass" = scan; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` + ;; + *) + $echo "$modename: warning: \`-L' is ignored for archives/objects" 1>&2 + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test "$pass" = link; then + dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'` + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) lib="$deplib" ;; + *.$libext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + valid_a_lib=no + case $deplibs_check_method in + match_pattern*) + set dummy $deplibs_check_method + match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` + if eval $echo \"$deplib\" 2>/dev/null \ + | $SED 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + valid_a_lib=yes + fi + ;; + pass_all) + valid_a_lib=yes + ;; + esac + if test "$valid_a_lib" != yes; then + $echo + $echo "*** Warning: Trying to link with static lib archive $deplib." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have" + $echo "*** because the file extensions .$libext of this argument makes me believe" + $echo "*** that it is just a static archive that I should not used here." + else + $echo + $echo "*** Warning: Linking the shared library $output against the" + $echo "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + fi + continue + ;; + prog) + if test "$pass" != link; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + elif test "$linkmode" = prog; then + if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + newdlprefiles="$newdlprefiles $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + newdlfiles="$newdlfiles $deplib" + fi + fi + continue + ;; + %DEPLIBS%) + alldeplibs=yes + continue + ;; + esac # case $deplib + if test "$found" = yes || test -f "$lib"; then : + else + $echo "$modename: cannot find the library \`$lib'" 1>&2 + exit $EXIT_FAILURE + fi + + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $lib | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + + ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` + test "X$ladir" = "X$lib" && ladir="." + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + # If the library was installed with an old release of libtool, + # it will not redefine variables installed, or shouldnotlink + installed=yes + shouldnotlink=no + avoidtemprpath= + + + # Read the .la file + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan" || + { test "$linkmode" != prog && test "$linkmode" != lib; }; then + test -n "$dlopen" && dlfiles="$dlfiles $dlopen" + test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" + fi + + if test "$pass" = conv; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 + exit $EXIT_FAILURE + fi + # It is a libtool convenience library, so add in its objects. + convenience="$convenience $ladir/$objdir/$old_library" + old_convenience="$old_convenience $ladir/$objdir/$old_library" + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + elif test "$linkmode" != prog && test "$linkmode" != lib; then + $echo "$modename: \`$lib' is not a convenience library" 1>&2 + exit $EXIT_FAILURE + fi + continue + fi # $pass = conv + + + # Get the name of the library we link against. + linklib= + for l in $old_library $library_names; do + linklib="$l" + done + if test -z "$linklib"; then + $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 + exit $EXIT_FAILURE + fi + + # This library was specified with -dlopen. + if test "$pass" = dlopen; then + if test -z "$libdir"; then + $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2 + exit $EXIT_FAILURE + fi + if test -z "$dlname" || + test "$dlopen_support" != yes || + test "$build_libtool_libs" = no; then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. We also need to preload any + # dependent libraries so libltdl's deplib preloader doesn't + # bomb out in the load deplibs phase. + dlprefiles="$dlprefiles $lib $dependency_libs" + else + newdlfiles="$newdlfiles $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2 + $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 + abs_ladir="$ladir" + fi + ;; + esac + laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + + # Find the relevant object directory and library name. + if test "X$installed" = Xyes; then + if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + $echo "$modename: warning: library \`$lib' was moved." 1>&2 + dir="$ladir" + absdir="$abs_ladir" + libdir="$abs_ladir" + else + dir="$libdir" + absdir="$libdir" + fi + test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes + else + if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then + dir="$ladir" + absdir="$abs_ladir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + else + dir="$ladir/$objdir" + absdir="$abs_ladir/$objdir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + fi + fi # $installed = yes + name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` + + # This library was specified with -dlpreopen. + if test "$pass" = dlpreopen; then + if test -z "$libdir"; then + $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2 + exit $EXIT_FAILURE + fi + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + newdlprefiles="$newdlprefiles $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + newdlprefiles="$newdlprefiles $dir/$dlname" + else + newdlprefiles="$newdlprefiles $dir/$linklib" + fi + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test "$linkmode" = lib; then + deplibs="$dir/$old_library $deplibs" + elif test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" # used for prog,scan pass + fi + continue + fi + + + if test "$linkmode" = prog && test "$pass" != link; then + newlib_search_path="$newlib_search_path $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=no + if test "$link_all_deplibs" != no || test -z "$library_names" || + test "$build_libtool_libs" = no; then + linkalldeplibs=yes + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test + esac + # Need to link against all dependency_libs? + if test "$linkalldeplibs" = yes; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + if test "$linkmode,$pass" = "prog,link"; then + if test -n "$library_names" && + { test "$prefer_static_libs" = no || test -z "$old_library"; }; then + # We need to hardcode the library path + if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath " in + *" $dir "*) ;; + *" $absdir "*) ;; + *) temp_rpath="$temp_rpath $dir" ;; + esac + fi + + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + fi # $linkmode,$pass = prog,link... + + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + fi + + link_static=no # Whether the deplib will be linked statically + if test -n "$library_names" && + { test "$prefer_static_libs" = no || test -z "$old_library"; }; then + if test "$installed" = no; then + notinst_deplibs="$notinst_deplibs $lib" + need_relink=yes + fi + # This is a shared library + + # Warn about portability, can't link against -module's on + # some systems (darwin) + if test "$shouldnotlink" = yes && test "$pass" = link ; then + $echo + if test "$linkmode" = prog; then + $echo "*** Warning: Linking the executable $output against the loadable module" + else + $echo "*** Warning: Linking the shared library $output against the loadable module" + fi + $echo "*** $linklib is not portable!" + fi + if test "$linkmode" = lib && + test "$hardcode_into_libs" = yes; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + realname="$2" + shift; shift + libname=`eval \\$echo \"$libname_spec\"` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname="$dlname" + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin* | mingw*) + major=`expr $current - $age` + versuffix="-$major" + ;; + esac + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot="$soname" + soname=`$echo $soroot | ${SED} -e 's/^.*\///'` + newlib="libimp-`$echo $soname | ${SED} 's/^lib//;s/\.dll$//'`.a" + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + $show "extracting exported symbol list from \`$soname'" + save_ifs="$IFS"; IFS='~' + cmds=$extract_expsyms_cmds + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + $show "generating import library for \`$soname'" + save_ifs="$IFS"; IFS='~' + cmds=$old_archive_from_expsyms_cmds + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n "$old_archive_from_expsyms_cmds" + + if test "$linkmode" = prog || test "$mode" != relink; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test "$hardcode_direct" = no; then + add="$dir/$linklib" + case $host in + *-*-sco3.2v5* ) add_dir="-L$dir" ;; + *-*-darwin* ) + # if the lib is a module then we can not link against + # it, someone is ignoring the new warnings I added + if /usr/bin/file -L $add 2> /dev/null | $EGREP "bundle" >/dev/null ; then + $echo "** Warning, lib $linklib is a module, not a shared library" + if test -z "$old_library" ; then + $echo + $echo "** And there doesn't seem to be a static archive available" + $echo "** The link will probably fail, sorry" + else + add="$dir/$old_library" + fi + fi + esac + elif test "$hardcode_minus_L" = no; then + case $host in + *-*-sunos*) add_shlibpath="$dir" ;; + esac + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = no; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + relink) + if test "$hardcode_direct" = yes; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$dir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case "$libdir" in + [\\/]*) + add_dir="$add_dir -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test "$lib_linked" != yes; then + $echo "$modename: configuration error: unsupported hardcode properties" + exit $EXIT_FAILURE + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; + esac + fi + if test "$linkmode" = prog; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test "$hardcode_direct" != yes && \ + test "$hardcode_minus_L" != yes && \ + test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + fi + fi + fi + + if test "$linkmode" = prog || test "$mode" = relink; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes; then + add="$libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$libdir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + add="-l$name" + elif test "$hardcode_automatic" = yes; then + if test -n "$inst_prefix_dir" && + test -f "$inst_prefix_dir$libdir/$linklib" ; then + add="$inst_prefix_dir$libdir/$linklib" + else + add="$libdir/$linklib" + fi + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir="-L$libdir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case "$libdir" in + [\\/]*) + add_dir="$add_dir -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + fi + + if test "$linkmode" = prog; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test "$linkmode" = prog; then + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test "$hardcode_direct" != unsupported; then + test -n "$old_library" && linklib="$old_library" + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test "$build_libtool_libs" = yes; then + # Not a shared library + if test "$deplibs_check_method" != pass_all; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + $echo + $echo "*** Warning: This system can not link to static lib archive $lib." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have." + if test "$module" = yes; then + $echo "*** But as you try to build a module library, libtool will still create " + $echo "*** a static module, that should work as long as the dlopening application" + $echo "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + $echo + $echo "*** However, this would only work if libtool was able to extract symbol" + $echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + $echo "*** not find such a program. So, this module is probably useless." + $echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + convenience="$convenience $dir/$old_library" + old_convenience="$old_convenience $dir/$old_library" + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test "$linkmode" = lib; then + if test -n "$dependency_libs" && + { test "$hardcode_into_libs" != yes || + test "$build_old_libs" = yes || + test "$link_static" = yes; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'` + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) xrpath="$xrpath $temp_xrpath";; + esac;; + *) temp_deplibs="$temp_deplibs $libdir";; + esac + done + dependency_libs="$temp_deplibs" + fi + + newlib_search_path="$newlib_search_path $absdir" + # Link against this library + test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + if test "X$duplicate_deps" = "Xyes" ; then + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + fi + tmp_libs="$tmp_libs $deplib" + done + + if test "$link_all_deplibs" != no; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + case $deplib in + -L*) path="$deplib" ;; + *.la) + dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$deplib" && dir="." + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2 + absdir="$dir" + fi + ;; + esac + if grep "^installed=no" $deplib > /dev/null; then + path="$absdir/$objdir" + else + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + if test -z "$libdir"; then + $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + if test "$absdir" != "$libdir"; then + $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2 + fi + path="$absdir" + fi + depdepl= + case $host in + *-*-darwin*) + # we do not want to link against static libs, + # but need to link against shared + eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names" ; then + for tmp in $deplibrary_names ; do + depdepl=$tmp + done + if test -f "$path/$depdepl" ; then + depdepl="$path/$depdepl" + fi + # do not add paths which are already there + case " $newlib_search_path " in + *" $path "*) ;; + *) newlib_search_path="$newlib_search_path $path";; + esac + fi + path="" + ;; + *) + path="-L$path" + ;; + esac + ;; + -l*) + case $host in + *-*-darwin*) + # Again, we only want to link against shared libraries + eval tmp_libs=`$echo "X$deplib" | $Xsed -e "s,^\-l,,"` + for tmp in $newlib_search_path ; do + if test -f "$tmp/lib$tmp_libs.dylib" ; then + eval depdepl="$tmp/lib$tmp_libs.dylib" + break + fi + done + path="" + ;; + *) continue ;; + esac + ;; + *) continue ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$path $deplibs" ;; + esac + case " $deplibs " in + *" $depdepl "*) ;; + *) deplibs="$depdepl $deplibs" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + dependency_libs="$newdependency_libs" + if test "$pass" = dlpreopen; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test "$pass" != dlopen; then + if test "$pass" != conv; then + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) lib_search_path="$lib_search_path $dir" ;; + esac + done + newlib_search_path= + fi + + if test "$linkmode,$pass" != "prog,link"; then + vars="deplibs" + else + vars="compile_deplibs finalize_deplibs" + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + # FIXME: Pedantically, this is the right thing to do, so + # that some nasty dependency loop isn't accidentally + # broken: + #new_libs="$deplib $new_libs" + # Pragmatically, this seems to cause very few problems in + # practice: + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + -R*) ;; + *) + # And here is the reason: when a library appears more + # than once as an explicit dependence of a library, or + # is implicitly linked in more than once by the + # compiler, it is considered special, and multiple + # occurrences thereof are not removed. Compare this + # with having the same library being listed as a + # dependency of multiple other libraries: in this case, + # we know (pedantically, we assume) the library does not + # need to be listed more than once, so we keep only the + # last copy. This is not always right, but it is rare + # enough that we require users that really mean to play + # such unportable linking tricks to link the library + # using -Wl,-lname, so that libtool does not consider it + # for duplicate removal. + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + # Last step: remove runtime libs from dependency_libs + # (they stay in deplibs) + tmp_libs= + for i in $dependency_libs ; do + case " $predeps $postdeps $compiler_lib_search_path " in + *" $i "*) + i="" + ;; + esac + if test -n "$i" ; then + tmp_libs="$tmp_libs $i" + fi + done + dependency_libs=$tmp_libs + done # for pass + if test "$linkmode" = prog; then + dlfiles="$newdlfiles" + dlprefiles="$newdlprefiles" + fi + + case $linkmode in + oldlib) + if test -n "$deplibs"; then + $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2 + fi + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2 + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2 + fi + + if test -n "$xrpath"; then + $echo "$modename: warning: \`-R' is ignored for archives" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info/-version-number' is ignored for archives" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for archives" 1>&2 + fi + + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2 + fi + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs="$output" + objs="$objs$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form `libNAME.la'. + case $outputname in + lib*) + name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + ;; + *) + if test "$module" = no; then + $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + if test "$need_lib_prefix" != no; then + # Add the "lib" prefix for modules if required + name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + else + libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` + fi + ;; + esac + + if test -n "$objs"; then + if test "$deplibs_check_method" != pass_all; then + $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1 + exit $EXIT_FAILURE + else + $echo + $echo "*** Warning: Linking the shared library $output against the non-libtool" + $echo "*** objects $objs is not portable!" + libobjs="$libobjs $objs" + fi + fi + + if test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2 + fi + + set dummy $rpath + if test "$#" -gt 2; then + $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2 + fi + install_libdir="$2" + + oldlibs= + if test -z "$rpath"; then + if test "$build_libtool_libs" = yes; then + # Building a libtool convenience library. + # Some compilers have problems with a `.al' extension so + # convenience libraries should have the same extension an + # archive normally would. + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info/-version-number' is ignored for convenience libraries" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2 + fi + else + + # Parse the version information argument. + save_ifs="$IFS"; IFS=':' + set dummy $vinfo 0 0 0 + IFS="$save_ifs" + + if test -n "$8"; then + $echo "$modename: too many parameters to \`-version-info'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # convert absolute version numbers to libtool ages + # this retains compatibility with .la files and attempts + # to make the code below a bit more comprehensible + + case $vinfo_number in + yes) + number_major="$2" + number_minor="$3" + number_revision="$4" + # + # There are really only two kinds -- those that + # use the current revision as the major version + # and those that subtract age and use age as + # a minor version. But, then there is irix + # which has an extra 1 added just for fun + # + case $version_type in + darwin|linux|osf|windows) + current=`expr $number_major + $number_minor` + age="$number_minor" + revision="$number_revision" + ;; + freebsd-aout|freebsd-elf|sunos) + current="$number_major" + revision="$number_minor" + age="0" + ;; + irix|nonstopux) + current=`expr $number_major + $number_minor - 1` + age="$number_minor" + revision="$number_minor" + ;; + esac + ;; + no) + current="$2" + revision="$3" + age="$4" + ;; + esac + + # Check that each of the things are valid numbers. + case $current in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + $echo "$modename: CURRENT \`$current' must be a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + case $revision in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + $echo "$modename: REVISION \`$revision' must be a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + case $age in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + $echo "$modename: AGE \`$age' must be a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + if test "$age" -gt "$current"; then + $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit $EXIT_FAILURE + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + major=.`expr $current - $age` + versuffix="$major.$age.$revision" + # Darwin ld doesn't like 0 for these options... + minor_current=`expr $current + 1` + verstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current"; + ;; + + irix | nonstopux) + major=`expr $current - $age + 1` + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring="$verstring_prefix$major.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test "$loop" -ne 0; do + iface=`expr $revision - $loop` + loop=`expr $loop - 1` + verstring="$verstring_prefix$major.$iface:$verstring" + done + + # Before this point, $major must not contain `.'. + major=.$major + versuffix="$major.$revision" + ;; + + linux) + major=.`expr $current - $age` + versuffix="$major.$age.$revision" + ;; + + osf) + major=.`expr $current - $age` + versuffix=".$current.$age.$revision" + verstring="$current.$age.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$age + while test "$loop" -ne 0; do + iface=`expr $current - $loop` + loop=`expr $loop - 1` + verstring="$verstring:${iface}.0" + done + + # Make executables depend on our current version. + verstring="$verstring:${current}.0" + ;; + + sunos) + major=".$current" + versuffix=".$current.$revision" + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 filesystems. + major=`expr $current - $age` + versuffix="-$major" + ;; + + *) + $echo "$modename: unknown library version type \`$version_type'" 1>&2 + $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit $EXIT_FAILURE + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring= + ;; + *) + verstring="0.0" + ;; + esac + if test "$need_version" = no; then + versuffix= + else + versuffix=".0.0" + fi + fi + + # Remove version info from name if versioning should be avoided + if test "$avoid_version" = yes && test "$need_version" = no; then + major= + versuffix= + verstring="" + fi + + # Check to see if the archive will have undefined symbols. + if test "$allow_undefined" = yes; then + if test "$allow_undefined_flag" = unsupported; then + $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2 + build_libtool_libs=no + build_old_libs=yes + fi + else + # Don't allow undefined symbols. + allow_undefined_flag="$no_undefined_flag" + fi + fi + + if test "$mode" != relink; then + # Remove our outputs, but don't remove object files since they + # may have been created when compiling PIC objects. + removelist= + tempremovelist=`$echo "$output_objdir/*"` + for p in $tempremovelist; do + case $p in + *.$objext) + ;; + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) + if test "X$precious_files_regex" != "X"; then + if echo $p | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 + then + continue + fi + fi + removelist="$removelist $p" + ;; + *) ;; + esac + done + if test -n "$removelist"; then + $show "${rm}r $removelist" + $run ${rm}r $removelist + fi + fi + + # Now set the variables for building old libraries. + if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + oldlibs="$oldlibs $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + for path in $notinst_path; do + lib_search_path=`$echo "$lib_search_path " | ${SED} -e 's% $path % %g'` + deplibs=`$echo "$deplibs " | ${SED} -e 's% -L$path % %g'` + dependency_libs=`$echo "$dependency_libs " | ${SED} -e 's% -L$path % %g'` + done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + temp_xrpath="$temp_xrpath -R$libdir" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles="$dlfiles" + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) dlfiles="$dlfiles $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles="$dlprefiles" + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) dlprefiles="$dlprefiles $lib" ;; + esac + done + + if test "$build_libtool_libs" = yes; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + deplibs="$deplibs -framework System" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + test "X$arg" = "X-lc" && continue + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test "$build_libtool_need_lc" = "yes"; then + deplibs="$deplibs -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release="" + versuffix="" + major="" + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behavior. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $rm conftest.c + cat > conftest.c </dev/null` + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null \ + | grep " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib="$potent_lib" + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; + *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \ + | ${SED} 10q \ + | $EGREP "$file_magic_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + $echo + $echo "*** Warning: linker path does not have real file for library $a_deplib." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have" + $echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $echo "*** with $libname but no candidates were found. (...for file magic test)" + else + $echo "*** with $libname and none of the candidates passed a file format test" + $echo "*** using a file magic. Last file checked: $potlib" + fi + fi + else + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + fi + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method + match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` + for a_deplib in $deplibs; do + name="`expr $a_deplib : '-l\(.*\)'`" + # If $name is empty we are operating on a -L argument. + if test -n "$name" && test "$name" != "0"; then + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $a_deplib "*) + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + ;; + esac + fi + if test -n "$a_deplib" ; then + libname=`eval \\$echo \"$libname_spec\"` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib="$potent_lib" # see symlink-check above in file_magic test + if eval $echo \"$potent_lib\" 2>/dev/null \ + | ${SED} 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + $echo + $echo "*** Warning: linker path does not have real file for library $a_deplib." + $echo "*** I have the capability to make that library automatically link in when" + $echo "*** you link to this library. But I can only do this if you have a" + $echo "*** shared version of the library, which you do not appear to have" + $echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $echo "*** with $libname but no candidates were found. (...for regex pattern test)" + else + $echo "*** with $libname and none of the candidates passed a file format test" + $echo "*** using a regex pattern. Last file checked: $potlib" + fi + fi + else + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + fi + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs="" + tmp_deplibs=`$echo "X $deplibs" | $Xsed -e 's/ -lc$//' \ + -e 's/ -[LR][^ ]*//g'` + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + for i in $predeps $postdeps ; do + # can't use Xsed below, because $i might contain '/' + tmp_deplibs=`$echo "X $tmp_deplibs" | ${SED} -e "1s,^X,," -e "s,$i,,"` + done + fi + if $echo "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' \ + | grep . >/dev/null; then + $echo + if test "X$deplibs_check_method" = "Xnone"; then + $echo "*** Warning: inter-library dependencies are not supported in this platform." + else + $echo "*** Warning: inter-library dependencies are not known to be supported." + fi + $echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + fi + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'` + ;; + esac + + if test "$droppeddeps" = yes; then + if test "$module" = yes; then + $echo + $echo "*** Warning: libtool could not satisfy all declared inter-library" + $echo "*** dependencies of module $libname. Therefore, libtool will create" + $echo "*** a static module, that should work as long as the dlopening" + $echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + $echo + $echo "*** However, this would only work if libtool was able to extract symbol" + $echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + $echo "*** not find such a program. So, this module is probably useless." + $echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + $echo "*** The inter-library dependencies that have been dropped here will be" + $echo "*** automatically added whenever a program is linked with this library" + $echo "*** or is declared to -dlopen it." + + if test "$allow_undefined" = no; then + $echo + $echo "*** Since this library must not contain undefined symbols," + $echo "*** because either the platform does not support them or" + $echo "*** it was explicitly requested with -no-undefined," + $echo "*** libtool will only create a static version of it." + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test "$build_libtool_libs" = yes; then + if test "$hardcode_into_libs" = yes; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath="$finalize_rpath" + test "$mode" != relink && rpath="$compile_rpath$rpath" + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + dep_rpath="$dep_rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + if test -n "$hardcode_libdir_flag_spec_ld"; then + eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" + else + eval dep_rpath=\"$hardcode_libdir_flag_spec\" + fi + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath="$finalize_shlibpath" + test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval shared_ext=\"$shrext_cmds\" + eval library_names=\"$library_names_spec\" + set dummy $library_names + realname="$2" + shift; shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + if test -z "$dlname"; then + dlname=$soname + fi + + lib="$output_objdir/$realname" + for link + do + linknames="$linknames $link" + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then + $show "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $run $rm $export_symbols + cmds=$export_symbols_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + if len=`expr "X$cmd" : ".*"` && + test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then + $show "$cmd" + $run eval "$cmd" || exit $? + skipped_export=false + else + # The command line is too long to execute in one step. + $show "using reloadable object file for export list..." + skipped_export=: + fi + done + IFS="$save_ifs" + if test -n "$export_symbols_regex"; then + $show "$EGREP -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\"" + $run eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + $show "$mv \"${export_symbols}T\" \"$export_symbols\"" + $run eval '$mv "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"' + fi + + tmp_deplibs= + for test_deplib in $deplibs; do + case " $convenience " in + *" $test_deplib "*) ;; + *) + tmp_deplibs="$tmp_deplibs $test_deplib" + ;; + esac + done + deplibs="$tmp_deplibs" + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + else + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $convenience + libobjs="$libobjs $func_extract_archives_result" + fi + fi + + if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + linker_flags="$linker_flags $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + eval test_cmds=\"$module_expsym_cmds\" + cmds=$module_expsym_cmds + else + eval test_cmds=\"$module_cmds\" + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval test_cmds=\"$archive_expsym_cmds\" + cmds=$archive_expsym_cmds + else + eval test_cmds=\"$archive_cmds\" + cmds=$archive_cmds + fi + fi + + if test "X$skipped_export" != "X:" && len=`expr "X$test_cmds" : ".*"` && + test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # The command line is too long to link in one step, link piecewise. + $echo "creating reloadable object files..." + + # Save the value of $output and $libobjs because we want to + # use them later. If we have whole_archive_flag_spec, we + # want to use save_libobjs as it was before + # whole_archive_flag_spec was expanded, because we can't + # assume the linker understands whole_archive_flag_spec. + # This may have to be revisited, in case too many + # convenience libraries get linked in and end up exceeding + # the spec. + if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + fi + save_output=$output + output_la=`$echo "X$output" | $Xsed -e "$basename"` + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + delfiles= + last_robj= + k=1 + output=$output_objdir/$output_la-${k}.$objext + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + eval test_cmds=\"$reload_cmds $objlist $last_robj\" + if test "X$objlist" = X || + { len=`expr "X$test_cmds" : ".*"` && + test "$len" -le "$max_cmd_len"; }; then + objlist="$objlist $obj" + else + # The command $test_cmds is almost too long, add a + # command to the queue. + if test "$k" -eq 1 ; then + # The first file doesn't have a previous command to add. + eval concat_cmds=\"$reload_cmds $objlist $last_robj\" + else + # All subsequent reloadable object files will link in + # the last one created. + eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj\" + fi + last_robj=$output_objdir/$output_la-${k}.$objext + k=`expr $k + 1` + output=$output_objdir/$output_la-${k}.$objext + objlist=$obj + len=1 + fi + done + # Handle the remaining objects by creating one last + # reloadable object file. All subsequent reloadable object + # files will link in the last one created. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\" + + if ${skipped_export-false}; then + $show "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $run $rm $export_symbols + libobjs=$output + # Append the command to create the export file. + eval concat_cmds=\"\$concat_cmds~$export_symbols_cmds\" + fi + + # Set up a command to remove the reloadable object files + # after they are used. + i=0 + while test "$i" -lt "$k" + do + i=`expr $i + 1` + delfiles="$delfiles $output_objdir/$output_la-${i}.$objext" + done + + $echo "creating a temporary reloadable object file: $output" + + # Loop through the commands generated above and execute them. + save_ifs="$IFS"; IFS='~' + for cmd in $concat_cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + libobjs=$output + # Restore the value of output. + output=$save_output + + if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + cmds=$module_expsym_cmds + else + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + cmds=$archive_expsym_cmds + else + cmds=$archive_cmds + fi + fi + + # Append the command to remove the reloadable object files + # to the just-reset $cmds. + eval cmds=\"\$cmds~\$rm $delfiles\" + fi + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $? + exit $EXIT_SUCCESS + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)" + $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $? + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test "$module" = yes || test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. + dlname="$soname" + fi + fi + ;; + + obj) + if test -n "$deplibs"; then + $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 + fi + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2 + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2 + fi + + if test -n "$xrpath"; then + $echo "$modename: warning: \`-R' is ignored for objects" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for objects" 1>&2 + fi + + case $output in + *.lo) + if test -n "$objs$old_deplibs"; then + $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2 + exit $EXIT_FAILURE + fi + libobj="$output" + obj=`$echo "X$output" | $Xsed -e "$lo2o"` + ;; + *) + libobj= + obj="$output" + ;; + esac + + # Delete the old objects. + $run $rm $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # reload_cmds runs $LD directly, so let us get rid of + # -Wl from whole_archive_flag_spec + wl= + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\" + else + gentop="$output_objdir/${obj}x" + generated="$generated $gentop" + + func_extract_archives $gentop $convenience + reload_conv_objs="$reload_objs $func_extract_archives_result" + fi + fi + + # Create the old-style object. + reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test + + output="$obj" + cmds=$reload_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit $EXIT_SUCCESS + fi + + if test "$build_libtool_libs" != yes; then + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + # $show "echo timestamp > $libobj" + # $run eval "echo timestamp > $libobj" || exit $? + exit $EXIT_SUCCESS + fi + + if test -n "$pic_flag" || test "$pic_mode" != default; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output="$libobj" + cmds=$reload_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit $EXIT_SUCCESS + ;; + + prog) + case $host in + *cygwin*) output=`$echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;; + esac + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for programs" 1>&2 + fi + + if test "$preload" = yes; then + if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown && + test "$dlopen_self_static" = unknown; then + $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support." + fi + fi + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'` + finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'` + ;; + esac + + case $host in + *darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + if test "$tagname" = CXX ; then + compile_command="$compile_command ${wl}-bind_at_load" + finalize_command="$finalize_command ${wl}-bind_at_load" + fi + ;; + esac + + compile_command="$compile_command $compile_deplibs" + finalize_command="$finalize_command $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + case :$dllsearchpath: in + *":$libdir:"*) ;; + *) dllsearchpath="$dllsearchpath:$libdir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath="$rpath" + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath="$rpath" + + if test -n "$libobjs" && test "$build_old_libs" = yes; then + # Transform all the library objects into standard objects. + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + fi + + dlsyms= + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + dlsyms="${outputname}S.c" + else + $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2 + fi + fi + + if test -n "$dlsyms"; then + case $dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist="$output_objdir/${outputname}.nm" + + $show "$rm $nlist ${nlist}S ${nlist}T" + $run $rm "$nlist" "${nlist}S" "${nlist}T" + + # Parse the name list into a source file. + $show "creating $output_objdir/$dlsyms" + + test -z "$run" && $echo > "$output_objdir/$dlsyms" "\ +/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */ +/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +/* Prevent the only kind of declaration conflicts we can make. */ +#define lt_preloaded_symbols some_other_symbol + +/* External symbol declarations for the compiler. */\ +" + + if test "$dlself" = yes; then + $show "generating symbol list for \`$output'" + + test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + for arg in $progfiles; do + $show "extracting global C symbols from \`$arg'" + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $run eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + $run eval '$mv "$nlist"T "$nlist"' + fi + + if test -n "$export_symbols_regex"; then + $run eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' + $run eval '$mv "$nlist"T "$nlist"' + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols="$output_objdir/$outputname.exp" + $run $rm $export_symbols + $run eval "${SED} -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + else + $run eval "${SED} -e 's/\([ ][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' + $run eval 'grep -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' + $run eval 'mv "$nlist"T "$nlist"' + fi + fi + + for arg in $dlprefiles; do + $show "extracting global C symbols from \`$arg'" + name=`$echo "$arg" | ${SED} -e 's%^.*/%%'` + $run eval '$echo ": $name " >> "$nlist"' + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + if test -z "$run"; then + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $mv "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if grep -v "^: " < "$nlist" | + if sort -k 3 /dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + grep -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"' + else + $echo '/* NONE */' >> "$output_objdir/$dlsyms" + fi + + $echo >> "$output_objdir/$dlsyms" "\ + +#undef lt_preloaded_symbols + +#if defined (__STDC__) && __STDC__ +# define lt_ptr void * +#else +# define lt_ptr char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +" + + case $host in + *cygwin* | *mingw* ) + $echo >> "$output_objdir/$dlsyms" "\ +/* DATA imports from DLLs on WIN32 can't be const, because + runtime relocations are performed -- see ld's documentation + on pseudo-relocs */ +struct { +" + ;; + * ) + $echo >> "$output_objdir/$dlsyms" "\ +const struct { +" + ;; + esac + + + $echo >> "$output_objdir/$dlsyms" "\ + const char *name; + lt_ptr address; +} +lt_preloaded_symbols[] = +{\ +" + + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms" + + $echo >> "$output_objdir/$dlsyms" "\ + {0, (lt_ptr) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + fi + + pic_flag_for_symtable= + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + case "$compile_command " in + *" -static "*) ;; + *) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND";; + esac;; + *-*-hpux*) + case "$compile_command " in + *" -static "*) ;; + *) pic_flag_for_symtable=" $pic_flag";; + esac + esac + + # Now compile the dynamic symbol file. + $show "(cd $output_objdir && $LTCC -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")" + $run eval '(cd $output_objdir && $LTCC -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $? + + # Clean up the generated files. + $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T" + $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T" + + # Transform the symbol file into the correct name. + compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` + finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` + ;; + *) + $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2 + exit $EXIT_FAILURE + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` + finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` + fi + + if test "$need_relink" = no || test "$build_libtool_libs" != yes; then + # Replace the output file specification. + compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + link_command="$compile_command$compile_rpath" + + # We have no uninstalled library dependencies, so finalize right now. + $show "$link_command" + $run eval "$link_command" + status=$? + + # Delete the generated files. + if test -n "$dlsyms"; then + $show "$rm $output_objdir/${outputname}S.${objext}" + $run $rm "$output_objdir/${outputname}S.${objext}" + fi + + exit $status + fi + + if test -n "$shlibpath_var"; then + # We should set the shlibpath_var + rpath= + for dir in $temp_rpath; do + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) + # Absolute path. + rpath="$rpath$dir:" + ;; + *) + # Relative path: add a thisdir entry. + rpath="$rpath\$thisdir/$dir:" + ;; + esac + done + temp_rpath="$rpath" + fi + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + rpath="$rpath$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test "$no_install" = yes; then + # We don't need to create a wrapper script. + link_command="$compile_var$compile_command$compile_rpath" + # Replace the output file specification. + link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $run $rm $output + # Link the executable and exit + $show "$link_command" + $run eval "$link_command" || exit $? + exit $EXIT_SUCCESS + fi + + if test "$hardcode_action" = relink; then + # Fast installation is not supported + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + + $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2 + $echo "$modename: \`$output' will be relinked during installation" 1>&2 + else + if test "$fast_install" != no; then + link_command="$finalize_var$compile_command$finalize_rpath" + if test "$fast_install" = yes; then + relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'` + else + # fast_install is set to needless + relink_command= + fi + else + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + fi + fi + + # Replace the output file specification. + link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname + + $show "$link_command" + $run eval "$link_command" || exit $? + + # Now create the wrapper script. + $show "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` + relink_command="$var=\"$var_value\"; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` + fi + + # Quote $echo for shipping. + if test "X$echo" = "X$SHELL $progpath --fallback-echo"; then + case $progpath in + [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";; + *) qecho="$SHELL `pwd`/$progpath --fallback-echo";; + esac + qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"` + else + qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"` + fi + + # Only actually do things if our run command is non-null. + if test -z "$run"; then + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) output=`$echo $output|${SED} 's,.exe$,,'` ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) + exeext=.exe + outputname=`$echo $outputname|${SED} 's,.exe$,,'` ;; + *) exeext= ;; + esac + case $host in + *cygwin* | *mingw* ) + cwrappersource=`$echo ${objdir}/lt-${outputname}.c` + cwrapper=`$echo ${output}.exe` + $rm $cwrappersource $cwrapper + trap "$rm $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 + + cat > $cwrappersource <> $cwrappersource<<"EOF" +#include +#include +#include +#include +#include +#include + +#if defined(PATH_MAX) +# define LT_PATHMAX PATH_MAX +#elif defined(MAXPATHLEN) +# define LT_PATHMAX MAXPATHLEN +#else +# define LT_PATHMAX 1024 +#endif + +#ifndef DIR_SEPARATOR +#define DIR_SEPARATOR '/' +#endif + +#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ + defined (__OS2__) +#define HAVE_DOS_BASED_FILE_SYSTEM +#ifndef DIR_SEPARATOR_2 +#define DIR_SEPARATOR_2 '\\' +#endif +#endif + +#ifndef DIR_SEPARATOR_2 +# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) +#else /* DIR_SEPARATOR_2 */ +# define IS_DIR_SEPARATOR(ch) \ + (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) +#endif /* DIR_SEPARATOR_2 */ + +#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) +#define XFREE(stale) do { \ + if (stale) { free ((void *) stale); stale = 0; } \ +} while (0) + +const char *program_name = NULL; + +void * xmalloc (size_t num); +char * xstrdup (const char *string); +char * basename (const char *name); +char * fnqualify(const char *path); +char * strendzap(char *str, const char *pat); +void lt_fatal (const char *message, ...); + +int +main (int argc, char *argv[]) +{ + char **newargz; + int i; + + program_name = (char *) xstrdup ((char *) basename (argv[0])); + newargz = XMALLOC(char *, argc+2); +EOF + + cat >> $cwrappersource <> $cwrappersource <<"EOF" + newargz[1] = fnqualify(argv[0]); + /* we know the script has the same name, without the .exe */ + /* so make sure newargz[1] doesn't end in .exe */ + strendzap(newargz[1],".exe"); + for (i = 1; i < argc; i++) + newargz[i+1] = xstrdup(argv[i]); + newargz[argc+1] = NULL; +EOF + + cat >> $cwrappersource <> $cwrappersource <<"EOF" +} + +void * +xmalloc (size_t num) +{ + void * p = (void *) malloc (num); + if (!p) + lt_fatal ("Memory exhausted"); + + return p; +} + +char * +xstrdup (const char *string) +{ + return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL +; +} + +char * +basename (const char *name) +{ + const char *base; + +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + /* Skip over the disk name in MSDOS pathnames. */ + if (isalpha (name[0]) && name[1] == ':') + name += 2; +#endif + + for (base = name; *name; name++) + if (IS_DIR_SEPARATOR (*name)) + base = name + 1; + return (char *) base; +} + +char * +fnqualify(const char *path) +{ + size_t size; + char *p; + char tmp[LT_PATHMAX + 1]; + + assert(path != NULL); + + /* Is it qualified already? */ +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + if (isalpha (path[0]) && path[1] == ':') + return xstrdup (path); +#endif + if (IS_DIR_SEPARATOR (path[0])) + return xstrdup (path); + + /* prepend the current directory */ + /* doesn't handle '~' */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal ("getcwd failed"); + size = strlen(tmp) + 1 + strlen(path) + 1; /* +2 for '/' and '\0' */ + p = XMALLOC(char, size); + sprintf(p, "%s%c%s", tmp, DIR_SEPARATOR, path); + return p; +} + +char * +strendzap(char *str, const char *pat) +{ + size_t len, patlen; + + assert(str != NULL); + assert(pat != NULL); + + len = strlen(str); + patlen = strlen(pat); + + if (patlen <= len) + { + str += len - patlen; + if (strcmp(str, pat) == 0) + *str = '\0'; + } + return str; +} + +static void +lt_error_core (int exit_status, const char * mode, + const char * message, va_list ap) +{ + fprintf (stderr, "%s: %s: ", program_name, mode); + vfprintf (stderr, message, ap); + fprintf (stderr, ".\n"); + + if (exit_status >= 0) + exit (exit_status); +} + +void +lt_fatal (const char *message, ...) +{ + va_list ap; + va_start (ap, message); + lt_error_core (EXIT_FAILURE, "FATAL", message, ap); + va_end (ap); +} +EOF + # we should really use a build-platform specific compiler + # here, but OTOH, the wrappers (shell script and this C one) + # are only useful if you want to execute the "real" binary. + # Since the "real" binary is built for $host, then this + # wrapper might as well be built for $host, too. + $run $LTCC -s -o $cwrapper $cwrappersource + ;; + esac + $rm $output + trap "$rm $output; exit $EXIT_FAILURE" 1 2 15 + + $echo > $output "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='${SED} -e 1s/^X//' +sed_quote_subst='$sed_quote_subst' + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variable: + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$echo are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + echo=\"$qecho\" + file=\"\$0\" + # Make sure echo works. + if test \"X\$1\" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift + elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then + # Yippee, \$echo works! + : + else + # Restart under the correct shell, and then maybe \$echo will work. + exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} + fi + fi\ +" + $echo >> $output "\ + + # Find the directory that this script lives in. + thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\` + done + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test "$fast_install" = yes; then + $echo >> $output "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || \\ + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $mkdir \"\$progdir\" + else + $rm \"\$progdir/\$file\" + fi" + + $echo >> $output "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + $echo \"\$relink_command_output\" >&2 + $rm \"\$progdir/\$file\" + exit $EXIT_FAILURE + fi + fi + + $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $rm \"\$progdir/\$program\"; + $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $rm \"\$progdir/\$file\" + fi" + else + $echo >> $output "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + $echo >> $output "\ + + if test -f \"\$progdir/\$program\"; then" + + # Export our shlibpath_var if we have one. + if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $echo >> $output "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` + + export $shlibpath_var +" + fi + + # fixup the dll searchpath if we need to. + if test -n "$dllsearchpath"; then + $echo >> $output "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + $echo >> $output "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. +" + case $host in + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2*) + $echo >> $output "\ + exec \$progdir\\\\\$program \${1+\"\$@\"} +" + ;; + + *) + $echo >> $output "\ + exec \$progdir/\$program \${1+\"\$@\"} +" + ;; + esac + $echo >> $output "\ + \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\" + exit $EXIT_FAILURE + fi + else + # The program doesn't exist. + \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2 + \$echo \"This script is just a wrapper for \$program.\" 1>&2 + $echo \"See the $PACKAGE documentation for more information.\" 1>&2 + exit $EXIT_FAILURE + fi +fi\ +" + chmod +x $output + fi + exit $EXIT_SUCCESS + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + if test "$build_libtool_libs" = convenience; then + oldobjs="$libobjs_save" + addlibs="$convenience" + build_libtool_libs=no + else + if test "$build_libtool_libs" = module; then + oldobjs="$libobjs_save" + build_libtool_libs=no + else + oldobjs="$old_deplibs $non_pic_objects" + fi + addlibs="$old_convenience" + fi + + if test -n "$addlibs"; then + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + func_extract_archives $gentop $addlibs + oldobjs="$oldobjs $func_extract_archives_result" + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + cmds=$old_archive_from_new_cmds + else + # POSIX demands no paths to be encoded in archives. We have + # to avoid creating archives with duplicate basenames if we + # might have to extract them afterwards, e.g., when creating a + # static archive out of a convenience library, or when linking + # the entirety of a libtool archive into another (currently + # not supported by libtool). + if (for obj in $oldobjs + do + $echo "X$obj" | $Xsed -e 's%^.*/%%' + done | sort | sort -uc >/dev/null 2>&1); then + : + else + $echo "copying selected object files to avoid basename conflicts..." + + if test -z "$gentop"; then + gentop="$output_objdir/${outputname}x" + generated="$generated $gentop" + + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "$mkdir $gentop" + $run $mkdir "$gentop" + status=$? + if test "$status" -ne 0 && test ! -d "$gentop"; then + exit $status + fi + fi + + save_oldobjs=$oldobjs + oldobjs= + counter=1 + for obj in $save_oldobjs + do + objbase=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` + case " $oldobjs " in + " ") oldobjs=$obj ;; + *[\ /]"$objbase "*) + while :; do + # Make sure we don't pick an alternate name that also + # overlaps. + newobj=lt$counter-$objbase + counter=`expr $counter + 1` + case " $oldobjs " in + *[\ /]"$newobj "*) ;; + *) if test ! -f "$gentop/$newobj"; then break; fi ;; + esac + done + $show "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" + $run ln "$obj" "$gentop/$newobj" || + $run cp "$obj" "$gentop/$newobj" + oldobjs="$oldobjs $gentop/$newobj" + ;; + *) oldobjs="$oldobjs $obj" ;; + esac + done + fi + + eval cmds=\"$old_archive_cmds\" + + if len=`expr "X$cmds" : ".*"` && + test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then + cmds=$old_archive_cmds + else + # the command line is too long to link in one step, link in parts + $echo "using piecewise archive linking..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + + # Is there a better way of finding the last object in the list? + for obj in $save_oldobjs + do + last_oldobj=$obj + done + for obj in $save_oldobjs + do + oldobjs="$objlist $obj" + objlist="$objlist $obj" + eval test_cmds=\"$old_archive_cmds\" + if len=`expr "X$test_cmds" : ".*"` && + test "$len" -le "$max_cmd_len"; then + : + else + # the above command should be used before it gets too long + oldobjs=$objlist + if test "$obj" = "$last_oldobj" ; then + RANLIB=$save_RANLIB + fi + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" + objlist= + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + if test "X$oldobjs" = "X" ; then + eval cmds=\"\$concat_cmds\" + else + eval cmds=\"\$concat_cmds~\$old_archive_cmds\" + fi + fi + fi + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + eval cmd=\"$cmd\" + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$generated"; then + $show "${rm}r$generated" + $run ${rm}r$generated + fi + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.$libext" + $show "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` + relink_command="$var=\"$var_value\"; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` + if test "$hardcode_automatic" = yes ; then + relink_command= + fi + + + # Only create the output if not a dry run. + if test -z "$run"; then + for installed in no yes; do + if test "$installed" = yes; then + if test -z "$install_libdir"; then + break + fi + output="$output_objdir/$outputname"i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + if test -z "$libdir"; then + $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + newdependency_libs="$newdependency_libs $libdir/$name" + ;; + *) newdependency_libs="$newdependency_libs $deplib" ;; + esac + done + dependency_libs="$newdependency_libs" + newdlfiles= + for lib in $dlfiles; do + name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + if test -z "$libdir"; then + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + newdlfiles="$newdlfiles $libdir/$name" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + if test -z "$libdir"; then + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit $EXIT_FAILURE + fi + newdlprefiles="$newdlprefiles $libdir/$name" + done + dlprefiles="$newdlprefiles" + else + newdlfiles= + for lib in $dlfiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + newdlfiles="$newdlfiles $abs" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + newdlprefiles="$newdlprefiles $abs" + done + dlprefiles="$newdlprefiles" + fi + $rm $output + # place dlname in correct position for cygwin + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; + esac + $echo > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Should we warn about portability when linking against -modules? +shouldnotlink=$module + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test "$installed" = no && test "$need_relink" = yes; then + $echo >> $output "\ +relink_command=\"$relink_command\"" + fi + done + fi + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" + $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $? + ;; + esac + exit $EXIT_SUCCESS + ;; + + # libtool install mode + install) + modename="$modename: install" + + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || + # Allow the use of GNU shtool's install command. + $echo "X$nonopt" | $Xsed | grep shtool > /dev/null; then + # Aesthetically quote it. + arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"` + case $arg in + *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") + arg="\"$arg\"" + ;; + esac + install_prog="$arg " + arg="$1" + shift + else + install_prog= + arg="$nonopt" + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog$arg" + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=no + stripme= + for arg + do + if test -n "$dest"; then + files="$files $dest" + dest="$arg" + continue + fi + + case $arg in + -d) isdir=yes ;; + -f) prev="-f" ;; + -g) prev="-g" ;; + -m) prev="-m" ;; + -o) prev="-o" ;; + -s) + stripme=" -s" + continue + ;; + -*) ;; + + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + prev= + else + dest="$arg" + continue + fi + ;; + esac + + # Aesthetically quote the argument. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog $arg" + done + + if test -z "$install_prog"; then + $echo "$modename: you must specify an install program" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + if test -n "$prev"; then + $echo "$modename: the \`$prev' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + if test -z "$files"; then + if test -z "$dest"; then + $echo "$modename: no file or destination specified" 1>&2 + else + $echo "$modename: you must specify a destination" 1>&2 + fi + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Strip any trailing slash from the destination. + dest=`$echo "X$dest" | $Xsed -e 's%/$%%'` + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=yes + if test "$isdir" = yes; then + destdir="$dest" + destname= + else + destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'` + test "X$destdir" = "X$dest" && destdir=. + destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'` + + # Not a directory, so check to see that there is only one file specified. + set dummy $files + if test "$#" -gt 2; then + $echo "$modename: \`$dest' is not a directory" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + staticlibs="$staticlibs $file" + ;; + + *.la) + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$file' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + library_names= + old_library= + relink_command= + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) current_libdirs="$current_libdirs $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) future_libdirs="$future_libdirs $libdir" ;; + esac + fi + + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/ + test "X$dir" = "X$file/" && dir= + dir="$dir$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$echo "$destdir" | $SED "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + # At present, this check doesn't affect windows .dll's that + # are installed into $libdir/../bin (currently, that works fine) + # but it's something to keep an eye on. + if test "$inst_prefix_dir" = "$destdir"; then + $echo "$modename: error: cannot install \`$file' to a directory not ending in $libdir" 1>&2 + exit $EXIT_FAILURE + fi + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$echo "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` + else + relink_command=`$echo "$relink_command" | $SED "s%@inst_prefix_dir@%%"` + fi + + $echo "$modename: warning: relinking \`$file'" 1>&2 + $show "$relink_command" + if $run eval "$relink_command"; then : + else + $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 + exit $EXIT_FAILURE + fi + fi + + # See the names of the shared library. + set dummy $library_names + if test -n "$2"; then + realname="$2" + shift + shift + + srcname="$realname" + test -n "$relink_command" && srcname="$realname"T + + # Install the shared library and build the symlinks. + $show "$install_prog $dir/$srcname $destdir/$realname" + $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $? + if test -n "$stripme" && test -n "$striplib"; then + $show "$striplib $destdir/$realname" + $run eval "$striplib $destdir/$realname" || exit $? + fi + + if test "$#" -gt 0; then + # Delete the old symlinks, and create new ones. + for linkname + do + if test "$linkname" != "$realname"; then + $show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" + $run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" + fi + done + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + cmds=$postinstall_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + # Install the pseudo-library for information purposes. + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + instname="$dir/$name"i + $show "$install_prog $instname $destdir/$name" + $run eval "$install_prog $instname $destdir/$name" || exit $? + + # Maybe install the static library, too. + test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"` + ;; + *.$objext) + staticdest="$destfile" + destfile= + ;; + *) + $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + # Install the libtool object if requested. + if test -n "$destfile"; then + $show "$install_prog $file $destfile" + $run eval "$install_prog $file $destfile" || exit $? + fi + + # Install the old object if enabled. + if test "$build_old_libs" = yes; then + # Deduce the name of the old-style object file. + staticobj=`$echo "X$file" | $Xsed -e "$lo2o"` + + $show "$install_prog $staticobj $staticdest" + $run eval "$install_prog \$staticobj \$staticdest" || exit $? + fi + exit $EXIT_SUCCESS + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # If the file is missing, and there is a .exe on the end, strip it + # because it is most likely a libtool script we actually want to + # install + stripped_ext="" + case $file in + *.exe) + if test ! -f "$file"; then + file=`$echo $file|${SED} 's,.exe$,,'` + stripped_ext=".exe" + fi + ;; + esac + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin*|*mingw*) + wrapper=`$echo $file | ${SED} -e 's,.exe$,,'` + ;; + *) + wrapper=$file + ;; + esac + if (${SED} -e '4q' $wrapper | grep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then + notinst_deplibs= + relink_command= + + # To insure that "foo" is sourced, and not "foo.exe", + # finese the cygwin/MSYS system by explicitly sourcing "foo." + # which disallows the automatic-append-.exe behavior. + case $build in + *cygwin* | *mingw*) wrapperdot=${wrapper}. ;; + *) wrapperdot=${wrapper} ;; + esac + # If there is no directory component, then add one. + case $file in + */* | *\\*) . ${wrapperdot} ;; + *) . ./${wrapperdot} ;; + esac + + # Check the variables that should have been set. + if test -z "$notinst_deplibs"; then + $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2 + exit $EXIT_FAILURE + fi + + finalize=yes + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + # If there is no directory component, then add one. + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + fi + libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test + if test -n "$libdir" && test ! -f "$libfile"; then + $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2 + finalize=no + fi + done + + relink_command= + # To insure that "foo" is sourced, and not "foo.exe", + # finese the cygwin/MSYS system by explicitly sourcing "foo." + # which disallows the automatic-append-.exe behavior. + case $build in + *cygwin* | *mingw*) wrapperdot=${wrapper}. ;; + *) wrapperdot=${wrapper} ;; + esac + # If there is no directory component, then add one. + case $file in + */* | *\\*) . ${wrapperdot} ;; + *) . ./${wrapperdot} ;; + esac + + outputname= + if test "$fast_install" = no && test -n "$relink_command"; then + if test "$finalize" = yes && test -z "$run"; then + tmpdir="/tmp" + test -n "$TMPDIR" && tmpdir="$TMPDIR" + tmpdir="$tmpdir/libtool-$$" + save_umask=`umask` + umask 0077 + if $mkdir "$tmpdir"; then + umask $save_umask + else + umask $save_umask + $echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2 + continue + fi + file=`$echo "X$file$stripped_ext" | $Xsed -e 's%^.*/%%'` + outputname="$tmpdir/$file" + # Replace the output file specification. + relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'` + + $show "$relink_command" + if $run eval "$relink_command"; then : + else + $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 + ${rm}r "$tmpdir" + continue + fi + file="$outputname" + else + $echo "$modename: warning: cannot relink \`$file'" 1>&2 + fi + else + # Install the binary that we compiled earlier. + file=`$echo "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyways + case $install_prog,$host in + */usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + destfile=`$echo $destfile | ${SED} -e 's,.exe$,,'` + ;; + esac + ;; + esac + $show "$install_prog$stripme $file $destfile" + $run eval "$install_prog\$stripme \$file \$destfile" || exit $? + test -n "$outputname" && ${rm}r "$tmpdir" + ;; + esac + done + + for file in $staticlibs; do + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + + $show "$install_prog $file $oldlib" + $run eval "$install_prog \$file \$oldlib" || exit $? + + if test -n "$stripme" && test -n "$old_striplib"; then + $show "$old_striplib $oldlib" + $run eval "$old_striplib $oldlib" || exit $? + fi + + # Do each command in the postinstall commands. + cmds=$old_postinstall_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$future_libdirs"; then + $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2 + fi + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + test -n "$run" && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' + else + exit $EXIT_SUCCESS + fi + ;; + + # libtool finish mode + finish) + modename="$modename: finish" + libdirs="$nonopt" + admincmds= + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for dir + do + libdirs="$libdirs $dir" + done + + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + cmds=$finish_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" || admincmds="$admincmds + $cmd" + done + IFS="$save_ifs" + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $run eval "$cmds" || admincmds="$admincmds + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + test "$show" = : && exit $EXIT_SUCCESS + + $echo "----------------------------------------------------------------------" + $echo "Libraries have been installed in:" + for libdir in $libdirs; do + $echo " $libdir" + done + $echo + $echo "If you ever happen to want to link against installed libraries" + $echo "in a given directory, LIBDIR, you must either use libtool, and" + $echo "specify the full pathname of the library, or use the \`-LLIBDIR'" + $echo "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + $echo " - add LIBDIR to the \`$shlibpath_var' environment variable" + $echo " during execution" + fi + if test -n "$runpath_var"; then + $echo " - add LIBDIR to the \`$runpath_var' environment variable" + $echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + $echo " - use the \`$flag' linker flag" + fi + if test -n "$admincmds"; then + $echo " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + $echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" + fi + $echo + $echo "See any operating system documentation about shared libraries for" + $echo "more information, such as the ld(1) and ld.so(8) manual pages." + $echo "----------------------------------------------------------------------" + exit $EXIT_SUCCESS + ;; + + # libtool execute mode + execute) + modename="$modename: execute" + + # The first argument is the command name. + cmd="$nonopt" + if test -z "$cmd"; then + $echo "$modename: you must specify a COMMAND" 1>&2 + $echo "$help" + exit $EXIT_FAILURE + fi + + # Handle -dlopen flags immediately. + for file in $execute_dlfiles; do + if test ! -f "$file"; then + $echo "$modename: \`$file' is not a file" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + dir= + case $file in + *.la) + # Check to see that this really is a libtool archive. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Read the libtool library. + dlname= + library_names= + + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'" + continue + fi + + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + + if test -f "$dir/$objdir/$dlname"; then + dir="$dir/$objdir" + else + $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2 + exit $EXIT_FAILURE + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + ;; + + *) + $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2 + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir="$absdir" + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic="$magic" + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -*) ;; + *) + # Do a test to see if this is really a libtool program. + if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Transform arg to wrapped name. + file="$progdir/$program" + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"` + args="$args \"$file\"" + done + + if test -z "$run"; then + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved environment variables + if test "${save_LC_ALL+set}" = set; then + LC_ALL="$save_LC_ALL"; export LC_ALL + fi + if test "${save_LANG+set}" = set; then + LANG="$save_LANG"; export LANG + fi + + # Now prepare to actually exec the command. + exec_cmd="\$cmd$args" + else + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\"" + $echo "export $shlibpath_var" + fi + $echo "$cmd$args" + exit $EXIT_SUCCESS + fi + ;; + + # libtool clean and uninstall mode + clean | uninstall) + modename="$modename: $mode" + rm="$nonopt" + files= + rmforce= + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + for arg + do + case $arg in + -f) rm="$rm $arg"; rmforce=yes ;; + -*) rm="$rm $arg" ;; + *) files="$files $arg" ;; + esac + done + + if test -z "$rm"; then + $echo "$modename: you must specify an RM program" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + fi + + rmdirs= + + origobjdir="$objdir" + for file in $files; do + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + if test "X$dir" = "X$file"; then + dir=. + objdir="$origobjdir" + else + objdir="$dir/$origobjdir" + fi + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + test "$mode" = uninstall && objdir="$dir" + + # Remember objdir for removal later, being careful to avoid duplicates + if test "$mode" = clean; then + case " $rmdirs " in + *" $objdir "*) ;; + *) rmdirs="$rmdirs $objdir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if (test -L "$file") >/dev/null 2>&1 \ + || (test -h "$file") >/dev/null 2>&1 \ + || test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif test "$rmforce" = yes; then + continue + fi + + rmfiles="$file" + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + . $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + rmfiles="$rmfiles $objdir/$n" + done + test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" + test "$mode" = clean && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" + + if test "$mode" = uninstall; then + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + cmds=$postuninstall_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" + if test "$?" -ne 0 && test "$rmforce" != yes; then + exit_status=1 + fi + done + IFS="$save_ifs" + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + cmds=$old_postuninstall_cmds + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $show "$cmd" + $run eval "$cmd" + if test "$?" -ne 0 && test "$rmforce" != yes; then + exit_status=1 + fi + done + IFS="$save_ifs" + fi + # FIXME: should reinstall the best remaining shared library. + fi + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + + # Read the .lo file + . $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" \ + && test "$pic_object" != none; then + rmfiles="$rmfiles $dir/$pic_object" + fi + + # Add non-PIC object to the list of files to remove. + if test -n "$non_pic_object" \ + && test "$non_pic_object" != none; then + rmfiles="$rmfiles $dir/$non_pic_object" + fi + fi + ;; + + *) + if test "$mode" = clean ; then + noexename=$name + case $file in + *.exe) + file=`$echo $file|${SED} 's,.exe$,,'` + noexename=`$echo $name|${SED} 's,.exe$,,'` + # $file with .exe has already been added to rmfiles, + # add $file without .exe + rmfiles="$rmfiles $file" + ;; + esac + # Do a test to see if this is a libtool program. + if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + relink_command= + . $dir/$noexename + + # note $name still contains .exe if it was in $file originally + # as does the version of $file that was added into $rmfiles + rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" + if test "$fast_install" = yes && test -n "$relink_command"; then + rmfiles="$rmfiles $objdir/lt-$name" + fi + if test "X$noexename" != "X$name" ; then + rmfiles="$rmfiles $objdir/lt-${noexename}.c" + fi + fi + fi + ;; + esac + $show "$rm $rmfiles" + $run $rm $rmfiles || exit_status=1 + done + objdir="$origobjdir" + + # Try to remove the ${objdir}s in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + $show "rmdir $dir" + $run rmdir $dir >/dev/null 2>&1 + fi + done + + exit $exit_status + ;; + + "") + $echo "$modename: you must specify a MODE" 1>&2 + $echo "$generic_help" 1>&2 + exit $EXIT_FAILURE + ;; + esac + + if test -z "$exec_cmd"; then + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$generic_help" 1>&2 + exit $EXIT_FAILURE + fi +fi # test -z "$show_help" + +if test -n "$exec_cmd"; then + eval exec $exec_cmd + exit $EXIT_FAILURE +fi + +# We need to display help for each of the modes. +case $mode in +"") $echo \ +"Usage: $modename [OPTION]... [MODE-ARG]... + +Provide generalized library-building support services. + + --config show all configuration variables + --debug enable verbose shell tracing +-n, --dry-run display commands without modifying any files + --features display basic configuration information and exit + --finish same as \`--mode=finish' + --help display this help message and exit + --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS] + --quiet same as \`--silent' + --silent don't print informational messages + --tag=TAG use configuration variables from tag TAG + --version print version information + +MODE must be one of the following: + + clean remove files from the build directory + compile compile a source file into a libtool object + execute automatically set library path, then run a program + finish complete the installation of libtool libraries + install install libraries or executables + link create a library or an executable + uninstall remove libraries from an installed directory + +MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for +a more detailed description of MODE. + +Report bugs to ." + exit $EXIT_SUCCESS + ;; + +clean) + $echo \ +"Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + +compile) + $echo \ +"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -prefer-pic try to building PIC objects only + -prefer-non-pic try to building non-PIC objects only + -static always build a \`.o' file suitable for static linking + +COMPILE-COMMAND is a command to be used in creating a \`standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix \`.c' with the +library object suffix, \`.lo'." + ;; + +execute) + $echo \ +"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to \`-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + +finish) + $echo \ +"Usage: $modename [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the \`--dry-run' option if you just want to see what would be executed." + ;; + +install) + $echo \ +"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the \`install' or \`cp' program. + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + +link) + $echo \ +"Usage: $modename [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -objectlist FILE Use a list of object files found in FILE to specify objects + -precious-files-regex REGEX + don't remove output files matching REGEX + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -static do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + +All other options (arguments beginning with \`-') are ignored. + +Every other argument is treated as a filename. Files ending in \`.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in \`.la', then a libtool library is created, +only library objects (\`.lo' files) may be specified, and \`-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created +using \`ar' and \`ranlib', or on Windows using \`lib'. + +If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file +is created, otherwise an executable program is created." + ;; + +uninstall) + $echo \ +"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + +*) + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$help" 1>&2 + exit $EXIT_FAILURE + ;; +esac + +$echo +$echo "Try \`$modename --help' for more information about other modes." + +exit $? + +# The TAGs below are defined such that we never get into a situation +# in which we disable both kinds of libraries. Given conflicting +# choices, we go for a static library, that is the most portable, +# since we can't tell whether shared libraries were disabled because +# the user asked for that or because the platform doesn't support +# them. This is particularly important on AIX, because we don't +# support having both static and shared libraries enabled at the same +# time on that platform, so we default to a shared-only configuration. +# If a disable-shared tag is given, we'll fallback to a static-only +# configuration. But we'll never go from static-only to shared-only. + +# ### BEGIN LIBTOOL TAG CONFIG: disable-shared +build_libtool_libs=no +build_old_libs=yes +# ### END LIBTOOL TAG CONFIG: disable-shared + +# ### BEGIN LIBTOOL TAG CONFIG: disable-static +build_old_libs=`case $build_libtool_libs in yes) $echo no;; *) $echo yes;; esac` +# ### END LIBTOOL TAG CONFIG: disable-static + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: diff --git a/m4/acx_pthread.m4 b/m4/acx_pthread.m4 new file mode 100644 index 0000000..bedf51c --- /dev/null +++ b/m4/acx_pthread.m4 @@ -0,0 +1,199 @@ +dnl Available from the GNU Autoconf Macro Archive at: +dnl http://www.gnu.org/software/ac-archive/htmldoc/acx_pthread.html +dnl +AC_DEFUN([ACX_PTHREAD], [ +AC_REQUIRE([AC_CANONICAL_HOST]) +AC_LANG_SAVE +AC_LANG_C +acx_pthread_ok=no + +# We used to check for pthread.h first, but this fails if pthread.h +# requires special compiler flags (e.g. on True64 or Sequent). +# It gets checked for in the link test anyway. + +# First of all, check if the user has set any of the PTHREAD_LIBS, +# etcetera environment variables, and if threads linking works using +# them: +if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) + AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes) + AC_MSG_RESULT($acx_pthread_ok) + if test x"$acx_pthread_ok" = xno; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" +fi + +# We must check for the threads library under a number of different +# names; the ordering is very important because some systems +# (e.g. DEC) have both -lpthread and -lpthreads, where one of the +# libraries is broken (non-POSIX). + +# Create a list of thread flags to try. Items starting with a "-" are +# C compiler flags, and other items are library names, except for "none" +# which indicates that we try without any flags at all, and "pthread-config" +# which is a program returning the flags for the Pth emulation library. + +acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" + +# The ordering *is* (sometimes) important. Some notes on the +# individual items follow: + +# pthreads: AIX (must check this before -lpthread) +# none: in case threads are in libc; should be tried before -Kthread and +# other compiler flags to prevent continual compiler warnings +# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) +# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) +# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) +# -pthreads: Solaris/gcc +# -mthreads: Mingw32/gcc, Lynx/gcc +# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it +# doesn't hurt to check since this sometimes defines pthreads too; +# also defines -D_REENTRANT) +# pthread: Linux, etcetera +# --thread-safe: KAI C++ +# pthread-config: use pthread-config program (for GNU Pth library) + +case "${host_cpu}-${host_os}" in + *solaris*) + + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (We need to link with -pthread or + # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather + # a function called by this macro, so we could check for that, but + # who knows whether they'll stub that too in a future libc.) So, + # we'll just look for -pthreads and -lpthread first: + + acx_pthread_flags="-pthread -pthreads pthread -mt $acx_pthread_flags" + ;; +esac + +if test x"$acx_pthread_ok" = xno; then +for flag in $acx_pthread_flags; do + + case $flag in + none) + AC_MSG_CHECKING([whether pthreads work without any flags]) + ;; + + -*) + AC_MSG_CHECKING([whether pthreads work with $flag]) + PTHREAD_CFLAGS="$flag" + ;; + + pthread-config) + AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no) + if test x"$acx_pthread_config" = xno; then continue; fi + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) + AC_MSG_CHECKING([for the pthreads library -l$flag]) + PTHREAD_LIBS="-l$flag" + ;; + esac + + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + AC_TRY_LINK([#include ], + [pthread_t th; pthread_join(th, 0); + pthread_attr_init(0); pthread_cleanup_push(0, 0); + pthread_create(0,0,0,0); pthread_cleanup_pop(0); ], + [acx_pthread_ok=yes]) + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + AC_MSG_RESULT($acx_pthread_ok) + if test "x$acx_pthread_ok" = xyes; then + break; + fi + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" +done +fi + +# Various other checks: +if test "x$acx_pthread_ok" = xyes; then + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Detect AIX lossage: threads are created detached by default + # and the JOINABLE attribute has a nonstandard name (UNDETACHED). + AC_MSG_CHECKING([for joinable pthread attribute]) + AC_TRY_LINK([#include ], + [int attr=PTHREAD_CREATE_JOINABLE;], + ok=PTHREAD_CREATE_JOINABLE, ok=unknown) + if test x"$ok" = xunknown; then + AC_TRY_LINK([#include ], + [int attr=PTHREAD_CREATE_UNDETACHED;], + ok=PTHREAD_CREATE_UNDETACHED, ok=unknown) + fi + if test x"$ok" != xPTHREAD_CREATE_JOINABLE; then + AC_DEFINE(PTHREAD_CREATE_JOINABLE, $ok, + [Define to the necessary symbol if this constant + uses a non-standard name on your system.]) + fi + AC_MSG_RESULT(${ok}) + if test x"$ok" = xunknown; then + AC_MSG_WARN([we do not know how to create joinable pthreads]) + fi + + AC_MSG_CHECKING([if more special flags are required for pthreads]) + flag=no + case "${host_cpu}-${host_os}" in + *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";; + *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";; + esac + AC_MSG_RESULT(${flag}) + if test "x$flag" != xno; then + PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" + fi + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + # More AIX lossage: must compile with cc_r + AC_CHECK_PROG(PTHREAD_CC, cc_r, cc_r, ${CC}) +else + PTHREAD_CC="$CC" +fi + +AC_SUBST(PTHREAD_LIBS) +AC_SUBST(PTHREAD_CFLAGS) +AC_SUBST(PTHREAD_CC) + +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: +if test x"$acx_pthread_ok" = xyes; then + ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1]) + : +else + acx_pthread_ok=no + $2 +fi +AC_LANG_RESTORE +])dnl ACX_PTHREAD diff --git a/m4/ax_c_float_words_bigendian.m4 b/m4/ax_c_float_words_bigendian.m4 new file mode 100644 index 0000000..68ae950 --- /dev/null +++ b/m4/ax_c_float_words_bigendian.m4 @@ -0,0 +1,56 @@ +AC_DEFUN([AX_C_FLOAT_WORDS_BIGENDIAN], +[ +AC_CACHE_CHECK(whether float word ordering is bigendian, + ax_cv_c_float_words_bigendian, [ + +ax_cv_c_float_words_bigendian=unknown + +STRINGS="strings -a -" + + +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include +void foo(double *d);],[ + +static double d = 90904234967036810337470478905505011476211692735615632014797120844053488865816695273723469097858056257517020191247487429516932130503560650002327564517570778480236724525140520121371739201496540132640109977779420565776568942592.0; + +foo(&d); +printf("%f",d); + +])], [ + +$STRINGS conftest.$ac_objext > conftest.str +if grep noonsees conftest.str >/dev/null ; then + ax_cv_c_float_words_bigendian=yes +fi +if grep seesnoon conftest.str >/dev/null ; then + if test "$ax_cv_c_float_words_bigendian" = unknown; then + ax_cv_c_float_words_bigendian=no + else + ax_cv_c_float_words_bigendian=unknown + fi +fi +cp conftest.o /tmp/conftest.osav +cp conftest.str /tmp/conftest.sav +/bin/rm -f conftest.str + +])]) + +case $ax_cv_c_float_words_bigendian in + yes) + m4_default([$1], + [AC_DEFINE([FLOAT_WORDS_BIGENDIAN], 1, + [Define to 1 if your system stores words within floats + with the most significant word first])]) ;; + no) + $2 ;; + *) + m4_default([$3], + [AC_MSG_ERROR([ + +Unknown float word ordering. You need to manually preset +ax_cv_c_float_words_bigendian=no (or yes) according to your system. + + ])]) ;; +esac + +])# AX_C_FLOAT_WORDS_BIGENDIAN diff --git a/m4/ax_check_gl.m4 b/m4/ax_check_gl.m4 new file mode 100644 index 0000000..47ea4e0 --- /dev/null +++ b/m4/ax_check_gl.m4 @@ -0,0 +1,82 @@ +dnl Available from the GNU Autoconf Macro Archive at: +dnl http://www.gnu.org/software/ac-archive/htmldoc/ax_check_gl.html +dnl +AC_DEFUN([AX_CHECK_GL], +[AC_REQUIRE([AC_PATH_X])dnl +AC_REQUIRE([ACX_PTHREAD])dnl + +# +# There isn't a reliable way to know we should use the Apple OpenGL framework +# without a configure option. A Mac OS X user may have installed an +# alternative GL implementation (e.g., Mesa), which may or may not depend on X. +# +AC_ARG_WITH([apple-opengl-framework], + [AC_HELP_STRING([--with-apple-opengl-framework], + [use Apple OpenGL framework (Mac OS X only)])]) +if test "X$with_apple_opengl_framework" = "Xyes"; then + AC_DEFINE([HAVE_APPLE_OPENGL_FRAMEWORK], [1], + [Use the Apple OpenGL framework.]) + GL_LIBS="-framework OpenGL" +else + AC_LANG_PUSH(C) + + AX_LANG_COMPILER_MS + if test X$ax_compiler_ms = Xno; then + GL_CFLAGS="${PTHREAD_CFLAGS}" + GL_LIBS="${PTHREAD_LIBS} -lm" + fi + + # + # Use x_includes and x_libraries if they have been set (presumably by + # AC_PATH_X). + # + if test "X$no_x" != "Xyes"; then + if test -n "$x_includes"; then + GL_CFLAGS="-I${x_includes} ${GL_CFLAGS}" + fi + if test -n "$x_libraries"; then + GL_LIBS="-L${x_libraries} -lX11 ${GL_LIBS}" + fi + fi + + AC_CHECK_HEADERS([windows.h]) + + AC_CACHE_CHECK([for OpenGL library], [ax_cv_check_gl_libgl], + [ax_cv_check_gl_libgl="no" + ax_save_CPPFLAGS="${CPPFLAGS}" + CPPFLAGS="${GL_CFLAGS} ${CPPFLAGS}" + ax_save_LIBS="${LIBS}" + LIBS="" + ax_check_libs="-lopengl32 -lGL" + for ax_lib in ${ax_check_libs}; do + if test X$ax_compiler_ms = Xyes; then + ax_try_lib=`echo $ax_lib | sed -e 's/^-l//' -e 's/$/.lib/'` + else + ax_try_lib="${ax_lib}" + fi + LIBS="${ax_try_lib} ${GL_LIBS} ${ax_save_LIBS}" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[ +# if HAVE_WINDOWS_H && defined(_WIN32) +# include +# endif +# include ]], + [[glBegin(0)]])], + [ax_cv_check_gl_libgl="${ax_try_lib}"; break]) + done + LIBS=${ax_save_LIBS} + CPPFLAGS=${ax_save_CPPFLAGS}]) + + if test "X${ax_cv_check_gl_libgl}" = "Xno"; then + no_gl="yes" + GL_CFLAGS="" + GL_LIBS="" + else + GL_LIBS="${ax_cv_check_gl_libgl} ${GL_LIBS}" + fi + AC_LANG_POP(C) +fi + +AC_SUBST([GL_CFLAGS]) +AC_SUBST([GL_LIBS]) +])dnl diff --git a/m4/ax_check_glu.m4 b/m4/ax_check_glu.m4 new file mode 100644 index 0000000..d1c22fa --- /dev/null +++ b/m4/ax_check_glu.m4 @@ -0,0 +1,58 @@ +dnl Available from the GNU Autoconf Macro Archive at: +dnl http://www.gnu.org/software/ac-archive/htmldoc/ax_check_glu.html +dnl +AC_DEFUN([AX_CHECK_GLU], +[AC_REQUIRE([AX_CHECK_GL])dnl +AC_REQUIRE([AC_PROG_CXX])dnl +GLU_CFLAGS="${GL_CFLAGS}" +if test "X${with_apple_opengl_framework}" != "Xyes"; then + AC_CACHE_CHECK([for OpenGL Utility library], [ax_cv_check_glu_libglu], + [ax_cv_check_glu_libglu="no" + ax_save_CPPFLAGS="${CPPFLAGS}" + CPPFLAGS="${GL_CFLAGS} ${CPPFLAGS}" + ax_save_LIBS="${LIBS}" + LIBS="" + ax_check_libs="-lglu32 -lGLU" + for ax_lib in ${ax_check_libs}; do + if test X$ax_compiler_ms = Xyes; then + ax_try_lib=`echo $ax_lib | sed -e 's/^-l//' -e 's/$/.lib/'` + else + ax_try_lib="${ax_lib}" + fi + LIBS="${ax_try_lib} ${GL_LIBS} ${ax_save_LIBS}" + # + # libGLU typically links with libstdc++ on POSIX platforms. However, + # setting the language to C++ means that test program source is named + # "conftest.cc"; and Microsoft cl doesn't know what to do with such a + # file. + # + AC_LANG_PUSH([C++]) + if test X$ax_compiler_ms = Xyes; then + AC_LANG_PUSH([C]) + fi + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[ +# if HAVE_WINDOWS_H && defined(_WIN32) +# include +# endif +# include ]], + [[gluBeginCurve(0)]])], + [ax_cv_check_glu_libglu="${ax_try_lib}"; break]) + if test X$ax_compiler_ms = Xyes; then + AC_LANG_POP([C]) + fi + AC_LANG_POP([C++]) + done + LIBS=${ax_save_LIBS} + CPPFLAGS=${ax_save_CPPFLAGS}]) + if test "X${ax_cv_check_glu_libglu}" = "Xno"; then + no_glu="yes" + GLU_CFLAGS="" + GLU_LIBS="" + else + GLU_LIBS="${ax_cv_check_glu_libglu} ${GL_LIBS}" + fi +fi +AC_SUBST([GLU_CFLAGS]) +AC_SUBST([GLU_LIBS]) +]) diff --git a/m4/ax_check_glut.m4 b/m4/ax_check_glut.m4 new file mode 100644 index 0000000..a6fd5cd --- /dev/null +++ b/m4/ax_check_glut.m4 @@ -0,0 +1,72 @@ +dnl Available from the GNU Autoconf Macro Archive at: +dnl http://www.gnu.org/software/ac-archive/htmldoc/ax_check_glut.html +dnl +AC_DEFUN([AX_CHECK_GLUT], +[AC_REQUIRE([AX_CHECK_GLU])dnl +AC_REQUIRE([AC_PATH_XTRA])dnl + +if test "X$with_apple_opengl_framework" = "Xyes"; then + GLUT_CFLAGS="${GLU_CFLAGS}" + GLUT_LIBS="-framework GLUT -lobjc ${GL_LIBS}" +else + GLUT_CFLAGS=${GLU_CFLAGS} + GLUT_LIBS=${GLU_LIBS} + + # + # If X is present, assume GLUT depends on it. + # + if test "X${no_x}" != "Xyes"; then + PRE_GLUT_LIBS="${X_PRE_LIBS} -L/usr/X11/lib -L/usr/X11R6/lib" + AC_CHECK_LIB([Xmu],[XmuMakeAtom],[ + PRE_GLUT_LIBS="${GLUT_LIBS} -lXmu" + ]) + AC_CHECK_LIB([Xi],[XAllowDeviceEvents],[ + PRE_GLUT_LIBS="${GLUTLIBS} -lXi" + ]) + GLUT_LIBS="${PRE_GLUT_LIBS} ${X_EXTRA_LIBS} ${GLUT_LIBS}" + fi + + AC_LANG_PUSH(C) + + ax_save_CPPFLAGS="${CPPFLAGS}" + CPPFLAGS="${GLUT_CFLAGS} ${CPPFLAGS}" + + AC_CACHE_CHECK([for GLUT library], [ax_cv_check_glut_libglut], + [ax_cv_check_glut_libglut="no" + ax_save_LIBS="${LIBS}" + LIBS="" + ax_check_libs="-lglut32 -lglut" + for ax_lib in ${ax_check_libs}; do + if test X$ax_compiler_ms = Xyes; then + ax_try_lib=`echo $ax_lib | sed -e 's/^-l//' -e 's/$/.lib/'` + else + ax_try_lib="${ax_lib}" + fi + LIBS="${ax_try_lib} ${GLUT_LIBS} ${ax_save_LIBS}" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[ +# if HAVE_WINDOWS_H && (defined(_WIN32) || defined(CYGWIN_USE_WIN32)) +# include +# endif +# include ]], + [[glutMainLoop()]])], + [ax_cv_check_glut_libglut="${ax_try_lib}"; break]) + + done + LIBS=${ax_save_LIBS} + ]) + CPPFLAGS="${ax_save_CPPFLAGS}" + AC_LANG_POP(C) + + if test "X${ax_cv_check_glut_libglut}" = "Xno"; then + no_glut="yes" + GLUT_CFLAGS="" + GLUT_LIBS="" + else + GLUT_LIBS="${ax_cv_check_glut_libglut} ${GLUT_LIBS}" + fi +fi + +AC_SUBST([GLUT_CFLAGS]) +AC_SUBST([GLUT_LIBS]) +])dnl diff --git a/m4/ax_lang_compiler_ms.m4 b/m4/ax_lang_compiler_ms.m4 new file mode 100644 index 0000000..d0c73dc --- /dev/null +++ b/m4/ax_lang_compiler_ms.m4 @@ -0,0 +1,14 @@ +dnl Available from the GNU Autoconf Macro Archive at: +dnl http://www.gnu.org/software/ac-archive/htmldoc/ax_lang_compiler_ms.html +dnl +AC_DEFUN([AX_LANG_COMPILER_MS], +[AC_CACHE_CHECK([whether we are using the Microsoft _AC_LANG compiler], + [ax_cv_[]_AC_LANG_ABBREV[]_compiler_ms], +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[#ifndef _MSC_VER + choke me +#endif +]])], + [ax_compiler_ms=yes], + [ax_compiler_ms=no]) +ax_cv_[]_AC_LANG_ABBREV[]_compiler_ms=$ax_compiler_ms +])]) diff --git a/m4/boinc_platform.m4 b/m4/boinc_platform.m4 new file mode 100644 index 0000000..da85d8f --- /dev/null +++ b/m4/boinc_platform.m4 @@ -0,0 +1,69 @@ +AC_DEFUN([BOINC_PLATFORM],[ + AC_ARG_WITH([boinc-platform], + AC_HELP_STRING([--with-boinc-platform], + [override the default boinc platform]), + [boinc_platform="$withval"], + [boinc_platform=]) + AC_ARG_WITH([boinc-alt-platform], + AC_HELP_STRING([--with-boinc-alt-platform], + [override the boinc alternate platform]), + [boinc_alt_platform="$withval"], + [boinc_alt_platform=]) + AC_MSG_CHECKING([boinc platform]) + if test -z "${boinc_platform}" ; then + boinc_platform=`echo $target | $SED -e 's/amd64/x86_64/' -e 's/portbld/pc/' -e 's/redhat/pc/' -e 's/x86_64-unknown/x86_64-pc/' -e 's/[[0-9]]$//' -e 's/[[0-9]]$//' -e 's/\.$//' -e 's/[[0-9]]$//' -e 's/\.$//' -e 's/[[0-9]]$//'` + case "${boinc_platform}" in + sparc-sun-solaris) + if test "$COMPILER_MODEL_BITS" = "64" ; then + boinc_platform=`echo $boinc_platform | $SED 's/sparc/sparc64/'` + if test -z "$boinc_alt_platform" ; then + boinc_alt_platform=sparc-sun-solaris + fi + elif test -z "$boinc_alt_platform" ; then + boinc_alt_platform=sparc-sun-solaris2.7 + fi + ;; + x86_64*linux-gnu) + if test "$COMPILER_MODEL_BITS" = "32" ; then + boinc_platform="i686-pc-linux-gnu" + elif test -z "$boinc_alt_platform" ; then + boinc_alt_platform="i686-pc-linux-gnu" + fi + ;; + powerpc-apple-darwin) + if test "$COMPILER_MODEL_BITS" = "64" ; then + boinc_platform="powerpc64-apple-darwin" + if test -z "$boinc_alt_platform" ; then + boinc_alt_platform="powerpc-apple-darwin" + fi + fi + ;; + hppa*-hp-hpux*) + if test "$COMPILER_MODEL_BITS" = "64" ; then + boinc_platform="hppa64-hp-hpux" + if test -z "${boinc_alt_platform}" ; then + boinc_alt_platform="hppa-hp-hpux" + fi + else + boinc_platform="hppa-hp-hpux" + fi + ;; + ia64-hp-hpux*) + boinc_platform="ia64-hp-hpux" + ;; + + esac + fi + AC_DEFINE_UNQUOTED([HOSTTYPE],"$boinc_platform",[Platform identification used to identify applications for this BOINC core client]) + AC_SUBST([boinc_platform],$boinc_platform) + AC_MSG_RESULT([$boinc_platform]) + AC_MSG_CHECKING([alternate boinc platform]) + if test -n "$boinc_alt_platform" ; then + AC_DEFINE_UNQUOTED([HOSTTYPEALT],"$boinc_alt_platform",[Alternate identification used to identify applications for this BOINC core client]) + AC_SUBST([boinc_alt_platform],$boinc_alt_platform) + AC_MSG_RESULT($boinc_alt_platform) + else + AC_MSG_RESULT(none) + fi +]) + diff --git a/m4/check_ssl.m4 b/m4/check_ssl.m4 new file mode 100644 index 0000000..c6fc398 --- /dev/null +++ b/m4/check_ssl.m4 @@ -0,0 +1,45 @@ +AC_DEFUN([CHECK_SSL], +[AC_MSG_CHECKING(for openssl) +SSLDIR= +found_ssl="no" +AC_ARG_WITH(ssl, + AC_HELP_STRING([--with-ssl], + [Use openssl (in specified installation directory)]), + [check_ssl_dir="$withval"], + [check_ssl_dir=]) +for dir in $check_ssl_dir /usr/local/ssl /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /usr; do + ssldir="$dir" + if test -f "$dir/include/openssl/ssl.h"; then + found_ssl="yes"; + SSLDIR="${ssldir}" + CFLAGS="$CFLAGS -I$ssldir/include -I$ssldir/include/openssl"; + CXXFLAGS="$CXXFLAGS -I$ssldir/include -I$ssldir/include/openssl"; + break; + fi + if test -f "$dir/include/ssl.h"; then + found_ssl="yes"; + SSLDIR="${ssldir}" + CFLAGS="$CFLAGS -I$ssldir/include/"; + CXXFLAGS="$CXXFLAGS -I$ssldir/include/"; + break + fi +done +AC_MSG_RESULT($found_ssl) +if test x_$found_ssl != x_yes; then + AC_MSG_ERROR([ +---------------------------------------------------------------------- + Cannot find openssl libraries. + + Please install openssl or specify installation directory with + --with-ssl=(dir). +---------------------------------------------------------------------- +]) +else + printf "OpenSSL found in $ssldir\n"; + LIBS="$LIBS -lssl -lcrypto"; + LDFLAGS="$LDFLAGS -L$ssldir/lib"; + AC_DEFINE_UNQUOTED([USE_OPENSSL],[1], + ["Define to 1 if you want to use the openssl crypto library"]) + AC_SUBST(SSLDIR) +fi +])dnl diff --git a/m4/libcurl.m4 b/m4/libcurl.m4 new file mode 100644 index 0000000..c72167d --- /dev/null +++ b/m4/libcurl.m4 @@ -0,0 +1,230 @@ +# LIBCURL_CHECK_CONFIG ([DEFAULT-ACTION], [MINIMUM-VERSION], +# [ACTION-IF-YES], [ACTION-IF-NO]) +# ---------------------------------------------------------- +# David Shaw Jun-21-2005 +# +# Checks for libcurl. DEFAULT-ACTION is the string yes or no to +# specify whether to default to --with-libcurl or --without-libcurl. +# If not supplied, DEFAULT-ACTION is yes. MINIMUM-VERSION is the +# minimum version of libcurl to accept. Pass the version as a regular +# version number like 7.10.1. If not supplied, any version is +# accepted. ACTION-IF-YES is a list of shell commands to run if +# libcurl was successfully found and passed the various tests. +# ACTION-IF-NO is a list of shell commands that are run otherwise. +# Note that using --without-libcurl does run ACTION-IF-NO. +# +# This macro defines HAVE_LIBCURL if a working libcurl setup is found, +# and sets @LIBCURL@ and @LIBCURL_CPPFLAGS@ to the necessary values. +# Other useful defines are LIBCURL_FEATURE_xxx where xxx are the +# various features supported by libcurl, and LIBCURL_PROTOCOL_yyy +# where yyy are the various protocols supported by libcurl. Both xxx +# and yyy are capitalized. See the list of AH_TEMPLATEs at the top of +# the macro for the complete list of possible defines. Shell +# variables $libcurl_feature_xxx and $libcurl_protocol_yyy are also +# defined to 'yes' for those features and protocols that were found. +# Note that xxx and yyy keep the same capitalization as in the +# curl-config list (e.g. it's "HTTP" and not "http"). +# +# Users may override the detected values by doing something like: +# LIBCURL="-lcurl" LIBCURL_CPPFLAGS="-I/usr/myinclude" ./configure +# +# For the sake of sanity, this macro assumes that any libcurl that is +# found is after version 7.7.2, the first version that included the +# curl-config script. Note that it is very important for people +# packaging binary versions of libcurl to include this script! +# Without curl-config, we can only guess what protocols are available. + +AC_DEFUN([LIBCURL_CHECK_CONFIG], +[ + AH_TEMPLATE([LIBCURL_FEATURE_SSL],[Defined if libcurl supports SSL]) + AH_TEMPLATE([LIBCURL_FEATURE_KRB4],[Defined if libcurl supports KRB4]) + AH_TEMPLATE([LIBCURL_FEATURE_IPV6],[Defined if libcurl supports IPv6]) + AH_TEMPLATE([LIBCURL_FEATURE_LIBZ],[Defined if libcurl supports libz]) + AH_TEMPLATE([LIBCURL_FEATURE_ASYNCHDNS],[Defined if libcurl supports AsynchDNS]) + + AH_TEMPLATE([LIBCURL_PROTOCOL_HTTP],[Defined if libcurl supports HTTP]) + AH_TEMPLATE([LIBCURL_PROTOCOL_HTTPS],[Defined if libcurl supports HTTPS]) + AH_TEMPLATE([LIBCURL_PROTOCOL_FTP],[Defined if libcurl supports FTP]) + AH_TEMPLATE([LIBCURL_PROTOCOL_FTPS],[Defined if libcurl supports FTPS]) + AH_TEMPLATE([LIBCURL_PROTOCOL_GOPHER],[Defined if libcurl supports GOPHER]) + AH_TEMPLATE([LIBCURL_PROTOCOL_FILE],[Defined if libcurl supports FILE]) + AH_TEMPLATE([LIBCURL_PROTOCOL_TELNET],[Defined if libcurl supports TELNET]) + AH_TEMPLATE([LIBCURL_PROTOCOL_LDAP],[Defined if libcurl supports LDAP]) + AH_TEMPLATE([LIBCURL_PROTOCOL_DICT],[Defined if libcurl supports DICT]) + + AC_ARG_WITH(libcurl, + AC_HELP_STRING([--with-libcurl=DIR],[look for the curl library in DIR]), + [_libcurl_with=$withval],[_libcurl_with=ifelse([$1],,[yes],[$1])]) + + if test "$_libcurl_with" != "no" ; then + + AC_PROG_AWK + + _libcurl_version_parse="eval $AWK '{split(\$NF,A,\".\"); X=256*256*A[[1]]+256*A[[2]]+A[[3]]; print X;}'" + + _libcurl_try_link=yes + + if test -d "$_libcurl_with" ; then + CPPFLAGS="${CPPFLAGS} -I$withval/include" + LDFLAGS="${LDFLAGS} -L$withval/lib" + fi + + AC_PATH_PROG([_libcurl_config],[curl-config]) + + if test x$_libcurl_config != "x" ; then + AC_CACHE_CHECK([for the version of libcurl], + [libcurl_cv_lib_curl_version], + [libcurl_cv_lib_curl_version=`$_libcurl_config --version | $AWK '{print $[]2}'`]) + + _libcurl_version=`echo $libcurl_cv_lib_curl_version | $_libcurl_version_parse` + _libcurl_wanted=`echo ifelse([$2],,[0],[$2]) | $_libcurl_version_parse` + + if test $_libcurl_wanted -gt 0 ; then + AC_CACHE_CHECK([for libcurl >= version $2], + [libcurl_cv_lib_version_ok], + [ + if test $_libcurl_version -ge $_libcurl_wanted ; then + libcurl_cv_lib_version_ok=yes + else + libcurl_cv_lib_version_ok=no + fi + ]) + fi + + if test $_libcurl_wanted -eq 0 || test x$libcurl_cv_lib_version_ok = xyes ; then + if test x"$LIBCURL_CPPFLAGS" = "x" ; then + LIBCURL_CPPFLAGS=`$_libcurl_config --cflags` + fi + if test x"$LIBCURL" = "x" ; then + LIBCURL=`$_libcurl_config --libs` + + # This is so silly, but Apple actually has a bug in their + # curl-config script. Fixed in Tiger, but there are still + # lots of Panther installs around. + case "${host}" in + powerpc-apple-darwin7*) + LIBCURL=`echo $LIBCURL | sed -e 's|-arch i386||g'` + ;; + esac + fi + + # All curl-config scripts support --feature + _libcurl_features=`$_libcurl_config --feature` + + # Is it modern enough to have --protocols? (7.12.4) + if test $_libcurl_version -ge 461828 ; then + _libcurl_protocols=`$_libcurl_config --protocols` + fi + else + _libcurl_try_link=no + fi + + unset _libcurl_wanted + fi + + if test $_libcurl_try_link = yes ; then + + # we didn't find curl-config, so let's see if the user-supplied + # link line (or failing that, "-lcurl") is enough. + LIBCURL=${LIBCURL-"-lcurl"} + + AC_CACHE_CHECK([whether libcurl is usable], + [libcurl_cv_lib_curl_usable], + [ + _libcurl_save_cppflags=$CPPFLAGS + CPPFLAGS="$CPPFLAGS $LIBCURL_CPPFLAGS" + _libcurl_save_libs=$LIBS + LIBS="$LIBS $LIBCURL" + + AC_LINK_IFELSE(AC_LANG_PROGRAM([#include ],[ +/* Try and use a few common options to force a failure if we are + missing symbols or can't link. */ +int x; +curl_easy_setopt(NULL,CURLOPT_URL,NULL); +x=CURL_ERROR_SIZE; +x=CURLOPT_WRITEFUNCTION; +x=CURLOPT_FILE; +x=CURLOPT_ERRORBUFFER; +x=CURLOPT_STDERR; +x=CURLOPT_VERBOSE; +]),libcurl_cv_lib_curl_usable=yes,libcurl_cv_lib_curl_usable=no) + + CPPFLAGS=$_libcurl_save_cppflags + LIBS=$_libcurl_save_libs + unset _libcurl_save_cppflags + unset _libcurl_save_libs + ]) + + if test $libcurl_cv_lib_curl_usable = yes ; then + + # Does curl_free() exist in this version of libcurl? + # If not, fake it with free() + + _libcurl_save_cppflags=$CPPFLAGS + CPPFLAGS="$CPPFLAGS $LIBCURL_CPPFLAGS" + _libcurl_save_libs=$LIBS + LIBS="$LIBS $LIBCURL" + + AC_CHECK_FUNC(curl_free,, + AC_DEFINE(curl_free,free, + [Define curl_free() as free() if our version of curl lacks curl_free.])) + + CPPFLAGS=$_libcurl_save_cppflags + LIBS=$_libcurl_save_libs + unset _libcurl_save_cppflags + unset _libcurl_save_libs + + AC_DEFINE(HAVE_LIBCURL,1, + [Define to 1 if you have a functional curl library.]) + AC_SUBST(LIBCURL_CPPFLAGS) + AC_SUBST(LIBCURL) + + for _libcurl_feature in $_libcurl_features ; do + AC_DEFINE_UNQUOTED(AS_TR_CPP(libcurl_feature_$_libcurl_feature),[1]) + eval AS_TR_SH(libcurl_feature_$_libcurl_feature)=yes + done + + if test "x$_libcurl_protocols" = "x" ; then + + # We don't have --protocols, so just assume that all + # protocols are available + _libcurl_protocols="HTTP FTP GOPHER FILE TELNET LDAP DICT" + + if test x$libcurl_feature_SSL = xyes ; then + _libcurl_protocols="$_libcurl_protocols HTTPS" + + # FTPS wasn't standards-compliant until version + # 7.11.0 + if test $_libcurl_version -ge 461568; then + _libcurl_protocols="$_libcurl_protocols FTPS" + fi + fi + fi + + for _libcurl_protocol in $_libcurl_protocols ; do + AC_DEFINE_UNQUOTED(AS_TR_CPP(libcurl_protocol_$_libcurl_protocol),[1]) + eval AS_TR_SH(libcurl_protocol_$_libcurl_protocol)=yes + done + fi + fi + + unset _libcurl_try_link + unset _libcurl_version_parse + unset _libcurl_config + unset _libcurl_feature + unset _libcurl_features + unset _libcurl_protocol + unset _libcurl_protocols + unset _libcurl_version + fi + + if test x$_libcurl_with = xno || test x$libcurl_cv_lib_curl_usable != xyes ; then + # This is the IF-NO path + ifelse([$4],,:,[$4]) + else + # This is the IF-YES path + ifelse([$3],,:,[$3]) + fi + + unset _libcurl_with +])dnl diff --git a/m4/libtool.m4 b/m4/libtool.m4 new file mode 100644 index 0000000..cb35506 --- /dev/null +++ b/m4/libtool.m4 @@ -0,0 +1,6163 @@ +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- +## Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005 +## Free Software Foundation, Inc. +## Originally by Gordon Matzigkeit , 1996 +## +## This file is free software; the Free Software Foundation gives +## unlimited permission to copy and/or distribute it, with or without +## modifications, as long as this notice is preserved. + +# serial 47 AC_PROG_LIBTOOL + + +# AC_PROVIDE_IFELSE(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED) +# ----------------------------------------------------------- +# If this macro is not defined by Autoconf, define it here. +m4_ifdef([AC_PROVIDE_IFELSE], + [], + [m4_define([AC_PROVIDE_IFELSE], + [m4_ifdef([AC_PROVIDE_$1], + [$2], [$3])])]) + + +# AC_PROG_LIBTOOL +# --------------- +AC_DEFUN([AC_PROG_LIBTOOL], +[AC_REQUIRE([_AC_PROG_LIBTOOL])dnl +dnl If AC_PROG_CXX has already been expanded, run AC_LIBTOOL_CXX +dnl immediately, otherwise, hook it in at the end of AC_PROG_CXX. + AC_PROVIDE_IFELSE([AC_PROG_CXX], + [AC_LIBTOOL_CXX], + [define([AC_PROG_CXX], defn([AC_PROG_CXX])[AC_LIBTOOL_CXX + ])]) +dnl And a similar setup for Fortran 77 support + AC_PROVIDE_IFELSE([AC_PROG_F77], + [AC_LIBTOOL_F77], + [define([AC_PROG_F77], defn([AC_PROG_F77])[AC_LIBTOOL_F77 +])]) + +dnl Quote A][M_PROG_GCJ so that aclocal doesn't bring it in needlessly. +dnl If either AC_PROG_GCJ or A][M_PROG_GCJ have already been expanded, run +dnl AC_LIBTOOL_GCJ immediately, otherwise, hook it in at the end of both. + AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [ifdef([AC_PROG_GCJ], + [define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[AC_LIBTOOL_GCJ])]) + ifdef([A][M_PROG_GCJ], + [define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[AC_LIBTOOL_GCJ])]) + ifdef([LT_AC_PROG_GCJ], + [define([LT_AC_PROG_GCJ], + defn([LT_AC_PROG_GCJ])[AC_LIBTOOL_GCJ])])])]) +])])# AC_PROG_LIBTOOL + + +# _AC_PROG_LIBTOOL +# ---------------- +AC_DEFUN([_AC_PROG_LIBTOOL], +[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl +AC_BEFORE([$0],[AC_LIBTOOL_CXX])dnl +AC_BEFORE([$0],[AC_LIBTOOL_F77])dnl +AC_BEFORE([$0],[AC_LIBTOOL_GCJ])dnl + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +# Prevent multiple expansion +define([AC_PROG_LIBTOOL], []) +])# _AC_PROG_LIBTOOL + + +# AC_LIBTOOL_SETUP +# ---------------- +AC_DEFUN([AC_LIBTOOL_SETUP], +[AC_PREREQ(2.50)dnl +AC_REQUIRE([AC_ENABLE_SHARED])dnl +AC_REQUIRE([AC_ENABLE_STATIC])dnl +AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_LD])dnl +AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl +AC_REQUIRE([AC_PROG_NM])dnl + +AC_REQUIRE([AC_PROG_LN_S])dnl +AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl +# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers! +AC_REQUIRE([AC_OBJEXT])dnl +AC_REQUIRE([AC_EXEEXT])dnl +dnl + +AC_LIBTOOL_SYS_MAX_CMD_LEN +AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE +AC_LIBTOOL_OBJDIR + +AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl +_LT_AC_PROG_ECHO_BACKSLASH + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='sed -e 1s/^X//' +[sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'] + +# Same as above, but do not quote variable references. +[double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g'] + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +# Constants: +rm="rm -f" + +# Global variables: +default_ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except M$VC, +# which needs '.lib'). +libext=a +ltmain="$ac_aux_dir/ltmain.sh" +ofile="$default_ofile" +with_gnu_ld="$lt_cv_prog_gnu_ld" + +AC_CHECK_TOOL(AR, ar, false) +AC_CHECK_TOOL(RANLIB, ranlib, :) +AC_CHECK_TOOL(STRIP, strip, :) + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$AR" && AR=ar +test -z "$AR_FLAGS" && AR_FLAGS=cru +test -z "$AS" && AS=as +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$DLLTOOL" && DLLTOOL=dlltool +test -z "$LD" && LD=ld +test -z "$LN_S" && LN_S="ln -s" +test -z "$MAGIC_CMD" && MAGIC_CMD=file +test -z "$NM" && NM=nm +test -z "$SED" && SED=sed +test -z "$OBJDUMP" && OBJDUMP=objdump +test -z "$RANLIB" && RANLIB=: +test -z "$STRIP" && STRIP=: +test -z "$ac_objext" && ac_objext=o + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds" + ;; + *) + old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + +_LT_CC_BASENAME([$compiler]) + +# Only perform the check for file, if the check method requires it +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + AC_PATH_MAGIC + fi + ;; +esac + +AC_PROVIDE_IFELSE([AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no) +AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL], +enable_win32_dll=yes, enable_win32_dll=no) + +AC_ARG_ENABLE([libtool-lock], + [AC_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +AC_ARG_WITH([pic], + [AC_HELP_STRING([--with-pic], + [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], + [pic_mode="$withval"], + [pic_mode=default]) +test -z "$pic_mode" && pic_mode=default + +# Use C for the default configuration in the libtool script +tagname= +AC_LIBTOOL_LANG_C_CONFIG +_LT_AC_TAGCONFIG +])# AC_LIBTOOL_SETUP + + +# _LT_AC_SYS_COMPILER +# ------------------- +AC_DEFUN([_LT_AC_SYS_COMPILER], +[AC_REQUIRE([AC_PROG_CC])dnl + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# Allow CC to be a program name with arguments. +compiler=$CC +])# _LT_AC_SYS_COMPILER + + +# _LT_CC_BASENAME(CC) +# ------------------- +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +AC_DEFUN([_LT_CC_BASENAME], +[for cc_temp in $1""; do + case $cc_temp in + compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; + distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` +]) + + +# _LT_COMPILER_BOILERPLATE +# ------------------------ +# Check for compiler boilerplate output or warnings with +# the simple compiler test code. +AC_DEFUN([_LT_COMPILER_BOILERPLATE], +[ac_outfile=conftest.$ac_objext +printf "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$rm conftest* +])# _LT_COMPILER_BOILERPLATE + + +# _LT_LINKER_BOILERPLATE +# ---------------------- +# Check for linker boilerplate output or warnings with +# the simple link test code. +AC_DEFUN([_LT_LINKER_BOILERPLATE], +[ac_outfile=conftest.$ac_objext +printf "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$rm conftest* +])# _LT_LINKER_BOILERPLATE + + +# _LT_AC_SYS_LIBPATH_AIX +# ---------------------- +# Links a minimal program and checks the executable +# for the system default hardcoded library path. In most cases, +# this is /usr/lib:/lib, but when the MPI compilers are used +# the location of the communication and MPI libs are included too. +# If we don't find anything, use the default library path according +# to the aix ld manual. +AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX], +[AC_LINK_IFELSE(AC_LANG_PROGRAM,[ +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'`; fi],[]) +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +])# _LT_AC_SYS_LIBPATH_AIX + + +# _LT_AC_SHELL_INIT(ARG) +# ---------------------- +AC_DEFUN([_LT_AC_SHELL_INIT], +[ifdef([AC_DIVERSION_NOTICE], + [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)], + [AC_DIVERT_PUSH(NOTICE)]) +$1 +AC_DIVERT_POP +])# _LT_AC_SHELL_INIT + + +# _LT_AC_PROG_ECHO_BACKSLASH +# -------------------------- +# Add some code to the start of the generated configure script which +# will find an echo command which doesn't interpret backslashes. +AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH], +[_LT_AC_SHELL_INIT([ +# Check that we are running under the correct shell. +SHELL=${CONFIG_SHELL-/bin/sh} + +case X$ECHO in +X*--fallback-echo) + # Remove one level of quotation (which was required for Make). + ECHO=`echo "$ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','` + ;; +esac + +echo=${ECHO-echo} +if test "X[$]1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X[$]1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then + # Yippee, $echo works! + : +else + # Restart under the correct shell. + exec $SHELL "[$]0" --no-reexec ${1+"[$]@"} +fi + +if test "X[$]1" = X--fallback-echo; then + # used as fallback echo + shift + cat </dev/null 2>&1 && unset CDPATH + +if test -z "$ECHO"; then +if test "X${echo_test_string+set}" != Xset; then +# find a string as large as possible, as long as the shell can cope with it + for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do + # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... + if (echo_test_string="`eval $cmd`") 2>/dev/null && + echo_test_string="`eval $cmd`" && + (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null + then + break + fi + done +fi + +if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + : +else + # The Solaris, AIX, and Digital Unix default echo programs unquote + # backslashes. This makes it impossible to quote backslashes using + # echo "$something" | sed 's/\\/\\\\/g' + # + # So, first we look for a working echo in the user's PATH. + + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for dir in $PATH /usr/ucb; do + IFS="$lt_save_ifs" + if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && + test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$dir/echo" + break + fi + done + IFS="$lt_save_ifs" + + if test "X$echo" = Xecho; then + # We didn't find a better echo, so look for alternatives. + if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # This shell has a builtin print -r that does the trick. + echo='print -r' + elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && + test "X$CONFIG_SHELL" != X/bin/ksh; then + # If we have ksh, try running configure again with it. + ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} + export ORIGINAL_CONFIG_SHELL + CONFIG_SHELL=/bin/ksh + export CONFIG_SHELL + exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"} + else + # Try using printf. + echo='printf %s\n' + if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # Cool, printf works + : + elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL + export CONFIG_SHELL + SHELL="$CONFIG_SHELL" + export SHELL + echo="$CONFIG_SHELL [$]0 --fallback-echo" + elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$CONFIG_SHELL [$]0 --fallback-echo" + else + # maybe with a smaller string... + prev=: + + for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do + if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null + then + break + fi + prev="$cmd" + done + + if test "$prev" != 'sed 50q "[$]0"'; then + echo_test_string=`eval $prev` + export echo_test_string + exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"} + else + # Oops. We lost completely, so just stick with echo. + echo=echo + fi + fi + fi + fi +fi +fi + +# Copy echo and quote the copy suitably for passing to libtool from +# the Makefile, instead of quoting the original, which is used later. +ECHO=$echo +if test "X$ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then + ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo" +fi + +AC_SUBST(ECHO) +])])# _LT_AC_PROG_ECHO_BACKSLASH + + +# _LT_AC_LOCK +# ----------- +AC_DEFUN([_LT_AC_LOCK], +[AC_ARG_ENABLE([libtool-lock], + [AC_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line __oline__ "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case "`/usr/bin/file conftest.o`" in + *32-bit*) + case $host in + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_PUSH(C) + AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_POP]) + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL], +[*-*-cygwin* | *-*-mingw* | *-*-pw32*) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; + ]) +esac + +need_locks="$enable_libtool_lock" + +])# _LT_AC_LOCK + + +# AC_LIBTOOL_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------------------- +# Check whether the given compiler option works +AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], +[AC_REQUIRE([LT_AC_PROG_SED]) +AC_CACHE_CHECK([$1], [$2], + [$2=no + ifelse([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$3" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed >conftest.exp + $SED '/^$/d' conftest.err >conftest.er2 + if test ! -s conftest.err || diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + fi + $rm conftest* +]) + +if test x"[$]$2" = xyes; then + ifelse([$5], , :, [$5]) +else + ifelse([$6], , :, [$6]) +fi +])# AC_LIBTOOL_COMPILER_OPTION + + +# AC_LIBTOOL_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [ACTION-SUCCESS], [ACTION-FAILURE]) +# ------------------------------------------------------------ +# Check whether the given compiler option works +AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], +[AC_CACHE_CHECK([$1], [$2], + [$2=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $3" + printf "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + $echo "X$_lt_linker_boilerplate" | $Xsed > conftest.exp + $SED '/^$/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + else + $2=yes + fi + fi + $rm conftest* + LDFLAGS="$save_LDFLAGS" +]) + +if test x"[$]$2" = xyes; then + ifelse([$4], , :, [$4]) +else + ifelse([$5], , :, [$5]) +fi +])# AC_LIBTOOL_LINKER_OPTION + + +# AC_LIBTOOL_SYS_MAX_CMD_LEN +# -------------------------- +AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], +[# find the maximum length of command line arguments +AC_MSG_CHECKING([the maximum length of command line arguments]) +AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for *BSD + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + *) + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + while (test "X"`$SHELL [$]0 --fallback-echo "X$teststring" 2>/dev/null` \ + = "XX$teststring") >/dev/null 2>&1 && + new_result=`expr "X$teststring" : ".*" 2>&1` && + lt_cv_sys_max_cmd_len=$new_result && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + teststring= + # Add a significant safety factor because C++ compilers can tack on massive + # amounts of additional arguments before passing them to the linker. + # It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + ;; + esac +]) +if test -n $lt_cv_sys_max_cmd_len ; then + AC_MSG_RESULT($lt_cv_sys_max_cmd_len) +else + AC_MSG_RESULT(none) +fi +])# AC_LIBTOOL_SYS_MAX_CMD_LEN + + +# _LT_AC_CHECK_DLFCN +# -------------------- +AC_DEFUN([_LT_AC_CHECK_DLFCN], +[AC_CHECK_HEADERS(dlfcn.h)dnl +])# _LT_AC_CHECK_DLFCN + + +# _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# ------------------------------------------------------------------ +AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF], +[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl +if test "$cross_compiling" = yes; then : + [$4] +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +#ifdef __cplusplus +extern "C" void exit (int); +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + + exit (status); +}] +EOF + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_unknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_AC_TRY_DLOPEN_SELF + + +# AC_LIBTOOL_DLOPEN_SELF +# ------------------- +AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], +[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen="shl_load"], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen="dlopen"], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_AC_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test "x$lt_cv_dlopen_self" = xyes; then + LDFLAGS="$LDFLAGS $link_static_flag" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_AC_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +])# AC_LIBTOOL_DLOPEN_SELF + + +# AC_LIBTOOL_PROG_CC_C_O([TAGNAME]) +# --------------------------------- +# Check to see if options -c and -o are simultaneously supported by compiler +AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O], +[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl +AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], + [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)], + [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no + $rm -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $echo "X$_lt_compiler_boilerplate" | $Xsed > out/conftest.exp + $SED '/^$/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.err || diff out/conftest.exp out/conftest.er2 >/dev/null; then + _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + fi + fi + chmod u+w . + $rm conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files + $rm out/* && rmdir out + cd .. + rmdir conftest + $rm conftest* +]) +])# AC_LIBTOOL_PROG_CC_C_O + + +# AC_LIBTOOL_SYS_HARD_LINK_LOCKS([TAGNAME]) +# ----------------------------------------- +# Check to see if we can do hard links to lock some files if needed +AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], +[AC_REQUIRE([_LT_AC_LOCK])dnl + +hard_links="nottested" +if test "$_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test "$hard_links" = no; then + AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi +])# AC_LIBTOOL_SYS_HARD_LINK_LOCKS + + +# AC_LIBTOOL_OBJDIR +# ----------------- +AC_DEFUN([AC_LIBTOOL_OBJDIR], +[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], +[rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null]) +objdir=$lt_cv_objdir +])# AC_LIBTOOL_OBJDIR + + +# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH([TAGNAME]) +# ---------------------------------------------- +# Check hardcoding attributes. +AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], +[AC_MSG_CHECKING([how to hardcode library paths into programs]) +_LT_AC_TAGVAR(hardcode_action, $1)= +if test -n "$_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)" || \ + test -n "$_LT_AC_TAGVAR(runpath_var, $1)" || \ + test "X$_LT_AC_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then + + # We can hardcode non-existant directories. + if test "$_LT_AC_TAGVAR(hardcode_direct, $1)" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)" != no && + test "$_LT_AC_TAGVAR(hardcode_minus_L, $1)" != no; then + # Linking always hardcodes the temporary library directory. + _LT_AC_TAGVAR(hardcode_action, $1)=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + _LT_AC_TAGVAR(hardcode_action, $1)=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + _LT_AC_TAGVAR(hardcode_action, $1)=unsupported +fi +AC_MSG_RESULT([$_LT_AC_TAGVAR(hardcode_action, $1)]) + +if test "$_LT_AC_TAGVAR(hardcode_action, $1)" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi +])# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH + + +# AC_LIBTOOL_SYS_LIB_STRIP +# ------------------------ +AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP], +[striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) +fi + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac +fi +])# AC_LIBTOOL_SYS_LIB_STRIP + + +# AC_LIBTOOL_SYS_DYNAMIC_LINKER +# ----------------------------- +# PORTME Fill in your ld.so characteristics +AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER], +[AC_MSG_CHECKING([dynamic linker characteristics]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix4* | aix5*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[[45]]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | [grep ';[c-zC-Z]:/' >/dev/null]; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='$(test .$module = .yes && echo .so || echo .dylib)' + # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. + if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` + else + sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' + fi + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +kfreebsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[[01]]* | freebsdelf3.[[01]]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + *) # from 3.2 on + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case "$host_cpu" in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:,\t]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +knetbsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='GNU ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +nto-qnx*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[[89]] | openbsd2.[[89]].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +sco3.2v5*) + version_type=osf + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + export_dynamic_flag_spec='${wl}-Blargedynsym' + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test "$dynamic_linker" = no && can_build_shared=no +])# AC_LIBTOOL_SYS_DYNAMIC_LINKER + + +# _LT_AC_TAGCONFIG +# ---------------- +AC_DEFUN([_LT_AC_TAGCONFIG], +[AC_ARG_WITH([tags], + [AC_HELP_STRING([--with-tags@<:@=TAGS@:>@], + [include additional configurations @<:@automatic@:>@])], + [tagnames="$withval"]) + +if test -f "$ltmain" && test -n "$tagnames"; then + if test ! -f "${ofile}"; then + AC_MSG_WARN([output file `$ofile' does not exist]) + fi + + if test -z "$LTCC"; then + eval "`$SHELL ${ofile} --config | grep '^LTCC='`" + if test -z "$LTCC"; then + AC_MSG_WARN([output file `$ofile' does not look like a libtool script]) + else + AC_MSG_WARN([using `LTCC=$LTCC', extracted from `$ofile']) + fi + fi + + # Extract list of available tagged configurations in $ofile. + # Note that this assumes the entire list is on one line. + available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'` + + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for tagname in $tagnames; do + IFS="$lt_save_ifs" + # Check whether tagname contains only valid characters + case `$echo "X$tagname" | $Xsed -e 's:[[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]]::g'` in + "") ;; + *) AC_MSG_ERROR([invalid tag name: $tagname]) + ;; + esac + + if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null + then + AC_MSG_ERROR([tag name \"$tagname\" already exists]) + fi + + # Update the list of available tags. + if test -n "$tagname"; then + echo appending configuration tag \"$tagname\" to $ofile + + case $tagname in + CXX) + if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + AC_LIBTOOL_LANG_CXX_CONFIG + else + tagname="" + fi + ;; + + F77) + if test -n "$F77" && test "X$F77" != "Xno"; then + AC_LIBTOOL_LANG_F77_CONFIG + else + tagname="" + fi + ;; + + GCJ) + if test -n "$GCJ" && test "X$GCJ" != "Xno"; then + AC_LIBTOOL_LANG_GCJ_CONFIG + else + tagname="" + fi + ;; + + RC) + AC_LIBTOOL_LANG_RC_CONFIG + ;; + + *) + AC_MSG_ERROR([Unsupported tag name: $tagname]) + ;; + esac + + # Append the new tag name to the list of available tags. + if test -n "$tagname" ; then + available_tags="$available_tags $tagname" + fi + fi + done + IFS="$lt_save_ifs" + + # Now substitute the updated list of available tags. + if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then + mv "${ofile}T" "$ofile" + chmod +x "$ofile" + else + rm -f "${ofile}T" + AC_MSG_ERROR([unable to update list of available tagged configurations.]) + fi +fi +])# _LT_AC_TAGCONFIG + + +# AC_LIBTOOL_DLOPEN +# ----------------- +# enable checks for dlopen support +AC_DEFUN([AC_LIBTOOL_DLOPEN], + [AC_BEFORE([$0],[AC_LIBTOOL_SETUP]) +])# AC_LIBTOOL_DLOPEN + + +# AC_LIBTOOL_WIN32_DLL +# -------------------- +# declare package support for building win32 dll's +AC_DEFUN([AC_LIBTOOL_WIN32_DLL], +[AC_BEFORE([$0], [AC_LIBTOOL_SETUP]) +])# AC_LIBTOOL_WIN32_DLL + + +# AC_ENABLE_SHARED([DEFAULT]) +# --------------------------- +# implement the --enable-shared flag +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +AC_DEFUN([AC_ENABLE_SHARED], +[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE([shared], + [AC_HELP_STRING([--enable-shared@<:@=PKGS@:>@], + [build shared libraries @<:@default=]AC_ENABLE_SHARED_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_shared=]AC_ENABLE_SHARED_DEFAULT) +])# AC_ENABLE_SHARED + + +# AC_DISABLE_SHARED +# ----------------- +#- set the default shared flag to --disable-shared +AC_DEFUN([AC_DISABLE_SHARED], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_SHARED(no) +])# AC_DISABLE_SHARED + + +# AC_ENABLE_STATIC([DEFAULT]) +# --------------------------- +# implement the --enable-static flag +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +AC_DEFUN([AC_ENABLE_STATIC], +[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE([static], + [AC_HELP_STRING([--enable-static@<:@=PKGS@:>@], + [build static libraries @<:@default=]AC_ENABLE_STATIC_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_static=]AC_ENABLE_STATIC_DEFAULT) +])# AC_ENABLE_STATIC + + +# AC_DISABLE_STATIC +# ----------------- +# set the default static flag to --disable-static +AC_DEFUN([AC_DISABLE_STATIC], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_STATIC(no) +])# AC_DISABLE_STATIC + + +# AC_ENABLE_FAST_INSTALL([DEFAULT]) +# --------------------------------- +# implement the --enable-fast-install flag +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +AC_DEFUN([AC_ENABLE_FAST_INSTALL], +[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE([fast-install], + [AC_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], + [optimize for fast installation @<:@default=]AC_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_fast_install=]AC_ENABLE_FAST_INSTALL_DEFAULT) +])# AC_ENABLE_FAST_INSTALL + + +# AC_DISABLE_FAST_INSTALL +# ----------------------- +# set the default to --disable-fast-install +AC_DEFUN([AC_DISABLE_FAST_INSTALL], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_FAST_INSTALL(no) +])# AC_DISABLE_FAST_INSTALL + + +# AC_LIBTOOL_PICMODE([MODE]) +# -------------------------- +# implement the --with-pic flag +# MODE is either `yes' or `no'. If omitted, it defaults to `both'. +AC_DEFUN([AC_LIBTOOL_PICMODE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +pic_mode=ifelse($#,1,$1,default) +])# AC_LIBTOOL_PICMODE + + +# AC_PROG_EGREP +# ------------- +# This is predefined starting with Autoconf 2.54, so this conditional +# definition can be removed once we require Autoconf 2.54 or later. +m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP], +[AC_CACHE_CHECK([for egrep], [ac_cv_prog_egrep], + [if echo a | (grep -E '(a|b)') >/dev/null 2>&1 + then ac_cv_prog_egrep='grep -E' + else ac_cv_prog_egrep='egrep' + fi]) + EGREP=$ac_cv_prog_egrep + AC_SUBST([EGREP]) +])]) + + +# AC_PATH_TOOL_PREFIX +# ------------------- +# find a file program which can recognise shared library +AC_DEFUN([AC_PATH_TOOL_PREFIX], +[AC_REQUIRE([AC_PROG_EGREP])dnl +AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in +[[\\/*] | ?:[\\/]*]) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="ifelse([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$1; then + lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac]) +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +])# AC_PATH_TOOL_PREFIX + + +# AC_PATH_MAGIC +# ------------- +# find a file program which can recognise a shared library +AC_DEFUN([AC_PATH_MAGIC], +[AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + AC_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) + else + MAGIC_CMD=: + fi +fi +])# AC_PATH_MAGIC + + +# AC_PROG_LD +# ---------- +# find the pathname to the GNU or non-GNU linker +AC_DEFUN([AC_PROG_LD], +[AC_ARG_WITH([gnu-ld], + [AC_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld @<:@default=no@:>@])], + [test "$withval" = no || with_gnu_ld=yes], + [with_gnu_ld=no]) +AC_REQUIRE([LT_AC_PROG_SED])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by $CC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case "$host_cpu" in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'] + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux*) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +nto-qnx*) + lt_cv_deplibs_check_method=unknown + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +sco3.2v5*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; +esac +]) +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown +])# AC_DEPLIBS_CHECK_METHOD + + +# AC_PROG_NM +# ---------- +# find the pathname to a BSD-compatible name lister +AC_DEFUN([AC_PROG_NM], +[AC_CACHE_CHECK([for BSD-compatible nm], lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/${ac_tool_prefix}nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + esac + fi + done + IFS="$lt_save_ifs" + test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm +fi]) +NM="$lt_cv_path_NM" +])# AC_PROG_NM + + +# AC_CHECK_LIBM +# ------------- +# check for math library +AC_DEFUN([AC_CHECK_LIBM], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, cos, LIBM="-lm") + ;; +esac +])# AC_CHECK_LIBM + + +# AC_LIBLTDL_CONVENIENCE([DIRECTORY]) +# ----------------------------------- +# sets LIBLTDL to the link flags for the libltdl convenience library and +# LTDLINCL to the include flags for the libltdl header and adds +# --enable-ltdl-convenience to the configure arguments. Note that LIBLTDL +# and LTDLINCL are not AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If +# DIRECTORY is not provided, it is assumed to be `libltdl'. LIBLTDL will +# be prefixed with '${top_builddir}/' and LTDLINCL will be prefixed with +# '${top_srcdir}/' (note the single quotes!). If your package is not +# flat and you're not using automake, define top_builddir and +# top_srcdir appropriately in the Makefiles. +AC_DEFUN([AC_LIBLTDL_CONVENIENCE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + case $enable_ltdl_convenience in + no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;; + "") enable_ltdl_convenience=yes + ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; + esac + LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la + LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) + # For backwards non-gettext consistent compatibility... + INCLTDL="$LTDLINCL" +])# AC_LIBLTDL_CONVENIENCE + + +# AC_LIBLTDL_INSTALLABLE([DIRECTORY]) +# ----------------------------------- +# sets LIBLTDL to the link flags for the libltdl installable library and +# LTDLINCL to the include flags for the libltdl header and adds +# --enable-ltdl-install to the configure arguments. Note that LIBLTDL +# and LTDLINCL are not AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If +# DIRECTORY is not provided and an installed libltdl is not found, it is +# assumed to be `libltdl'. LIBLTDL will be prefixed with '${top_builddir}/' +# and LTDLINCL will be prefixed with '${top_srcdir}/' (note the single +# quotes!). If your package is not flat and you're not using automake, +# define top_builddir and top_srcdir appropriately in the Makefiles. +# In the future, this macro may have to be called after AC_PROG_LIBTOOL. +AC_DEFUN([AC_LIBLTDL_INSTALLABLE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + AC_CHECK_LIB(ltdl, lt_dlinit, + [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no], + [if test x"$enable_ltdl_install" = xno; then + AC_MSG_WARN([libltdl not installed, but installation disabled]) + else + enable_ltdl_install=yes + fi + ]) + if test x"$enable_ltdl_install" = x"yes"; then + ac_configure_args="$ac_configure_args --enable-ltdl-install" + LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la + LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) + else + ac_configure_args="$ac_configure_args --enable-ltdl-install=no" + LIBLTDL="-lltdl" + LTDLINCL= + fi + # For backwards non-gettext consistent compatibility... + INCLTDL="$LTDLINCL" +])# AC_LIBLTDL_INSTALLABLE + + +# AC_LIBTOOL_CXX +# -------------- +# enable support for C++ libraries +AC_DEFUN([AC_LIBTOOL_CXX], +[AC_REQUIRE([_LT_AC_LANG_CXX]) +])# AC_LIBTOOL_CXX + + +# _LT_AC_LANG_CXX +# --------------- +AC_DEFUN([_LT_AC_LANG_CXX], +[AC_REQUIRE([AC_PROG_CXX]) +AC_REQUIRE([_LT_AC_PROG_CXXCPP]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}CXX]) +])# _LT_AC_LANG_CXX + +# _LT_AC_PROG_CXXCPP +# --------------- +AC_DEFUN([_LT_AC_PROG_CXXCPP], +[ +AC_REQUIRE([AC_PROG_CXX]) +if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + AC_PROG_CXXCPP +fi +])# _LT_AC_PROG_CXXCPP + +# AC_LIBTOOL_F77 +# -------------- +# enable support for Fortran 77 libraries +AC_DEFUN([AC_LIBTOOL_F77], +[AC_REQUIRE([_LT_AC_LANG_F77]) +])# AC_LIBTOOL_F77 + + +# _LT_AC_LANG_F77 +# --------------- +AC_DEFUN([_LT_AC_LANG_F77], +[AC_REQUIRE([AC_PROG_F77]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}F77]) +])# _LT_AC_LANG_F77 + + +# AC_LIBTOOL_GCJ +# -------------- +# enable support for GCJ libraries +AC_DEFUN([AC_LIBTOOL_GCJ], +[AC_REQUIRE([_LT_AC_LANG_GCJ]) +])# AC_LIBTOOL_GCJ + + +# _LT_AC_LANG_GCJ +# --------------- +AC_DEFUN([_LT_AC_LANG_GCJ], +[AC_PROVIDE_IFELSE([AC_PROG_GCJ],[], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],[], + [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ],[], + [ifdef([AC_PROG_GCJ],[AC_REQUIRE([AC_PROG_GCJ])], + [ifdef([A][M_PROG_GCJ],[AC_REQUIRE([A][M_PROG_GCJ])], + [AC_REQUIRE([A][C_PROG_GCJ_OR_A][M_PROG_GCJ])])])])])]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}GCJ]) +])# _LT_AC_LANG_GCJ + + +# AC_LIBTOOL_RC +# -------------- +# enable support for Windows resource files +AC_DEFUN([AC_LIBTOOL_RC], +[AC_REQUIRE([LT_AC_PROG_RC]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}RC]) +])# AC_LIBTOOL_RC + + +# AC_LIBTOOL_LANG_C_CONFIG +# ------------------------ +# Ensure that the configuration vars for the C compiler are +# suitably defined. Those variables are subsequently used by +# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. +AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG], [_LT_AC_LANG_C_CONFIG]) +AC_DEFUN([_LT_AC_LANG_C_CONFIG], +[lt_save_CC="$CC" +AC_LANG_PUSH(C) + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +_LT_AC_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;\n" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}\n' + +_LT_AC_SYS_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# +# Check for any special shared library compilation flags. +# +_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)= +if test "$GCC" = no; then + case $host_os in + sco3.2v5*) + _LT_AC_TAGVAR(lt_prog_cc_shlib, $1)='-belf' + ;; + esac +fi +if test -n "$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)"; then + AC_MSG_WARN([`$CC' requires `$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)' to build shared libraries]) + if echo "$old_CC $old_CFLAGS " | grep "[[ ]]$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)[[ ]]" >/dev/null; then : + else + AC_MSG_WARN([add `$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)' to the CC or CFLAGS env variable and reconfigure]) + _LT_AC_TAGVAR(lt_cv_prog_cc_can_build_shared, $1)=no + fi +fi + + +# +# Check to make sure the static flag actually works. +# +AC_LIBTOOL_LINKER_OPTION([if $compiler static flag $_LT_AC_TAGVAR(lt_prog_compiler_static, $1) works], + _LT_AC_TAGVAR(lt_prog_compiler_static_works, $1), + $_LT_AC_TAGVAR(lt_prog_compiler_static, $1), + [], + [_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=]) + + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1) +AC_LIBTOOL_PROG_COMPILER_PIC($1) +AC_LIBTOOL_PROG_CC_C_O($1) +AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) +AC_LIBTOOL_PROG_LD_SHLIBS($1) +AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) +AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) +AC_LIBTOOL_SYS_LIB_STRIP +AC_LIBTOOL_DLOPEN_SELF($1) + +# Report which librarie types wil actually be built +AC_MSG_CHECKING([if libtool supports shared libraries]) +AC_MSG_RESULT([$can_build_shared]) + +AC_MSG_CHECKING([whether to build shared libraries]) +test "$can_build_shared" = "no" && enable_shared=no + +# On AIX, shared libraries and static libraries use the same namespace, and +# are all built from PIC. +case "$host_os" in +aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + +aix4* | aix5*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; +esac +AC_MSG_RESULT([$enable_shared]) + +AC_MSG_CHECKING([whether to build static libraries]) +# Make sure either enable_shared or enable_static is yes. +test "$enable_shared" = yes || enable_static=yes +AC_MSG_RESULT([$enable_static]) + +AC_LIBTOOL_CONFIG($1) + +AC_LANG_POP +CC="$lt_save_CC" +])# AC_LIBTOOL_LANG_C_CONFIG + + +# AC_LIBTOOL_LANG_CXX_CONFIG +# -------------------------- +# Ensure that the configuration vars for the C compiler are +# suitably defined. Those variables are subsequently used by +# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. +AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG], [_LT_AC_LANG_CXX_CONFIG(CXX)]) +AC_DEFUN([_LT_AC_LANG_CXX_CONFIG], +[AC_LANG_PUSH(C++) +AC_REQUIRE([AC_PROG_CXX]) +AC_REQUIRE([_LT_AC_PROG_CXXCPP]) + +_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_AC_TAGVAR(allow_undefined_flag, $1)= +_LT_AC_TAGVAR(always_export_symbols, $1)=no +_LT_AC_TAGVAR(archive_expsym_cmds, $1)= +_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_AC_TAGVAR(hardcode_direct, $1)=no +_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= +_LT_AC_TAGVAR(hardcode_libdir_separator, $1)= +_LT_AC_TAGVAR(hardcode_minus_L, $1)=no +_LT_AC_TAGVAR(hardcode_automatic, $1)=no +_LT_AC_TAGVAR(module_cmds, $1)= +_LT_AC_TAGVAR(module_expsym_cmds, $1)= +_LT_AC_TAGVAR(link_all_deplibs, $1)=unknown +_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_AC_TAGVAR(no_undefined_flag, $1)= +_LT_AC_TAGVAR(whole_archive_flag_spec, $1)= +_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Dependencies to place before and after the object being linked: +_LT_AC_TAGVAR(predep_objects, $1)= +_LT_AC_TAGVAR(postdep_objects, $1)= +_LT_AC_TAGVAR(predeps, $1)= +_LT_AC_TAGVAR(postdeps, $1)= +_LT_AC_TAGVAR(compiler_lib_search_path, $1)= + +# Source file extension for C++ test sources. +ac_ext=cc + +# Object file extension for compiled C++ test sources. +objext=o +_LT_AC_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;\n" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(int, char *[]) { return(0); }\n' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_AC_SYS_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_LD=$LD +lt_save_GCC=$GCC +GCC=$GXX +lt_save_with_gnu_ld=$with_gnu_ld +lt_save_path_LD=$lt_cv_path_LD +if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx +else + unset lt_cv_prog_gnu_ld +fi +if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX +else + unset lt_cv_path_LD +fi +test -z "${LDCXX+set}" || LD=$LDCXX +CC=${CXX-"c++"} +compiler=$CC +_LT_AC_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) + +# We don't want -fno-exception wen compiling C++ code, so set the +# no_builtin_flag separately +if test "$GXX" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' +else + _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= +fi + +if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + AC_PROG_LD + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | \ + grep 'no-whole-archive' > /dev/null; then + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + +else + GXX=no + with_gnu_ld=no + wlarc= +fi + +# PORTME: fill in a description of your system's C++ link characteristics +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +_LT_AC_TAGVAR(ld_shlibs, $1)=yes +case $host_os in + aix3*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_AC_TAGVAR(archive_cmds, $1)='' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + if test "$GXX" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + else + # We have old collect2 + _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= + fi + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_AC_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + # -bexpall does not export symbols beginning with underscore (_) + _LT_AC_TAGVAR(always_export_symbols, $1)=yes + # Exported symbols can be pulled into shared objects from archives + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=' ' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds it's shared libraries. + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(always_export_symbols, $1)=no + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + darwin* | rhapsody*) + case "$host_os" in + rhapsody* | darwin1.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; + esac + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_automatic, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + if test "$GXX" = yes ; then + lt_int_apple_cc_single_mod=no + output_verbose_link_cmd='echo' + if $CC -dumpspecs 2>&1 | $EGREP 'single_module' >/dev/null ; then + lt_int_apple_cc_single_mod=yes + fi + if test "X$lt_int_apple_cc_single_mod" = Xyes ; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + fi + _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's + if test "X$lt_int_apple_cc_single_mod" = Xyes ; then + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + case $cc_basename in + xlc*) + output_verbose_link_cmd='echo' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + fi + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + freebsd[[12]]*) + # C++ shared libraries reported to be fairly broken before switch to ELF + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + freebsd-elf*) + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + freebsd* | kfreebsd*-gnu | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + _LT_AC_TAGVAR(ld_shlibs, $1)=yes + ;; + gnu*) + ;; + hpux9*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "[[-]]L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + case "$host_cpu" in + hppa*64*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + ia64*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + ;; + *) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + esac + fi + case "$host_cpu" in + hppa*64*) + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + ia64*) + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + *) + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + case "$host_cpu" in + hppa*64*|ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case "$host_cpu" in + ia64*|hppa*64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib' + fi + fi + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + ;; + esac + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + linux*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc*) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC*) + # Portland Group C++ compiler + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='' + ;; + cxx*) + # Compaq C++ + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + esac + ;; + lynxos*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + m88k*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + openbsd2*) + # C++ shared libraries are fairly broken + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + openbsd*) + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd='echo' + ;; + osf3*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~ + $rm $lib.exp' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + psos*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + sco*) + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + solaris*) + case $cc_basename in + CC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_AC_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -nolib -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -nolib ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The C++ compiler is used as linker so we must use $wl + # flag to pass the commands to the underlying system + # linker. We must also pass each convience library through + # to the system linker between allextract/defaultextract. + # The C++ compiler will combine linker options so we + # cannot just pass the convience library names through + # without $wl. + # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' + ;; + esac + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep "\-[[LR]]"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' + if $CC --version | grep -v '^2\.7' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" + fi + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' + fi + ;; + esac + ;; + sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7*) + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + vxworks*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; +esac +AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)]) +test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + +_LT_AC_TAGVAR(GCC, $1)="$GXX" +_LT_AC_TAGVAR(LD, $1)="$LD" + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +AC_LIBTOOL_POSTDEP_PREDEP($1) +AC_LIBTOOL_PROG_COMPILER_PIC($1) +AC_LIBTOOL_PROG_CC_C_O($1) +AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) +AC_LIBTOOL_PROG_LD_SHLIBS($1) +AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) +AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) +AC_LIBTOOL_SYS_LIB_STRIP +AC_LIBTOOL_DLOPEN_SELF($1) + +AC_LIBTOOL_CONFIG($1) + +AC_LANG_POP +CC=$lt_save_CC +LDCXX=$LD +LD=$lt_save_LD +GCC=$lt_save_GCC +with_gnu_ldcxx=$with_gnu_ld +with_gnu_ld=$lt_save_with_gnu_ld +lt_cv_path_LDCXX=$lt_cv_path_LD +lt_cv_path_LD=$lt_save_path_LD +lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld +lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +])# AC_LIBTOOL_LANG_CXX_CONFIG + +# AC_LIBTOOL_POSTDEP_PREDEP([TAGNAME]) +# ------------------------ +# Figure out "hidden" library dependencies from verbose +# compiler output when linking a shared library. +# Parse the compiler output and extract the necessary +# objects, libraries and library flags. +AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP],[ +dnl we can't use the lt_simple_compile_test_code here, +dnl because it contains code intended for an executable, +dnl not a library. It's possible we should let each +dnl tag define a new lt_????_link_test_code variable, +dnl but it's only used here... +ifelse([$1],[],[cat > conftest.$ac_ext < conftest.$ac_ext < conftest.$ac_ext < conftest.$ac_ext <> "$cfgfile" +ifelse([$1], [], +[#! $SHELL + +# `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. +# +# This file is part of GNU Libtool: +# Originally by Gordon Matzigkeit , 1996 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="$SED -e 1s/^X//" + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# The names of the tagged configurations supported by this script. +available_tags= + +# ### BEGIN LIBTOOL CONFIG], +[# ### BEGIN LIBTOOL TAG CONFIG: $tagname]) + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$_LT_AC_TAGVAR(archive_cmds_need_lc, $1) + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=$_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1) + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A C compiler. +LTCC=$lt_LTCC + +# A language-specific compiler. +CC=$lt_[]_LT_AC_TAGVAR(compiler, $1) + +# Is the compiler the GNU C compiler? +with_gcc=$_LT_AC_TAGVAR(GCC, $1) + +# An ERE matcher. +EGREP=$lt_EGREP + +# The linker used to build libraries. +LD=$lt_[]_LT_AC_TAGVAR(LD, $1) + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$lt_STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Shared library suffix (normally ".so"). +shrext_cmds='$shrext_cmds' + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) +pic_mode=$pic_mode + +# What is the maximum length of a command? +max_cmd_len=$lt_cv_sys_max_cmd_len + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_[]_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1) + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_static, $1) + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_[]_LT_AC_TAGVAR(export_dynamic_flag_spec, $1) + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_[]_LT_AC_TAGVAR(whole_archive_flag_spec, $1) + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_[]_LT_AC_TAGVAR(thread_safe_flag_spec, $1) + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_cmds, $1) +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_new_cmds, $1) + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) + +# Commands used to build and install a shared archive. +archive_cmds=$lt_[]_LT_AC_TAGVAR(archive_cmds, $1) +archive_expsym_cmds=$lt_[]_LT_AC_TAGVAR(archive_expsym_cmds, $1) +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds=$lt_[]_LT_AC_TAGVAR(module_cmds, $1) +module_expsym_cmds=$lt_[]_LT_AC_TAGVAR(module_expsym_cmds, $1) + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=$lt_[]_LT_AC_TAGVAR(predep_objects, $1) + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=$lt_[]_LT_AC_TAGVAR(postdep_objects, $1) + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps=$lt_[]_LT_AC_TAGVAR(predeps, $1) + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps=$lt_[]_LT_AC_TAGVAR(postdeps, $1) + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_[]_LT_AC_TAGVAR(compiler_lib_search_path, $1) + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_[]_LT_AC_TAGVAR(allow_undefined_flag, $1) + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_[]_LT_AC_TAGVAR(no_undefined_flag, $1) + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$_LT_AC_TAGVAR(hardcode_action, $1) + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) + +# If ld is used when linking, flag to hardcode \$libdir into +# a binary during linking. This must work even if \$libdir does +# not exist. +hardcode_libdir_flag_spec_ld=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1) + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_separator, $1) + +# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$_LT_AC_TAGVAR(hardcode_direct, $1) + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$_LT_AC_TAGVAR(hardcode_minus_L, $1) + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1) + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=$_LT_AC_TAGVAR(hardcode_automatic, $1) + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$_LT_AC_TAGVAR(link_all_deplibs, $1) + +# Compile-time system search path for libraries +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path="$_LT_AC_TAGVAR(fix_srcfile_path, $1)" + +# Set to yes if exported symbols are required. +always_export_symbols=$_LT_AC_TAGVAR(always_export_symbols, $1) + +# The commands to list exported symbols. +export_symbols_cmds=$lt_[]_LT_AC_TAGVAR(export_symbols_cmds, $1) + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_[]_LT_AC_TAGVAR(exclude_expsyms, $1) + +# Symbols that must always be exported. +include_expsyms=$lt_[]_LT_AC_TAGVAR(include_expsyms, $1) + +ifelse([$1],[], +[# ### END LIBTOOL CONFIG], +[# ### END LIBTOOL TAG CONFIG: $tagname]) + +__EOF__ + +ifelse([$1],[], [ + case $host_os in + aix3*) + cat <<\EOF >> "$cfgfile" + +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +EOF + ;; + esac + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || \ + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +]) +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` + if test -f "$ltmain_in"; then + test -f Makefile && make "$ltmain" + fi +fi +])# AC_LIBTOOL_CONFIG + + +# AC_LIBTOOL_PROG_COMPILER_NO_RTTI([TAGNAME]) +# ------------------------------------------- +AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], +[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl + +_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + +if test "$GCC" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + + AC_LIBTOOL_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], + lt_cv_prog_compiler_rtti_exceptions, + [-fno-rtti -fno-exceptions], [], + [_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) +fi +])# AC_LIBTOOL_PROG_COMPILER_NO_RTTI + + +# AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE +# --------------------------------- +AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], +[AC_REQUIRE([AC_CANONICAL_HOST]) +AC_REQUIRE([AC_PROG_NM]) +AC_REQUIRE([AC_OBJEXT]) +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output from $compiler object]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], +[ +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Transform an extracted symbol line into a proper C declaration +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) # Its linker distinguishes data from code symbols + if test "$host_cpu" = ia64; then + symcode='[[ABCDEGRST]]' + fi + lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + ;; +linux*) + if test "$host_cpu" = ia64; then + symcode='[[ABCDGIRSTW]]' + lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + fi + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris* | sysv5*) + symcode='[[BDRT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[[ABCDGIRSTW]]' ;; +esac + +# Try without a prefix undercore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext < $nlist) && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if grep ' nm_test_var$' "$nlist" >/dev/null; then + if grep ' nm_test_func$' "$nlist" >/dev/null; then + cat < conftest.$ac_ext +#ifdef __cplusplus +extern "C" { +#endif + +EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext' + + cat <> conftest.$ac_ext +#if defined (__STDC__) && __STDC__ +# define lt_ptr_t void * +#else +# define lt_ptr_t char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr_t address; +} +lt_preloaded_symbols[[]] = +{ +EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext + cat <<\EOF >> conftest.$ac_ext + {0, (lt_ptr_t) 0} +}; + +#ifdef __cplusplus +} +#endif +EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_save_LIBS="$LIBS" + lt_save_CFLAGS="$CFLAGS" + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS="$lt_save_LIBS" + CFLAGS="$lt_save_CFLAGS" + else + echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.$ac_ext >&5 + fi + rm -f conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi +]) # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE + + +# AC_LIBTOOL_PROG_COMPILER_PIC([TAGNAME]) +# --------------------------------------- +AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC], +[_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)= +_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= +_LT_AC_TAGVAR(lt_prog_compiler_static, $1)= + +AC_MSG_CHECKING([for $compiler option to produce PIC]) + ifelse([$1],[CXX],[ + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | os2* | pw32*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + sysv4*MP*) + if test -d /usr/nec; then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case "$host_cpu" in + hppa*64*|ia64*) + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + case $host_os in + aix4* | aix5*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case $cc_basename in + xlc*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-qnocommon' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + esac + ;; + dgux*) + case $cc_basename in + ec++*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | kfreebsd*-gnu | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive" + if test "$host_cpu" != ia64; then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + fi + ;; + aCC*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive" + case "$host_cpu" in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux*) + case $cc_basename in + KCC*) + # KAI C++ Compiler + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + icpc* | ecpc*) + # Intel C++ + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgCC*) + # Portland Group C++ compiler. + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd*) + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + cxx*) + # Digital/Compaq C++ + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + sco*) + case $cc_basename in + CC*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + *) + ;; + esac + ;; + solaris*) + case $cc_basename in + CC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + lcc*) + # Lucid + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + *) + ;; + esac + ;; + unixware*) + ;; + vxworks*) + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +], +[ + if test "$GCC" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + + beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + enable_shared=no + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case "$host_cpu" in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case $cc_basename in + xlc*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-qnocommon' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + esac + ;; + + mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case "$host_cpu" in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC (with -KPIC) is the default. + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + newsos6) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + linux*) + case $cc_basename in + icc* | ecc*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgcc* | pgf77* | pgf90*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + ccc*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All Alpha code is PIC. + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + esac + ;; + + osf3* | osf4* | osf5*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All OSF/1 code is PIC. + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + sco3.2v5*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kpic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-dn' + ;; + + solaris*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + case $cc_basename in + f77* | f90* | f95*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; + *) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; + esac + ;; + + sunos4*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + unicos*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + + uts4*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *) + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +]) +AC_MSG_RESULT([$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)]) + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)"; then + AC_LIBTOOL_COMPILER_OPTION([if $compiler PIC flag $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) works], + _LT_AC_TAGVAR(lt_prog_compiler_pic_works, $1), + [$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])], [], + [case $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) in + "" | " "*) ;; + *) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)" ;; + esac], + [_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) +fi +case "$host_os" in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])" + ;; +esac +]) + + +# AC_LIBTOOL_PROG_LD_SHLIBS([TAGNAME]) +# ------------------------------------ +# See if the linker supports building shared libraries. +AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS], +[AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +ifelse([$1],[CXX],[ + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + case $host_os in + aix4* | aix5*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + else + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + _LT_AC_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" + ;; + cygwin* | mingw*) + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]] /s/.* \([[^ ]]*\)/\1 DATA/;/^.* __nm__/s/^.* __nm__\([[^ ]]*\) [[^ ]]*/\1 DATA/;/^I /d;/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols' + ;; + *) + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac +],[ + runpath_var= + _LT_AC_TAGVAR(allow_undefined_flag, $1)= + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no + _LT_AC_TAGVAR(archive_cmds, $1)= + _LT_AC_TAGVAR(archive_expsym_cmds, $1)= + _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)= + _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1)= + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + _LT_AC_TAGVAR(thread_safe_flag_spec, $1)= + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_minus_L, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_AC_TAGVAR(link_all_deplibs, $1)=unknown + _LT_AC_TAGVAR(hardcode_automatic, $1)=no + _LT_AC_TAGVAR(module_cmds, $1)= + _LT_AC_TAGVAR(module_expsym_cmds, $1)= + _LT_AC_TAGVAR(always_export_symbols, $1)=no + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + _LT_AC_TAGVAR(include_expsyms, $1)= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + _LT_AC_TAGVAR(exclude_expsyms, $1)="_GLOBAL_OFFSET_TABLE_" + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + extract_expsyms_cmds= + # Just being paranoid about ensuring that cc_basename is set. + _LT_CC_BASENAME([$compiler]) + case $host_os in + cygwin* | mingw* | pw32*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + _LT_AC_TAGVAR(ld_shlibs, $1)=yes + if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + fi + supports_anon_versioning=no + case `$LD -v 2>/dev/null` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix3* | aix4* | aix5*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + _LT_AC_TAGVAR(ld_shlibs, $1)=no + cat <&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +EOF + fi + ;; + + amigaos*) + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + + # Samuel A. Falvo II reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we can't use + # them. + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(always_export_symbols, $1)=no + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]] /s/.* \([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols' + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + linux*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + tmp_addflag= + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + ;; + pgf77* | pgf90* ) # Portland Group f77 and f90 compilers + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + tmp_addflag=' -fpic -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + esac + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test $supports_anon_versioning = yes; then + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + $echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris* | sysv5*) + if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then + _LT_AC_TAGVAR(ld_shlibs, $1)=no + cat <&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +EOF + elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + sunos4*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + + if test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no; then + runpath_var= + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(always_export_symbols, $1)=yes + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + if test "$GCC" = yes && test -z "$link_static_flag"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported + fi + ;; + + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + else + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_AC_TAGVAR(archive_cmds, $1)='' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + if test "$GCC" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + else + # We have old collect2 + _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= + fi + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_AC_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + # -bexpall does not export symbols beginning with underscore (_) + _LT_AC_TAGVAR(always_export_symbols, $1)=yes + # Exported symbols can be pulled into shared objects from archives + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=' ' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds it's shared libraries. + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + # see comment about different semantics on the GNU ld section + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + + bsdi[[45]]*) + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic + ;; + + cygwin* | mingw* | pw32*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='true' + # FIXME: Should let the user specify the lib program. + _LT_AC_TAGVAR(old_archive_cmds, $1)='lib /OUT:$oldlib$oldobjs$old_deplibs' + _LT_AC_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`' + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + darwin* | rhapsody*) + case "$host_os" in + rhapsody* | darwin1.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; + esac + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_automatic, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + if test "$GCC" = yes ; then + output_verbose_link_cmd='echo' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + case $cc_basename in + xlc*) + output_verbose_link_cmd='echo' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + fi + ;; + + dgux*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + freebsd1*) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | kfreebsd*-gnu | dragonfly*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + hpux9*) + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + + hpux10* | hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case "$host_cpu" in + hppa*64*|ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case "$host_cpu" in + hppa*64*|ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + ;; + esac + fi + if test "$with_gnu_ld" = no; then + case "$host_cpu" in + hppa*64*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + ia64*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + ;; + *) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + newsos6) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + openbsd*) + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + else + case $host_os in + openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + ;; + esac + fi + ;; + + os2*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(archive_cmds, $1)='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + else + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ + $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' + + # Both c and cxx compiler support -rpath directly + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + fi + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + sco3.2v5*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ;; + + solaris*) + _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text' + if test "$GCC" = yes; then + wlarc='${wl}' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' + else + wlarc='' + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine linker options so we + # cannot just pass the convience library names through + # without $wl, iff we do not link with $LD. + # Luckily, gcc supports the same syntax we need for Sun Studio. + # Supported since Solaris 2.6 (maybe 2.5.1?) + case $wlarc in + '') + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; + *) + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;; + esac ;; + esac + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4) + case $host_vendor in + sni) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' + _LT_AC_TAGVAR(hardcode_direct, $1)=no + ;; + motorola) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4.3*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + _LT_AC_TAGVAR(ld_shlibs, $1)=yes + fi + ;; + + sysv4.2uw2*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + hardcode_runpath_var=yes + runpath_var=LD_RUN_PATH + ;; + + sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7*) + _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z ${wl}text' + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + runpath_var='LD_RUN_PATH' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv5*) + _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text' + # $CC -shared without GNU ld will not create a library from C++ + # object files and a static libstdc++, better avoid it by now + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + ;; + + uts4*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + fi +]) +AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)]) +test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +# +# Do we need to explicitly link libc? +# +case "x$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)" in +x|xyes) + # Assume -lc should be added + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $_LT_AC_TAGVAR(archive_cmds, $1) in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_MSG_CHECKING([whether -lc should be explicitly linked in]) + $rm conftest* + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile) 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$_LT_AC_TAGVAR(allow_undefined_flag, $1) + _LT_AC_TAGVAR(allow_undefined_flag, $1)= + if AC_TRY_EVAL(_LT_AC_TAGVAR(archive_cmds, $1) 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) + then + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + else + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + fi + _LT_AC_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $rm conftest* + AC_MSG_RESULT([$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)]) + ;; + esac + fi + ;; +esac +])# AC_LIBTOOL_PROG_LD_SHLIBS + + +# _LT_AC_FILE_LTDLL_C +# ------------------- +# Be careful that the start marker always follows a newline. +AC_DEFUN([_LT_AC_FILE_LTDLL_C], [ +# /* ltdll.c starts here */ +# #define WIN32_LEAN_AND_MEAN +# #include +# #undef WIN32_LEAN_AND_MEAN +# #include +# +# #ifndef __CYGWIN__ +# # ifdef __CYGWIN32__ +# # define __CYGWIN__ __CYGWIN32__ +# # endif +# #endif +# +# #ifdef __cplusplus +# extern "C" { +# #endif +# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved); +# #ifdef __cplusplus +# } +# #endif +# +# #ifdef __CYGWIN__ +# #include +# DECLARE_CYGWIN_DLL( DllMain ); +# #endif +# HINSTANCE __hDllInstance_base; +# +# BOOL APIENTRY +# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) +# { +# __hDllInstance_base = hInst; +# return TRUE; +# } +# /* ltdll.c ends here */ +])# _LT_AC_FILE_LTDLL_C + + +# _LT_AC_TAGVAR(VARNAME, [TAGNAME]) +# --------------------------------- +AC_DEFUN([_LT_AC_TAGVAR], [ifelse([$2], [], [$1], [$1_$2])]) + + +# old names +AC_DEFUN([AM_PROG_LIBTOOL], [AC_PROG_LIBTOOL]) +AC_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AC_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) +AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) +AC_DEFUN([AM_PROG_LD], [AC_PROG_LD]) +AC_DEFUN([AM_PROG_NM], [AC_PROG_NM]) + +# This is just to silence aclocal about the macro not being used +ifelse([AC_DISABLE_FAST_INSTALL]) + +AC_DEFUN([LT_AC_PROG_GCJ], +[AC_CHECK_TOOL(GCJ, gcj, no) + test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS) +]) + +AC_DEFUN([LT_AC_PROG_RC], +[AC_CHECK_TOOL(RC, windres, no) +]) + +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ +# LT_AC_PROG_SED +# -------------- +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +AC_DEFUN([LT_AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f $lt_ac_sed && continue + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test $lt_ac_count -gt 10 && break + lt_ac_count=`expr $lt_ac_count + 1` + if test $lt_ac_count -gt $lt_ac_max; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done +]) +SED=$lt_cv_path_SED +AC_MSG_RESULT([$SED]) +]) diff --git a/m4/optimizations.m4 b/m4/optimizations.m4 new file mode 100644 index 0000000..69f2505 --- /dev/null +++ b/m4/optimizations.m4 @@ -0,0 +1,113 @@ +AC_DEFUN([SAH_OPTIMIZATIONS],[ +if test x_$sah_opt_only_once = x_ ; then + +sah_opt_only_once=all_done + +AC_ARG_ENABLE([sse3], + AC_HELP_STRING([--enable-sse3], + [Use SSE3 optimizations]) +) + +if test x_$enable_sse3 = x_yes ; then + AC_DEFINE_UNQUOTED([USE_SSE3],[1], + [Define to 1 if you want to use SSE3 optimizations]) +# put compiler specific flags here + if test x_$ac_cv_c_compiler_gnu = x_yes ; then + CFLAGS="-march=prescott -msse3 -mfpmath=sse ${CFLAGS}" + fi +fi + +AC_ARG_ENABLE([sse2], + AC_HELP_STRING([--enable-sse2], + [Use SSE2 optimizations]) +) + +if test x_$enable_sse2 = x_yes ; then + AC_DEFINE_UNQUOTED([USE_SSE2],[1], + [Define to 1 if you want to use SSE2 optimizations]) +# put compiler specific flags here + if test x_$ac_cv_c_compiler_gnu = x_yes ; then + CFLAGS="-msse2 -mfpmath=sse ${CFLAGS}" + if test -z "echo $CFLAGS | grep march=" ; then + CFLAGS="-march=pentium4 ${CFLAGS}" + fi + fi +fi + +AC_ARG_ENABLE([sse], + AC_HELP_STRING([--enable-sse], + [Use SSE optimizations]) +) + +if test x_$enable_sse = x_yes ; then + AC_DEFINE_UNQUOTED([USE_SSE],[1], + [Define to 1 if you want to use SSE optimizations]) +# put compiler specific flags here + if test x_$ac_cv_c_compiler_gnu = x_yes ; then + CFLAGS="-march=pentium3 -msse -mfpmath=sse ${CFLAGS}" + fi +fi + +AC_ARG_ENABLE([mmx], + AC_HELP_STRING([--enable-mmx], + [Use MMX optimizations]) +) + +if test x_$enable_mmx = x_yes ; then + AC_DEFINE_UNQUOTED([USE_MMX],[1], + [Define to 1 if you want to use MMX optimizations]) +# put compiler specific flags here + if test x_$ac_cv_c_compiler_gnu = x_yes ; then + CFLAGS="-march=pentium2 -mmmx -mfpmath=387 ${CFLAGS}" + fi +fi + +AC_ARG_ENABLE([3dnow], + AC_HELP_STRING([--enable-3dnow], + [Use 3dnow optimizations]) +) + + +if test x_$enable_3dnow = x_yes ; then + AC_DEFINE_UNQUOTED([USE_3DNOW],[1], + [Define to 1 if you want to use 3D-Now optimizations]) +# put compiler specific flags here + if test x_$ac_cv_c_compiler_gnu = x_yes ; then + CFLAGS="-march=pentium2 -m3dnow -mfpmath=387 ${CFLAGS}" + fi +fi + +AC_ARG_ENABLE([fast-math], + AC_HELP_STRING([--enable-fast-math], + [Use gcc -ffast-math optimization]) + ) + +if test x_$enable_fast_math = x_yes ; then + AC_DEFINE_UNQUOTED([USE_FAST_MATH],[1], + [Define to 1 if you want to use the gcc -ffast-math optimization]) +# put compiler specific flags here + if test x_$ac_cv_c_compiler_gnu = x_yes ; then + CFLAGS="${CFLAGS} -ffast-math" + fi +fi + +AC_ARG_ENABLE([altivec], + AC_HELP_STRING([--enable-altivec], + [Use altivec optimizations]) + ) + +if test x_$enable_altivec = x_yes ; then + AC_DEFINE_UNQUOTED([USE_ALTIVEC],[1], + [Define to 1 if you want to use ALTIVEC optimizations]) +# put compiler specific flags here + if test x_$ac_cv_c_compiler_gnu = x_yes ; then + SAH_CHECK_CFLAG([-faltivec],[CFLAGS="-faltivec ${CFLAGS}"]) + SAH_CHECK_CFLAG([-maltivec],[CFLAGS="-maltivec ${CFLAGS}"]) + SAH_CHECK_CFLAG([-mtune=G5],[CFLAGS="-mtune=G5 ${CFLAGS}"]) + SAH_CHECK_CFLAG([-mcpu=powerpc],[CFLAGS="-mcpu=powerpc ${CFLAGS}"]) + SAH_CHECK_LDFLAG([-framework Accelerate],[LDFLAGS="${LDFLAGS} -framework Accelerate"]) + fi +fi + +fi +]) diff --git a/m4/sah_asmlib.m4 b/m4/sah_asmlib.m4 new file mode 100644 index 0000000..6cd4358 --- /dev/null +++ b/m4/sah_asmlib.m4 @@ -0,0 +1,62 @@ +AC_DEFUN([SAH_CHECK_ASMLIB],[ + AC_LANG_PUSH([C++]) + AC_MSG_CHECKING([asmlib]) + AC_ARG_ENABLE(asmlib, + AC_HELP_STRING([--disable-asmlib], + [disable use of asmlib for CPU identification (iX86 only)]), + [ + disable_asmlib=yes + enable_asmlib=no + ], + [ + disable_asmlib=no + enable_asmlib=yes + ] + ) + if test -z "`echo $target | grep '[3456]86'`" ; then + disable_asmlib=yes + enable_asmlib=no + fi + ASMLIB_CFLAGS= + ASMLIB_LDFLAGS= + ASMLIB_LIBS= + asmlib_save_CFLAGS="${CFLAGS}" + asmlib_save_CXXFLAGS="${CXXFLAGS}" + asmlib_save_LDFLAGS="${LDFLAGS}" + asmlib_save_LIBS="${LIBS}" + asmlib_dir="${SAH_TOP_DIR}/client/vector/" + asmlib_works=no + if test "${disable_asmlib}" != "yes" ; then + CFLAGS="${CFLAGS} -I${asmlib_dir}" + CXXFLAGS="${CXXFLAGS} -I${asmlib_dir}" + for ASMLIB_LIBS in ${asmlib_dir}/asmlibe.a ${asmlib_dir}/asmlibm.a ${asmlib_dir}/asmlibo.lib + do + LIBS="${ASMLIB_LIBS} ${asmlib_save_LIBS}" + AC_LINK_IFELSE( + [ + AC_LANG_PROGRAM( + [[#include "asmlib.h"]], + [[InstructionSet()]] + ) + ], + [asmlib_works=yes; break] + ) + done + fi + if test "${asmlib_works}" = "yes" ; then + AC_DEFINE_UNQUOTED([USE_ASMLIB],[1], + [Define to 1 to use ASMLIB to determine processor capabilities]) + AC_MSG_RESULT([$ASMLIB_LIBS]) + else + ASMLIB_LIBS= + AC_MSG_RESULT([no]) + fi + CFLAGS="${asmlib_save_CFLAGS}" + CXXFLAGS="${asmlib_save_CXXFLAGS}" + LDFLAGS="${asmlib_save_LDFLAGS}" + LIBS="${asmlib_save_LIBS}" + AC_SUBST([ASMLIB_LDFLAGS]) + AC_SUBST([ASMLIB_CFLAGS]) + AC_SUBST([ASMLIB_LIBS]) + AC_LANG_POP([C++]) +]) diff --git a/m4/sah_avx.m4 b/m4/sah_avx.m4 new file mode 100644 index 0000000..b856743 --- /dev/null +++ b/m4/sah_avx.m4 @@ -0,0 +1,51 @@ +AC_DEFUN([SAH_AVX],[ + AC_LANG_PUSH(C) + AC_MSG_CHECKING([if compiler supports -mavx]) + save_cflags="${CFLAGS}" + CFLAGS="-mavx" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[return 0;])],[ + have_avx=yes + ],[ + have_avx=no + ] + ) + AC_MSG_RESULT($have_avx) + if test "$have_avx" = "yes" ; then + AC_MSG_CHECKING([type of arg 2 of _mm256_maskstore_ps()]) + for type in __m256d __m256i __m256 ; do + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#if defined(HAVE_IMMINTRIN_H) +#include +#elif defined(HAVE_AVXINTRIN_H) +#include +#elif defined(HAVE_X86INTRIN_H) +#include +#elif defined(HAVE_INTRIN_H) +#include +#endif + +float *a1; +$type a2; +__m256 a3; +int foo(void) { + _mm256_maskstore_ps(a1,a2,a3); + return 0; +} +]],[return foo();])], +[ type_found=yes ], +[ type_found=no ]) + if test "${type_found}" = "yes" ; then + break; + fi + done + fi + if test "${type_found}" = "yes" ; then + AC_MSG_RESULT($type) + avx_type=${type} + else + AC_MSG_RESULT(none) + avx_type= + fi + CFLAGS="${save_cflags}" + AC_LANG_POP(C) +]) diff --git a/m4/sah_check_boinc.m4 b/m4/sah_check_boinc.m4 new file mode 100644 index 0000000..3378d7f --- /dev/null +++ b/m4/sah_check_boinc.m4 @@ -0,0 +1,62 @@ +# SETI_BOINC is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2, or (at your option) any later +# version. + +AC_PREREQ([2.54]) + +AC_DEFUN([SAH_CHECK_BOINC],[ + AC_ARG_VAR([BOINCDIR],[boinc directory]) + AC_ARG_VAR([PROJECTDIR],[project config.xml directory]) + if test -z "$HEAD" + then + AC_PATH_PROG(HEAD,head) + fi + if test -z "$FIND" + then + AC_PATH_PROG(FIND,find) + fi + thisdir=`pwd` + AC_MSG_CHECKING([for BOINC]) + boinc_search_path="$BOINCDIR boinc ../boinc $HOME/boinc /usr/local/boinc /usr/local/lib/boinc /opt/misc/boinc /opt/misc/lib/boinc $2" + for boinc_dir in $boinc_search_path + do + if test -d $boinc_dir + then + if test -f $boinc_dir/include/std_fixes.h -o -f $boinc_dir/lib/std_fixes.h + then + cd $boinc_dir + BOINCDIR=`pwd` + cd $thisdir + break + else + if $FIND $boinc_dir -name "std_fixes.h" >& /dev/null + then + BOINCDIR=`$FIND $boinc_dir -name "std_fixes.h" -print | $HEAD -1 | sed 's/\/std_fixes.h//'` + cd $BOINCDIR/.. + BOINCDIR=`pwd` + cd $thisdir + break + fi + fi + fi + done + if test -n "$BOINCDIR" + then + AC_MSG_RESULT($BOINCDIR) + else + no_boinc=yes + AC_MSG_RESULT(not found) + fi + if test -z "$PROJECTDIR" + then + PROJECTDIR=~boincadm/projects/ap + fi + AC_DEFINE_UNQUOTED([PROJECTDIR],["$PROJECTDIR"],[Define as directory containing the project config.xml]) + AC_SUBST([PROJECTDIR]) + AC_SUBST([BOINCDIR]) + BOINC_CFLAGS="-I$BOINCDIR -I$BOINCDIR/api -I$BOINCDIR/lib -I$BOINCDIR/sched -I$BOINCDIR/db" + AC_SUBST([BOINC_CFLAGS]) +]) + + diff --git a/m4/sah_check_healpix.m4 b/m4/sah_check_healpix.m4 new file mode 100644 index 0000000..621432c --- /dev/null +++ b/m4/sah_check_healpix.m4 @@ -0,0 +1,52 @@ +# SETI_BOINC is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2, or (at your option) any later +# version. + +AC_PREREQ([2.54]) + +AC_DEFUN([SAH_CHECK_HEALPIX],[ + AC_ARG_VAR([HEALPIX],[HEALPIX directory]) + if test -z "$HEAD" + then + AC_PATH_PROG(HEAD,head) + fi + if test -z "$FIND" + then + AC_PATH_PROG(FIND,find) + fi + thisdir=`pwd` + AC_MSG_CHECKING([for HEALPIX]) + healpix_search_path=[`echo $HEALPIX [Hh]ealpix* ../[Hh]ealpix* ../lib/[Hh]ealpix* $HOME/lib/[Hh]ealpix* /usr/local/[Hh]ealpix* /usr/local`] + for healpix_dir in $healpix_search_path + do + if test -d $healpix_dir/lib + then + if test -f $healpix_dir/lib/libchealpix.a + then + cd $healpix_dir + HEALPIX=`pwd` + cd $thisdir + break + else + if $FIND $healpix_dir -name "lib/libchealpix.a" 2>/dev/null >/dev/null + then + HEALPIX=`$FIND $healpix_dir -name "lib/libchealpix.a" -print | $HEAD -1 | sed 's/\/lib\/libchealpix.a//'` + cd $HEALPIX + HEALPIX=`pwd` + cd $thisdir + break + fi + fi + fi + done + if test -n "$HEALPIX" + then + AC_MSG_RESULT($HEALPIX) + else + AC_MSG_RESULT(not found) + no_healpix=yes + fi +]) + + diff --git a/m4/sah_check_ipp.m4 b/m4/sah_check_ipp.m4 new file mode 100644 index 0000000..4339487 --- /dev/null +++ b/m4/sah_check_ipp.m4 @@ -0,0 +1,39 @@ +AC_DEFUN([SAH_CHECK_IPP], +[AC_MSG_CHECKING([for Intel Performance Primitives]) +IPP= +found_ipp="no" +AC_ARG_WITH(ipp, + AC_HELP_STRING([--with-ipp@<:@=DIR@:>@], + [Use Intel Performance Primitives (in specified installation directory)]), + [check_ipp_dir="$withval"], + [check_ipp_dir=]) + +SAH_OPTIMIZATIONS + +for dir in $check_ipp_dir $check_ipp_dir/ia32* $check_ipp_dir/ipp*/ia32* /opt/intel/ipp*/ia32* /usr/local/ipp*/ia32* /usr/lib/ipp*/ia32* /usr/ipp*/ia32* /usr/pkg/ipp*/ia32* /usr/local /usr; do + ippdir="$dir" + if test -f "$dir/include/ipp.h"; then + found_ipp="yes"; + IPPDIR="${ippdir}" + CFLAGS="$CFLAGS -I$ippdir/include -I$ippdir/tools/staticlib"; + CXXFLAGS="$CXXFLAGS -I$ippdir/include -I$ippdir/tools/staticlib"; + break; + fi + if test -f "$dir/include/ipp.h"; then + found_ipp="yes"; + IPPDIR="${ippdir}" + CFLAGS="$CFLAGS -I$ippdir/include/"; + CXXFLAGS="$CXXFLAGS -I$ippdir/include/"; + break + fi +done +AC_MSG_RESULT($found_ipp) +if test x_$found_ipp = x_yes ; then + printf "IPP found in $ippdir\n"; + LIBS="$LIBS -lippcore -lippsmerged"; + LDFLAGS="$LDFLAGS -L$ippdir/lib"; + AC_DEFINE_UNQUOTED([USE_IPP],[1], + ["Define to 1 if you want to use the Intel Performance Primitives"]) + AC_SUBST(IPPDIR) +fi +]) diff --git a/m4/sah_check_jpeglib.m4 b/m4/sah_check_jpeglib.m4 new file mode 100644 index 0000000..4e84c4a --- /dev/null +++ b/m4/sah_check_jpeglib.m4 @@ -0,0 +1,24 @@ +AC_DEFUN([SAH_CHECK_JPEGLIB],[ +AC_ARG_WITH([my-libjpeg], + AC_HELP_STRING([--with-my-libjpeg],[use the jpeglib that is distributed with setiatthome]), + [use_my_libjpeg="$withval"]) +if test "x${use_my_libjpeg}" = "xyes" ; then + LIBS="-L`pwd`/jpeglib ${LIBS}" + CFLAGS="${CFLAGS} -I`pwd`/jpeglib" + sah_cv_lib_jpeg_jpeg_start_decompress="`pwd`/jpeglib/libjpeg.a" + sah_cv_lib_jpeg_fopen="`pwd`/jpeglib/libjpeg.a" + sah_cv_static_lib_jpeg_jpeg_start_decompress="$sah_cv_lib_jpeg_jpeg_start_decompress" + sah_cv_static_lib_jpeg_fopen="$sah_cv_lib_jpeg_fopen" + if test -f "${sah_cv_lib_jpeg_fopen}" ; then + /bin/rm -f "${sah_cv_lib_jpeg_fopen}" + fi + echo "int foo() { return 0; }" >foo.c + $CC -c foo.c + $AR cr "${sah_cv_lib_jpeg_fopen}" foo.$OBJEXT + /bin/rm foo.$OBJEXT foo.c + $RANLIB "${sah_cv_lib_jpeg_fopen}" +fi +SAH_CHECK_LIB([jpeg], [jpeg_start_decompress], + AC_DEFINE([HAVE_LIBJPEG],[1],[Define to 1 if you have the jpeg library])) +AM_CONDITIONAL(USE_MY_LIBJPEG, [test "x${use_my_libjpeg}" = "xyes" -o "${sah_cv_lib_jpeg_jpeg_start_decompress}" = "no"]) +]) diff --git a/m4/sah_check_lib.m4 b/m4/sah_check_lib.m4 new file mode 100644 index 0000000..72684da --- /dev/null +++ b/m4/sah_check_lib.m4 @@ -0,0 +1,503 @@ + +AC_DEFUN([SAH_CHECK_LIB],[ + alib="$1" + # check to see if it is in our static list + for slib in ${STATIC_LIB_LIST}; do + lib_is_static="no" + tmp_pattern=`echo s/x${slib}// | sed 's/\*/.*/'` + if test -z "`echo x${alib} | sed ${tmp_pattern}`" + then + SAH_STATIC_LIB_REQUIRED(${alib},[$2],[ + lib_is_static="yes" + sah_lib_last="${sah_static_lib_last}" + $3 + ],[$4],[$5],[$6]) + break; + fi + done + if test "${lib_is_static}" = "no" ; then + SAH_DYNAMIC_LIB_REQUIRED(${alib},[$2],[ + sah_lib_last="${sah_dynamic_lib_last}" + $3 + ],[$4],[$5],[$6]) + fi +]) + + + + +AC_DEFUN([SAH_CHECK_LDFLAG],[ + sv_ldflags="${LDFLAGS}" + AC_MSG_CHECKING(if linker works with $1 flag) + LDFLAGS="${LDFLAGS} $1" + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([[ + #define CONFIG_TEST + int foo() {return 1;} + ]], + [ return foo(); ])], + [ + AC_MSG_RESULT(yes) + $2 + ], + [ + AC_MSG_RESULT(no) + LDFLAGS="${sv_ldflags}" + $3 + ] + ) +]) + +AC_DEFUN([SAH_CHECK_CFLAG],[ + AC_LANG_PUSH(C) + sv_cflags="${CFLAGS}" + AC_MSG_CHECKING(if compiler works with $1 flag) + CFLAGS="${CFLAGS} $1" + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ + #define CONFIG_TEST + int foo() {return 1;} + ]], + [ return foo(); ])], + [ + AC_MSG_RESULT(yes) + $2 + ], + [ + AC_MSG_RESULT(no) + CFLAGS="${sv_ldflags}" + $3 + ] + ) + AC_LANG_POP +]) + +AC_DEFUN([SAH_LINKAGE_FLAGS],[ + AC_ARG_ENABLE(static_client, + AC_HELP_STRING([--disable-static-linkage], + [disable static linking of certain libraries]), + [ + disable_static_linkage=yes + enable_client_release=no + ], + [ + disable_static_linkage=no + enable_client_release=yes + ]) + if test "${disable_static_linkage}" = "yes" + then + ld_static_option="" + ld_dynamic_option="" + LD_EXPORT_DYNAMIC="" + else + if test -z "${ld_static_option}" + then + case $target in + *linux* | *solaris* | *cygwin* ) + AC_MSG_CHECKING([${CC} flags for static linkage ...]) + ld_static_option="-Wl,-Bstatic" + AC_MSG_RESULT($ld_static_option) + AC_MSG_CHECKING([${CC} flags for dynamic linkage ...]) + ld_dynamic_option="-Wl,-Bdynamic" + AC_MSG_RESULT($ld_dynamic_option) + ;; + *darwin* ) + AC_MSG_CHECKING([${CC} flags for static linkage ...]) + ld_static_option="-static" + AC_MSG_RESULT($ld_static_option) + AC_MSG_CHECKING([${CC} flags for dynamic linkage ...]) + ld_dynamic_option="-dynamic" + AC_MSG_RESULT($ld_dynamic_option) + ;; + *) + if test -z "${dummy_ld_variable_gfdsahjf}" + then + dummy_ld_variable_gfdsahjf="been there done that" + AC_MSG_CHECKING([${CC} flags for static linkage ...]) + AC_MSG_RESULT(unknown) + AC_MSG_CHECKING([${CC} flags for dynamic linkage ...]) + AC_MSG_RESULT(unknown) + fi + ;; + esac + AC_MSG_CHECKING([${CC} flags for exporting dynamic symbols from an executable ...]) + LD_EXPORT_DYNAMIC="${export_dynamic_flag_spec}" + if test -z "${LD_EXPORT_DYNAMIC}" ; then + case $target in + *cygwin*) + LD_EXPORT_DYNAMIC="-Wl,--export-all-symbols" + AC_MSG_RESULT(${LD_EXPORT_DYNAMIC}) + ;; + *linux*) + AC_MSG_RESULT(-rdynamic) + LD_EXPORT_DYNAMIC="-rdynamic" + ;; + *) + AC_MSG_RESULT(none required) + LD_EXPORT_DYNAMIC= + ;; + esac + fi + fi + fi + if test -z "${LIBEXT}"; + then + SAH_LIBEXT + fi + if test -z "${DLLEXT}"; + then + SAH_DLLEXT + fi + AC_SUBST(LD_EXPORT_DYNAMIC) +]) + + +# use this function in order to find a library that we require to be static. +# we will check in the following order.... +# 1) files named lib{name}.a +# 2) files named {name}.a +# 3) linking with the static flags "$STATIC_FLAGS -l{name}" +AC_DEFUN([SAH_STATIC_LIB_REQUIRED],[ +SAH_LINKAGE_FLAGS +# upercase the library name for our definition +ac_uc_defn=HAVE_LIB`echo $1 | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` +# Build our cache variable names +STATIC_LIB_LIST="${STATIC_LIB_LIST} $1" +varname=`echo sah_cv_static_lib_$1_$2 | $as_tr_sh` +var2=`echo sah_cv_static_lib_$1_fopen | $as_tr_sh` +if test "$2" != "fopen" ; then + tmp_msg="for $2 in static library $1" +else + tmp_msg="for static library $1" +fi +AC_CACHE_CHECK([$tmp_msg], + [$varname], +[ + tmp_res="no" +# +# check if we want to actually do all this. + if test "${disable_static_linkage}" = "yes" + then + sah_static_checklibs="-l$1" + else + sah_static_checklibs="lib$1.${LIBEXT} $1.${LIBEXT} -l$1" + fi + sah_save_libs="${LIBS}" + for libname in ${sah_static_checklibs} + do + SAH_FIND_STATIC_LIB(${libname}) + if test -n "${tmp_lib_name}" + then + LIBS="${tmp_lib_name} ${sah_save_libs} $5 $6" + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([[ + #define CONFIG_TEST 1 + #ifdef __cplusplus + extern "C" { + #endif + char $2 (); + #ifdef __cplusplus + } + #endif + ]], + [ $2 (); ])], + [ + tmp_res="${tmp_lib_name}" + ] + ) + fi + if test "${tmp_res}" != "no" + then + break + fi + done + LIBS="${sah_save_libs}" + eval ${varname}='"'${tmp_res}'"' + eval ${var2}='"'${tmp_res}'"' + ]) +# +# save the result for use by the caller +sah_static_lib_last="`eval echo '${'$varname'}'`" +# +if test "${sah_static_lib_last}" != "no" +then + tmp_pattern=`echo "${sah_static_lib_last}" | sed 's/-/./'` + if echo ${LIBS} | grep "${tmp_pattern}" > /dev/null + then + echo Already in LIBS, not adding... >&5 + else + LIBS="${sah_static_lib_last} ${LIBS}" + fi + AC_DEFINE_UNQUOTED([$ac_uc_defn], [1], + [Define to 1 if the $1 library has the function $2] + ) + $3 +else + $4 + echo > /dev/null +fi +]) + +# use this function in order to find a library that we require to be dynamic. +# we will check in the following order.... +# 1) linking with the dynamic flags "$DYNAMIC_FLAGS -l{name}" +# 2) linking with no flags "-l{name}" +AC_DEFUN([SAH_DYNAMIC_LIB_REQUIRED],[ +SAH_LINKAGE_FLAGS +# upercase the library name for our definition +ac_uc_defn=HAVE_LIB`echo $1 | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` +# Build our cache variable names +DYNAMIC_LIB_LIST="${DYNAMIC_LIB_LIST} $1" +varname=`echo sah_cv_dynamic_lib_$1_$2 | $as_tr_sh` +var2=`echo sah_cv_dynamic_lib_$1_fopen | $as_tr_sh` +if test "$2" != "fopen" ; then + tmp_msg="for $2 in dynamic library $1" +else + tmp_msg="for dynamic library $1" +fi +AC_CACHE_CHECK([$tmp_msg], + [$varname], +[ + tmp_res="no" +# +# check if we want to actually do all this. + if test "${disable_static_linkage}" = "yes" + then + sah_dynamic_checklibs="-l$1 -l$1.${DLLEXT}" + else + sah_dynamic_checklibs="-l$1" + fi + sah_save_libs="${LIBS}" + for libname in ${sah_dynamic_checklibs} + do + tmp_lib_name="${libname}" + LIBS="${ld_dynamic_option} ${tmp_lib_name} ${sah_save_libs} $5 $6" + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([[ + #define CONFIG_TEST 1 + #ifdef __cplusplus + extern "C" { + #endif + char $2 (); + #ifdef __cplusplus + } + #endif + ]], + [ $2 (); ]) + ], + [ + tmp_res="${ld_dynamic_option} ${tmp_lib_name}" + ]) + if test "${tmp_res}" = "no" + then + tmp_lib_name="${libname}" + LIBS="${tmp_lib_name} ${sah_save_libs}" + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([[ + #define CONFIG_TEST 1 + #ifdef __cplusplus + extern "C" { + #endif + char $2 (); + #ifdef __cplusplus + } + #endif + ]], + [ $2 (); ]) + ], + [ + tmp_res="${tmp_lib_name}" + ]) + fi + done + LIBS="${sah_save_libs}" + eval ${varname}='"'${tmp_res}'"' + eval ${var2}='"'${tmp_res}'"' +]) +# +# save the result for use by the caller +sah_dynamic_lib_last="`eval echo '${'$varname'}'`" +# +if test "${sah_dynamic_lib_last}" != "no" +then + tmp_pattern=`echo "${sah_dynamic_lib_last}" | sed 's/-/./'` + if echo ${LIBS} | grep "${tmp_pattern}" > /dev/null + then + echo Already in LIBS, not adding... >&5 + else + LIBS="${sah_dynamic_lib_last} ${LIBS}" + fi + AC_DEFINE_UNQUOTED([$ac_uc_defn], [1], + [Define to 1 if the $1 library has the function $2] + ) + $3 +else + $4 + echo > /dev/null +fi +]) + +AC_DEFUN([SAH_STATIC_LIB],[ + SAH_STATIC_LIB_REQUIRED([$1],[$2]) + sah_lib_last="${sah_static_lib_last}" + if test "${sah_lib_last}" = "no" ; then + SAH_DYNAMIC_LIB_REQUIRED([$1],[$2]) + sah_lib_last=${sah_dynamic_lib_last} + fi + if test "${sah_lib_last}" != "no" ; then + $3 + echo > /dev/null + else + $4 + echo > /dev/null + fi +]) + +AC_DEFUN([SAH_DYNAMIC_LIB],[ + SAH_DYNAMIC_LIB_REQUIRED([$1],[$2]) + sah_lib_last="${sah_dynamic_lib_last}" + if test "${sah_lib_last}" = "no" ; then + SAH_STATIC_LIB_REQUIRED([$1],[$2]) + sah_lib_last=${sah_static_lib_last} + fi + if test "${sah_lib_last}" != "no" ; then + $3 + echo > /dev/null + else + $4 + echo > /dev/null + fi +]) + +#The SAH_FIND_STATIC_LIB macro searches the LD_LIBRARY_PATH or equivalent +#in order to find a static version of the library being loaded. +AC_DEFUN([SAH_FIND_STATIC_LIB],[ +# libtool sets up the variable shlibpath_var which holds the name of the +# LIB_PATH variable. We also want to strip the sparcv9 and 64s from the +# path, because we'll add them again later +strip_pattern="s/sparcv9//g; s/lib64/lib/g; s/lib\/64/lib/g" +tmp_libpath=`eval echo '${'$shlibpath_var'}' | sed "${strip_pattern}"` + +# in cygwin, the DLLs are in the path, but the static libraries are elsewhere. +# Here's an educated guess. +if test "${shlibpath_var}" = "PATH" +then + tmp_libpath=`echo ${PATH} | sed 's/\/bin/\/lib/g'` + tmp_libpath="${tmp_libpath}:${PATH}" +fi + +gcc_version=`${CC} -v 2>&1 | grep "gcc version" | $AWK '{print $[]3}'` + +for gcc_host in `${CC} -v 2>&1 | grep host` --host=${ac_cv_target} +do + if test -n "`echo x$gcc_host | grep x--host=`" + then + gcc_host="`echo $gcc_host | sed 's/--host=//'`" + break + fi +done + +gcc_specs=`${CC} -v 2>&1 | grep specs | $AWK '{print $[]4}' | sed 's/\/specs//'` + +for dirs in `${CC} -v 2>&1 | grep prefix` --prefix=${gcc_specs} +do + if test -n "`echo x$dirs | grep x--prefix=`" + then + gcc_prefix="`echo $dirs | sed 's/--prefix=//'`" + tmp_libpath="${gcc_specs}:${gcc_prefix}/lib:${gcc_prefix}/lib/gcc-lib/${gcc_host}/${gcc_version}:${tmp_libpath}" + break + fi +done + +gcc_lib_dirs=`${CC} -print-search-dirs 2>&1 | grep libraries: | sed 's/^libraries: =//'` +tmp_libpath="${gcc_lib_dirs}:${tmp_libpath}" + +# Put machine/arch specific tweaks to the libpath here. +if test -z "${COMPILER_MODEL_BITS}" +then + SAH_DEFAULT_BITNESS +fi +case $target in + x86_64-*-linux*) + if test -n "${COMPILER_MODEL_BITS}" + then + tmp_pattern="s/\/lib/\/lib${COMPILER_MODEL_BITS}/g" + tmp_pattern_b="s/${COMPILER_MODEL_BITS}${COMPILER_MODEL_BITS}/${COMPILER_MODEL_BITS}/g" + abcd_q=`echo ${tmp_libpath} | sed ${tmp_pattern} | sed ${tmp_pattern_b} ` + case ${COMPILER_MODEL_BITS} in + 32) + gcc_host_dirs=`echo ${gcc_prefix}/lib/gcc*/i[3456]86*linux*/${gcc_version}` + ;; + 64) + gcc_host_dirs=`echo ${gcc_prefix}/lib/gcc-lib/x86_64*linux*/${gcc_version}` + ;; + esac + tmp_libpath="${abcd_q}:${tmp_libpath}" + for tmp_dir in ${gcc_host_dirs} + do + tmp_libpath="${tmp_dir}:${tmp_libpath}" + done + fi + ;; + sparc*-sun-solaris*) + if test -n "${COMPILER_MODEL_BITS}" + then + tmp_pattern="s/\/lib/\/lib\/${COMPILER_MODEL_BITS}/g" + tmp_pattern_b="s/${COMPILER_MODEL_BITS}\/${COMPILER_MODEL_BITS}/${COMPILER_MODEL_BITS}/g" + abcd_q=`echo ${tmp_libpath} | sed ${tmp_pattern} | sed ${tmp_pattern_b}` + case ${COMPILER_MODEL_BITS} in + 64) + tmp_arch="sparcv9" + ;; + 32) + tmp_arch= + ;; + esac + abcd_r="/notadir/" + for tmp_dir in `echo ${tmp_libpath} | sed 's/\:/ /g'` + do + abcd_r="${abcd_r}:${tmp_dir}/${tmp_arch}" + done + tmp_libpath="${abcd_r}:${abcd_q}:${tmp_libpath}" + fi + ;; + *) + echo > /dev/null + ;; +esac + + +if test -n "`echo x$1 | grep x-l`" +then + # in the -l case, don't search, just use the ld_static_option (usually + # -Wl,-B static + tmp_lib_name="${ld_static_option} $1" +else + # we also want to check the system config files for library dirs. + tmp_dir_list= + if test -e /etc/ld.so.conf + then + tmp_dir_list=`cat /etc/ld.so.conf` + else + if test -e /var/ld/ld.config + then + tmp_dir_list=`cat /var/ld/ld.config` + fi + fi + + tmp_dir_list=`echo ${tmp_libpath}:/lib:/usr/lib:/usr/ucb/lib:/usr/local/lib:/opt/misc/lib:${tmp_dir_list} | $AWK -F: '{for (i=1;i<(NF+1);i++) { print $[]i; }}'` + + tmp_lib_name= + # now that we know where we are looking, find our library + for tmp_dir in $tmp_dir_list + do + if test -e $tmp_dir/$1 + then + tmp_lib_name=${tmp_dir}/$1 + break + fi + done +fi +]) diff --git a/m4/sah_check_math_functions.m4 b/m4/sah_check_math_functions.m4 new file mode 100644 index 0000000..21777e9 --- /dev/null +++ b/m4/sah_check_math_functions.m4 @@ -0,0 +1,10 @@ +AC_DEFUN([SAH_CHECK_MATH_FUNCS],[ + for func in $1 ; do + AH_TEMPLATE(AS_TR_CPP(have_${func}),[Define to 1 if you have the function ${func}()]) + AC_CHECK_LIB([m],$func,[ + eval "ac_cv_func_${func}=yes" + AC_DEFINE_UNQUOTED(AS_TR_CPP(have_${func}),1,[Define to 1 if you have the function ${func()}]) + ]) + AC_CHECK_FUNC($func) + done +]) diff --git a/m4/sah_find_s4path.m4 b/m4/sah_find_s4path.m4 new file mode 100644 index 0000000..4c51d1a --- /dev/null +++ b/m4/sah_find_s4path.m4 @@ -0,0 +1,32 @@ +# SETI_BOINC is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2, or (at your option) any later +# version. + +AC_DEFUN([SAH_FIND_S4PATH],[ +AC_MSG_CHECKING([path to S4 library]) +s4_search_path="$S4PATH /usr/local/warez/projects/s4/siren /disks/cyclops/c/users/seti/s4/siren" +for tmp_dir in $s4_search_path +do + if test -f $tmp_dir/lib/libs4.a + then + S4PATH=$tmp_dir + S4LIBS="-L$S4PATH/lib -ls4" + S4CFLAGS="-I$S4PATH/include" + S4_RECEIVER_CONFIG="$S4PATH/db/ReceiverConfig.tab" + break + fi +done +if test -n "$S4PATH" +then + AC_MSG_RESULT([$S4PATH]) +else + no_s4=yes + AC_MSG_RESULT([not found]) +fi +AC_SUBST([S4PATH]) +AC_SUBST([S4LIBS]) +AC_SUBST([S4CFLAGS]) +AC_DEFINE_UNQUOTED([S4_RECEIVER_CONFIG_FILE],["$S4_RECEIVER_CONFIG"],[Path to the S4 receiver config file]) +]) + diff --git a/m4/sah_find_setilib.m4 b/m4/sah_find_setilib.m4 new file mode 100644 index 0000000..5cd132f --- /dev/null +++ b/m4/sah_find_setilib.m4 @@ -0,0 +1,33 @@ +# SETI_BOINC is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2, or (at your option) any later +# version. + +AC_DEFUN([SAH_FIND_SETILIB],[ +AC_MSG_CHECKING([path to setilib library]) +setilib_search_path="$SETILIBDIR setilib ../setilib $HOME/setilib /usr/local /usr/local/setilib /usr/local/lib/setilib /opt/misc/setilib /opt/misc/lib/setilib" +for tmp_dir in $setilib_search_path +do + if test -f $tmp_dir/lib/libseti.a + then + mydir=`pwd` + cd $tmp_dir + SETILIB_PATH=`pwd` + SETILIB_LIBS="-L$SETILIB_PATH/lib -lseti" + SETILIB_CFLAGS="-I$SETILIB_PATH/include -I$SETILIB_PATH" + cd $mydir + break + fi +done +if test -n "$SETILIB_PATH" +then + AC_MSG_RESULT([$SETILIB_PATH]) +else + no_setilib=yes + AC_MSG_RESULT([not found]) +fi +AC_SUBST([SETILIB_PATH]) +AC_SUBST([SETILIB_LIBS]) +AC_SUBST([SETILIB_CFLAGS]) +]) + diff --git a/m4/sah_grx.m4 b/m4/sah_grx.m4 new file mode 100644 index 0000000..ec9daed --- /dev/null +++ b/m4/sah_grx.m4 @@ -0,0 +1,27 @@ + + +AC_DEFUN([SAH_GRX_LIBS],[ + AC_LANG_PUSH(C) + sah_save_libs="$LIBS" + AC_PATH_PROG(XLSFONTS,[xlsfonts],[/usr/X11/bin:/usr/X11R6/bin:/usr/X11R5/bin:/usr/X11R4/bin:/usr/openwin/bin:$PATH]) + sah_xpath=`echo $XLSFONTS | sed 's/bin\/xlsfonts//' ` + LIBS=`echo $LIBS "-L$sah_xpath"` + GRXLIBS="-L${sah_xpath} -ljpeg -lX11 -lXext -lXt -lICE -lSM -lGL -lGLU -lm" + LIBS="$sah_save_libs" + AC_SUBST(GRXLIBS) + AC_LANG_POP +]) + +AC_DEFUN([SAH_GRX_INCLUDES],[ + AC_LANG_PUSH(C++) + AC_PATH_PROG(XLSFONTS,[xlsfonts],[/usr/X11/bin:/usr/X11R6/bin:/usr/X11R5/bin:/usr/X11R4/bin:/usr/openwin/bin:$PATH]) + sah_xpath=`echo $XLSFONTS | sed 's/bin\/xlsfonts//' ` + save_cflags="$CFLAGS" + CFLAGS=`echo $CFLAGS "-I$sah_xpath/include"` + GRX_CFLAGS="-I$sah_xpath" + AC_SUBST(GRX_CFLAGS) + AC_CHECK_HEADERS([gl.h glu.h glut.h glaux.h GL/gl.h GL/glu.h GL/glut.h GL/glaux.h OpenGL/gl.h OpenGL/glu.h OpenGL/glut.h OpenGL/glaux.h glut/glut.h MesaGL/gl.h MesaGL/glu.h MesaGL/glut.h MesaGL/glaux.h]) + CFLAGS="$save_cflags" + AC_LANG_POP +]) + diff --git a/m4/sah_header_stdcxx.m4 b/m4/sah_header_stdcxx.m4 new file mode 100644 index 0000000..7c6ee99 --- /dev/null +++ b/m4/sah_header_stdcxx.m4 @@ -0,0 +1,71 @@ +# The contents of this file are subject to the BOINC Public License +# Version 1.0 (the "License"); you may not use this file except in +# compliance with the License. You may obtain a copy of the License at +# http://boinc.berkeley.edu/license_1.0.txt + +AC_PREREQ([2.54]) + +AC_DEFUN([SAH_HEADER_STDCXX],[ + save_inc="$ac_includes_default" + ac_includes_default=" +#define CONFIG_TEST +#include \"$BOINCDIR/lib/std_fixes.h\" +$ac_includes_default + +" + + sah_stdcxx_headers="algorithm bitset cassert cctype cerrno cfloat climits clocale cmath complex csetjmp csignal cstdarg cstddef cstdio cstdlib cstring ctime deque fstream functional iomanip ios iosfwd iostream istream iterator limits list locale map memory numeric ostream queue set sstream stack stdexcept streambuf string utility valarray vector" + AC_LANG_PUSH(C++) + dnl First we'll check to see if they are all here in order to save time. + AC_MSG_CHECKING([standard C++ headers]) + tmp_includes= + for header in $sah_stdcxx_headers + do + tmp_includes="$tmp_includes +#include <$header> +" + done + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ +$ac_includes_default +$tmp_includes + ]], + [] + )], + [ + ac_includes_default="${ac_includes_default} +${tmp_includes} +" + sah_cxx_includes=${tmp_includes} + AC_MSG_RESULT(yes) + for header in $sah_stdcxx_headers + do + eval ac_cv_header_${header}=yes + ac_uc_defn=HAVE_`echo ${header} | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + AC_DEFINE_UNQUOTED([${ac_uc_defn}],1,[Define to 1 if you have the ${header} header]) + AC_CACHE_CHECK([for C++ header <${header}>],[ac_cv_header_${header}]) + done + ], + [ + ac_includes_default="$save_inc" + AC_MSG_RESULT(no) + AC_CHECK_HEADERS([$sah_stdcxx_headers]) + for header in $sah_stdcxx_headers + do + eval tmp_var=\$ac_cv_header_${header} + if test "$tmp_var" = "yes" + then + sah_cxx_includes="$sah_cxx_includes +#include <$header> +" + fi + done + ] + ) + ac_includes_default="$save_inc" + AC_CACHE_SAVE + AC_LANG_POP(C++) + CONFIG_TEST= +]) + diff --git a/m4/sah_informix.m4 b/m4/sah_informix.m4 new file mode 100644 index 0000000..4a82bc8 --- /dev/null +++ b/m4/sah_informix.m4 @@ -0,0 +1,47 @@ +# SETI_BOINC is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2, or (at your option) any later +# version. + +AC_DEFUN([SAH_CHECK_INFORMIX],[ + AC_ARG_VAR([INFORMIXDIR],[informix directory]) + AC_LANG_PUSH(C) + AC_MSG_CHECKING(for Informix) + if test -z "$INFORMIXDIR" + then + AC_PATH_PROG([INFORMIXDIR],[dbaccess],[],[/disks/galileo/a/apps/informix/bin:$PATH:/usr/local/informix/bin:/opt/misc/informix:~informix/bin]) + INFORMIXDIR=`echo $INFORMIXDIR | $SED 's/bin\/dbaccess//'` + fi + if test -n "$INFORMIXDIR" + then + AC_MSG_RESULT(yes) + INFORMIX_CFLAGS="-I$INFORMIXDIR/incl -I$INFORMIXDIR/incl/esql " + INFORMIX_LIBS=" -L$INFORMIXDIR/lib -L$INFORMIXDIR/lib/esql $INFORMIXDIR/lib/esql/checkapi.o -lifasf -lifgen -lifgls -lifos -lifsql" + AC_CHECK_LIB([socket], [bind], INFORMIX_LIBS="${INFORMIX_LIBS} -lsocket") + AC_CHECK_LIB([nsl], [gethostbyname], INFORMIX_LIBS="${INFORMIX_LIBS} -lnsl") + AC_CHECK_LIB([crypt], [crypt], INFORMIX_LIBS="${INFORMIX_LIBS} -lcrypt") + AC_CHECK_LIB([dl], [dlopen], INFORMIX_LIBS="${INFORMIX_LIBS} -ldl") + AC_CHECK_LIB([m], [ceil], INFORMIX_LIBS="${INFORMIX_LIBS} -lm") + + tmpvar=$LIBS + LIBS=`echo $LIBS $INFORMIX_LIBS` + AC_MSG_CHECKING(informix library flags) + AC_TRY_LINK_FUNC(main,AC_DEFINE([USE_INFORMIX],[1],[Define to 1 if informix is installed]) sah_cv_use_informix="yes", sah_cv_use_informix="no") + AC_MSG_RESULT($sah_cv_use_informix) + LIBS=$tmpvar + SAH_FORCE_LIBSEARCH_PATH(tmpvar,[$INFORMIXDIR/lib:$INFORMIXDIR/lib/esql]) + INFORMIX_LIBS=`echo $tmpval $INFORMIX_LIBS` + else + INFORMIXDIR= + INFORMIX_CFLAGS= + INFORMIX_LIBS= + AC_MSG_RESULT(no) + no_informix=yes + fi + AC_SUBST(INFORMIXDIR) + AC_SUBST(INFORMIX_CFLAGS) + AC_SUBST(INFORMIX_LIBS) + AC_LANG_POP +]) + + diff --git a/m4/sah_largefile_breaks_cxx.m4 b/m4/sah_largefile_breaks_cxx.m4 new file mode 100644 index 0000000..c1af234 --- /dev/null +++ b/m4/sah_largefile_breaks_cxx.m4 @@ -0,0 +1,27 @@ +# SETI_BOINC is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2, or (at your option) any later +# version. + +AC_DEFUN([SAH_LARGEFILE_BREAKS_CXX],[ + AC_MSG_CHECKING([whether largefile support breaks C++]) + AC_LANG_PUSH(C++) + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[ + #define CONFIG_TEST + #include + ]], + [[ + std::cout << 1.0 << std::endl; + ]])], + [tmp_res="no"], + [AC_DEFINE([LARGEFILE_BREAKS_CXX],[1], + ["Define to 1 if largefile support causes missing symbols in C++"] ) + tmp_res="yes" + sah_cxx_includes=`echo "#include \"$BOINCDIR/lib/std_fixes.h\"" ; echo $sah_cxx_includes` + ] + ) + AC_MSG_RESULT($tmp_res) + AC_LANG_POP +]) + diff --git a/m4/sah_libext.m4 b/m4/sah_libext.m4 new file mode 100644 index 0000000..4f569e7 --- /dev/null +++ b/m4/sah_libext.m4 @@ -0,0 +1,33 @@ +# SETI_BOINC is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2, or (at your option) any later +# version. + +AC_DEFUN([SAH_LIBEXT],[ + AC_MSG_CHECKING(library extension) + if test -n `echo $AR | grep ar` + then + LIBEXT=a + else + LIBEXT=lib + fi + AC_MSG_RESULT($LIBEXT) + AC_SUBST(LIBEXT) +]) + +AC_DEFUN([SAH_DLLEXT],[ + AC_MSG_CHECKING(shared object extension) + case "${host}" in + *-*-emx* | *-*-mingw* | *-*-cygwin* | *-*-rmx*) + DLLEXT="dll" + ;; + *-*-darwin*) + DLLEXT="dylib" + ;; + *) + DLLEXT="so" + ;; + esac + AC_MSG_RESULT($DLLEXT) + AC_SUBST(DLLEXT) +]) diff --git a/m4/sah_libsearch.m4 b/m4/sah_libsearch.m4 new file mode 100644 index 0000000..f7023a0 --- /dev/null +++ b/m4/sah_libsearch.m4 @@ -0,0 +1,34 @@ +# SETI_BOINC is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2, or (at your option) any later +# version. + +AC_DEFUN([SAH_FORCE_LIBSEARCH_PATH],[ + if test -z "$LD" + then + AC_PATH_PROGS([LD],[ld link]) + fi + if test "$GCC" = "yes" + then + link_pass_flag="-Xlinker " + else + if test "$CC" = "lcc" + then + link_pass_flag="-Wl" + fi + fi + if test -n "$link_pass_flag" + then + if test -n "$LD" + then + if $LD -V 2>&1 | grep GNU + then + $1="$link_pass_flag -rpath $link_pass_flag $2 " + else + $1="$link_pass_flag -R $link_pass_flag $2 " + fi + fi + fi +]) + + diff --git a/m4/sah_links.m4 b/m4/sah_links.m4 new file mode 100644 index 0000000..492282d --- /dev/null +++ b/m4/sah_links.m4 @@ -0,0 +1,36 @@ +AC_DEFUN([SAH_LINKS],[ + AC_PATH_PROGS(LN,[ln cp copy]) + if test -n "$LN" ; then + AC_MSG_CHECKING(whether '$LN' works) + if $LN config.sub erase.me$$ && \ + test -e erase.me$$ && \ + diff config.sub erase.me$$ >/dev/null 2>&5 + then + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + LN=cp + fi + /bin/rm erase.me$$ + else + LN=cp + fi + AC_PROG_LN_S + if test -n "$LN_S" ; then + AC_MSG_CHECKING(whether '$LN_S' really works or whether I'm deluding myself) + if $LN_S config.sub erase.me$$ && \ + test -e erase.me$$ && \ + diff config.sub erase.me$$ >/dev/null 2>&5 + then + AC_MSG_RESULT(it works) + else + AC_MSG_RESULT(I'm deluding myself) + LN_S=cp + fi + /bin/rm erase.me$$ + else + LN_S=cp + fi +]) + + diff --git a/m4/sah_make_dll.m4 b/m4/sah_make_dll.m4 new file mode 100644 index 0000000..7ed00f4 --- /dev/null +++ b/m4/sah_make_dll.m4 @@ -0,0 +1,14 @@ +AC_DEFUN([SAH_LINK_DLL],[ + case ${host} in + *darwin*) + LINK_DLL="${CC} -fPIC -bundle -flat_namespace -undefined suppress" + ;; + *solaris*) + LINK_DLL="/usr/ccs/bin/ld -G " + ;; + *) + LINK_DLL="${CC} -fPIC -shared" + ;; + esac + AC_SUBST(LINK_DLL) +]) diff --git a/m4/sah_mysql.m4 b/m4/sah_mysql.m4 new file mode 100644 index 0000000..7dff3de --- /dev/null +++ b/m4/sah_mysql.m4 @@ -0,0 +1,30 @@ +# SETI_BOINC is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2, or (at your option) any later +# version. + +AC_DEFUN([SAH_CHECK_MYSQL],[ +AC_LANG_PUSH(C) +AC_ARG_VAR([MYSQL_CONFIG], [mysql_config program]) +if test -z "$MYSQL_CONFIG"; then + AC_PATH_PROG(MYSQL_CONFIG,mysql_config,,[$PATH:/usr/local/mysql/bin:/opt/misc/mysql/bin:~mysql/bin]) +fi +if test -z "$MYSQL_CONFIG" +then + echo MYSQL not found + no_mysql=yes +else + AC_MSG_RESULT(yes) + AC_MSG_CHECKING(mysql libraries) + MYSQL_LIBS=`${MYSQL_CONFIG} --libs` + AC_MSG_RESULT($MYSQL_LIBS) + AC_MSG_CHECKING(mysql includes) + MYSQL_CFLAGS=`${MYSQL_CONFIG} --cflags` + AC_DEFINE(USE_MYSQL,1,[Define if MYSQL is installed]) + AC_MSG_RESULT($MYSQL_CFLAGS) +fi +AC_SUBST(MYSQL_LIBS) +AC_SUBST(MYSQL_CFLAGS) +AC_LANG_POP +]) + diff --git a/m4/sah_namespace.m4 b/m4/sah_namespace.m4 new file mode 100644 index 0000000..2108f8e --- /dev/null +++ b/m4/sah_namespace.m4 @@ -0,0 +1,92 @@ +# The contents of this file are subject to the BOINC Public License +# Version 1.0 (the "License"); you may not use this file except in +# compliance with the License. You may obtain a copy of the License at +# http://boinc.berkeley.edu/license_1.0.txt +# +# Revision Log: +# $Log: sah_namespace.m4,v $ +# Revision 1.5.2.1 2005/05/19 01:07:10 korpela +# *** empty log message *** +# +# Revision 1.3 2005/05/10 15:43:56 korpela +# Fixed bug in caching of SAH_FUNCS_IN_NAMESPACE results. +# +# Revision 1.2 2005/05/06 00:31:05 korpela +# Added caching of results to SAH_CHECK_NAMESPACES and SAH_FUNCS_IN_NAMESPACE +# +# Revision 1.1 2003/12/11 18:38:24 korpela +# Added checked macro files into boinc +# +# Revision 1.5 2003/12/03 23:46:11 korpela +# Fixed "sah_namespaces.m4" not to rely on "tr". +# +# + +AC_PREREQ([2.54]) + + +AC_DEFUN([SAH_LC_TO_DEFN],[ + $1=`echo $2 | $AWK '{split($[]1,a,"(");print a[[ 1 ]]}' | $as_tr_cpp` +]) + +AC_DEFUN([SAH_NS_TO_DEFN],[ + $1=`echo $2 | $as_tr_cpp` +]) + +AC_DEFUN([SAH_CHECK_NAMESPACES],[ + AC_LANG_PUSH(C++) + AC_CACHE_CHECK([for C++ namespaces], + [sah_cv_have_namespaces],[ + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([ + #define CONFIG_TEST + namespace foo { + int foo(void) { return(0); } + } + ],[ + return foo::foo(); + ]) + ], [sah_cv_have_namespaces="yes"], [sah_cv_have_namespaces="no"]) + ]) + if test "${sah_cv_have_namespaces}" = "yes" ; then + AC_DEFINE(HAVE_NAMESPACES,[1],[Define if your C++ compiler supports namespaces]) + fi + AC_LANG_POP(C++) +]) + +AC_DEFUN([SAH_FUNCS_IN_NAMESPACE],[ + AC_LANG_PUSH(C++) + for func_name in $1 + do + func_name=m4_quote($func_name) + t_ns=m4_quote($2) + SAH_LC_TO_DEFN(ac_func_upper,[$func_name]) + SAH_LC_TO_DEFN(ac_namespace_upper,[$t_ns]) + ac_uc_defn=`echo HAVE_"$ac_namespace_upper"_$ac_func_upper` + AC_CACHE_CHECK([for $func_name in namespace $t_ns], + [sah_cv_func_$2_$ac_func_upper],[ + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[ + #define CONFIG_TEST + $sah_cxx_includes + ]], + [[ + $2::$func_name ; + ]])], + [ + eval sah_cv_func_$2_$ac_func_upper="yes" + ], + [ + eval sah_cv_func_$2_$ac_func_upper="no" + ] + ) + ]) + if test "`eval echo '${'sah_cv_func_$2_$ac_func_upper'}'`" = "yes" ; then + AC_DEFINE_UNQUOTED([$ac_uc_defn], [1], + ["Define to 1 if $func_name is in namespace $t_ns::" ]) + fi + done + AC_LANG_POP(C++) +]) + + diff --git a/m4/sah_raw_ldflags.m4 b/m4/sah_raw_ldflags.m4 new file mode 100644 index 0000000..84d50a5 --- /dev/null +++ b/m4/sah_raw_ldflags.m4 @@ -0,0 +1,5 @@ +AC_DEFUN([SAH_RAW_LDFLAGS],[ + $2=`echo $1 | $SED 's/-Wl,//g'` + echo RAW_LDFLAGS:$2=`echo $1 | $SED 's/-Wl,//g'` >&5 + AC_SUBST([$2]) +]) diff --git a/m4/sah_requires.m4 b/m4/sah_requires.m4 new file mode 100644 index 0000000..eda657f --- /dev/null +++ b/m4/sah_requires.m4 @@ -0,0 +1,38 @@ + +AC_DEFUN([SAH_REQUIRES],[ + $2 + if test $3; then + AC_MSG_WARN([ $1 not found. +============================================================================ +$4 +============================================================================ +]) +$5 + fi +]) + + +AC_DEFUN([SAH_SERVER_REQUIRES],[ +if test "${enable_server}" = yes; then + SAH_REQUIRES([$1],[$2],[$3], +[ +WARNING: trying to build the seti_boinc server but $1 was not found. +If you don't want to build the server you should use --disable-server. + +I am continuing now as if --disable-server had been specified. +],[enable_server=no]) +fi +]) + +AC_DEFUN([SAH_CLIENT_REQUIRES],[ +if test "${enable_client}" = yes; then + SAH_REQUIRES([$1],[$2],[$3], +[ +WARNING: trying to build the seti_boinc client but $1 was not found. +If you don't want to build the client you should use --disable-client. + +I am continuing now as if --disable-client had been specified. +],[enable_client=no]) +fi +]) + diff --git a/m4/sah_select_bitness.m4 b/m4/sah_select_bitness.m4 new file mode 100644 index 0000000..f96a6bb --- /dev/null +++ b/m4/sah_select_bitness.m4 @@ -0,0 +1,56 @@ +AC_DEFUN([SAH_DEFAULT_BITNESS],[ + if test -z "${COMPILER_MODEL_BITS}" + then + AC_MSG_CHECKING(default bitness of compiler) + echo "int main() { return 0; }" >conftest.c + ${CC} ${CFLAGS} -c conftest.c >&5 + COMPILER_MODEL_BITS=32 + if test -f conftest.${OBJEXT} ; then + if test -n "`file conftest.${OBJEXT} | grep -i 64-bit`" + then + COMPILER_MODEL_BITS=64 + else + if test -n "`file conftest.${OBJEXT} | grep -i 16-bit`" + then + COMPILER_MODEL_BITS=16 + fi + fi + fi + /bin/rm conftest.c + AC_MSG_RESULT($COMPILER_MODEL_BITS) + fi +]) + + +AC_DEFUN([SAH_SELECT_BITNESS],[ + AC_LANG_PUSH(C) + SAH_DEFAULT_BITNESS + AC_MSG_CHECKING(Selecting $1 bit model) + echo "int main() { return 0; }" >conftest.$ac_ext + if test "$1" != "${COMPILER_MODEL_BITS}" + then + ${CC} ${CFLAGS} ${CPPFLAGS} -m$1 -c conftest.$ac_ext >&5 + if test -f conftest.${OBJEXT} ; then + if test -n "`file conftest.${OBJEXT} | grep -i $1-bit`" + then + CFLAGS="${CFLAGS} -m$1" + AC_MSG_RESULT(-m$1) + COMPILER_MODEL_BITS=$1 + fi + AC_MSG_RESULT(failed) + fi + else + AC_MSG_RESULT(ok) + fi + AC_LANG_POP(C) +]) + +AC_DEFUN([SAH_OPTION_BITNESS],[ + AC_ARG_ENABLE(bitness, + AC_HELP_STRING([--enable-bitness=(32,64)], + [enable 32 or 64 bit object/executable files] + ), + [SAH_SELECT_BITNESS(${enableval})], + [SAH_DEFAULT_BITNESS] + ) +]) diff --git a/m4/sah_staticize_ldflags.m4 b/m4/sah_staticize_ldflags.m4 new file mode 100644 index 0000000..93ddcd7 --- /dev/null +++ b/m4/sah_staticize_ldflags.m4 @@ -0,0 +1,41 @@ +AC_DEFUN([SAH_STATICIZE_LDFLAGS],[ + STATIC_LIB_LIST="${STATIC_LIB_LIST} $3" + liblist=`echo $1 | $AWK '{for (i=1;i<(NF+1);i++) {print $[]i;}}' | grep -v "Wl,[sd]" ` + ssl_sah_save_libs="${LIBS}" + echo "DEBUG: before mangling $2:$1" >&5 + sah_outputlibs= + for somelib in ${liblist}; do + # look for the -l to find the libraries + alib=`echo x${somelib} | grep x-l | sed 's/x-l//'` + if test -n "${alib}" + then + # check to see if it is in our static list + for slib in ${STATIC_LIB_LIST}; do + lib_is_static="no" + tmp_pattern=`echo s/x${slib}// | sed 's/\*/.*/'` + if test -z "`echo x${alib} | sed ${tmp_pattern}`" + then + SAH_STATIC_LIB(${alib},[fopen],[sah_outputlibs="${sah_outputlibs} ${sah_lib_last}"]) + lib_is_static="yes" + break; + fi + done + if test "${lib_is_static}" = "no" ; then + SAH_DYNAMIC_LIB(${alib},[fopen],[sah_outputlibs="${sah_outputlibs} ${sah_lib_last}"]) + fi + else + tmp_pattern_a="s/x${ld_dynamic_option}//" + tmp_pattern_b="s/x${ld_static_option}//" + if test -n "`echo x${somelib} | sed ${tmp_pattern_a}`" -a \ + -n "`echo x${somelib} | sed ${tmp_pattern_b}`" + then + sah_outputlibs="${sah_outputlibs} ${somelib}" + LIBS="${LIBS} ${somelib}" + fi + fi + done + echo "DEBUG: final link-line for $2:${sah_outputlibs}" >&5 + $2=${sah_outputlibs} + LIBS="${ssl_sah_save_libs}" +]) + diff --git a/mac_build/HowToBuildSETI_XCode.rtf b/mac_build/HowToBuildSETI_XCode.rtf new file mode 100644 index 0000000..acb2ba7 --- /dev/null +++ b/mac_build/HowToBuildSETI_XCode.rtf @@ -0,0 +1,226 @@ +{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf350 +{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fmodern\fcharset0 Courier;\f2\fmodern\fcharset0 Courier-Bold; +\f3\fnil\fcharset0 LucidaGrande;} +{\colortbl;\red255\green255\blue255;} +\margl1440\margr1440\vieww16740\viewh9900\viewkind0 +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\qc + +\f0\b\fs28 \cf0 Building the Macintosh SETI@home Client\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural + +\b0\fs24 \cf0 \ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\qc +\cf0 Written by Charlie Fenton\ +Last updated 4/9/11\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural +\cf0 \ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\qc\pardirnatural + +\b\fs28 \cf0 Step 1: Get the source files for the components\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural + +\i\b0\fs24 \cf0 SETI@home and BOINC source files are now archived using Subversion. You can download svnX, a free GUI application for running Subversion from either\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural + +\i0 \cf0 {\field{\*\fldinst{HYPERLINK "http://www.apple.com/downloads/macosx/development_tools/svnx.html"}}{\fldrslt http://www.apple.com/downloads/macosx/development_tools/svnx.html}}\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural + +\i \cf0 or\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural + +\i0 \cf0 {\field{\*\fldinst{HYPERLINK "http://www.lachoseinteractive.net/en/community/subversion/svnx/"}}{\fldrslt http://www.lachoseinteractive.net/en/community/subversion/svnx/}}\ +\ +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural\pardirnatural + +\i \cf0 Subversion itself may now be included and installed with XCode. If it is not , then you can get it from +\i0 \ +{\field{\*\fldinst{HYPERLINK "http://subversion.apache.org/"}}{\fldrslt http://subversion.apache.org/}}\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural +\cf0 \ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural +\cf0 F +\f1 irst, create a parent directory to hold all the components for building the SETI@home client, and cd to it. Throughout this document, we will refer to this parent directory as +\f0 +\b \{parent_dir\} +\b0 ; please substitute your path for this in all commands.\ +\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural + +\i \cf0 Hint: you can avoid typing paths by dragging files or directories from the Finder onto the Terminal window. The path will be inserted at the current position of the text cursor .\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural + +\i0 \cf0 \ + In the +\b Terminal +\b0 application, type the following, substituting the path to your desired parent directory for \{parent_dir\}:\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural + +\f1\fs26 \cf0 $mkdir \{parent_dir\}/boinc\ +$ cd \{parent_dir\}/boinc\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural + +\f0\fs24 \cf0 \ +Next, get the source tree for BOINC so you can build the BOINC libraries.\ +To determine the available branches and tags for BOINC, browse in \ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural +{\field{\*\fldinst{HYPERLINK "http://boinc.berkeley.edu/trac/browser"}}{\fldrslt \cf0 http://boinc.berkeley.edu/trac/browser}}\ +\ +SVN normally is built in directory usr/local/bin/, so you must include it in the standard search path:\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural + +\f1\fs26 \cf0 $ export PATH=/usr/local/bin:$PATH\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural + +\f0\fs24 \cf0 \ +To get the BOINC sources from branch +\b boinc_core_release_5_10 +\b0 :\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural + +\f1\fs26 \cf0 $ svn co http://boinc.berkeley.edu/svn/branches/boinc_core_release_5_10/ \ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural + +\f0\fs24 \cf0 \ +To get the sources from the trunk:\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural + +\f1\fs26 \cf0 $ svn co http://boinc.berkeley.edu/svn/trunk/boinc/boinc\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural + +\f0\fs24 \cf0 \ +To get the BOINC sources from tag +\b boinc_core_release_5_10_13 +\b0 :\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural + +\f1\fs26 \cf0 $ svn co http://boinc.berkeley.edu/svn/tags/boinc_core_release_5_10_13/\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural + +\f0\fs24 \cf0 \ +Next, get the Fast Fourier Transform sources using svnX from\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural +{\field{\*\fldinst{HYPERLINK "https://setisvn.ssl.berkeley.edu/svn/lib/fftw-3.1.1/"}}{\fldrslt \cf0 https://setisvn.ssl.berkeley.edu/svn/lib/fftw-3.1.1/}}\ +or from Terminal with:\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural + +\f1\fs26 \cf0 $ svn co https://setisvn.ssl.berkeley.edu/svn/lib/fftw-3.1.1/\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural + +\f0\fs24 \cf0 \ +To determine the available branches or tags for +\b setiathome_enhanced +\b0 , browse in\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural +{\field{\*\fldinst{HYPERLINK "https://setisvn.ssl.berkeley.edu/trac/browser/"}}{\fldrslt \cf0 https://setisvn.ssl.berkeley.edu/trac/browser/}}\ +\ +Then download the setiathome_enhanced source tree :\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural + +\f1\fs26 \cf0 $ cd \{parent_dir\}/\ +$ cvs -d :pserver:anonymous:@alien.ssl.berkeley.edu:/home/cvs/cvsroot checkout [-r +\f2\b branch_or_tag_name +\f1\b0 ] seti_boinc\ +\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural + +\f0\fs24 \cf0 Or use svnX. For the sah_v7 branch, the URL would be\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural +{\field{\*\fldinst{HYPERLINK "https://setisvn.ssl.berkeley.edu/svn/branches/sah_v7/seti_boinc"}}{\fldrslt \cf0 https://setisvn.ssl.berkeley.edu/svn/branches/sah_v7/seti_boinc}}\ +\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\qc\pardirnatural + +\b\fs28 \cf0 Step 2: Build the BOINC libraries\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural + +\b0\fs24 \cf0 \ +Find the file +\b \{parent_dir\}/boinc/mac_build/HowToBuildBOINC_XCode.rtf +\f3\b0 +\f0 and follow the directions for building the BOINC libraries. A version of this document can be found on-line at {\field{\*\fldinst{HYPERLINK "http://boinc.berkeley.edu/trac/wiki/MacBuild"}}{\fldrslt http://boinc.berkeley.edu/trac/wiki/MacBuild}} but the build procedures vary for different versions of BOINC. You should always use the instructions in the BOINC source tree for the version you are building. +\f3 \ + +\f1 \ +You do not need to build the BOINC Client or BOINC Manager. You can ignore the information in that documentation on building BOINC project applications; follow these instructions instead.\ +\ +You should now have the following subdirectories inside your parent directory:\ +\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural + +\fs26 \cf0 boinc/\ + curl-x.y.z/\ + jpeg-6b/\ + lib/fftw-3.1.1/\ + seti_boinc/\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural + +\f0\fs24 \cf0 \ +Note: you can rename the seti_boinc directory if you wish, and the curl directory will have the version number instead of x.y.z. All other directories must have the exact names shown above. If you wish to use a different name for the +\f1\fs26 boinc +\f0\fs24 directory or the +\f1\fs26 lib/fftw-3.1.1/ +\f0\fs24 directory, you must create a symbolic link from the standard directory name to the one you have used. An alias created by the Macintosh Finder will +\i\b not +\i0\b0 work! In Terminal, type:\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural + +\f1\fs26 \cf0 $ cd \{parent_dir\}/\ +$ ln -s real_boinc_dir_name boinc\ +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural\pardirnatural + +\f0\fs24 \cf0 or: +\f1\fs26 \ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural +\cf0 $ cd \{parent_dir\}/lib\ +$ ln -s real_fftw_dir_name fftw-3.1.1/\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural + +\f0\fs24 \cf0 \ + \ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\qc\pardirnatural + +\b\fs28 \cf0 Step 2: Build the Fast Fourier Transform library\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural + +\b0\fs24 \cf0 \ +In the +\b Terminal +\b0 application, run the shell script seti_boinc/mac_build/ +\f3 buildfftw-3.1.1.sh by typing:\ + +\f0 \ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural + +\f1\fs26 \cf0 $ cd \{parent_dir\}/lib/fftw-3.3.1/\ +$ source \{parent_dir\}/seti_boinc/mac_build/buildfftw-3.1.1.sh\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural + +\f0\fs24 \cf0 \ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\qc\pardirnatural + +\b\fs28 \cf0 Step 3: Build the SETI@home application\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural + +\b0\fs24 \cf0 \ +\ +Update the configuration files to the current version number. In the Terminal application, run the shell script seti_boinc/mac_build/makeseticonfigs.sh by typing:\ +\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural + +\f1\fs26 \cf0 $ sh seti_boinc/mac_build/makeseticonfigs.sh \{parent_dir\}/seti_boinc \{parent_dir\}/boinc\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural + +\f0\fs24 \cf0 Double-click on the XCode project \{parent_dir\}/seti_boinc/mac_build/seti_boinc.xcodeproj.\ +\ +In the Active Target popup menu, select seti_boinc_ppc. In the Active Build Configuration popup menu, select Deployment and click on the Build icon.\ +Browse to \{parent_dir\}/seti_boinc/mac_build/Deployment and rename the seti_boinc_ppc file as desired (for example, +\b setiathome-7.89.powerpc-apple-darwin +\b0 ). +\f1 \ + +\f0 \ +In the Active Target popup menu, select seti_boinc_i386. In the Active Build Configuration popup menu, select Deployment and click on the Build icon.\ +Browse to \{parent_dir\}/seti_boinc/mac_build/Deployment and rename the seti_boinc_i386 file as desired (for example, +\b setiathome_7.89_i686-apple-darwin +\b0 ).\ +\ +} \ No newline at end of file diff --git a/mac_build/HowToTestSETI.txt b/mac_build/HowToTestSETI.txt new file mode 100644 index 0000000..4f93365 --- /dev/null +++ b/mac_build/HowToTestSETI.txt @@ -0,0 +1,29 @@ +[1] Quit BOINC + +[2] Set Screensaver to something other than BOINC + +[3] Create a test folder + +[4] Copy the following files to your test folder: +[path]/seti_boinc/mac_build/build/Deployment/seti_boinc_xxx +[path]/seti_boinc/mac_build/build/Deployment/seti_graphics_xxx +[path]/set_boinc/client/test_workunits/reference_work_unit.sah +[path]/set_boinc/client/test_workunits/reference_work_unit.sah +[path]/set_boinc/client/better_banner.jpg + +where "xxx" is either i386 or ppc, depending on the CPU type. + +[5] Rename reference_work_unit.sah to work_unit.sah +[6] Rename better_banner.jpg to seti_logo + +[7] In Terminal: + cd to the test folder + ./seti_boinc_i386 -standalone -verbose + or + ./seti_boinc_ppc -standalone -verbose + +[8] Open another Terminal window, and type the following while seti_boinc is running: + cd to the test folder + ./seti_graphics_i386 + or + ./seti_graphics_ppc diff --git a/mac_build/buildfftw-3.1.1.sh b/mac_build/buildfftw-3.1.1.sh new file mode 100644 index 0000000..0bab62e --- /dev/null +++ b/mac_build/buildfftw-3.1.1.sh @@ -0,0 +1,97 @@ +#!/bin/sh + +# Berkeley Open Infrastructure for Network Computing +# http://boinc.berkeley.edu +# Copyright (C) 2005 University of California +# +# This is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; +# either version 2.1 of the License, or (at your option) any later version. +# +# This software is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Lesser General Public License for more details. +# +# To view the GNU Lesser General Public License visit +# http://www.gnu.org/copyleft/lesser.html +# or write to the Free Software Foundation, Inc., +# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# +# Script to build Macintosh Universal Binary library of fftw-3.3.1 for +# use in building SETI_BOINC. +# +# by Charlie Fenton 5/2/06 +# updated for OS 10.4 SDK and SETI@home v7 on 4/9/11 +# +## In Terminal, CD to the fftw-3.3.1 directory. +## cd [path]/lib/fftw-3.3.1/ +## then run this script: +## source [path]/buildfftw-3.3.1 [ -clean ] +## +## the -clean argument will force a full rebuild. +# + +if [ "$1" != "-clean" ]; then + if [ -f .libs/libfftw3f_ppc.a ] && [ -f .libs/libfftw3f_i386.a ] && [ -f .libs/libfftw3f.a ]; then + + echo "buildfftw-3.3.1 already built" + return 0 + fi +fi + +export PATH=/usr/local/bin:$PATH +export CC=/usr/bin/gcc-4.0;export CXX=/usr/bin/g++-4.0 +export SDKROOT="/Developer/SDKs/MacOSX10.4u.sdk" + +export CFLAGS="-isysroot/Developer/SDKs/MacOSX10.4u.sdk -O3 -fomit-frame-pointer -fstrict-aliasing -ffast-math -mcpu=powerpc -mtune=G5 -arch ppc -D_THREAD_SAFE -mmacosx-version-min=10.4" +export CPPFLAGS="-isysroot/Developer/SDKs/MacOSX10.4u.sdk -O3 -fomit-frame-pointer -fstrict-aliasing -ffast-math -mcpu=powerpc -mtune=G5 -arch ppc -D_THREAD_SAFE -mmacosx-version-min=10.4" +export LDFLAGS="-isysroot/Developer/SDKs/MacOSX10.4u.sdk -Wl,-syslibroot,/Developer/SDKs/MacOSX10.4u.sdk -arch ppc" + +./configure -C --with-pic --enable-altivec --enable-fma --disable-fortran --enable-portable-binary --enable-single --enable-threads --with-combined-threads --host=ppc --build=ppc +if [ $? -ne 0 ]; then exit 1; fi + +make clean + +rm -f .libs/libfftw3f.a +rm -f .libs/libfftw3f_ppc.a +rm -f .libs/libfftw3f_i386.a + + +make -e +if [ $? -ne 0 ]; then exit 1; fi +mv -f .libs/libfftw3f.a ./libfftw3f_ppc.a + +make clean +if [ $? -ne 0 ]; then exit 1; fi + +export PATH=/usr/local/bin:$PATH +export CC=/usr/bin/gcc-4.0;export CXX=/usr/bin/g++-4.0 +export LDFLAGS="" +export CPPFLAGS="" +export CFLAGS="" +export SDKROOT="/Developer/SDKs/MacOSX10.4u.sdk" + +export CFLAGS="-isysroot/Developer/SDKs/MacOSX10.4u.sdk -O3 -fomit-frame-pointer -fstrict-aliasing -ffast-math -march=pentium-m -mtune=pentium-m -mfpmath=sse -isysroot /Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.4 -arch i386" +export CPPFLAGS="-isysroot/Developer/SDKs/MacOSX10.4u.sdk -O3 -fomit-frame-pointer -fstrict-aliasing -ffast-math -march=pentium-m -mtune=pentium-m -mfpmath=sse -isysroot /Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.4 -arch i386" +export LDFLAGS="-isysroot/Developer/SDKs/MacOSX10.4u.sdk -Wl,-syslibroot,/Developer/SDKs/MacOSX10.4u.sdk -arch i386" + +./configure --enable-sse --disable-fortran --enable-portable-binary --enable-single --enable-threads --with-combined-threads --host=i386 +if [ $? -ne 0 ]; then exit 1; fi + +make -e +if [ $? -ne 0 ]; then exit 1; fi +mv -f .libs/libfftw3f.a .libs/libfftw3f_i386.a +mv -f ./libfftw3f_ppc.a .libs/libfftw3f_ppc.a +lipo -create .libs/libfftw3f_i386.a .libs/libfftw3f_ppc.a -output .libs/libfftw3f.a +if [ $? -ne 0 ]; then exit 1; fi + +export CC="";export CXX="" +export LDFLAGS="" +export CPPFLAGS="" +export CFLAGS="" +export SDKROOT="" + +return 0 diff --git a/mac_build/config-i386.h b/mac_build/config-i386.h new file mode 100644 index 0000000..e70acca --- /dev/null +++ b/mac_build/config-i386.h @@ -0,0 +1,610 @@ +/* sah_config.h. Generated from sah_config.h.in by configure. */ +/* sah_config.h.in. Generated from configure.ac by autoheader. */ + + +#ifndef _SAH_CONFIG_H_ +#define _SAH_CONFIG_H_ + +#ifdef _WIN32 +#include "win-sah_config.h" +#else + + +/* Define to 1 to build a graphical application */ +#define BOINC_APP_GRAPHICS 1 + +/* Define to a string identifying your compiler */ +#define COMPILER_STRING "i686-apple-darwin10-g++-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5664)" + +/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP + systems. This function is required for `alloca.c' support on those systems. + */ +/* #undef CRAY_STACKSEG_END */ + +/* Define to 1 if using `alloca.c'. */ +/* #undef C_ALLOCA */ + +/* Define to 1 if your system stores words within floats with the most + significant word first */ +/* #undef FLOAT_WORDS_BIGENDIAN */ + +/* Define to 1 if you have the `alloca' function. */ +#define HAVE_ALLOCA 1 + +/* Define to 1 if you have and it should be used (not on Ultrix). + */ +#define HAVE_ALLOCA_H 1 + +/* Use the Apple OpenGL framework. */ +#define HAVE_APPLE_OPENGL_FRAMEWORK 1 + +/* Define to 1 if you have the `atanf' function. */ +#define HAVE_ATANF 1 + +/* Define to 1 if you have the `atexit' function. */ +#define HAVE_ATEXIT 1 + +/* Define to 1 if you have the `atoll' function. */ +#define HAVE_ATOLL 1 + +/* Define to 1 if the system has the type `bool'. */ +#define HAVE_BOOL 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_COMPLEX_H 1 + +/* Define to 1 if you have the `cosf' function. */ +#define HAVE_COSF 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_DIRENT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_DLFCN_H 1 + +/* Define to 1 if you have the `dlopen' function. */ +#define HAVE_DLOPEN 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_EMMINTRIN_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_ERRNO_H 1 + +/* Define to 1 if you have the `exit' function. */ +#define HAVE_EXIT 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_FFTW3_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_FLOATINGPOINT_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_FLOAT_H 1 + +/* Define to 1 if you have the `floor' function. */ +#define HAVE_FLOOR 1 + +/* Define to 1 if you have the `fork' function. */ +#define HAVE_FORK 1 + +/* Define to 1 if you have the `getcwd' function. */ +#define HAVE_GETCWD 1 + +/* Define to 1 if you have the `gethrtime' function. */ +/* #undef HAVE_GETHRTIME */ + +/* Define to 1 if you have the `gettimeofday' function. */ +#define HAVE_GETTIMEOFDAY 1 + +/* Define to 1 if you have the `get_cyclecount' function. */ +/* #undef HAVE_GET_CYCLECOUNT */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_GLAUX_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_GLUT_GLUT_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_GLUT_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_GLU_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_GL_GLAUX_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_GL_GLUT_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_GL_GLU_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_GL_GL_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_GL_H */ + +/* Define to 1 if the system has the type `hrtime_t'. */ +/* #undef HAVE_HRTIME_T */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_IEEEFP_H */ + +/* Define to 1 if the system has the type `int32_t'. */ +#define HAVE_INT32_T 1 + +/* Define to 1 if the system has the type `int64_t'. */ +#define HAVE_INT64_T 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_INTRIN_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the `isnan' function. */ +#define HAVE_ISNAN 1 + +/* Define to 1 if you have the `isnanf' function. */ +/* #undef HAVE_ISNANF */ + +/* Define to 1 if you have the fftw3f library */ +/* #undef HAVE_LIBFFTW3F */ + +/* Define to 1 if you have the math library */ +#define HAVE_LIBM 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* Define to 1 if the type `long double' works and has more range or precision + than `double'. */ +#define HAVE_LONG_DOUBLE 1 + +/* Define to 1 if the type `long double' works and has more range or precision + than `double'. */ +#define HAVE_LONG_DOUBLE_WIDER 1 + +/* Define to 1 if the system has the type `long long'. */ +#define HAVE_LONG_LONG 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_MACHINE_CPU_H */ + +/* Define to 1 if you have the `mach_absolute_time' function. */ +#define HAVE_MACH_ABSOLUTE_TIME 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MACH_MACH_TIME_H 1 + +/* Define to 1 if your system has a GNU libc compatible `malloc' function, and + to 0 otherwise. */ +#define HAVE_MALLOC 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_MALLOC_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_MATH_H 1 + +/* Define to 1 if you have the `memalign' function. */ +/* #undef HAVE_MEMALIGN */ + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the `memset' function. */ +#define HAVE_MEMSET 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_MESAGL_GLAUX_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_MESAGL_GLUT_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_MESAGL_GLU_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_MESAGL_GL_H */ + +/* Define to 1 if you have the `microtime' function. */ +/* #undef HAVE_MICROTIME */ + +/* Define to 1 if you have the `munmap' function. */ +#define HAVE_MUNMAP 1 + +/* Define if your C++ compiler supports namespaces */ +#define HAVE_NAMESPACES 1 + +/* Define to 1 if you have the `nanotime' function. */ +/* #undef HAVE_NANOTIME */ + +/* Define to 1 if the system has the type `off64_t'. */ +/* #undef HAVE_OFF64_T */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_OPENGL_GLAUX_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_OPENGL_GLUT_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_OPENGL_GLU_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_OPENGL_GL_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_PMMINTRIN_H 1 + +/* Have pthread */ +#define HAVE_PTHREAD 1 + +/* Define to 1 if the system has the type `ptrdiff_t'. */ +#define HAVE_PTRDIFF_T 1 + +/* Define to 1 if you have the `putenv' function. */ +#define HAVE_PUTENV 1 + +/* Define to 1 if your system has a GNU libc compatible `realloc' function, + and to 0 otherwise. */ +#define HAVE_REALLOC 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SETJMP_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SIGNAL_H 1 + +/* Define to 1 if you have the `sincos' function. */ +/* #undef HAVE_SINCOS */ + +/* Define to 1 if you have the `sincosf' function. */ +/* #undef HAVE_SINCOSF */ + +/* Define to 1 if you have the `sinf' function. */ +#define HAVE_SINF 1 + +/* Define to 1 if you have the `sqrt' function. */ +#define HAVE_SQRT 1 + +/* Define to 1 if the system has the type `ssize_t'. */ +#define HAVE_SSIZE_T 1 + +/* Define to 1 if `stat' has the bug that it succeeds when given the + zero-length file name argument. */ +/* #undef HAVE_STAT_EMPTY_STRING_BUG */ + +/* Define to 1 if stdbool.h conforms to C99. */ +/* #undef HAVE_STDBOOL_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if max is in namespace std:: */ +#define HAVE_STD_MAX 1 + +/* Define to 1 if min is in namespace std:: */ +#define HAVE_STD_MIN 1 + +/* Define to 1 if transform is in namespace std:: */ +#define HAVE_STD_TRANSFORM 1 + +/* Define to 1 if you have the `strcasestr' function. */ +#define HAVE_STRCASESTR 1 + +/* Define to 1 if you have the `strchr' function. */ +#define HAVE_STRCHR 1 + +/* Define to 1 if you have the `strftime' function. */ +#define HAVE_STRFTIME 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the `strstr' function. */ +#define HAVE_STRSTR 1 + +/* Define to 1 if `st_blocks' is member of `struct stat'. */ +#define HAVE_STRUCT_STAT_ST_BLOCKS 1 + +/* Define to 1 if your `struct stat' has `st_blocks'. Deprecated, use + `HAVE_STRUCT_STAT_ST_BLOCKS' instead. */ +#define HAVE_ST_BLOCKS 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_IOCTL_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_PARAM_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STATVFS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_SYSTM_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have that is POSIX.1 compatible. */ +#define HAVE_SYS_WAIT_H 1 + +/* Define to 1 if the system has the type `uint64_t'. */ +#define HAVE_UINT64_T 1 + +/* Define to 1 if the system has the type `uint_fast64_t'. */ +#define HAVE_UINT_FAST64_T 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if the system has the type `u_int64_t'. */ +#define HAVE_U_INT64_T 1 + +/* Define to 1 if you have the `vfork' function. */ +#define HAVE_VFORK 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_VFORK_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_WINDOWS_H */ + +/* Define to 1 if `fork' works. */ +#define HAVE_WORKING_FORK 1 + +/* Define to 1 if `vfork' works. */ +#define HAVE_WORKING_VFORK 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_XMMINTRIN_H 1 + +/* Define to 1 if you have the `_aligned_malloc' function. */ +/* #undef HAVE__ALIGNED_MALLOC */ + +/* Define to 1 if you have the `_alloca' function. */ +/* #undef HAVE__ALLOCA */ + +/* Define to 1 if the system has the type `_Bool'. */ +/* #undef HAVE__BOOL */ + +/* Define to 1 if you have the `_exit' function. */ +#define HAVE__EXIT 1 + +/* Define to 1 if the system has the type `_int32'. */ +/* #undef HAVE__INT32 */ + +/* Define to 1 if the system has the type `_int64'. */ +/* #undef HAVE__INT64 */ + +/* Define to 1 if you have the `_isnan' function. */ +/* #undef HAVE__ISNAN */ + +/* Define to 1 if you have the `_isnanf' function. */ +/* #undef HAVE__ISNANF */ + +/* Define to 1 if the system has the type `_uint64'. */ +/* #undef HAVE__UINT64 */ + +/* Define to 1 if you have the `__builtin_alloca' function. */ +/* #undef HAVE___BUILTIN_ALLOCA */ + +/* Define to 1 if you have the `__isnan' function. */ +#define HAVE___ISNAN 1 + +/* Define to 1 if you have the `__isnanf' function. */ +#define HAVE___ISNANF 1 + +/* Platform identification used to identify applications for this BOINC core + client */ +#define HOSTTYPE "i686-apple-darwin" + +/* Alternate identification used to identify applications for this BOINC core + client */ +/* #undef HOSTTYPEALT */ + +/* "Define to 1 if largefile support causes missing symbols in C++" */ +/* #undef LARGEFILE_BREAKS_CXX */ + +/* Define to 1 if `lstat' dereferences a symlink specified with a trailing + slash. */ +/* #undef LSTAT_FOLLOWS_SLASHED_SYMLINK */ + +/* Define to 1 if `major', `minor', and `makedev' are declared in . + */ +/* #undef MAJOR_IN_MKDEV */ + +/* Define to 1 if `major', `minor', and `makedev' are declared in + . */ +/* #undef MAJOR_IN_SYSMACROS */ + +/* Define to 1 if your C compiler doesn't accept -c and -o together. */ +/* #undef NO_MINUS_C_MINUS_O */ + +/* Name of package */ +#define PACKAGE "setiathome_v7" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "ports@setiathome.ssl.berkeley.edu" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "setiathome_v7" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "setiathome_v7 6.92" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "setiathome_v7" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "6.92" + +/* Define as directory containing the project config.xml */ +#define PROJECTDIR "/BOINC_Mac_SL/seti_boinc" + +/* Define to the necessary symbol if this constant uses a non-standard name on + your system. */ +/* #undef PTHREAD_CREATE_JOINABLE */ + +/* Define to the BOINC application name for setiathome */ +#define SAH_APP_NAME "setiathome_v7" + +/* The size of `long double', as computed by sizeof. */ +#define SIZEOF_LONG_DOUBLE 16 + +/* The size of `long int', as computed by sizeof. */ +#define SIZEOF_LONG_INT 4 + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at runtime. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown */ +/* #undef STACK_DIRECTION */ + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define to be the subversion revision number */ +#define SVN_REV "Revision: 1064" + +/* Define to 1 if your declares `struct tm'. */ +/* #undef TM_IN_SYS_TIME */ + +/* Define to 1 if you want to use 3D-Now optimizations */ +/* #undef USE_3DNOW */ + +/* Define to 1 if you want to use ALTIVEC optimizations */ +/* #undef USE_ALTIVEC */ + +/* Define to 1 to use ASMLIB to determine processor capabilities */ +/* #undef USE_ASMLIB */ + +/* Define to 1 if you want to use the gcc -ffast-math optimization */ +#define USE_FAST_MATH 1 + +/* Define to 1 if informix is installed */ +/* #undef USE_INFORMIX */ + +/* Define to 1 to use SIMD intrinsics rather than inline assembly */ +#define USE_INTRINSICS 1 + +/* "Define to 1 if you want to use the Intel Performance Primitives" */ +/* #undef USE_IPP */ + +/* Define to 1 if you want to use MMX optimizations */ +/* #undef USE_MMX */ + +/* Define if MYSQL is installed */ +/* #undef USE_MYSQL */ + +/* "Define to 1 if you want to use the openssl crypto library" */ +#define USE_OPENSSL 1 + +/* Define to 1 if you want to use SSE optimizations */ +/* #undef USE_SSE */ + +/* Define to 1 if you want to use SSE2 optimizations */ +/* #undef USE_SSE2 */ + +/* Define to 1 if you want to use SSE3 optimizations */ +#define USE_SSE3 1 + +/* Version number of package */ +#define VERSION "6.92" + +/* SETI@home major version number */ +#define VERSION_MAJOR 6 + +/* SETI@home minor version number */ +#define VERSION_MINOR 92 + +/* Define to 1 if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ +/* #undef WORDS_BIGENDIAN */ + +/* Define to 1 if the X Window System is missing or not being used. */ +/* #undef X_DISPLAY_MISSING */ + +/* Number of bits in a file offset, on hosts where this is settable. */ +/* #undef _FILE_OFFSET_BITS */ + +/* Define for large files, on AIX-style hosts. */ +/* #undef _LARGE_FILES */ + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +/* #undef inline */ +#endif + +/* Define to rpl_malloc if the replacement function should be used. */ +/* #undef malloc */ + +/* Define to `long int' if does not define. */ +/* #undef off_t */ + +/* Define to `int' if does not define. */ +/* #undef pid_t */ + +/* Define to rpl_realloc if the replacement function should be used. */ +/* #undef realloc */ + +/* Define to `unsigned int' if does not define. */ +/* #undef size_t */ + +/* Define as `fork' if `vfork' does not work. */ +/* #undef vfork */ + + + +/* Define USE_NAMESPACES if you may access more than one database from the + * same program + */ + +#endif + +/* + * Use fftw if we have the library + */ +#if defined(HAVE_LIBFFTW3F) && defined(HAVE_FFTW3_H) +#define USE_FFTWF +#endif + +#if defined(USE_INFORMIX) && defined(USE_MYSQL) && defined(HAVE_NAMESPACES) +#define USE_NAMESPACES +#endif + +#if !defined(CUSTOM_STRING) && defined(COMPILER_STRING) +#define CUSTOM_STRING PACKAGE_STRING" "SVN_REV" "COMPILER_STRING +#endif + +#include "std_fixes.h" + +#endif + diff --git a/mac_build/config-ppc.h b/mac_build/config-ppc.h new file mode 100644 index 0000000..01ef7b9 --- /dev/null +++ b/mac_build/config-ppc.h @@ -0,0 +1,610 @@ +/* sah_config.h. Generated from sah_config.h.in by configure. */ +/* sah_config.h.in. Generated from configure.ac by autoheader. */ + + +#ifndef _SAH_CONFIG_H_ +#define _SAH_CONFIG_H_ + +#ifdef _WIN32 +#include "win-sah_config.h" +#else + + +/* Define to 1 to build a graphical application */ +#define BOINC_APP_GRAPHICS 1 + +/* Define to a string identifying your compiler */ +#define COMPILER_STRING "i686-apple-darwin10-g++-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5664)" + +/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP + systems. This function is required for `alloca.c' support on those systems. + */ +/* #undef CRAY_STACKSEG_END */ + +/* Define to 1 if using `alloca.c'. */ +/* #undef C_ALLOCA */ + +/* Define to 1 if your system stores words within floats with the most + significant word first */ +#define FLOAT_WORDS_BIGENDIAN 1 + +/* Define to 1 if you have the `alloca' function. */ +#define HAVE_ALLOCA 1 + +/* Define to 1 if you have and it should be used (not on Ultrix). + */ +#define HAVE_ALLOCA_H 1 + +/* Use the Apple OpenGL framework. */ +#define HAVE_APPLE_OPENGL_FRAMEWORK 1 + +/* Define to 1 if you have the `atanf' function. */ +#define HAVE_ATANF 1 + +/* Define to 1 if you have the `atexit' function. */ +#define HAVE_ATEXIT 1 + +/* Define to 1 if you have the `atoll' function. */ +#define HAVE_ATOLL 1 + +/* Define to 1 if the system has the type `bool'. */ +#define HAVE_BOOL 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_COMPLEX_H 1 + +/* Define to 1 if you have the `cosf' function. */ +#define HAVE_COSF 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_DIRENT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_DLFCN_H 1 + +/* Define to 1 if you have the `dlopen' function. */ +#define HAVE_DLOPEN 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_EMMINTRIN_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_ERRNO_H 1 + +/* Define to 1 if you have the `exit' function. */ +#define HAVE_EXIT 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_FFTW3_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_FLOATINGPOINT_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_FLOAT_H 1 + +/* Define to 1 if you have the `floor' function. */ +#define HAVE_FLOOR 1 + +/* Define to 1 if you have the `fork' function. */ +#define HAVE_FORK 1 + +/* Define to 1 if you have the `getcwd' function. */ +#define HAVE_GETCWD 1 + +/* Define to 1 if you have the `gethrtime' function. */ +/* #undef HAVE_GETHRTIME */ + +/* Define to 1 if you have the `gettimeofday' function. */ +#define HAVE_GETTIMEOFDAY 1 + +/* Define to 1 if you have the `get_cyclecount' function. */ +/* #undef HAVE_GET_CYCLECOUNT */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_GLAUX_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_GLUT_GLUT_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_GLUT_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_GLU_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_GL_GLAUX_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_GL_GLUT_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_GL_GLU_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_GL_GL_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_GL_H */ + +/* Define to 1 if the system has the type `hrtime_t'. */ +/* #undef HAVE_HRTIME_T */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_IEEEFP_H */ + +/* Define to 1 if the system has the type `int32_t'. */ +#define HAVE_INT32_T 1 + +/* Define to 1 if the system has the type `int64_t'. */ +#define HAVE_INT64_T 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_INTRIN_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the `isnan' function. */ +#define HAVE_ISNAN 1 + +/* Define to 1 if you have the `isnanf' function. */ +/* #undef HAVE_ISNANF */ + +/* Define to 1 if you have the fftw3f library */ +/* #undef HAVE_LIBFFTW3F */ + +/* Define to 1 if you have the math library */ +#define HAVE_LIBM 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* Define to 1 if the type `long double' works and has more range or precision + than `double'. */ +#define HAVE_LONG_DOUBLE 1 + +/* Define to 1 if the type `long double' works and has more range or precision + than `double'. */ +#define HAVE_LONG_DOUBLE_WIDER 1 + +/* Define to 1 if the system has the type `long long'. */ +#define HAVE_LONG_LONG 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_MACHINE_CPU_H */ + +/* Define to 1 if you have the `mach_absolute_time' function. */ +#define HAVE_MACH_ABSOLUTE_TIME 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MACH_MACH_TIME_H 1 + +/* Define to 1 if your system has a GNU libc compatible `malloc' function, and + to 0 otherwise. */ +#define HAVE_MALLOC 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_MALLOC_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_MATH_H 1 + +/* Define to 1 if you have the `memalign' function. */ +/* #undef HAVE_MEMALIGN */ + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the `memset' function. */ +#define HAVE_MEMSET 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_MESAGL_GLAUX_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_MESAGL_GLUT_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_MESAGL_GLU_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_MESAGL_GL_H */ + +/* Define to 1 if you have the `microtime' function. */ +/* #undef HAVE_MICROTIME */ + +/* Define to 1 if you have the `munmap' function. */ +#define HAVE_MUNMAP 1 + +/* Define if your C++ compiler supports namespaces */ +#define HAVE_NAMESPACES 1 + +/* Define to 1 if you have the `nanotime' function. */ +/* #undef HAVE_NANOTIME */ + +/* Define to 1 if the system has the type `off64_t'. */ +/* #undef HAVE_OFF64_T */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_OPENGL_GLAUX_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_OPENGL_GLUT_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_OPENGL_GLU_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_OPENGL_GL_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_PMMINTRIN_H */ + +/* Have pthread */ +#define HAVE_PTHREAD 1 + +/* Define to 1 if the system has the type `ptrdiff_t'. */ +#define HAVE_PTRDIFF_T 1 + +/* Define to 1 if you have the `putenv' function. */ +#define HAVE_PUTENV 1 + +/* Define to 1 if your system has a GNU libc compatible `realloc' function, + and to 0 otherwise. */ +#define HAVE_REALLOC 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SETJMP_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SIGNAL_H 1 + +/* Define to 1 if you have the `sincos' function. */ +/* #undef HAVE_SINCOS */ + +/* Define to 1 if you have the `sincosf' function. */ +/* #undef HAVE_SINCOSF */ + +/* Define to 1 if you have the `sinf' function. */ +#define HAVE_SINF 1 + +/* Define to 1 if you have the `sqrt' function. */ +#define HAVE_SQRT 1 + +/* Define to 1 if the system has the type `ssize_t'. */ +#define HAVE_SSIZE_T 1 + +/* Define to 1 if `stat' has the bug that it succeeds when given the + zero-length file name argument. */ +/* #undef HAVE_STAT_EMPTY_STRING_BUG */ + +/* Define to 1 if stdbool.h conforms to C99. */ +/* #undef HAVE_STDBOOL_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if max is in namespace std:: */ +#define HAVE_STD_MAX 1 + +/* Define to 1 if min is in namespace std:: */ +#define HAVE_STD_MIN 1 + +/* Define to 1 if transform is in namespace std:: */ +#define HAVE_STD_TRANSFORM 1 + +/* Define to 1 if you have the `strcasestr' function. */ +#define HAVE_STRCASESTR 1 + +/* Define to 1 if you have the `strchr' function. */ +#define HAVE_STRCHR 1 + +/* Define to 1 if you have the `strftime' function. */ +#define HAVE_STRFTIME 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the `strstr' function. */ +#define HAVE_STRSTR 1 + +/* Define to 1 if `st_blocks' is member of `struct stat'. */ +#define HAVE_STRUCT_STAT_ST_BLOCKS 1 + +/* Define to 1 if your `struct stat' has `st_blocks'. Deprecated, use + `HAVE_STRUCT_STAT_ST_BLOCKS' instead. */ +#define HAVE_ST_BLOCKS 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_IOCTL_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_PARAM_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STATVFS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_SYSTM_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have that is POSIX.1 compatible. */ +#define HAVE_SYS_WAIT_H 1 + +/* Define to 1 if the system has the type `uint64_t'. */ +#define HAVE_UINT64_T 1 + +/* Define to 1 if the system has the type `uint_fast64_t'. */ +#define HAVE_UINT_FAST64_T 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if the system has the type `u_int64_t'. */ +#define HAVE_U_INT64_T 1 + +/* Define to 1 if you have the `vfork' function. */ +#define HAVE_VFORK 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_VFORK_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_WINDOWS_H */ + +/* Define to 1 if `fork' works. */ +#define HAVE_WORKING_FORK 1 + +/* Define to 1 if `vfork' works. */ +#define HAVE_WORKING_VFORK 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_XMMINTRIN_H */ + +/* Define to 1 if you have the `_aligned_malloc' function. */ +/* #undef HAVE__ALIGNED_MALLOC */ + +/* Define to 1 if you have the `_alloca' function. */ +/* #undef HAVE__ALLOCA */ + +/* Define to 1 if the system has the type `_Bool'. */ +/* #undef HAVE__BOOL */ + +/* Define to 1 if you have the `_exit' function. */ +#define HAVE__EXIT 1 + +/* Define to 1 if the system has the type `_int32'. */ +/* #undef HAVE__INT32 */ + +/* Define to 1 if the system has the type `_int64'. */ +/* #undef HAVE__INT64 */ + +/* Define to 1 if you have the `_isnan' function. */ +/* #undef HAVE__ISNAN */ + +/* Define to 1 if you have the `_isnanf' function. */ +/* #undef HAVE__ISNANF */ + +/* Define to 1 if the system has the type `_uint64'. */ +/* #undef HAVE__UINT64 */ + +/* Define to 1 if you have the `__builtin_alloca' function. */ +/* #undef HAVE___BUILTIN_ALLOCA */ + +/* Define to 1 if you have the `__isnan' function. */ +#define HAVE___ISNAN 1 + +/* Define to 1 if you have the `__isnanf' function. */ +#define HAVE___ISNANF 1 + +/* Platform identification used to identify applications for this BOINC core + client */ +#define HOSTTYPE "powerpc-apple-darwin" + +/* Alternate identification used to identify applications for this BOINC core + client */ +/* #undef HOSTTYPEALT */ + +/* "Define to 1 if largefile support causes missing symbols in C++" */ +/* #undef LARGEFILE_BREAKS_CXX */ + +/* Define to 1 if `lstat' dereferences a symlink specified with a trailing + slash. */ +/* #undef LSTAT_FOLLOWS_SLASHED_SYMLINK */ + +/* Define to 1 if `major', `minor', and `makedev' are declared in . + */ +/* #undef MAJOR_IN_MKDEV */ + +/* Define to 1 if `major', `minor', and `makedev' are declared in + . */ +/* #undef MAJOR_IN_SYSMACROS */ + +/* Define to 1 if your C compiler doesn't accept -c and -o together. */ +/* #undef NO_MINUS_C_MINUS_O */ + +/* Name of package */ +#define PACKAGE "setiathome_v7" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "ports@setiathome.ssl.berkeley.edu" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "setiathome_v7" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "setiathome_v7 6.92" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "setiathome_v7" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "6.92" + +/* Define as directory containing the project config.xml */ +#define PROJECTDIR "/BOINC_Mac_SL/seti_boinc" + +/* Define to the necessary symbol if this constant uses a non-standard name on + your system. */ +/* #undef PTHREAD_CREATE_JOINABLE */ + +/* Define to the BOINC application name for setiathome */ +#define SAH_APP_NAME "setiathome_v7" + +/* The size of `long double', as computed by sizeof. */ +#define SIZEOF_LONG_DOUBLE 16 + +/* The size of `long int', as computed by sizeof. */ +#define SIZEOF_LONG_INT 4 + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at runtime. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown */ +/* #undef STACK_DIRECTION */ + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define to be the subversion revision number */ +#define SVN_REV "Revision: 1064" + +/* Define to 1 if your declares `struct tm'. */ +/* #undef TM_IN_SYS_TIME */ + +/* Define to 1 if you want to use 3D-Now optimizations */ +/* #undef USE_3DNOW */ + +/* Define to 1 if you want to use ALTIVEC optimizations */ +#define USE_ALTIVEC 1 + +/* Define to 1 to use ASMLIB to determine processor capabilities */ +/* #undef USE_ASMLIB */ + +/* Define to 1 if you want to use the gcc -ffast-math optimization */ +#define USE_FAST_MATH 1 + +/* Define to 1 if informix is installed */ +/* #undef USE_INFORMIX */ + +/* Define to 1 to use SIMD intrinsics rather than inline assembly */ +/* #undef USE_INTRINSICS */ + +/* "Define to 1 if you want to use the Intel Performance Primitives" */ +/* #undef USE_IPP */ + +/* Define to 1 if you want to use MMX optimizations */ +/* #undef USE_MMX */ + +/* Define if MYSQL is installed */ +/* #undef USE_MYSQL */ + +/* "Define to 1 if you want to use the openssl crypto library" */ +#define USE_OPENSSL 1 + +/* Define to 1 if you want to use SSE optimizations */ +/* #undef USE_SSE */ + +/* Define to 1 if you want to use SSE2 optimizations */ +/* #undef USE_SSE2 */ + +/* Define to 1 if you want to use SSE3 optimizations */ +/* #undef USE_SSE3 */ + +/* Version number of package */ +#define VERSION "6.92" + +/* SETI@home major version number */ +#define VERSION_MAJOR 6 + +/* SETI@home minor version number */ +#define VERSION_MINOR 92 + +/* Define to 1 if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ +#define WORDS_BIGENDIAN 1 + +/* Define to 1 if the X Window System is missing or not being used. */ +/* #undef X_DISPLAY_MISSING */ + +/* Number of bits in a file offset, on hosts where this is settable. */ +/* #undef _FILE_OFFSET_BITS */ + +/* Define for large files, on AIX-style hosts. */ +/* #undef _LARGE_FILES */ + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +/* #undef inline */ +#endif + +/* Define to rpl_malloc if the replacement function should be used. */ +/* #undef malloc */ + +/* Define to `long int' if does not define. */ +/* #undef off_t */ + +/* Define to `int' if does not define. */ +/* #undef pid_t */ + +/* Define to rpl_realloc if the replacement function should be used. */ +/* #undef realloc */ + +/* Define to `unsigned int' if does not define. */ +/* #undef size_t */ + +/* Define as `fork' if `vfork' does not work. */ +/* #undef vfork */ + + + +/* Define USE_NAMESPACES if you may access more than one database from the + * same program + */ + +#endif + +/* + * Use fftw if we have the library + */ +#if defined(HAVE_LIBFFTW3F) && defined(HAVE_FFTW3_H) +#define USE_FFTWF +#endif + +#if defined(USE_INFORMIX) && defined(USE_MYSQL) && defined(HAVE_NAMESPACES) +#define USE_NAMESPACES +#endif + +#if !defined(CUSTOM_STRING) && defined(COMPILER_STRING) +#define CUSTOM_STRING PACKAGE_STRING" "SVN_REV" "COMPILER_STRING +#endif + +#include "std_fixes.h" + +#endif + diff --git a/mac_build/makeseticonfigs.sh b/mac_build/makeseticonfigs.sh new file mode 100644 index 0000000..ae8142e --- /dev/null +++ b/mac_build/makeseticonfigs.sh @@ -0,0 +1,102 @@ +#!/bin/sh + +# Berkeley Open Infrastructure for Network Computing +# http://boinc.berkeley.edu +# Copyright (C) 2006 University of California +# +# This is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; +# either version 2.1 of the License, or (at your option) any later version. +# +# This software is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Lesser General Public License for more details. +# +# To view the GNU Lesser General Public License visit +# http://www.gnu.org/copyleft/lesser.html +# or write to the Free Software Foundation, Inc., +# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# +# Script to build PowerPC-specific and Intel-specific config.h files +# for use in building SETI_BOINC. +# +# by Charlie Fenton 9/10/07 +# updated for OS 10.4 SDK and SETI@home v7 on 4/9/11 +# +## In Terminal, CD to the seti_boinc directory. +## cd [path]/seti_boinc/ +## then run this script: +## source [path]/makeseticonfigs.sh path_to_seti_boinc_dir path_to_boinc_dir +# + +if [ $# -ne 2 ]; then + echo "usage sh $0 path_to_seti_boinc_dir path_to_boinc_dir" + exit +fi + +echo " *************************************************" +echo " * *" +echo " * Configuring for i686-apple-darwin *" +echo " * *" +echo " *************************************************" + +cd "$1" +##export PATH=/usr/local/bin:$PATH +export CC=/usr/bin/gcc-4.0;export CXX=/usr/bin/g++-4.0 +export SDKROOT="/Developer/SDKs/MacOSX10.4u.sdk" + +export CFLAGS="-isysroot/Developer/SDKs/MacOSX10.4u.sdk -O3 -isysroot /Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.4 -arch i386" +export CPPFLAGS="-isysroot/Developer/SDKs/MacOSX10.4u.sdk -O3 -isysroot /Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.4 -arch i386" + +export PROJECTDIR="$1" +export BOINCDIR="$2" +./_autosetup --host=i686-apple-darwin + + +if [ $? -ne 0 ]; then + exit +fi + +./configure -C --disable-server --enable-fast-math --enable-sse3 --with-apple-opengl-framework --disable-dynamic-graphics --host=i686-apple-darwin + +if [ $? -ne 0 ]; then + exit +fi + +mv ./sah_config.h ./mac_build/config-i386.h + + +echo " *************************************************" +echo " * *" +echo " * Configuring for powerpc-apple-darwin *" +echo " * *" +echo " *************************************************" + +cd "$1" +##export PATH=/usr/local/bin:$PATH +export CC=/usr/bin/gcc-4.0;export CXX=/usr/bin/g++-4.0 +export SDKROOT="/Developer/SDKs/MacOSX10.4u.sdk" + +export CFLAGS="-isysroot/Developer/SDKs/MacOSX10.4u.sdk -O3 -arch ppc -D_THREAD_SAFE -mmacosx-version-min=10.4" +export CPPFLAGS="-isysroot/Developer/SDKs/MacOSX10.4u.sdk -O3 -arch ppc -D_THREAD_SAFE -mmacosx-version-min=10.4" + +export PROJECTDIR="$1" +export BOINCDIR="$2" +./_autosetup --host=powerpc-apple-darwin + +if [ $? -ne 0 ]; then + exit +fi + +./configure --disable-server --enable-fast-math --enable-altivec --with-apple-opengl-framework --disable-dynamic-graphics --host=powerpc-apple-darwin + +if [ $? -ne 0 ]; then + exit +fi + +mv ./sah_config.h ./mac_build/config-ppc.h + + diff --git a/mac_build/sah_config.h b/mac_build/sah_config.h new file mode 100644 index 0000000..3e52c63 --- /dev/null +++ b/mac_build/sah_config.h @@ -0,0 +1,125 @@ +// Copyright 2006 Regents of the University of California + +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +// This file contains compile time configuration parameters +// for the seti@home reference algorithm implementation. + +/* Special config.h file for Macintosh */ + + +/************************************** IMPORTANT INSTRUCTIONS: **************************** + + Build the config-i386.h and config-ppc.h in the seti_boinc/mac_build/ directory by + running the shell script: + sh [path]makeseticonfigs.sh path_to_seti_boinc_dir path_to_boinc_dir + +*********************************************************************************************/ + +/******************* Additional Compiler Flags for Individual Source Files ******************* + +These are set up in the XCode project itself: + +client/vector/analyzeFuncs_altivec.cpp: + on PowerPC, add the GCC command line options "-DUSE_ALTIVEC -faltivec" + +client/vector/analyzeFuncs_vector.cpp + on PowerPC, add the GCC command line options "-DUSE_ALTIVEC" + on Intel, add the GCC command line options "-DUSE_SSE -DUSE_SSE2 -DUSE_SSE3" + +client/vector/analyzeFuncs_sse.cpp + on Intel add the GCC command line options "-DUSE_SSE -msse" + +client/vector/analyzeFuncs_sse2.cpp + on Intel add the GCC command line options "-DUSE_SSE -DUSE_SSE2 -msse2" + +client/vector/analyzeFuncs_sse3.cpp + on Intel add the GCC command line options "-DUSE_SSE -DUSE_SSE2 +-DUSE_SSE3 -msse3" + +client/vector/analyzeFuncs_x86_64.cpp + on Intel, add the GCC command line options -DUSE_SSE -msse2 -mfpmath=sse" + +client/vector/x86_float4.cpp + on Intel, add the GCC command line options "-DUSE_SSE -msse" +*********************************************************************************************/ + +#ifndef _SAH_MAC_CONFIG_H_ +#define _SAH_MAC_CONFIG_H_ + +#ifndef __APPLE_CC__ +#error Wrong sah_config.h file! +#endif + +#include "version.h" // Get BOINC_VERSION_STRING (BOINC library version) + +#undef PACKAGE_STRING +#undef PACKAGE +#undef PACKAGE_NAME +#undef PACKAGE_BUGREPORT +#undef PACKAGE_TARNAME +#undef PACKAGE_VERSION +#undef VERSION + + +#ifdef __i386__ // Intel + +#include "config-i386.h" + +#undef COMPILER_STRING +#define COMPILER_STRING "XCode GCC " __VERSION__ " i386" + +#else // PowerPC + +// Won't compile unless we define HAVE_STD_MAX, HAVE_STD_MIN and HAVE_STD_TRANSFORM +#define HAVE_STD_MAX 1 // Override the autoconfig setting for Mac PowerPC builds +#define HAVE_STD_MIN 1 // Override the autoconfig setting for Mac PowerPC builds +#define HAVE_STD_TRANSFORM 1 // Override the autoconfig setting for Mac PowerPC builds + +#include "config-ppc.h" + +#undef COMPILER_STRING +#define COMPILER_STRING "XCode GCC " __VERSION__ " ppc" + +// The following three were #undefined in previous versions, though only +// HAVE_ATANF is actually necessary for OS 10.3.0 compatibility +#undef HAVE_ATANF // OS 10.3.0 does not have atanf +#undef HAVE_COSF +#undef HAVE_SINF + +#endif + +// Overrides for both Intel and PowerPC Macs +#ifndef USE_FFTWF +#define USE_FFTWF +#endif + +#undef CUSTOM_STRING +//#if !defined(CUSTOM_STRING) && defined(COMPILER_STRING) +#define CUSTOM_STRING PACKAGE_STRING " " COMPILER_STRING "\n\nlibboinc: " BOINC_VERSION_STRING +//#endif + +#endif /* _SAH_MAC_CONFIG_H */ diff --git a/mac_build/seti_boinc.xcodeproj/project.pbxproj b/mac_build/seti_boinc.xcodeproj/project.pbxproj new file mode 100644 index 0000000..8527c4b --- /dev/null +++ b/mac_build/seti_boinc.xcodeproj/project.pbxproj @@ -0,0 +1,1478 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 42; + objects = { + +/* Begin PBXAggregateTarget section */ + DDC969040D09674F00A480B2 /* Build-All */ = { + isa = PBXAggregateTarget; + buildConfigurationList = DDC969140D0967AE00A480B2 /* Build configuration list for PBXAggregateTarget "Build-All" */; + buildPhases = ( + ); + dependencies = ( + DDC969080D09676700A480B2 /* PBXTargetDependency */, + DDC9690A0D09676700A480B2 /* PBXTargetDependency */, + DDC9690C0D09676700A480B2 /* PBXTargetDependency */, + DDC9690E0D09676700A480B2 /* PBXTargetDependency */, + ); + name = "Build-All"; + productName = "Build-All"; + }; +/* End PBXAggregateTarget section */ + +/* Begin PBXBuildFile section */ + DD10AF2C0D09363D000227CC /* sah_gfx_base.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5AB5707D15FB000318A98 /* sah_gfx_base.cpp */; }; + DD10AF320D09363D000227CC /* timecvt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5AB7407D15FCD00318A98 /* timecvt.cpp */; }; + DD10AF430D09363D000227CC /* GLUT.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DDA5AB8E07D161A700318A98 /* GLUT.framework */; }; + DD10AF440D09363D000227CC /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DDA5AB8F07D161A700318A98 /* OpenGL.framework */; }; + DD10AF450D09363D000227CC /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD6D832C081320B9008F7200 /* AppKit.framework */; }; + DD10AF460D09363D000227CC /* libboinc_api.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DD9476000A6F684000834371 /* libboinc_api.a */; }; + DD10AF480D09363D000227CC /* libboinc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DD9476020A6F684000834371 /* libboinc.a */; }; + DD10AF490D09363D000227CC /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DDED51610A8010CC00699E63 /* Accelerate.framework */; }; + DD10AF710D093949000227CC /* libboinc_graphics2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DD10AF700D093949000227CC /* libboinc_graphics2.a */; }; + DD10AF750D093995000227CC /* sah_gfx_main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD10AF5F0D093830000227CC /* sah_gfx_main.cpp */; }; + DD10AF850D093BBF000227CC /* graphics_main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD10AF840D093BBF000227CC /* graphics_main.cpp */; }; + DD10AF880D093C21000227CC /* sah_gfx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5AB5207D15FB000318A98 /* sah_gfx.cpp */; }; + DD10B0830D095113000227CC /* sah_gfx_main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD10AF5F0D093830000227CC /* sah_gfx_main.cpp */; }; + DD10B0AA0D0951CC000227CC /* GLUT.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DDA5AB8E07D161A700318A98 /* GLUT.framework */; }; + DD10B0AB0D0951CC000227CC /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DDA5AB8F07D161A700318A98 /* OpenGL.framework */; }; + DD10B0AC0D0951CC000227CC /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD6D832C081320B9008F7200 /* AppKit.framework */; }; + DD10B0AD0D0951CC000227CC /* libboinc_api.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DD9476000A6F684000834371 /* libboinc_api.a */; }; + DD10B0AF0D0951CC000227CC /* libboinc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DD9476020A6F684000834371 /* libboinc.a */; }; + DD10B0B00D0951CC000227CC /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DDED51610A8010CC00699E63 /* Accelerate.framework */; }; + DD10B0BA0D095255000227CC /* graphics_main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD10AF840D093BBF000227CC /* graphics_main.cpp */; }; + DD10B0BB0D09525A000227CC /* sah_gfx_base.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5AB5707D15FB000318A98 /* sah_gfx_base.cpp */; }; + DD10B0BC0D09525A000227CC /* sah_gfx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5AB5207D15FB000318A98 /* sah_gfx.cpp */; }; + DD10B0BD0D09526A000227CC /* timecvt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5AB7407D15FCD00318A98 /* timecvt.cpp */; }; + DD10B0BE0D095293000227CC /* libboinc_graphics2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DD10AF700D093949000227CC /* libboinc_graphics2.a */; }; + DD10B0C70D09533D000227CC /* sqlblob.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5ABBD07D16BC100318A98 /* sqlblob.cpp */; }; + DD10B0C90D095344000227CC /* sqlrow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5ABBF07D16BC100318A98 /* sqlrow.cpp */; }; + DD10B0CB0D09534A000227CC /* schema_master.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5ABB807D16B7F00318A98 /* schema_master.cpp */; }; + DD10B0CD0D095350000227CC /* xml_util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5ABED07D16D1300318A98 /* xml_util.cpp */; }; + DD10B0D10D09538D000227CC /* libboinc_graphics2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DD10AF700D093949000227CC /* libboinc_graphics2.a */; }; + DD10B0D40D095402000227CC /* libboinc_graphics2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DD10AF700D093949000227CC /* libboinc_graphics2.a */; }; + DD2A2C890C5604C700D9D34F /* x86_float4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD2A2C870C5604C700D9D34F /* x86_float4.cpp */; settings = {COMPILER_FLAGS = "-DUSE_SSE -msse"; }; }; + DD2A2D050C5607D500D9D34F /* analyzePoT.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5AB2907D15F8D00318A98 /* analyzePoT.cpp */; }; + DD2A2D060C5607D500D9D34F /* chirpfft.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5AB2A07D15F8D00318A98 /* chirpfft.cpp */; }; + DD2A2D070C5607D500D9D34F /* analyzeFuncs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5AB2F07D15F8D00318A98 /* analyzeFuncs.cpp */; }; + DD2A2D080C5607D500D9D34F /* analyzeReport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5AB3107D15F8D00318A98 /* analyzeReport.cpp */; }; + DD2A2D090C5607D500D9D34F /* lcgamm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5AB3E07D15F9700318A98 /* lcgamm.cpp */; }; + DD2A2D0A0C5607D500D9D34F /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5AB3F07D15F9700318A98 /* main.cpp */; }; + DD2A2D0B0C5607D500D9D34F /* gdata.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5AB4107D15F9700318A98 /* gdata.cpp */; }; + DD2A2D0C0C5607D500D9D34F /* fft8g.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5AB4207D15F9700318A98 /* fft8g.cpp */; }; + DD2A2D0D0C5607D500D9D34F /* gaussfit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5AB4307D15F9700318A98 /* gaussfit.cpp */; }; + DD2A2D0F0C5607D500D9D34F /* malloc_a.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5AB5407D15FB000318A98 /* malloc_a.cpp */; }; + DD2A2D100C5607D500D9D34F /* s_util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5AB5607D15FB000318A98 /* s_util.cpp */; }; + DD2A2D120C5607D500D9D34F /* pulsefind.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5AB5907D15FB000318A98 /* pulsefind.cpp */; }; + DD2A2D130C5607D500D9D34F /* progress.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5AB5B07D15FB000318A98 /* progress.cpp */; }; + DD2A2D140C5607D500D9D34F /* seti_header.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5AB6907D15FBE00318A98 /* seti_header.cpp */; }; + DD2A2D150C5607D500D9D34F /* seti.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5AB6B07D15FBE00318A98 /* seti.cpp */; }; + DD2A2D160C5607D500D9D34F /* spike.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5AB7107D15FC400318A98 /* spike.cpp */; }; + DD2A2D180C5607D500D9D34F /* sah_version.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5AB7607D15FCD00318A98 /* sah_version.cpp */; }; + DD2A2D190C5607D500D9D34F /* worker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5AB7C07D15FD800318A98 /* worker.cpp */; }; + DD2A2D1A0C5607D500D9D34F /* schema_master.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5ABB807D16B7F00318A98 /* schema_master.cpp */; }; + DD2A2D1B0C5607D500D9D34F /* sqlblob.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5ABBD07D16BC100318A98 /* sqlblob.cpp */; }; + DD2A2D1C0C5607D500D9D34F /* sqlrow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5ABBF07D16BC100318A98 /* sqlrow.cpp */; }; + DD2A2D1D0C5607D500D9D34F /* xml_util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5ABED07D16D1300318A98 /* xml_util.cpp */; }; + DD2A2D1E0C5607D500D9D34F /* analyzeFuncs_altivec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDB3D9CE0A6F883F002ADFC6 /* analyzeFuncs_altivec.cpp */; settings = {COMPILER_FLAGS = "-DUSE_ALTIVEC -faltivec"; }; }; + DD2A2D1F0C5607D500D9D34F /* analyzeFuncs_vector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDB3D9CF0A6F883F002ADFC6 /* analyzeFuncs_vector.cpp */; settings = {COMPILER_FLAGS = "-DUSE_ALTIVEC"; }; }; + DD2A2D200C5607D500D9D34F /* analyzeFuncs_x86_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDB3D9D10A6F883F002ADFC6 /* analyzeFuncs_x86_64.cpp */; }; + DD2A2D210C5607D500D9D34F /* hires_timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDB3D9D20A6F883F002ADFC6 /* hires_timer.cpp */; }; + DD2A2D220C5607D500D9D34F /* analyzeFuncs_fpu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD5F15B80C5218A600CA453D /* analyzeFuncs_fpu.cpp */; }; + DD2A2D230C5607D500D9D34F /* analyzeFuncs_sse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD5F15BA0C5218A600CA453D /* analyzeFuncs_sse.cpp */; }; + DD2A2D240C5607D500D9D34F /* analyzeFuncs_sse2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD5F15BB0C5218A600CA453D /* analyzeFuncs_sse2.cpp */; }; + DD2A2D250C5607D500D9D34F /* analyzeFuncs_sse3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD5F15BC0C5218A600CA453D /* analyzeFuncs_sse3.cpp */; }; + DD2A2D260C5607D500D9D34F /* x86_float4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD2A2C870C5604C700D9D34F /* x86_float4.cpp */; }; + DD2A2D280C5607D500D9D34F /* GLUT.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DDA5AB8E07D161A700318A98 /* GLUT.framework */; }; + DD2A2D290C5607D500D9D34F /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DDA5AB8F07D161A700318A98 /* OpenGL.framework */; }; + DD2A2D2A0C5607D500D9D34F /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD6D832C081320B9008F7200 /* AppKit.framework */; }; + DD2A2D2B0C5607D500D9D34F /* libboinc_api.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DD9476000A6F684000834371 /* libboinc_api.a */; }; + DD2A2D2D0C5607D500D9D34F /* libboinc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DD9476020A6F684000834371 /* libboinc.a */; }; + DD2A2D2E0C5607D500D9D34F /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DDED51610A8010CC00699E63 /* Accelerate.framework */; }; + DD5F15BD0C5218A600CA453D /* analyzeFuncs_fpu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD5F15B80C5218A600CA453D /* analyzeFuncs_fpu.cpp */; }; + DD5F15BF0C5218A600CA453D /* analyzeFuncs_sse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD5F15BA0C5218A600CA453D /* analyzeFuncs_sse.cpp */; settings = {COMPILER_FLAGS = "-DUSE_SSE -msse"; }; }; + DD5F15C00C5218A600CA453D /* analyzeFuncs_sse2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD5F15BB0C5218A600CA453D /* analyzeFuncs_sse2.cpp */; settings = {COMPILER_FLAGS = "-DUSE_SSE -DUSE_SSE2 -msse2"; }; }; + DD5F15C10C5218A600CA453D /* analyzeFuncs_sse3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD5F15BC0C5218A600CA453D /* analyzeFuncs_sse3.cpp */; settings = {COMPILER_FLAGS = "-DUSE_SSE -DUSE_SSE2 -DUSE_SSE3 -msse3"; }; }; + DD6D832D081320B9008F7200 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD6D832C081320B9008F7200 /* AppKit.framework */; }; + DD8DA299135087EF007C873C /* autocorr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD8DA298135087EF007C873C /* autocorr.cpp */; }; + DD8DA29A135087EF007C873C /* autocorr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD8DA298135087EF007C873C /* autocorr.cpp */; }; + DD9476030A6F684000834371 /* libboinc_api.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DD9476000A6F684000834371 /* libboinc_api.a */; }; + DD9476050A6F684000834371 /* libboinc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DD9476020A6F684000834371 /* libboinc.a */; }; + DDA5AB3407D15F8D00318A98 /* analyzePoT.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5AB2907D15F8D00318A98 /* analyzePoT.cpp */; }; + DDA5AB3507D15F8D00318A98 /* chirpfft.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5AB2A07D15F8D00318A98 /* chirpfft.cpp */; }; + DDA5AB3A07D15F8D00318A98 /* analyzeFuncs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5AB2F07D15F8D00318A98 /* analyzeFuncs.cpp */; }; + DDA5AB3C07D15F8D00318A98 /* analyzeReport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5AB3107D15F8D00318A98 /* analyzeReport.cpp */; }; + DDA5AB4707D15F9700318A98 /* lcgamm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5AB3E07D15F9700318A98 /* lcgamm.cpp */; }; + DDA5AB4807D15F9700318A98 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5AB3F07D15F9700318A98 /* main.cpp */; }; + DDA5AB4A07D15F9700318A98 /* gdata.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5AB4107D15F9700318A98 /* gdata.cpp */; }; + DDA5AB4B07D15F9700318A98 /* fft8g.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5AB4207D15F9700318A98 /* fft8g.cpp */; }; + DDA5AB4C07D15F9700318A98 /* gaussfit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5AB4307D15F9700318A98 /* gaussfit.cpp */; }; + DDA5AB6007D15FB000318A98 /* malloc_a.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5AB5407D15FB000318A98 /* malloc_a.cpp */; }; + DDA5AB6207D15FB000318A98 /* s_util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5AB5607D15FB000318A98 /* s_util.cpp */; }; + DDA5AB6507D15FB000318A98 /* pulsefind.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5AB5907D15FB000318A98 /* pulsefind.cpp */; }; + DDA5AB6707D15FB000318A98 /* progress.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5AB5B07D15FB000318A98 /* progress.cpp */; }; + DDA5AB6D07D15FBE00318A98 /* seti_header.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5AB6907D15FBE00318A98 /* seti_header.cpp */; }; + DDA5AB6F07D15FBE00318A98 /* seti.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5AB6B07D15FBE00318A98 /* seti.cpp */; }; + DDA5AB7307D15FC400318A98 /* spike.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5AB7107D15FC400318A98 /* spike.cpp */; }; + DDA5AB7A07D15FCD00318A98 /* sah_version.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5AB7607D15FCD00318A98 /* sah_version.cpp */; }; + DDA5AB7E07D15FD800318A98 /* worker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA5AB7C07D15FD800318A98 /* worker.cpp */; }; + DDA5AB9007D161A700318A98 /* GLUT.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DDA5AB8E07D161A700318A98 /* GLUT.framework */; }; + DDA5AB9107D161A700318A98 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DDA5AB8F07D161A700318A98 /* OpenGL.framework */; }; + DDB3D9D50A6F883F002ADFC6 /* analyzeFuncs_altivec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDB3D9CE0A6F883F002ADFC6 /* analyzeFuncs_altivec.cpp */; }; + DDB3D9D60A6F883F002ADFC6 /* analyzeFuncs_vector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDB3D9CF0A6F883F002ADFC6 /* analyzeFuncs_vector.cpp */; settings = {COMPILER_FLAGS = "-DUSE_SSE -DUSE_SSE2 -DUSE_SSE3"; }; }; + DDB3D9D80A6F883F002ADFC6 /* analyzeFuncs_x86_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDB3D9D10A6F883F002ADFC6 /* analyzeFuncs_x86_64.cpp */; settings = {COMPILER_FLAGS = "-DUSE_SSE -msse2 -mfpmath=sse"; }; }; + DDB3D9D90A6F883F002ADFC6 /* hires_timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDB3D9D20A6F883F002ADFC6 /* hires_timer.cpp */; }; + DDED51620A8010CC00699E63 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DDED51610A8010CC00699E63 /* Accelerate.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXBuildRule section */ + DD10AF4A0D09363D000227CC /* PBXBuildRule */ = { + isa = PBXBuildRule; + compilerSpec = com.apple.compilers.gcc.3_3; + fileType = sourcecode.cpp; + isEditable = 1; + outputFiles = ( + ); + }; + DD10AF4B0D09363D000227CC /* PBXBuildRule */ = { + isa = PBXBuildRule; + compilerSpec = com.apple.compilers.gcc.3_3; + fileType = sourcecode.c; + isEditable = 1; + outputFiles = ( + ); + }; + DD10AF4C0D09363D000227CC /* PBXBuildRule */ = { + isa = PBXBuildRule; + compilerSpec = com.apple.compilers.gcc.3_3; + fileType = sourcecode.asm; + isEditable = 1; + outputFiles = ( + ); + }; + DD10B0B20D0951CC000227CC /* PBXBuildRule */ = { + isa = PBXBuildRule; + compilerSpec = com.apple.compilers.gcc.3_3; + fileType = sourcecode.cpp; + isEditable = 1; + outputFiles = ( + ); + }; + DD10B0B30D0951CC000227CC /* PBXBuildRule */ = { + isa = PBXBuildRule; + compilerSpec = com.apple.compilers.gcc.3_3; + fileType = sourcecode.c; + isEditable = 1; + outputFiles = ( + ); + }; + DD10B0B40D0951CC000227CC /* PBXBuildRule */ = { + isa = PBXBuildRule; + compilerSpec = com.apple.compilers.gcc.3_3; + fileType = sourcecode.asm; + isEditable = 1; + outputFiles = ( + ); + }; + DD1FF02A08698A37004F0593 /* PBXBuildRule */ = { + isa = PBXBuildRule; + compilerSpec = com.apple.compilers.gcc.3_3; + fileType = sourcecode.c; + isEditable = 1; + outputFiles = ( + ); + }; + DD1FF02B08698A37004F0593 /* PBXBuildRule */ = { + isa = PBXBuildRule; + compilerSpec = com.apple.compilers.gcc.3_3; + fileType = sourcecode.cpp; + isEditable = 1; + outputFiles = ( + ); + }; + DD2A2D2F0C5607D500D9D34F /* PBXBuildRule */ = { + isa = PBXBuildRule; + compilerSpec = com.apple.compilers.gcc.3_3; + fileType = sourcecode.cpp; + isEditable = 1; + outputFiles = ( + ); + }; + DD2A2D300C5607D500D9D34F /* PBXBuildRule */ = { + isa = PBXBuildRule; + compilerSpec = com.apple.compilers.gcc.3_3; + fileType = sourcecode.c; + isEditable = 1; + outputFiles = ( + ); + }; + DD2A2D310C5607D500D9D34F /* PBXBuildRule */ = { + isa = PBXBuildRule; + compilerSpec = com.apple.compilers.gcc.3_3; + fileType = sourcecode.asm; + isEditable = 1; + outputFiles = ( + ); + }; + DD30E12C08CB006300436BE4 /* PBXBuildRule */ = { + isa = PBXBuildRule; + compilerSpec = com.apple.compilers.gcc.3_3; + fileType = sourcecode.asm; + isEditable = 1; + outputFiles = ( + ); + }; +/* End PBXBuildRule section */ + +/* Begin PBXContainerItemProxy section */ + DDC969070D09676700A480B2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8DD76F620486A84900D96B5E; + remoteInfo = seti_boinc_i386; + }; + DDC969090D09676700A480B2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DD2A2D020C5607D500D9D34F; + remoteInfo = seti_boinc_ppc; + }; + DDC9690B0D09676700A480B2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DD10AF1D0D09363D000227CC; + remoteInfo = seti_gfx_i386; + }; + DDC9690D0D09676700A480B2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DD10B0870D0951CC000227CC; + remoteInfo = seti_gfx_ppc; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 0249A663FF388D9811CA2CEA /* libstdc++.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libstdc++.a"; path = "/usr/lib/libstdc++.a"; sourceTree = ""; }; + 8DD76F6C0486A84900D96B5E /* seti_boinc_i386 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = seti_boinc_i386; sourceTree = BUILT_PRODUCTS_DIR; }; + DD10AF500D09363D000227CC /* seti_graphics_i386 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = seti_graphics_i386; sourceTree = BUILT_PRODUCTS_DIR; }; + DD10AF5F0D093830000227CC /* sah_gfx_main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = sah_gfx_main.cpp; path = ../client/sah_gfx_main.cpp; sourceTree = SOURCE_ROOT; }; + DD10AF610D09383E000227CC /* sah_gfx_main.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sah_gfx_main.h; path = ../client/sah_gfx_main.h; sourceTree = SOURCE_ROOT; }; + DD10AF700D093949000227CC /* libboinc_graphics2.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libboinc_graphics2.a; path = ../../_boinc_head_SL/mac_build/build/Deployment/libboinc_graphics2.a; sourceTree = SOURCE_ROOT; }; + DD10AF840D093BBF000227CC /* graphics_main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = graphics_main.cpp; path = ../client/graphics_main.cpp; sourceTree = SOURCE_ROOT; }; + DD10B0B80D0951CC000227CC /* seti_graphics_ppc */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = seti_graphics_ppc; sourceTree = BUILT_PRODUCTS_DIR; }; + DD2A2C870C5604C700D9D34F /* x86_float4.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = x86_float4.cpp; path = ../client/vector/x86_float4.cpp; sourceTree = SOURCE_ROOT; }; + DD2A2C880C5604C700D9D34F /* x86_float4.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = x86_float4.h; path = ../client/vector/x86_float4.h; sourceTree = SOURCE_ROOT; }; + DD2A2D360C5607D500D9D34F /* seti_boinc_ppc */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = seti_boinc_ppc; sourceTree = BUILT_PRODUCTS_DIR; }; + DD5F15B80C5218A600CA453D /* analyzeFuncs_fpu.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = analyzeFuncs_fpu.cpp; path = ../client/vector/analyzeFuncs_fpu.cpp; sourceTree = SOURCE_ROOT; }; + DD5F15BA0C5218A600CA453D /* analyzeFuncs_sse.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = analyzeFuncs_sse.cpp; path = ../client/vector/analyzeFuncs_sse.cpp; sourceTree = SOURCE_ROOT; }; + DD5F15BB0C5218A600CA453D /* analyzeFuncs_sse2.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = analyzeFuncs_sse2.cpp; path = ../client/vector/analyzeFuncs_sse2.cpp; sourceTree = SOURCE_ROOT; }; + DD5F15BC0C5218A600CA453D /* analyzeFuncs_sse3.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = analyzeFuncs_sse3.cpp; path = ../client/vector/analyzeFuncs_sse3.cpp; sourceTree = SOURCE_ROOT; }; + DD6D832C081320B9008F7200 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; + DD8BB3AB0A1004390079F5C1 /* app_icon.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = app_icon.h; path = ../client/app_icon.h; sourceTree = SOURCE_ROOT; }; + DD8DA298135087EF007C873C /* autocorr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = autocorr.cpp; path = ../client/autocorr.cpp; sourceTree = SOURCE_ROOT; }; + DD8DA29B13508806007C873C /* autocorr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = autocorr.h; path = ../client/autocorr.h; sourceTree = SOURCE_ROOT; }; + DD9476000A6F684000834371 /* libboinc_api.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libboinc_api.a; path = ../../boinc/mac_build/build/Deployment/libboinc_api.a; sourceTree = SOURCE_ROOT; }; + DD9476020A6F684000834371 /* libboinc.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libboinc.a; path = ../../boinc/mac_build/build/Deployment/libboinc.a; sourceTree = SOURCE_ROOT; }; + DDA5AB2907D15F8D00318A98 /* analyzePoT.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = analyzePoT.cpp; path = ../client/analyzePoT.cpp; sourceTree = SOURCE_ROOT; }; + DDA5AB2A07D15F8D00318A98 /* chirpfft.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = chirpfft.cpp; path = ../client/chirpfft.cpp; sourceTree = SOURCE_ROOT; }; + DDA5AB2B07D15F8D00318A98 /* analyzeReport.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = analyzeReport.h; path = ../client/analyzeReport.h; sourceTree = SOURCE_ROOT; }; + DDA5AB2C07D15F8D00318A98 /* analyzePoT.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = analyzePoT.h; path = ../client/analyzePoT.h; sourceTree = SOURCE_ROOT; }; + DDA5AB2D07D15F8D00318A98 /* chirpfft.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = chirpfft.h; path = ../client/chirpfft.h; sourceTree = SOURCE_ROOT; }; + DDA5AB2F07D15F8D00318A98 /* analyzeFuncs.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = analyzeFuncs.cpp; path = ../client/analyzeFuncs.cpp; sourceTree = SOURCE_ROOT; }; + DDA5AB3007D15F8D00318A98 /* analyzeFuncs.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = analyzeFuncs.h; path = ../client/analyzeFuncs.h; sourceTree = SOURCE_ROOT; }; + DDA5AB3107D15F8D00318A98 /* analyzeReport.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = analyzeReport.cpp; path = ../client/analyzeReport.cpp; sourceTree = SOURCE_ROOT; }; + DDA5AB3207D15F8D00318A98 /* analyze.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = analyze.h; path = ../client/analyze.h; sourceTree = SOURCE_ROOT; }; + DDA5AB3E07D15F9700318A98 /* lcgamm.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = lcgamm.cpp; path = ../client/lcgamm.cpp; sourceTree = SOURCE_ROOT; }; + DDA5AB3F07D15F9700318A98 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = main.cpp; path = ../client/main.cpp; sourceTree = SOURCE_ROOT; }; + DDA5AB4007D15F9700318A98 /* gaussfit.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = gaussfit.h; path = ../client/gaussfit.h; sourceTree = SOURCE_ROOT; }; + DDA5AB4107D15F9700318A98 /* gdata.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = gdata.cpp; path = ../client/gdata.cpp; sourceTree = SOURCE_ROOT; }; + DDA5AB4207D15F9700318A98 /* fft8g.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = fft8g.cpp; path = ../client/fft8g.cpp; sourceTree = SOURCE_ROOT; }; + DDA5AB4307D15F9700318A98 /* gaussfit.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = gaussfit.cpp; path = ../client/gaussfit.cpp; sourceTree = SOURCE_ROOT; }; + DDA5AB4407D15F9700318A98 /* gdata.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = gdata.h; path = ../client/gdata.h; sourceTree = SOURCE_ROOT; }; + DDA5AB4507D15F9700318A98 /* lcgamm.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = lcgamm.h; path = ../client/lcgamm.h; sourceTree = SOURCE_ROOT; }; + DDA5AB4607D15F9700318A98 /* fft8g.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = fft8g.h; path = ../client/fft8g.h; sourceTree = SOURCE_ROOT; }; + DDA5AB5007D15FB000318A98 /* sah_gfx_base.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = sah_gfx_base.h; path = ../client/sah_gfx_base.h; sourceTree = SOURCE_ROOT; }; + DDA5AB5107D15FB000318A98 /* sah_gfx.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = sah_gfx.h; path = ../client/sah_gfx.h; sourceTree = SOURCE_ROOT; }; + DDA5AB5207D15FB000318A98 /* sah_gfx.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = sah_gfx.cpp; path = ../client/sah_gfx.cpp; sourceTree = SOURCE_ROOT; }; + DDA5AB5307D15FB000318A98 /* malloc_a.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = malloc_a.h; path = ../client/malloc_a.h; sourceTree = SOURCE_ROOT; }; + DDA5AB5407D15FB000318A98 /* malloc_a.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = malloc_a.cpp; path = ../client/malloc_a.cpp; sourceTree = SOURCE_ROOT; }; + DDA5AB5507D15FB000318A98 /* s_util.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = s_util.h; path = ../client/s_util.h; sourceTree = SOURCE_ROOT; }; + DDA5AB5607D15FB000318A98 /* s_util.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = s_util.cpp; path = ../client/s_util.cpp; sourceTree = SOURCE_ROOT; }; + DDA5AB5707D15FB000318A98 /* sah_gfx_base.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = sah_gfx_base.cpp; path = ../client/sah_gfx_base.cpp; sourceTree = SOURCE_ROOT; }; + DDA5AB5807D15FB000318A98 /* pulsefind.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = pulsefind.h; path = ../client/pulsefind.h; sourceTree = SOURCE_ROOT; }; + DDA5AB5907D15FB000318A98 /* pulsefind.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = pulsefind.cpp; path = ../client/pulsefind.cpp; sourceTree = SOURCE_ROOT; }; + DDA5AB5A07D15FB000318A98 /* progress.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = progress.h; path = ../client/progress.h; sourceTree = SOURCE_ROOT; }; + DDA5AB5B07D15FB000318A98 /* progress.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = progress.cpp; path = ../client/progress.cpp; sourceTree = SOURCE_ROOT; }; + DDA5AB6807D15FBE00318A98 /* seti_header.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = seti_header.h; path = ../client/seti_header.h; sourceTree = SOURCE_ROOT; }; + DDA5AB6907D15FBE00318A98 /* seti_header.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = seti_header.cpp; path = ../client/seti_header.cpp; sourceTree = SOURCE_ROOT; }; + DDA5AB6A07D15FBE00318A98 /* seti.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = seti.h; path = ../client/seti.h; sourceTree = SOURCE_ROOT; }; + DDA5AB6B07D15FBE00318A98 /* seti.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = seti.cpp; path = ../client/seti.cpp; sourceTree = SOURCE_ROOT; }; + DDA5AB7007D15FC400318A98 /* spike.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = spike.h; path = ../client/spike.h; sourceTree = SOURCE_ROOT; }; + DDA5AB7107D15FC400318A98 /* spike.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = spike.cpp; path = ../client/spike.cpp; sourceTree = SOURCE_ROOT; }; + DDA5AB7407D15FCD00318A98 /* timecvt.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = timecvt.cpp; path = ../client/timecvt.cpp; sourceTree = SOURCE_ROOT; }; + DDA5AB7507D15FCD00318A98 /* sah_version.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = sah_version.h; path = ../client/sah_version.h; sourceTree = SOURCE_ROOT; }; + DDA5AB7607D15FCD00318A98 /* sah_version.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = sah_version.cpp; path = ../client/sah_version.cpp; sourceTree = SOURCE_ROOT; }; + DDA5AB7707D15FCD00318A98 /* timecvt.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = timecvt.h; path = ../client/timecvt.h; sourceTree = SOURCE_ROOT; }; + DDA5AB7C07D15FD800318A98 /* worker.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = worker.cpp; path = ../client/worker.cpp; sourceTree = SOURCE_ROOT; }; + DDA5AB7D07D15FD800318A98 /* worker.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = worker.h; path = ../client/worker.h; sourceTree = SOURCE_ROOT; }; + DDA5AB8E07D161A700318A98 /* GLUT.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GLUT.framework; path = /System/Library/Frameworks/GLUT.framework; sourceTree = ""; }; + DDA5AB8F07D161A700318A98 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = /System/Library/Frameworks/OpenGL.framework; sourceTree = ""; }; + DDA5ABB807D16B7F00318A98 /* schema_master.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = schema_master.cpp; path = ../db/schema_master.cpp; sourceTree = SOURCE_ROOT; }; + DDA5ABB907D16B7F00318A98 /* schema_master.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = schema_master.h; path = ../db/schema_master.h; sourceTree = SOURCE_ROOT; }; + DDA5ABBD07D16BC100318A98 /* sqlblob.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = sqlblob.cpp; path = ../db/sqlblob.cpp; sourceTree = SOURCE_ROOT; }; + DDA5ABBE07D16BC100318A98 /* sqlblob.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = sqlblob.h; path = ../db/sqlblob.h; sourceTree = SOURCE_ROOT; }; + DDA5ABBF07D16BC100318A98 /* sqlrow.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = sqlrow.cpp; path = ../db/sqlrow.cpp; sourceTree = SOURCE_ROOT; }; + DDA5ABC007D16BC100318A98 /* sqlrow.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = sqlrow.h; path = ../db/sqlrow.h; sourceTree = SOURCE_ROOT; }; + DDA5ABC807D16BF700318A98 /* sqldefs.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = sqldefs.h; path = ../db/sqldefs.h; sourceTree = SOURCE_ROOT; }; + DDA5ABD007D16C5400318A98 /* db_table.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = db_table.h; path = ../db/db_table.h; sourceTree = SOURCE_ROOT; }; + DDA5ABD607D16C8900318A98 /* sqlapi.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = sqlapi.h; path = ../db/sqlapi.h; sourceTree = SOURCE_ROOT; }; + DDA5ABDD07D16CB100318A98 /* sqlint8.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = sqlint8.h; path = ../db/sqlint8.h; sourceTree = SOURCE_ROOT; }; + DDA5ABED07D16D1300318A98 /* xml_util.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = xml_util.cpp; path = ../db/xml_util.cpp; sourceTree = SOURCE_ROOT; }; + DDA5ABEE07D16D1300318A98 /* xml_util.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = xml_util.h; path = ../db/xml_util.h; sourceTree = SOURCE_ROOT; }; + DDB3D9CE0A6F883F002ADFC6 /* analyzeFuncs_altivec.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = analyzeFuncs_altivec.cpp; path = ../client/vector/analyzeFuncs_altivec.cpp; sourceTree = SOURCE_ROOT; }; + DDB3D9CF0A6F883F002ADFC6 /* analyzeFuncs_vector.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = analyzeFuncs_vector.cpp; path = ../client/vector/analyzeFuncs_vector.cpp; sourceTree = SOURCE_ROOT; }; + DDB3D9D00A6F883F002ADFC6 /* analyzeFuncs_vector.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = analyzeFuncs_vector.h; path = ../client/vector/analyzeFuncs_vector.h; sourceTree = SOURCE_ROOT; }; + DDB3D9D10A6F883F002ADFC6 /* analyzeFuncs_x86_64.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = analyzeFuncs_x86_64.cpp; path = ../client/vector/analyzeFuncs_x86_64.cpp; sourceTree = SOURCE_ROOT; }; + DDB3D9D20A6F883F002ADFC6 /* hires_timer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = hires_timer.cpp; path = ../client/vector/hires_timer.cpp; sourceTree = SOURCE_ROOT; }; + DDB3D9D30A6F883F002ADFC6 /* hires_timer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hires_timer.h; path = ../client/vector/hires_timer.h; sourceTree = SOURCE_ROOT; }; + DDB3D9D40A6F883F002ADFC6 /* sighandler.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = sighandler.h; path = ../client/vector/sighandler.h; sourceTree = SOURCE_ROOT; }; + DDB9947E134F12930092F582 /* sincos.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sincos.h; path = ../client/sincos.h; sourceTree = SOURCE_ROOT; }; + DDE5BF660C520E55000726A5 /* sah_config.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = sah_config.h; sourceTree = SOURCE_ROOT; }; + DDED51610A8010CC00699E63 /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = /System/Library/Frameworks/Accelerate.framework; sourceTree = ""; }; + DDEE185D0A8097EA0055E466 /* config-i386.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = "config-i386.h"; sourceTree = SOURCE_ROOT; }; + DDEE185E0A8097EA0055E466 /* config-ppc.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = "config-ppc.h"; sourceTree = SOURCE_ROOT; }; + DDF9383307E28823004DC076 /* checkin_notes */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = checkin_notes; path = ../checkin_notes; sourceTree = SOURCE_ROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 8DD76F660486A84900D96B5E /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + DDA5AB9007D161A700318A98 /* GLUT.framework in Frameworks */, + DDA5AB9107D161A700318A98 /* OpenGL.framework in Frameworks */, + DD6D832D081320B9008F7200 /* AppKit.framework in Frameworks */, + DD9476030A6F684000834371 /* libboinc_api.a in Frameworks */, + DD9476050A6F684000834371 /* libboinc.a in Frameworks */, + DDED51620A8010CC00699E63 /* Accelerate.framework in Frameworks */, + DD10B0D10D09538D000227CC /* libboinc_graphics2.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DD10AF420D09363D000227CC /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + DD10AF430D09363D000227CC /* GLUT.framework in Frameworks */, + DD10AF440D09363D000227CC /* OpenGL.framework in Frameworks */, + DD10AF450D09363D000227CC /* AppKit.framework in Frameworks */, + DD10AF460D09363D000227CC /* libboinc_api.a in Frameworks */, + DD10AF480D09363D000227CC /* libboinc.a in Frameworks */, + DD10AF490D09363D000227CC /* Accelerate.framework in Frameworks */, + DD10AF710D093949000227CC /* libboinc_graphics2.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DD10B0A90D0951CC000227CC /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + DD10B0AA0D0951CC000227CC /* GLUT.framework in Frameworks */, + DD10B0AB0D0951CC000227CC /* OpenGL.framework in Frameworks */, + DD10B0AC0D0951CC000227CC /* AppKit.framework in Frameworks */, + DD10B0AD0D0951CC000227CC /* libboinc_api.a in Frameworks */, + DD10B0AF0D0951CC000227CC /* libboinc.a in Frameworks */, + DD10B0B00D0951CC000227CC /* Accelerate.framework in Frameworks */, + DD10B0BE0D095293000227CC /* libboinc_graphics2.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DD2A2D270C5607D500D9D34F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + DD2A2D280C5607D500D9D34F /* GLUT.framework in Frameworks */, + DD2A2D290C5607D500D9D34F /* OpenGL.framework in Frameworks */, + DD2A2D2A0C5607D500D9D34F /* AppKit.framework in Frameworks */, + DD2A2D2B0C5607D500D9D34F /* libboinc_api.a in Frameworks */, + DD2A2D2D0C5607D500D9D34F /* libboinc.a in Frameworks */, + DD2A2D2E0C5607D500D9D34F /* Accelerate.framework in Frameworks */, + DD10B0D40D095402000227CC /* libboinc_graphics2.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 0249A662FF388D9811CA2CEA /* External Frameworks and Libraries */ = { + isa = PBXGroup; + children = ( + DD9476000A6F684000834371 /* libboinc_api.a */, + DD10AF700D093949000227CC /* libboinc_graphics2.a */, + DD9476020A6F684000834371 /* libboinc.a */, + DDA5AB8E07D161A700318A98 /* GLUT.framework */, + DD6D832C081320B9008F7200 /* AppKit.framework */, + DDA5AB8F07D161A700318A98 /* OpenGL.framework */, + DDED51610A8010CC00699E63 /* Accelerate.framework */, + 0249A663FF388D9811CA2CEA /* libstdc++.a */, + ); + name = "External Frameworks and Libraries"; + sourceTree = ""; + }; + 08FB7794FE84155DC02AAC07 /* seti_boinc */ = { + isa = PBXGroup; + children = ( + 08FB7795FE84155DC02AAC07 /* Source */, + C6859E8C029090F304C91782 /* Documentation */, + 0249A662FF388D9811CA2CEA /* External Frameworks and Libraries */, + 1AB674ADFE9D54B511CA2CBB /* Products */, + ); + name = seti_boinc; + sourceTree = ""; + }; + 08FB7795FE84155DC02AAC07 /* Source */ = { + isa = PBXGroup; + children = ( + DDA5ABB707D16B6000318A98 /* db */, + DDA5ABB207D16B4100318A98 /* client */, + ); + name = Source; + sourceTree = SOURCE_ROOT; + }; + 1AB674ADFE9D54B511CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 8DD76F6C0486A84900D96B5E /* seti_boinc_i386 */, + DD2A2D360C5607D500D9D34F /* seti_boinc_ppc */, + DD10AF500D09363D000227CC /* seti_graphics_i386 */, + DD10B0B80D0951CC000227CC /* seti_graphics_ppc */, + ); + name = Products; + sourceTree = ""; + }; + C6859E8C029090F304C91782 /* Documentation */ = { + isa = PBXGroup; + children = ( + DDF9383307E28823004DC076 /* checkin_notes */, + ); + name = Documentation; + sourceTree = SOURCE_ROOT; + }; + DDA5ABB207D16B4100318A98 /* client */ = { + isa = PBXGroup; + children = ( + DD8BB3AB0A1004390079F5C1 /* app_icon.h */, + DDE5BF660C520E55000726A5 /* sah_config.h */, + DDEE185D0A8097EA0055E466 /* config-i386.h */, + DDEE185E0A8097EA0055E466 /* config-ppc.h */, + DDA5AB3207D15F8D00318A98 /* analyze.h */, + DDA5AB2F07D15F8D00318A98 /* analyzeFuncs.cpp */, + DDA5AB3007D15F8D00318A98 /* analyzeFuncs.h */, + DDA5AB2C07D15F8D00318A98 /* analyzePoT.h */, + DDA5AB2907D15F8D00318A98 /* analyzePoT.cpp */, + DDA5AB2B07D15F8D00318A98 /* analyzeReport.h */, + DDA5AB3107D15F8D00318A98 /* analyzeReport.cpp */, + DD8DA29B13508806007C873C /* autocorr.h */, + DD8DA298135087EF007C873C /* autocorr.cpp */, + DDA5AB2D07D15F8D00318A98 /* chirpfft.h */, + DDA5AB2A07D15F8D00318A98 /* chirpfft.cpp */, + DDA5AB4607D15F9700318A98 /* fft8g.h */, + DDA5AB4207D15F9700318A98 /* fft8g.cpp */, + DDA5AB4007D15F9700318A98 /* gaussfit.h */, + DDA5AB4307D15F9700318A98 /* gaussfit.cpp */, + DDA5AB4407D15F9700318A98 /* gdata.h */, + DDA5AB4107D15F9700318A98 /* gdata.cpp */, + DD10AF840D093BBF000227CC /* graphics_main.cpp */, + DDA5AB4507D15F9700318A98 /* lcgamm.h */, + DDA5AB3E07D15F9700318A98 /* lcgamm.cpp */, + DDA5AB3F07D15F9700318A98 /* main.cpp */, + DDA5AB5307D15FB000318A98 /* malloc_a.h */, + DDA5AB5407D15FB000318A98 /* malloc_a.cpp */, + DDA5AB5A07D15FB000318A98 /* progress.h */, + DDA5AB5B07D15FB000318A98 /* progress.cpp */, + DDA5AB5807D15FB000318A98 /* pulsefind.h */, + DDA5AB5907D15FB000318A98 /* pulsefind.cpp */, + DDA5AB5007D15FB000318A98 /* sah_gfx_base.h */, + DDA5AB5707D15FB000318A98 /* sah_gfx_base.cpp */, + DDA5AB5107D15FB000318A98 /* sah_gfx.h */, + DDA5AB5207D15FB000318A98 /* sah_gfx.cpp */, + DD10AF610D09383E000227CC /* sah_gfx_main.h */, + DD10AF5F0D093830000227CC /* sah_gfx_main.cpp */, + DDA5AB6A07D15FBE00318A98 /* seti.h */, + DDA5AB6B07D15FBE00318A98 /* seti.cpp */, + DDA5AB6807D15FBE00318A98 /* seti_header.h */, + DDA5AB6907D15FBE00318A98 /* seti_header.cpp */, + DDB9947E134F12930092F582 /* sincos.h */, + DDA5AB7007D15FC400318A98 /* spike.h */, + DDA5AB7107D15FC400318A98 /* spike.cpp */, + DDA5AB5507D15FB000318A98 /* s_util.h */, + DDA5AB5607D15FB000318A98 /* s_util.cpp */, + DDA5AB7707D15FCD00318A98 /* timecvt.h */, + DDA5AB7407D15FCD00318A98 /* timecvt.cpp */, + DDA5AB7507D15FCD00318A98 /* sah_version.h */, + DDB3D9BD0A6F87C9002ADFC6 /* vector */, + DDA5AB7607D15FCD00318A98 /* sah_version.cpp */, + DDA5AB7C07D15FD800318A98 /* worker.cpp */, + DDA5AB7D07D15FD800318A98 /* worker.h */, + ); + name = client; + sourceTree = SOURCE_ROOT; + }; + DDA5ABB707D16B6000318A98 /* db */ = { + isa = PBXGroup; + children = ( + DDA5ABD007D16C5400318A98 /* db_table.h */, + DDA5ABD607D16C8900318A98 /* sqlapi.h */, + DDA5ABDD07D16CB100318A98 /* sqlint8.h */, + DDA5ABBE07D16BC100318A98 /* sqlblob.h */, + DDA5ABBD07D16BC100318A98 /* sqlblob.cpp */, + DDA5ABC807D16BF700318A98 /* sqldefs.h */, + DDA5ABC007D16BC100318A98 /* sqlrow.h */, + DDA5ABBF07D16BC100318A98 /* sqlrow.cpp */, + DDA5ABB907D16B7F00318A98 /* schema_master.h */, + DDA5ABB807D16B7F00318A98 /* schema_master.cpp */, + DDA5ABEE07D16D1300318A98 /* xml_util.h */, + DDA5ABED07D16D1300318A98 /* xml_util.cpp */, + ); + name = db; + sourceTree = SOURCE_ROOT; + }; + DDB3D9BD0A6F87C9002ADFC6 /* vector */ = { + isa = PBXGroup; + children = ( + DDB3D9CE0A6F883F002ADFC6 /* analyzeFuncs_altivec.cpp */, + DD5F15B80C5218A600CA453D /* analyzeFuncs_fpu.cpp */, + DD5F15BA0C5218A600CA453D /* analyzeFuncs_sse.cpp */, + DD5F15BB0C5218A600CA453D /* analyzeFuncs_sse2.cpp */, + DD5F15BC0C5218A600CA453D /* analyzeFuncs_sse3.cpp */, + DDB3D9CF0A6F883F002ADFC6 /* analyzeFuncs_vector.cpp */, + DDB3D9D00A6F883F002ADFC6 /* analyzeFuncs_vector.h */, + DDB3D9D10A6F883F002ADFC6 /* analyzeFuncs_x86_64.cpp */, + DD2A2C870C5604C700D9D34F /* x86_float4.cpp */, + DD2A2C880C5604C700D9D34F /* x86_float4.h */, + DDB3D9D20A6F883F002ADFC6 /* hires_timer.cpp */, + DDB3D9D30A6F883F002ADFC6 /* hires_timer.h */, + DDB3D9D40A6F883F002ADFC6 /* sighandler.h */, + ); + name = vector; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 8DD76F620486A84900D96B5E /* seti_boinc_i386 */ = { + isa = PBXNativeTarget; + buildConfigurationList = DD3A24540979D8FA000BB4EC /* Build configuration list for PBXNativeTarget "seti_boinc_i386" */; + buildPhases = ( + DD079E8B0C73E73E00ABDDA2 /* ShellScript */, + 8DD76F640486A84900D96B5E /* Sources */, + 8DD76F660486A84900D96B5E /* Frameworks */, + ); + buildRules = ( + DD1FF02B08698A37004F0593 /* PBXBuildRule */, + DD1FF02A08698A37004F0593 /* PBXBuildRule */, + DD30E12C08CB006300436BE4 /* PBXBuildRule */, + ); + dependencies = ( + ); + name = seti_boinc_i386; + productInstallPath = "$(HOME)/bin"; + productName = seti_boinc; + productReference = 8DD76F6C0486A84900D96B5E /* seti_boinc_i386 */; + productType = "com.apple.product-type.tool"; + }; + DD10AF1D0D09363D000227CC /* seti_gfx_i386 */ = { + isa = PBXNativeTarget; + buildConfigurationList = DD10AF4D0D09363D000227CC /* Build configuration list for PBXNativeTarget "seti_gfx_i386" */; + buildPhases = ( + DD10AF1E0D09363D000227CC /* ShellScript */, + DD10AF1F0D09363D000227CC /* Sources */, + DD10AF420D09363D000227CC /* Frameworks */, + ); + buildRules = ( + DD10AF4A0D09363D000227CC /* PBXBuildRule */, + DD10AF4B0D09363D000227CC /* PBXBuildRule */, + DD10AF4C0D09363D000227CC /* PBXBuildRule */, + ); + dependencies = ( + ); + name = seti_gfx_i386; + productInstallPath = "$(HOME)/bin"; + productName = seti_boinc; + productReference = DD10AF500D09363D000227CC /* seti_graphics_i386 */; + productType = "com.apple.product-type.tool"; + }; + DD10B0870D0951CC000227CC /* seti_gfx_ppc */ = { + isa = PBXNativeTarget; + buildConfigurationList = DD10B0B50D0951CC000227CC /* Build configuration list for PBXNativeTarget "seti_gfx_ppc" */; + buildPhases = ( + DD10B0B10D0951CC000227CC /* ShellScript */, + DD10B0880D0951CC000227CC /* Sources */, + DD10B0A90D0951CC000227CC /* Frameworks */, + ); + buildRules = ( + DD10B0B20D0951CC000227CC /* PBXBuildRule */, + DD10B0B30D0951CC000227CC /* PBXBuildRule */, + DD10B0B40D0951CC000227CC /* PBXBuildRule */, + ); + dependencies = ( + ); + name = seti_gfx_ppc; + productInstallPath = "$(HOME)/bin"; + productName = seti_boinc; + productReference = DD10B0B80D0951CC000227CC /* seti_graphics_ppc */; + productType = "com.apple.product-type.tool"; + }; + DD2A2D020C5607D500D9D34F /* seti_boinc_ppc */ = { + isa = PBXNativeTarget; + buildConfigurationList = DD2A2D320C5607D500D9D34F /* Build configuration list for PBXNativeTarget "seti_boinc_ppc" */; + buildPhases = ( + DD079E8D0C73E75000ABDDA2 /* ShellScript */, + DD2A2D040C5607D500D9D34F /* Sources */, + DD2A2D270C5607D500D9D34F /* Frameworks */, + ); + buildRules = ( + DD2A2D2F0C5607D500D9D34F /* PBXBuildRule */, + DD2A2D300C5607D500D9D34F /* PBXBuildRule */, + DD2A2D310C5607D500D9D34F /* PBXBuildRule */, + ); + dependencies = ( + ); + name = seti_boinc_ppc; + productInstallPath = "$(HOME)/bin"; + productName = seti_boinc; + productReference = DD2A2D360C5607D500D9D34F /* seti_boinc_ppc */; + productType = "com.apple.product-type.tool"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 08FB7793FE84155DC02AAC07 /* Project object */ = { + isa = PBXProject; + buildConfigurationList = DD3A24580979D8FA000BB4EC /* Build configuration list for PBXProject "seti_boinc" */; + compatibilityVersion = "Xcode 2.4"; + developmentRegion = English; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); + mainGroup = 08FB7794FE84155DC02AAC07 /* seti_boinc */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + DDC969040D09674F00A480B2 /* Build-All */, + 8DD76F620486A84900D96B5E /* seti_boinc_i386 */, + DD2A2D020C5607D500D9D34F /* seti_boinc_ppc */, + DD10AF1D0D09363D000227CC /* seti_gfx_i386 */, + DD10B0870D0951CC000227CC /* seti_gfx_ppc */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXShellScriptBuildPhase section */ + DD079E8B0C73E73E00ABDDA2 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "cp -fp \"${SRCROOT}/sah_config.h\" \"${SRCROOT}/config.h\""; + }; + DD079E8D0C73E75000ABDDA2 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "cp -fp \"${SRCROOT}/sah_config.h\" \"${SRCROOT}/config.h\""; + }; + DD10AF1E0D09363D000227CC /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "cp -fp \"${SRCROOT}/sah_config.h\" \"${SRCROOT}/config.h\""; + }; + DD10B0B10D0951CC000227CC /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "cp -fp \"${SRCROOT}/sah_config.h\" \"${SRCROOT}/config.h\""; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 8DD76F640486A84900D96B5E /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DDA5AB3407D15F8D00318A98 /* analyzePoT.cpp in Sources */, + DDA5AB3507D15F8D00318A98 /* chirpfft.cpp in Sources */, + DDA5AB3A07D15F8D00318A98 /* analyzeFuncs.cpp in Sources */, + DDA5AB3C07D15F8D00318A98 /* analyzeReport.cpp in Sources */, + DDA5AB4707D15F9700318A98 /* lcgamm.cpp in Sources */, + DDA5AB4807D15F9700318A98 /* main.cpp in Sources */, + DDA5AB4A07D15F9700318A98 /* gdata.cpp in Sources */, + DDA5AB4B07D15F9700318A98 /* fft8g.cpp in Sources */, + DDA5AB4C07D15F9700318A98 /* gaussfit.cpp in Sources */, + DDA5AB6007D15FB000318A98 /* malloc_a.cpp in Sources */, + DDA5AB6207D15FB000318A98 /* s_util.cpp in Sources */, + DDA5AB6507D15FB000318A98 /* pulsefind.cpp in Sources */, + DDA5AB6707D15FB000318A98 /* progress.cpp in Sources */, + DDA5AB6D07D15FBE00318A98 /* seti_header.cpp in Sources */, + DDA5AB6F07D15FBE00318A98 /* seti.cpp in Sources */, + DDA5AB7307D15FC400318A98 /* spike.cpp in Sources */, + DDA5AB7A07D15FCD00318A98 /* sah_version.cpp in Sources */, + DDA5AB7E07D15FD800318A98 /* worker.cpp in Sources */, + DDB3D9D50A6F883F002ADFC6 /* analyzeFuncs_altivec.cpp in Sources */, + DDB3D9D60A6F883F002ADFC6 /* analyzeFuncs_vector.cpp in Sources */, + DDB3D9D80A6F883F002ADFC6 /* analyzeFuncs_x86_64.cpp in Sources */, + DDB3D9D90A6F883F002ADFC6 /* hires_timer.cpp in Sources */, + DD5F15BD0C5218A600CA453D /* analyzeFuncs_fpu.cpp in Sources */, + DD5F15BF0C5218A600CA453D /* analyzeFuncs_sse.cpp in Sources */, + DD5F15C00C5218A600CA453D /* analyzeFuncs_sse2.cpp in Sources */, + DD5F15C10C5218A600CA453D /* analyzeFuncs_sse3.cpp in Sources */, + DD2A2C890C5604C700D9D34F /* x86_float4.cpp in Sources */, + DD10AF750D093995000227CC /* sah_gfx_main.cpp in Sources */, + DD10B0C70D09533D000227CC /* sqlblob.cpp in Sources */, + DD10B0C90D095344000227CC /* sqlrow.cpp in Sources */, + DD10B0CB0D09534A000227CC /* schema_master.cpp in Sources */, + DD10B0CD0D095350000227CC /* xml_util.cpp in Sources */, + DD8DA299135087EF007C873C /* autocorr.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DD10AF1F0D09363D000227CC /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DD10AF2C0D09363D000227CC /* sah_gfx_base.cpp in Sources */, + DD10AF320D09363D000227CC /* timecvt.cpp in Sources */, + DD10AF850D093BBF000227CC /* graphics_main.cpp in Sources */, + DD10AF880D093C21000227CC /* sah_gfx.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DD10B0880D0951CC000227CC /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DD10B0BA0D095255000227CC /* graphics_main.cpp in Sources */, + DD10B0BB0D09525A000227CC /* sah_gfx_base.cpp in Sources */, + DD10B0BC0D09525A000227CC /* sah_gfx.cpp in Sources */, + DD10B0BD0D09526A000227CC /* timecvt.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DD2A2D040C5607D500D9D34F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DD2A2D050C5607D500D9D34F /* analyzePoT.cpp in Sources */, + DD2A2D060C5607D500D9D34F /* chirpfft.cpp in Sources */, + DD2A2D070C5607D500D9D34F /* analyzeFuncs.cpp in Sources */, + DD2A2D080C5607D500D9D34F /* analyzeReport.cpp in Sources */, + DD2A2D090C5607D500D9D34F /* lcgamm.cpp in Sources */, + DD2A2D0A0C5607D500D9D34F /* main.cpp in Sources */, + DD2A2D0B0C5607D500D9D34F /* gdata.cpp in Sources */, + DD2A2D0C0C5607D500D9D34F /* fft8g.cpp in Sources */, + DD2A2D0D0C5607D500D9D34F /* gaussfit.cpp in Sources */, + DD2A2D0F0C5607D500D9D34F /* malloc_a.cpp in Sources */, + DD2A2D100C5607D500D9D34F /* s_util.cpp in Sources */, + DD2A2D120C5607D500D9D34F /* pulsefind.cpp in Sources */, + DD2A2D130C5607D500D9D34F /* progress.cpp in Sources */, + DD2A2D140C5607D500D9D34F /* seti_header.cpp in Sources */, + DD2A2D150C5607D500D9D34F /* seti.cpp in Sources */, + DD2A2D160C5607D500D9D34F /* spike.cpp in Sources */, + DD2A2D180C5607D500D9D34F /* sah_version.cpp in Sources */, + DD2A2D190C5607D500D9D34F /* worker.cpp in Sources */, + DD2A2D1A0C5607D500D9D34F /* schema_master.cpp in Sources */, + DD2A2D1B0C5607D500D9D34F /* sqlblob.cpp in Sources */, + DD2A2D1C0C5607D500D9D34F /* sqlrow.cpp in Sources */, + DD2A2D1D0C5607D500D9D34F /* xml_util.cpp in Sources */, + DD2A2D1E0C5607D500D9D34F /* analyzeFuncs_altivec.cpp in Sources */, + DD2A2D1F0C5607D500D9D34F /* analyzeFuncs_vector.cpp in Sources */, + DD2A2D200C5607D500D9D34F /* analyzeFuncs_x86_64.cpp in Sources */, + DD2A2D210C5607D500D9D34F /* hires_timer.cpp in Sources */, + DD2A2D220C5607D500D9D34F /* analyzeFuncs_fpu.cpp in Sources */, + DD2A2D230C5607D500D9D34F /* analyzeFuncs_sse.cpp in Sources */, + DD2A2D240C5607D500D9D34F /* analyzeFuncs_sse2.cpp in Sources */, + DD2A2D250C5607D500D9D34F /* analyzeFuncs_sse3.cpp in Sources */, + DD2A2D260C5607D500D9D34F /* x86_float4.cpp in Sources */, + DD10B0830D095113000227CC /* sah_gfx_main.cpp in Sources */, + DD8DA29A135087EF007C873C /* autocorr.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + DDC969080D09676700A480B2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 8DD76F620486A84900D96B5E /* seti_boinc_i386 */; + targetProxy = DDC969070D09676700A480B2 /* PBXContainerItemProxy */; + }; + DDC9690A0D09676700A480B2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DD2A2D020C5607D500D9D34F /* seti_boinc_ppc */; + targetProxy = DDC969090D09676700A480B2 /* PBXContainerItemProxy */; + }; + DDC9690C0D09676700A480B2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DD10AF1D0D09363D000227CC /* seti_gfx_i386 */; + targetProxy = DDC9690B0D09676700A480B2 /* PBXContainerItemProxy */; + }; + DDC9690E0D09676700A480B2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DD10B0870D0951CC000227CC /* seti_gfx_ppc */; + targetProxy = DDC9690D0D09676700A480B2 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + DD10AF4E0D09363D000227CC /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)", + ); + FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Versions/A/Frameworks\""; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = ""; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; + HEADER_SEARCH_PATHS = ( + ../mac_build/, + ../, + ../db, + ../../boinc/api/, + ../../boinc/lib/, + "../../lib/fftw-3.1.1/api/", + ../../boinc/, + ); + INSTALL_PATH = "$(HOME)/bin"; + LIBRARY_SEARCH_PATHS = ( + ../../boinc/mac_build/build/Development/, + "../../jpeg-6b/", + "../../lib/fftw-3.1.1/.libs/", + "$(LIBRARY_SEARCH_PATHS_QUOTED_1)", + "$(LIBRARY_SEARCH_PATHS_QUOTED_2)", + "$(LIBRARY_SEARCH_PATHS_QUOTED_3)", + "$(LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", + ); + LIBRARY_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/../../boinc/mac_build/build/Deployment\""; + LIBRARY_SEARCH_PATHS_QUOTED_2 = "\"$(SRCROOT)/../client/vector\""; + LIBRARY_SEARCH_PATHS_QUOTED_3 = "\"$(SRCROOT)/../client/vector\""; + MACOSX_DEPLOYMENT_TARGET = 10.4; + OTHER_CFLAGS = ( + "-DMAC_OS_X_VERSION_MAX_ALLOWED=1040", + "-DHAVE_CONFIG_H", + "-DTEXT_UI", + "-DDEBUG", + "-DCLIENT", + "-D_THREAD_SAFE", + "-DUSING_XCODE", + "-fomit-frame-pointer", + "-fstrict-aliasing", + "-ffast-math", + "-Wno-long-double", + ); + OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; + OTHER_LDFLAGS = "-ljpeg"; + PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = YES; + PRODUCT_NAME = seti_graphics_i386; + SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + SKIP_INSTALL = YES; + USER_HEADER_SEARCH_PATHS = ""; + ZERO_LINK = NO; + }; + name = Development; + }; + DD10AF4F0D09363D000227CC /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = i386; + COPY_PHASE_STRIP = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)", + ); + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = ""; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; + HEADER_SEARCH_PATHS = ( + ../mac_build/, + ../, + ../db, + ../../boinc/api/, + ../../boinc/lib/, + "../../lib/fftw-3.1.1/api/", + ../../boinc/, + ); + INSTALL_PATH = "$(HOME)/bin"; + LIBRARY_SEARCH_PATHS = ( + ../../boinc/mac_build/build/Deployment/, + "../../jpeg-6b/", + "../../lib/fftw-3.1.1/.libs/", + "$(LIBRARY_SEARCH_PATHS_QUOTED_1)", + "$(LIBRARY_SEARCH_PATHS_QUOTED_2)", + "$(LIBRARY_SEARCH_PATHS_QUOTED_3)", + "$(LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", + ); + MACOSX_DEPLOYMENT_TARGET = 10.4; + OTHER_CFLAGS = ( + "-DMAC_OS_X_VERSION_MAX_ALLOWED=1040", + "-DHAVE_CONFIG_H", + "-DTEXT_UI", + "-DNDEBUG", + "-DCLIENT", + "-D_THREAD_SAFE", + "-DUSING_XCODE", + "-fomit-frame-pointer", + "-fstrict-aliasing", + "-ffast-math", + "-march=pentium-m", + "-mtune=pentium-m", + ); + OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; + OTHER_LDFLAGS = "-ljpeg"; + PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = YES; + PRODUCT_NAME = seti_graphics_i386; + SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + SKIP_INSTALL = YES; + USER_HEADER_SEARCH_PATHS = ""; + ZERO_LINK = NO; + }; + name = Deployment; + }; + DD10B0B60D0951CC000227CC /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = ppc; + COPY_PHASE_STRIP = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)", + ); + FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Versions/A/Frameworks\""; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; + HEADER_SEARCH_PATHS = ( + ../mac_build/, + ../, + ../db, + ../../boinc/api/, + ../../boinc/lib/, + "../../lib/fftw-3.1.1/api/", + ../../boinc/, + ); + INSTALL_PATH = "$(HOME)/bin"; + LIBRARY_SEARCH_PATHS = ( + ../../boinc/mac_build/build/Deployment/, + "../../jpeg-6b/", + "../../lib/fftw-3.1.1/.libs/", + "$(LIBRARY_SEARCH_PATHS_QUOTED_1)", + "$(LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", + ); + LIBRARY_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/../../boinc/mac_build/build/Deployment\""; + MACOSX_DEPLOYMENT_TARGET = 10.4; + OTHER_CFLAGS = ( + "-DMAC_OS_X_VERSION_MAX_ALLOWED=1040", + "-DHAVE_CONFIG_H", + "-DTEXT_UI", + "-DDEBUG", + "-DCLIENT", + "-D_THREAD_SAFE", + "-DUSING_XCODE", + "-fomit-frame-pointer", + "-fstrict-aliasing", + "-ffast-math", + "-Wno-long-double", + ); + OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; + OTHER_LDFLAGS = ( + "-lobjc", + "-lz", + "-lm", + "-ljpeg", + ); + PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = YES; + PRODUCT_NAME = seti_graphics_ppc; + SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + SKIP_INSTALL = YES; + USER_HEADER_SEARCH_PATHS = ""; + ZERO_LINK = NO; + }; + name = Development; + }; + DD10B0B70D0951CC000227CC /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = ppc; + COPY_PHASE_STRIP = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)", + ); + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G4; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; + HEADER_SEARCH_PATHS = ( + ../mac_build/, + ../, + ../db, + ../../boinc/api/, + ../../boinc/lib/, + "../../lib/fftw-3.1.1/api/", + ../../boinc/, + ); + INSTALL_PATH = "$(HOME)/bin"; + LIBRARY_SEARCH_PATHS = ( + ../../boinc/mac_build/build/Deployment/, + "../../jpeg-6b/", + "../../lib/fftw-3.1.1/.libs/", + "$(LIBRARY_SEARCH_PATHS_QUOTED_1)", + "$(LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", + ); + MACOSX_DEPLOYMENT_TARGET = 10.4; + OTHER_CFLAGS = ( + "-DMAC_OS_X_VERSION_MAX_ALLOWED=1040", + "-DHAVE_CONFIG_H", + "-DTEXT_UI", + "-DNDEBUG", + "-DCLIENT", + "-D_THREAD_SAFE", + "-DUSING_XCODE", + "-fomit-frame-pointer", + "-fstrict-aliasing", + "-ffast-math", + "-mcpu=powerpc", + "-mtune=G5", + "-Wno-long-double", + ); + OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; + OTHER_LDFLAGS = "-ljpeg"; + PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = YES; + PRODUCT_NAME = seti_graphics_ppc; + SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + SKIP_INSTALL = YES; + USER_HEADER_SEARCH_PATHS = ""; + ZERO_LINK = NO; + }; + name = Deployment; + }; + DD2A2D330C5607D500D9D34F /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = ppc; + COPY_PHASE_STRIP = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)", + ); + FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Versions/A/Frameworks\""; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + GCC_VERSION_i386 = 4.0; + GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; + HEADER_SEARCH_PATHS = ( + ../mac_build/, + ../, + ../db, + ../../boinc/api/, + ../../boinc/lib/, + "../../lib/fftw-3.1.1/api/", + ../../boinc/, + ); + INSTALL_PATH = "$(HOME)/bin"; + LIBRARY_SEARCH_PATHS = ( + ../../boinc/mac_build/build/Deployment/, + "../../jpeg-6b/", + "../../lib/fftw-3.1.1/.libs/", + "$(LIBRARY_SEARCH_PATHS_QUOTED_1)", + "$(LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", + ); + LIBRARY_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/../../boinc/mac_build/build/Deployment\""; + MACOSX_DEPLOYMENT_TARGET_i386 = 10.4; + OTHER_CFLAGS = ( + "-DMAC_OS_X_VERSION_MAX_ALLOWED=1040", + "-DHAVE_CONFIG_H", + "-DTEXT_UI", + "-DDEBUG", + "-DCLIENT", + "-D_THREAD_SAFE", + "-DUSING_XCODE", + "-fomit-frame-pointer", + "-fstrict-aliasing", + "-ffast-math", + "-Wno-long-double", + ); + OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; + OTHER_LDFLAGS = "-lfftw3f"; + PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = YES; + PRODUCT_NAME = seti_boinc_ppc; + SDKROOT_i386 = /Developer/SDKs/MacOSX10.4u.sdk; + SKIP_INSTALL = YES; + USER_HEADER_SEARCH_PATHS = ""; + ZERO_LINK = NO; + }; + name = Development; + }; + DD3A24550979D8FA000BB4EC /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)", + ); + FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Versions/A/Frameworks\""; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = ""; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + GCC_VERSION_i386 = 4.0; + GCC_VERSION_ppc = 3.3; + GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; + HEADER_SEARCH_PATHS = ( + ../mac_build/, + ../, + ../db, + ../../boinc/api/, + ../../boinc/lib/, + ../../boinc/, + ../client/win_build/, + ); + INSTALL_PATH = "$(HOME)/bin"; + LIBRARY_SEARCH_PATHS = ( + ../../boinc/mac_build/build/Deployment/, + "../../jpeg-6b/", + "../../lib/fftw-3.1.1/.libs/", + "$(LIBRARY_SEARCH_PATHS_QUOTED_1)", + "$(LIBRARY_SEARCH_PATHS_QUOTED_2)", + "$(LIBRARY_SEARCH_PATHS_QUOTED_3)", + "$(LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", + "$(LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", + ); + LIBRARY_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/../../boinc/mac_build/build/Deployment\""; + LIBRARY_SEARCH_PATHS_QUOTED_2 = "\"$(SRCROOT)/../client/vector\""; + LIBRARY_SEARCH_PATHS_QUOTED_3 = "\"$(SRCROOT)/../client/vector\""; + LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/../../boinc/mac_build/build/Deployment\""; + MACOSX_DEPLOYMENT_TARGET = 10.4; + MACOSX_DEPLOYMENT_TARGET_i386 = 10.4; + MACOSX_DEPLOYMENT_TARGET_ppc = 10.3; + OTHER_CFLAGS = ( + "-DMAC_OS_X_VERSION_MAX_ALLOWED=1040", + "-DHAVE_CONFIG_H", + "-DTEXT_UI", + "-DDEBUG", + "-DCLIENT", + "-D_THREAD_SAFE", + "-DUSING_XCODE", + "-fomit-frame-pointer", + "-fstrict-aliasing", + "-ffast-math", + "-Wno-long-double", + ); + OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; + OTHER_LDFLAGS = ( + "-lobjc", + "-lz", + "-lm", + "-ljpeg", + "-lfftw3f", + ); + PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = YES; + PRODUCT_NAME = seti_boinc_i386; + SDKROOT_i386 = /Developer/SDKs/MacOSX10.4u.sdk; + SDKROOT_ppc = /Developer/SDKs/MacOSX10.3.9.sdk; + SKIP_INSTALL = YES; + USER_HEADER_SEARCH_PATHS = ""; + ZERO_LINK = NO; + }; + name = Development; + }; + DD3A24590979D8FA000BB4EC /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_VERSION = 4.0; + MACOSX_DEPLOYMENT_TARGET = 10.4; + PREBINDING = NO; + SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + }; + name = Development; + }; + DD3E19A00C560FD000D18FD4 /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = i386; + COPY_PHASE_STRIP = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)", + ); + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = ""; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; + HEADER_SEARCH_PATHS = ( + ../mac_build/, + ../, + ../db, + ../../boinc/api/, + ../../boinc/lib/, + ../../boinc/, + ../client/win_build/, + ); + INSTALL_PATH = "$(HOME)/bin"; + LIBRARY_SEARCH_PATHS = ( + ../../boinc/mac_build/build/Deployment/, + "../../jpeg-6b/", + "../../lib/fftw-3.1.1/.libs/", + "$(LIBRARY_SEARCH_PATHS_QUOTED_1)", + "$(LIBRARY_SEARCH_PATHS_QUOTED_2)", + "$(LIBRARY_SEARCH_PATHS_QUOTED_3)", + "$(LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", + "$(LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_2)", + ); + MACOSX_DEPLOYMENT_TARGET = 10.4; + OTHER_CFLAGS = ( + "-DMAC_OS_X_VERSION_MAX_ALLOWED=1040", + "-DHAVE_CONFIG_H", + "-DTEXT_UI", + "-DNDEBUG", + "-DCLIENT", + "-D_THREAD_SAFE", + "-DUSING_XCODE", + "-fomit-frame-pointer", + "-fstrict-aliasing", + "-ffast-math", + "-march=pentium-m", + "-mtune=pentium-m", + ); + OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; + OTHER_LDFLAGS = "-lfftw3f"; + PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = YES; + PRODUCT_NAME = seti_boinc_i386; + SKIP_INSTALL = YES; + USER_HEADER_SEARCH_PATHS = ""; + ZERO_LINK = NO; + }; + name = Deployment; + }; + DD3E19A10C560FD000D18FD4 /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = ppc; + COPY_PHASE_STRIP = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)", + ); + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G4; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; + GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; + HEADER_SEARCH_PATHS = ( + ../mac_build/, + ../, + ../db, + ../../boinc/api/, + ../../boinc/lib/, + "../../lib/fftw-3.1.1/api/", + ../../boinc/, + ); + INSTALL_PATH = "$(HOME)/bin"; + LIBRARY_SEARCH_PATHS = ( + ../../boinc/mac_build/build/Deployment/, + "../../jpeg-6b/", + "../../lib/fftw-3.1.1/.libs/", + "$(LIBRARY_SEARCH_PATHS_QUOTED_1)", + "$(LIBRARY_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", + ); + OTHER_CFLAGS = ( + "-DMAC_OS_X_VERSION_MAX_ALLOWED=1040", + "-DHAVE_CONFIG_H", + "-DTEXT_UI", + "-DNDEBUG", + "-DCLIENT", + "-D_THREAD_SAFE", + "-DUSING_XCODE", + "-fomit-frame-pointer", + "-fstrict-aliasing", + "-ffast-math", + "-mcpu=powerpc", + "-mtune=G5", + "-Wno-long-double", + ); + OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; + OTHER_LDFLAGS = "-lfftw3f"; + PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = YES; + PRODUCT_NAME = seti_boinc_ppc; + SKIP_INSTALL = YES; + USER_HEADER_SEARCH_PATHS = ""; + ZERO_LINK = NO; + }; + name = Deployment; + }; + DD3E19A20C560FD000D18FD4 /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_VERSION = 4.0; + MACOSX_DEPLOYMENT_TARGET = 10.4; + PREBINDING = NO; + SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + }; + name = Deployment; + }; + DDC969050D09674F00A480B2 /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + PRODUCT_NAME = "Build-All"; + }; + name = Development; + }; + DDC969060D09674F00A480B2 /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + PRODUCT_NAME = "Build-All"; + ZERO_LINK = NO; + }; + name = Deployment; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + DD10AF4D0D09363D000227CC /* Build configuration list for PBXNativeTarget "seti_gfx_i386" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DD10AF4E0D09363D000227CC /* Development */, + DD10AF4F0D09363D000227CC /* Deployment */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Development; + }; + DD10B0B50D0951CC000227CC /* Build configuration list for PBXNativeTarget "seti_gfx_ppc" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DD10B0B60D0951CC000227CC /* Development */, + DD10B0B70D0951CC000227CC /* Deployment */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Development; + }; + DD2A2D320C5607D500D9D34F /* Build configuration list for PBXNativeTarget "seti_boinc_ppc" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DD2A2D330C5607D500D9D34F /* Development */, + DD3E19A10C560FD000D18FD4 /* Deployment */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Development; + }; + DD3A24540979D8FA000BB4EC /* Build configuration list for PBXNativeTarget "seti_boinc_i386" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DD3A24550979D8FA000BB4EC /* Development */, + DD3E19A00C560FD000D18FD4 /* Deployment */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Development; + }; + DD3A24580979D8FA000BB4EC /* Build configuration list for PBXProject "seti_boinc" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DD3A24590979D8FA000BB4EC /* Development */, + DD3E19A20C560FD000D18FD4 /* Deployment */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Development; + }; + DDC969140D0967AE00A480B2 /* Build configuration list for PBXAggregateTarget "Build-All" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DDC969050D09674F00A480B2 /* Development */, + DDC969060D09674F00A480B2 /* Deployment */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Development; + }; +/* End XCConfigurationList section */ + }; + rootObject = 08FB7793FE84155DC02AAC07 /* Project object */; +} diff --git a/missing b/missing new file mode 100755 index 0000000..6a37006 --- /dev/null +++ b/missing @@ -0,0 +1,336 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. +# Copyright (C) 1996, 1997, 1999, 2000, 2002 Free Software Foundation, Inc. +# Originally by Fran,cois Pinard , 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +run=: + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +case "$1" in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case "$1" in + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + tar try tar, gnutar, gtar, then tar without non-portable flags + yacc create \`y.tab.[ch]', if possible, from existing .[ch]" + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing 0.4 - GNU automake" + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + + aclocal*) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case "$f" in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is needed, and you do not seem to have it handy on your + system. You might have modified some files without having the + proper tools for further handling them. + You can get \`$1Help2man' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` + test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison|yacc) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if [ ! -f y.tab.h ]; then + echo >y.tab.h + fi + if [ ! -f y.tab.c ]; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex|flex) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if [ ! -f lex.yy.c ]; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` + fi + if [ -f "$file" ]; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit 1 + fi + ;; + + makeinfo) + if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then + # We have makeinfo, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` + fi + touch $file + ;; + + tar) + shift + if test -n "$run"; then + echo 1>&2 "ERROR: \`tar' requires --run" + exit 1 + fi + + # We have already tried tar in the generic part. + # Look for gnutar/gtar before invocation to avoid ugly error + # messages. + if (gnutar --version > /dev/null 2>&1); then + gnutar "$@" && exit 0 + fi + if (gtar --version > /dev/null 2>&1); then + gtar "$@" && exit 0 + fi + firstarg="$1" + if shift; then + case "$firstarg" in + *o*) + firstarg=`echo "$firstarg" | sed s/o//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + case "$firstarg" in + *h*) + firstarg=`echo "$firstarg" | sed s/h//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + fi + + echo 1>&2 "\ +WARNING: I can't seem to be able to run \`tar' with the given arguments. + You may want to install GNU tar or Free paxutils, or check the + command line arguments." + exit 1 + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and you do not seem to have it handy on your + system. You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequirements for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 diff --git a/nightly-tarball b/nightly-tarball new file mode 100755 index 0000000..85ad46c --- /dev/null +++ b/nightly-tarball @@ -0,0 +1,37 @@ +#!/bin/sh + +## $Id: nightly-tarball,v 1.6.2.6 2007/06/01 20:46:03 korpela Exp $ + +# Create a nightly tarball from CVS export + +# need to set PATH because we might be running from a cron job. +# on our Solaris servers, cvs is in /opt/misc/bin + +cd `dirname $0` + +#CVSROOT=/usr/local/warez/cvsroot \ +# CHECKOUT='cvs checkout -r HEAD lib/fftw-3.1.1 && mv lib/fftw-3.1.1 .' \ +# DIR=fftw-3.1.1 \ +# FILENAME_TGZ="fftw-3.1.1_seti.tar.gz" \ +# FILENAME_ZIP="fftw-3.1.1_seti.zip" \ +# DESTINATION="/home/boincadm/projects/sah/html/user/seti_source/nightly/" \ +# ./export-tarball + +# CVSROOT=/usr/local/warez/cvsroot \ +# CHECKOUT='cvs checkout -r HEAD seti_boinc && (cd seti_boinc && ./trim_sources DOIT)' \ +# DIR=seti_boinc \ +# FILENAME_TGZ="seti_boinc-client-cvs-TODAY.tar.gz" \ +# FILENAME_ZIP="seti_boinc-client-cvs-TODAY.zip" \ +# DESTINATION="/home/boincadm/projects/sah/html/user/seti_source/nightly/" \ +# ./export-tarball + + CHECKOUT='svn export file:///home/svn/seti_boinc' \ + DIR=seti_boinc \ + FILENAME_TGZ="setiathome_enhanced-client-cvs-TODAY.tar.gz" \ + FILENAME_ZIP="setiathome_enhanced-client-cvs-TODAY.zip" \ + DESTINATION="/home/boincadm/projects/sah/html/user/seti_source/nightly/" \ + ./export-tarball + +cd /home/boincadm/projects/sah/html/user/seti_source/nightly/ +find . -mtime +30 -exec mv {} old \; +/bin/rm -rf /tmp/export-tarball-* diff --git a/ops/bin/README b/ops/bin/README new file mode 100644 index 0000000..0dff97a --- /dev/null +++ b/ops/bin/README @@ -0,0 +1,22 @@ +This is the seti_boinc ops/bin directory. Here you will find all kinds +of script/binary tools for day-to-day operations of seti (and other +affiliated projects). If you add anything, please note here where you +expect the actually script to live and run in normal life. + +### The following are in ~seti/dr2_data/productions/scripts and are +### used for data_pipeline management. Note that data_flow.cfg is a +### perl "include file" that many of the other scripts read in before +### executing. Maybe that should go elsewhere at some point. + +avg_file_create_dir +count_hard_links.csh +count_wugs_wus_by_tape.csh +data_flow.cfg +erase_data_drive +file_to_thumper +fill_xfer_to_hpss +make_hpss_script +make_xfer_script +run_jan.csh +seti_hsi.csh +xfer_to_hpss diff --git a/ops/bin/avg_file_create_dir b/ops/bin/avg_file_create_dir new file mode 100755 index 0000000..8ba036f --- /dev/null +++ b/ops/bin/avg_file_create_dir @@ -0,0 +1,21 @@ +#! /usr/bin/env perl + +$now = time(); +@files = `/bin/ls -1`; +$alltime = 0; +$count = 0; +foreach $file (@files) { + chomp $file; + if (($now - (stat($file))[9]) > 5184000) { + print "$file too old - skipping\n"; + } + else { + $count++; + $alltime += (stat($file))[9]; + print "$file\n"; + } + } +$avg = $alltime / $count; +print "average mtime: $avg (" . localtime($avg) . ")\n"; +exit (0); + diff --git a/ops/bin/count_hard_links.csh b/ops/bin/count_hard_links.csh new file mode 100755 index 0000000..34d6c2f --- /dev/null +++ b/ops/bin/count_hard_links.csh @@ -0,0 +1,3 @@ +#! /bin/csh + +echo $1" "`stat -c%h $1` diff --git a/ops/bin/count_wugs_wus_by_tape.csh b/ops/bin/count_wugs_wus_by_tape.csh new file mode 100755 index 0000000..06a385f --- /dev/null +++ b/ops/bin/count_wugs_wus_by_tape.csh @@ -0,0 +1,39 @@ +#! /bin/csh + + +if(${#argv} == 0 || $1 == "-h") then + echo " " + echo spikesbytape db tape_name + echo " " + exit +endif + +set DB = $1 +set TAPE = $2 + +source ~davea/seti/db/$DB + +dbaccess -e - << HERE + +database sah2; + +select tape.id, tape.name, tape.beam, tape.last_block_done, + count(workunit_grp.id) from tape, workunit_grp + where + tape.name = "$TAPE" and + workunit_grp.tape_info = tape.id + group by + tape.id, tape.name, tape.beam, tape.last_block_done + order by + tape.name, tape.beam; + +select count(workunit.id)/3584 from workunit, workunit_grp, tape where + workunit.group_info = workunit_grp.id and + workunit_grp.tape_info = tape.id and + tape.name = "$TAPE"; + + +HERE + +echo "checking down at HPSS:" +/disks/thumper/raid5_d/users/seti/dr2_data/production/scripts/seti_hsi.csh --list $TAPE diff --git a/ops/bin/data_flow.cfg b/ops/bin/data_flow.cfg new file mode 100755 index 0000000..e1bf8ab --- /dev/null +++ b/ops/bin/data_flow.cfg @@ -0,0 +1,98 @@ +#! /usr/bin/env perl + +# data_flow.cfg - edit all data_flow config stuff here for scripts in: +$scriptdir = "/disks/thumper/raid5_d/users/seti/dr2_data/production/scripts"; + +# list of possible data drives and where they should be mounted +@drive_array=("/dev/sda1","/dev/sdb1","/dev/sdc1","/dev/sdd1"); +@drive_mount_points=("/mnt/seti_data_1","/mnt/seti_data_2","/mnt/seti_data_3","/mnt/seti_data_4"); +$num_drives = scalar(@drive_array); + +# a list of possible block sizes for data drives (to check for proper disk in fdisk) +@partition_block_sizes=(488384001,732572001); + +# where to write data to (via scp) +$scpdatato = 'seti@thumper:/mydisks/raid5_d/users/seti/dr2_data/production/processing'; + +# NFS directory where files are going to AS WELL AS +# where to check for full disk (via nfs/df) and where files will end up: +$nfsdatato = "/disks/thumper/raid5_d/users/seti/dr2_data/production/processing"; +$fullcheck = $nfsdatato; + +# NFS directory where processing is +$processing_dir = $fullcheck; # same as nfsdatati/fullcheck usually + +# NFS directory where xfer_to_hpss is +$xfer_to_hpss_dir = "/disks/thumper/raid5_d/users/seti/dr2_data/production/xfer_to_hpss"; + +# NFS directory where trigger files are +$triggers_dir = "/disks/thumper/raid5_d/users/seti/dr2_data/production/trigger_files"; + +# trigger files: +$xferring_to_hpss = "$triggers_dir/xferring_to_hpss"; + +# buffer space (in bytes) for full disk (i.e. how much under 100% full before we just call it full) +$buffer = 60000000000; # ~60GB + +# md5sum size (bytes) +$md5size = 1073741824; + +# where to write md5s to (via scp) +$scpmd5to = 'seti@thumper:/mydisks/raid5_d/users/seti/dr2_data/production/md5'; + +# email recipients +$mailto = 'mattl@ssl.berkeley.edu jeffc@ssl.berkeley.edu'; + +# lock file to avoid restart: +$lockfile = "/root/lock.data_flow_lando"; + +$awk = "/bin/awk"; +$cat = "/bin/cat"; +$df = "/bin/df"; +$fdisk = "/sbin/fdisk"; +$grep = "/bin/grep"; +$head = "/usr/bin/head"; +$hsi = "$scriptdir/seti_hsi.csh"; +$ln = "/bin/ln"; +$ls = "/bin/ls"; +$mail = "/bin/mail"; +$md5sum = "/usr/bin/md5sum"; +$mke2fs = "/sbin/mke2fs"; +$mount = "/bin/mount"; +$mv = "/bin/mv"; +$ps = "/bin/ps"; +$rm = "/bin/rm"; +$scp = "/usr/bin/scp"; +$su = "/bin/su"; +$tail = "/usr/bin/tail"; +$touch = "/bin/touch"; +$umount = "/bin/umount"; +$wc = "/usr/bin/wc"; +$whoami = "/usr/bin/whoami"; + +# MODULES TO INCLUDE: + +use File::Basename; + +# FUNCTIONS: + +sub send_mail { + my $subject = $_[0]; + my $message = $_[1]; + open (SENDMAIL,"|$mail -s \"$subject\" $mailto"); + print SENDMAIL "$message\n"; + close (SENDMAIL); + return 0; + } + +# PRELIMINARY CHECKS: + +$hostname = `/usr/ucb/hostname`; chomp $hostname; +$whoami = `/usr/bin/whoami`; chomp $whoami; + +if ($whoami ne "root") { + print "sorry - all data flow scripts must be run as root\n"; + print "(don't worry - we'll su to seti as needed)\n"; + exit(0); + } + diff --git a/ops/bin/erase_data_drive b/ops/bin/erase_data_drive new file mode 100755 index 0000000..7cd755f --- /dev/null +++ b/ops/bin/erase_data_drive @@ -0,0 +1,101 @@ +#! /usr/bin/env perl + +# where is the configuration file? +$cfgfile = "/disks/thumper/raid5_d/users/seti/dr2_data/production/scripts/data_flow.cfg"; + +# read it in and continue... +$cfg = ""; +open (CNFFILE,$cfgfile) or die "cannot open configuration file: $cfgfile\nmake sure this variable is set properly"; +while () { $cfg .= $_ } +close (CNFFILE); +eval $cfg; + +$drivedev = $ARGV[0]; +if ($drivedev eq "" || $drivedev eq "-h" || $drivedev eq "--help") { + print "usage: erase_data_drive device_name (i.e. /dev/sdx2)\n"; + print " note: will only work on unmounted drives\n\n"; + exit (1); + } + +if (! -b $drivedev) { + print "no such device: $drivedev - exiting...\n"; + exit (1); + } + +$ismounted = `$mount | $awk '\$1 == "$drivedev"'`; +if ($ismounted ne "") { + print "drive $drivedev currently mounted! exiting...\n"; + exit (1); + } + +$tmpmount = "/mnt/temp_data_$$"; +print "making temporary mount point: $tmpmount...\n"; +mkdir $tmpmount || die "cannot make mount point: $tmpmount"; + +print "mounting $drivedev on $tmpmount...\n"; +system ("$mount $drivedev $tmpmount"); + +print ".AO_DATA number on the data drive is: "; +$aonumber = ""; +if (-f "$tmpmount/.AO_DATA") { + $aonumber = `$cat $tmpmount/.AO_DATA`; + chomp $aonumber; + } +if ($aonumber eq "") { + print "there is no number! exiting...\n"; + chdir ("/root"); + system ("$umount $drivedev"); + rmdir $tmpmount || die "cannot remove mount point: $tmpmount"; + exit (1); + } +print "$aonumber\n"; + +print "double checking data files are elsewhere...\n"; +chdir ($tmpmount); # go to mounted drive +@datafiles = `$ls -1 [0-9][0-9][a-z][a-z][0-9][0-9][a-z][a-z]`; +foreach $datafile (@datafiles) { + chomp $datafile; + print " datafile: $datafile "; + if (-f "$xfer_to_hpss_dir/$datafile") { print "in xfer_to_hpss"; } + elsif (-f "$processing_dir/$datafile") { print "in processing"; } + else { + print "- checking at hpss... "; + $hsicommand = "$su seti -c \"$hsi --list $datafile\""; + $retval = system ($hsicommand . "> /dev/null"); + $retval = $retval >> 8; + if ($retval == 0) { print "yes"; } + else { + # file not at hpss, or anywhere obvious + print "no! can't find anywhere obvious - exiting...\n"; + chdir ("/root"); + system ("$umount $drivedev"); + rmdir $tmpmount || die "cannot remove mount point: $tmpmount"; + exit (1); + } + } + print "\n"; + } +chdir ("/root"); + +print "all files are somewhere else! moving on...\n"; +print "umounting $drivedev...\n"; +system ("$umount $drivedev"); + +print "okay here we go: WIPING DRIVE with mke2fs...\n"; +system ("$mke2fs -m 1 -T largefile4 -j $drivedev"); + +print "mounting empty $drivedev on $tmpmount...\n"; +system ("$mount $drivedev $tmpmount"); + +print "creating .AO_DATA file with number $aonumber...\n"; +open (AODATA,">$tmpmount/.AO_DATA"); +print AODATA $aonumber; +close (AODATA); +chmod 0000, "$tmpmount/.AO_DATA"; +chdir ("/root"); # just to be sure we can unmount + +print "umounting $drivedev one last time...\n"; +system ("$umount $drivedev"); + +print "removing temporary mount point: $tmpmount...\n"; +rmdir $tmpmount || die "cannot remove mount point: $tmpmount"; diff --git a/ops/bin/file_to_thumper b/ops/bin/file_to_thumper new file mode 100755 index 0000000..2bb586d --- /dev/null +++ b/ops/bin/file_to_thumper @@ -0,0 +1,79 @@ +#! /usr/bin/env perl + +# where is the configuration file? +$cfgfile = "/disks/thumper/raid5_d/users/seti/dr2_data/production/scripts/data_flow.cfg"; + +# read it in and continue... +$cfg = ""; +open (CNFFILE,$cfgfile) or die "cannot open configuration file: $cfgfile\nmake sure this variable is set properly"; +while () { $cfg .= $_ } +close (CNFFILE); +eval $cfg; + +$file = $ARGV[0]; +if ($file eq "" || $file eq "-h" || $file eq "--help") { + print "file_to_thumper full_path_to_file :\n copy data file to $nfsdatato (and do md5 checks)\n"; + exit (1); + } + +if (ord($file) ne ord("/")) { + print "$file doesn't big with a \"/\" - make sure you enter a full path!\n"; + exit (1); + } + +if (! -f $file) { + print "cannot find file: $file\n"; + exit (1); + } + +$basefile = basename($file); + +# will file fit on remote partition? + +$filesize = `$ls -l $file | $awk '{print \$5}'`; +chomp $filesize; +$spaceleft = `$df -P $fullcheck | $tail -1 | $awk '{print \$4}'`; +chomp $spaceleft; +$spaceleft *= 1024; +if (($filesize + $buffer) > $spaceleft) { + print "file: $file is too big to currently fit on $nfsdatato!\n"; + exit (1); + } + +# move the file, etc. + +print "file: $file (get md5s... "; +# get initial md5s +$headmd5 = `$head -c $md5size $file | $md5sum | awk '{print \$1}'`; +chomp $headmd5; +$tailmd5 = `$tail -c $md5size $file | $md5sum | awk '{print \$1}'`; +chomp $tailmd5; +open (OUTFILE,">${file}.md5_head_${md5size}"); +print OUTFILE $headmd5 . "\n"; +close (OUTFILE); +open (OUTFILE,">${file}.md5_tail_${md5size}"); +print OUTFILE $tailmd5 . "\n"; +close (OUTFILE); +# copy everything over +print "scp files... "; +system ("$su - seti -c \"$scp $file ${scpdatato}/${basefile}.copying\" > /dev/null 2>&1"); +system ("$su - seti -c \"$scp ${file}.md5_head_${md5size} $scpmd5to\" > /dev/null 2>&1"); +system ("$su - seti -c \"$scp ${file}.md5_tail_${md5size} $scpmd5to\" > /dev/null 2>&1"); +# check remote md5s +print "checking md5s... "; +$rheadmd5 = `$head -c $md5size $nfsdatato/${basefile}.copying | $md5sum | awk '{print \$1}'`; +chomp $rheadmd5; +$rtailmd5 = `$tail -c $md5size $nfsdatato/${basefile}.copying | $md5sum | awk '{print \$1}'`; +chomp $rtailmd5; +if ($rheadmd5 ne $headmd5 || $rtailmd5 ne $tailmd5) { + print "failure!)\n"; + send_mail("ALERT: file_to_thumper md5 mismatch","The file: $file failed to copy from $hostname to thumper due to md5 mismatch."); + system ("$touch $lockfile"); + exit(1); +} +system ("$su - seti -c \"$mv $nfsdatato/${basefile}.copying $nfsdatato/${basefile}\" > /dev/null 2>&1"); +print "unlinking... "; +#unlink "$file"; +unlink "${file}.md5_head_${md5size}"; +unlink "${file}.md5_tail_${md5size}"; +print "done!)\n"; diff --git a/ops/bin/fill_xfer_to_hpss b/ops/bin/fill_xfer_to_hpss new file mode 100755 index 0000000..0bbd6a3 --- /dev/null +++ b/ops/bin/fill_xfer_to_hpss @@ -0,0 +1,54 @@ +#! /usr/bin/env perl + +# where is the configuration file? +$cfgfile = "/disks/thumper/raid5_d/users/seti/dr2_data/production/scripts/data_flow.cfg"; + +# read it in and continue... +$cfg = ""; +open (CNFFILE,$cfgfile) or die "cannot open configuration file: $cfgfile\nmake sure this variable is set properly"; +while () { $cfg .= $_ } +close (CNFFILE); +eval $cfg; + +print "checking xfer_to_hpss directory for excess files..."; +chdir ($xfer_to_hpss_dir); +@datafiles = `$ls -1 [0-9][0-9][a-z][a-z][0-9][0-9][a-z][a-z]`; +foreach $datafile (@datafiles) { + chomp $datafile; + print "datafile: $datafile "; + $hsicommand = "$su seti -c \"$hsi --list $datafile\""; + $retval = system ($hsicommand . "> /dev/null"); + $retval = $retval >> 8; + if ($retval == 0) { + print "already at hpss - removing hard link"; + system ("$su seti -c \"$rm $xfer_to_hpss_dir/$datafile\""); + } + else { print " - not transferred yet"; } + print "\n"; + } + +chdir ($processing_dir); +@datafiles = `$ls -1 [0-9][0-9][a-z][a-z][0-9][0-9][a-z][a-z]`; +foreach $datafile (@datafiles) { + chomp $datafile; + print "datafile: $datafile "; + if (-f "${datafile}.at_hpss") { print "- .at_hpss exists - skipping"; } + else { + if (-f "$xfer_to_hpss_dir/$datafile") { print "- already hard linked in xfer_to_hpss - skipping"; } + else { + print "- checking at hpss... "; + $hsicommand = "$su seti -c \"$hsi --list $datafile\""; + $retval = system ($hsicommand . "> /dev/null"); + $retval = $retval >> 8; + if ($retval == 0) { print "already at hpss - skipping"; } + else { + # file here and not at hpss, so make hard link in xfer to hpss dir: + system ("$su seti -c \"$ln $datafile $xfer_to_hpss_dir/$datafile\""); + print " - made hard link in xfer_to_hpss"; + } + } + } + print "\n"; + } +exit (0); + diff --git a/ops/bin/make_hpss_script b/ops/bin/make_hpss_script new file mode 100755 index 0000000..8d4b836 --- /dev/null +++ b/ops/bin/make_hpss_script @@ -0,0 +1,12 @@ +#! /bin/csh + +# make_hpss_script - makes xfer_to_hpss script for all ??????? files in current directory + +set CURDIR = `/bin/pwd` + +echo '#! /bin/csh' +echo " " + +foreach i (`/bin/ls -1 [0-9][0-9][a-z][a-z][0-9][0-9][a-z][a-z]`) + echo /disks/thumper/raid5_d/users/seti/dr2_data/production/scripts/seti_hsi.csh --put $i +end diff --git a/ops/bin/make_xfer_script b/ops/bin/make_xfer_script new file mode 100755 index 0000000..92d5108 --- /dev/null +++ b/ops/bin/make_xfer_script @@ -0,0 +1,12 @@ +#! /bin/csh + +# make_xfer_script - makes file_to_thumper script for all ??????? files in current directory + +set CURDIR = `/bin/pwd` + +echo '#! /bin/csh' +echo " " + +foreach i (`/bin/ls -1 [0-9][0-9][a-z][a-z][0-9][0-9][a-z][a-z]`) + echo /disks/thumper/raid5_d/users/seti/dr2_data/production/scripts/file_to_thumper $CURDIR/$i +end diff --git a/ops/bin/run_jan.csh b/ops/bin/run_jan.csh new file mode 100755 index 0000000..1f864c2 --- /dev/null +++ b/ops/bin/run_jan.csh @@ -0,0 +1,6 @@ +#! /bin/csh + +source ~davea/seti/db/master +# ~boincadm/projects/sah/bin/splitter_janitor --dir . +~boincadm/projects/sah/bin/splitter_janitor +echo exit status was $status diff --git a/ops/bin/seti_hsi.csh b/ops/bin/seti_hsi.csh new file mode 100755 index 0000000..82ff368 --- /dev/null +++ b/ops/bin/seti_hsi.csh @@ -0,0 +1,99 @@ +#! /bin/csh + +# This script gets from and puts to HPSS. It does checks on a put. +# It can also list files and directories. + +set action = $1 +set filename = $2 +set target_dir = seti/dr2_data/production +set throttle_speed = "32M" # 32Mbps +set md5_check_length = 1048576 +set retval = 0 +if (`hostname` == "ewen") then + alias hsi hsi.hpss +endif + +hsi touch hpss_ping >& /dev/null +if($status == 1) then + echo hpss is down + exit 1 +endif + +if($action == "--list") then + hsi "ls -l $target_dir/${filename}" |& tail -1 > /tmp/$filename.ls + if ($status) then + echo "$filename not found" + set retval = 1 + else + cat /tmp/$filename.ls + endif + \rm /tmp/$filename.ls + +else if($action == "--dir") then + hsi "ls -l $target_dir" |& tail --lines=+31 + +else if ($action == "--get") then + touch $filename.at_hpss + hsi "firewall -on ; get $target_dir/$filename" | throttle $throttle_speed > $filename + +else if ($action == "--put") then + set retry = 1 + while ($retry == 1) + echo starting the put of $filename + throttle $throttle_speed < $filename | hsi "firewall -on ; put - : $target_dir/$filename" + # start transfer check + set local_length = `ls -l $filename | awk '{print $5}'` + set hpss_length = `hsi list -l $target_dir/$filename | & tail -1 | awk '{print $5}'` + if ($local_length != $hpss_length) then + echo "$filename transfer was bad (file length mismatch)" + set retval = 1 + exit 1 + else + hsi "firewall -on ; get -O ::$md5_check_length /tmp/$filename.start.hpss : $target_dir/$filename" + head -c $md5_check_length $filename > /tmp/$filename.start.local + set hpss_md5 = `md5sum /tmp/$filename.start.hpss | awk '{print $1}'` + set local_md5 = `md5sum /tmp/$filename.start.local | awk '{print $1}'` + if ($hpss_md5 != $local_md5) then + echo "$filename transfer was bad (md5 mismatch at start of file)" + set retval = 1 + else + set end_offset = `python -c "print $hpss_length - $md5_check_length"` + hsi "firewall -on ; get -O ${end_offset}::$md5_check_length /tmp/$filename.end.hpss : $target_dir/$filename" + tail --bytes=$md5_check_length $filename > /tmp/$filename.end.local + set hpss_md5 = `md5sum /tmp/$filename.end.hpss | awk '{print $1}'` + set local_md5 = `md5sum /tmp/$filename.end.local | awk '{print $1}'` + if ($hpss_md5 != $local_md5) then + echo "$filename transfer was bad (md5 mismatch at end of file)" + set retval = 1 + endif + \rm /tmp/$filename.end.hpss + \rm /tmp/$filename.end.local + endif + \rm /tmp/$filename.start.hpss + \rm /tmp/$filename.start.local + endif + if ($retval == 0) then + echo "$filename transfer was good" + set retry = 0 + else + set retry = 1 + echo retrying in 60 seconds + sleep 60 + endif + # end transfer check + end +else if ($action == "--check") then + # if the test ping failed above, we already exited, otherwise print success + echo "hpss is up" + set retval = 0 + +else + echo "usage $0:t --list | --dir | --get | --put | --check" + set retval = 1 + +endif + +echo " " +echo " " + +exit $retval diff --git a/ops/bin/xfer_to_hpss b/ops/bin/xfer_to_hpss new file mode 100755 index 0000000..e212da0 --- /dev/null +++ b/ops/bin/xfer_to_hpss @@ -0,0 +1,29 @@ +#! /usr/bin/env perl + +# where is the configuration file? +$cfgfile = "/disks/thumper/raid5_d/users/seti/dr2_data/production/scripts/data_flow.cfg"; + +# read it in and continue... +$cfg = ""; +open (CNFFILE,$cfgfile) or die "cannot open configuration file: $cfgfile\nmake sure this variable is set properly"; +while () { $cfg .= $_ } +close (CNFFILE); +eval $cfg; + +$file = $ARGV[0]; +if ($file eq "" || $file eq "-h" || $file eq "--help") { + print "xfer_to_hpss full_path_to_file :\n copy data file to hpss\n"; + exit (1); + } + +if (ord($file) ne ord("/")) { + print "$file doesn't big with a \"/\" - make sure you enter a full path!\n"; + exit (1); + } + +if (! -f $file) { + print "cannot find file: $file\n"; + exit (1); + } + + diff --git a/setiathome.pbproj/project.pbxproj b/setiathome.pbproj/project.pbxproj new file mode 100644 index 0000000..1627a16 --- /dev/null +++ b/setiathome.pbproj/project.pbxproj @@ -0,0 +1,2497 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 38; + objects = { + 0249A665FF388DC511CA2CEA = { + isa = PBXApplicationReference; + path = setiathome.app; + refType = 3; + }; + 0249A669FF388E3911CA2CEA = { + isa = PBXFileReference; + name = "libstdc++.a"; + path = "/usr/lib/libstdc++.a"; + refType = 0; + }; +//020 +//021 +//022 +//023 +//024 +//040 +//041 +//042 +//043 +//044 + 04313892FE3035C9C02AAC07 = { + buildActionMask = 2147483647; + files = ( + ); + isa = PBXRezBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; +//040 +//041 +//042 +//043 +//044 +//050 +//051 +//052 +//053 +//054 + 05952DFCFFF02D1B11CA0E50 = { + buildRules = ( + ); + buildSettings = { + COPY_PHASE_STRIP = NO; + OPTIMIZATION_CFLAGS = "-O0"; + }; + isa = PBXBuildStyle; + name = Development; + }; + 05952DFDFFF02D1B11CA0E50 = { + buildRules = ( + ); + buildSettings = { + COPY_PHASE_STRIP = YES; + }; + isa = PBXBuildStyle; + name = Deployment; + }; +//050 +//051 +//052 +//053 +//054 +//060 +//061 +//062 +//063 +//064 + 0640BAA4FFF0323A11CA0E50 = { + isa = PBXFrameworkReference; + name = ApplicationServices.framework; + path = /System/Library/Frameworks/ApplicationServices.framework; + refType = 0; + }; + 0640BAA5FFF0323A11CA0E50 = { + isa = PBXFrameworkReference; + name = CoreServices.framework; + path = /System/Library/Frameworks/CoreServices.framework; + refType = 0; + }; +//060 +//061 +//062 +//063 +//064 +//190 +//191 +//192 +//193 +//194 + 195DF8C9FE9D4F0611CA2CBB = { + children = ( + 0249A665FF388DC511CA2CEA, + ); + isa = PBXGroup; + name = Products; + refType = 4; + }; +//190 +//191 +//192 +//193 +//194 +//200 +//201 +//202 +//203 +//204 + 20286C28FDCF999611CA2CEA = { + buildStyles = ( + 05952DFCFFF02D1B11CA0E50, + 05952DFDFFF02D1B11CA0E50, + ); + hasScannedForEncodings = 1; + isa = PBXProject; + mainGroup = 20286C29FDCF999611CA2CEA; + projectDirPath = ""; + targets = ( + 20286C34FDCF999611CA2CEA, + ); + }; + 20286C29FDCF999611CA2CEA = { + children = ( + AA3FFC8F053BDEC000164350, + AA3FFC00053BCCC700164350, + AA6AA8C804113B7B00A80164, + 20286C2AFDCF999611CA2CEA, + 20286C2CFDCF999611CA2CEA, + 20286C32FDCF999611CA2CEA, + 195DF8C9FE9D4F0611CA2CBB, + ); + isa = PBXGroup; + name = "«PROJECTNAME»"; + path = ""; + refType = 4; + }; + 20286C2AFDCF999611CA2CEA = { + children = ( + AA763A9B0400775C00A80164, + AA3FFB63053BC42600164350, + AA763A910400775C00A80164, + AA3FFB0B053BC3AA00164350, + AA763A930400775C00A80164, + AA763A940400775C00A80164, + AA763A950400775C00A80164, + AA3FFB0C053BC3AA00164350, + AA763A970400775C00A80164, + AA3FFB64053BC42600164350, + AABC80520410BC6E00A80164, + AA763A9C0400775C00A80164, + AA763A9E0400775C00A80164, + AA763A9D0400775C00A80164, + AA763A9F0400775C00A80164, + AA763AB00400777000A80164, + AA763AB20400777000A80164, + AABC80550410BCCF00A80164, + AABC80540410BCCF00A80164, + AADBC6EE04226C0F00A80164, + AADBC6EF04226C0F00A80164, + AA763AB30400777000A80164, + AA763AB10400777000A80164, + AA3FFB69053BC4DA00164350, + AA3FFBF2053BC99600164350, + AA3FFBF3053BC99600164350, + AA3FFBF8053BCAAD00164350, + AA3FFBF9053BCAAD00164350, + ); + isa = PBXGroup; + name = "BOINC Sources"; + path = ""; + refType = 4; + }; + 20286C2CFDCF999611CA2CEA = { + children = ( + ); + isa = PBXGroup; + name = Resources; + path = ""; + refType = 4; + }; + 20286C32FDCF999611CA2CEA = { + children = ( + 20286C33FDCF999611CA2CEA, + 0249A669FF388E3911CA2CEA, + 0640BAA4FFF0323A11CA0E50, + 0640BAA5FFF0323A11CA0E50, + AA763B590400789200A80164, + AA763B5B040078AC00A80164, + AA763B5C040078AC00A80164, + AA763B6104007BB800A80164, + AA6AA8C60410C8B300A80164, + ); + isa = PBXGroup; + name = "External Frameworks and Libraries"; + path = ""; + refType = 4; + }; + 20286C33FDCF999611CA2CEA = { + isa = PBXFrameworkReference; + name = Carbon.framework; + path = /System/Library/Frameworks/Carbon.framework; + refType = 0; + }; + 20286C34FDCF999611CA2CEA = { + buildPhases = ( + 20286C35FDCF999611CA2CEA, + 20286C36FDCF999611CA2CEA, + 20286C38FDCF999611CA2CEA, + 20286C3BFDCF999611CA2CEA, + 04313892FE3035C9C02AAC07, + ); + buildSettings = { + FRAMEWORK_SEARCH_PATHS = ""; + HEADER_SEARCH_PATHS = ""; + INSTALL_PATH = "$(HOME)/Applications"; + LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/3.1; + OTHER_CFLAGS = "-DHAVE_DIRENT_H -DHAVE_SYS_RESOURCE_H -DHAVE_INTTYPES_H -DHAVE_UNISTD_H -DHAVE_SIGNAL_H -DHAVE_SYS_TIME_H -DFFTW_ENABLE_FLOAT -DBOINC_APP_GRAPHICS -DHAVE_SYS_SHM_H -DHAVE_SYS_IPC_H -DHAVE_SYS_MOUNT_H -DCLIENT -DVERSION_MINOR=00 -DVERSION_MAJOR=4 -DHAVE_ATOLL -DFAR="; + OTHER_LDFLAGS = ""; + OTHER_REZFLAGS = ""; + PRODUCT_NAME = setiathome; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas"; + WRAPPER_EXTENSION = app; + }; + dependencies = ( + ); + isa = PBXApplicationTarget; + name = setiathome; + productInstallPath = "$(HOME)/Applications"; + productName = "«PROJECTNAME»"; + productReference = 0249A665FF388DC511CA2CEA; + productSettingsXML = " + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + setiathome + CFBundleIconFile + + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 0.1 + CSResourcesFileMapped + + + +"; + }; + 20286C35FDCF999611CA2CEA = { + buildActionMask = 2147483647; + files = ( + AA763AAC0400775C00A80164, + AA763AAD0400775C00A80164, + AA763AB40400777000A80164, + AA763AB50400777000A80164, + AABC80570410BCCF00A80164, + AABC806A0410BD2600A80164, + AABC806E0410BD2800A80164, + AABC80730410BEEE00A80164, + AABC80790410C06700A80164, + AA6AA8B10410C34000A80164, + AADBC6F104226C0F00A80164, + AA3FFB39053BC3EB00164350, + AA3FFB3B053BC3EB00164350, + AA3FFB3D053BC3EB00164350, + AA3FFB3F053BC3EB00164350, + AA3FFB41053BC3EB00164350, + AA3FFB43053BC3EB00164350, + AA3FFB46053BC3EB00164350, + AA3FFB48053BC3EB00164350, + AA3FFB4B053BC3EB00164350, + AA3FFB4E053BC3EB00164350, + AA3FFB4F053BC3EB00164350, + AA3FFB51053BC3EB00164350, + AA3FFB54053BC3EB00164350, + AA3FFB56053BC3EB00164350, + AA3FFB58053BC3EB00164350, + AA3FFB5A053BC3EB00164350, + AA3FFB5C053BC3EB00164350, + AA3FFB5E053BC3EB00164350, + AA3FFB60053BC3EB00164350, + AA3FFB62053BC3EB00164350, + AA3FFB6A053BC4DA00164350, + AA3FFBF5053BC99600164350, + AA3FFBFB053BCAAD00164350, + AA3FFBFF053BCAF200164350, + AA3FFC43053BCCE200164350, + AA3FFC44053BCCE200164350, + AA3FFC4B053BCCE200164350, + AA3FFC51053BCCE200164350, + AA3FFC5D053BCCE200164350, + AA3FFC60053BCCE200164350, + AA3FFC6B053BCCE200164350, + AA3FFC73053BCCE200164350, + AA3FFC76053BCCE200164350, + AA3FFC77053BCCE200164350, + AA3FFC78053BCCE200164350, + AA3FFC79053BCCE200164350, + AA3FFC7D053BCCE200164350, + AA3FFC86053BCDAD00164350, + AA3FFC8A053BD34A00164350, + AA3FFC8E053BDE9100164350, + ); + isa = PBXHeadersBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 20286C36FDCF999611CA2CEA = { + buildActionMask = 2147483647; + files = ( + ); + isa = PBXResourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 20286C38FDCF999611CA2CEA = { + buildActionMask = 2147483647; + files = ( + AA763AAE0400775C00A80164, + AA763AAF0400775C00A80164, + AA763AB60400777000A80164, + AA763AB70400777000A80164, + AABC80530410BC6E00A80164, + AABC80560410BCCF00A80164, + AABC80720410BEED00A80164, + AADBC6F004226C0F00A80164, + AA3FFB0D053BC3AA00164350, + AA3FFB0E053BC3AA00164350, + AA3FFB3A053BC3EB00164350, + AA3FFB3C053BC3EB00164350, + AA3FFB3E053BC3EB00164350, + AA3FFB40053BC3EB00164350, + AA3FFB42053BC3EB00164350, + AA3FFB44053BC3EB00164350, + AA3FFB45053BC3EB00164350, + AA3FFB47053BC3EB00164350, + AA3FFB4A053BC3EB00164350, + AA3FFB4C053BC3EB00164350, + AA3FFB4D053BC3EB00164350, + AA3FFB50053BC3EB00164350, + AA3FFB52053BC3EB00164350, + AA3FFB53053BC3EB00164350, + AA3FFB55053BC3EB00164350, + AA3FFB57053BC3EB00164350, + AA3FFB59053BC3EB00164350, + AA3FFB5B053BC3EB00164350, + AA3FFB5D053BC3EB00164350, + AA3FFB5F053BC3EB00164350, + AA3FFB61053BC3EB00164350, + AA3FFB65053BC42600164350, + AA3FFB66053BC42600164350, + AA3FFBF4053BC99600164350, + AA3FFBFA053BCAAD00164350, + AA3FFBFE053BCAF200164350, + AA3FFC45053BCCE200164350, + AA3FFC46053BCCE200164350, + AA3FFC47053BCCE200164350, + AA3FFC48053BCCE200164350, + AA3FFC49053BCCE200164350, + AA3FFC4A053BCCE200164350, + AA3FFC4C053BCCE200164350, + AA3FFC4D053BCCE200164350, + AA3FFC4E053BCCE200164350, + AA3FFC4F053BCCE200164350, + AA3FFC50053BCCE200164350, + AA3FFC52053BCCE200164350, + AA3FFC53053BCCE200164350, + AA3FFC54053BCCE200164350, + AA3FFC55053BCCE200164350, + AA3FFC56053BCCE200164350, + AA3FFC57053BCCE200164350, + AA3FFC58053BCCE200164350, + AA3FFC59053BCCE200164350, + AA3FFC5A053BCCE200164350, + AA3FFC5B053BCCE200164350, + AA3FFC5C053BCCE200164350, + AA3FFC5E053BCCE200164350, + AA3FFC5F053BCCE200164350, + AA3FFC61053BCCE200164350, + AA3FFC62053BCCE200164350, + AA3FFC63053BCCE200164350, + AA3FFC64053BCCE200164350, + AA3FFC65053BCCE200164350, + AA3FFC66053BCCE200164350, + AA3FFC67053BCCE200164350, + AA3FFC68053BCCE200164350, + AA3FFC69053BCCE200164350, + AA3FFC6A053BCCE200164350, + AA3FFC6C053BCCE200164350, + AA3FFC6D053BCCE200164350, + AA3FFC6E053BCCE200164350, + AA3FFC6F053BCCE200164350, + AA3FFC70053BCCE200164350, + AA3FFC71053BCCE200164350, + AA3FFC72053BCCE200164350, + AA3FFC74053BCCE200164350, + AA3FFC75053BCCE200164350, + AA3FFC7A053BCCE200164350, + AA3FFC7B053BCCE200164350, + AA3FFC7C053BCCE200164350, + AA3FFC7E053BCCE200164350, + AA3FFC7F053BCCE200164350, + AA3FFC80053BCCE200164350, + AA3FFC81053BCCE200164350, + AA3FFC82053BCCE200164350, + AA3FFC83053BCCE200164350, + AA3FFC84053BCCE200164350, + AA3FFC89053BD34A00164350, + AA3FFC8D053BDE9100164350, + ); + isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 20286C3BFDCF999611CA2CEA = { + buildActionMask = 2147483647; + files = ( + AA763B5A0400789200A80164, + AA763B5E040078AC00A80164, + AA763B6304007BD100A80164, + AA763B8904007C2F00A80164, + AA763B8A04007C8A00A80164, + AA6AA8C70410C8B300A80164, + ); + isa = PBXFrameworksBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; +//200 +//201 +//202 +//203 +//204 +//AA0 +//AA1 +//AA2 +//AA3 +//AA4 + AA3FFB0B053BC3AA00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = gutil.C; + path = ../boinc/api/gutil.C; + refType = 4; + }; + AA3FFB0C053BC3AA00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = reduce.C; + path = ../boinc/api/reduce.C; + refType = 4; + }; + AA3FFB0D053BC3AA00164350 = { + fileRef = AA3FFB0B053BC3AA00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB0E053BC3AA00164350 = { + fileRef = AA3FFB0C053BC3AA00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB0F053BC3EB00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = analyze.h; + path = client/analyze.h; + refType = 4; + }; + AA3FFB10053BC3EB00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = analyzeFuncs.cpp; + path = client/analyzeFuncs.cpp; + refType = 4; + }; + AA3FFB11053BC3EB00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = analyzeFuncs.h; + path = client/analyzeFuncs.h; + refType = 4; + }; + AA3FFB12053BC3EB00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = analyzePoT.cpp; + path = client/analyzePoT.cpp; + refType = 4; + }; + AA3FFB13053BC3EB00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = analyzePoT.h; + path = client/analyzePoT.h; + refType = 4; + }; + AA3FFB14053BC3EB00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = analyzeReport.cpp; + path = client/analyzeReport.cpp; + refType = 4; + }; + AA3FFB15053BC3EB00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = analyzeReport.h; + path = client/analyzeReport.h; + refType = 4; + }; + AA3FFB16053BC3EB00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = chirpfft.cpp; + path = client/chirpfft.cpp; + refType = 4; + }; + AA3FFB17053BC3EB00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = chirpfft.h; + path = client/chirpfft.h; + refType = 4; + }; + AA3FFB18053BC3EB00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = fft8g.cpp; + path = client/fft8g.cpp; + refType = 4; + }; + AA3FFB19053BC3EB00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = fft8g.h; + path = client/fft8g.h; + refType = 4; + }; + AA3FFB1A053BC3EB00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = gasdev.cpp; + path = client/gasdev.cpp; + refType = 4; + }; + AA3FFB1B053BC3EB00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = gaussfit.cpp; + path = client/gaussfit.cpp; + refType = 4; + }; + AA3FFB1C053BC3EB00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = gaussfit.h; + path = client/gaussfit.h; + refType = 4; + }; + AA3FFB1D053BC3EB00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = gdata.cpp; + path = client/gdata.cpp; + refType = 4; + }; + AA3FFB1E053BC3EB00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = gdata.h; + path = client/gdata.h; + refType = 4; + }; + AA3FFB20053BC3EB00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = lcgamm.cpp; + path = client/lcgamm.cpp; + refType = 4; + }; + AA3FFB21053BC3EB00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = lcgamm.h; + path = client/lcgamm.h; + refType = 4; + }; + AA3FFB22053BC3EB00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = main.cpp; + path = client/main.cpp; + refType = 4; + }; + AA3FFB23053BC3EB00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = malloc_a.cpp; + path = client/malloc_a.cpp; + refType = 4; + }; + AA3FFB24053BC3EB00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = malloc_a.h; + path = client/malloc_a.h; + refType = 4; + }; + AA3FFB25053BC3EB00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = nr.h; + path = client/nr.h; + refType = 4; + }; + AA3FFB26053BC3EB00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = pulsefind.cpp; + path = client/pulsefind.cpp; + refType = 4; + }; + AA3FFB27053BC3EB00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = pulsefind.h; + path = client/pulsefind.h; + refType = 4; + }; + AA3FFB28053BC3EB00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = ran1.cpp; + path = client/ran1.cpp; + refType = 4; + }; + AA3FFB29053BC3EB00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = s_util.cpp; + path = client/s_util.cpp; + refType = 4; + }; + AA3FFB2A053BC3EB00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = s_util.h; + path = client/s_util.h; + refType = 4; + }; + AA3FFB2B053BC3EB00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = sah_gfx.cpp; + path = client/sah_gfx.cpp; + refType = 4; + }; + AA3FFB2C053BC3EB00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = sah_gfx.h; + path = client/sah_gfx.h; + refType = 4; + }; + AA3FFB2D053BC3EB00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = seti_header.cpp; + path = client/seti_header.cpp; + refType = 4; + }; + AA3FFB2E053BC3EB00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = seti_header.h; + path = client/seti_header.h; + refType = 4; + }; + AA3FFB2F053BC3EB00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = seti.cpp; + path = client/seti.cpp; + refType = 4; + }; + AA3FFB30053BC3EB00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = seti.h; + path = client/seti.h; + refType = 4; + }; + AA3FFB31053BC3EB00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = spike.cpp; + path = client/spike.cpp; + refType = 4; + }; + AA3FFB32053BC3EB00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = spike.h; + path = client/spike.h; + refType = 4; + }; + AA3FFB33053BC3EB00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = timecvt.cpp; + path = client/timecvt.cpp; + refType = 4; + }; + AA3FFB34053BC3EB00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = timecvt.h; + path = client/timecvt.h; + refType = 4; + }; + AA3FFB35053BC3EB00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = version.cpp; + path = client/version.cpp; + refType = 4; + }; + AA3FFB36053BC3EB00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = version.h; + path = client/version.h; + refType = 4; + }; + AA3FFB37053BC3EB00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = worker.cpp; + path = client/worker.cpp; + refType = 4; + }; + AA3FFB38053BC3EB00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = worker.h; + path = client/worker.h; + refType = 4; + }; + AA3FFB39053BC3EB00164350 = { + fileRef = AA3FFB0F053BC3EB00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB3A053BC3EB00164350 = { + fileRef = AA3FFB10053BC3EB00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB3B053BC3EB00164350 = { + fileRef = AA3FFB11053BC3EB00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB3C053BC3EB00164350 = { + fileRef = AA3FFB12053BC3EB00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB3D053BC3EB00164350 = { + fileRef = AA3FFB13053BC3EB00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB3E053BC3EB00164350 = { + fileRef = AA3FFB14053BC3EB00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB3F053BC3EB00164350 = { + fileRef = AA3FFB15053BC3EB00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB40053BC3EB00164350 = { + fileRef = AA3FFB16053BC3EB00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB41053BC3EB00164350 = { + fileRef = AA3FFB17053BC3EB00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB42053BC3EB00164350 = { + fileRef = AA3FFB18053BC3EB00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB43053BC3EB00164350 = { + fileRef = AA3FFB19053BC3EB00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB44053BC3EB00164350 = { + fileRef = AA3FFB1A053BC3EB00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB45053BC3EB00164350 = { + fileRef = AA3FFB1B053BC3EB00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB46053BC3EB00164350 = { + fileRef = AA3FFB1C053BC3EB00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB47053BC3EB00164350 = { + fileRef = AA3FFB1D053BC3EB00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB48053BC3EB00164350 = { + fileRef = AA3FFB1E053BC3EB00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB4A053BC3EB00164350 = { + fileRef = AA3FFB20053BC3EB00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB4B053BC3EB00164350 = { + fileRef = AA3FFB21053BC3EB00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB4C053BC3EB00164350 = { + fileRef = AA3FFB22053BC3EB00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB4D053BC3EB00164350 = { + fileRef = AA3FFB23053BC3EB00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB4E053BC3EB00164350 = { + fileRef = AA3FFB24053BC3EB00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB4F053BC3EB00164350 = { + fileRef = AA3FFB25053BC3EB00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB50053BC3EB00164350 = { + fileRef = AA3FFB26053BC3EB00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB51053BC3EB00164350 = { + fileRef = AA3FFB27053BC3EB00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB52053BC3EB00164350 = { + fileRef = AA3FFB28053BC3EB00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB53053BC3EB00164350 = { + fileRef = AA3FFB29053BC3EB00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB54053BC3EB00164350 = { + fileRef = AA3FFB2A053BC3EB00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB55053BC3EB00164350 = { + fileRef = AA3FFB2B053BC3EB00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB56053BC3EB00164350 = { + fileRef = AA3FFB2C053BC3EB00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB57053BC3EB00164350 = { + fileRef = AA3FFB2D053BC3EB00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB58053BC3EB00164350 = { + fileRef = AA3FFB2E053BC3EB00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB59053BC3EB00164350 = { + fileRef = AA3FFB2F053BC3EB00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB5A053BC3EB00164350 = { + fileRef = AA3FFB30053BC3EB00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB5B053BC3EB00164350 = { + fileRef = AA3FFB31053BC3EB00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB5C053BC3EB00164350 = { + fileRef = AA3FFB32053BC3EB00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB5D053BC3EB00164350 = { + fileRef = AA3FFB33053BC3EB00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB5E053BC3EB00164350 = { + fileRef = AA3FFB34053BC3EB00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB5F053BC3EB00164350 = { + fileRef = AA3FFB35053BC3EB00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB60053BC3EB00164350 = { + fileRef = AA3FFB36053BC3EB00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB61053BC3EB00164350 = { + fileRef = AA3FFB37053BC3EB00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB62053BC3EB00164350 = { + fileRef = AA3FFB38053BC3EB00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB63053BC42600164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = mac_app_opengl.C; + path = ../boinc/api/mac_app_opengl.C; + refType = 4; + }; + AA3FFB64053BC42600164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = mac_carbon_gl.C; + path = ../boinc/api/mac_carbon_gl.C; + refType = 4; + }; + AA3FFB65053BC42600164350 = { + fileRef = AA3FFB63053BC42600164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB66053BC42600164350 = { + fileRef = AA3FFB64053BC42600164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFB69053BC4DA00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = config.h; + path = ../boinc/config.h; + refType = 4; + }; + AA3FFB6A053BC4DA00164350 = { + fileRef = AA3FFB69053BC4DA00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFBF2053BC99600164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = app_ipc.C; + path = ../boinc/lib/app_ipc.C; + refType = 4; + }; + AA3FFBF3053BC99600164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = app_ipc.h; + path = ../boinc/lib/app_ipc.h; + refType = 4; + }; + AA3FFBF4053BC99600164350 = { + fileRef = AA3FFBF2053BC99600164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFBF5053BC99600164350 = { + fileRef = AA3FFBF3053BC99600164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFBF8053BCAAD00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = xml_util.C; + path = ../boinc/lib/xml_util.C; + refType = 4; + }; + AA3FFBF9053BCAAD00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = xml_util.h; + path = ../boinc/lib/xml_util.h; + refType = 4; + }; + AA3FFBFA053BCAAD00164350 = { + fileRef = AA3FFBF8053BCAAD00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFBFB053BCAAD00164350 = { + fileRef = AA3FFBF9053BCAAD00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFBFC053BCAF200164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = schema_master.cpp; + path = db/schema_master.cpp; + refType = 4; + }; + AA3FFBFD053BCAF200164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = schema_master.h; + path = db/schema_master.h; + refType = 4; + }; + AA3FFBFE053BCAF200164350 = { + fileRef = AA3FFBFC053BCAF200164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFBFF053BCAF200164350 = { + fileRef = AA3FFBFD053BCAF200164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC00053BCCC700164350 = { + children = ( + AA3FFC01053BCCE100164350, + AA3FFC02053BCCE100164350, + AA3FFC03053BCCE100164350, + AA3FFC04053BCCE100164350, + AA3FFC05053BCCE100164350, + AA3FFC06053BCCE100164350, + AA3FFC07053BCCE100164350, + AA3FFC08053BCCE100164350, + AA3FFC09053BCCE100164350, + AA3FFC0A053BCCE100164350, + AA3FFC0B053BCCE100164350, + AA3FFC0C053BCCE100164350, + AA3FFC0D053BCCE100164350, + AA3FFC0E053BCCE100164350, + AA3FFC0F053BCCE100164350, + AA3FFC10053BCCE100164350, + AA3FFC11053BCCE100164350, + AA3FFC12053BCCE100164350, + AA3FFC13053BCCE100164350, + AA3FFC14053BCCE100164350, + AA3FFC15053BCCE100164350, + AA3FFC16053BCCE100164350, + AA3FFC17053BCCE100164350, + AA3FFC18053BCCE100164350, + AA3FFC19053BCCE100164350, + AA3FFC1A053BCCE100164350, + AA3FFC1B053BCCE100164350, + AA3FFC1C053BCCE100164350, + AA3FFC1D053BCCE100164350, + AA3FFC1E053BCCE100164350, + AA3FFC1F053BCCE100164350, + AA3FFC20053BCCE100164350, + AA3FFC21053BCCE100164350, + AA3FFC22053BCCE100164350, + AA3FFC23053BCCE100164350, + AA3FFC24053BCCE100164350, + AA3FFC25053BCCE100164350, + AA3FFC26053BCCE100164350, + AA3FFC27053BCCE100164350, + AA3FFC28053BCCE100164350, + AA3FFC29053BCCE100164350, + AA3FFC2A053BCCE100164350, + AA3FFC2B053BCCE100164350, + AA3FFC2C053BCCE100164350, + AA3FFC2D053BCCE100164350, + AA3FFC2E053BCCE100164350, + AA3FFC2F053BCCE100164350, + AA3FFC30053BCCE200164350, + AA3FFC31053BCCE200164350, + AA3FFC32053BCCE200164350, + AA3FFC33053BCCE200164350, + AA3FFC34053BCCE200164350, + AA3FFC35053BCCE200164350, + AA3FFC36053BCCE200164350, + AA3FFC37053BCCE200164350, + AA3FFC38053BCCE200164350, + AA3FFC39053BCCE200164350, + AA3FFC3A053BCCE200164350, + AA3FFC3B053BCCE200164350, + AA3FFC3C053BCCE200164350, + AA3FFC3D053BCCE200164350, + AA3FFC3E053BCCE200164350, + AA3FFC3F053BCCE200164350, + AA3FFC40053BCCE200164350, + AA3FFC41053BCCE200164350, + AA3FFC42053BCCE200164350, + ); + isa = PBXGroup; + name = JPEGLib; + refType = 4; + }; + AA3FFC01053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = cderror.h; + path = ../boinc/jpeglib/cderror.h; + refType = 4; + }; + AA3FFC02053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = cdjpeg.h; + path = ../boinc/jpeglib/cdjpeg.h; + refType = 4; + }; + AA3FFC03053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jcapimin.c; + path = ../boinc/jpeglib/jcapimin.c; + refType = 4; + }; + AA3FFC04053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jcapistd.c; + path = ../boinc/jpeglib/jcapistd.c; + refType = 4; + }; + AA3FFC05053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jccoefct.c; + path = ../boinc/jpeglib/jccoefct.c; + refType = 4; + }; + AA3FFC06053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jccolor.c; + path = ../boinc/jpeglib/jccolor.c; + refType = 4; + }; + AA3FFC07053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jcdctmgr.c; + path = ../boinc/jpeglib/jcdctmgr.c; + refType = 4; + }; + AA3FFC08053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jchuff.c; + path = ../boinc/jpeglib/jchuff.c; + refType = 4; + }; + AA3FFC09053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jchuff.h; + path = ../boinc/jpeglib/jchuff.h; + refType = 4; + }; + AA3FFC0A053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jcinit.c; + path = ../boinc/jpeglib/jcinit.c; + refType = 4; + }; + AA3FFC0B053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jcmainct.c; + path = ../boinc/jpeglib/jcmainct.c; + refType = 4; + }; + AA3FFC0C053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jcmarker.c; + path = ../boinc/jpeglib/jcmarker.c; + refType = 4; + }; + AA3FFC0D053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jcmaster.c; + path = ../boinc/jpeglib/jcmaster.c; + refType = 4; + }; + AA3FFC0E053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jcomapi.c; + path = ../boinc/jpeglib/jcomapi.c; + refType = 4; + }; + AA3FFC0F053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jconfig.h; + path = ../boinc/jpeglib/jconfig.h; + refType = 4; + }; + AA3FFC10053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jcparam.c; + path = ../boinc/jpeglib/jcparam.c; + refType = 4; + }; + AA3FFC11053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jcphuff.c; + path = ../boinc/jpeglib/jcphuff.c; + refType = 4; + }; + AA3FFC12053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jcprepct.c; + path = ../boinc/jpeglib/jcprepct.c; + refType = 4; + }; + AA3FFC13053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jcsample.c; + path = ../boinc/jpeglib/jcsample.c; + refType = 4; + }; + AA3FFC14053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jctrans.c; + path = ../boinc/jpeglib/jctrans.c; + refType = 4; + }; + AA3FFC15053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jdapimin.c; + path = ../boinc/jpeglib/jdapimin.c; + refType = 4; + }; + AA3FFC16053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jdapistd.c; + path = ../boinc/jpeglib/jdapistd.c; + refType = 4; + }; + AA3FFC17053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jdatadst.c; + path = ../boinc/jpeglib/jdatadst.c; + refType = 4; + }; + AA3FFC18053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jdatasrc.c; + path = ../boinc/jpeglib/jdatasrc.c; + refType = 4; + }; + AA3FFC19053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jdcoefct.c; + path = ../boinc/jpeglib/jdcoefct.c; + refType = 4; + }; + AA3FFC1A053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jdcolor.c; + path = ../boinc/jpeglib/jdcolor.c; + refType = 4; + }; + AA3FFC1B053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jdct.h; + path = ../boinc/jpeglib/jdct.h; + refType = 4; + }; + AA3FFC1C053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jddctmgr.c; + path = ../boinc/jpeglib/jddctmgr.c; + refType = 4; + }; + AA3FFC1D053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jdhuff.c; + path = ../boinc/jpeglib/jdhuff.c; + refType = 4; + }; + AA3FFC1E053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jdhuff.h; + path = ../boinc/jpeglib/jdhuff.h; + refType = 4; + }; + AA3FFC1F053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jdinput.c; + path = ../boinc/jpeglib/jdinput.c; + refType = 4; + }; + AA3FFC20053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jdmainct.c; + path = ../boinc/jpeglib/jdmainct.c; + refType = 4; + }; + AA3FFC21053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jdmarker.c; + path = ../boinc/jpeglib/jdmarker.c; + refType = 4; + }; + AA3FFC22053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jdmaster.c; + path = ../boinc/jpeglib/jdmaster.c; + refType = 4; + }; + AA3FFC23053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jdmerge.c; + path = ../boinc/jpeglib/jdmerge.c; + refType = 4; + }; + AA3FFC24053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jdphuff.c; + path = ../boinc/jpeglib/jdphuff.c; + refType = 4; + }; + AA3FFC25053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jdpostct.c; + path = ../boinc/jpeglib/jdpostct.c; + refType = 4; + }; + AA3FFC26053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jdsample.c; + path = ../boinc/jpeglib/jdsample.c; + refType = 4; + }; + AA3FFC27053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jdtrans.c; + path = ../boinc/jpeglib/jdtrans.c; + refType = 4; + }; + AA3FFC28053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jerror.c; + path = ../boinc/jpeglib/jerror.c; + refType = 4; + }; + AA3FFC29053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jerror.h; + path = ../boinc/jpeglib/jerror.h; + refType = 4; + }; + AA3FFC2A053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jfdctflt.c; + path = ../boinc/jpeglib/jfdctflt.c; + refType = 4; + }; + AA3FFC2B053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jfdctfst.c; + path = ../boinc/jpeglib/jfdctfst.c; + refType = 4; + }; + AA3FFC2C053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jfdctint.c; + path = ../boinc/jpeglib/jfdctint.c; + refType = 4; + }; + AA3FFC2D053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jidctflt.c; + path = ../boinc/jpeglib/jidctflt.c; + refType = 4; + }; + AA3FFC2E053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jidctfst.c; + path = ../boinc/jpeglib/jidctfst.c; + refType = 4; + }; + AA3FFC2F053BCCE100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jidctint.c; + path = ../boinc/jpeglib/jidctint.c; + refType = 4; + }; + AA3FFC30053BCCE200164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jidctred.c; + path = ../boinc/jpeglib/jidctred.c; + refType = 4; + }; + AA3FFC31053BCCE200164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jinclude.h; + path = ../boinc/jpeglib/jinclude.h; + refType = 4; + }; + AA3FFC32053BCCE200164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jmemmgr.c; + path = ../boinc/jpeglib/jmemmgr.c; + refType = 4; + }; + AA3FFC33053BCCE200164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jmemnobs.c; + path = ../boinc/jpeglib/jmemnobs.c; + refType = 4; + }; + AA3FFC34053BCCE200164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jmemsys.h; + path = ../boinc/jpeglib/jmemsys.h; + refType = 4; + }; + AA3FFC35053BCCE200164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jmorecfg.h; + path = ../boinc/jpeglib/jmorecfg.h; + refType = 4; + }; + AA3FFC36053BCCE200164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jpegint.h; + path = ../boinc/jpeglib/jpegint.h; + refType = 4; + }; + AA3FFC37053BCCE200164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jpeglib.h; + path = ../boinc/jpeglib/jpeglib.h; + refType = 4; + }; + AA3FFC38053BCCE200164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jquant1.c; + path = ../boinc/jpeglib/jquant1.c; + refType = 4; + }; + AA3FFC39053BCCE200164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jquant2.c; + path = ../boinc/jpeglib/jquant2.c; + refType = 4; + }; + AA3FFC3A053BCCE200164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jutils.c; + path = ../boinc/jpeglib/jutils.c; + refType = 4; + }; + AA3FFC3B053BCCE200164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = jversion.h; + path = ../boinc/jpeglib/jversion.h; + refType = 4; + }; + AA3FFC3C053BCCE200164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = rdbmp.c; + path = ../boinc/jpeglib/rdbmp.c; + refType = 4; + }; + AA3FFC3D053BCCE200164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = rdcolmap.c; + path = ../boinc/jpeglib/rdcolmap.c; + refType = 4; + }; + AA3FFC3E053BCCE200164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = rdgif.c; + path = ../boinc/jpeglib/rdgif.c; + refType = 4; + }; + AA3FFC3F053BCCE200164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = rdppm.c; + path = ../boinc/jpeglib/rdppm.c; + refType = 4; + }; + AA3FFC40053BCCE200164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = rdrle.c; + path = ../boinc/jpeglib/rdrle.c; + refType = 4; + }; + AA3FFC41053BCCE200164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = rdswitch.c; + path = ../boinc/jpeglib/rdswitch.c; + refType = 4; + }; + AA3FFC42053BCCE200164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = rdtarga.c; + path = ../boinc/jpeglib/rdtarga.c; + refType = 4; + }; + AA3FFC43053BCCE200164350 = { + fileRef = AA3FFC01053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC44053BCCE200164350 = { + fileRef = AA3FFC02053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC45053BCCE200164350 = { + fileRef = AA3FFC03053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC46053BCCE200164350 = { + fileRef = AA3FFC04053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC47053BCCE200164350 = { + fileRef = AA3FFC05053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC48053BCCE200164350 = { + fileRef = AA3FFC06053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC49053BCCE200164350 = { + fileRef = AA3FFC07053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC4A053BCCE200164350 = { + fileRef = AA3FFC08053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC4B053BCCE200164350 = { + fileRef = AA3FFC09053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC4C053BCCE200164350 = { + fileRef = AA3FFC0A053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC4D053BCCE200164350 = { + fileRef = AA3FFC0B053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC4E053BCCE200164350 = { + fileRef = AA3FFC0C053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC4F053BCCE200164350 = { + fileRef = AA3FFC0D053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC50053BCCE200164350 = { + fileRef = AA3FFC0E053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC51053BCCE200164350 = { + fileRef = AA3FFC0F053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC52053BCCE200164350 = { + fileRef = AA3FFC10053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC53053BCCE200164350 = { + fileRef = AA3FFC11053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC54053BCCE200164350 = { + fileRef = AA3FFC12053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC55053BCCE200164350 = { + fileRef = AA3FFC13053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC56053BCCE200164350 = { + fileRef = AA3FFC14053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC57053BCCE200164350 = { + fileRef = AA3FFC15053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC58053BCCE200164350 = { + fileRef = AA3FFC16053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC59053BCCE200164350 = { + fileRef = AA3FFC17053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC5A053BCCE200164350 = { + fileRef = AA3FFC18053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC5B053BCCE200164350 = { + fileRef = AA3FFC19053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC5C053BCCE200164350 = { + fileRef = AA3FFC1A053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC5D053BCCE200164350 = { + fileRef = AA3FFC1B053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC5E053BCCE200164350 = { + fileRef = AA3FFC1C053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC5F053BCCE200164350 = { + fileRef = AA3FFC1D053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC60053BCCE200164350 = { + fileRef = AA3FFC1E053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC61053BCCE200164350 = { + fileRef = AA3FFC1F053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC62053BCCE200164350 = { + fileRef = AA3FFC20053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC63053BCCE200164350 = { + fileRef = AA3FFC21053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC64053BCCE200164350 = { + fileRef = AA3FFC22053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC65053BCCE200164350 = { + fileRef = AA3FFC23053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC66053BCCE200164350 = { + fileRef = AA3FFC24053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC67053BCCE200164350 = { + fileRef = AA3FFC25053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC68053BCCE200164350 = { + fileRef = AA3FFC26053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC69053BCCE200164350 = { + fileRef = AA3FFC27053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC6A053BCCE200164350 = { + fileRef = AA3FFC28053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC6B053BCCE200164350 = { + fileRef = AA3FFC29053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC6C053BCCE200164350 = { + fileRef = AA3FFC2A053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC6D053BCCE200164350 = { + fileRef = AA3FFC2B053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC6E053BCCE200164350 = { + fileRef = AA3FFC2C053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC6F053BCCE200164350 = { + fileRef = AA3FFC2D053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC70053BCCE200164350 = { + fileRef = AA3FFC2E053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC71053BCCE200164350 = { + fileRef = AA3FFC2F053BCCE100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC72053BCCE200164350 = { + fileRef = AA3FFC30053BCCE200164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC73053BCCE200164350 = { + fileRef = AA3FFC31053BCCE200164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC74053BCCE200164350 = { + fileRef = AA3FFC32053BCCE200164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC75053BCCE200164350 = { + fileRef = AA3FFC33053BCCE200164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC76053BCCE200164350 = { + fileRef = AA3FFC34053BCCE200164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC77053BCCE200164350 = { + fileRef = AA3FFC35053BCCE200164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC78053BCCE200164350 = { + fileRef = AA3FFC36053BCCE200164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC79053BCCE200164350 = { + fileRef = AA3FFC37053BCCE200164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC7A053BCCE200164350 = { + fileRef = AA3FFC38053BCCE200164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC7B053BCCE200164350 = { + fileRef = AA3FFC39053BCCE200164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC7C053BCCE200164350 = { + fileRef = AA3FFC3A053BCCE200164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC7D053BCCE200164350 = { + fileRef = AA3FFC3B053BCCE200164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC7E053BCCE200164350 = { + fileRef = AA3FFC3C053BCCE200164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC7F053BCCE200164350 = { + fileRef = AA3FFC3D053BCCE200164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC80053BCCE200164350 = { + fileRef = AA3FFC3E053BCCE200164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC81053BCCE200164350 = { + fileRef = AA3FFC3F053BCCE200164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC82053BCCE200164350 = { + fileRef = AA3FFC40053BCCE200164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC83053BCCE200164350 = { + fileRef = AA3FFC41053BCCE200164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC84053BCCE200164350 = { + fileRef = AA3FFC42053BCCE200164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC85053BCDAD00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = sqlint8.h; + path = db/sqlint8.h; + refType = 4; + }; + AA3FFC86053BCDAD00164350 = { + fileRef = AA3FFC85053BCDAD00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC87053BD34A00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = sqlblob.cpp; + path = db/sqlblob.cpp; + refType = 4; + }; + AA3FFC88053BD34A00164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = sqlblob.h; + path = db/sqlblob.h; + refType = 4; + }; + AA3FFC89053BD34A00164350 = { + fileRef = AA3FFC87053BD34A00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC8A053BD34A00164350 = { + fileRef = AA3FFC88053BD34A00164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC8B053BDE9100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = sqlrow.cpp; + path = db/sqlrow.cpp; + refType = 4; + }; + AA3FFC8C053BDE9100164350 = { + fileEncoding = 30; + isa = PBXFileReference; + name = sqlrow.h; + path = db/sqlrow.h; + refType = 4; + }; + AA3FFC8D053BDE9100164350 = { + fileRef = AA3FFC8B053BDE9100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC8E053BDE9100164350 = { + fileRef = AA3FFC8C053BDE9100164350; + isa = PBXBuildFile; + settings = { + }; + }; + AA3FFC8F053BDEC000164350 = { + children = ( + AA3FFBFC053BCAF200164350, + AA3FFBFD053BCAF200164350, + AA3FFC85053BCDAD00164350, + AA3FFC87053BD34A00164350, + AA3FFC88053BD34A00164350, + AA3FFC8B053BDE9100164350, + AA3FFC8C053BDE9100164350, + ); + isa = PBXGroup; + name = DB; + refType = 4; + }; + AA6AA8B10410C34000A80164 = { + fileRef = AA763A950400775C00A80164; + isa = PBXBuildFile; + settings = { + }; + }; + AA6AA8C60410C8B300A80164 = { + isa = PBXFrameworkReference; + name = Cocoa.framework; + path = /System/Library/Frameworks/Cocoa.framework; + refType = 0; + }; + AA6AA8C70410C8B300A80164 = { + fileRef = AA6AA8C60410C8B300A80164; + isa = PBXBuildFile; + settings = { + }; + }; + AA6AA8C804113B7B00A80164 = { + children = ( + AA3FFB0F053BC3EB00164350, + AA3FFB10053BC3EB00164350, + AA3FFB11053BC3EB00164350, + AA3FFB12053BC3EB00164350, + AA3FFB13053BC3EB00164350, + AA3FFB14053BC3EB00164350, + AA3FFB15053BC3EB00164350, + AA3FFB16053BC3EB00164350, + AA3FFB17053BC3EB00164350, + AA3FFB18053BC3EB00164350, + AA3FFB19053BC3EB00164350, + AA3FFB1A053BC3EB00164350, + AA3FFB1B053BC3EB00164350, + AA3FFB1C053BC3EB00164350, + AA3FFB1D053BC3EB00164350, + AA3FFB1E053BC3EB00164350, + AA3FFB20053BC3EB00164350, + AA3FFB21053BC3EB00164350, + AA3FFB22053BC3EB00164350, + AA3FFB23053BC3EB00164350, + AA3FFB24053BC3EB00164350, + AA3FFB25053BC3EB00164350, + AA3FFB26053BC3EB00164350, + AA3FFB27053BC3EB00164350, + AA3FFB28053BC3EB00164350, + AA3FFB29053BC3EB00164350, + AA3FFB2A053BC3EB00164350, + AA3FFB2B053BC3EB00164350, + AA3FFB2C053BC3EB00164350, + AA3FFB2D053BC3EB00164350, + AA3FFB2E053BC3EB00164350, + AA3FFB2F053BC3EB00164350, + AA3FFB30053BC3EB00164350, + AA3FFB31053BC3EB00164350, + AA3FFB32053BC3EB00164350, + AA3FFB33053BC3EB00164350, + AA3FFB34053BC3EB00164350, + AA3FFB35053BC3EB00164350, + AA3FFB36053BC3EB00164350, + AA3FFB37053BC3EB00164350, + AA3FFB38053BC3EB00164350, + ); + isa = PBXGroup; + name = "SETI@home"; + refType = 4; + }; + AA763A910400775C00A80164 = { + fileEncoding = 30; + isa = PBXFileReference; + name = gutil.h; + path = ../boinc/api/gutil.h; + refType = 2; + }; + AA763A930400775C00A80164 = { + fileEncoding = 30; + isa = PBXFileReference; + name = graphics_data.h; + path = ../boinc/api/graphics_data.h; + refType = 2; + }; + AA763A940400775C00A80164 = { + fileEncoding = 30; + isa = PBXFileReference; + name = graphics_data.C; + path = ../boinc/api/graphics_data.C; + refType = 2; + }; + AA763A950400775C00A80164 = { + fileEncoding = 30; + isa = PBXFileReference; + name = reduce.h; + path = ../boinc/api/reduce.h; + refType = 2; + }; + AA763A970400775C00A80164 = { + fileEncoding = 30; + isa = PBXFileReference; + name = mac_carbon_gl.h; + path = ../boinc/api/mac_carbon_gl.h; + refType = 2; + }; + AA763A9B0400775C00A80164 = { + fileEncoding = 30; + isa = PBXFileReference; + name = mac_app_opengl.h; + path = ../boinc/api/mac_app_opengl.h; + refType = 2; + }; + AA763A9C0400775C00A80164 = { + fileEncoding = 30; + isa = PBXFileReference; + name = graphics_api.h; + path = ../boinc/api/graphics_api.h; + refType = 2; + }; + AA763A9D0400775C00A80164 = { + fileEncoding = 30; + isa = PBXFileReference; + name = boinc_api.h; + path = ../boinc/api/boinc_api.h; + refType = 2; + }; + AA763A9E0400775C00A80164 = { + fileEncoding = 30; + isa = PBXFileReference; + name = graphics_api.C; + path = ../boinc/api/graphics_api.C; + refType = 2; + }; + AA763A9F0400775C00A80164 = { + fileEncoding = 30; + isa = PBXFileReference; + name = boinc_api.C; + path = ../boinc/api/boinc_api.C; + refType = 2; + }; + AA763AAC0400775C00A80164 = { + fileRef = AA763A9C0400775C00A80164; + isa = PBXBuildFile; + settings = { + }; + }; + AA763AAD0400775C00A80164 = { + fileRef = AA763A9D0400775C00A80164; + isa = PBXBuildFile; + settings = { + }; + }; + AA763AAE0400775C00A80164 = { + fileRef = AA763A9E0400775C00A80164; + isa = PBXBuildFile; + settings = { + }; + }; + AA763AAF0400775C00A80164 = { + fileRef = AA763A9F0400775C00A80164; + isa = PBXBuildFile; + settings = { + }; + }; + AA763AB00400777000A80164 = { + fileEncoding = 30; + isa = PBXFileReference; + name = filesys.h; + path = ../boinc/lib/filesys.h; + refType = 2; + }; + AA763AB10400777000A80164 = { + fileEncoding = 30; + isa = PBXFileReference; + name = util.h; + path = ../boinc/lib/util.h; + refType = 2; + }; + AA763AB20400777000A80164 = { + fileEncoding = 30; + isa = PBXFileReference; + name = filesys.C; + path = ../boinc/lib/filesys.C; + refType = 2; + }; + AA763AB30400777000A80164 = { + fileEncoding = 30; + isa = PBXFileReference; + name = util.C; + path = ../boinc/lib/util.C; + refType = 2; + }; + AA763AB40400777000A80164 = { + fileRef = AA763AB00400777000A80164; + isa = PBXBuildFile; + settings = { + }; + }; + AA763AB50400777000A80164 = { + fileRef = AA763AB10400777000A80164; + isa = PBXBuildFile; + settings = { + }; + }; + AA763AB60400777000A80164 = { + fileRef = AA763AB20400777000A80164; + isa = PBXBuildFile; + settings = { + }; + }; + AA763AB70400777000A80164 = { + fileRef = AA763AB30400777000A80164; + isa = PBXBuildFile; + settings = { + }; + }; + AA763B590400789200A80164 = { + isa = PBXFrameworkReference; + name = AGL.framework; + path = /System/Library/Frameworks/AGL.framework; + refType = 0; + }; + AA763B5A0400789200A80164 = { + fileRef = AA763B590400789200A80164; + isa = PBXBuildFile; + settings = { + }; + }; + AA763B5B040078AC00A80164 = { + isa = PBXFrameworkReference; + name = DrawSprocket.framework; + path = /System/Library/Frameworks/DrawSprocket.framework; + refType = 0; + }; + AA763B5C040078AC00A80164 = { + isa = PBXFrameworkReference; + name = OpenGL.framework; + path = /System/Library/Frameworks/OpenGL.framework; + refType = 0; + }; + AA763B5E040078AC00A80164 = { + fileRef = AA763B5C040078AC00A80164; + isa = PBXBuildFile; + settings = { + }; + }; + AA763B6104007BB800A80164 = { + isa = PBXFrameworkReference; + name = GLUT.framework; + path = /System/Library/Frameworks/GLUT.framework; + refType = 0; + }; + AA763B6304007BD100A80164 = { + fileRef = AA763B6104007BB800A80164; + isa = PBXBuildFile; + settings = { + }; + }; + AA763B8904007C2F00A80164 = { + fileRef = 20286C33FDCF999611CA2CEA; + isa = PBXBuildFile; + settings = { + }; + }; + AA763B8A04007C8A00A80164 = { + fileRef = AA763B5B040078AC00A80164; + isa = PBXBuildFile; + settings = { + }; + }; + AABC80520410BC6E00A80164 = { + fileEncoding = 30; + isa = PBXFileReference; + name = mfile.C; + path = ../boinc/api/mfile.C; + refType = 2; + }; + AABC80530410BC6E00A80164 = { + fileRef = AABC80520410BC6E00A80164; + isa = PBXBuildFile; + settings = { + }; + }; + AABC80540410BCCF00A80164 = { + fileEncoding = 30; + isa = PBXFileReference; + name = parse.C; + path = ../boinc/lib/parse.C; + refType = 2; + }; + AABC80550410BCCF00A80164 = { + fileEncoding = 30; + isa = PBXFileReference; + name = parse.h; + path = ../boinc/lib/parse.h; + refType = 2; + }; + AABC80560410BCCF00A80164 = { + fileRef = AABC80540410BCCF00A80164; + isa = PBXBuildFile; + settings = { + }; + }; + AABC80570410BCCF00A80164 = { + fileRef = AABC80550410BCCF00A80164; + isa = PBXBuildFile; + settings = { + }; + }; + AABC806A0410BD2600A80164 = { + fileRef = AA763A970400775C00A80164; + isa = PBXBuildFile; + settings = { + }; + }; + AABC806E0410BD2800A80164 = { + fileRef = AA763A9B0400775C00A80164; + isa = PBXBuildFile; + settings = { + }; + }; + AABC80720410BEED00A80164 = { + fileRef = AA763A940400775C00A80164; + isa = PBXBuildFile; + settings = { + }; + }; + AABC80730410BEEE00A80164 = { + fileRef = AA763A930400775C00A80164; + isa = PBXBuildFile; + settings = { + }; + }; + AABC80790410C06700A80164 = { + fileRef = AA763A910400775C00A80164; + isa = PBXBuildFile; + settings = { + }; + }; + AADBC6EE04226C0F00A80164 = { + fileEncoding = 30; + isa = PBXFileReference; + name = shmem.C; + path = ../boinc/lib/shmem.C; + refType = 4; + }; + AADBC6EF04226C0F00A80164 = { + fileEncoding = 30; + isa = PBXFileReference; + name = shmem.h; + path = ../boinc/lib/shmem.h; + refType = 4; + }; + AADBC6F004226C0F00A80164 = { + fileRef = AADBC6EE04226C0F00A80164; + isa = PBXBuildFile; + settings = { + }; + }; + AADBC6F104226C0F00A80164 = { + fileRef = AADBC6EF04226C0F00A80164; + isa = PBXBuildFile; + settings = { + }; + }; + }; + rootObject = 20286C28FDCF999611CA2CEA; +} diff --git a/splitter/Makefile.am b/splitter/Makefile.am new file mode 100644 index 0000000..6ff1078 --- /dev/null +++ b/splitter/Makefile.am @@ -0,0 +1,65 @@ +CC=gcc +BOINCDIR=@BOINCDIR@ +INFORMIXDIR=@INFORMIXDIR@ +SETILIB_PATH=@SETILIB_PATH@ +SETILIB_LIBS=@SETILIB_LIBS@ +SETIHOME=.. + +LINKOPTIONS= + + + +DBLIBS=@INFORMIX_LIBS@ -lm -lstdc++ + + +LINKOPTIONS=-Xlinker -R -Xlinker $(INFORMIXDIR)/lib:$(INFORMIXDIR)/lib/esql:$(LD_LIBRARY_PATH) + + +AM_CFLAGS= -g -Wall $(INCLUDE_DIRS) -DUSE_INFORMIX @PTHREAD_CFLAGS@ -ISETILIB_PATH/include + + +SYSLIBS = -lcrypto -ldl + +BOINCLIBS= -L$(BOINCDIR)/sched -lsched @MYSQL_LIBS@ @PTHREAD_LIBS@ -L$(BOINCDIR)/lib -lboinc_crypt -lboinc -L$(SSLDIR) -lcrypto -lssl + +SPLITLIBS= $(SETILIB_LIBS) \ + $(DBLIBS) \ + $(BOINCLIBS) \ + $(SYSLIBS) \ + -lchealpix \ + -lfftw3f + +noinst_PROGRAMS = mb_splitter + + +mb_splitter_SOURCES=mb_angdist.cpp \ + mb_message.cpp \ + mb_splitter.cpp \ + mb_wufiles.cpp \ + mb_dotransform.cpp \ + mb_validrun.cpp \ + cmap_interp.cpp \ + ../db/schema_master.cpp \ + ../db/sqlifx.cpp \ + ../db/sqlrow.cpp \ + ../db/sqlblob.cpp ../db/sqlint8.cpp \ + ../db/xml_util.cpp \ + ../db/app_config.cpp \ + ../client/seti_header.cpp \ + ../client/timecvt.cpp \ + ../client/lcgamm.cpp \ + ../client/hr_min_sec.o + +mb_splitter_CXXFLAGS= \ + -I$(SETIHOME) -I$(SETIHOME)/client -I$(SETIHOME)/db \ + @MYSQL_CFLAGS@ -I$(HEALPIX)/include \ + @INFORMIX_CFLAGS@ @SETILIB_CFLAGS@ \ + @BOINC_CFLAGS@ -I$(BOINCDIR)/tools -I$(BOINCDIR)/sched -I$(BOINCDIR)/db +mb_splitter_CFLAGS=$(mb_splitter_CXXFLAGS) +mb_splitter_LDFLAGS=-static $(AM_LDFLAGS) -L$(HEALPIX)/lib $(LINKOPTIONS) +mb_splitter_LDADD=$(SPLITLIBS) + +../db/sqlifx.cpp: ../db/sqlifx.ec + $(INFORMIXDIR)/bin/esql -e $< + mv sqlifx.c $*.cpp + diff --git a/splitter/angdist.cpp b/splitter/angdist.cpp new file mode 100644 index 0000000..a4d9cf2 --- /dev/null +++ b/splitter/angdist.cpp @@ -0,0 +1,79 @@ +/* + * angdist.c + * + * Computes angular distance between two lat/lon points + * + * $Id: angdist.cpp,v 1.3.4.1 2006/12/14 22:24:37 korpela Exp $ + * + */ + +#include "sah_config.h" +#include +#include +#include +#include "seti_header.h" + +#define DTOR (M_PI/180) + +double angdist(double r1, double d1, double r2, double d2) { + double alpha,dist,d; + + r1*=DTOR; + r2*=DTOR; + d1*=DTOR; + d2*=DTOR; + alpha=r1-r2; + dist=sin(d2)*sin(d1)+cos(d1)*cos(d2)*cos(alpha); + if ((dist*dist)<1) { + d=sqrt(1.0-dist*dist); + } else { + dist=1.0; + d=0.0; + } + dist=atan2(d,dist); + dist=dist/DTOR; + return (dist); +} + +double angdist(const SCOPE_STRING &a, const SCOPE_STRING &b) { + return angdist(a.ra*15,a.dec,b.ra*15,b.dec); +} + +/* + * $Log: angdist.cpp,v $ + * Revision 1.3.4.1 2006/12/14 22:24:37 korpela + * *** empty log message *** + * + * Revision 1.3 2003/09/11 18:53:37 korpela + * *** empty log message *** + * + * Revision 1.2 2003/08/05 17:23:39 korpela + * More work on database stuff. + * Further tweaks. + * + * Revision 1.1 2003/07/29 20:35:31 korpela + * + * renames .C files to .cpp + * + * Revision 1.2 2003/06/03 01:01:15 korpela + * + * First working splitter under CVS. + * + * Revision 1.1 2003/06/03 00:16:08 korpela + * + * Initial splitter under CVS control. + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.1 1998/11/02 16:41:21 korpela + * Minor Change. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.1 1998/10/27 00:47:33 korpela + * Initial revision + * + * + */ diff --git a/splitter/angdist.h b/splitter/angdist.h new file mode 100644 index 0000000..c3fc069 --- /dev/null +++ b/splitter/angdist.h @@ -0,0 +1,33 @@ +/* + * angdist.h + * + * Computes angular distance between two lat/lon points + * + * $Id: angdist.h,v 1.1 2003/06/03 00:16:09 korpela Exp $ + * + */ + +double angdist(double r1, double d1, double r2, double d2) ; +double angdist(const SCOPE_STRING &a,const SCOPE_STRING &b); + +/* + * $Log: angdist.h,v $ + * Revision 1.1 2003/06/03 00:16:09 korpela + * + * Initial splitter under CVS control. + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.1 1998/11/02 16:41:21 korpela + * Minor Change. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.1 1998/10/27 01:03:21 korpela + * Initial revision + * + * + */ + diff --git a/splitter/cmap_interp.cpp b/splitter/cmap_interp.cpp new file mode 100644 index 0000000..d431f92 --- /dev/null +++ b/splitter/cmap_interp.cpp @@ -0,0 +1,40 @@ +#include +#include +#include "setilib.h" +#include "sqlrow.h" +#include "sqlblob.h" +#include "sqlapi.h" +#include "db_table.h" +#include "schema_master.h" + +coordinate_t cmap_interp(std::map &map, seti_time &t) { + std::map::iterator above(map.upper_bound(t)); + std::map::iterator below; + below=above; + if (above==map.begin()) { + above++; + } else { + below--; + } + if (above==map.end()) { + above--; + below--; + } + coordinate_t upper(above->second); + coordinate_t lower(below->second); + coordinate_t rv; + + if ((upper.ra-lower.ra)>23) lower.ra+=24; + if ((lower.ra-upper.ra)>23) upper.ra+=24; + rv.time=t.jd().uval(); + double f=(seti_time(t.jd()-JD1970,JD1970)-seti_time(days(lower.time)))/ + days(upper.time-lower.time); + rv.ra=(upper.ra-lower.ra)*f+lower.ra; + rv.ra=fmod(rv.ra,24.0); + rv.dec=(upper.dec-lower.dec)*f+lower.dec; + return rv; +} + + + + diff --git a/splitter/cmap_interp.h b/splitter/cmap_interp.h new file mode 100644 index 0000000..37ee520 --- /dev/null +++ b/splitter/cmap_interp.h @@ -0,0 +1,6 @@ + +extern coordinate_t cmap_interp(std::map &map, seti_time &t); + + + + diff --git a/splitter/coordcvt.cpp b/splitter/coordcvt.cpp new file mode 100644 index 0000000..959f231 --- /dev/null +++ b/splitter/coordcvt.cpp @@ -0,0 +1,179 @@ +/* + * coordcvt.c + * + * Celestial coordinate conversion routines. + * + * $Id: coordcvt.cpp,v 1.2.4.1 2006/12/14 22:24:37 korpela Exp $ + * + */ + +#include "sah_config.h" +#include +#include +#include + +#include "sqlrow.h" +#include "sqlblob.h" +#include "sqlapi.h" +#include "db_table.h" +#include "schema_master.h" + +#include +#include +#include + +#include "splitparms.h" +#include "splittypes.h" +#include "coordcvt.h" + +extern int gregorian; + +namespace SPLITTER { + +double jd_to_lmst(double jd, double longitude) { +/* + * converts from julian date/time to local mean siderial time + * + */ + + double tu; /* time, in centuries from Jan 0, 2000 */ + double tusqr; + double tucb; + double g; /* derrived from tu, used to calculate gmst */ + double gmst; /* Greenwich Mean Sidereal Time */ + double lmst; /* Local Mean Sidereal Time */ + double jd0=floor(jd+0.5)-0.5; /* jd at noon GMT */ + double ddtime=fmod((jd-jd0)*24,24); /* GMT hours */ + + tu = (jd0 - 2451545.0)/36525; + tusqr = tu * tu; + tucb = tusqr * tu; + +/* computation of the gmst at ddtime UT */ + + g = 24110.54841 + 8640184.812866 * tu + 0.093104 * tusqr - 6.62E-6 * tucb; + + for (gmst = g; gmst < 0; gmst += 86400) ; + + gmst /= 3600; /* GMST at 0h UT */ + gmst += (1.0027379093 * ddtime); /* GMST at utime UT */ + + gmst=fmod(gmst,24); + +/* computation of lmst given gmst and longitude */ + + lmst = gmst + ((longitude/360) * 24); + + if (lmst < 0) + lmst += 24; + lmst = fmod(lmst,24); + return(lmst); +} + + +void horz_to_equatorial(double alt, double azimuth, double lsthour, + double lat, double *ra, double *dec) { + double dec_rad, hour_ang_rad, zenith_ang=90.0-alt; + double temp; + + zenith_ang*=(M_PI/180.0); + azimuth*=(M_PI/180.0); + + dec_rad = asin ((cos(zenith_ang) * sin(lat*M_PI/180)) + + (sin(zenith_ang) * cos(lat*M_PI/180) * cos(azimuth))); + + *dec = dec_rad * 180.0/M_PI; /* radians to decimal degrees */ + + temp = (cos(zenith_ang) - sin(lat*M_PI/180) * sin(dec_rad)) / + (cos(lat*M_PI/180) * cos(dec_rad)); + if (temp > 1) + temp = 1; + else if (temp < -1) + temp = -1; + hour_ang_rad = acos (temp); + + if (sin(azimuth) > 0.0) /* insure correct quadrant */ + hour_ang_rad = (2 * M_PI) - hour_ang_rad; + + + /* to get ra, we convert hour angle to decimal degrees, */ + /* convert degrees to decimal hours, and subtract the */ + /* result from local sidereal decimal hours. */ + *ra = lsthour - ((hour_ang_rad * 180.0/M_PI) / 15.0); + + // Take care of wrap situations in RA + if (*ra < 0.0) + *ra += 24.0; + *ra=fmod(*ra,24); +} +#define D2R 0.017453292 + +void AltAzCorrection(double *alt, double *az) { + double zen=90-*alt; + co_ZenAzCorrection((telescope_id)(gregorian?AOGREG_1420:AO_1420),&zen,az); + *alt=90-zen; +} + +} + +void telstr_coord_convert(SCOPE_STRING *telstr, double lat, double lon) { + + double lmst=SPLITTER::jd_to_lmst(telstr->st.jd,lon); + + SPLITTER::AltAzCorrection(&(telstr->alt),&(telstr->az)); + SPLITTER::horz_to_equatorial(telstr->alt, telstr->az, lmst, lat, &(telstr->ra), + &(telstr->dec)); +} + +/* + * $Log: coordcvt.cpp,v $ + * Revision 1.2.4.1 2006/12/14 22:24:37 korpela + * *** empty log message *** + * + * Revision 1.2 2003/09/11 18:53:37 korpela + * *** empty log message *** + * + * Revision 1.1 2003/07/29 20:35:33 korpela + * + * renames .C files to .cpp + * + * Revision 1.3 2003/06/05 19:01:45 korpela + * + * Fixed coordiate bug that allowed RA>24 hours. + * + * Revision 1.2 2003/06/05 15:52:46 korpela + * + * Fixed coordinate bug that was using the wrong zenith angle from the telescope + * strings when handling units from the gregorian. + * + * Revision 1.1 2003/06/03 00:16:09 korpela + * + * Initial splitter under CVS control. + * + * Revision 3.1 2003/05/20 16:01:54 eheien + * *** empty log message *** + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.3 1999/03/05 01:47:18 korpela + * New zenith angle correction. + * + * Revision 2.2 1999/02/22 22:21:09 korpela + * Fixed half-day error. + * + * Revision 2.1 1998/11/02 16:41:21 korpela + * Minor Change. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.2 1998/10/27 00:48:48 korpela + * Bug fixes. + * + * Revision 1.1 1998/10/19 23:02:43 korpela + * Initial revision + * + * + */ + diff --git a/splitter/coordcvt.h b/splitter/coordcvt.h new file mode 100644 index 0000000..5595f06 --- /dev/null +++ b/splitter/coordcvt.h @@ -0,0 +1,40 @@ +/* + * coordcvt.h + * + * Celestial coordinate conversion routines. + * + * $Id: coordcvt.h,v 1.1 2003/06/03 00:16:09 korpela Exp $ + * + */ + +#ifndef COORDCVT_H +#define COORDCVT_H + +double jd_to_lmst(double jd, double longitude); + +void horz_to_equatorial(double alt, double azimuth, double lsthour, + double lat, double *ra, double *dec); + +void telstr_coord_convert(SCOPE_STRING *telstr, double lat, double lon); + +#endif + +/* + * $Log: coordcvt.h,v $ + * Revision 1.1 2003/06/03 00:16:09 korpela + * + * Initial splitter under CVS control. + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.1 1998/11/02 16:41:21 korpela + * Minor Change. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.1 1998/10/19 23:03:18 korpela + * Initial revision + * + */ diff --git a/splitter/db_fns.cpp b/splitter/db_fns.cpp new file mode 100644 index 0000000..9234ed3 --- /dev/null +++ b/splitter/db_fns.cpp @@ -0,0 +1,199 @@ +/* + * $Id: db_fns.cpp,v 1.3.4.2 2006/12/14 22:24:37 korpela Exp $ + * + */ + + +#include "sah_config.h" +#include +#include +#include +#include + +#include "splitparms.h" +#include "splittypes.h" +#include "splitter.h" +#include "message.h" +#include "readtape.h" +#include "sqlrow.h" +#include "sqlblob.h" +#include "db_table.h" +#include "schema_master.h" + + +static tape tape_struct; + +int update_tape_entry( tapeheader_t *tapeheader) ; + +int get_last_block(tapeheader_t *tapeheader) { + int err; + strncat(tape_struct.tapename,tapeheader->name,20); + if (!db_tape_lookup_name(&tape_struct)) { + return(tape_struct.last_block_done/TAPE_FRAMES_PER_RECORD); + } else { + if ((err=db_tape_new(&tape_struct))) { + log_messages.printf( SCHED_MSG_LOG::MSG_CRITICAL,"Unable to create db entry for tape %s error %d.\n",tapeheader->name,err); + exit(1); + } + return 0; + } +} + + +/* returns id number of tape db entry or zero if failure */ +/*int update_tape_entry( tapeheader_t *tapeheader) { + if (strncmp(tapeheader->name,tape_struct.tapename,20)) { + strncat(tape_struct.tapename,tapeheader->name,20); + if (db_tape_lookup_name(&tape_struct)) { + tape_struct.id=0; + strncpy(tape_struct.tapename,tapeheader->name,20); + tape_struct.start_time=tapeheader->st.jd; + tape_struct.last_block_time=tapeheader->st.jd; + tape_struct.last_block_done=tapeheader->frameseq; + if (db_tape_new(&tape_struct)) { + char tmpstr[256]; + fprintf( stderr, "Point 2\n" ); + sprintf(tmpstr,"Unable to create db entry for tape %s.",tapeheader->name); + message(tmpstr); + return(0); + } + } + } + tape_struct.last_block_time=tapeheader->st.jd; + tape_struct.last_block_done=tapeheader->frameseq; + if (db_tape_update(&tape_struct)) { + char tmpstr[256]; + sprintf(tmpstr,"Unable to update db entry for tape %s.",tapeheader->name); + message(tmpstr); + return(0); + } + return(tape_struct.id); +} +*/ + +/* returns workunit group id number on success, 0 on failure */ +/* +int create_wugrp_entry(workunit_grp &wugrp, int tapenum, tapeheader_t *tapeheader) { + int i,n; + + wugrp.tapenum=tapenum; + strncpy(wugrp.wugrpname,wugrpname,64); + wugrp.splitter_version=wuheader->wuinfo.splitter_version; + wugrp.start_ra=wuheader->wuinfo.start_ra; + wugrp.start_dec=wuheader->wuinfo.start_dec; + wugrp.end_ra=wuheader->wuinfo.end_ra; + wugrp.end_dec=wuheader->wuinfo.end_dec; + wugrp.angle_range=wuheader->wuinfo.angle_range; + wugrp.true_angle_range=wuheader->wuinfo.true_angle_range; + wugrp.beam_width=wuheader->wuinfo.beam_width; + wugrp.time_recorded=wuheader->wuinfo.time_recorded; + wugrp.fft_len=wuheader->wuinfo.fft_len; + wugrp.ifft_len=wuheader->wuinfo.ifft_len; + wugrp.receiver=wuheader->wuinfo.source; + wugrp.nsamples=wuheader->wuinfo.nsamples; + wugrp.sample_rate=tapeheader->samplerate; + wugrp.data_class=wuheader->wuinfo.data_class; + strncpy(wugrp.tape_version,wuheader->wuinfo.tape_version,13); + wugrp.num_positions=wuheader->wuinfo.num_positions; + if (db_workunit_grp_new(&wugrp)) { + char tmpstr[256]; + sprintf(tmpstr,"Unable to create db entry for workunit_grp %s\n",wugrpname); + message(tmpstr); + return(0); + } + for (i=0;iwuinfo.position_history[i].st.jd, + wuheader->wuinfo.position_history[i].ra, + wuheader->wuinfo.position_history[i].dec + ); + if (n=db_workunit_grp_update_position(wugrp.id,i,tmpstr)) { + fprintf( stderr, "%d\n", n ); + sprintf(tmpstr,"Unable to add position %d to workunit_grp %s\n",i,wugrpname); + message(tmpstr); + } + } + return (wugrp.id); +} + +int create_workunit_entry(wuheader_t *wuheader, int wugrpid, int subband_number) { + WORKUNIT wu; + + memset(&wu,0,sizeof(wu)); + strncpy(wu.name,wuheader->wuhead.name,63); + wu.grpnum=wugrpid; + wu.subb_center=wuheader->wuinfo.subband_center; + wu.subb_base=wuheader->wuinfo.subband_base; + wu.subb_sample_rate=wuheader->wuinfo.subband_sample_rate; + wu.subband_number=subband_number; + wu.data_class=wuheader->wuinfo.data_class; + if (db_workunit_new(&wu)) { + char tmpstr[256]; + sprintf(tmpstr,"Unable to create workunit entry %s\n",wu.name); + message(tmpstr); + return(0); + } + return(wu.id); +} +*/ + +/* + * $Log: db_fns.cpp,v $ + * Revision 1.3.4.2 2006/12/14 22:24:37 korpela + * *** empty log message *** + * + * Revision 1.3.4.1 2006/01/13 00:37:56 korpela + * Moved splitter to using standard BOINC logging mechanisms. All stderr now + * goes to "error.log" + * + * Added command line parameters "-iterations=" (number of workunit groups to + * create before exiting), "-trigger_file_path=" (path to the splitter_stop trigger + * file. Default is /disks/setifiler1/wutape/tapedir/splitter_stop). + * + * Reduced deadlines by a factor of three. We now need a 30 MFLOP machine to meet + * the deadline. + * + * Revision 1.3 2003/09/11 18:53:37 korpela + * *** empty log message *** + * + * Revision 1.2 2003/08/05 17:23:40 korpela + * More work on database stuff. + * Further tweaks. + * + * Revision 1.1 2003/07/29 20:35:35 korpela + * + * renames .C files to .cpp + * + * Revision 1.2 2003/06/03 01:01:16 korpela + * + * First working splitter under CVS. + * + * Revision 1.1 2003/06/03 00:16:10 korpela + * + * Initial splitter under CVS control. + * + * Revision 3.2 2003/05/19 17:40:59 eheien + * *** empty log message *** + * + * Revision 3.1 2001/11/07 00:51:47 korpela + * Added splitter version to database. + * Added max_wus_ondisk option. + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 1.4 2000/12/01 01:13:29 korpela + * *** empty log message *** + * +// Revision 1.3 1999/03/05 01:47:18 korpela +// Added data_class field. +// +// Revision 1.2 1999/02/22 22:21:09 korpela +// Fixed half-day error. +// +// Revision 1.1 1999/02/11 16:46:28 korpela +// Initial revision +// + * + */ diff --git a/splitter/db_fns.h b/splitter/db_fns.h new file mode 100644 index 0000000..3ccf871 --- /dev/null +++ b/splitter/db_fns.h @@ -0,0 +1,48 @@ +/* + * $Id: db_fns.h,v 1.3 2003/08/05 17:23:40 korpela Exp $ + * + */ + + +#ifndef DB_FNS_H +#define DB_FNS_H + +#include "schema_master.h" + +int get_last_block(tapeheader_t *tapeheader) ; + +//int update_tape_entry( tapeheader_t *tapeheader) ; + +/* returns workunit group id number on success, 0 on failure */ +//int create_wugrp_entry(char *wugrpname,wuheader_t *wuheader, int tapenum, tapeheader_t *tapeheader) ; + +//int create_workunit_entry(wuheader_t *wuheader, int wugrpid, int subband_number) ; + +#endif + +/* + * + * $Log: db_fns.h,v $ + * Revision 1.3 2003/08/05 17:23:40 korpela + * More work on database stuff. + * Further tweaks. + * + * Revision 1.2 2003/06/03 01:01:16 korpela + * + * First working splitter under CVS. + * + * Revision 1.1 2003/06/03 00:16:10 korpela + * + * Initial splitter under CVS control. + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 1.2 1999/02/22 22:21:09 korpela + * added -nodb option + * + * Revision 1.1 1999/02/11 16:46:28 korpela + * Initial revision + * + * + */ diff --git a/splitter/dotransform.cpp b/splitter/dotransform.cpp new file mode 100644 index 0000000..1663a50 --- /dev/null +++ b/splitter/dotransform.cpp @@ -0,0 +1,218 @@ +/* + * + * dotransform.c + * + * Functions for division by frequency into work units. + * + * $Id: dotransform.cpp,v 1.2.4.1 2006/12/14 22:24:38 korpela Exp $ + * + */ + +#include "sah_config.h" +#include +#include +#include +#include +#include +#include +#include + +#include "splitparms.h" +#include "splittypes.h" +#include "splitter.h" +#include "fftw.h" +#include "wufiles.h" + +/* buffer for fft input/output */ +float databuf[FFT_LEN*2]; + +/* buffer for ftt output before data writes, needs to be multiple + * of three bytes long for encode to work. + */ +#define SAMPLES_PER_OBUF (FFT_LEN*2*3/CHAR_BIT) +unsigned char output_buf[NSTRIPS][SAMPLES_PER_OBUF]; + + +int obuf_pos; /* Tracks current postition in the output buffers */ + + +void output_samples(float *data, int i, int buf_pos) { + int j,k; + unsigned short s; + float *p=data; + + for (j=0;j<2;j++) { + s=0; + for (k=0; k<8; k++) { + s >>= 2; + if (*p>0) s |= 0x8000; + if (*(p+1)>0) s |= 0x4000; + p+=2; + } + output_buf[i][buf_pos++]=*(char *)(&s); + output_buf[i][buf_pos++]=*(((char *)(&s))+1); + } +} + +void splitter_bits_to_float(unsigned short *raw, float *data, int nsamples) { + unsigned int i, j; + unsigned short s; + static int first_time=1; + static float lut[65536][16]; + + assert(!(nsamples % 8)); + + if (first_time) { + for (i=0;i<65536;i++) { + s=(unsigned short)i; + for (j=0;j<8;j++) { + lut[i][j*2]=(float)2*(s & 1)-1; + s >>= 1; + lut[i][j*2+1]=(float)2*(s & 1)-1; + s >>= 1; + } + } + first_time--; + } + + for (i=0;i<(nsamples/8);i++) { + memcpy(data+16*i,lut[raw[i]],16*sizeof(float)); + } +} + +void process_seg(float* data) { + int i; + float* p = data; + static float dbuff[FFT_LEN*2]; + static fftw_plan planfwd,planinverse; + + if (!planfwd) { + planfwd=fftw_create_plan(FFT_LEN, FFTW_BACKWARD, + FFTW_MEASURE | FFTW_IN_PLACE | FFTW_USE_WISDOM ); + planinverse=fftw_create_plan(IFFT_LEN, FFTW_FORWARD, + FFTW_MEASURE | FFTW_IN_PLACE | FFTW_USE_WISDOM ); + } + + fftw_one(planfwd, (fftw_complex *)data, (fftw_complex *)NULL); + data[0]=0; + data[1]=0; + fftw(planinverse, NSTRIPS, (fftw_complex *)data, 1, IFFT_LEN, + (fftw_complex *)NULL, 1, IFFT_LEN); + for (i=0; i TAPE_DATA_SIZE) { + /* End of frame crossed need to trasfer correctly */ + end_trans.frame++; + end_trans.byte-=TAPE_DATA_SIZE; + nsamp=(TAPE_DATA_SIZE-start_trans.byte)*(CHAR_BIT/2); + assert((nsamp+end_trans.byte*(CHAR_BIT/2)) == FFT_LEN); + splitter_bits_to_float((unsigned short *)TBUF_OFFSET(start_trans.frame,start_trans.byte), + databuf, nsamp); + splitter_bits_to_float((unsigned short *)TBUF_OFFSET(end_trans.frame,0),databuf+nsamp*2, + end_trans.byte*(CHAR_BIT/2)); + } else { + splitter_bits_to_float((unsigned short *)TBUF_OFFSET(start_trans.frame,start_trans.byte), + databuf,FFT_LEN); + } + process_seg(databuf); + /* Go on to next transform */ + start_trans=end_trans; + } + /* Check if we're at the end of the wu file. If so we print less bytes */ + if ((end_trans.frame>=end_of_wu->frame) && + (end_trans.byte>=end_of_wu->byte)) { + write_wufile_blocks(NBYTES % SAMPLES_PER_OBUF); + } else { + write_wufile_blocks(SAMPLES_PER_OBUF); + } + } while (!((end_trans.frame>=end_of_wu->frame) && (end_trans.byte>=end_of_wu->byte))); + + /* Move the data in the buffer so we don't have to reread portions of the + * tape. + */ + { + unsigned char *record_offset; + int copysize; + end_of_wu->frame-=WU_OVERLAP_FRAMES; + records_in_buffer=TAPE_RECORDS_IN_BUFFER- + (end_of_wu->frame/TAPE_FRAMES_PER_RECORD); + record_offset=tapebuffer+ + (end_of_wu->frame/TAPE_FRAMES_PER_RECORD)*TAPE_RECORD_SIZE; + copysize=records_in_buffer*TAPE_RECORD_SIZE; + bcopy(record_offset,tapebuffer,copysize); + } +} + +/* + * + * $Log: dotransform.cpp,v $ + * Revision 1.2.4.1 2006/12/14 22:24:38 korpela + * *** empty log message *** + * + * Revision 1.2 2003/09/11 18:53:37 korpela + * *** empty log message *** + * + * Revision 1.1 2003/07/29 20:35:36 korpela + * + * renames .C files to .cpp + * + * Revision 1.1 2003/06/03 00:16:10 korpela + * + * Initial splitter under CVS control. + * + * Revision 3.2 2003/05/19 17:40:59 eheien + * *** empty log message *** + * + * Revision 3.1 2003/04/10 22:09:00 korpela + * *** empty log message *** + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.7 1999/03/27 16:19:35 korpela + * *** empty log message *** + * + * Revision 2.6 1999/02/22 19:02:50 korpela + * Revered input real & imaginary. + * + * Revision 2.5 1999/02/10 21:49:44 korpela + * Zeroed DC component of forward transform. + * + * Revision 2.4 1999/02/01 22:28:52 korpela + * FFTW version. + * + * Revision 2.3 1998/12/14 23:41:44 korpela + * *** empty log message *** + * + * Revision 2.2 1998/11/04 23:08:25 korpela + * Byte and bit order change. + * + * Revision 2.1 1998/11/02 16:41:21 korpela + * Minor Change. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.2 1998/10/30 20:26:03 korpela + * Bug Fixes. Now mostly working. + * + * Revision 1.1 1998/10/27 00:51:08 korpela + * Initial revision + * + * + */ diff --git a/splitter/dotransform.h b/splitter/dotransform.h new file mode 100644 index 0000000..5b3136d --- /dev/null +++ b/splitter/dotransform.h @@ -0,0 +1,56 @@ +/* + * + * dotransform.h + * + * Functions for division by frequency into work units. + * + * $Id: dotransform.h,v 1.1 2003/06/03 00:16:11 korpela Exp $ + * + */ + +/* buffer for fft input/output */ +extern float databuf[FFT_LEN*2]; + +/* buffer for ftt output before data writes, needs to be multiple + * of three bytes long for encode to work. + */ +#define SAMPLES_PER_OBUF (FFT_LEN*2*3/CHAR_BIT) +#define TBUF_OFFSET(frame,byte) (tapebuffer+(frame)*TAPE_FRAME_SIZE+(byte)) +extern unsigned char output_buf[NSTRIPS][SAMPLES_PER_OBUF]; + + +extern int obuf_pos; /* Tracks current postition in the output buffers */ + + +void output_samples(float *data, int i, int buf_pos); +void splitter_bits_to_float(unsigned short *raw, float *data, int nsamples) ; +void process_seg(float* data) ; +void do_transform(buffer_pos_t *start_of_wu, buffer_pos_t *end_of_wu) ; + +/* + * + * $Log: dotransform.h,v $ + * Revision 1.1 2003/06/03 00:16:11 korpela + * + * Initial splitter under CVS control. + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.3 1999/02/01 22:28:52 korpela + * FFTW version. + * + * Revision 2.2 1998/11/04 23:08:25 korpela + * Byte and bit order change. + * + * Revision 2.1 1998/11/02 16:41:21 korpela + * Minor Change. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.1 1998/10/27 01:05:22 korpela + * Initial revision + * + * + */ diff --git a/splitter/encode.cpp b/splitter/encode.cpp new file mode 100644 index 0000000..579697b --- /dev/null +++ b/splitter/encode.cpp @@ -0,0 +1,93 @@ +/* + * + * binary to ascii encoding for work unit files + * + * $Id: encode.cpp,v 1.2.4.2 2007/06/01 03:29:25 korpela Exp $ + * + */ + +#include "sah_config.h" +#include +#include +#include +#include + +/* Write a range of bytes encoded into printable chars. + * Encodes 3 bytes into 4 chars. + * May read up to two bytes past end + */ + +void splitter_encode(unsigned char *bin, int nbytes, FILE *f) { + int count=0, offset=0, nleft, count1=0; + unsigned char c[4*1024+64]; + unsigned char nl=10; + assert(nbytes<=(3*1024)); + for (nleft = nbytes; nleft > 0; nleft -= 3) { + c[0+count1] = bin[offset]&0x3f; // 6 + c[1+count1] = (bin[offset]>>6) | (bin[offset+1]<<2)&0x3f; // 2+4 + c[2+count1] = ((bin[offset+1]>>4)&0xf) | (bin[offset+2]<<4)&0x3f;// 4+2 + c[3+count1] = bin[offset+2]>>2; // 6 + c[0+count1] += 0x20; + c[1+count1] += 0x20; + c[2+count1] += 0x20; + c[3+count1] += 0x20; + offset += 3; + count += 4; + count1 +=4; + if (count == 64) { + count = 0; + c[count1++]=nl; + } + } + write(fileno(f),c,count1); +} + +/* + * + * $Log: encode.cpp,v $ + * Revision 1.2.4.2 2007/06/01 03:29:25 korpela + * Fixes for linux build of Joe's updated code. + * + * Probably not working yet. + * + * Revision 1.2.4.1 2006/12/14 22:24:38 korpela + * *** empty log message *** + * + * Revision 1.2 2003/09/11 18:53:37 korpela + * *** empty log message *** + * + * Revision 1.1 2003/07/29 20:35:37 korpela + * + * renames .C files to .cpp + * + * Revision 1.1 2003/06/03 00:16:11 korpela + * + * Initial splitter under CVS control. + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.3 1998/11/04 23:08:25 korpela + * Byte and bit order change. + * + * Revision 2.2 1998/11/02 21:20:58 korpela + * changed function name from encode() to splitter_encode() to avoid + * conflict with encode routine in ../client/util.C. Will investigate + * if merging of two functions is possible. + * + * Revision 2.1 1998/11/02 16:41:21 korpela + * Minor Change. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.2 1998/10/30 20:26:03 korpela + * Bug Fixes. Now mostly working. + * + * Revision 1.1 1998/10/27 00:52:56 korpela + * Initial revision + * + * + */ + + diff --git a/splitter/encode.h b/splitter/encode.h new file mode 100644 index 0000000..d17775f --- /dev/null +++ b/splitter/encode.h @@ -0,0 +1,39 @@ +/* + * + * binary to ascii encoding for work unit files + * + * $Id: encode.h,v 1.1 2003/06/03 00:16:11 korpela Exp $ + * + */ + +/* Write a range of bytes encoded into printable chars. + * Encodes 3 bytes into 4 chars. + * May read up to two bytes past end + */ + +void splitter_encode(unsigned char *bin, int nbytes, FILE *f); + +/* + * $Log: encode.h,v $ + * Revision 1.1 2003/06/03 00:16:11 korpela + * + * Initial splitter under CVS control. + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.2 1998/11/02 21:20:58 korpela + * Changed routine name from encode() to splitter_encode(). See encode.C + * for details. + * + * Revision 2.1 1998/11/02 16:41:21 korpela + * Minor Change. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.1 1998/10/27 01:06:46 korpela + * Initial revision + * + * + */ diff --git a/splitter/fftw.h b/splitter/fftw.h new file mode 100644 index 0000000..41698f7 --- /dev/null +++ b/splitter/fftw.h @@ -0,0 +1,413 @@ +/* fftw/fftw.h. Generated automatically by configure. */ +/* -*- C -*- */ +/* + * Copyright (c) 1997,1998 Massachusetts Institute of Technology + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/* fftw.h -- system-wide definitions */ +/* $Id: fftw.h,v 1.1 2003/06/03 00:16:12 korpela Exp $ */ + +#ifndef FFTW_H +#define FFTW_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Define for using single precision */ +/* + * If you can, use configure --enable-float instead of changing this + * flag directly + */ +#define FFTW_ENABLE_FLOAT 1 + +/* our real numbers */ +#ifdef FFTW_ENABLE_FLOAT +typedef float fftw_real; +#else +typedef double fftw_real; +#endif + +/********************************************* + * Complex numbers and operations + *********************************************/ +typedef struct { + fftw_real re, im; +} fftw_complex; + +#define c_re(c) ((c).re) +#define c_im(c) ((c).im) + +typedef enum { + FFTW_FORWARD = -1, FFTW_BACKWARD = 1 +} fftw_direction; + +/* backward compatibility with FFTW-1.3 */ +typedef fftw_complex FFTW_COMPLEX; +typedef fftw_real FFTW_REAL; + +#ifndef FFTW_1_0_COMPATIBILITY +#define FFTW_1_0_COMPATIBILITY 0 +#endif + +#if FFTW_1_0_COMPATIBILITY +/* backward compatibility with FFTW-1.0 */ +#define REAL fftw_real +#define COMPLEX fftw_complex +#endif + +/********************************************* + * Success or failure status + *********************************************/ + +typedef enum { + FFTW_SUCCESS = 0, FFTW_FAILURE = -1 +} fftw_status; + +/********************************************* + * Codelets + *********************************************/ +typedef void (fftw_notw_codelet) + (const fftw_complex *, fftw_complex *, int, int); +typedef void (fftw_twiddle_codelet) + (fftw_complex *, const fftw_complex *, int, + int, int); +typedef void (fftw_generic_codelet) + (fftw_complex *, const fftw_complex *, int, + int, int, int); +typedef void (fftw_real2hc_codelet) + (const fftw_real *, fftw_real *, fftw_real *, + int, int, int); +typedef void (fftw_hc2real_codelet) + (const fftw_real *, const fftw_real *, + fftw_real *, int, int, int); +typedef void (fftw_hc2hc_codelet) + (fftw_real *, const fftw_complex *, + int, int, int); +typedef void (fftw_rgeneric_codelet) + (fftw_real *, const fftw_complex *, int, + int, int, int); + +/********************************************* + * Configurations + *********************************************/ +/* + * A configuration is a database of all known codelets + */ + +enum fftw_node_type { + FFTW_NOTW, FFTW_TWIDDLE, FFTW_GENERIC, FFTW_RADER, + FFTW_REAL2HC, FFTW_HC2REAL, FFTW_HC2HC, FFTW_RGENERIC +}; + +/* description of a codelet */ +typedef struct { + const char *name; /* name of the codelet */ + void (*codelet) (); /* pointer to the codelet itself */ + int size; /* size of the codelet */ + fftw_direction dir; /* direction */ + enum fftw_node_type type; /* TWIDDLE or NO_TWIDDLE */ + int signature; /* unique id */ + int ntwiddle; /* number of twiddle factors */ + const int *twiddle_order; /* + * array that determines the order + * in which the codelet expects + * the twiddle factors + */ +} fftw_codelet_desc; + +/* On Win32, you need to do funny things to access global variables + in shared libraries. Thanks to Andrew Sterian for this hack. */ +#if defined(__WIN32__) || defined(WIN32) || defined(_WINDOWS) +# if defined(BUILD_FFTW_DLL) +# define DL_IMPORT(type) __declspec(dllexport) type +# elif defined(USE_FFTW_DLL) +# define DL_IMPORT(type) __declspec(dllimport) type +# else +# define DL_IMPORT(type) type +# endif +#else +# define DL_IMPORT(type) type +#endif + +extern DL_IMPORT(const char *) fftw_version; + +/***************************** + * Plans + *****************************/ +/* + * A plan is a sequence of reductions to compute a FFT of + * a given size. At each step, the FFT algorithm can: + * + * 1) apply a notw codelet, or + * 2) recurse and apply a twiddle codelet, or + * 3) apply the generic codelet. + */ + +/* structure that contains twiddle factors */ +typedef struct fftw_twiddle_struct { + int n; + const fftw_codelet_desc *cdesc; + fftw_complex *twarray; + struct fftw_twiddle_struct *next; + int refcnt; +} fftw_twiddle; + +typedef struct fftw_rader_data_struct { + struct fftw_plan_struct *plan; + fftw_complex *omega; + int g, ginv; + int p, flags, refcount; + struct fftw_rader_data_struct *next; + fftw_codelet_desc *cdesc; +} fftw_rader_data; + +typedef void (fftw_rader_codelet) + (fftw_complex *, const fftw_complex *, int, + int, int, fftw_rader_data *); + +/* structure that holds all the data needed for a given step */ +typedef struct fftw_plan_node_struct { + enum fftw_node_type type; + + union { + /* nodes of type FFTW_NOTW */ + struct { + int size; + fftw_notw_codelet *codelet; + const fftw_codelet_desc *codelet_desc; + } notw; + + /* nodes of type FFTW_TWIDDLE */ + struct { + int size; + fftw_twiddle_codelet *codelet; + fftw_twiddle *tw; + struct fftw_plan_node_struct *recurse; + const fftw_codelet_desc *codelet_desc; + } twiddle; + + /* nodes of type FFTW_GENERIC */ + struct { + int size; + fftw_generic_codelet *codelet; + fftw_twiddle *tw; + struct fftw_plan_node_struct *recurse; + } generic; + + /* nodes of type FFTW_RADER */ + struct { + int size; + fftw_rader_codelet *codelet; + fftw_rader_data *rader_data; + fftw_twiddle *tw; + struct fftw_plan_node_struct *recurse; + } rader; + + /* nodes of type FFTW_REAL2HC */ + struct { + int size; + fftw_real2hc_codelet *codelet; + const fftw_codelet_desc *codelet_desc; + } real2hc; + + /* nodes of type FFTW_HC2REAL */ + struct { + int size; + fftw_hc2real_codelet *codelet; + const fftw_codelet_desc *codelet_desc; + } hc2real; + + /* nodes of type FFTW_HC2HC */ + struct { + int size; + fftw_direction dir; + fftw_hc2hc_codelet *codelet; + fftw_twiddle *tw; + struct fftw_plan_node_struct *recurse; + const fftw_codelet_desc *codelet_desc; + } hc2hc; + + /* nodes of type FFTW_RGENERIC */ + struct { + int size; + fftw_direction dir; + fftw_rgeneric_codelet *codelet; + fftw_twiddle *tw; + struct fftw_plan_node_struct *recurse; + } rgeneric; + } nodeu; + + int refcnt; +} fftw_plan_node; + +struct fftw_plan_struct { + int n; + int refcnt; + fftw_direction dir; + int flags; + int wisdom_signature; + enum fftw_node_type wisdom_type; + struct fftw_plan_struct *next; + fftw_plan_node *root; + double cost; +}; + +/* a plan is just an array of instructions */ +typedef struct fftw_plan_struct *fftw_plan; + +/* flags for the planner */ +#define FFTW_ESTIMATE (0) +#define FFTW_MEASURE (1) + +#define FFTW_OUT_OF_PLACE (0) +#define FFTW_IN_PLACE (8) +#define FFTW_USE_WISDOM (16) + +#define FFTW_THREADSAFE (128) /* guarantee plan is read-only so that the + same plan can be used in parallel by + multiple threads */ + +#define FFTWND_FORCE_BUFFERED (256) /* internal, undocumented flag */ + +extern fftw_plan fftw_create_plan_specific(int n, fftw_direction dir, + int flags, + fftw_complex *in, int istride, + fftw_complex *out, int ostride); +#define FFTW_HAS_PLAN_SPECIFIC +extern fftw_plan fftw_create_plan(int n, fftw_direction dir, int flags); +extern void fftw_print_plan(fftw_plan plan); +extern void fftw_destroy_plan(fftw_plan plan); +extern void fftw(fftw_plan plan, int howmany, fftw_complex *in, int istride, + int idist, fftw_complex *out, int ostride, int odist); +extern void fftw_one(fftw_plan plan, fftw_complex *in, fftw_complex *out); +extern void fftw_die(const char *s); +extern void *fftw_malloc(size_t n); +extern void fftw_free(void *p); +extern void fftw_check_memory_leaks(void); +extern void fftw_print_max_memory_usage(void); + +typedef void *(*fftw_malloc_type_function) (size_t n); +typedef void (*fftw_free_type_function) (void *p); +typedef void (*fftw_die_type_function) (const char *errString); +extern DL_IMPORT(fftw_malloc_type_function) fftw_malloc_hook; +extern DL_IMPORT(fftw_free_type_function) fftw_free_hook; +extern DL_IMPORT(fftw_die_type_function) fftw_die_hook; + +extern size_t fftw_sizeof_fftw_real(void); + +/* Wisdom: */ +/* + * define this symbol so that users know we are using a version of FFTW + * with wisdom + */ +#define FFTW_HAS_WISDOM +extern void fftw_forget_wisdom(void); +extern void fftw_export_wisdom(void (*emitter) (char c, void *), void *data); +extern fftw_status fftw_import_wisdom(int (*g) (void *), void *data); +extern void fftw_export_wisdom_to_file(FILE *output_file); +extern fftw_status fftw_import_wisdom_from_file(FILE *input_file); +extern char *fftw_export_wisdom_to_string(void); +extern fftw_status fftw_import_wisdom_from_string(const char *input_string); + +/* + * define symbol so we know this function is available (it is not in + * older FFTWs) + */ +#define FFTW_HAS_FPRINT_PLAN +extern void fftw_fprint_plan(FILE *f, fftw_plan plan); + +/***************************** + * N-dimensional code + *****************************/ +typedef struct { + int is_in_place; /* 1 if for in-place FFTs, 0 otherwise */ + + int rank; /* + * the rank (number of dimensions) of the + * array to be FFTed + */ + int *n; /* + * the dimensions of the array to the + * FFTed + */ + fftw_direction dir; + + int *n_before; /* + * n_before[i] = product of n[j] for j < i + */ + int *n_after; /* n_after[i] = product of n[j] for j > i */ + + fftw_plan *plans; /* 1d fftw plans for each dimension */ + + int nbuffers, nwork; + fftw_complex *work; /* + * work array big enough to hold + * nbuffers+1 of the largest dimension + * (has nwork elements) + */ +} fftwnd_data; + +typedef fftwnd_data *fftwnd_plan; + +/* Initializing the FFTWND plan: */ +extern fftwnd_plan fftw2d_create_plan(int nx, int ny, fftw_direction dir, + int flags); +extern fftwnd_plan fftw3d_create_plan(int nx, int ny, int nz, + fftw_direction dir, int flags); +extern fftwnd_plan fftwnd_create_plan(int rank, const int *n, + fftw_direction dir, + int flags); + +extern fftwnd_plan fftw2d_create_plan_specific(int nx, int ny, + fftw_direction dir, + int flags, + fftw_complex *in, int istride, + fftw_complex *out, int ostride); +extern fftwnd_plan fftw3d_create_plan_specific(int nx, int ny, int nz, + fftw_direction dir, int flags, + fftw_complex *in, int istride, + fftw_complex *out, int ostride); +extern fftwnd_plan fftwnd_create_plan_specific(int rank, const int *n, + fftw_direction dir, + int flags, + fftw_complex *in, int istride, + fftw_complex *out, int ostride); + +/* Freeing the FFTWND plan: */ +extern void fftwnd_destroy_plan(fftwnd_plan plan); + +/* Printing the plan: */ +extern void fftwnd_fprint_plan(FILE *f, fftwnd_plan p); +extern void fftwnd_print_plan(fftwnd_plan p); +#define FFTWND_HAS_PRINT_PLAN + +/* Computing the N-Dimensional FFT */ +extern void fftwnd(fftwnd_plan plan, int howmany, + fftw_complex *in, int istride, int idist, + fftw_complex *out, int ostride, int odist); +extern void fftwnd_one(fftwnd_plan p, fftw_complex *in, fftw_complex *out); + +#ifdef __cplusplus +} /* extern "C" */ + +#endif /* __cplusplus */ +#endif /* FFTW_H */ diff --git a/splitter/four1.cpp b/splitter/four1.cpp new file mode 100644 index 0000000..f775a98 --- /dev/null +++ b/splitter/four1.cpp @@ -0,0 +1,88 @@ +/* + * + * Fourier transform routine from numerical recipes. + * + * $Id: four1.cpp,v 1.2.4.1 2006/12/14 22:24:38 korpela Exp $ + * + */ + +#include "sah_config.h" +#include +#define SWAP(a,b) tempr=(a);(a)=(b);(b)=tempr + +void four1(float data[], unsigned long nn, int isign) { + unsigned long n,mmax,m,j,istep,i; + double wtemp,wr,wpr,wpi,wi,theta; + float tempr,tempi; + + n=nn << 1; + j=1; + for (i=1;i i) { + SWAP(data[j],data[i]); + SWAP(data[j+1],data[i+1]); + } + m=n >> 1; + while (m >= 2 && j > m) { + j -= m; + m >>= 1; + } + j += m; + } + mmax=2; + while (n > mmax) { + istep=mmax << 1; + theta=isign*(6.28318530717959/mmax); + wtemp=sin(0.5*theta); + wpr = -2.0*wtemp*wtemp; + wpi=sin(theta); + wr=1.0; + wi=0.0; + for (m=1;m +#include + +char* hr_min_sec (double x) { + static char buf[256]; + int hr = (int)(x / 3600); + int min = (int)((x/3600-(double)hr)*60); + float s = (float)(x - ((double)hr)*3600 - ((double)min)*60); + + // the "-.05" below is to prevent it from printing 60.0 sec + // when the real value is e.g. 59.91 + // + sprintf(buf, "%d hr %02d min %04.1f sec", hr, min, s-.05); + return buf; +} + + +/* + * $Log: hr_min_sec.cpp,v $ + * Revision 1.2.4.1 2006/12/14 22:24:39 korpela + * *** empty log message *** + * + * Revision 1.2 2003/09/11 18:53:38 korpela + * *** empty log message *** + * + * Revision 1.1 2003/07/29 20:35:40 korpela + * + * renames .C files to .cpp + * + * Revision 1.1 2003/06/03 01:01:16 korpela + * + * First working splitter under CVS. + * + * Revision 4.4 2003/03/10 02:50:03 jeffc + * jeffc - t_strncpy() + * + * Revision 4.3 2003/01/22 20:51:58 korpela + * Changed all strcpy to strncpy. + * Changed all gets to fgets. + * + * Revision 4.2 2001/12/27 21:35:57 davea + * *** empty log message *** + * + * Revision 4.1 2001/09/10 00:25:17 davea + * *** empty log message *** + * + * Revision 4.0 2000/10/05 18:12:12 korpela + * Synchronized versions to 4.0 following release of 3.0 client + * + * Revision 3.8 2000/09/14 01:01:31 korpela + * *** empty log message *** + * + * Revision 3.7 2000/04/24 08:39:06 charlief + * eliminate compiler warning in hr_min_sec() function. + * + * Revision 3.6 2000/01/19 08:32:32 davea + * *** empty log message *** + * + * Revision 3.5 1999/10/19 08:07:24 davea + * *** empty log message *** + * + * Revision 3.4 1999/06/26 06:56:44 hiramc + * Hiram 99/06/25 23:59 moved the include out of the + * ifdef _WIN32 to define strcpy() for all compiles + * + * Revision 3.3 1999/06/22 09:40:36 charlief + * Reverse last change:restore jd_string() as it was before. + * Add new function short_jd_string(), which does not print + * Julian Date as a floating point value. + * + * Revision 3.1 1999/06/10 00:44:11 korpela + * *** empty log message *** + * + * Revision 3.0 1999/05/14 19:17:35 korpela + * 1.0(Win/Mac) 1.1(Unix) Release Version + * + * Revision 2.11 1999/03/14 00:23:02 davea + * *** empty log message *** + * + * Revision 2.10 1999/03/11 21:46:58 korpela + * Fixed rounding error in st_to_ut(). + * + * Revision 2.9 1999/03/05 09:15:07 kyleg + * *** empty log message *** + * + * Revision 2.8 1999/02/18 19:36:49 korpela + * *** empty log message *** + * + * Revision 2.7 1999/02/13 23:54:44 kyleg + * *** empty log message *** + * + * Revision 2.6 1999/02/11 08:36:54 davea + * *** empty log message *** + * + * Revision 2.5 1998/11/17 21:47:02 korpela + * *** empty log message *** + * + * Revision 2.4 1998/11/05 21:25:21 davea + * replace floor() with (int) + * + * Revision 2.3 1998/11/05 02:00:06 kyleg + * *** empty log message *** + * + * Revision 2.2 1998/11/02 17:59:06 korpela + * *** empty log message *** + * + * Revision 2.1 1998/11/02 17:23:29 korpela + * .` + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.2 1998/10/27 00:58:56 korpela + * Bug fixes. + * + * Revision 1.1 1998/10/19 18:57:56 korpela + * Initial revision + * + * + */ diff --git a/splitter/hr_min_sec.h b/splitter/hr_min_sec.h new file mode 100644 index 0000000..062a2c3 --- /dev/null +++ b/splitter/hr_min_sec.h @@ -0,0 +1,106 @@ +/* + * + * timecvt.c + * + * Time conversion routines. + * + * $Id: hr_min_sec.h,v 1.1 2003/06/03 01:01:16 korpela Exp $ + * + */ + +char* hr_min_sec (double x) ; + + +/* + * $Log: hr_min_sec.h,v $ + * Revision 1.1 2003/06/03 01:01:16 korpela + * + * First working splitter under CVS. + * + * Revision 4.4 2003/03/10 02:50:03 jeffc + * jeffc - t_strncpy() + * + * Revision 4.3 2003/01/22 20:51:58 korpela + * Changed all strcpy to strncpy. + * Changed all gets to fgets. + * + * Revision 4.2 2001/12/27 21:35:57 davea + * *** empty log message *** + * + * Revision 4.1 2001/09/10 00:25:17 davea + * *** empty log message *** + * + * Revision 4.0 2000/10/05 18:12:12 korpela + * Synchronized versions to 4.0 following release of 3.0 client + * + * Revision 3.8 2000/09/14 01:01:31 korpela + * *** empty log message *** + * + * Revision 3.7 2000/04/24 08:39:06 charlief + * eliminate compiler warning in hr_min_sec() function. + * + * Revision 3.6 2000/01/19 08:32:32 davea + * *** empty log message *** + * + * Revision 3.5 1999/10/19 08:07:24 davea + * *** empty log message *** + * + * Revision 3.4 1999/06/26 06:56:44 hiramc + * Hiram 99/06/25 23:59 moved the include out of the + * ifdef _WIN32 to define strcpy() for all compiles + * + * Revision 3.3 1999/06/22 09:40:36 charlief + * Reverse last change:restore jd_string() as it was before. + * Add new function short_jd_string(), which does not print + * Julian Date as a floating point value. + * + * Revision 3.1 1999/06/10 00:44:11 korpela + * *** empty log message *** + * + * Revision 3.0 1999/05/14 19:17:35 korpela + * 1.0(Win/Mac) 1.1(Unix) Release Version + * + * Revision 2.11 1999/03/14 00:23:02 davea + * *** empty log message *** + * + * Revision 2.10 1999/03/11 21:46:58 korpela + * Fixed rounding error in st_to_ut(). + * + * Revision 2.9 1999/03/05 09:15:07 kyleg + * *** empty log message *** + * + * Revision 2.8 1999/02/18 19:36:49 korpela + * *** empty log message *** + * + * Revision 2.7 1999/02/13 23:54:44 kyleg + * *** empty log message *** + * + * Revision 2.6 1999/02/11 08:36:54 davea + * *** empty log message *** + * + * Revision 2.5 1998/11/17 21:47:02 korpela + * *** empty log message *** + * + * Revision 2.4 1998/11/05 21:25:21 davea + * replace floor() with (int) + * + * Revision 2.3 1998/11/05 02:00:06 kyleg + * *** empty log message *** + * + * Revision 2.2 1998/11/02 17:59:06 korpela + * *** empty log message *** + * + * Revision 2.1 1998/11/02 17:23:29 korpela + * .` + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.2 1998/10/27 00:58:56 korpela + * Bug fixes. + * + * Revision 1.1 1998/10/19 18:57:56 korpela + * Initial revision + * + * + */ diff --git a/splitter/libfftw.a b/splitter/libfftw.a new file mode 100644 index 0000000000000000000000000000000000000000..3a34c2f8c23c1710184f8d0ceb1da9c4308fecb0 GIT binary patch literal 248164 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 Smv}HX@77E-_c_tz-TwqHih&#e literal 0 HcmV?d00001 diff --git a/splitter_old/makebufs.cpp b/splitter_old/makebufs.cpp new file mode 100644 index 0000000..1fa2059 --- /dev/null +++ b/splitter_old/makebufs.cpp @@ -0,0 +1,127 @@ +/* + * makebuf.c + * + * Creates temporary files and buffers for use in processing.... + * + * $Id: makebufs.cpp,v 1.1.2.1 2006/01/13 00:24:54 jeffc Exp $ + * + */ + +#include "config.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#include "splitparms.h" +#include "splittypes.h" +#include "splitter.h" + +int tapebuffd; +char tapebufname[30]; + +void delbuffer(void) { + munmap((char *)tapebuffer,TAPE_BUFFER_SIZE); + close(tapebuffd); + unlink(tapebufname); +} + +void delbuffer_sig(int i) { + munmap((char *)tapebuffer,TAPE_BUFFER_SIZE); + close(tapebuffd); + unlink(tapebufname); + exit(1); +} + + + +void makebuffers(unsigned char **tapebuffer) { +/* + * Allocate temp files for tape and wu buffers. Memory mapping these + * files will prevent us from running out of virtual memory + */ +/* sprintf(tapebufname,"tape%d",getpid()); + + if ((tapebuffd=open(tapebufname,O_RDWR|O_CREAT,0777))==-1) { + fprintf(stderr,"Unable to open temp file!\n"); + fprintf(errorlog,"Unable to open temp file!\n"); + exit(EXIT_FAILURE); + } + + if (ftruncate(tapebuffd,TAPE_BUFFER_SIZE) == -1) { + fprintf(stderr,"ftruncate failure\n"); + fprintf(stderr," errno=%d\n",errno); + fprintf(errorlog,"ftruncate failure\n"); + fprintf(errorlog," errno=%d\n",errno); + exit(EXIT_FAILURE); + } + + if (((*tapebuffer= + mmap(0,TAPE_BUFFER_SIZE,PROT_READ|PROT_WRITE,MAP_SHARED,tapebuffd,0))==(char *)-1)) + { + fprintf(stderr,"mmap failure\n"); + fprintf(errorlog,"mmap failure\n"); + exit(EXIT_FAILURE); + } + + atexit(delbuffer); + signal(SIGINT,delbuffer_sig); +*/ + fprintf(stderr, "making tapebuffer of length %d...", TAPE_BUFFER_SIZE); + if (!(*tapebuffer=(unsigned char *)malloc(TAPE_BUFFER_SIZE))) { + exit(0); + } + fprintf(stderr, " done\n"); +} + +/* + * $Log: makebufs.cpp,v $ + * Revision 1.1.2.1 2006/01/13 00:24:54 jeffc + * *** empty log message *** + * + * Revision 1.3 2004/06/16 20:57:18 jeffc + * *** empty log message *** + * + * Revision 1.2 2003/09/11 18:53:38 korpela + * *** empty log message *** + * + * Revision 1.1 2003/07/29 20:35:42 korpela + * + * renames .C files to .cpp + * + * Revision 1.1 2003/06/03 00:16:13 korpela + * + * Initial splitter under CVS control. + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.3 1998/12/14 23:41:44 korpela + * *** empty log message *** + * + * Revision 2.2 1998/11/02 21:20:58 korpela + * Added signal handler for removal of temporary files on SIGINT. + * + * Revision 2.1 1998/11/02 16:41:21 korpela + * Minor Change. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.4 1998/10/30 20:26:03 korpela + * Bug Fixes. Now mostly working. + * + * Revision 1.3 1998/10/27 00:55:43 korpela + * Bug Fixes + * + * Revision 1.2 1998/10/20 20:40:54 korpela + * Removed wu buffer. + * + * Revision 1.1 1998/10/19 19:01:56 korpela + * Initial revision + * + */ diff --git a/splitter_old/makebufs.h b/splitter_old/makebufs.h new file mode 100644 index 0000000..986f7a7 --- /dev/null +++ b/splitter_old/makebufs.h @@ -0,0 +1,41 @@ +/* + * makebufs.h + * + * Creates temporary files and buffers for use in processing.... + * + * $Id: makebufs.h,v 1.1.2.1 2006/01/13 00:24:55 jeffc Exp $ + * + */ + +#ifndef MAKEBUFS_H +#define MAKEBUFS_H + +void makebuffers(unsigned char **tapebuffer); + +#endif + +/* + * $Log: makebufs.h,v $ + * Revision 1.1.2.1 2006/01/13 00:24:55 jeffc + * *** empty log message *** + * + * Revision 1.1 2003/06/03 00:16:14 korpela + * + * Initial splitter under CVS control. + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.1 1998/11/02 16:41:21 korpela + * Minor Change. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.2 1998/10/20 20:41:45 korpela + * Remove wu buffer. + * + * Revision 1.1 1998/10/19 19:02:36 korpela + * Initial revision + * + */ diff --git a/splitter_old/message.cpp b/splitter_old/message.cpp new file mode 100644 index 0000000..6476a92 --- /dev/null +++ b/splitter_old/message.cpp @@ -0,0 +1,52 @@ +/* + * Functions for sending messages to stderr and log files. + * + * $Id: message.cpp,v 1.1.2.1 2006/01/13 00:24:55 jeffc Exp $ + */ + +#include "config.h" +#include +#include +#include + +#include "splitter.h" + +void message(char *msg) { + fprintf(stderr,"%s %s",tapeheaders[0].name,msg); + fprintf(errorlog,"%s %s",tapeheaders[0].name,msg); +} + + + +/* + * $Log: message.cpp,v $ + * Revision 1.1.2.1 2006/01/13 00:24:55 jeffc + * *** empty log message *** + * + * Revision 1.2 2003/09/11 18:53:38 korpela + * *** empty log message *** + * + * Revision 1.1 2003/07/29 20:35:43 korpela + * + * renames .C files to .cpp + * + * Revision 1.1 2003/06/03 00:16:14 korpela + * + * Initial splitter under CVS control. + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.2 2000/12/01 01:13:29 korpela + * *** empty log message *** + * + * Revision 2.1 1998/11/02 16:41:21 korpela + * Minor Change. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.1 1998/10/27 00:56:16 korpela + * Initial revision + * + */ diff --git a/splitter_old/message.h b/splitter_old/message.h new file mode 100644 index 0000000..9da0cf0 --- /dev/null +++ b/splitter_old/message.h @@ -0,0 +1,30 @@ +/* + * Functions for sending messages to stderr and log files. + * + * $Id: message.h,v 1.1.2.1 2006/01/13 00:24:55 jeffc Exp $ + */ + +void message(char *msg); + +/* + * $Log: message.h,v $ + * Revision 1.1.2.1 2006/01/13 00:24:55 jeffc + * *** empty log message *** + * + * Revision 1.1 2003/06/03 00:16:14 korpela + * + * Initial splitter under CVS control. + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.1 1998/11/02 16:41:21 korpela + * Minor Change. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.1 1998/10/27 01:09:00 korpela + * Initial revision + * + */ diff --git a/splitter_old/polyphase.cpp b/splitter_old/polyphase.cpp new file mode 100644 index 0000000..6f64429 --- /dev/null +++ b/splitter_old/polyphase.cpp @@ -0,0 +1,149 @@ + +#include "config.h" +#include +#include +#include +#include +#include +#include +#include + +#include "splitparms.h" +#include "splittypes.h" +#include "splitter.h" +#include "fftw.h" +#include "wufiles.h" +#include "polyphase.h" +#include "dotransform.h" + +/* buffer for fft input/output */ +//float databuf[FFT_LEN*2]; + +/* buffer for ftt output before data writes, needs to be multiple + * of three bytes long for encode to work. + */ +#define SAMPLES_PER_OBUF (FFT_LEN*2*3/CHAR_BIT) + +extern unsigned char output_buf[NSTRIPS][SAMPLES_PER_OBUF]; + +double *filter_r, *filter_i; +float *f_data; + +extern int obuf_pos; /* Tracks current postition in the output buffers */ + +void make_FIR (int n_points, int M, int window, double *output) { + /* Create Mth band lowpass FIR filter, n_points long. */ + + /* Modify this to give 8-bit quantized filter. */ + /* Also generate Hilbert transformed filter */ + + int n; + double q, p; + + for (n=0; n TAPE_DATA_SIZE) { + // End of frame crossed need to trasfer correctly + end_trans.frame++; + end_trans.byte-=TAPE_DATA_SIZE; + nsamp=(TAPE_DATA_SIZE-start_trans.byte)*(CHAR_BIT/2); + assert((nsamp+end_trans.byte*(CHAR_BIT/2)) == FFT_LEN); + splitter_bits_to_float((unsigned short *)TBUF_OFFSET(start_trans.frame,start_trans.byte), + databuf, nsamp); + splitter_bits_to_float((unsigned short *)TBUF_OFFSET(end_trans.frame,0),databuf+nsamp*2, + end_trans.byte*(CHAR_BIT/2)); + } else { + splitter_bits_to_float((unsigned short *)TBUF_OFFSET(start_trans.frame,start_trans.byte), + databuf,FFT_LEN); + } + polyphase_seg(databuf); + // Go on to next transform + start_trans=end_trans; + } + // Check if we're at the end of the wu file. If so we print less bytes + if ((end_trans.frame>=end_of_wu->frame) && + (end_trans.byte>=end_of_wu->byte)) { + write_wufile_blocks(NBYTES % SAMPLES_PER_OBUF); + } else { + write_wufile_blocks(SAMPLES_PER_OBUF); + } + } while (!((end_trans.frame>=end_of_wu->frame) && (end_trans.byte>=end_of_wu->byte))); + + // Move the data in the buffer so we don't have to reread portions of the + // tape. + // + { + unsigned char *record_offset; + int copysize; + end_of_wu->frame-=WU_OVERLAP_FRAMES; + records_in_buffer=TAPE_RECORDS_IN_BUFFER- + (end_of_wu->frame/TAPE_FRAMES_PER_RECORD); + record_offset=tapebuffer+ + (end_of_wu->frame/TAPE_FRAMES_PER_RECORD)*TAPE_RECORD_SIZE; + copysize=records_in_buffer*TAPE_RECORD_SIZE; + bcopy(record_offset,tapebuffer,copysize); + } +} + + diff --git a/splitter_old/polyphase.h b/splitter_old/polyphase.h new file mode 100644 index 0000000..0393c38 --- /dev/null +++ b/splitter_old/polyphase.h @@ -0,0 +1,26 @@ +#define NONE 0 +#define WELCH 1 +#define HANNING 2 + +#define N_WINDOWS 8 +#define P_FFT_LEN 256 + +/* buffer for fft input/output */ +extern float databuf[FFT_LEN*2]; + +/* buffer for ftt output before data writes, needs to be multiple + * of three bytes long for encode to work. + */ +#define SAMPLES_PER_OBUF (FFT_LEN*2*3/CHAR_BIT) +#define TBUF_OFFSET(frame,byte) (tapebuffer+(frame)*TAPE_FRAME_SIZE+(byte)) +extern unsigned char output_buf[NSTRIPS][SAMPLES_PER_OBUF]; + +extern double *filter_r, *filter_i; +extern float *f_data; + +extern int obuf_pos; /* Tracks current postition in the output buffers */ + +void make_FIR (int n_points, int M, int window, double *output); +void polyphase_seg(float *data); +void do_polyphase(buffer_pos_t *start_of_wu, buffer_pos_t *end_of_wu); + diff --git a/splitter_old/randomdata.cpp b/splitter_old/randomdata.cpp new file mode 100644 index 0000000..9947e29 --- /dev/null +++ b/splitter_old/randomdata.cpp @@ -0,0 +1,77 @@ +#include "config.h" +#include +#include +#include +#include +#include +#include + +#define NUM_FRAMES 200L +#define FRAME_DATA_SIZE (1024L*1024) +#define HEADER_SIZE 1024 +#define FILESIZE (NUM_FRAMES*(FRAME_DATA_SIZE+HEADER_SIZE)) + +char header[HEADER_SIZE]; + +int main(void) { + int i; + int datapos=0; + int frameseq=0; + long written=0; + int on=0; + struct tm *tm; + unsigned char data; + + char tmpstr[256]; + char telstr[256]; + double time0=(double)time(0); + time_t clock; + + srandom(time(0)); + + for (written=0;writtentm_year,tm->tm_yday,tm->tm_hour,tm->tm_min,tm->tm_sec,(int)((time0-floor(time0))*100)); + strcpy(header+headerpos,tmpstr); + headerpos+=strlen(tmpstr)+1; + if (!((frameseq-1)%5)) { + sprintf(telstr,"TELSTR=%.2d%.3d%.2d%.2d%.2d 0.0 0.0 15.0",tm->tm_year,tm->tm_yday,tm->tm_hour,tm->tm_min,tm->tm_sec); + } + strcpy(header+headerpos,telstr); + headerpos+=strlen(telstr)+1; + strcpy(header+headerpos,"RECEIVER=ao1420"); + headerpos+=strlen("RECEIVER=ao1420")+1; + strcpy(header+headerpos,"SAMPLERATE=2.5000"); + headerpos+=strlen("SAMPLERATE=2.5000")+1; + strcpy(header+headerpos,"CENTERFREQ=1420.0"); + headerpos+=strlen("CENTERFREQ=1420.0")+1; + strcpy(header+headerpos,"VER=1.00"); + headerpos+=strlen("VER=1.00")+1; + strcpy(header+headerpos,"NUMRINGBUFS=4"); + headerpos+=strlen("NUMRINGBUFS=4")+1; + strcpy(header+headerpos,"NUMDISKBUFS=2"); + headerpos+=strlen("NUMDISKBUFS=2")+1; + strcpy(header+headerpos,"EOH="); + write(stdout->_file, header, HEADER_SIZE); + for(i=0;i_file, &data, 1); + } + time0+=(1024.0*1024.0*4.0/2.5e6); + } +} + diff --git a/splitter_old/readheader.cpp b/splitter_old/readheader.cpp new file mode 100644 index 0000000..fd9c123 --- /dev/null +++ b/splitter_old/readheader.cpp @@ -0,0 +1,218 @@ +/* + * Functions for reading tape and work unit headers + * + * This file currently assumes that the reciever is at Arecibo. + * + * $Id: readheader.cpp,v 1.1.2.1 2006/01/13 00:24:58 jeffc Exp $ + * + */ + +#include "config.h" +#include +#include +#include +#include +#include +#include + +#include "splitter.h" +#include "splitparms.h" +#include "splittypes.h" +#include "message.h" +#include "timecvt.h" +#include "coordcvt.h" + +/* Read a tape header at buffer into a tapeheader_t */ +int read_tape_header(char *buffer, tapeheader_t *header) +{ + static char *receivers[]={"","synthetic","ao1420"}; + int done=0,len; + int pos=0,i; + char tmpstr[256]; + double dummy; + unsigned int firstdata; + + do { + len=strlen(buffer+pos)+1; + if (!strncmp(buffer+pos,"EOH=",4)) { + done=1; + } else if (!strncmp(buffer+pos,"NAME=",5)) { + strncpy(tmpstr,buffer+pos+5,36); + i=0; + while(!isalnum(tmpstr[i])) i++; + strncpy(header->name,tmpstr+i,36); + } else if (!strncmp(buffer+pos,"RCDTYPE=",8)) { + sscanf(buffer+pos+8,"%d",&(header->rcdtype)); + } else if (!strncmp(buffer+pos,"FRAMESEQ=",9)) { + sscanf(buffer+pos+9,"%lu",&(header->frameseq)); + } else if (!strncmp(buffer+pos,"DATASEQ=",8)) { + sscanf(buffer+pos+8,"%lu",&(header->dataseq)); + } else if (!strncmp(buffer+pos,"NUMRINGBUFS=",12)) { + sscanf(buffer+pos+12,"%d",&(header->numringbufs)); + } else if (!strncmp(buffer+pos,"NUMDISKBUFS=",12)) { + sscanf(buffer+pos+12,"%d",&(header->numdiskbufs)); + } else if (!strncmp(buffer+pos,"MISSED=",7)) { + sscanf(buffer+pos+7,"%d",&(header->missed)); + } else if (!strncmp(buffer+pos,"AST=",4)) { + sscanf(buffer+pos+4,"%2d%3d%2d%2d%2d%2d", + &(header->st.y), &(header->st.d), &(header->st.h), + &(header->st.m), &(header->st.s), &(header->st.c)); + header->st.tz=AST; + } else if (!strncmp(buffer+pos,"TELSTR=",7)) { + sscanf(buffer+pos+7,"%2d%3d%2d%2d%2d %lf %lf %lf", + &(header->telstr.st.y), &(header->telstr.st.d), + &(header->telstr.st.h), &(header->telstr.st.m), + &(header->telstr.st.s), &(header->telstr.az), + gregorian?&(header->telstr.alt):&dummy, + gregorian?&dummy:&(header->telstr.alt)); + header->telstr.alt=90.0-header->telstr.alt; + header->telstr.st.tz=AST; + header->telstr.st.c=0; + } else if (!strncmp(buffer+pos,"RECEIVER=",9)) { + i=1; + while ((!strstr(buffer+pos+9,receivers[i])) && (++isource=0; + } else { + header->source=i; + } + } else if (!strncmp(buffer+pos,"CENTERFREQ=",11)) { + sscanf(buffer+pos+11,"%lf",&(header->centerfreq)); + header->centerfreq*=1e6; + } else if (!strncmp(buffer+pos,"SAMPLERATE=",11)) { + sscanf(buffer+pos+11,"%lf",&(header->samplerate)); + header->samplerate*=1e6; + } else if (!strncmp(buffer+pos,"VER=",4)) { + strncpy(&(header->version[0]),&(buffer[pos+4]),16); + } else if (len>1) { + sprintf(tmpstr,"Unknown header field: %40s\n",buffer+pos); + message(tmpstr); + } + pos+=len; + } while (!done && (posst)); + header->st.jd-=(float)RECORDER_BUFFER_SAMPLES/header->samplerate/86400; + st_time_convert(&(header->telstr.st)); + telstr_coord_convert(&(header->telstr),ARECIBO_LAT,ARECIBO_LON); + +/* + * Fix a bug in recorder versions prior to 1.30 + */ + + if (atof(&(header->version[0]))<1.299) { + header->centerfreq-=2.0; + } + +/* + * Check for blank tape + */ + firstdata=*(unsigned int *)(buffer+TAPE_HEADER_SIZE); + if (!(firstdata & 0x55555555) || !(firstdata & 0xaaaaaaaa) || + ((firstdata & 0x55555555) == 0x55555555) || + ((firstdata & 0xaaaaaaaa) == 0xaaaaaaaa)) { + header->missed++; + sprintf(tmpstr,"Possible data problem...data[0] = 0x%x\n",firstdata); + message(tmpstr); + } + + return(1); +} + +/* Read a work unit header from a FILE into a wuheader_t */ +//int read_wu_header(FILE *file, wuheader_t *header) { +/* to be implemented. Don't need it yet. */ +// return(0); +//} + +int parse_tape_headers(unsigned char *tapebuffer, tapeheader_t *tapeheaders) { + int i; + + for (i=0;i +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "util.h" +#include "splitparms.h" +#include "splitter.h" +#include "message.h" +#include "readheader.h" +#include "readtape.h" +#include "sqlrow.h" +#include "sqlblob.h" +#include "sqlapi.h" +#include "db_table.h" +#include "schema_master.h" + +int is_tape; + +static tape tape_info; + +int current_record; +static int tape_fd; +struct mtget tape_status; + +static void update_checkpoint() { + FILE *file=fopen("rcd.chk","w"); + if (file) { + fprintf(file,"%d\n",current_record); + fclose(file); + } +} + +int read_checkpoint() { + FILE *file=fopen("rcd.chk","r"); + int retval=0; + if (file) { + fscanf(file,"%d",&retval); + fclose(file); + } + return(retval); +} + +int tape_busy() { +/* Check if tape is busy. If so return 1 else return 0 + */ + if (is_tape) { + if (ioctl(tape_fd,MTIOCGET,&tape_status) != -1) { + return (tape_status.mt_dsreg); + } else { + message("Unable to get tape status\n"); + return (1); + } + } else { + return (0); + } +} + +int tape_eject() { +/* Rewind and eject the tape. Return 1 if sucessful else return 0 + */ + struct mtop op={MTOFFL,1}; + + close(tape_fd); + if (is_tape) { + while (tape_busy()) sleep(1); + if (ioctl(tape_fd,MTIOCTOP,&op)==-1) { + message("Unable to eject tape\n"); + return(0); + } else { + return(1); + } + } else { + return(1); + } +} + + +int tape_rewind() { +/* Rewind to beginning of tape. Return 1 if sucessful, 0 if failure + */ + struct mtop op={MTREW, 1}; + if (is_tape) { + while (tape_busy()) sleep(1); + if (ioctl(tape_fd,MTIOCTOP,&op)!=-1) { + current_record=0; + update_checkpoint(); + } else { + current_record=-1; + message("Tape rewind failed\n"); + } + } else { + if (lseek(tape_fd, 0, SEEK_SET)!=-1) { + current_record=0; + update_checkpoint(); + } else { + current_record=-1; + message("File rewind failed\n"); + } + } + return (!current_record); +} + + + +int open_tape_device(char *device) { +/* opens a device, checks if it is a tape device. If so, sets is_tape + * flag. If not, it resets the flag. All tape routines check this flag + * so routines will work for both tapes and files + */ + + + int fd, errcnt=0; + struct mtop op={MTNOP,1}; + + if ((fd=open(device, O_RDONLY|0x2000, 0777))!=-1) { + tape_fd=fd; + if (ioctl(tape_fd,MTIOCGET,&tape_status) != -1) { + is_tape = 1; + } else { + is_tape = 0; + } + while (!norewind && !tape_rewind() && errcnt<10 ) errcnt++; + if (!nodb && resumetape) { + tape_rewind(); + fill_tape_buffer(tapebuffer,TAPE_RECORDS_IN_BUFFER); + parse_tape_headers(tapebuffer, &(tapeheaders[0])); + if (!tape_info.id) { + if (!tape_info.fetch(std::string("where name=\'")+tapeheaders->name+"\'")) { + tape_info.start_time=tapeheaders->st.jd; + tape_info.last_block_time=tapeheaders->st.jd; + tape_info.last_block_done=tapeheaders->frameseq; + strlcpy(tape_info.name,tapeheaders->name,sizeof(tape_info.name)); + tape_info.insert(); + } + } + startblock=tape_info.last_block_done/TAPE_FRAMES_PER_RECORD; + } + if (norewind) { + startblock=MAX(read_checkpoint()-TAPE_RECORDS_IN_BUFFER,0); + tape_rewind(); + } + if (startblock) { + return select_record(startblock); + } + return (1); + } else { + perror( NULL ); + return (0); + } +} + +int select_record(int record_number) { +/* seeks to a specific record number returns 1 if successful */ + int diff; + struct mtop op; + char tmpstr[100]; + off64_t off,offset; + + if ((current_record<0) && !tape_rewind()) { + message("Tape error: position lost and unable to rewind!\n"); + return(0); + } + + diff=record_number-current_record; + + if (is_tape) { + if (diff==0) return (1); + if (diff>0) { + op.mt_op=MTFSR; + op.mt_count=diff; + } else { + op.mt_op=MTBSR; + op.mt_count=diff; + } + if (ioctl(tape_fd,MTIOCTOP,&op)==-1) { + sprintf(tmpstr,"Tape error: unable to position to record %d\nerrno=%d\n", + record_number,errno); + message(tmpstr); + current_record=-1; + return(0); + } else { + current_record+=diff; + update_checkpoint(); + return(1); + } + } else { + current_record=record_number; + update_checkpoint(); + offset = record_number; + offset *= TAPE_RECORD_SIZE; + //fprintf( stderr, "offset: %lld", offset ); + off=lseek64(tape_fd,offset,SEEK_SET) ; + //fprintf( stderr, "off: %lld", offset ); + return (off != -1); + } +} + +int tape_read_record(char *buffer) { + int bytesread=0; + int i; + + while (tape_busy()) sleep(1); + + do { + i=read(tape_fd,buffer+bytesread,TAPE_RECORD_SIZE); + if (i>0) bytesread+=i; + } while ((bytesread0)); + + if (i==0) { + message("End of tape. Please insert new tape\n"); + current_record=-1; + return(0); + } + + if (i<0) { + message("Tape error.\n"); + current_record=-1; + return(0); + } + + current_record++; + update_checkpoint(); + return(1); +} + +int fill_tape_buffer(unsigned char *buffer, int n_records) { + int i; + long record; + char tmpstr[100]; + + for (i=0;i + +#define WU_SUBDIR "/download" + +#define SPLITTER_VERSION 0x0012 +#define MAX_WUS_ONDISK 500000 +#define N_SIMULT_SPLITTERS 6 + +/* Work Unit Parameters */ +#define NBYTES 262144L +#define NSAMPLES (NBYTES*CHAR_BIT/2) +#define MAX_POSITION_HISTORY 40 +#define WU_FILESIZE (360L*1024) + +/* FFT Parameters */ +#define FFT_LEN 2048 +#define IFFT_LEN 8 +#define NSTRIPS (FFT_LEN/IFFT_LEN) + +/* Tape format parameters */ +#define TAPE_HEADER_SIZE 1024L +#define TAPE_DATA_SIZE 1048576L +#define TAPE_FRAMES_PER_RECORD 8L +#define TAPE_FRAME_SIZE (TAPE_HEADER_SIZE+TAPE_DATA_SIZE) +#define TAPE_RECORD_SIZE (TAPE_FRAMES_PER_RECORD*TAPE_FRAME_SIZE) +#define TAPE_BUFFER_SIZE (((NSTRIPS*NBYTES*7/4)/TAPE_RECORD_SIZE+1)*TAPE_RECORD_SIZE) +#define TAPE_RECORDS_IN_BUFFER (TAPE_BUFFER_SIZE/TAPE_RECORD_SIZE) +#define TAPE_FRAMES_IN_BUFFER (TAPE_RECORDS_IN_BUFFER*8) +#define TAPE_FRAMES_PER_WU (NBYTES*NSTRIPS/TAPE_DATA_SIZE) +#define WU_OVERLAP_RECORDS 2 +#define WU_OVERLAP_FRAMES (TAPE_FRAMES_PER_RECORD*WU_OVERLAP_RECORDS) +#define WU_OVERLAP_BYTES (WU_OVERLAP_FRAMES*TAPE_DATA_SIZE) +#define RECORDER_BUFFER_BYTES (1024L*1024L) +#define RECORDER_BUFFER_SAMPLES (RECORDER_BUFFER_BYTES*4) + + +/* Time Zone Parameters */ +#define UTC 0.0 +#define AST (UTC-4.0) + +/* Arecibo Observatory Parameters */ +#define ARECIBO_LAT 18.3538056 +#define ARECIBO_LON (-66.7552222) + +#endif +/* + * $Log: splitparms.h,v $ + * Revision 1.1.2.1 2006/01/13 00:25:00 jeffc + * *** empty log message *** + * + * Revision 1.10 2004/11/23 21:26:29 jeffc + * *** empty log message *** + * + * Revision 1.9 2004/08/14 04:44:26 jeffc + * *** empty log message *** + * + * Revision 1.8 2004/06/16 20:57:19 jeffc + * *** empty log message *** + * + * Revision 1.7 2004/05/22 18:12:18 korpela + * *** empty log message *** + * + * Revision 1.6 2003/10/27 17:53:21 korpela + * *** empty log message *** + * + * Revision 1.5 2003/09/26 20:48:51 jeffc + * jeffc - merge in branch setiathome-4_all_platforms_beta. + * + * Revision 1.3.2.1 2003/09/22 17:39:34 korpela + * *** empty log message *** + * + * Revision 1.4 2003/09/22 17:05:38 korpela + * *** empty log message *** + * + * Revision 1.3 2003/09/11 18:53:38 korpela + * *** empty log message *** + * + * Revision 1.2 2003/08/05 17:23:42 korpela + * More work on database stuff. + * Further tweaks. + * + * Revision 1.1 2003/06/03 00:23:40 korpela + * + * Again + * + * Revision 3.1 2001/11/07 00:51:47 korpela + * Added splitter version to database. + * Added max_wus_ondisk option. + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.9 2000/12/01 01:13:29 korpela + * *** empty log message *** + * + * Revision 2.8 1999/10/20 19:20:26 korpela + * *** empty log message *** + * + * Revision 2.7 1999/06/07 21:00:52 korpela + * *** empty log message *** + * + * Revision 2.6 1999/03/27 16:19:35 korpela + * *** empty log message *** + * + * Revision 2.5 1999/03/05 01:47:18 korpela + * Added data_class field. + * + * Revision 2.4 1999/02/23 18:57:09 korpela + * *** empty log message *** + * + * Revision 2.3 1999/02/22 22:21:09 korpela + * Changed version number. + * + * Revision 2.2 1999/02/11 16:46:28 korpela + * Added WU_FILESIZE, RECORDER_BUFFER_BYTES, RECORDER_BUFFER_SAMPLES.` + * + * Revision 2.1 1998/11/02 16:38:29 korpela + * Variable type changes. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.4 1998/10/27 01:10:04 korpela + * Bug fixes. + * + * Revision 1.3 1998/10/19 23:06:40 korpela + * Added UTC and AST definition. + * Added ARECIBO_LAT and ARECIBO_LON definitions. + * + * Revision 1.2 1998/10/16 19:22:14 korpela + * Reduced WU file size from 512K to 256K. + * + * Revision 1.1 1998/10/15 16:39:51 korpela + * Initial revision + * + */ + diff --git a/splitter_old/splitter.cpp b/splitter_old/splitter.cpp new file mode 100644 index 0000000..9710d85 --- /dev/null +++ b/splitter_old/splitter.cpp @@ -0,0 +1,682 @@ +/* + * + * The splitter main program. + * + * $Id: splitter.cpp,v 1.1.2.1 2006/01/13 00:25:00 jeffc Exp $ + * + */ + +#include "config.h" +#undef USE_MYSQL +#include +#include +#include +#include +#include +#include + +#include "boinc_db.h" +#include "crypt.h" +#include "backend_lib.h" +#include "sched_config.h" +#include "splitparms.h" +#include "splittypes.h" +#include "splitter.h" +#include "validrun.h" +#include "makebufs.h" +#include "readtape.h" +#include "readheader.h" +#include "wufiles.h" +#include "dotransform.h" +#include "polyphase.h" +#include "sqlrow.h" +#include "sqlapi.h" +#include "db/db_table.h" +#include "db/schema_master.h" +#include "db/app_config.h" + +extern "C" { + int sqldetach(); +} + + +SCHED_CONFIG boinc_config; +DB_APP app; +R_RSA_PRIVATE_KEY key; + + +// TEMPLATE DEFS ------------------------------------------------------ +// IMPORTANT: a change to a template should *always* include a change +// to the template filename. Only the result template is used now. +const char *wu_template_filename_id = "wu_0.xml"; +const char *wu_template= + "\n" + " 0\n" + "\n" + "\n" + " \n" + " 0\n" + " work_unit.sah\n" + " \n" + "\n"; + +const char *result_template_filename_id = "result_0.xml"; +const char *result_template= + "\n" + " \n" + " \n" + " \n" + " 65536\n" + " http://setiboincdata.ssl.berkeley.edu/sah_cgi/file_upload_handler\n" + "\n" + "\n" + " \n" + " \n" + " result.sah\n" + " \n" + "\n"; +// END TEMPLATE DEFS -------------------------------------------------- + +unsigned char *tapebuffer; /* A buffer for a tape section */ +workunit wuheaders[NSTRIPS]; +tapeheader_t tapeheaders[TAPE_FRAMES_IN_BUFFER]; +int max_wus_ondisk=MAX_WUS_ONDISK; +int nodb; +int noencode; +int resumetape; +int norewind; +int startblock; +int dataclass; +int atnight; +int gregorian; +int output_xml; +int polyphase; +int filter_window = 0; +double start_time; +double stop_time; +unsigned long minvfsbuf=-1; +char wd[1024]; +//char * scidb = NULL; +char * projectdir = NULL; + +APP_CONFIG sah_config; + +//const char *result_template_filename="projectdir"/"SAH_APP_NAME"_result.tpl"; +char result_template_filename[1024]; +char result_template_filepath[1024]; +char wu_template_filename[1024]; + +int check_for_halt(); +int wait_until_night(); +int check_free_disk_space(); +int wait_for_db_wus_ondisk(); + +void cprint(char *p) { + printf("%s\n",p); +} + +/* wulog: File for logging names of completed wu files */ +/* errorlog: File for logging errors */ + +FILE *wulog,*errorlog; +buffer_pos_t start_of_wu,end_of_wu; /* position of start and end of wu in + tape buffer */ +int seqno; +int records_in_buffer; + +void cleanup(void) { + FILE *tmpfile; + if ((tmpfile=fopen("seqno.dat","w"))) { + fprintf(tmpfile,"%d\n",seqno); + fclose(tmpfile); + } else { + fprintf(stderr,"Unable to open seqno.dat for write\n"); + fprintf(errorlog,"Unable to open seqno.dat for write\n"); + } +} + + +int process_command_line(int argc, char *argv[],char **tape_device, + int *norewind, int *startblock, int *resumetape, + int *nodb, int *dataclass, int *atnight, + int *max_wus_ondisk, char **projectdir) { + int nargs=0,i; + char *ep; + for (i=1;itm_wday>0) && (lt->tm_wday<6) && (lt->tm_hour>8) && (lt->tm_hour<18)) { + sleep(100); + } + } while ((lt->tm_wday>0) && (lt->tm_wday<6) && (lt->tm_hour>8) && (lt->tm_hour<18)); + return 0; +} + +int check_free_disk_space() { + struct statvfs vfsbuf; + + /* check disk free space */ + statvfs("wu_inbox/.",&vfsbuf); + if (vfsbuf.f_bavail < (100000*1024/vfsbuf.f_frsize)) { + fprintf(stderr, + "Not enough free disk space in working directory to continue\n"); + fprintf(errorlog, + "Not enough free disk space in working directory to continue\n"); + exit(EXIT_FAILURE); + } + return 0; +} + +int wait_for_db_wus_ondisk() { + int wus_ondisk,rv; + + // The boinc db query below takes a long time. Until we fix this, + // we will do it only every 100 times into this routine. All other + // calls here will assume that we need to add WUs. -- jeffc + static int check_count = 100; + if (check_count < 100) { + check_count++; + return 0; + } else { + check_count = 0; + } + + if (boinc_db.open(boinc_config.db_name,boinc_config.db_host,boinc_config.db_user,boinc_config.db_passwd)) { + boinc_db.print_error("boinc_db.open"); + fprintf(errorlog,"boinc_db.open\n"); + exit(1); + } + do { + DB_RESULT boinc_result; + char query[1024]; + sprintf(query,"where appid=%d and server_state=2",app.id); + rv=boinc_result.count(wus_ondisk,query); + if (rv) { + boinc_db.print_error("boinc_result.count"); + fprintf(stderr,"DB Error, unable to count workunits on disk\n"); + fprintf(errorlog,"DB Error, unable to count workunits on disk\n"); + exit(EXIT_FAILURE); + } + check_for_halt(); + fprintf(stderr,"%d WUs ondisk\n", wus_ondisk); + fprintf(errorlog,"%d WUs ondisk\n", wus_ondisk); + if (wus_ondisk>sah_config.max_wus_ondisk) sleep(600); + } while (wus_ondisk>sah_config.max_wus_ondisk); + + return 0; +} + +/* + * $Log: splitter.cpp,v $ + * Revision 1.1.2.1 2006/01/13 00:25:00 jeffc + * *** empty log message *** + * + * Revision 1.23 2006/01/10 00:06:07 jeffc + * *** empty log message *** + * + * Revision 1.22 2005/01/27 23:03:27 mattl + * + * commented out tf=0 in check_for_halt + * + * Revision 1.21 2004/12/27 20:48:54 jeffc + * *** empty log message *** + * + * Revision 1.20 2004/08/12 15:45:41 jeffc + * *** empty log message *** + * + * Revision 1.19 2004/07/09 22:35:39 jeffc + * *** empty log message *** + * + * Revision 1.18 2004/06/27 21:07:04 jeffc + * *** empty log message *** + * + * Revision 1.17 2004/06/20 18:56:48 jeffc + * *** empty log message *** + * + * Revision 1.16 2004/06/18 23:23:32 jeffc + * *** empty log message *** + * + * Revision 1.15 2004/06/16 20:57:19 jeffc + * *** empty log message *** + * + * Revision 1.14 2004/04/08 22:25:47 jeffc + * *** empty log message *** + * + * Revision 1.13 2004/01/22 00:57:53 korpela + * *** empty log message *** + * + * Revision 1.12 2004/01/01 18:42:01 korpela + * *** empty log message *** + * + * Revision 1.11 2003/12/03 23:46:41 korpela + * WU count is now only for SAH workunits. + * + * Revision 1.10 2003/11/25 21:59:52 korpela + * *** empty log message *** + * + * Revision 1.9 2003/11/01 20:54:02 korpela + * *** empty log message *** + * + * Revision 1.8 2003/10/24 16:57:03 korpela + * *** empty log message *** + * + * Revision 1.7 2003/09/26 20:48:51 jeffc + * jeffc - merge in branch setiathome-4_all_platforms_beta. + * + * Revision 1.5.2.2 2003/09/23 00:49:12 korpela + * *** empty log message *** + * + * Revision 1.5.2.1 2003/09/22 17:39:34 korpela + * *** empty log message *** + * + * Revision 1.6 2003/09/22 17:05:38 korpela + * *** empty log message *** + * + * Revision 1.5 2003/09/13 20:48:38 korpela + * directory reorg. Moved client files to ./client + * + * Revision 1.4 2003/09/11 18:53:38 korpela + * *** empty log message *** + * + * Revision 1.3 2003/08/13 23:18:47 korpela + * *** empty log message *** + * + * Revision 1.2 2003/08/05 17:23:42 korpela + * More work on database stuff. + * Further tweaks. + * + * Revision 1.1 2003/07/29 20:35:50 korpela + * + * renames .C files to .cpp + * + * Revision 1.2 2003/06/03 01:01:17 korpela + * + * First working splitter under CVS. + * + * Revision 1.1 2003/06/03 00:23:40 korpela + * + * Again + * + * Revision 3.6 2003/05/21 00:41:42 korpela + * *** empty log message *** + * + * Revision 3.5 2003/05/19 17:40:59 eheien + * *** empty log message *** + * + * Revision 3.4 2003/04/09 17:46:54 korpela + * *** empty log message *** + * + * Revision 3.3 2002/06/20 22:09:17 eheien + * *** empty log message *** + * + * Revision 3.2 2001/11/07 00:51:47 korpela + * Added splitter version to database. + * Added max_wus_ondisk option. + * + * Revision 3.1 2001/08/16 23:42:08 korpela + * Mods for splitter to make binary workunits. + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.7 2000/12/01 01:13:29 korpela + * *** empty log message *** + * + * Revision 2.6 1999/06/07 21:00:52 korpela + * *** empty log message *** + * + * Revision 2.5 1999/03/27 16:19:35 korpela + * *** empty log message *** + * + * Revision 2.4 1999/03/05 01:47:18 korpela + * Added dataclass paramter. + * + * Revision 2.3 1999/02/22 22:21:09 korpela + * added -nodb option + * + * Revision 2.2 1999/02/11 16:46:28 korpela + * Added some db access functions. + * + * Revision 2.1 1998/11/02 16:41:21 korpela + * Minor Change. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.2 1998/10/30 20:26:03 korpela + * Bug Fixes. Now mostly working. + * + * Revision 1.1 1998/10/27 00:58:16 korpela + * Initial revision + * + * + */ diff --git a/splitter_old/splitter.h b/splitter_old/splitter.h new file mode 100644 index 0000000..f750402 --- /dev/null +++ b/splitter_old/splitter.h @@ -0,0 +1,122 @@ +/* + * splitter.h + * + * Global definitions from the splitter main program. + * + * $Id: splitter.h,v 1.1.2.1 2006/01/13 00:25:01 jeffc Exp $ + * + */ + +#ifndef SPLITTER_H +#define SPLITTER_H + +#include "splitparms.h" +#include "splittypes.h" + +#define MAX(x,y) ( ((x)<(y)) ? (y) : (x) ) +#define MIN(x,y) ( ((y)<(x)) ? (y) : (x) ) + +/* wulog: File for logging names of completed wu files */ +/* errorlog: File for logging errors */ +#include "boinc_db.h" +#include "crypt.h" +#include "backend_lib.h" +#include "sched_config.h" + +extern SCHED_CONFIG boinc_config; +extern DB_APP app; +extern R_RSA_PRIVATE_KEY key; +extern FILE *wulog,*errorlog; +extern workunit wuheaders[NSTRIPS]; +extern tapeheader_t tapeheaders[TAPE_FRAMES_IN_BUFFER]; +extern int noencode; +extern int dataclass; +extern int nodb; +extern int resumetape; +extern int startblock; +extern int norewind; +extern int output_xml; +extern int polyphase; +extern int wu_database_id[NSTRIPS]; +extern int gregorian; +extern char * projectdir; + +/* Buffer that holds tape data */ +extern unsigned char *tapebuffer; + +/* Number of records remaining in the buffer after WU creations is complete */ +extern int records_in_buffer; + +extern const char *wu_template; +extern const char *result_template; +// jeffc +//extern const char *result_template_filename; +extern char result_template_filename[]; +extern char result_template_filepath[]; +extern char wu_template_filename[]; + +/* Persistant sequence number of wu file */ +extern int seqno; + +#endif + +/* + * $Log: splitter.h,v $ + * Revision 1.1.2.1 2006/01/13 00:25:01 jeffc + * *** empty log message *** + * + * Revision 1.6 2004/07/09 22:35:39 jeffc + * *** empty log message *** + * + * Revision 1.5 2004/06/16 20:57:19 jeffc + * *** empty log message *** + * + * Revision 1.4 2003/09/26 20:48:52 jeffc + * jeffc - merge in branch setiathome-4_all_platforms_beta. + * + * Revision 1.2.2.1 2003/09/22 17:39:35 korpela + * *** empty log message *** + * + * Revision 1.3 2003/09/22 17:05:38 korpela + * *** empty log message *** + * + * Revision 1.2 2003/08/05 17:23:42 korpela + * More work on database stuff. + * Further tweaks. + * + * Revision 1.1 2003/06/03 00:23:40 korpela + * + * Again + * + * Revision 3.2 2003/05/19 17:40:59 eheien + * *** empty log message *** + * + * Revision 3.1 2001/08/16 23:42:08 korpela + * Mods for splitter to make binary workunits. + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.5 1999/10/20 19:20:26 korpela + * *** empty log message *** + * + * Revision 2.4 1999/03/05 01:47:18 korpela + * Added data_class field. + * + * Revision 2.3 1999/02/22 22:21:09 korpela + * Added nodb option + * + * Revision 2.2 1999/02/11 16:46:28 korpela + * Added startblock and norewind support, and wu_database_id. + * + * Revision 2.1 1998/11/02 16:41:21 korpela + * Minor Change. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.1 1998/10/27 01:10:32 korpela + * Initial revision + * + * + */ diff --git a/splitter_old/splittypes.h b/splitter_old/splittypes.h new file mode 100644 index 0000000..3707a64 --- /dev/null +++ b/splitter_old/splittypes.h @@ -0,0 +1,114 @@ +/* splittypes.h + * + * Type definitions specific to the splitter. + * + * + * $Id: splittypes.h,v 1.1.2.1 2006/01/13 00:25:01 jeffc Exp $ + * + */ +#ifndef SPLITTYPES_H +#define SPLITTYPES_H + +#include + +#include "splitparms.h" +#include "s_util.h" +#include "seti_header.h" + +//typedef struct wuheader { + //WU_INFO wuhead; + //SETI_WU_INFO wuinfo; +//} wuheader_t; + +typedef struct tapeheader { + char name[36]; + int rcdtype; + int numringbufs; + int numdiskbufs; + unsigned long frameseq; + unsigned long dataseq; + int missed; + TIME st; + SCOPE_STRING telstr; + int source; + double centerfreq,samplerate; + char version[16]; +} tapeheader_t; + +typedef struct buffer_pos { + int frame; + long byte; +} buffer_pos_t; + +#endif +/* + * $Log: splittypes.h,v $ + * Revision 1.1.2.1 2006/01/13 00:25:01 jeffc + * *** empty log message *** + * + * Revision 1.4 2003/08/05 17:23:43 korpela + * More work on database stuff. + * Further tweaks. + * + * Revision 1.3 2003/07/29 20:35:51 korpela + * + * renames .C files to .cpp + * + * Revision 1.2 2003/06/03 01:01:17 korpela + * + * First working splitter under CVS. + * + * Revision 1.1 2003/06/03 00:23:41 korpela + * + * Again + * + * Revision 3.1 2003/05/19 17:40:59 eheien + * *** empty log message *** + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.5 1999/02/11 16:46:28 korpela + * Added startblock and norewind support, and wu_database_id. + * + * Revision 2.4 1998/11/10 00:02:44 korpela + * Moved remaining wuheader fields into a WU_INFO structure. + * + * Revision 2.3 1998/11/05 21:18:41 korpela + * Moved name field from header to seti header. + * + * Revision 2.2 1998/11/02 21:20:58 korpela + * Moved tape_version and encoding_type into SETI_WU_INFO. + * + * Revision 2.1 1998/11/02 16:38:29 korpela + * Variable type changes. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.7 1998/10/30 21:01:13 davea + * *** empty log message *** + * + * Revision 1.6 1998/10/27 01:10:58 korpela + * Modified tapeheader_t to match new tape header fields. + * + * Revision 1.5 1998/10/19 23:04:32 korpela + * Moved times in telstr_t into an st_t. + * Changed name of ast_t to st_t. + * Added time zone (tz) field to ast_t. + * + * Revision 1.4 1998/10/15 19:13:30 korpela + * Renamed "unix" fields to "unix_time" because of GCC #define. + * Added position_history field to wuheader_t. + * + * Revision 1.3 1998/10/15 18:58:50 korpela + * Added time_t unix to ast_t and telstr_t types. + * Changed times in wuheader_t to time_t types. + * + * Revision 1.2 1998/10/15 18:01:19 korpela + * Removed month field from ast_t and telstr_t. + * + * Revision 1.1 1998/10/15 16:20:24 korpela + * Initial revision + * + */ diff --git a/splitter_old/squarewave.cpp b/splitter_old/squarewave.cpp new file mode 100644 index 0000000..8e67e9a --- /dev/null +++ b/splitter_old/squarewave.cpp @@ -0,0 +1,75 @@ +#include "config.h" +#include +#include +#include +#include +#include +#include + +#define NUM_FRAMES 200L +#define FRAME_DATA_SIZE (1024L*1024) +#define HEADER_SIZE 1024 +#define FILESIZE (NUM_FRAMES*(FRAME_DATA_SIZE+HEADER_SIZE)) + +char header[HEADER_SIZE]; + +int main(void) { + int i; + int datapos=0; + int frameseq=0; + long written=0; + int on=0; + struct tm *tm; + char data; + + char tmpstr[256]; + char telstr[256]; + double time0=(double)time(0); + time_t clock; + + for (written=0;writtentm_year,tm->tm_yday,tm->tm_hour,tm->tm_min,tm->tm_sec,(int)((time0-floor(time0))*100)); + strcpy(header+headerpos,tmpstr); + headerpos+=strlen(tmpstr)+1; + if (!((frameseq-1)%5)) { + sprintf(telstr,"TELSTR=%.2d%.3d%.2d%.2d%.2d 0.0 0.0 15.0",tm->tm_year,tm->tm_yday,tm->tm_hour,tm->tm_min+(tm->tm_sec>57),(tm->tm_sec+2)%60); + } + strcpy(header+headerpos,telstr); + headerpos+=strlen(telstr)+1; + strcpy(header+headerpos,"RECEIVER=ao1420"); + headerpos+=strlen("RECEIVER=ao1420")+1; + strcpy(header+headerpos,"SAMPLERATE=2.5000"); + headerpos+=strlen("SAMPLERATE=2.5000")+1; + strcpy(header+headerpos,"VER=1.00"); + headerpos+=strlen("VER=1.00")+1; + strcpy(header+headerpos,"CENTERFREQ=1420.0"); + headerpos+=strlen("CENTERFREQ=1420.0")+1; + strcpy(header+headerpos,"NUMRINGBUFS=4"); + headerpos+=strlen("NUMRINGBUFS=4")+1; + strcpy(header+headerpos,"NUMDISKBUFS=2"); + headerpos+=strlen("NUMDISKBUFS=2")+1; + strcpy(header+headerpos,"EOH="); + write(stdout->_file, header, HEADER_SIZE); + for(i=0;i_file, &data, 1); + } + time0+=(1024.0*1024.0*4.0/2.5e6); + } +} + diff --git a/splitter_old/tools/disksplitter b/splitter_old/tools/disksplitter new file mode 100755 index 0000000..a4bc323 --- /dev/null +++ b/splitter_old/tools/disksplitter @@ -0,0 +1,121 @@ +#! /bin/tcsh -x + +set PATH=/opt/misc:/opt/misc/bin:/usr/ccs/bin:/usr/openwin/bin:/usr/openwin/bin/xview:/usr/lang:/usr/ucb:/bin:/usr/bin:/usr/local/bin:/usr/hosts:/usr/bin/X11:/usr/casual/sparc:/usr/etc:/usr/local/lib/tex/bin:/usr/local/lib/frame/bin:/disks/asimov/a/apps/informix/bin:.:/disks/albert/d/office/bin:/usr/ucb:/disks/albert/e/users/eurd/data_analysis/bin:/usr/local/lib/g++-include.bak:/disks/siren/a/users/seti/s4/siren/bin:/disks/albert/d/orfeus:/disks/albert/d/chips:/disks/asimov/a/apps/informix/bin:/usr/local/tex +# export PATH +set LD_LIBRARY_PATH=/usr/lib/X11:/usr/openwin/lib:/usr/lib:/lib:/disks/islay/a/users/korpela/bin/lib:/disks/asimov/a/apps/informix/lib:/disks/asimov/a/apps/informix/lib/esql +# export LD_LIBRARY_PATH +set INFORMIXDIR=/disks/asimov/a/apps/informix +# export INFORMIXDIR +set INFORMIXSERVER=ejk_tcp +# export INFORMIXSERVER + +set SPLIT_PROG_LOC=/disks/milkyway/a/users/anderson/seti/splitter/bin/ +set SPLIT_PROG_NAME=splitter +set SPLIT_LOG_LOC=/disks/milkyway/a/users/anderson/seti/sethi/hi_tape_logs/ +# set HI_TAPE_DIR=/disks/philmor/a/users/eheien/hitest/ +set SPLIT_TAPE_DIR=/disks/setifiler1/wutape/tapedir/ +set SPLIT_SUFFIX=.split +set HIDONE_SUFFIX=.hidone +set SPLITDONE_SUFFIX=.splitdone +set EMAIL_LIST="jeffc@ssl.berkeley.edu mattl@ssl.berkeley.edu" +set FOUND_FILE=0 +set HOST=`hostname` +set SPLIT_HALT_MSG=splitter_stop + +# Check to see if this machine is already running the splitter program +set PROG_RUNNING=`/usr/ucb/ps -auxww | grep "$SPLIT_PROG_NAME" | grep -v "disksplitter" | wc | awk '{print $1}'` +echo "$PROG_RUNNING" +if( $PROG_RUNNING > 1 ) then + echo "Splitter is already running on this machine. Quitting." + exit +endif + +# Get rid of all .split files here with HOSTNAME in them(?) + +while ( ! -f $SPLIT_TAPE_DIR$SPLIT_HALT_MSG ) + +set FOUND_FILE=0 +cd $SPLIT_TAPE_DIR + +set FILE_LIST=`ls . | grep ".tape" | grep -v "done" | grep -v "reading" | grep -v "hi" | grep -v "msg" | grep -v "split"` + +if( -z "$FILE_LIST" ) then + exit +endif + +foreach file ($FILE_LIST) + if ( $FOUND_FILE == 0 && ! -f $file$SPLITDONE_SUFFIX ) then + if( -f $file$SPLIT_SUFFIX ) then + set FOUND_FILE=0 + else + echo $HOST > $file$SPLIT_SUFFIX + set TAPE_FILE=$file + set SPLIT_FILE=$SPLIT_TAPE_DIR$file + set SPLIT_MARK_FILE=$SPLIT_TAPE_DIR$file$SPLIT_SUFFIX + set HI_DONE_FILE=$SPLIT_TAPE_DIR$file$HIDONE_SUFFIX + set SPLIT_DONE_FILE=$SPLIT_TAPE_DIR$file$SPLITDONE_SUFFIX + set FOUND_FILE=1 + endif + endif +end + +cd /mydisks/a/servers/splitter/ +/bin/rm -f error.log rcd.chk +touch error.log +touch rcd.chk + +if ( $FOUND_FILE == 0 ) then +# echo "" | /usr/ucb/mail -s"no more splitter tape files" $EMAIL_LIST + exit +else + if( -f /disks/milkyway/a/users/anderson/seti/watchdogs/go_spliiter ) then + /bin/rm -f wu_inbox/.* +#set START_MSG=`echo "Splitter is starting on tape" $SPLIT_FILE "on" $HOST` + cat error.log rcd.chk | /usr/ucb/mail -s""$HOST" splitter starting" $EMAIL_LIST + /bin/nice $SPLIT_PROG_LOC$SPLIT_PROG_NAME $SPLIT_FILE $1 -resume >>& splitterlog + set TEMP=`grep -i "end" error.log` + if( "$TEMP" != "" ) then + sleep 60 # wait for it to finish moving the files from wu_inbox + cat error.log rcd.chk | /usr/ucb/mail -s""$HOST" splitter finished" $EMAIL_LIST + /bin/rm -f error.log rcd.chk + /bin/rm -f wu_inbox/.* + /bin/rm -f $SPLIT_MARK_FILE + if( -f $HI_DONE_FILE ) then + /bin/rm -f $HI_DONE_FILE + /bin/rm -f `cd $SPLIT_TAPE_DIR; ls -l | grep $TAPE_FILE | awk '{print $NF}'` + /bin/rm -f $SPLIT_FILE + else + touch -f $SPLIT_DONE_FILE + endif + endif + /bin/rm -f $SPLIT_MARK_FILE + exit + else + /bin/rm -f $SPLIT_MARK_FILE + exit + endif +endif + +#if ( 0 == 1 ) then +# if ( grep -i done hi_log ) then +# cat error.log rcd.chk | /usr/ucb/mail -s"end of tape on $HOST" $EMAIL_LIST +# touch $HI_FILE$HIDONE_SUFFIX +# if ( -f $HI_FILE$HIDONE_SUFFIX ) then +# unlink $SPLITFILE +# fi +# unlink .$SPLITFILE +# /bin/rm error.log rcd.chk +# /bin/rm wu_inbox/.* +# nice -10 $SPLITTER_PROG_LOC $SPLITFILE -resume 2>> splitterlog & +#else +# if [ -f $MARKER$HOST ] +# then +# /bin/rm wu_inbox/.* +# cat error.log rcd.chk | /usr/ucb/mail -s"restarting HI analysis on $HOST" $EMAIL_LIST +# nice -10 $SPLITTER_PROG_LOC $SPLITFILE -resume 2>> splitterlog & +# else +# cat error.log rcd.chk | /usr/ucb/mail -s"hi analysis disabled on $HOST" $EMAIL_LIST +# fi +#endif +end + diff --git a/splitter_old/tools/sah_splitter.sh b/splitter_old/tools/sah_splitter.sh new file mode 100755 index 0000000..2ff1d34 --- /dev/null +++ b/splitter_old/tools/sah_splitter.sh @@ -0,0 +1,150 @@ +#! /bin/sh +PATH=/opt/misc:/opt/misc/bin:/usr/ccs/bin:/usr/openwin/bin:/usr/openwin/bin/xview:/usr/lang:/usr/ucb:/bin:/usr/bin:/usr/local/bin:/usr/hosts:/usr/bin/X11:/usr/casual/sparc:/usr/etc:/usr/local/lib/tex/bin:/usr/local/lib/frame/bin:/disks/asimov/a/apps/informix/bin:.:/disks/albert/d/office/bin:/usr/ucb:/disks/albert/e/users/eurd/data_analysis/bin:/usr/local/lib/g++-include.bak:/disks/siren/a/users/seti/s4/siren/bin:/disks/albert/d/orfeus:/disks/albert/d/chips:/disks/asimov/a/apps/informix/bin:/usr/local/tex +export PATH +LD_LIBRARY_PATH=/lib:/disks/asimov/a/apps/informix/lib:/disks/asimov/a/apps/informix/lib/esql::/usr/ucblib:/lib:/usr/lib:/usr/openwin/lib:/usr/ccs/lib:/usr/local/gcc/lib:/disks/asimov/a/lang/gnu/H-sparc-sun-solaris2/lib:/opt/misc/lib:/usr/local/lib:/disks/ellie/a/users/korpela/lib:/usr/dt/lib +export LD_LIBRARY_PATH +INFORMIXDIR=/disks/asimov/a/apps/informix/ +export INFORMIXDIR +INFORMIXSERVER=ejk_tcp +export INFORMIXSERVER +S4_RECEIVER_CONFIG=/usr/local/warez/projects/s4/siren/db/ReceiverConfig.tab +export S4_RECEIVER_CONFIG + +PROJECTDIR=/disks/koloth/a/inet_services/boinc_www/share/projects/sah +SPLIT_PROG_LOC=${PROJECTDIR}/bin/ +SPLIT_PROG_NAME=sah_splitter +SPLIT_TAPE_DIR=/disks/setifiler1/wutape/tapedir/seti_boinc_public/ +SPLIT_SUFFIX=.split +#HIDONE_SUFFIX=.hidone +SPLITDONE_SUFFIX=.splitdone +EMAIL_LIST="korpela@ssl.berkeley.edu jeffc@ssl.berkeley.edu mattl@ssl.berkeley.edu davea@ssl.berkeley.edu" +FOUND_FILE=0 +HOST=`hostname` +SPLIT_HALT_MSG=splitter_stop + +# Check to see if this machine is already running the splitter program +PROG_RUNNING=`/usr/ucb/ps -auxww | grep "$SPLIT_PROG_NAME " | grep -v grep` +if [ ! -z "$PROG_RUNNING" ] +then + echo "Splitter is already running on this machine. Quitting." + exit 1 +fi + +# Get rid of all .split files here with HOSTNAME in them(?) + +TAPE_FILE= + +# get list of all tapes in the sah classic tape directory +cd $SPLIT_TAPE_DIR/.. +FILE_LIST=`ls *.tape` + +cd $SPLIT_TAPE_DIR + +# if no sah classic tapes then bail +if [ -z "$FILE_LIST" ] +then + exit 2 +fi + +# for each sah classic tape... +for file in $FILE_LIST +do + # if we have already split it... + if [ -f $file$SPLITDONE_SUFFIX ] + then + # ... then remove it ("it" being a hard link upward into the sah classic dir) + if [ -f $file ] + then + /bin/rm $file + fi + else + # if we are in the process of splitting it... + if [ -f $file$SPLIT_SUFFIX ] + then + # and are splitting it from this host... (this logic prevents one host from repeating another host's tape) + if grep $HOST $file$SPLIT_SUFFIX + then + # trigger to restart the split + /bin/rm $file$SPLIT_SUFFIX + fi + fi + # if a restart or a brand new tape... + if [ ! -f $file$SPLIT_SUFFIX ] + then + # claim it for this host (there is certainly a race condition here) + echo $HOST > $file$SPLIT_SUFFIX + ln ../$file + TAPE_FILE=$file + SPLIT_FILE=$SPLIT_TAPE_DIR$file + SPLIT_MARK_FILE=$SPLIT_TAPE_DIR$file$SPLIT_SUFFIX +# HI_DONE_FILE=$SPLIT_TAPE_DIR$file$HIDONE_SUFFIX + SPLIT_DONE_FILE=$SPLIT_TAPE_DIR$file$SPLITDONE_SUFFIX + break + fi + fi +done + +cd /tmp/splitter/sah +if [ ! -d splitter ] +then + mkdir splitter +fi +cd splitter +if [ ! -d wu_inbox ] +then + mkdir wu_inbox +fi +/bin/rm -f error.log rcd.chk +touch error.log +touch rcd.chk + +if [ -z "$TAPE_FILE" ] +then + exit 3 +else + /bin/rm -f wu_inbox/.* + cat error.log rcd.chk | /usr/ucb/mail -s""$HOST" boinc_splitter starting" $EMAIL_LIST + /bin/nice $SPLIT_PROG_LOC$SPLIT_PROG_NAME $SPLIT_FILE $* -resume -projectdir=$PROJECTDIR + if grep -i "end" error.log >/dev/null 2>&1 + then + /bin/nice $SPLIT_PROG_LOC$SPLIT_PROG_NAME $SPLIT_FILE $* -resume -projectdir=$PROJECTDIR + fi + if grep -i "end" error.log >/dev/null 2>&1 + then + cat error.log rcd.chk | /usr/ucb/mail -s""$HOST" boinc_splitter finished" $EMAIL_LIST + /bin/rm -f error.log rcd.chk + /bin/rm -f wu_inbox/.* + /bin/rm -f $SPLIT_MARK_FILE + /bin/rm -f `cd $SPLIT_TAPE_DIR; ls -l | grep $TAPE_FILE | awk '{print $NF}'` + /bin/rm -f $SPLIT_FILE + touch -f $SPLIT_DONE_FILE + exit + else + /bin/rm -f $SPLIT_MARK_FILE + exit 4 + fi +fi + +#if ( 0 == 1 ) then +# if ( grep -i done hi_log ) then +# cat error.log rcd.chk | /usr/ucb/mail -s"end of tape on $HOST" $EMAIL_LIST +# touch $HI_FILE$HIDONE_SUFFIX +# if ( -f $HI_FILE$HIDONE_SUFFIX ) then +# unlink $SPLITFILE +# fi +# unlink .$SPLITFILE +# /bin/rm error.log rcd.chk +# /bin/rm wu_inbox/.* +# nice -10 $SPLITTER_PROG_LOC $SPLITFILE -resume 2>> splitterlog & +#else +# if [ -f $MARKER$HOST ] +# then +# /bin/rm wu_inbox/.* +# cat error.log rcd.chk | /usr/ucb/mail -s"restarting HI analysis on $HOST" $EMAIL_LIST +# nice -10 $SPLITTER_PROG_LOC $SPLITFILE -resume 2>> splitterlog & +# else +# cat error.log rcd.chk | /usr/ucb/mail -s"hi analysis disabled on $HOST" $EMAIL_LIST +# fi +#endif +end + diff --git a/splitter_old/uttolst.h b/splitter_old/uttolst.h new file mode 100644 index 0000000..8f29efb --- /dev/null +++ b/splitter_old/uttolst.h @@ -0,0 +1,2 @@ +double tm_UtToLst(double ddtime, double longitude, + long mon, long day, long year); diff --git a/splitter_old/validrun.cpp b/splitter_old/validrun.cpp new file mode 100644 index 0000000..a5eef50 --- /dev/null +++ b/splitter_old/validrun.cpp @@ -0,0 +1,165 @@ +/* + * validrun.c + * + * Functions for determining if a section of the tape buffer can be + * turned into a valid work unit + * + * $Id: validrun.cpp,v 1.1.2.1 2006/01/13 00:25:03 jeffc Exp $ + * + */ + +#include "config.h" +#include +#include +#include +#include +#include "splitparms.h" +#include "splittypes.h" +#include "splitter.h" +#include "message.h" + + +int valid_run(tapeheader_t tapeheader[],buffer_pos_t *start_of_wu, + buffer_pos_t *end_of_wu) { + + int i=0,valid=1; + SCOPE_STRING *first_telstr; + double first_telstr_time=0; + double first_jd=tapeheader[0].st.jd; + char tmpstr[256]; + + /* find the first telstr that refers to valid data */ + + do { + first_telstr=&(tapeheader[++i].telstr); + first_telstr_time=first_telstr->st.jd; + } while ((first_telstr_time<=first_jd) && (iframe=1+WU_OVERLAP_FRAMES; + end_of_wu->byte=0; + return(0); + } + + /* find the correct byte offset for the start of the work unit */ + + start_of_wu->frame=i; + start_of_wu->byte=(long)((tapeheader[i].telstr.st.jd-tapeheader[i].st.jd)*86400.0*tapeheader[i].samplerate*2/CHAR_BIT); + start_of_wu->byte &= 0xfffffffe; + + + while (start_of_wu->byte<0) { + start_of_wu->frame--; + start_of_wu->byte+=TAPE_DATA_SIZE; + } + + while (start_of_wu->byte>TAPE_DATA_SIZE) { + start_of_wu->frame++; + start_of_wu->byte-=TAPE_DATA_SIZE; + } + + if (start_of_wu->frame<0) { + sprintf(tmpstr,"Missing telescope strings near %lu\n", + tapeheader[0].frameseq); + message(tmpstr); + end_of_wu->frame=0; + end_of_wu->byte=0; + records_in_buffer=0; + return(0); + } + + if ((start_of_wu->frame+TAPE_FRAMES_PER_WU)>TAPE_FRAMES_IN_BUFFER) { + sprintf(tmpstr,"Missing telescope strings near %lu\n", + tapeheader[0].frameseq); + message(tmpstr); + end_of_wu->frame=0; + end_of_wu->byte=0; + records_in_buffer=0; + return(0); + } + + /* check for missed frames */ + for (i=0; iframe+i; + if (tapeheader[j].missed) { + sprintf(tmpstr,"Missing frames between %lu and %lu\n", + tapeheader[j-1].frameseq,tapeheader[j].frameseq); + message(tmpstr); + valid=0; + end_of_wu->frame=j+WU_OVERLAP_FRAMES+1; + end_of_wu->byte=0; + assert((j+WU_OVERLAP_FRAMES)<=TAPE_FRAMES_IN_BUFFER); + } + } + + if (!valid) { + end_of_wu->frame=0; + records_in_buffer=0; + return(valid); + } + + end_of_wu->frame=start_of_wu->frame+TAPE_FRAMES_PER_WU; + end_of_wu->byte=start_of_wu->byte; + + return(valid); +} + + +/* + * $Log: validrun.cpp,v $ + * Revision 1.1.2.1 2006/01/13 00:25:03 jeffc + * *** empty log message *** + * + * Revision 1.2 2003/09/11 18:53:38 korpela + * *** empty log message *** + * + * Revision 1.1 2003/07/29 20:35:57 korpela + * + * renames .C files to .cpp + * + * Revision 1.1 2003/06/03 00:23:43 korpela + * + * Again + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.7 2000/12/01 01:13:29 korpela + * *** empty log message *** + * + * Revision 2.6 1999/06/07 21:00:52 korpela + * *** empty log message *** + * + * Revision 2.5 1999/03/27 16:19:35 korpela + * *** empty log message *** + * + * Revision 2.4 1999/02/22 22:21:09 korpela + * added -nodb option + * + * Revision 2.3 1999/02/11 16:46:28 korpela + * Added checkpointing. + * + * Revision 2.2 1998/11/04 23:08:25 korpela + * Byte and bit order change. + * + * Revision 2.1 1998/11/02 16:41:21 korpela + * Minor Change. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.3 1998/10/30 20:26:03 korpela + * Bug Fixes. Now mostly working. + * + * Revision 1.2 1998/10/27 00:59:22 korpela + * Bug fixes. + * + * Revision 1.1 1998/10/22 17:48:20 korpela + * Initial revision + * + * + */ diff --git a/splitter_old/validrun.h b/splitter_old/validrun.h new file mode 100644 index 0000000..e2fe4a8 --- /dev/null +++ b/splitter_old/validrun.h @@ -0,0 +1,36 @@ +/* + * validrun.h + * + * Functions for determining if a section of the tape buffer can be + * turned into a valid work unit + * + * $Id: validrun.h,v 1.1.2.1 2006/01/13 00:25:04 jeffc Exp $ + * + */ + +int valid_run(tapeheader_t tapeheader[],buffer_pos_t *start_of_wu, + buffer_pos_t *end_of_wu); + +/* + * $Log: validrun.h,v $ + * Revision 1.1.2.1 2006/01/13 00:25:04 jeffc + * *** empty log message *** + * + * Revision 1.1 2003/06/03 00:23:43 korpela + * + * Again + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.1 1998/11/02 16:41:21 korpela + * Minor Change. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.1 1998/10/22 17:49:15 korpela + * Initial revision + * + * + */ diff --git a/splitter_old/writeheader.cpp b/splitter_old/writeheader.cpp new file mode 100644 index 0000000..d8d3aff --- /dev/null +++ b/splitter_old/writeheader.cpp @@ -0,0 +1,105 @@ +/* + * Functions for writing tape and work unit headers + * + * $Id: writeheader.cpp,v 1.1.2.1 2006/01/13 00:25:04 jeffc Exp $ + * + */ + +#include "config.h" +#include +#include +#include +#include + +#include "splitparms.h" +#include "splittypes.h" +#include "timecvt.h" +#include "seti_header.h" + +extern int output_xml; + +/* Write a tape header into a buffer */ +int write_tape_header(char *buffer, tapeheader_t *header) { +/* Unimplemented as yet */ +return(0); +} + +char *monthnames[]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep" + "Oct","Nov","Dec"}; +char *daynames[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"}; + +/* Write a work unit header into a FILE */ +/*int splitter_write_wu_header(FILE *file, wuheader_t *header) { + if (!output_xml) + write_wu_header(file, header->wuhead); + return (seti_write_wu_header(file,header->wuinfo,output_xml)); + +} +*/ + +/* + * $Log: writeheader.cpp,v $ + * Revision 1.1.2.1 2006/01/13 00:25:04 jeffc + * *** empty log message *** + * + * Revision 1.3 2003/09/11 18:53:38 korpela + * *** empty log message *** + * + * Revision 1.2 2003/08/05 17:23:44 korpela + * More work on database stuff. + * Further tweaks. + * + * Revision 1.1 2003/07/29 20:35:59 korpela + * + * renames .C files to .cpp + * + * Revision 1.2 2003/06/03 01:01:18 korpela + * + * First working splitter under CVS. + * + * Revision 1.1 2003/06/03 00:23:43 korpela + * + * Again + * + * Revision 3.1 2003/05/19 17:40:59 eheien + * *** empty log message *** + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.6 1999/01/04 22:27:55 korpela + * Updated return codes. + * + * Revision 2.5 1998/11/10 00:02:44 korpela + * Moved remaining wuheader fields into a WU_INFO structure. + * + * Revision 2.4 1998/11/09 23:26:27 korpela + * Added generic version= to default header. + * + * Revision 2.3 1998/11/05 21:18:41 korpela + * Moved name field from header to seti header. + * + * Revision 2.2 1998/11/02 18:42:03 korpela + * Changed write_wu_header to call seti_write_wu_header + * + * Revision 2.1 1998/11/02 16:38:29 korpela + * Will be transfered to client. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.4 1998/10/30 20:26:03 korpela + * Bug Fixes. Now mostly working. + * + * Revision 1.3 1998/10/27 00:59:43 korpela + * Bug fixes. + * / + * + * Revision 1.2 1998/10/20 16:32:03 korpela + * Fixed syntax error. + * + * Revision 1.1 1998/10/20 16:27:41 korpela + * Initial revision + * + * + */ diff --git a/splitter_old/writeheader.h b/splitter_old/writeheader.h new file mode 100644 index 0000000..b48cf23 --- /dev/null +++ b/splitter_old/writeheader.h @@ -0,0 +1,42 @@ +/* + * Functions for writing tape and work unit headers + * + * $Id: writeheader.h,v 1.1.2.1 2006/01/13 00:25:05 jeffc Exp $ + * + */ + +/* Write a tape header into a buffer */ +int write_tape_header(char *buffer, tapeheader_t *header); + +/* Write a work unit header into a FILE */ +// int splitter_write_wu_header(FILE *file, wuheader_t *header); + +/* + * $Log: writeheader.h,v $ + * Revision 1.1.2.1 2006/01/13 00:25:05 jeffc + * *** empty log message *** + * + * Revision 1.2 2003/08/05 17:23:44 korpela + * More work on database stuff. + * Further tweaks. + * + * Revision 1.1 2003/06/03 00:23:44 korpela + * + * Again + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.2 1999/01/04 22:27:55 korpela + * Updated return codes. + * + * Revision 2.1 1998/11/02 16:41:21 korpela + * Minor Change. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.1 1998/10/15 17:20:01 korpela + * Initial revision + * + */ diff --git a/splitter_old/wufiles.cpp b/splitter_old/wufiles.cpp new file mode 100644 index 0000000..0d3e0be --- /dev/null +++ b/splitter_old/wufiles.cpp @@ -0,0 +1,530 @@ +/* + * + * Functions for managing wufiles and their data + * + * $Id: wufiles.cpp,v 1.1.2.1 2006/01/13 00:25:06 jeffc Exp $ + * + */ + +#include "config.h" +#undef USE_MYSQL +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "boinc_db.h" +#include "sched_util.h" +#include "splitparms.h" +#include "splittypes.h" +#include "timecvt.h" +#include "s_util.h" +#include "util.h" +#include "splitter.h" +#include "writeheader.h" +#include "message.h" +#include "encode.h" +#include "dotransform.h" +#include "angdist.h" +#include "readtape.h" +#include "sqlrow.h" +#include "sqlblob.h" +#include "sqlapi.h" +#include "db_table.h" +#include "schema_master.h" +#include "s4tel.h" +#include "s4cfg.h" +#include "xml_util.h" +#include "db/app_config.h" + +int wu_database_id[NSTRIPS]; +static std::vector bin_data[NSTRIPS]; + +extern APP_CONFIG sah_config; + +int make_wu_headers(tapeheader_t tapeheader[],workunit wuheader[], + buffer_pos_t *start_of_wu) { + int procid=getpid(); + int i,j,startframe=start_of_wu->frame; + double receiver_freq; + int bandno; + SCOPE_STRING *lastpos; + FILE *tmpfile; + char tmpstr[256]; + static int HaveConfigTable=0; + static ReceiverConfig_t ReceiverConfig; + static receiver_config r; + static settings s; + + if(!HaveConfigTable) { + char buf[64]; + sprintf(buf,"where s4_id=%d",gregorian?AOGREG_1420:AO_1420); + r.fetch(std::string(buf)); + ReceiverConfig.ReceiverID=r.s4_id; + strlcpy(ReceiverConfig.ReceiverName,r.name, + sizeof(ReceiverConfig.ReceiverName)); + ReceiverConfig.Latitude=r.latitude; + ReceiverConfig.Longitude=r.longitude; + ReceiverConfig.WLongitude=-r.longitude; + ReceiverConfig.Elevation=r.elevation; + ReceiverConfig.Diameter=r.diameter; + ReceiverConfig.BeamWidth=r.beam_width; + ReceiverConfig.CenterFreq=r.center_freq; + ReceiverConfig.AzOrientation=r.az_orientation; + for (i=0;i<(sizeof(ReceiverConfig.ZenCorrCoeff)/sizeof(ReceiverConfig.ZenCorrCoeff[0]));i++) { + ReceiverConfig.ZenCorrCoeff[i]=r.zen_corr_coeff[i]; + ReceiverConfig.AzCorrCoeff[i]=r.az_corr_coeff[i]; + } + HaveConfigTable=1; + s.fetch(std::string("where (active=1);")); // 1 is the boinc app.id + s.recorder_cfg->fetch(); + s.splitter_cfg->fetch(); + s.analysis_cfg->fetch(); + if (!strncmp(s.splitter_cfg->data_type,"encoded", + std::min(static_cast(7),sizeof(s.splitter_cfg->data_type)))) { + noencode=0; + } else { + noencode=1; + } + } + + workunit_grp wugrp; + // wugrp.name = tape_name.___.___.settings_id + sprintf(wugrp.name,"%s.%ld.%d.%ld.%d",tapeheader[startframe].name, + procid, + (current_record-TAPE_RECORDS_IN_BUFFER)*8+startframe, + start_of_wu->byte,s.id); + wugrp.receiver_cfg=r; + wugrp.recorder_cfg=s.recorder_cfg; + wugrp.splitter_cfg=s.splitter_cfg; + wugrp.analysis_cfg=s.analysis_cfg; + + wugrp.data_desc.start_ra=tapeheader[startframe+1].telstr.ra; + wugrp.data_desc.start_dec=tapeheader[startframe+1].telstr.dec; + wugrp.data_desc.end_ra=tapeheader[startframe+TAPE_FRAMES_PER_WU].telstr.ra; + wugrp.data_desc.end_dec=tapeheader[startframe+TAPE_FRAMES_PER_WU].telstr.dec; + wugrp.data_desc.nsamples=NSAMPLES; + wugrp.data_desc.true_angle_range=0; + { + double sample_rate=tapeheader[startframe].samplerate/NSTRIPS; + /* startframe+1 contains the first valid RA and Dec */ + TIME st=tapeheader[startframe+1].telstr.st; + TIME et=tapeheader[startframe+TAPE_FRAMES_PER_WU].telstr.st; + double diff=(et-st).jd*86400.0; + for (j=2;jst.jd) > (1.0/86400.0)) + { + lastpos=&(tapeheader[startframe+j].telstr); + tmpcoord.time=tapeheader[startframe+j].telstr.st.jd; + tmpcoord.ra=tapeheader[startframe+j].telstr.ra; + tmpcoord.dec=tapeheader[startframe+j].telstr.dec; + wugrp.data_desc.coords.push_back(tmpcoord); + } + } + + wugrp.tape_info->id=0; + wugrp.tape_info->fetch(std::string("where name=\'")+tapeheader[startframe].name+"\'"); + wugrp.tape_info->start_time=tapeheader[startframe].st.jd; + wugrp.tape_info->last_block_time=tapeheader[startframe].st.jd; + wugrp.tape_info->last_block_done=tapeheader[startframe].frameseq; + + if (!nodb) { + if (wugrp.tape_info.id) { + if (!(wugrp.tape_info->update())) printf("%s",sql_error_message()); + } else { + strlcpy(wugrp.tape_info->name,tapeheader[startframe].name,sizeof(wugrp.tape_info->name)); + wugrp.tape_info->insert(); + } + } + + if (!nodb) wugrp.insert(); + + for (i=0;ibyte,s.id,i); + wuheader[i].subband_desc.sample_rate=tapeheader[startframe].samplerate/NSTRIPS; + + receiver_freq=tapeheader[startframe].centerfreq; + + bandno=((i+NSTRIPS/2)%NSTRIPS)-NSTRIPS/2; + + wuheader[i].subband_desc.base=receiver_freq+ + (double)(bandno)*wuheader[i].subband_desc.sample_rate; + wuheader[i].subband_desc.center=receiver_freq+wuheader[i].subband_desc.sample_rate*NSTRIPS*((double)IFFT_LEN*bandno/FFT_LEN+(double)IFFT_LEN/(2*FFT_LEN)-1.0/(2*FFT_LEN)); + wuheader[i].subband_desc.number=i; + + if (!nodb ) { + if (!(wu_database_id[i]=wuheader[i].insert())) { + message("Database error in make_wu_headers()\n"); + exit(EXIT_FAILURE); + } + } + + sprintf(tmpstr,"./wu_inbox/%s",wuheader[i].name); + if ((tmpfile=fopen(tmpstr,"w"))) { + fprintf(tmpfile,"\n"); + fprintf(tmpfile,wuheader[i].print_xml().c_str()); + fclose(tmpfile); + } else { + sprintf(tmpstr,"Unable to open file ./wu_inbox/%s, errno=%d\n",wuheader[i].name,errno); + message(tmpstr); + exit(1); + } + bin_data[i].reserve(wuheaders[i].group_info->recorder_cfg->bits_per_sample* + wuheaders[i].group_info->data_desc.nsamples/8); + } + return(1); +} + + +void write_wufile_blocks(int nbytes) { + static bool first_call=true; + int i,j; + + + for (i=0;i0); + fclose(oldfile); + fclose(newfile); + return 0; + } else { + return 1; + } +} + + + +void rename_wu_files() { + int i, retval; + char oldname[256],newname[1024]; + unsigned long sz; + DB_WORKUNIT db_wu; + const char *name[1]; + char *wudir="./wu_inbox"; + xml_encoding encoding=(noencode?_binary:_x_setiathome); + FILE *tmpfile; + + if (boinc_db.open(boinc_config.db_name,boinc_config.db_host,boinc_config.db_user,boinc_config.db_passwd)) { + boinc_db.print_error("boinc_db.open"); + fprintf(errorlog,"boinc_db.open\n"); + exit(1); + } + + for (i=0;i",tmpstr.size(), + xml_encoding_names[encoding]); + fwrite(tmpstr.c_str(),tmpstr.size(),1,tmpfile); + fprintf(tmpfile,"\n"); + fprintf(tmpfile,"\n"); + sz=bin_data[i].size(); + + fclose(tmpfile); + } + if (!filecopy(oldname,newname)) { + db_wu.clear(); + db_wu.opaque=wuheaders[i].id; + strncpy(db_wu.name,name[0],sizeof(db_wu.name)-2); + db_wu.appid=app.id; + //db_wu.rsc_fpops_est=2.79248e+13*6; + //db_wu.rsc_fpops_bound=4.46797e+14*6; + db_wu.rsc_fpops_est=2.79248e+13; + db_wu.rsc_fpops_bound=4.46797e+14; + db_wu.rsc_memory_bound=67108864; + db_wu.rsc_disk_bound=500000; + db_wu.delay_bound=14*86400; + db_wu.min_quorum=sah_config.min_quorum; + db_wu.target_nresults=sah_config.target_nresults; + db_wu.max_error_results=sah_config.max_error_results; + db_wu.max_total_results=sah_config.max_total_results; + db_wu.max_success_results=sah_config.max_success_results; + strncpy(db_wu.app_name,SAH_APP_NAME,sizeof(db_wu.app_name)-2); + if (create_work(db_wu, + wu_template, + result_template_filename, + result_template_filepath, + name, + 1, + boinc_config + ) + ) { + fprintf(stderr,"create work failed\n"); + exit(1); + } + //unlink(oldname); // we now *always* unlink + } else { + fprintf(stderr,"file copy failed\n"); + exit(1); + } + unlink(oldname); + } + boinc_db.close(); +} + +/* + * $Log: wufiles.cpp,v $ + * Revision 1.1.2.1 2006/01/13 00:25:06 jeffc + * *** empty log message *** + * + * Revision 1.30 2006/01/10 00:06:07 jeffc + * *** empty log message *** + * + * Revision 1.29 2005/03/08 22:36:15 jeffc + * jeffc - fixed call to create_work() + * + * Revision 1.28 2005/02/15 23:06:47 korpela + * Fixed missing dir_hier symbol. + * + * Revision 1.27 2004/12/27 20:48:54 jeffc + * *** empty log message *** + * + * Revision 1.26 2004/11/18 22:24:48 korpela + * *** empty log message *** + * + * Revision 1.25 2004/08/25 22:42:11 jeffc + * *** empty log message *** + * + * Revision 1.24 2004/08/14 04:44:26 jeffc + * *** empty log message *** + * + * Revision 1.23 2004/08/12 15:45:41 jeffc + * *** empty log message *** + * + * Revision 1.22 2004/07/15 17:54:20 jeffc + * *** empty log message *** + * + * Revision 1.21 2004/07/09 22:35:39 jeffc + * *** empty log message *** + * + * Revision 1.20 2004/07/01 17:56:51 korpela + * *** empty log message *** + * + * Revision 1.19 2004/06/25 13:49:33 jeffc + * *** empty log message *** + * + * Revision 1.18 2004/06/18 23:23:32 jeffc + * *** empty log message *** + * + * Revision 1.17 2004/06/16 20:57:19 jeffc + * *** empty log message *** + * + * Revision 1.16 2004/06/02 20:51:32 jeffc + * *** empty log message *** + * + * Revision 1.15 2004/01/22 00:57:54 korpela + * *** empty log message *** + * + * Revision 1.14 2004/01/20 22:33:44 korpela + * *** empty log message *** + * + * Revision 1.13 2004/01/06 22:44:05 korpela + * *** empty log message *** + * + * Revision 1.12 2004/01/01 18:42:01 korpela + * *** empty log message *** + * + * Revision 1.11 2003/12/12 01:51:39 korpela + * Now using the opaque field in workunit to store SAH wuid. + * + * Revision 1.10 2003/12/03 23:46:41 korpela + * WU count is now only for SAH workunits. + * + * Revision 1.9 2003/11/25 21:59:53 korpela + * *** empty log message *** + * + * Revision 1.8 2003/11/11 06:20:30 korpela + * Increased max fpops_max to prevent timeout on windows clients + * + * Revision 1.7 2003/10/25 18:19:44 korpela + * *** empty log message *** + * + * Revision 1.6 2003/10/24 16:57:03 korpela + * *** empty log message *** + * + * Revision 1.5 2003/09/26 20:48:52 jeffc + * jeffc - merge in branch setiathome-4_all_platforms_beta. + * + * Revision 1.3.2.2 2003/09/22 19:00:31 korpela + * *** empty log message *** + * + * Revision 1.3.2.1 2003/09/22 17:39:35 korpela + * *** empty log message *** + * + * Revision 1.4 2003/09/22 17:05:38 korpela + * *** empty log message *** + * + * Revision 1.3 2003/09/11 18:53:38 korpela + * *** empty log message *** + * + * Revision 1.2 2003/08/05 17:23:44 korpela + * More work on database stuff. + * Further tweaks. + * + * Revision 1.1 2003/07/29 20:36:00 korpela + * + * renames .C files to .cpp + * + * Revision 1.3 2003/06/05 15:52:47 korpela + * + * Fixed coordinate bug that was using the wrong zenith angle from the telescope + * strings when handling units from the gregorian. + * + * Revision 1.2 2003/06/03 01:01:18 korpela + * + * First working splitter under CVS. + * + * Revision 1.1 2003/06/03 00:23:44 korpela + * + * Again + * + * Revision 3.8 2003/05/19 17:40:59 eheien + * *** empty log message *** + * + * Revision 3.7 2003/04/10 17:32:25 korpela + * *** empty log message *** + * + * Revision 3.6 2002/06/21 01:42:15 eheien + * *** empty log message *** + * + * Revision 3.5 2001/11/07 00:51:47 korpela + * Added splitter version to database. + * Added max_wus_ondisk option. + * + * Revision 3.4 2001/08/17 22:20:54 korpela + * *** empty log message *** + * + * Revision 3.3 2001/08/17 01:22:31 korpela + * *** empty log message *** + * + * Revision 3.2 2001/08/17 01:16:53 korpela + * *** empty log message *** + * + * Revision 3.1 2001/08/16 23:42:08 korpela + * Mods for splitter to make binary workunits. + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.18 2000/12/01 01:13:29 korpela + * *** empty log message *** + * + * Revision 2.17 1999/06/07 21:00:52 korpela + * *** empty log message *** + * + * Revision 2.16 1999/03/27 16:19:35 korpela + * *** empty log message *** + * + * Revision 2.15 1999/03/05 01:47:18 korpela + * Added data_class field. + * + * Revision 2.14 1999/02/22 22:21:09 korpela + * added -nodb option + * + * Revision 2.13 1999/02/11 16:46:28 korpela + * Added db access functions. + * + * Revision 2.12 1999/01/04 22:27:55 korpela + * Updated return codes. + * + * Revision 2.11 1998/12/14 23:41:44 korpela + * Added subband_base to work unit header. + * Changed frequency calculation. + * + * Revision 2.10 1998/12/14 21:55:07 korpela + * Added fft_len and ifft_len to work unit header. + * + * Revision 2.9 1998/11/13 23:58:52 korpela + * Modified for move of name field between structures. + * + * Revision 2.8 1998/11/13 22:18:12 davea + * *** empty log message *** + * + * Revision 2.7 1998/11/10 01:55:26 korpela + * Server requires a CR at the end of a WU file + * ??? + * + * Revision 2.6 1998/11/10 00:02:44 korpela + * Moved remaining wuheader fields into a WU_INFO structure. + * + * Revision 2.5 1998/11/05 21:33:02 korpela + * Fixed angle_range bug. + * + * Revision 2.4 1998/11/05 21:18:41 korpela + * Moved name field from header to seti header. + * + * Revision 2.3 1998/11/02 21:20:58 korpela + * Modified for (internal) integer receiver ID. + * + * Revision 2.2 1998/11/02 18:45:39 korpela + * Changed location of timecvt.h + * + * Revision 2.1 1998/11/02 16:38:29 korpela + * Variable type changes. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.2 1998/10/30 20:26:03 korpela + * Bug Fixes. Now mostly working. + * + * Revision 1.1 1998/10/27 01:01:16 korpela + * Initial revision + * + * + */ diff --git a/splitter_old/wufiles.h b/splitter_old/wufiles.h new file mode 100644 index 0000000..cdd09e4 --- /dev/null +++ b/splitter_old/wufiles.h @@ -0,0 +1,42 @@ +/* + * + * Functions for managing wufiles and their data + * + * $Id: wufiles.h,v 1.1.2.1 2006/01/13 00:25:06 jeffc Exp $ + * + */ + + + +int make_wu_headers(tapeheader_t tapeheader[],workunit wuheaders[], + buffer_pos_t *start_of_wu) ; +void write_wufile_blocks(int nbytes) ; +void rename_wu_files(); + +/* + * $Log: wufiles.h,v $ + * Revision 1.1.2.1 2006/01/13 00:25:06 jeffc + * *** empty log message *** + * + * Revision 1.2 2003/08/05 17:23:45 korpela + * More work on database stuff. + * Further tweaks. + * + * Revision 1.1 2003/06/03 00:23:44 korpela + * + * Again + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.1 1998/11/02 16:41:21 korpela + * Minor Change. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.1 1998/10/27 01:13:16 korpela + * Initial revision + * + * + */ diff --git a/tools/Makefile.am b/tools/Makefile.am new file mode 100644 index 0000000..5bef77d --- /dev/null +++ b/tools/Makefile.am @@ -0,0 +1,50 @@ +## $Id: Makefile.am,v 1.1.2.2 2006/01/04 00:47:33 korpela Exp $ + +include $(top_srcdir)/Makefile.incl + +LDFLAGS= +AM_LDFLAGS= + +BOINC_LIBS = -L$(BOINCDIR)/api -lboinc_api -L$(BOINCDIR)/lib -lboinc + +CLIENT_C_FLAGS = $(CFLAGS) \ + $(DEFS) \ + -DTEXT_UI -DNDEBUG -DCLIENT \ + -include $(top_builddir)/config.h \ + -I$(top_srcdir)/db \ + -I$(top_srcdir)/client \ + $(BOINC_CFLAGS) \ + $(PTHREAD_CFLAGS) + +CLIENT_LD_FLAGS = $(PTHREAD_CFLAGS) $(LDFLAGS) $(PTHREAD_LIBS) $(BOINC_LIBS) + +noinst_PROGRAMS = fakedata workunit_resample + +fakedata_SOURCES = \ + fakedata.cpp \ + ../client/seti_header.cpp \ + ../client/timecvt.cpp \ + ../db/schema_master.cpp \ + ../db/sqlrow.cpp \ + ../db/sqlblob.cpp \ + ../db/xml_util.cpp + +fakedata_CFLAGS = $(CLIENT_C_FLAGS) +fakedata_CXXFLAGS = $(CLIENT_C_FLAGS) +fakedata_LDFLAGS = $(CLIENT_LD_FLAGS) + +workunit_resample_SOURCES = \ + workunit_resample.cpp \ + ../client/seti_header.cpp \ + ../client/timecvt.cpp \ + ../client/s_util.cpp \ + ../db/schema_master.cpp \ + ../db/sqlrow.cpp \ + ../db/sqlblob.cpp \ + ../db/xml_util.cpp + +workunit_resample_CFLAGS = $(CLIENT_C_FLAGS) +workunit_resample_CXXFLAGS = $(CLIENT_C_FLAGS) +workunit_resample_LDFLAGS = $(CLIENT_LD_FLAGS) +workunit_resample_LDADD = -lfftw3f + diff --git a/tools/fakedata.cpp b/tools/fakedata.cpp new file mode 100755 index 0000000..06740f1 --- /dev/null +++ b/tools/fakedata.cpp @@ -0,0 +1,431 @@ +// fakedata [ options ] filename +// +// Title : fakedata.c +// Programmer : Jeff Cobb / David Anderson +// History : 12/13/95 - first release +// : 10/25/05 - Modified for setiathome_enhanced Eric Korpela +// Copyright (c) 1998 University of California Regents + +// Credits for seti@home reference package: +// algorithm design: Dan Werthimer (UCB), +// Mike Lampton, (UCB), +// Charles Donnelly (UCB), +// Jeff Cobb (UCB) +// reference code programming: Jeff Cobb +// seti@home network design and programming: David Anderson + +// This program is to be used to generate fake digital data +// for testing seti@home algorithms. It generates random +// noise embedded with any of the following signal types: +// - continuous +// - pulsed +// - chirped +// - showing an gaussian power profile over time +// The randomness of the noise can be colored by: +// - change in noise amplitude over time +// - favoring certain frequencies (changing noise +// amplitude over frequency) + +// The signal to noise ratio you want to use to emulate a setiathome work +// unit depends upon the signal type and the FFT length you want to find it at. +// For example if you want to build a gaussian that is 5 times the noise power +// at an FFT length of 16384 you should specify a noise amplitude of 1 and +// a gaussian amplitude of 5/sqrt(16384) (about 0.04). If you want to specify +// a spike of 30 times the mean noise power at an FFT length of 128k you would +// specify a sine wave of amplitude 30/sqrt(128k) (about 0.083). + +// The output file contains +// the number of data points and an array of floating +// point numbers representing power over time. +// That the array is a series of complex values, +// using 2 array elements for each data point. +// Real parts are held in even elements (starting with [0]) +// and imaginary parts are held in the adjacent odd elements. + +// options: +// +// -sr n +// samples per second +// -dur x +// duration of data (seconds) +// -sine amp freq chirp start end +// inject a sine wave, amplitude amp +// freq: frequency at center of time interval +// (note: freqs must lie in [-sr/2, sr/2] +// chirp rate in Hz/sec +// NOTE: chirp is applied starting from time 0 +// (not necessarily from the start of the sine wave) +// Start and end times; if zero, whole duration +// -noise amp +// inject noise of amplitude amp; +// -gauss amp midpt sig freq chirp +// Inject a Gaussian signal with the given amplitude and midpoint, +// halfpower width (seconds), frequency (Hz), chirp rate (Hz/sec) +// -pulse period duty +// Inject a pulse signal with the given period (seconds) and duty cycle (percent). It +// is "encased" in the Gaussian envelope determined by the -gaussian parameters +// -ascii +// generate ascii data +// default: 1-bit output samples (binary). + +//#define DEBUG + +#include +#include +#include +#include + +#include "analyze.h" +#include "seti_header.h" +#include "xml_util.h" + +#define NEG_LN_ONE_HALF 0.693 +#if 0 +#define EXP(a,b,c) exp(-(NEG_LN_ONE_HALF * pow((double)(a) - (double)(b), 2.0)) / (double)(c)) +#endif + +struct SIGNAL_DESC { + double sample_rate; + double dur; + bool onebit; + double noise_amp; + double sine_amp; + double sine_freq; + double sine_chirp; + double sine_start; + double sine_end; + double gauss_amp; + double gauss_midpt; + double gauss_sigma; + double gauss_freq; + double gauss_chirp; + double pulse_period; + double pulse_duty_cycle; +}; + +void bad_args() { + fprintf(stderr, "bad args\n"); + exit(1); +} + +float randu() { +// Uniform random numbers between 0 and 1 + static bool first=true; + if (first) { + srand(time(0)); + first=false; + } + return static_cast(rand())/RAND_MAX; +} + +float rande() { +// exponentially distributed random numbers + return -log(randu()); +} + +float randn() { +// normally distributed random numbers + static float last=0; + float a,b,h=0; + if (last==0) { + while (h==0 || h>=1) { + a=2*randu()-1; + b=2*randu()-1; + h=a*a+b*b; + } + h=sqrt(-2*log(h)/h); + last=a*h; + return b*h; + } else { + a=last; + last=0; + return a; + } +} + + + +void getopts(int argc, char* argv[], SIGNAL_DESC& sd) { + int i; + sd.onebit = true; + for (i=1; i data; + + time_t st=time(0); + + + if (argc < 2) bad_args(); + + idum = -time(NULL); + + memset(&sd, 0, sizeof(sd)); + getopts(argc, argv, sd); + +// some default values -- added by EK ///////////////////////////// + if (sd.sample_rate == 0) sd.sample_rate=9765.625; + if (sd.noise_amp == 0) sd.noise_amp=1; + if (sd.dur==0) { + npoints=1024*1024; + sd.dur=npoints/sd.sample_rate; + } else { + npoints = (int)(sd.sample_rate * sd.dur); + } + data.reserve(npoints/4); + if (sd.gauss_sigma == 0) sd.gauss_sigma=12.5; +//////////////////////////////////////////////////////////////////// + + if (sd.sine_end == 0) sd.sine_end = sd.dur; + +// Added workunit header - EK /////////////////////////////////// + sprintf(wu.name,"fake.%d.0",st); +///////////////////////// Group Info //////////////////////////// + sprintf(wu.group_info->name,"fake.%d",st); +///////////////////////// Tape Info ///////////////////////////// + sprintf(wu.group_info->tape_info->name,"fake"); + wu.group_info->tape_info->start_time=time_t_to_jd(st); + wu.group_info->tape_info->last_block_time=time_t_to_jd(st); +///////////////////////// Recv Conf ///////////////////////////// + wu.group_info->receiver_cfg->s4_id=1; + sprintf(wu.group_info->receiver_cfg->name,"fake"); + wu.group_info->receiver_cfg->beam_width=5.0/60.0; + wu.group_info->receiver_cfg->center_freq=1420.0; + wu.group_info->receiver_cfg->az_corr_coeff.push_back(0.0); + wu.group_info->receiver_cfg->zen_corr_coeff.push_back(0.0); +///////////////////////// Recorder Cfg ////////////////////////// + sprintf(wu.group_info->recorder_cfg->name,"fake"); + wu.group_info->recorder_cfg->bits_per_sample=2; + wu.group_info->recorder_cfg->beams=1; + wu.group_info->recorder_cfg->sample_rate=sd.sample_rate; +///////////////////////// Splitter Cfg ////////////////////////// + wu.group_info->splitter_cfg->version=0.17; + sprintf(wu.group_info->splitter_cfg->data_type,"encoded"); + sprintf(wu.group_info->splitter_cfg->filter,"fft"); + sprintf(wu.group_info->splitter_cfg->window,"welsh"); + wu.group_info->splitter_cfg->fft_len=1; + wu.group_info->splitter_cfg->ifft_len=1; +///////////////////////// Data Desc ///////////////////////////// + wu.group_info->data_desc.start_ra=0; + wu.group_info->data_desc.start_dec=18.4; + wu.group_info->data_desc.end_dec=18.4; + wu.group_info->data_desc.time_recorded_jd=time_t_to_jd(st); + sprintf(wu.group_info->data_desc.time_recorded,"%s",jd_string(time_t_to_jd(st))); + wu.group_info->data_desc.nsamples=npoints; + wu.group_info->data_desc.true_angle_range=sd.dur/sd.gauss_sigma*wu.group_info->receiver_cfg->beam_width; + { + time_t dt=0; + double dr=wu.group_info->data_desc.true_angle_range/(cos(18.4*M_PI/180)*15*sd.dur); + while (dt<(sd.dur+5)) { + coordinate_t tmp; + tmp.time=time_t_to_jd(st+dt); + tmp.dec=18.4; + tmp.ra=dt*dr; + wu.group_info->data_desc.coords.push_back(tmp); + dt+=5; + } + } +///////////////////////// Subband Desc ///////////////////////////// + wu.subband_desc.number=0; + wu.subband_desc.center=1420000000; + wu.subband_desc.base=1420000000; + wu.subband_desc.sample_rate=sd.sample_rate; + + +///////////////////////// Analysis Cfg ///////////////////////////// + wu.group_info->analysis_cfg->spike_thresh=24.0; + wu.group_info->analysis_cfg->spikes_per_spectrum=1; + wu.group_info->analysis_cfg->gauss_null_chi_sq_thresh=2.2249999; + wu.group_info->analysis_cfg->gauss_chi_sq_thresh=1.41999996; + wu.group_info->analysis_cfg->gauss_power_thresh=3; + wu.group_info->analysis_cfg->gauss_peak_power_thresh=3.2; + wu.group_info->analysis_cfg->gauss_pot_length=64; + wu.group_info->analysis_cfg->pulse_thresh=19.5; + wu.group_info->analysis_cfg->pulse_display_thresh=0.5; + wu.group_info->analysis_cfg->pulse_max=40960; + wu.group_info->analysis_cfg->pulse_min=16; + wu.group_info->analysis_cfg->pulse_fft_max=8192; + wu.group_info->analysis_cfg->pulse_pot_length=256; + wu.group_info->analysis_cfg->triplet_thresh=8.5; + wu.group_info->analysis_cfg->triplet_max=131072; + wu.group_info->analysis_cfg->triplet_min=16; + wu.group_info->analysis_cfg->triplet_pot_length=256; + wu.group_info->analysis_cfg->pot_overlap_factor=0.5; + wu.group_info->analysis_cfg->pot_t_offset=1; + wu.group_info->analysis_cfg->pot_min_slew=0.00209999993; + wu.group_info->analysis_cfg->pot_max_slew=0.0104999999; + wu.group_info->analysis_cfg->chirp_resolution=0.333; + wu.group_info->analysis_cfg->analysis_fft_lengths=262136; + wu.group_info->analysis_cfg->bsmooth_boxcar_length=8192; + wu.group_info->analysis_cfg->bsmooth_chunk_size=32768; + { + chirp_parameter_t tmp; + tmp.chirp_limit=20; + tmp.fft_len_flags=262136; + wu.group_info->analysis_cfg->chirps.push_back(tmp); + tmp.chirp_limit=50; + tmp.fft_len_flags=65528; + wu.group_info->analysis_cfg->chirps.push_back(tmp); + } + wu.group_info->analysis_cfg->pulse_beams=1; + wu.group_info->analysis_cfg->max_signals=3000; + wu.group_info->analysis_cfg->max_spikes=3000; + wu.group_info->analysis_cfg->max_gaussians=3000; + wu.group_info->analysis_cfg->max_pulses=3000; + wu.group_info->analysis_cfg->max_triplets=3000; + + + + + + +///////////////////////////////////////////////////////////////// + + fprintf (stderr, "sample rate: %f\n", sd.sample_rate); + fprintf (stderr, "duration: %f\n", sd.dur); + fprintf (stderr, "number of points: %d\n", npoints); + fprintf (stderr, "noise: %f\n", sd.noise_amp); + fprintf (stderr, "sine_amp: %f\n", sd.sine_amp); + fprintf (stderr, "sine_freq: %f (wu %d)\n", sd.sine_freq, + freq_to_wu(sd, sd.sine_freq) + ); + fprintf (stderr, "sine_chirp: %f\n", sd.sine_chirp); + fprintf (stderr, "sine_start: %f\n", sd.sine_start); + fprintf (stderr, "sine_end: %f\n", sd.sine_end); + fprintf (stderr, "gauss_amp: %f\n", sd.gauss_amp); + fprintf (stderr, "gauss_midpt: %f\n", sd.gauss_midpt); + fprintf (stderr, "gauss_sigma: %f\n", sd.gauss_sigma); + fprintf (stderr, "gauss_freq: %f (wu %d)\n", sd.gauss_freq, + freq_to_wu(sd, sd.gauss_freq) + ); + fprintf (stderr, "gauss_chirp: %f\n", sd.gauss_chirp); + fprintf (stderr, "pulse_period: %f\n", sd.pulse_period); + fprintf (stderr, "pulse_duty_cycle: %f\n", sd.pulse_duty_cycle); + + fprintf (stderr, "data format: %s\n", sd.onebit?"binary":"ascii"); + + cnt = 0; + if(!sd.onebit) { + printf("nsamples=%d\n", npoints); + printf("real imag\n"); + } + double sine_phase = 0, sine_freq; + double sine_midpt = (sd.sine_end - sd.sine_start)/2; + double gauss_phase = 0, gauss_freq; + double dt = sd.dur/npoints; + double sigma_sq = sd.gauss_sigma*sd.gauss_sigma; + double pulseActive = 1.0; + double pulseTime = sd.pulse_period*sd.pulse_duty_cycle/100.0; + + for (i=0; i 0) { + real += randn()*sd.noise_amp; + imag += randn()*sd.noise_amp; + } + if (sd.sine_amp) { + if (mytime >= sd.sine_start && mytime <= sd.sine_end) { + real += sd.sine_amp*cos(sine_phase); + imag -= sd.sine_amp*sin(sine_phase); + } + sine_freq = sd.sine_freq + sd.sine_chirp*mytime; + sine_phase += M_PI*2*dt*sine_freq; + } + if (sd.pulse_period > 0) { + if( (mytime - (floor(mytime/sd.pulse_period))*sd.pulse_period) > pulseTime ) { + pulseActive = 0.0; + } + } + if (sd.gauss_amp > 0) { + double gauss_factor = EXP(mytime, sd.gauss_midpt, sigma_sq); + real += gauss_factor*pulseActive*sd.gauss_amp*cos(gauss_phase); + imag -= gauss_factor*pulseActive*sd.gauss_amp*sin(gauss_phase); + gauss_freq = sd.gauss_freq + sd.gauss_chirp*mytime; + gauss_phase += M_PI*2*dt*gauss_freq; + } + + if (sd.onebit) { + c >>= 2; + if (real >= 0) c |= 0x8000; + if (imag >= 0) c |= 0x4000; + cnt += 2; + if (cnt == 16) { + cnt = 0; + data.push_back(c/256); + data.push_back(c&255); + } + } else { + printf("%e %e\n", real, imag); + } + } + // flush out remaining samples + if (sd.onebit) { + for (i=0; i<7; i++) { + c >>= 2; + cnt += 2; + if (cnt == 16) { + cnt = 0; + data.push_back(c/256); + data.push_back(c&255); + } + } + printf("\n"); + std::cout << wu; + std::string tmpstr=xml_encode_string(data,_x_setiathome); + printf("",tmpstr.size(), + xml_encoding_names[_x_setiathome]); + fwrite(tmpstr.c_str(),tmpstr.size(),1,stdout); + printf("\n\n"); + } +} + +void print_error( int e ) { + printf( "Error %d\n", e ); + exit(1); +} + diff --git a/tools/workunit_resample.cpp b/tools/workunit_resample.cpp new file mode 100644 index 0000000..051aff8 --- /dev/null +++ b/tools/workunit_resample.cpp @@ -0,0 +1,142 @@ +// SETI_BOINC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. + +// SETI_BOINC is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along +// with SETI_BOINC; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +// In addition, as a special exception, the Regents of the University of +// California give permission to link the code of this program with libraries +// that provide specific optimized fast Fourier transform (FFT) functions and +// distribute a linked executable. You must obey the GNU General Public +// License in all respects for all of the code used other than the FFT library +// itself. Any modification required to support these libraries must be +// distributed in source code form. If you modify this file, you may extend +// this exception to your version of the file, but you are not obligated to +// do so. If you do not wish to do so, delete this exception statement from +// your version. + +// workunit_resample - a program to read in a workunit and convert it to +// real samples at twice the sampling rate with all frequencies shifted to +// be positive. + +#include "sah_config.h" + +#include +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_STAT_H +#include +#endif +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#include +#include +#include +#include + + +#ifdef HAVE_IEEEFP_H +#include +#endif + +#include "client/timecvt.h" +#include "client/s_util.h" +#include "db/db_table.h" +#include "db/schema_master.h" +#include "seti.h" + +#include "fftw3.h" + + +workunit_header header; + +int main(int argc, char *argv[]) { + char *outfile=NULL, buf[256]; + struct stat statbuf; + int nbytes,nread,nsamples; + std::string tmpbuf(""); + int i=0,j; + + if ((argc < 2) || (argc > 3)) { + fprintf(stderr,"%s infile [outfile]\n",argv[0]); + exit(1); + } + char *infile=argv[1]; + if (argc==3) { + outfile=argv[2]; + } + FILE *in=fopen(infile,"r"); + FILE *out; + if (outfile) { + out=fopen(outfile,"w"); + } else { + out=stdout; + } + stat(infile,&statbuf); + nbytes=statbuf.st_size; + fseek(in,0,SEEK_SET); + tmpbuf.reserve(nbytes); + // read entire file into a buffer. + while ((nread=(int)fread(buf,1,sizeof(buf),in))) { + tmpbuf+=std::string(&(buf[0]),nread); + } + // parse the header + header.parse_xml(tmpbuf); + // decode the data + std::vector datav( + xml_decode_field(tmpbuf,"data") + ); + tmpbuf.clear(); + nsamples=header.group_info->data_desc.nsamples; + nbytes=nsamples*header.group_info->recorder_cfg->bits_per_sample/8; + if (datav.size() < nbytes) { + fprintf(stderr,"Data size does not match number of samples\n"); + exit(1); + } + // convert the data to floating point + sah_complex *fpdata=(sah_complex *)calloc(nsamples,sizeof(sah_complex)); + sah_complex *fpout=(sah_complex *)calloc(2048,sizeof(sah_complex)); + sah_complex *tmpb=(sah_complex *)calloc(1024,sizeof(sah_complex)); + if (!fpdata || !fpout) { + fprintf(stderr,"Memory allocation failure\n"); + exit(1); + } + bits_to_floats(&(datav[0]),fpdata,nsamples); + datav.clear(); + + sah_complex workbuf[2048]; + fftwf_plan reverse=fftwf_plan_dft_1d(2048,workbuf,fpout,FFTW_BACKWARD,FFTW_MEASURE); + fftwf_plan forward=fftwf_plan_dft_1d(1024,tmpb,workbuf,FFTW_FORWARD,FFTW_MEASURE|FFTW_PRESERVE_INPUT); + + while (i configure.ac.trimmed +mv configure.ac.trimmed configure.ac +./_autosetup diff --git a/validate/Makefile.in b/validate/Makefile.in new file mode 100644 index 0000000..3b8d5dc --- /dev/null +++ b/validate/Makefile.in @@ -0,0 +1,68 @@ +# under construction - jeffc +@SET_MAKE@ + +EXEEXT = @EXEEXT@ +OBJEXT = @OBJEXT@ +LIBEXT = @LIBEXT@ +DLLEXT = @DLLEXT@ +DOTEXEEXT = @DOTEXEEXT@ + +SUFFIXES = .cpp .c .@OBJEXT@ .@DLLEXT@ .@LIBEXT@ @DOTEXEEXT@ + +BOINCDIR = @BOINCDIR@ + +CC = @CC@ +CFLAGS = @CFLAGS@ @DEFS@ -DTEXT_UI -DNDEBUG @PTHREAD_CFLAGS@ + +CXX = @CXX@ +CXXFLAGS = $(CFLAGS) + +LDFLAGS = @LDFLAGS@ + +CLIBS = @LIBS@ + +#SUFFIXES = .cpp .@OBJEXT@ + +#BOINC_INC = -I$(BOINCDIR)/api -I$(BOINCDIR)/lib -I$(BOINCDIR)/sched -I$(BOINCDIR)/db +BOINCDIR = @BOINCDIR@ +BOINC_CFLAGS = @BOINC_CFLAGS@ +BOINC_LIBS = -L$(BOINCDIR)/sched -lsched @PTHREAD_LIBS@ -L$(BOINCDIR)/lib -lboinc +MYSQL_CFLAGS = @MYSQL_CFLAGS@ +MYSQL_LIBS = @MYSQL_LIBS@ +INFORMIXDIR = @INFORMIXDIR@ +INFORMIX_CFLAGS = @INFORMIX_CFLAGS@ +INFORMIX_LIBS = @INFORMIX_LIBS@ + +OBJS = \ + sah_validate.$(OBJEXT) \ + sah_result.$(OBJEXT) \ + sah_boinc_db.$(OBJEXT) + +BOINC_OBJS = $(BOINCDIR)/sched/validator.o \ + $(BOINCDIR)/sched/validate_util.o + + +PROG = sah_validate + +.cpp.@OBJEXT@: + $(CXX) $(CXXFLAGS) $(BOINC_CFLAGS) $(MYSQL_CFLAGS) -I.. -I../db -c -o $*.@OBJEXT@ $< + +.c.@OBJEXT@: + $(CC) $(CFLAGS) $(BOINC_CFLAGS) -I.. -I../db -c -o $*.@OBJEXT@ $< + +#all: Makefile dependencies $(PROGS) +all: Makefile $(PROG) + +../aclocal.m4: ../m4/*.m4 + @CAT@ ../m4/*.m4 >../aclocal.m4 + +../configure: ../configure.ac ../aclocal.m4 ../config.h.in + (cd ..; make config.h) + +$(PROG): $(OBJS) $(BOINC_OBJS) + $(CXX) $(OBJS) $(BOINC_OBJS) -I../db $(BOINC_CFLAGS) $(CLIBS) $(BOINC_LIBS) $(MYSQL_LIBS) $(INFORMIX_LIBS) -o $(PROG) + +clean: + rm -f *.$(OBJEXT) $(PROG) dependencies config.log config.cache + +#include dependencies diff --git a/validate/sah_boinc_db.cpp b/validate/sah_boinc_db.cpp new file mode 100644 index 0000000..fac7cbb --- /dev/null +++ b/validate/sah_boinc_db.cpp @@ -0,0 +1,57 @@ +// stuff that refers to the BOINC DB. +// Separate to avoid name conflicts w/ SETI@home DB + +#include +#include + +#include "parse.h" +#include "error_numbers.h" +#include "sah_boinc_db.h" +#include "sched_config.h" +#include "sched_util.h" +#include "util.h" +#include "validate_util.h" +#include "filesys.h" +#include "sched_msgs.h" + + +extern SCHED_CONFIG config; + +int get_result_file(RESULT& r, SAH_RESULT& s) { + int retval; + FILE * f; + char filename[256]; + char * path; + std::string path_str; + + // Obtain and check the full path to the boinc result file. + retval = get_output_file_path(r, path_str); + if (retval) { + if (retval == ERR_XML_PARSE) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, + "[%s] Cannot extract filename from canonical result %ld.\n", + r.name, r.id); + return(retval); + } else { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, + "[%s] unknown error from get_output_file_path() fpr result %ld.\n", + r.name, r.id); + return(retval); + } + } else { + path = (char *)path_str.c_str(); + if (!boinc_file_exists(path)) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL, + "[%s] Output file %s does not exist for result %ld\n", + r.name, path, r.id); + return(-1); + } + } + + retval = try_fopen(path, f, "r"); + if (retval) return retval; + s.have_result = true; // we had good read of the result file + s.parse_file(f); + fclose(f); + return 0; +} diff --git a/validate/sah_boinc_db.h b/validate/sah_boinc_db.h new file mode 100644 index 0000000..bf7931c --- /dev/null +++ b/validate/sah_boinc_db.h @@ -0,0 +1,4 @@ +#include "boinc_db.h" +#include "sah_result.h" + +extern int get_result_file(RESULT&, SAH_RESULT&); diff --git a/validate/sah_result.cpp b/validate/sah_result.cpp new file mode 100644 index 0000000..7c7bb47 --- /dev/null +++ b/validate/sah_result.cpp @@ -0,0 +1,296 @@ +#include +#include + +#include "parse.h" +#include "sah_result.h" + +// the difference between two numbers, +// as a fraction of the largest in absolute value +// +double rel_diff(double x1, double x2) { + if (x1 == 0 && x2 == 0) return 0; + if (x1 == 0) return 1; + if (x2 == 0) return 1; + + double d1 = fabs(x1); + double d2 = fabs(x2); + double d = fabs(x1-x2); + if (d1 > d2) return d/d1; + return d/d2; +} + +double abs_diff(double x1, double x2) { + return fabs(x1-x2); +} + + +// return true if the two signals are the same +// within numerical tolerances +// +bool SIGNAL::roughly_equal(SIGNAL& s) { + double second = 1.0/86400.0; // 1 second as a fraction of a day + + if (type != s.type) return false; + + // tolerances common to all signals + if (abs_diff(ra, s.ra) > .00066) return false; // .01 deg + if (abs_diff(decl, s.decl) > .01) return false; // .01 deg + if (abs_diff(time, s.time) > second) return false; // 1 sec + if (abs_diff(freq, s.freq) > .01) return false; // .01 Hz + if (abs_diff(chirp_rate, s.chirp_rate) > .01) return false; // .01 Hz/s + if (fft_len != s.fft_len) return false; // equal + + switch (type) { + case SIGNAL_TYPE_SPIKE: + case SIGNAL_TYPE_BEST_SPIKE: + if (rel_diff(power, s.power) > .01) return false; // 1% + return true; + case SIGNAL_TYPE_GAUSSIAN: + case SIGNAL_TYPE_BEST_GAUSSIAN: + if (rel_diff(peak_power, s.peak_power) > .01) return false; // 1% + if (rel_diff(mean_power, s.mean_power) > .01) return false; // 1% + if (rel_diff(sigma, s.sigma) > .01) return false; // 1% + if (rel_diff(chisqr, s.chisqr) > .01) return false; // 1% + //if (rel_diff(max_power, s.max_power) > .01) return false; // ?? jeffc + return true; + case SIGNAL_TYPE_PULSE: + case SIGNAL_TYPE_BEST_PULSE: + if (rel_diff(power, s.power) > .01) return false; // 1% + if (rel_diff(mean_power, s.mean_power) > .01) return false; // 1% + if (abs_diff(period, s.period) > .01) return false; // .01 sec + if (rel_diff(snr, s.snr) > .01) return false; // 1% + if (rel_diff(thresh, s.thresh) > .01) return false; // 1% + return true; + case SIGNAL_TYPE_TRIPLET: + case SIGNAL_TYPE_BEST_TRIPLET: + if (rel_diff(power, s.power) > .01) return false; // 1% + if (rel_diff(mean_power, s.mean_power) > .01) return false; // 1% + if (rel_diff(period, s.period) > .01) return false; // 1% + return true; + case SIGNAL_TYPE_AUTOCORR: + case SIGNAL_TYPE_BEST_AUTOCORR: + if (rel_diff(power, s.power) > .01) return false; // 1% + if (rel_diff(delay, s.delay) > .01) return false; // 1% + return true; + } + return false; +} + +// parse a SETI@home result file +// +int SAH_RESULT::parse_file(FILE* f) { + char buf[1024]; + SIGNAL s; + double d; + int i; + + num_signals = 0; + + memset(&s, 0, sizeof(s)); + while (fgets(buf, 256, f)) { + + if (match_tag(buf, "")) { + memset(&s, 0, sizeof(s)); + s.type = SIGNAL_TYPE_SPIKE; + num_signals++; + + } else if (match_tag(buf, "")) { + memset(&s, 0, sizeof(s)); + s.type = SIGNAL_TYPE_BEST_SPIKE; + + } else if (match_tag(buf, "")) { + memset(&s, 0, sizeof(s)); + s.type = SIGNAL_TYPE_AUTOCORR; + num_signals++; + + } else if (match_tag(buf, "")) { + memset(&s, 0, sizeof(s)); + s.type = SIGNAL_TYPE_BEST_AUTOCORR; + + } else if (match_tag(buf, "")) { + memset(&s, 0, sizeof(s)); + s.type = SIGNAL_TYPE_GAUSSIAN; + num_signals++; + + } else if (match_tag(buf, "")) { + memset(&s, 0, sizeof(s)); + s.type = SIGNAL_TYPE_BEST_GAUSSIAN; + + } else if (match_tag(buf, "")) { + memset(&s, 0, sizeof(s)); + s.type = SIGNAL_TYPE_PULSE; + num_signals++; + + } else if (match_tag(buf, "")) { + memset(&s, 0, sizeof(s)); + s.type = SIGNAL_TYPE_BEST_PULSE; + + } else if (match_tag(buf, "")) { + memset(&s, 0, sizeof(s)); + s.type = SIGNAL_TYPE_TRIPLET; + num_signals++; + + } else if (match_tag(buf, "")) { + memset(&s, 0, sizeof(s)); + s.type = SIGNAL_TYPE_BEST_TRIPLET; + + } else if (parse_double(buf, "", d)) { + s.ra = d; + } else if (parse_double(buf, "", d)) { + s.decl = d; + } else if (parse_double(buf, "", d)) { + s.power = d; + } else if (parse_double(buf, "")) { + if (s.type != SIGNAL_TYPE_SPIKE) { + return -1; + } + signals.push_back(s); + + } else if (match_tag(buf, "")) { + if (s.type != SIGNAL_TYPE_BEST_SPIKE) { + return -1; + } + signals.push_back(s); + + } else if (match_tag(buf, "")) { + if (s.type != SIGNAL_TYPE_AUTOCORR) { + return -1; + } + signals.push_back(s); + + } else if (match_tag(buf, "")) { + if (s.type != SIGNAL_TYPE_BEST_AUTOCORR) { + return -1; + } + signals.push_back(s); + + } else if (match_tag(buf, "")) { + if (s.type != SIGNAL_TYPE_GAUSSIAN) { + return -1; + } + signals.push_back(s); + + } else if (match_tag(buf, "")) { + if (s.type != SIGNAL_TYPE_BEST_GAUSSIAN) { + return -1; + } + signals.push_back(s); + + } else if (match_tag(buf, "")) { + if (s.type != SIGNAL_TYPE_PULSE) { + return -1; + } + signals.push_back(s); + + } else if (match_tag(buf, "")) { + if (s.type != SIGNAL_TYPE_BEST_PULSE) { + return -1; + } + signals.push_back(s); + + } else if (match_tag(buf, "")) { + if (s.type != SIGNAL_TYPE_TRIPLET) { + return -1; + } + signals.push_back(s); + + } else if (match_tag(buf, "")) { + if (s.type != SIGNAL_TYPE_BEST_TRIPLET) { + return -1; + } + signals.push_back(s); + + } + } + + return 0; +} + +// return true if the given signal is roughly equal to a signal +// from the result +// +bool SAH_RESULT::has_roughly_equal_signal(SIGNAL& s) { + unsigned int i; + for (i=0; i +#include + +using namespace std; + +#define SIGNAL_TYPE_SPIKE 1 +#define SIGNAL_TYPE_GAUSSIAN 2 +#define SIGNAL_TYPE_PULSE 3 +#define SIGNAL_TYPE_TRIPLET 4 +#define SIGNAL_TYPE_BEST_SPIKE 5 +#define SIGNAL_TYPE_BEST_GAUSSIAN 6 +#define SIGNAL_TYPE_BEST_PULSE 7 +#define SIGNAL_TYPE_BEST_TRIPLET 8 +#define SIGNAL_TYPE_AUTOCORR 9 +#define SIGNAL_TYPE_BEST_AUTOCORR 10 + +// Result Flags. Can be passed from validator to assimilator +// via the BOINC result.opaque field. Note that you have +// to cast to float in order to assign a flag to the opaque +// field. OR into a temp int and then assign with a cast. +#define RESULT_FLAG_OVERFLOW 0x00000001 + +struct SIGNAL { + int type; + double power; + double period; + double ra; + double decl; + double time; + double freq; + double delay; + double sigma; + double chisqr; + double max_power; + double peak_power; + double mean_power; + double score; + unsigned char pot[256]; + int len_prof; + double snr; + double thresh; + int fft_len; + double chirp_rate; + + bool checked; // temp + + bool roughly_equal(SIGNAL&); +}; + +struct SAH_RESULT { + bool have_result; + bool overflow; + vector signals; + + bool has_roughly_equal_signal(SIGNAL&); + bool strongly_similar(SAH_RESULT&); + bool weakly_similar(SAH_RESULT&); + bool bad_values(); + int parse_file(FILE*); + int num_signals; +}; + +extern int write_sah_db_entries(SAH_RESULT&); + +#endif diff --git a/validate/sah_validate.cpp b/validate/sah_validate.cpp new file mode 100644 index 0000000..36fe319 --- /dev/null +++ b/validate/sah_validate.cpp @@ -0,0 +1,596 @@ +#include "sah_config.h" +#include +#include +#include +#include + +#include "parse.h" +#include "boinc_db.h" +#include "error_numbers.h" + +#include "sah_result.h" +#include "sah_boinc_db.h" + +//#include "boinc_db.h" +#include "util.h" +#include "sched_config.h" +#include "sched_util.h" +#include "sched_msgs.h" + +const int MAX_ALLOWABLE_CREDIT = 115; + +struct VALIDATE_STATS { + int nstrong_compare; + int nstrong; + int nweak_compare; + int nweak; + int bad_results; + + void print(); +}; + +int validate_single(vector& results, int& canonical_id, double& granted_credit); +int validate_plural(vector& results, vector& sah_results, int& canonical_id, double& granted_credit); +void check_overflow_result(RESULT& r); +int log_cuda_result(RESULT& result, double& granted_credit); +bool is_cuda(RESULT result); +int handle_cuda_notvalid(RESULT& result_1, RESULT& result_2); + +void VALIDATE_STATS::print() { + printf("Strongly similar: %d out of %d\n", nstrong, nstrong_compare); + printf("Weakly similar: %d out of %d\n", nweak, nweak_compare); +} + +VALIDATE_STATS validate_stats; + +// check_set() is called from BOINC code and is passed a vector of all +// received results for work unit. check_set() determines the canonical +// result and flags each result as to whether it is similar enough to the +// canonical result to be given credit. check_set provides BOINC with both +// the canonical ID and the amount of credit to be granted to each validated +// result. As a matter of policy the validator does not do values checking. +// The canonical result could have bad values. The detection and flagging +// of this situation is a function of the assimilator. +// +//------------------------------------------------------------ +int check_set( + vector& results, WORKUNIT& wu, int& canonicalid, double& granted_credit, bool& retry) { +//------------------------------------------------------------ + + // Note that SAH_RESULT is not the same type as the standard sah + // result as it appears in the app and the science backend. Rather + // it simply contains a vector of all the signals returned in a + // a given result, along with functions used to validate that result + // (ie that set of signals). + // I should rename the type. jeffc + vector sah_results; + //SAH_RESULT s; + RESULT r; + DB_RESULT db_result; + + unsigned int i, j, k, good_result_count=0; + bool found, err_opendir=false; + double max_credit, min_credit, sum; + int max_credit_i=-1, min_credit_i=-1, nvalid, retval; + vector bad_result; + + retry=false; // init + + log_messages.printf( + SCHED_MSG_LOG::MSG_DEBUG, + "check_set() checking %d results\n", + results.size() + ); + + // read and parse the result files + // + for (i=0; i& results, int& canonicalid, double& granted_credit) { +// This routine is called for single validation (from a trusted client). +//------------------------------------------------------------ + + log_messages.printf( + SCHED_MSG_LOG::MSG_DEBUG, + "[RESULT#%d] is trusted nonredundant and therefore canonical\n", + results[0].id + ); + + check_overflow_result(results[0]); + + results[0].validate_state = VALIDATE_STATE_VALID; + canonicalid = results[0].id; + + if (results[0].claimed_credit <= MAX_ALLOWABLE_CREDIT) { + granted_credit = results[0].claimed_credit; + } else { + log_messages.printf( + SCHED_MSG_LOG::MSG_DEBUG, + "[RESULT#%d] is claiming greater than max allowable credit (%d). Granting max allowable.\n", + results[0].id, MAX_ALLOWABLE_CREDIT + ); + granted_credit = MAX_ALLOWABLE_CREDIT; + } + + return(0); +} + +//------------------------------------------------------------ +int validate_plural(vector& results, vector& sah_results, int& canonicalid, double& granted_credit) { +// This routine is called for redundant validation (from nontrusted or test case clients) . +//------------------------------------------------------------ + + unsigned int i, j, k; + bool found; + double max_credit, min_credit, sum; + int max_credit_i=-1, min_credit_i=-1, nvalid, retval; + + // see if there's a pair of results that are strongly similar + // Not all results are *neccessarily* checked for overflow. Any + // result that may become the canonical reult is checked and thus + // a valid overflow indicator is always paased on to the assimilator. + found = false; + for (i=0; i= max_credit) { + max_credit = results[k].claimed_credit; + max_credit_i = k; + } + if (results[k].claimed_credit <= min_credit) { + min_credit = results[k].claimed_credit; + min_credit_i = k; + } + } + nvalid++; + } // end validate_state == VALIDATE_STATE_VALID + } // end scan with [k] to validate rest of set against canonical + + // the granted credit is the average of claimed credits + // of valid results, discarding the largest and smallest + // + if (nvalid == 2) { + granted_credit = min_credit; + } else { + // Take care of case where all claimed credits are equal. + if (max_credit == min_credit) { + granted_credit = min_credit; + } else { + sum = 0; + for (k=0; k results; + double credit, test_credit=5.5; + int i, canonical, retval; + RESULT r; + + memset(&validate_stats, 0, sizeof(validate_stats)); + + for (i=1; i\n" + " %s\n" + "\n", + argv[i] + ); + results.push_back(r); + } + + retval = check_set(results, canonical, credit); + if (retval) { + printf("error: %d\n", retval); + } + + for (i=0; i < results.size(); i++) { + printf("validate_state of %s is %d\n", argv[i+1], results[i].validate_state); + } + + if (canonical) { + printf("canonical result is %d; credit is %f\n", canonical, credit); + } else { + printf("no canonical result found\n"); + } + validate_stats.print(); +} +#endif diff --git a/vector_lib/3dnow.h b/vector_lib/3dnow.h new file mode 100644 index 0000000..156941d --- /dev/null +++ b/vector_lib/3dnow.h @@ -0,0 +1,303 @@ +// Copyright 2004 Regents of the University of California +// +// libSIMD++ is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. +// +// libSIMD++ is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along +// with libSIMD++; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// $Id: 3dnow.h,v 1.3 2004/10/28 21:15:36 korpela Exp $ +// +// Specific template instances for 3DNow! supported SIMD routines. This file +// is included from "simd.h" +// +// Original revision: 28-Jul-2004, Eric J. Korpela +// + +#include "mmx.h" + +static const float zeros[4]={0,0}; +static const float ones[4]={1,1}; + +// First lets do the easy operators...... +//--------------------- binary operators------------------------------------- +#define tdn_deref(t,n) \ +inline simd::arrtype REF simd::ptr::operator *() { \ + return reinterpret_cast::arrtype REF>(*(__m64 *)(v)); \ +} + +tdn_deref(float,2) + +#define tdn_array_deref(t,n) \ +inline simd::arrtype REF simd::ptr::operator [](int i) { \ + return reinterpret_cast::arrtype REF >(*((__m64 *)(v)+i)); \ +} + +tdn_array_deref(float,2) + +#define tdn_commutative_binop(t,n,__op,__instr,__followup_instr) \ +inline simd::arrtype REF simd::arrtype::operator __op( \ + const simd::arrtype &b) const \ +{ \ + register __m64 retval64; \ + __asm__ ( __instr " %2,%1\n" __followup_instr \ + : "=y" (retval64) \ + : "%0" (m64.all) , \ + "ym" (b.m64.all) \ + ); \ + return reinterpret_cast::arrtype REF >(retval64); \ +} + +#define tdn_noncomm_binop(t,n,__op,__instr,__followup_instr) \ +inline simd::arrtype REF simd::arrtype::operator __op( \ + const simd::arrtype &b) const \ +{ \ + register __m64 retval64; \ + __asm__ ( __instr " %2,%1\n" __followup_instr \ + : "=y" (retval64) \ + : "0" (m64.all) , \ + "ym" (b.m64.all) \ + ); \ + return reinterpret_cast::arrtype REF >(retval64); \ +} + +#define tdn_binop_const(t,n,__op,__instr,__followup_instr, __const_operand) \ +inline simd::arrtype REF simd::arrtype::operator __op() const \ +{ \ + register __m64 retval64; \ + __asm__ ( __instr " %2,%1\n" __followup_instr \ + : "=y" (retval64) \ + : "0" (__const_operand) , \ + "ym" (m64.all) \ + ); \ + return reinterpret_cast::arrtype REF >(retval64); \ +} + +#define tdn_assign_op(t,n,__op,__instr,__followup_instr) \ +inline simd::arrtype &simd::arrtype::operator __op( \ + const simd::arrtype &b) \ +{ \ + __asm__ ( __instr " %1,%0\n" __followup_instr \ + : "=y" (m64.all) \ + : "ym" (b.m64.all) \ + ); \ + return *this; \ +} + +#define tdn_comp_op(t,n,__op,instr) \ +inline simd::arrtype REF simd::arrtype::operator __op(const \ + simd::arrtype &b) const \ +{ \ + register __m32 retval32; \ + register __m16 retval16; \ + __asm__ ( instr" %2,%1\n" \ + "\tpackssdw %1,%1\n" \ + "\tpacksswb %1,%0\n" \ + "\tpandn _trueb,%0\n" \ + : "=r" (retval16) \ + : "%y" (m64.all), \ + "ym" (b.m64.all) \ + ); \ + return reinterpret_cast::arrtype REF>(retval32); \ +} + +tdn_commutative_binop(float,2,+,"pfadd","") +tdn_commutative_binop(float,2,*,"pfmul","") + +tdn_noncomm_binop(float,2,-,"pfsub","") + +tdn_binop_const(float,2,-,"pfsub","",zeros) + +tdn_assign_op(float,2,+=,"pfadd","") +tdn_assign_op(float,2,*=,"pfmul","") +tdn_assign_op(float,2,-=,"pfsub","") + +tdn_comp_op(float,2,==,"pfcmpeq") +tdn_comp_op(float,2,>=,"pfcmpge") +tdn_comp_op(float,2,>,"pfcmpgt") + +//-----------------------------division---------------------------------- +#define tdn_divop(t,n,__op) \ +inline simd::arrtype REF simd::arrtype::operator __op( \ + const simd::arrtype &b) const \ +{ \ + register __m64 intermed,retval64; \ + __asm__ ( "pfrcp %3,%1\n" \ + "\punpckldq %3,%3\n" \ + "\tpfrcit1 %1,%3\n" \ + "\tpfrcit2 %1,%3\n" \ + "\tpfmul %3,%0\n" \ + : "=y" (retval64),"=y" (intermed) \ + : "0" (m64.all) , \ + "y" (b.m64.all) \ + ); \ + return reinterpret_cast::arrtype &>(retval64); \ +} + +tdn_divop(float,2,/) + +//-----------------------------sqrt-------------------------------- + +inline simd::arrtype REF simd::arrtype::sqrt() const { + return (*this)*rsqrt(); +} + +inline simd::arrtype REF simd::arrtype::aprx_sqrt() const { + return (*this)*aprx_rsqrt(); +} + +//-----------------------------reciprocal-------------------------------- + + +#define tdn_pfrcp_macro(t,n) \ +inline simd::arrtype REF simd::arrtype::aprx_recip() \ + const \ +{ \ + register __m64 retval64; \ + __asm__ ( "pfrcp %1,%0\n" \ + : "=y" (retval64) \ + : "ym" (m64.all) \ + ); \ + return reinterpret_cast::arrtype REF>(retval64); \ +} + +tdn_pfrcp_macro(float,2) + +#define tdn_recip_macro(t,n) \ +inline simd::arrtype REF simd::arrtype::recip() \ + const \ +{ \ + register __m64 intermed,retval64; \ + __asm__ ( "pfrcp %0,%1\n" \ + "\punpckldq %0,%0\n" \ + "\tpfrcpit1 %1,%0\n" \ + "\tpfrcpit2 %1,%0\n" \ + : "=y" (retval64), "=y" (intermed) \ + : "0" (m64.all) \ + ); \ + return reinterpret_cast::arrtype REF>(retval64); \ +} +tdn_recip_macro(float,2) + +//-----------------------------reciprocal sqrt-------------------------------- + +#define tdn_rsqrt_macro(t,n) \ +inline simd::arrtype REF simd::arrtype::rsqrt() \ + const \ +{ \ + register __m64 retval64,intermed; \ + __asm__ ( "pfrsqrt %2,%1\n" \ + "\tmovq %1,%0\n" \ + "\tfpmul %1,%1\n" \ + "\tpunpckldq %2,%2\n" \ + "\tpfrsqit1 %2,%1" \ + "\tpfrcpit2 %0,%1" \ + : "=y" (intermed), "=y" (retval64) \ + : "y" (m64.all) \ + ); \ + return reinterpret_cast::arrtype REF>(retval64); \ +} +tdn_rsqrt_macro(float,4) + +#define tdn_pfrsqrt_macro(t,n) \ +inline simd::arrtype REF simd::arrtype::aprx_rsqrt() \ + const \ +{ \ + register __m64 retval64; \ + __asm__ ( "pfrsqrt %1,%0\n" \ + : "=y" (retval64) \ + : "ym" (m64.all) \ + ); \ + return reinterpret_cast::arrtype REF>(retval64); \ +} +tdn_pfrsqrt_macro(float,4) + +//-----------------------------max-------------------------------- + +#define tdn_pfmax_macro(t,n) \ +inline simd::arrtype REF simd::arrtype::max(const simd::arrtype &b) \ + const \ +{ \ + register __m64 retval64; \ + __asm__ ( "pfmax %2,%1\n" \ + : "=y" (retval64) \ + : "%0" (m64.all), \ + "ym" (b.m64.all) \ + ); \ + return reinterpret_cast::arrtype REF>(retval64); \ +} +tdn_pfmax_macro(float,2) + +//-----------------------------min-------------------------------- + +#define tdn_pfmin_macro(t,n) \ +inline simd::arrtype REF simd::arrtype::min(const simd::arrtype &b) \ + const \ +{ \ + register __m64 retval64; \ + __asm__ ( "pfmin %2,%1\n" \ + : "=y" (retval64) \ + : "%0" (m64.all), \ + "ym" (b.m64.all) \ + ); \ + return reinterpret_cast::arrtype REF>(retval64); \ +} +tdn_pfmin_macro(float,2) + +//-----------------------------shuffle--------------------------------------- + + +//-----------------------------interleave----------------------------------- + + +//-----------------------------ancillary------------------------------------- + +#define tdn_start_macro(t,n) \ +inline volatile void simd::simd_mode_start() { \ +} +tdn_start_macro(float,4) + +#define tdn_end_macro(t,n) \ +inline volatile void simd::simd_mode_finish() { \ + __asm__ volatile (EMMS \ + : \ + : \ + : FP_STACK,MMX_REGS \ + ); \ +} +tdn_end_macro(float,4) + +template +inline void simd::arrtype::prefetch() const { + __asm__ ( "prefetch %0" + : + : "m" (*(reinterpret_cast(this)+32))); +} + +template +inline void simd::arrtype::prefetchw() const { + __asm__ ( "prefetch %0" + : + : "m" (*(reinterpret_cast(this)+32))); +} + +/* + * + * $Log: 3dnow.h,v $ + * Revision 1.3 2004/10/28 21:15:36 korpela + * Added prefetch support. + * + * Revision 1.1 2004/09/29 16:42:02 korpela + * *** empty log message *** + * + * + */ + diff --git a/vector_lib/Makefile b/vector_lib/Makefile new file mode 100644 index 0000000..31a8be0 --- /dev/null +++ b/vector_lib/Makefile @@ -0,0 +1,9 @@ +t1.s: ../config.h ../../boinc/lib/std_fixes.h simd.h mmx.h generics.h t1.cpp sse.h + gcc -w -I../../boinc/lib -march=pentium4 -mfpmath=sse -O2 -DUSE_SSE -S t1.cpp + +t1: ../config.h ../../boinc/lib/std_fixes.h simd.h mmx.h generics.h t1.cpp sse.h + gcc -w -I../../boinc/lib -march=pentium4 -mfpmath=sse -O2 -DUSE_SSE -o t1 t1.cpp + +ps.s: ../config.h ../../boinc/lib/std_fixes.h simd.h mmx.h generics.h ps.cpp sse.h + gcc -w -I../../boinc/lib -march=pentium4 -mfpmath=sse -O2 -DUSE_SSE -S ps.cpp + diff --git a/vector_lib/generics.h b/vector_lib/generics.h new file mode 100644 index 0000000..66a69d0 --- /dev/null +++ b/vector_lib/generics.h @@ -0,0 +1,612 @@ +// Copyright 2004 Regents of the University of California +// +// libSIMD++ is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. +// +// libSIMD++ is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along +// with libSIMD++; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// $Id: generics.h,v 1.9.2.1 2007/03/22 00:03:59 korpela Exp $ +// +// Specific template instances for SSE supported SIMD routines. This file +// is included from "simd.h" +// +// Original revision: 28-Jul-2004, Eric J. Korpela +// +// + +template +inline typename simd::arrtype &simd::ptr::operator *() { + return (*(this->v)); +} + + +#define single_binary_op(t,__op) \ +inline simd::arrtype REF simd::arrtype::operator __op(const \ + simd::arrtype &b) const { \ + register t tmp; \ + tmp=this->v[0] __op b.v[0]; \ + return reinterpret_cast::arrtype &>(tmp); \ +} + +#define single_binary_fltops(t) \ +single_binary_op(t,+) \ +single_binary_op(t,-) \ +single_binary_op(t,*) \ +single_binary_op(t,/) + +#define single_binary_intops(t) \ +single_binary_fltops(t) \ +single_binary_op(t,&) \ +single_binary_op(t,^) \ +single_binary_op(t,|) \ +single_binary_op(t,%) \ +single_binary_op(t,<<) \ +single_binary_op(t,>>) + +single_binary_intops(char) +single_binary_intops(unsigned char) +single_binary_intops(signed char) +single_binary_intops(short) +single_binary_intops(unsigned short) +single_binary_intops(long) +single_binary_intops(unsigned long) +single_binary_fltops(float) +single_binary_fltops(double) +#undef single_binary_op +#undef single_binary_fltops +#undef single_binary_intops + + +#define binary_operator(__op) \ +template \ +inline typename simd::arrtype REF simd::arrtype::operator __op(const \ + typename simd::arrtype &b) const { \ + typename simd::arrtype tmp; \ + *typename simd::ptr((void *)&tmp)=*typename simd::ptr((void *)&v) \ + __op *typename simd::ptr((void *)&(b.v)); \ + *(typename simd::ptr((void *)&tmp)+1)=*(typename simd::ptr((void *)&v)+1) \ + __op *(typename simd::ptr((void *)&(b.v))+1); \ + return tmp; \ +} + + +binary_operator(+) +binary_operator(-) +binary_operator(*) +binary_operator(/) +binary_operator(&) +binary_operator(^) +binary_operator(|) +binary_operator(%) +binary_operator(<<) +binary_operator(>>) +#undef binary_operator + +#define single_bool_op(t,__op,__op_type) \ +inline simd::arrtype REF simd::arrtype::operator __op(const \ + simd<__op_type,1>::arrtype &b) const { \ + register pbool tmp; \ + tmp=this->v[0] __op b.v[0]; \ + return reinterpret_cast::arrtype &>(tmp); \ +} + +#define single_bool_ops(t) \ +single_bool_op(t,&&,t) \ +single_bool_op(t,||,t) \ +single_bool_op(t,==,t) \ +single_bool_op(t,!=,t) \ +single_bool_op(t,<,t) \ +single_bool_op(t,>,t) \ +single_bool_op(t,<=,t) \ +single_bool_op(t,>=,t) +single_bool_ops(char) +single_bool_ops(unsigned char) +single_bool_ops(signed char) +single_bool_ops(short) +single_bool_ops(unsigned short) +single_bool_ops(long) +single_bool_ops(unsigned long) +single_bool_ops(float) +single_bool_ops(double) +#undef single_bool_ops +#undef single_bool_op + +#define bool_operator(__op,__op_type) \ +template \ +inline typename simd::arrtype REF simd::arrtype::operator __op(const \ + typename simd<__op_type,N>::arrtype &b) const { \ + typename simd::arrtype tmp; \ + *typename simd::ptr((void *)&tmp)=*typename simd::ptr((void *)&v) \ + __op *typename simd<__op_type,N/2>::ptr((void *)&(b.v)); \ + *(typename simd::ptr((void *)&tmp)+1)=*(typename simd::ptr((void *)&v)+1) \ + __op *(typename simd<__op_type,N/2>::ptr((void *)&(b.v))+1); \ + return reinterpret_cast::arrtype &>(tmp); \ +} +bool_operator(&&,T) +bool_operator(||,T) +bool_operator(==,T) +bool_operator(!=,T) +bool_operator(<,T) +bool_operator(>,T) +bool_operator(<=,T) +bool_operator(>=,T) +#undef bool_operator + +#define single_ubool_op(t,__op) \ +inline simd::arrtype REF simd::arrtype::operator __op() const \ +{ \ + register pbool tmp; \ + tmp= __op v[0]; \ + return reinterpret_cast::arrtype &>(tmp); \ +} + +#define single_ubool_ops(t) \ +single_ubool_op(t,!) +single_ubool_ops(char) +single_ubool_ops(unsigned char) +single_ubool_ops(signed char) +single_ubool_ops(short) +single_ubool_ops(unsigned short) +single_ubool_ops(long) +single_ubool_ops(unsigned long) +single_ubool_ops(float) +single_ubool_ops(double) +#undef single_ubool_ops +#undef single_ubool_op + +#define ubool_operator(__op) \ +template \ +inline typename simd::arrtype REF simd::arrtype::operator __op() const { \ + typename simd::arrtype tmp; \ + *simd::ptr((void *)&tmp)= __op *simd::ptr((void *)this); \ + *(simd::ptr((void *)&tmp)+1)= __op *(simd::ptr((void *)this)+1); \ + return tmp; \ +} +ubool_operator(!) +#undef ubool_operator + +#define single_unary_op(t,__op) \ +inline simd::arrtype REF simd::arrtype::operator __op() const \ +{ \ + register t tmp; \ + tmp= __op v[0]; \ + return reinterpret_cast::arrtype &>(tmp); \ +} + +#define single_unary_fltops(t) \ +single_unary_op(t,-) + +#define single_unary_intops(t) \ +single_unary_fltops(t) \ +single_unary_op(t,~) +single_unary_intops(char) +single_unary_intops(unsigned char) +single_unary_intops(signed char) +single_unary_intops(short) +single_unary_intops(unsigned short) +single_unary_intops(long) +single_unary_intops(unsigned long) +single_unary_fltops(float) +single_unary_fltops(double) +#undef single_unary_op +#undef single_unary_fltops +#undef single_unary_intops + +#define unary_operator(__op) \ +template \ +inline typename simd::arrtype REF simd::arrtype::operator __op() const \ +{ \ + typename simd::arrtype tmp; \ + *simd::ptr((void *)&tmp)=__op *simd::ptr((void *)this); \ + *(simd::ptr((void *)&tmp)+1)=__op *(simd::ptr((void *)this)+1); \ + return reinterpret_cast::arrtype &>(tmp); \ +} + +unary_operator(-) +unary_operator(~) +#undef unary_operator + +#define single_assignment_op(t,__op) \ +inline simd::arrtype &simd::arrtype::operator __op(const \ + simd::arrtype &b) \ +{ \ + v[0] __op b.v[0]; \ + return *this; \ +} +#define single_assignment_fltops(t) \ +single_assignment_op(t,=) \ +single_assignment_op(t,+=) \ +single_assignment_op(t,-=) \ +single_assignment_op(t,*=) \ +single_assignment_op(t,/=) +#define single_assignment_intops(t) \ +single_assignment_fltops(t) \ +single_assignment_op(t,&=) \ +single_assignment_op(t,^=) \ +single_assignment_op(t,|=) \ +single_assignment_op(t,%=) \ +single_assignment_op(t,<<=) \ +single_assignment_op(t,>>=) +single_assignment_intops(char) +single_assignment_intops(unsigned char) +single_assignment_intops(signed char) +single_assignment_intops(short) +single_assignment_intops(unsigned short) +single_assignment_intops(long) +single_assignment_intops(unsigned long) +single_assignment_fltops(float) +#if !defined(USE_MMX) && !defined(USE_SSE) && !defined(USE_SSE2) && !defined(USE_3DNOW) +single_assignment_fltops(double) +#endif +#undef single_assignment_op +#undef single_assignment_fltops +#undef single_assignment_intops + +#define multiple_assignment_op(t,n,__big_type,__op) \ +inline simd::arrtype &simd::arrtype::operator __op(const \ + simd::arrtype &b) \ +{ \ + *reinterpret_cast<__big_type *>(this) \ + __op *reinterpret_cast(&(b.v)); \ + return *this; \ +} +multiple_assignment_op(char,4,unsigned long,=) +multiple_assignment_op(signed char,4,unsigned long,=) +multiple_assignment_op(unsigned char,4,unsigned long,=) +multiple_assignment_op(short,2,unsigned long,=) +multiple_assignment_op(unsigned short,2,unsigned long,=) +multiple_assignment_op(char,2,unsigned short,=) +multiple_assignment_op(signed char,2,unsigned short,=) +multiple_assignment_op(unsigned char,2,unsigned short,=) +#undef multiple_assignment_op + +#define assignment_operator(__op) \ +template \ +inline typename simd::arrtype &simd::arrtype::operator __op(const \ + typename simd::arrtype &b) \ +{ \ + *simd::ptr((void *)this) __op *simd::ptr((void *)&(b.v)); \ + *(simd::ptr((void *)this)+1) __op *(simd::ptr((void *)&(b.v))+1); \ + return *this; \ +} + +assignment_operator(=) +assignment_operator(+=) +assignment_operator(-=) +assignment_operator(*=) +assignment_operator(/=) +assignment_operator(&=) +assignment_operator(^=) +assignment_operator(|=) +assignment_operator(%=) +assignment_operator(<<=) +assignment_operator(>>=) +#undef assignment_operator + +#define _simd_mode_start(t) \ +inline volatile void simd::simd_mode_start() {} + +#define _simd_mode_finish(t) \ +inline volatile void simd::simd_mode_finish() {} + +template +inline volatile void simd::simd_mode_start() { + simd::simd_mode_start(); +} + +template +inline volatile void simd::simd_mode_finish() { + simd::simd_mode_start(); +} + +_simd_mode_start(char) +_simd_mode_start(unsigned char) +_simd_mode_start(signed char) +_simd_mode_start(short) +_simd_mode_start(unsigned short) +_simd_mode_start(long) +_simd_mode_start(unsigned long) +_simd_mode_start(float) +_simd_mode_start(double) +#undef simd_mode_start + +#define single_joint_op(t,__op,__op_type,__ret_type) \ +inline simd<__ret_type,1>::arrtype simd::arrtype::operator __op(const \ + __op_type &b) const \ +{ \ + register __ret_type tmp; \ + tmp=v[0] __op b; \ + return reinterpret_cast::arrtype &>(tmp); \ +} + +#define single_joint_fltops(t) \ +single_joint_op(t,+,t,t) \ +single_joint_op(t,-,t,t) \ +single_joint_op(t,*,t,t) \ +single_joint_op(t,/,t,t) \ +single_joint_op(t,&&,t,pbool) \ +single_joint_op(t,||,t,pbool) \ +single_joint_op(t,==,t,pbool) \ +single_joint_op(t,!=,t,pbool) \ +single_joint_op(t,<,t,pbool) \ +single_joint_op(t,>,t,pbool) \ +single_joint_op(t,<=,t,pbool) \ +single_joint_op(t,>=,t,pbool) + +#define single_joint_intops(t) \ +single_joint_fltops(t) \ +single_joint_op(t,<<,int,t) \ +single_joint_op(t,>>,int,t) \ +single_joint_op(t,&,t,t) \ +single_joint_op(t,^,t,t) \ +single_joint_op(t,|,t,t) \ +single_joint_op(t,%,t,t) + + +single_joint_intops(char) +single_joint_intops(unsigned char) +single_joint_intops(signed char) +single_joint_intops(short) +single_joint_intops(unsigned short) +single_joint_intops(long) +single_joint_intops(unsigned long) +single_joint_fltops(float) +single_joint_fltops(double) +#undef single_joint_op +#undef single_joint_fltops +#undef single_joint_intops + +#define joint_operator(__op,__op_type,__ret_type) \ +template \ +inline typename simd<__ret_type,N>::arrtype simd::arrtype::operator __op(const \ + __op_type &b) const \ +{ \ + typename simd<__ret_type,N>::arrtype tmp; \ + *typename simd<__ret_type,N/2>::ptr((void *)&tmp)=*typename simd::ptr((void *)this) __op b; \ + *(typename simd<__ret_type,N/2>::ptr((void *)&tmp)+1)=*(typename simd::ptr((void *)this)+1) __op b; \ + return tmp; \ +} + +joint_operator(+,T,T) +joint_operator(-,T,T) +joint_operator(*,T,T) +joint_operator(/,T,T) +joint_operator(&&,T,pbool) +joint_operator(||,T,pbool) +joint_operator(==,T,pbool) +joint_operator(!=,T,pbool) +joint_operator(<,T,pbool) +joint_operator(>,T,pbool) +joint_operator(<=,T,pbool) +joint_operator(>=,T,pbool) +joint_operator(&,T,T) +joint_operator(^,T,T) +joint_operator(|,T,T) +joint_operator(%,T,T) +joint_operator(<<,int,T) +joint_operator(>>,int,T) +#undef joint_operator + +#define single_jointasgn_op(t,__op,__op_type) \ +inline simd::arrtype & simd::arrtype::operator __op(const \ + __op_type &b) \ +{ \ + v[0] __op b; \ + return *this; \ +} + +#define single_jointasgn_fltops(t) \ +single_jointasgn_op(t,=,t) \ +single_jointasgn_op(t,+=,t) \ +single_jointasgn_op(t,-=,t) \ +single_jointasgn_op(t,*=,t) \ +single_jointasgn_op(t,/=,t) + +#define single_jointasgn_intops(t) \ +single_jointasgn_fltops(t) \ +single_jointasgn_op(t,<<=,int) \ +single_jointasgn_op(t,>>=,int) \ +single_jointasgn_op(t,&=,t) \ +single_jointasgn_op(t,^=,t) \ +single_jointasgn_op(t,|=,t) \ +single_jointasgn_op(t,%=,t) + +single_jointasgn_intops(char) +single_jointasgn_intops(unsigned char) +single_jointasgn_intops(signed char) +single_jointasgn_intops(short) +single_jointasgn_intops(unsigned short) +single_jointasgn_intops(long) +single_jointasgn_intops(unsigned long) +single_jointasgn_fltops(float) +single_jointasgn_fltops(double) +#undef single_jointasgn_op +#undef single_jointasgn_fltops +#undef single_jointasgn_intops + +#define jointasgn_operator(__op,__op_type) \ +template \ +inline typename simd::arrtype &simd::arrtype::operator __op(const \ + __op_type &b) \ +{ \ + *simd::ptr((void *)this) __op b; \ + *(simd::ptr((void *)this)+1) __op b; \ + return *this; \ +} + +jointasgn_operator(+=,T) +jointasgn_operator(-=,T) +jointasgn_operator(*=,T) +jointasgn_operator(/=,T) +jointasgn_operator(&=,T) +jointasgn_operator(^=,T) +jointasgn_operator(|=,T) +jointasgn_operator(%=,T) +jointasgn_operator(=,T) +jointasgn_operator(<<=,int) +jointasgn_operator(>>=,int) +#undef jointasgn_operator + +#define single_constructor(t) \ +inline simd::arrtype::arrtype(const t &b) \ +{ \ + v[0]=b; \ +} + +single_constructor(char) +single_constructor(unsigned char) +single_constructor(signed char) +single_constructor(short) +single_constructor(unsigned short) +single_constructor(long) +single_constructor(unsigned long) +single_constructor(float) +single_constructor(double) +#undef single_constructor + +template +inline simd::arrtype::arrtype(const T &b) +{ + *simd::ptr((void *)this)=b; + *(simd::ptr((void *)this)+1)=b; +} + +#define pb_assign(t) \ +inline simd::arrtype::arrtype(const simd::arrtype &b) { \ + v[0]=b.v[0]; \ +} + +pb_assign(char) +pb_assign(unsigned char) +pb_assign(signed char) +pb_assign(short) +pb_assign(unsigned short) +pb_assign(long) +pb_assign(unsigned long) +pb_assign(float) +pb_assign(double) + + +template +inline simd::arrtype::arrtype(const typename simd::arrtype &b) { + *typename simd::ptr((void *)this)=*typename simd::ptr((void *)(&(b.v))); + *(typename simd::ptr((void *)this)+1)=*(typename simd::ptr((void *)(&(b.v)))+1); +} + +#define gen_shuffle_macro(t,n) \ +template \ +inline typename simd::arrtype REF shuffle( \ + const typename simd::arrtype &v) \ +{ \ + static t tmp[n];\ + switch (n) { \ + case 8: \ + tmp[n-5]=v.v[(order>>16) & (n-1)]; \ + tmp[n-6]=v.v[(order>>20) & (n-1)]; \ + tmp[n-7]=v.v[(order>>24) & (n-1)]; \ + tmp[n-8]=v.v[(order>>28) & (n-1)]; \ + case 4: \ + tmp[n-3]=v.v[(order>> 8) & (n-1)]; \ + tmp[n-4]=v.v[(order>>12) & (n-1)]; \ + case 2: \ + tmp[n-1]=v.v[(order ) & (n-1)]; \ + tmp[n-2]=v.v[(order>> 4) & (n-1)]; \ + break; \ + default: \ + register int j=order; \ + for (register int i=n-1;i>-1;i--) { tmp[i]=v.v[j&(n-1)]; j>>=4; } \ + } \ + return *reinterpret_cast::arrtype *>(&tmp); \ +} + +gen_shuffle_macro(double,2) +#ifndef USE_SSE +gen_shuffle_macro(float,4) +gen_shuffle_macro(long,4) +gen_shuffle_macro(unsigned long,4) +gen_shuffle_macro(short,4) +gen_shuffle_macro(unsigned short,4) +#endif +gen_shuffle_macro(float,2) +gen_shuffle_macro(long,2) +gen_shuffle_macro(unsigned long,2) +gen_shuffle_macro(char,8) +gen_shuffle_macro(unsigned char,8) +gen_shuffle_macro(signed char,8) +gen_shuffle_macro(char,4) +//gen_shuffle_macro(unsigned char,4) +gen_shuffle_macro(signed char,4) + +#define gen_interleave_macro(t,n) \ +template \ +inline typename simd::arrtype REF interleave( \ + const typename simd::arrtype &a, const typename simd::arrtype & b) \ +{ \ + simd::arrtype tmp; \ + register long long j=order; \ + for (register int i=n/2-1;i>-1;i--) { tmp.v[i]=a.v[j&(n-1)]; j>>=4; } \ + for (register int i=n-1;i>n/2-1;i--) { tmp.v[i]=b.v[j&(n-1)]; j>>=4; } \ + return tmp; \ +} + +gen_interleave_macro(char,8) +gen_interleave_macro(unsigned char,8) +gen_interleave_macro(signed char,8) + +#define gen_interleave_four(t) \ +template \ +inline typename simd::arrtype REF interleave( \ + const typename simd::arrtype &a, const typename simd::arrtype & b) \ +{ \ + static simd::arrtype tmp; \ + tmp.v[0]=a.v[(order>>12)&3]; \ + tmp.v[1]=a.v[(order>>8)&3]; \ + tmp.v[2]=b.v[(order>>4)&3]; \ + tmp.v[3]=b.v[order&3]; \ + return tmp; \ +} + +#if !defined(USE_SSE2) && !defined(USE_SSE) && !defined(USE_MMX) && \ + !defined(USE_3DNOW) +gen_interleave_four(float) +gen_interleave_four(long) +gen_interleave_four(unsigned long) +#endif + +gen_interleave_four(short) +gen_interleave_four(unsigned short) + +gen_interleave_four(char) +gen_interleave_four(signed char) + +#define gen_interleave_two(t) \ +template \ +inline typename simd::arrtype REF interleave( \ + const typename simd::arrtype &a, const typename simd::arrtype & b) \ +{ \ + simd::arrtype tmp; \ + tmp.v[0]=a.v[(order>>4)&1]; \ + tmp.v[1]=b.v[order&1]; \ + return tmp; \ +} + +#if !defined(USE_MMX) && !defined(USE_SSE) && !defined(USE_SSE2) && \ + !defined(USE_3DNOW) +gen_interleave_two(long) +gen_interleave_two(unsigned long) +gen_interleave_two(float) +#endif + +#if !defined(USE_SSE2) +gen_interleave_two(double) +#endif + diff --git a/vector_lib/mmx.h b/vector_lib/mmx.h new file mode 100644 index 0000000..5640b6d --- /dev/null +++ b/vector_lib/mmx.h @@ -0,0 +1,1100 @@ +// Copyright 2004 Regents of the University of California +// +// libSIMD++ is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. +// +// libSIMD++ is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along +// with libSIMD++; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// $Id: mmx.h,v 1.7.2.1 2007/03/22 00:03:59 korpela Exp $ +// +// Specific template instances for MMX supported SIMD routines. This file +// is included from "simd.h" +// +// Original revision: 28-Jul-2004, Eric J. Korpela +// + +#define FP_STACK "st","st(1)","st(2)","st(3)","st(4)","st(5)","st(6)","st(7)" +#define MMX_REGS "mm0","mm1","mm2","mm3","mm4","mm5","mm6","mm7" + +#ifdef __GNUC__ +//register int retval64 __asm__("mm7") __attribute__ ((mode(V8QI))); +//register unsigned long retval32 __asm__("ebx"); +//register unsigned short retval16 __asm__("bx"); +#endif + +static const char trueb[8]={1,1,1,1,1,1,1,1}; +static const short truew[4]={1,1,1,1}; +static const long trued[2]={1,1}; +static const v_i64 falsed=0; +static const v_i64 minus_one=(v_i64)(-1); +static const v_i64 hi_d=(v_i64)0xffffffff00000000LL; +static const v_i64 lo_d=(v_i64)0x00000000ffffffffLL; + +// First lets do the easy operators...... +//--------------------- binary operators ------------------------------------- + +#define mmx_deref(t,n) \ +inline simd::arrtype &simd::ptr::operator *() { \ + return reinterpret_cast::arrtype &>(*(__m64 *)(v)); \ +} + +mmx_deref(char,8) +mmx_deref(unsigned char,8) +mmx_deref(signed char,8) +mmx_deref(short,4) +mmx_deref(unsigned short,4) +mmx_deref(long,2) +mmx_deref(unsigned long,2) + +#define mmx_array_deref(t,n) \ +inline simd::arrtype &simd::ptr::operator [](int i) { \ + return reinterpret_cast::arrtype &>(*((__m64 *)(v)+i)); \ +} + +mmx_array_deref(char,8) +mmx_array_deref(unsigned char,8) +mmx_array_deref(signed char,8) +mmx_array_deref(short,4) +mmx_array_deref(unsigned short,4) +mmx_array_deref(long,2) +mmx_array_deref(unsigned long,2) + +#define mmx_commutative_binop(t,n,__op,__instr,__followup_instr) \ +inline simd::arrtype REF simd::arrtype::operator __op( \ + const simd::arrtype &b) const \ +{ \ + register __m64 retval64; \ + __asm__ ( __instr " %2,%1\n" __followup_instr \ + : "=y" (retval64) \ + : "%0" (m64.all) , \ + "ym" (b.m64.all) \ + ); \ + return reinterpret_cast::arrtype & >(retval64); \ +} + +#define mmx_noncomm_binop(t,n,__op,__instr,__followup_instr) \ +inline simd::arrtype REF simd::arrtype::operator __op( \ + const simd::arrtype &b) const \ +{ \ + register __m64 retval64; \ + __asm__ ( __instr " %2,%1\n" __followup_instr \ + : "=y" (retval64) \ + : "0" (m64.all) , \ + "ym" (b.m64.all) \ + ); \ + return reinterpret_cast::arrtype & >(retval64); \ +} + +#define mmx_binop_const(t,n,__op,__instr,__followup_instr, __const_operand) \ +inline simd::arrtype REF simd::arrtype::operator __op() const \ +{ \ + register __m64 retval64; \ + __asm__ ( __instr " %2,%1\n" __followup_instr \ + : "=y" (retval64) \ + : "0" (__const_operand) , \ + "ym" (m64.all) \ + ); \ + return reinterpret_cast::arrtype & >(retval64); \ +} + +#define mmx_assign(t,n,__op,__instr,__followup_instr) \ +inline simd::arrtype &simd::arrtype::operator __op( \ + const simd::arrtype &b) \ +{ \ + __asm__ volatile ( "" \ + : "=y" (m64.all) \ + : "0" (b.m64.all) \ + ); \ + return *static_cast::arrtype *>(this); \ +} + +#define mmx_assign_op(t,n,__op,__instr,__followup_instr) \ +inline simd::arrtype &simd::arrtype::operator __op( \ + const simd::arrtype &b) \ +{ \ + __asm__ ( __instr" %1,%0\n" __followup_instr \ + : "=ym" (m64.all) \ + : "y" (b.m64.all) \ + ); \ + return *static_cast::arrtype *>(this); \ +} + + +//--------------------- addition ------------------------------------- + +mmx_commutative_binop(char,8,+,"paddb","") +mmx_commutative_binop(signed char,8,+,"paddb","") +mmx_commutative_binop(unsigned char,8,+,"paddb","") +mmx_commutative_binop(short,4,+,"paddw","") +mmx_commutative_binop(unsigned short,4,+,"paddw","") +mmx_commutative_binop(long,2,+,"paddd","") +mmx_commutative_binop(unsigned long,2,+,"paddd","") + +//---------------------- multiplication ------------------------------ +mmx_commutative_binop(short,4,*,"pmullw","") +mmx_commutative_binop(unsigned short,4,*,"pmullw","") + +//---------------------- subtraction --------------------------------- +mmx_noncomm_binop(char,8,-,"psubb","") +mmx_noncomm_binop(signed char,8,-,"psubb","") +mmx_noncomm_binop(unsigned char,8,-,"psubb","") +mmx_noncomm_binop(short,4,-,"psubw","") +mmx_noncomm_binop(unsigned short,4,-,"psubw","") +mmx_noncomm_binop(long,2,-,"psubd","") +mmx_noncomm_binop(unsigned long,2,-,"psubd","") + +//-----------------------------AND-------------------------------- +mmx_commutative_binop(char,8,&,"pand","") +mmx_commutative_binop(signed char,8,&,"pand","") +mmx_commutative_binop(unsigned char,8,&,"pand","") +mmx_commutative_binop(short,4,&,"pand","") +mmx_commutative_binop(unsigned short,4,&,"pand","") +mmx_commutative_binop(long,2,&,"pand","") +mmx_commutative_binop(unsigned long,2,&,"pand","") +mmx_commutative_binop(long long,1,&,"pand","") +mmx_commutative_binop(unsigned long long,1,&,"pand","") + +//-----------------------------OR-------------------------------- +mmx_commutative_binop(char,8,|,"por","") +mmx_commutative_binop(signed char,8,|,"por","") +mmx_commutative_binop(unsigned char,8,|,"por","") +mmx_commutative_binop(short,4,|,"por","") +mmx_commutative_binop(unsigned short,4,|,"por","") +mmx_commutative_binop(long,2,|,"por","") +mmx_commutative_binop(unsigned long,2,|,"por","") +mmx_commutative_binop(long long,1,|,"por","") +mmx_commutative_binop(unsigned long long,1,|,"por","") + +//-----------------------------XOR-------------------------------- +mmx_commutative_binop(char,8,^,"pxor","") +mmx_commutative_binop(signed char,8,^,"pxor","") +mmx_commutative_binop(unsigned char,8,^,"pxor","") +mmx_commutative_binop(short,4,^,"pxor","") +mmx_commutative_binop(unsigned short,4,^,"pxor","") +mmx_commutative_binop(long,2,^,"pxor","") +mmx_commutative_binop(unsigned long,2,^,"pxor","") +mmx_commutative_binop(long long,1,^,"pxor","") +mmx_commutative_binop(unsigned long long,1,^,"pxor","") + +//-----------------------------NOT-------------------------------- +mmx_binop_const(char,8,~,"pxor","",minus_one); +mmx_binop_const(unsigned char,8,~,"pxor","",minus_one); +mmx_binop_const(signed char,8,~,"pxor","",minus_one); +mmx_binop_const(short,4,~,"pxor","",minus_one); +mmx_binop_const(unsigned short,4,~,"pxor","",minus_one); +mmx_binop_const(long,2,~,"pxor","",minus_one); +mmx_binop_const(unsigned long,2,~,"pxor","",minus_one); +mmx_binop_const(long long,1,~,"pxor","",minus_one); +mmx_binop_const(unsigned long long,1,~,"pxor","",minus_one); + +//-----------------------------negative-------------------------------- +mmx_binop_const(char,8,-,"psubb","",falsed); +mmx_binop_const(unsigned char,8,-,"psubb","",falsed); +mmx_binop_const(signed char,8,-,"psubb","",falsed); +mmx_binop_const(short,4,-,"psubw","",falsed); +mmx_binop_const(unsigned short,4,-,"psubw","",falsed); +mmx_binop_const(long,2,-,"psubd","",falsed); +mmx_binop_const(unsigned long,2,-,"psubd","",falsed); + +//--------------------- assignment ----------------------------------- +mmx_assign(char,8,=,"","") +mmx_assign(unsigned char,8,=,"","") +mmx_assign(signed char,8,=,"","") +mmx_assign(short,4,=,"","") +mmx_assign(unsigned short,4,=,"","") +mmx_assign(long,2,=,"","") +mmx_assign(unsigned long,2,=,"","") +mmx_assign(float,2,=,"","") +mmx_assign(long long,1,=,"","") +mmx_assign(unsigned long long,1,=,"","") +mmx_assign(double,1,=,"","") + +mmx_assign_op(char,8,&=,"pand","") +mmx_assign_op(unsigned char,8,&=,"pand","") +mmx_assign_op(signed char,8,&=,"pand","") +mmx_assign_op(short,4,&=,"pand","") +mmx_assign_op(unsigned short,4,&=,"pand","") +mmx_assign_op(long,2,&=,"pand","") +mmx_assign_op(unsigned long,2,&=,"pand","") +mmx_assign_op(long long,1,&=,"pand","") +mmx_assign_op(unsigned long long,1,&=,"pand","") + +mmx_assign_op(char,8,|=,"por","") +mmx_assign_op(unsigned char,8,|=,"por","") +mmx_assign_op(signed char,8,|=,"por","") +mmx_assign_op(short,4,|=,"por","") +mmx_assign_op(unsigned short,4,|=,"por","") +mmx_assign_op(long,2,|=,"por","") +mmx_assign_op(unsigned long,2,|=,"por","") +mmx_assign_op(long long,1,|=,"por","") +mmx_assign_op(unsigned long long,1,|=,"por","") + +mmx_assign_op(char,8,^=,"pxor","") +mmx_assign_op(unsigned char,8,^=,"pxor","") +mmx_assign_op(signed char,8,^=,"pxor","") +mmx_assign_op(short,4,^=,"pxor","") +mmx_assign_op(unsigned short,4,^=,"pxor","") +mmx_assign_op(long,2,^=,"pxor","") +mmx_assign_op(unsigned long,2,^=,"pxor","") +mmx_assign_op(long long,1,^=,"pxor","") +mmx_assign_op(unsigned long long,1,^=,"pxor","") + +mmx_assign_op(char,8,+=,"paddb","") +mmx_assign_op(unsigned char,8,+=,"paddb","") +mmx_assign_op(signed char,8,+=,"paddb","") +mmx_assign_op(short,4,+=,"paddw","") +mmx_assign_op(unsigned short,4,+=,"paddw","") +mmx_assign_op(long,2,+=,"paddd","") +mmx_assign_op(unsigned long,2,+=,"paddd","") + +mmx_assign_op(char,8,-=,"psubb","") +mmx_assign_op(unsigned char,8,-=,"psubb","") +mmx_assign_op(signed char,8,-=,"psubb","") +mmx_assign_op(short,4,-=,"psubw","") +mmx_assign_op(unsigned short,4,-=,"psubw","") +mmx_assign_op(long,2,-=,"psubd","") +mmx_assign_op(unsigned long,2,-=,"psubd","") + +mmx_assign_op(short,4,*=,"pmullw","") +mmx_assign_op(unsigned short,4,*=,"pmullw","") + +// unfortunately logical ops require more fiddling +// ------------- generic logical ops +// +#define mmx_logical_op(t,n,__op,__op_t,__instr,__conv_ops, __out_spec, __outvar) \ +inline simd::arrtype REF simd::arrtype::operator __op( \ + const simd<__op_t,n>::arrtype &b) const \ +{ \ + register __m64 retval64; \ + register __m32 retval32; \ + register __m16 retval16; \ + __asm__ ( __instr" %2,%1\n\t"__conv_ops"\n" \ + : __out_spec (__outvar) \ + : "y" (b.m64.all), \ + "ym" (m64.all) \ + ); \ + return reinterpret_cast::arrtype &>(__outvar); \ +} + +#define mmx_logical_byteop(t,__op,__op_t,__instr) \ + mmx_logical_op(t,8,__op,__op_t,__instr, \ + "pand _trueb,%1\n" \ + "\tmovq %1,%0", \ + "=y",retval64) + +#define mmx_logical_wordop(t,__op,__op_t,__instr) \ + mmx_logical_op(t,4,__op,__op_t,__instr, \ + "packssdw %1,%1\n" \ + "\tpand _trueb,%1\n" \ + "\tmovd %1,%0", \ + "=r",retval32) + +#define mmx_logical_dwordop(t,__op,__op_t,__instr) \ + mmx_logical_op(t,4,__op,__op_t,__instr, \ + "packssdw %1,%1\n" \ + "\tpacksswb %1,%1\n" \ + "\tpand _trueb,%1\n" \ + "\tmovd %1,%0", \ + "=a",retval16) + +#define mmx_logical_notbyteop(t,__op,__op_t,__instr) \ + mmx_logical_op(t,8,__op,__op_t,__instr, \ + "pandn _trueb,%1\n" \ + "\tmovq %1,%0", \ + "=y",retval64) + +#define mmx_logical_notwordop(t,__op,__op_t,__instr) \ + mmx_logical_op(t,4,__op,__op_t,__instr, \ + "packssdw %1,%1\n" \ + "\tpandn _trueb,%1\n" \ + "\tmovd %1,%0", \ + "=r",retval32) + +#define mmx_logical_notdwordop(t,__op,__op_t,__instr) \ + mmx_logical_op(t,4,__op,__op_t,__instr, \ + "packssdw %1,%1\n" \ + "\tpacksswb %1,%1\n" \ + "\tpandn _trueb,%1\n" \ + "\tmovd %1,%0", \ + "=a",retval16) + +//-----------------------------EQUALS-------------------------------- + +mmx_logical_byteop(char,==,char,"pcmpeqb") +mmx_logical_byteop(unsigned char,==,unsigned char, "pcmpeqb") +mmx_logical_byteop(signed char,==,signed char, "pcmpeqb") + +mmx_logical_wordop(short,==,short,"pcmpeqw") +mmx_logical_wordop(unsigned short,==,unsigned short,"pcmpeqw") + +mmx_logical_dwordop(long,==,long,"pcmpeqd") +mmx_logical_dwordop(unsigned long,==,unsigned long,"pcmpeqd") + +//-----------------------------NOT EQUALS-------------------------------- + +mmx_logical_notbyteop(char,!=,char, "pcmpeqb") +mmx_logical_notbyteop(unsigned char,!=,unsigned char, "pcmpeqb") +mmx_logical_notbyteop(signed char,!=,signed char, "pcmpeqb") + +mmx_logical_notwordop(short,!=,short,"pcmpeqw") +mmx_logical_notwordop(unsigned short,!=,unsigned short,"pcmpeqw") + +mmx_logical_notdwordop(long,!=,long,"pcmpeqd") +mmx_logical_notdwordop(unsigned long,!=,unsigned long,"pcmpeqd") + +//-----------------------------GREATER THAN-------------------------------- +#if (CHAR_MIN<0) +mmx_logical_byteop(char,>,char, "pcmpgtb") +#endif +mmx_logical_byteop(signed char,>,signed char, "pcmpgtb") + +mmx_logical_wordop(short,>,short,"pcmpgtw") + +mmx_logical_dwordop(long,>,long,"pcmpgtd") + + +//-----------------------------LESS THAN OR EQUAL---------------------------- +#if (CHAR_MIN<0) +mmx_logical_notbyteop(char,<=,char, "pcmpgtb") +#endif +mmx_logical_notbyteop(signed char,<=,signed char, "pcmpgtb") + +mmx_logical_notwordop(short,<=,short,"pcmpgtw") + +mmx_logical_notdwordop(long,<=,long,"pcmpgtd") + +//-----------------------------LESS THAN-------------------------------- +#if (CHAR_MIN<0) +mmx_logical_byteop(char,<,char, "pcmpltb") +#endif +mmx_logical_byteop(signed char,<,signed char, "pcmpltb") + +mmx_logical_wordop(short,<,short,"pcmpltw") + +mmx_logical_dwordop(long,<,long,"pcmpltd") + +//-----------------------------GREATER THAN OR EQUAL----------------------- +#if (CHAR_MIN<0) +mmx_logical_notbyteop(char,>=,char, "pcmpltb") +#endif +mmx_logical_notbyteop(signed char,>=,signed char, "pcmpltb") + +mmx_logical_notwordop(short,>=,short,"pcmpltw") + +mmx_logical_notdwordop(long,>=,long,"pcmpltd") + +//-------------------------LOGICAL OR-------------------------------- + +#define mmx_por_macro(t,n) \ +inline simd::arrtype REF simd::arrtype::operator ||(const \ + simd::arrtype &b) const \ +{ \ + return ((*this)|b)!=reinterpret_cast::arrtype &>(falsed); \ +} + +mmx_por_macro(char,8) +mmx_por_macro(unsigned char,8) +mmx_por_macro(signed char,8) + +mmx_por_macro(short,4) +mmx_por_macro(unsigned short,4) + +mmx_por_macro(long,2) +mmx_por_macro(unsigned long,2) + +//-------------------------LOGICAL AND-------------------------------- +#define mmx_pand_macro(t,n) \ +inline simd::arrtype &simd::arrtype::operator &&(const \ + simd::arrtype &b) const \ +{ \ + return ((*this)&b)!=reinterpret_cast::arrtype &>(falsed); \ +} + +mmx_pand_macro(char,8) +mmx_pand_macro(unsigned char,8) +mmx_pand_macro(signed char,8) + +mmx_pand_macro(short,4) +mmx_pand_macro(unsigned short,4) + +mmx_pand_macro(long,2) +mmx_pand_macro(unsigned long,2) + +//-----------------------------LOGICAL NOT-------------------------------- +#define mmx_pnot_macro(t,n) \ +inline simd::arrtype REF simd::arrtype::operator !() const \ +{ \ + return (*this)!=reinterpret_cast::arrtype &>(falsed); \ +} + +mmx_pnot_macro(char,8) +mmx_pnot_macro(unsigned char,8) +mmx_pnot_macro(signed char,8) + +mmx_pnot_macro(short,4) +mmx_pnot_macro(unsigned short,4) + +mmx_pnot_macro(long,2) +mmx_pnot_macro(unsigned long,2) +//---------------------------average---------------------------------- + +#if defined(USE_SSE) || defined(USE_SSE2) || defined(USE_3DNOW) +#define mmx_avg_macro(t,n,instr) \ +inline simd::arrtype REF simd::arrtype::avg( \ + const simd::arrtype &b) const { \ + register __m64 retval64; \ + __asm__ ( instr" %2,%1\n" \ + : "=y" (retval64) \ + : "%0" (m128.all),\ + "ym" (b.m128.all) \ + ); \ + return reinterpret_cast::arrtype &>(retval64); \ +} +#endif + +#if defined(USE_3DNOW) +mmx_avg_macro(unsigned char,8,"pavgusb") +#if (CHAR_MIN==0) +mmx_avg_macro(char,8,"pavgusb") +#endif +#elif defined(USE_SSE) || defined(USE_SSE2) +mmx_avg_macro(unsigned short,4,"pavgw") +mmx_avg_macro(unsigned char,8,"pavgb") +#if (CHAR_MIN==0) +mmx_avg_macro(char,8,"pavgb") +#endif +#endif + +//---------------------------max---------------------------------- + +#if defined(USE_SSE) || defined(USE_SSE2) +#define mmx_max_macro(t,n,instr) \ +inline simd::arrtype REF simd::arrtype::max( \ + const simd::arrtype &b) const { \ + register __m64 retval64; \ + __asm__ ( instr" %2,%1\n" \ + : "=y" (retval64) \ + : "%0" (m128.all), \ + "ym" (b.m128.all) \ + ); \ + return reinterpret_cast::arrtype &>(retval64); \ +} + +#if (CHAR_MIN<0) +mmx_max_macro(char,8,"pmaxsb") +#else +mmx_max_macro(char,8,"pmaxub") +#endif +mmx_max_macro(unsigned char,8,"pmaxub") +mmx_max_macro(signed char,8,"pmaxsb") +mmx_max_macro(short,4,"pmaxsw") +mmx_max_macro(unsigned short,4,"pmaxuw") + +#endif +//---------------------------min---------------------------------- + +#if defined(USE_SSE) || defined(USE_SSE2) +#define mmx_min_macro(t,n,instr) \ +inline simd::arrtype REF simd::arrtype::min( \ + const simd::arrtype &b) const { \ + register __m64 retval64; \ + __asm__ ( instr" %2,%1\n" \ + : "=y" (retval64) \ + : "%0" (m128.all), \ + "ym" (b.m128.all) \ + ); \ + return reinterpret_cast::arrtype &>(retval64); \ +} + +#if (CHAR_MIN<0) +mmx_min_macro(char,8,"pminsb") +#else +mmx_min_macro(char,8,"pminub") +#endif +mmx_min_macro(unsigned char,8,"pminub") +mmx_min_macro(signed char,8,"pminsb") +mmx_min_macro(short,4,"pminsw") +mmx_min_macro(unsigned short,4,"pminuw") + +#endif + +//-----------------------------shuffle--------------------------------------- +#if defined(USE_SSE) || defined(USE_SSE2) +#define mmx_shuffle_macro(t,n) \ +template \ +inline typename simd::arrtype REF shuffle( \ + const typename simd::arrtype &v)\ +{ \ + register __m64 retval64; \ + __asm__ ("pshufw %2,%1,%0\n" : \ + "=y" (retval64) : \ + "ym" (v.m64.all), \ + "i" (((order&0x3000)>>12)| \ + ((order&0x0300)>>6)| \ + (order&0x0030)| \ + ((order&0x0003)<<6)) \ + ); \ + return reinterpret_cast::arrtype REF >(retval64); \ +} + +mmx_shuffle_macro(short,4) +mmx_shuffle_macro(unsigned short,4) +#endif +#undef mmx_shuffle_macro + +#define mmx_shuffle_macro(t,n) \ +template \ +extern typename simd::arrtype REF shuffle( \ + const typename simd::arrtype &v) ; + +#define mmx_spec_shuffle_macro(t,n,order,instr) \ +template <> \ +inline simd::arrtype REF shuffle( \ + const simd::arrtype &v) \ +{ \ + register __m64 retval64; \ + __asm__ (instr" %2,%0\n" : \ + "=y" (retval64) : \ + "0" (v.m64.all) , \ + "ym" (v.m64.all) \ + ); \ + return reinterpret_cast::arrtype REF >(retval64); \ +} + +mmx_spec_shuffle_macro(char,8,0x00112233,"punpcklbw"); +mmx_spec_shuffle_macro(char,8,0x44556677,"punpckhbw"); +mmx_spec_shuffle_macro(char,4,0x0011,"punpcklbw"); +mmx_spec_shuffle_macro(char,4,0x4455,"punpckhbw"); +mmx_spec_shuffle_macro(unsigned char,8,0x00112233,"punpcklbw"); +mmx_spec_shuffle_macro(unsigned char,8,0x44556677,"punpckhbw"); +//mmx_spec_shuffle_macro(unsigned char,4,0x0011,"punpcklbw"); +//mmx_spec_shuffle_macro(unsigned char,4,0x4455,"punpckhbw"); +mmx_spec_shuffle_macro(signed char,8,0x00112233,"punpcklbw"); +mmx_spec_shuffle_macro(signed char,8,0x44556677,"punpckhbw"); +mmx_spec_shuffle_macro(signed char,4,0x0011,"punpcklbw"); +mmx_spec_shuffle_macro(signed char,4,0x4455,"punpckhbw"); + +mmx_spec_shuffle_macro(short,4,0x0011,"punpcklwd"); +mmx_spec_shuffle_macro(short,4,0x2233,"punpckhwd"); +mmx_spec_shuffle_macro(unsigned short,4,0x0011,"punpcklwd"); +mmx_spec_shuffle_macro(unsigned short,4,0x2233,"punpckhwd"); + +mmx_spec_shuffle_macro(long,2,0x00,"punpckldq"); +mmx_spec_shuffle_macro(long,2,0x11,"punpckhdq"); +mmx_spec_shuffle_macro(unsigned long,2,0x00,"punpckldq"); +mmx_spec_shuffle_macro(unsigned long,2,0x11,"punpckhdq"); +mmx_spec_shuffle_macro(float,2,0x00,"punpckldq"); +mmx_spec_shuffle_macro(float,2,0x11,"punpckhdq"); + +//-----------------------------interleave--------------------------------------- +#define mmx_spec_interleave_macro(t,n,order,instr,mask) \ +template <> \ +inline simd::arrtype REF interleave( \ + const simd::arrtype &a,const simd::arrtype &b) \ +{ \ + register __m64 retval64,dummy; \ + __asm__ ("pand %4,%0\n" \ + "\tpand %4,%3\n" \ + "\t"instr" %3,%0\n" : \ + "=y" (retval64),"=y" (dummy) : \ + "0" (a.m64.all) , \ + "1" (b.m64.all), \ + "ym" (mask) \ + ); \ + return reinterpret_cast::arrtype REF >(retval64); \ +} + +mmx_spec_interleave_macro(signed char,8,0x02460246,"packuswb",0x00ff00ff00ff00ffLL); +mmx_spec_interleave_macro(unsigned char,8,0x02460246,"packuswb",0x00ff00ff00ff00ffLL); +mmx_spec_interleave_macro(char,8,0x02460246,"packuswb",0x00ff00ff00ff00ffLL); + +#undef mmx_spec_interleave_macro +#define mmx_spec_interleave_macro(t,n,order,instr,shift_inst) \ +template <> \ +inline simd::arrtype REF interleave( \ + const simd::arrtype &a,const simd::arrtype &b) \ +{ \ + register __m64 retval64,dummy; \ + __asm__ ( \ + shift_inst",%0\n" \ + "\t"shift_inst",%3\n" \ + "\t"instr" %3,%0\n" : \ + "=y" (retval64),"=y" (dummy) : \ + "0" (a.m64.all) , \ + "1" (b.m64.all) \ + ); \ + return reinterpret_cast::arrtype REF >(retval64); \ +} + +mmx_spec_interleave_macro(signed char,8,0x13571357,"packuswb","psraw $8"); +mmx_spec_interleave_macro(unsigned char,8,0x13571357,"packuswb","psraw $8"); +mmx_spec_interleave_macro(char,8,1357135746,"packuswb","psraw $8"); +mmx_spec_interleave_macro(short,4,0x1313,"packssdw","psrad $16"); +mmx_spec_interleave_macro(unsigned short,4,0x1313,"packssdw","psrad $16"); + +#undef mmx_spec_interleave_macro +#define mmx_spec_interleave_macro(t,n,order,instr,shift_inst1,shift_inst2) \ +template <> \ +inline simd::arrtype REF interleave( \ + const simd::arrtype &a,const simd::arrtype &b) \ +{ \ + register __m64 retval64,dummy; \ + __asm__ ( \ + shift_inst1",%0\n" \ + "\t"shift_inst1",%3\n" \ + "\t"shift_inst2",%0\n" \ + "\t"shift_inst2",%3\n" \ + "\t"instr" %3,%0\n" : \ + "=y" (retval64),"=y" (dummy) : \ + "0" (a.m64.all) , \ + "1" (b.m64.all) \ + ); \ + return reinterpret_cast::arrtype REF >(retval64); \ +} +mmx_spec_interleave_macro(short,4,0x0202,"packssdw","pslld $16","psrad $16"); +mmx_spec_interleave_macro(unsigned short,4,0x0202,"packssdw","pslld $16","psrad $16"); + +#undef mmx_spec_interleave_macro +#define mmx_spec_interleave_two(t,n) \ +template \ +inline simd::arrtype REF interleave( \ + const simd::arrtype &a,const simd::arrtype &b) \ +{ \ + register __m64 retval64,dummy; \ + __asm__ ( "psrlq %5,%0\n" \ + "\tpsllq %4,%1\n" \ + "\tpand %1,%0\n" \ + : "=y" (retval64), "=y" (dummy) \ + : "0" (a.m64.all),\ + "y" (b.m64.all),\ + "i" ((order & 1)<<5), \ + "i" (((order ^ 0x10) & 0x10)<<1) \ + ); \ + return reinterpret_cast::arrtype REF >(retval64); \ +} + +mmx_spec_interleave_two(long,2); +mmx_spec_interleave_two(unsigned long,2); +mmx_spec_interleave_two(float,2); + +#define mmx_spec_interleave_four(t,n) \ +template \ +inline simd::arrtype REF interleave( \ + const simd::arrtype &a,const simd::arrtype &b) \ +{ \ + register __m64 tmp1,tmp2,tmp3; \ + static const long long lowd=0x00000000ffffffffLL; \ + static const long long highd=0xffffffff00000000LL; \ + static __m64 retval128[2]; \ + switch (order & 0x3000) { \ + case 0x0000: \ + case 0x1000: \ + tmp1=*reinterpret_cast(&a); \ + break; \ + case 0x2000: \ + case 0x3000: \ + tmp1=*(reinterpret_cast(&a)+1); \ + break; \ + } \ + switch (order & 0x1000) { \ + case 0x0000: \ + __asm__ ( "pand %2,%0" \ + : "=y" (tmp1) \ + : "0" (tmp1), "ym" (lowd)); \ + break; \ + case 0x1000: \ + __asm__ ( "psrlq %2,%0" \ + : "=y" (tmp1) \ + : "0" (tmp1), "i" (32)); \ + break; \ + } \ + switch (order & 0x300) { \ + case 0x000: \ + case 0x100: \ + tmp2=*reinterpret_cast(&a); \ + break; \ + case 0x200: \ + case 0x300: \ + tmp2=*(reinterpret_cast(&a)+1); \ + break; \ + } \ + switch (order & 0x100) { \ + case 0x100: \ + __asm__ ( "pand %2,%0" \ + : "=y" (tmp2) \ + : "0" (tmp2), "ym" (highd)); \ + break; \ + case 0x000: \ + __asm__ ( "psllq %2,%0" \ + : "=y" (tmp2) \ + : "0" (tmp2), "i" (32)); \ + break; \ + } \ + __asm__ ( "por %2,%0" \ + : "=y" (retval128[0]) \ + : "0" (tmp1), "y" (tmp2)); \ + switch (order & 0x30) { \ + case 0x00: \ + case 0x10: \ + tmp3=*reinterpret_cast(&b); \ + break; \ + case 0x20: \ + case 0x30: \ + tmp3=*(reinterpret_cast(&b)+1); \ + break; \ + } \ + switch (order & 0x10) { \ + case 0x00: \ + __asm__ ( "pand %2,%0" \ + : "=y" (tmp3) \ + : "0" (tmp3), "ym" (lowd)); \ + break; \ + case 0x10: \ + __asm__ ( "psrlq %2,%0" \ + : "=y" (tmp3) \ + : "0" (tmp3), "i" (32)); \ + break; \ + } \ + switch (order & 0x3) { \ + case 0x0: \ + case 0x1: \ + tmp2=*reinterpret_cast(&b); \ + break; \ + case 0x2: \ + case 0x3: \ + tmp2=*(reinterpret_cast(&b)+1); \ + break; \ + } \ + switch (order & 0x1) { \ + case 0x1: \ + __asm__ ( "pand %2,%0" \ + : "=y" (tmp2) \ + : "0" (tmp2), "ym" (highd)); \ + break; \ + case 0x0: \ + __asm__ ( "psllq %2,%0" \ + : "=y" (tmp2) \ + : "0" (tmp2), "i" (32)); \ + break; \ + } \ + __asm__ ( "por %2,%0" \ + : "=y" (retval128[1]) \ + : "0" (tmp3), "y" (tmp2)); \ + return reinterpret_cast::arrtype &>(retval128); \ +} + +#if !defined(USE_SSE) && !defined(USE_SSE2) +mmx_spec_interleave_four(long,4); +mmx_spec_interleave_four(unsigned long,4); +mmx_spec_interleave_four(float,4); +#endif + +//---------------------------left shift------------------------------- +inline void mmx_psllw(const vec_m64 *a, int b, vec_m64 *c) { +#ifdef __GNUC__ + __asm__ ("psllw %2,%1\n" + : "=y" (c->all) // outputs into c + : "%0" (a->all), // inputs a from memory + "iy" (b) // inputs b from mms register + ); +#endif +} + +#define _mmx_psllw_macro(t,n) \ +inline simd::arrtype simd::arrtype::operator <<(const int &b) \ + const \ +{ \ + vec_m64 tmp; \ + mmx_psllw(&m64,b,&tmp); \ + return simd::arrtype(tmp); \ +} +_mmx_psllw_macro(short,4) +_mmx_psllw_macro(unsigned short,4) +#undef _mmx_psllw_macro + +inline void mmx_pslleqw(const int a, vec_m64 *c) { +#ifdef __GNUC__ + __asm__ ("psllw %2,%1\n" + "\tmovq %1,%0\n" + : "=m" (c->all) // outputs into c + : "%y" (c->all), // inputs a from memory + "iy" (a) // inputs b from mms register + ); +#endif +} + +#define _mmx_pslleqw_macro(t,n) \ +inline simd::arrtype &simd::arrtype::operator <<=(const int &b) \ +{ \ + mmx_pslleqw(b,&m64); \ + return *this; \ +} +_mmx_pslleqw_macro(short,4) +_mmx_pslleqw_macro(unsigned short,4) +#undef _mmx_pslleqw_macro + +inline void mmx_pslld(const vec_m64 *a, int b, vec_m64 *c) { +#ifdef __GNUC__ + __asm__ ("pslld %2,%1\n" + : "=y" (c->all) // outputs into c + : "%0" (a->all), // inputs a from memory + "iy" (b) // inputs b from mms register + ); +#endif +} + +#define _mmx_pslld_macro(t,n) \ +inline simd::arrtype simd::arrtype::operator <<(const int &b) \ + const \ +{ \ + vec_m64 tmp; \ + mmx_pslld(&m64,b,&tmp); \ + return simd::arrtype(tmp); \ +} +_mmx_pslld_macro(long,2) +_mmx_pslld_macro(unsigned long,2) +#undef _mmx_pslld_macro + +inline void mmx_pslleqd(int a, vec_m64 *c) { +#ifdef __GNUC__ + __asm__ ("pslld %2,%1\n" + "\tmovq %1,%0\n" + : "=m" (c->all) // outputs into c + : "%y" (c->all), // inputs a from memory + "iy" (a) // inputs b from mms register + ); +#endif +} + +#define _mmx_pslleqd_macro(t,n) \ +inline simd::arrtype &simd::arrtype::operator <<=(const int &b) \ +{ \ + mmx_pslleqd(b,&m64); \ + return *this; \ +} +_mmx_pslleqd_macro(long,2) +_mmx_pslleqd_macro(unsigned long,2) +#undef _mmx_pslleqd_macro + +//---------------------------right unsigned shift------------------------------- +inline void mmx_psrlw(const vec_m64 *a, int b, vec_m64 *c) { +#ifdef __GNUC__ + __asm__ ("psrlw %2,%1\n" + : "=y" (c->all) // outputs into c + : "%0" (a->all), // inputs a from memory + "iy" (b) // inputs b from mms register + ); +#endif +} + +#define _mmx_psrlw_macro(t,n) \ +inline simd::arrtype simd::arrtype::operator >>(const int &b) \ + const \ +{ \ + vec_m64 tmp; \ + mmx_psrlw(&m64,b,&tmp); \ + return simd::arrtype(tmp); \ +} +_mmx_psrlw_macro(unsigned short,4) +#undef _mmx_psrlw_macro + +inline void mmx_psrleqw(const int a, vec_m64 *c) { +#ifdef __GNUC__ + __asm__ ("psrlw %2,%1\n" + "\tmovq %1,%0\n" + : "=m" (c->all) // outputs into c + : "%y" (c->all), // inputs a from memory + "iy" (a) // inputs b from mms register + ); +#endif +} + +#define _mmx_psrleqw_macro(t,n) \ +inline simd::arrtype &simd::arrtype::operator >>=(const int &b) \ +{ \ + mmx_psrleqw(b,&m64); \ + return *this; \ +} +_mmx_psrleqw_macro(unsigned short,4) +#undef _mmx_psrleqw_macro + +inline void mmx_psrld(const vec_m64 *a, int b, vec_m64 *c) { +#ifdef __GNUC__ + __asm__ ("psrld %2,%1\n" + : "=y" (c->all) // outputs into c + : "%0" (a->all), // inputs a from memory + "iy" (b) // inputs b from mms register + ); +#endif +} + +#define _mmx_psrld_macro(t,n) \ +inline simd::arrtype simd::arrtype::operator >>(const int &b) \ + const \ +{ \ + vec_m64 tmp; \ + mmx_psrld(&m64,b,&tmp); \ + return simd::arrtype(tmp); \ +} +_mmx_psrld_macro(unsigned long,2) +#undef _mmx_psrld_macro + +inline void mmx_psrleqd(int a, vec_m64 *c) { +#ifdef __GNUC__ + __asm__ ("psrld %2,%1\n" + "\tmovq %1,%0\n" + : "=m" (c->all) // outputs into c + : "%y" (c->all), // inputs a from memory + "iy" (a) // inputs b from mms register + ); +#endif +} + +#define _mmx_psrleqd_macro(t,n) \ +inline simd::arrtype &simd::arrtype::operator >>=(const int &b) \ +{ \ + mmx_psrleqd(b,&m64); \ + return *this; \ +} +_mmx_psrleqd_macro(unsigned long,2) +#undef _mmx_psrleqd_macro + +//---------------------------right signed shift------------------------------- +inline void mmx_psraw(const vec_m64 *a, int b, vec_m64 *c) { +#ifdef __GNUC__ + __asm__ ("psraw %2,%1\n" + : "=y" (c->all) // outputs into c + : "%0" (a->all), // inputs a from memory + "iy" (b) // inputs b from mms register + ); +#endif +} + +#define _mmx_psraw_macro(t,n) \ +inline simd::arrtype simd::arrtype::operator >>(const int &b) \ + const \ +{ \ + vec_m64 tmp; \ + mmx_psraw(&m64,b,&tmp); \ + return simd::arrtype(tmp); \ +} +_mmx_psraw_macro(short,4) +#undef _mmx_psraw_macro + +inline void mmx_psraeqw(const int a, vec_m64 *c) { +#ifdef __GNUC__ + __asm__ ("psraw %2,%1\n" + "\tmovq %1,%0\n" + : "=m" (c->all) // outputs into c + : "%y" (c->all), // inputs a from memory + "iy" (a) // inputs b from mms register + ); +#endif +} + +#define _mmx_psraeqw_macro(t,n) \ +inline simd::arrtype &simd::arrtype::operator >>=(const int &b) \ +{ \ + mmx_psraeqw(b,&m64); \ + return *this; \ +} +_mmx_psraeqw_macro(short,4) +#undef _mmx_psraeqw_macro + +inline void mmx_psrad(const vec_m64 *a, int b, vec_m64 *c) { +#ifdef __GNUC__ + __asm__ ("psrad %2,%1\n" + : "=y" (c->all) // outputs into c + : "%0" (a->all), // inputs a from memory + "iy" (b) // inputs b from mms register + ); +#endif +} + +#define _mmx_psrad_macro(t,n) \ +inline simd::arrtype simd::arrtype::operator >>(const int &b) \ + const \ +{ \ + vec_m64 tmp; \ + mmx_psrad(&m64,b,&tmp); \ + return simd::arrtype(tmp); \ +} +_mmx_psrad_macro(long,2) +#undef _mmx_psrad_macro + +inline void mmx_psraeqd(int a, vec_m64 *c) { +#ifdef __GNUC__ + __asm__ ("psrad %2,%1\n" + "\tmovq %1,%0\n" + : "=m" (c->all) // outputs into c + : "%y" (c->all), // inputs a from memory + "iy" (a) // inputs b from mms register + ); +#endif +} + +#define _mmx_psraeqd_macro(t,n) \ +inline simd::arrtype &simd::arrtype::operator >>=(const int &b) \ +{ \ + mmx_psraeqd(b,&m64); \ + return *this; \ +} +_mmx_psraeqd_macro(long,2) +#undef _mmx_psraeqd_macro + +//-----------------------------ancillary------------------------------------- + +#define _mmx_start_macro(t,n) \ +inline volatile void simd::simd_mode_start() { \ +} +_mmx_start_macro(char,8) +_mmx_start_macro(unsigned char,8) +_mmx_start_macro(signed char,8) +_mmx_start_macro(short,4) +_mmx_start_macro(unsigned short,4) +_mmx_start_macro(long,2) +_mmx_start_macro(unsigned long,2) +_mmx_start_macro(float,2) + +#ifndef USE_3DNOW +#define EMMS "emms\n" +#else +#define EMMS "femms\n" +#endif + +#define _mmx_end_macro(t,n) \ +inline volatile void simd::simd_mode_finish() { \ + __asm__("emms\n" \ + : \ + : \ + : MMX_REGS, FP_STACK \ + ); \ +} +_mmx_end_macro(char,8) +_mmx_end_macro(unsigned char,8) +_mmx_end_macro(signed char,8) +_mmx_end_macro(short,4) +_mmx_end_macro(unsigned short,4) +_mmx_end_macro(long,2) +_mmx_end_macro(unsigned long,2) +_mmx_end_macro(float,2) +#if !defined(USE_SSE) && !defined(USE_SSE2) && !defined(USE_3DNOW) +_mmx_end_macro(float,4) +#endif + +/* + * + * Revision 1.1 2004/09/17 01:42:36 korpela + * initial checkin of test code. + * + */ + diff --git a/vector_lib/ps.cpp b/vector_lib/ps.cpp new file mode 100644 index 0000000..80c2f4e --- /dev/null +++ b/vector_lib/ps.cpp @@ -0,0 +1,23 @@ +#include "../config.h" +#include "simd.h" + +void v_GetPowerSpectrum( + float* FreqData, + float* PowerSpectrum, + int NumDataPoints +) { + int i, j; + + simd::ptr spec(PowerSpectrum),data(FreqData); + + for (i=0,j=0; i < (NumDataPoints*2)/simd::size; i+=2,j++) { + spec[j].prefetchw(); + data[i].prefetch(); + spec[j]=interleave<0x0202>( + data[i]*data[i]+shuffle<0x1032>(data[i]*data[i]), + data[i+1]*data[i+1]+shuffle<0x1032>(data[i+1]*data[i+1]) + ); + + } +} + diff --git a/vector_lib/simd.h b/vector_lib/simd.h new file mode 100644 index 0000000..f0ddbf7 --- /dev/null +++ b/vector_lib/simd.h @@ -0,0 +1,376 @@ +// Copyright 2004 Regents of the University of California +// +// libSIMD++ is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. +// +// libSIMD++ is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along +// with libSIMD++; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// $Id: simd.h,v 1.10.2.1 2007/03/22 00:03:59 korpela Exp $ +// +// Original revision: 28-Jul-2004, Eric J. Korpela +// + +#include +#include +#include +#include + +// HOW TO ALIGN +#if defined(__GNUC__) +#define ALIGN_DEF(x) +#define ALIGN_ATTRIBUTE(x) __attribute__ ((aligned(x))) +#if defined(USE_MMX) || defined(USE_SSE) || \ + defined(USE_SSE2) || defined(USE_3DNOW) +#define REF & +#else +#define REF +#endif +typedef float __m128 __attribute__ ((mode(V4SF))); +typedef int __m64 __attribute__ ((mode(V4HI))); +typedef unsigned long __m32; +typedef unsigned short __m16; +typedef unsigned char __m8; +#define PURE_FUNCTION __attribute__ ((pure)) +#define HAVE__M128 +#define HAVE__M64 +#elif defined(_MSC_VER) +#define REF +#define ALIGN_DEF(x) __declspec(align( x )) +#define ALIGN_ATTRIBUTE(x) +#define PURE_FUNCTION +#else +#define REF +#define ALIGN_DEF(x) +#define ALIGN_ATTRIBUTE(x) +#define PURE_FUNCTION +#endif + + +struct s_m128 { +#ifdef HAVE__M128 + __m128 m128; +#elif (SIZEOF__LONG_DOUBLE)==16 + long double m128 +#elif defined(HAVE_UINT64_T) + uint64_t m128[2]; +#elif defined(HAVE_LONG_LONG) + unsigned long long m128[2]; +#elif defined(HAVE___INT64) + __int64 m128[2]; +#endif +} ALIGN_ATTRIBUTE(16); + +typedef unsigned char pbool; + + +typedef union { + __m8 all ALIGN_ATTRIBUTE(1); + unsigned char c[1] ALIGN_ATTRIBUTE(1); +} vec_m8; + +typedef union { + __m16 all ALIGN_ATTRIBUTE(2); + unsigned short s[1] ALIGN_ATTRIBUTE(2); + unsigned char c[2] ALIGN_ATTRIBUTE(2); + vec_m8 v8[2] ALIGN_ATTRIBUTE(2); +} vec_m16; + +typedef union { + __m32 all ALIGN_ATTRIBUTE(4); + float f[1] ALIGN_ATTRIBUTE(4); + unsigned long l[4/sizeof(long)] ALIGN_ATTRIBUTE(4); + unsigned int i[4/sizeof(int)] ALIGN_ATTRIBUTE(4); + unsigned short s[8/sizeof(short)] ALIGN_ATTRIBUTE(4); + unsigned char c[4] ALIGN_ATTRIBUTE(4); + vec_m8 v8[4] ALIGN_ATTRIBUTE(4); + vec_m16 v16[2] ALIGN_ATTRIBUTE(4); +} vec_m32; + +#if defined(HAVE_UNIT64_T) +typedef uint64_t v_i64; +#elif defined(HAVE_LONG_LONG) +typedef unsigned long long v_i64; +#elif defined(HAVE__INT64) +typedef unsigned _int64 v_i64; +#else +typedef unsigned long v_i64[2]; +#endif + +typedef union { + __m64 all ALIGN_ATTRIBUTE(8); + v_i64 ll[1] ALIGN_ATTRIBUTE(8); + double d[8/sizeof(double)] ALIGN_ATTRIBUTE(8); + float f[8/sizeof(float)] ALIGN_ATTRIBUTE(8); + unsigned long l[8/sizeof(long)] ALIGN_ATTRIBUTE(8); + unsigned int i[8/sizeof(int)] ALIGN_ATTRIBUTE(8); + unsigned short s[8/sizeof(short)] ALIGN_ATTRIBUTE(8); + unsigned char c[8] ALIGN_ATTRIBUTE(8); + vec_m8 v8[8] ALIGN_ATTRIBUTE(8); + vec_m16 v16[4] ALIGN_ATTRIBUTE(8); + vec_m32 v32[2] ALIGN_ATTRIBUTE(8); +} vec_m64; + +typedef union { + __m128 all ALIGN_ATTRIBUTE(16); +#ifdef HAVE__M128 + __m128 m128 ALIGN_ATTRIBUTE(16); +#endif +#ifdef HAVE__M128D + __m128d m128d ALIGN_ATTRIBUTE(16); +#endif +#ifdef HAVE__M128D + __m128i m128i ALIGN_ATTRIBUTE(16); +#endif +#if defined(HAVE_UINT128_T) + uint128_t u128 ALIGN_ATTRIBUTE(16); +#elif defined(HAVE___INT128) + __int128 u128 ALIGN_ATTRIBUTE(16); +#endif +#if defined(HAVE_UINT64_T) + inline operator __m128() const { return *(reinterpret_cast<__m128 *>(this)) }; + uint64_t ll[2] ALIGN_ATTRIBUTE(16); +#elif defined(HAVE_LONG_LONG) + unsigned long long ll[2] ALIGN_ATTRIBUTE(16); +#elif defined(HAVE___INT64) + __int64 ll[2] ALIGN_ATTRIBUTE(16); +#endif +#if defined(HAVE_LONG_DOUBLE) +#if (SIZEOF_LONG_DOUBLE>8) + long double ld[1] ALIGN_ATTRIBUTE(16); +#elif (SIZEOF_LONG_DOUBLE == 8) + long double ld[2] ALIGN_ATTRIBUTE(16); +#endif +#endif + double d[16/sizeof(double)] ALIGN_ATTRIBUTE(16); + float f[16/sizeof(float)] ALIGN_ATTRIBUTE(16); + unsigned long l[16/sizeof(long)] ALIGN_ATTRIBUTE(16); + unsigned int i[16/sizeof(int)] ALIGN_ATTRIBUTE(16); + unsigned short s[16/sizeof(short)] ALIGN_ATTRIBUTE(16); + unsigned char c[16] ALIGN_ATTRIBUTE(16); + vec_m8 v8[16] ALIGN_ATTRIBUTE(16); + vec_m16 v16[8] ALIGN_ATTRIBUTE(16); + vec_m32 v32[4] ALIGN_ATTRIBUTE(16); + vec_m64 v64[2] ALIGN_ATTRIBUTE(16); +} vec_m128; + + + + +// Generic definitions + +template +inline t1 &interpret_as(t0 &a) { return reinterpret_cast(a); } + +template +class simd { + public: + class ptr; + class arrtype; + class arrtype { + public: + const size_t size(T*N); + typedef T array[N] ALIGN_ATTRIBUTE(size); + union { + array v; + vec_m8 m8; + vec_m16 m16; + vec_m32 m32; + vec_m64 m64; + vec_m128 m128; + }; + arrtype(vec_m128 &b) : m128(b) {}; + arrtype(vec_m64 &b) : m64(b) {}; + arrtype(vec_m32 &b) : m32(b) {}; + arrtype(vec_m16 &b) : m16(b) {}; + arrtype(vec_m8 &b) : m8(b) {}; + arrtype(__m128 &b) : m128(reinterpret_cast(b)) {}; + arrtype(const typename simd::arrtype &b); + arrtype() {} ; + arrtype(const T &m); + void prefetch() const PURE_FUNCTION; + void prefetchw() const PURE_FUNCTION; + + inline T &operator [](int i) {return v[i];} + // binary operators +#define binop(__op,t) \ + arrtype REF operator __op(const arrtype &b) const PURE_FUNCTION; \ + arrtype operator __op(const t &n) const PURE_FUNCTION; + binop(+,T) + binop(-,T) + binop(*,T) + binop(/,T) + binop(&,T) + binop(^,T) + binop(|,T) + binop(%,T) + binop(<<,int) + binop(>>,int) +#undef binop +#define bool_binop(__op,t) \ + typename simd::arrtype REF operator __op(const typename \ + simd::arrtype &b) const PURE_FUNCTION; \ + typename simd::arrtype operator __op(const T &n) const PURE_FUNCTION; + bool_binop(&&,T) + bool_binop(||,T) + bool_binop(==,T) + bool_binop(!=,T) + bool_binop(<,T) + bool_binop(>,T) + bool_binop(<=,T) + bool_binop(>=,T) + // unary operators + arrtype REF operator +() const { return *this; }; + arrtype REF operator -() const PURE_FUNCTION; + arrtype REF operator ~() const PURE_FUNCTION; + typename simd::arrtype REF operator !() const PURE_FUNCTION; + //arrtype operator *() const; + ptr operator &() { return ptr((void *)this); }; + // assignment operators + arrtype &operator =(const arrtype &b); + arrtype &operator =(const T &b); + arrtype &operator +=(const arrtype &b); + arrtype &operator +=(const T &b); + arrtype &operator -=(const arrtype &b); + arrtype &operator -=(const T &b); + arrtype &operator *=(const arrtype &b); + arrtype &operator *=(const T &b); + arrtype &operator /=(const arrtype &b); + arrtype &operator /=(const T &b); + arrtype &operator &=(const arrtype &b); + arrtype &operator &=(const T &b); + arrtype &operator ^=(const arrtype &b); + arrtype &operator ^=(const T &b); + arrtype &operator |=(const arrtype &b); + arrtype &operator |=(const T &b); + arrtype &operator %=(const arrtype &b); + arrtype &operator %=(const T &b); + arrtype &operator <<=(const arrtype &b); + arrtype &operator <<=(const int &b); + arrtype &operator >>=(const arrtype &b); + arrtype &operator >>=(const int &b); + // other functions + arrtype REF sqrt() const PURE_FUNCTION; + arrtype REF aprx_sqrt() const PURE_FUNCTION; + arrtype REF rsqrt() const PURE_FUNCTION; + arrtype REF aprx_rsqrt() const PURE_FUNCTION; + arrtype REF recip() const PURE_FUNCTION; + arrtype REF aprx_recip() const PURE_FUNCTION; + arrtype REF max(const arrtype &b) const PURE_FUNCTION; + arrtype REF min(const arrtype &b) const PURE_FUNCTION; + arrtype REF avg(const arrtype &b) const PURE_FUNCTION; + arrtype REF splat(const int &b) const PURE_FUNCTION; + // conversion operators + operator typename simd::arrtype() const; + operator __m128() { return *(reinterpret_cast<__m128 *>(this)); } ; + }; + arrtype data; + static const size_t size; + static const size_t nbits; + static volatile void simd_mode_start(); + static volatile void simd_mode_finish(); + class ptr { + private: + union { + unsigned char *p; + arrtype *v; + }; + public: + inline operator void *() const { return (void *)p; }; + inline void *addr() const { return (void *)p; }; + inline ptr(void *a) : p((unsigned char *)a) {}; + inline ptr operator +(int i) const + { return ptr(p+i*(N*sizeof(T))); }; + inline ptr operator -(int i) const + { return ptr(p-i*(N*sizeof(T))); }; + inline off_t operator -(simd::ptr &pp) const + { return (p-pp.p)/(N*sizeof(T)); }; + inline ptr &operator ++() + { p+=(N*sizeof(T)); return *this; }; + inline ptr operator ++(int i) + { register void *z(p); p+=(N*sizeof(T)); return z; }; + inline ptr &operator --() + { p-=(N*sizeof(T)); return *this; }; + inline ptr operator --(int i) + { register void *z(p); p-=(N*sizeof(T)); return z; }; + inline ptr operator +=(int i) + { return p+=(i*N*sizeof(T)); }; + inline ptr operator -=(int i) + { return p-=(i*N*sizeof(T)); }; + inline arrtype &operator *(); + inline const arrtype &operator [](const int n) const { + return static_cast(*(const arrtype *)(p+n*N*sizeof(T))); + }; + inline arrtype &operator [](const int n) { + return static_cast(*(arrtype *)(p+n*N*sizeof(T))); + }; + }; +}; + +template +const size_t simd::size=n*sizeof(t); + +template +const size_t simd::nbits=n*sizeof(t)*CHAR_BIT; + +template +typename simd::arrtype &shuffle(const typename simd::arrtype &v) + PURE_FUNCTION; + + +// generics to fill in the missing stuff +#include "generics.h" +// stuff for specific processors +#ifdef USE_MMX +#include "mmx.h" +#elif defined(USE_SSE) +#include "sse.h" +#elif defined(USE_SSE2) +#include "sse2.h" +#elif defined(USE_3DNOW) +#include "3dnow.h" +#elif defined(USE_ALTIVEC) +#include "altivec.h" +#elif defined(USE_VIS) +#include "vis.h" +#elif defined(USE_VIS2) +#include "vis2.h" +#endif +#include "more_generics.h" + + +typedef simd::arrtype double2; +typedef simd::arrtype longlong2; +typedef simd::arrtype ulonglong2; +typedef simd::arrtype float4; +typedef simd::arrtype long4; +typedef simd::arrtype ulong4; +typedef simd::arrtype short8; +typedef simd::arrtype ushort8; +typedef simd::arrtype char16; +typedef simd::arrtype uchar16; +typedef simd::arrtype schar16; + +typedef simd::arrtype float2; +typedef simd::arrtype long2; +typedef simd::arrtype ulong2; +typedef simd::arrtype short4; +typedef simd::arrtype ushort4; +typedef simd::arrtype char8; +typedef simd::arrtype uchar8; +typedef simd::arrtype schar8; + +typedef simd::arrtype short2; +typedef simd::arrtype ushort2; +typedef simd::arrtype char4; +typedef simd::arrtype uchar4; +typedef simd::arrtype schar4; + diff --git a/vector_lib/sse.h b/vector_lib/sse.h new file mode 100644 index 0000000..fa7b985 --- /dev/null +++ b/vector_lib/sse.h @@ -0,0 +1,364 @@ +// Copyright 2004 Regents of the University of California +// +// libSIMD++ is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. +// +// libSIMD++ is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along +// with libSIMD++; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// $Id: sse.h,v 1.11.2.1 2007/03/22 00:04:00 korpela Exp $ +// +// Specific template instances for SSE supported SIMD routines. This file +// is included from "simd.h" +// +// Original revision: 28-Jul-2004, Eric J. Korpela +// + +#include "mmx.h" + +#ifdef __GNUC__ +// register int retval128 __asm__("xmm7") __attribute__ ((mode(V4SF))); +#endif + +static const float zeros[4]={0,0,0,0}; +static const float ones[4]={1,1,1,1}; +static const float twos[4]={2,2,2,2}; +static const float threes[4]={3,3,3,3}; +static const float halves[4]={0.5,0.5,0.5,0.5}; +typedef enum { + eq=0, + lt, + leq, + gt, + geq, + unordered, + ne, + nlt, + nleq, + ngt, + ngeq, + ordered +} __sse_cond_code; + +static const unsigned long cmpps_results[16]={ + 0x00000000, + 0x00000001, + 0x00000100, + 0x00000101, + 0x00010000, + 0x00010001, + 0x00010100, + 0x00010101, + 0x01000000, + 0x01000001, + 0x01000100, + 0x01000101, + 0x01010000, + 0x01010001, + 0x01010100, + 0x01010101 +}; + +// First lets do the easy operators...... +//--------------------- binary operators------------------------------------- +#define sse_deref(t,n) \ +inline simd::arrtype REF simd::ptr::operator *() { \ + return reinterpret_cast::arrtype REF>(*(__m128 *)(v)); \ +} + +sse_deref(float,4) + +#define sse_array_deref(t,n) \ +inline simd::arrtype REF simd::ptr::operator [](int i) { \ + return reinterpret_cast::arrtype REF >(*((__m128 *)(v)+i)); \ +} + +sse_array_deref(float,4) + +#define sse_commutative_binop(t,n,__op,__instr,__followup_instr) \ +inline simd::arrtype REF simd::arrtype::operator __op( \ + const simd::arrtype &b) const \ +{ \ + register __m128 retval128; \ + __asm__ ( __instr " %2,%1\n" __followup_instr \ + : "=x" (retval128) \ + : "%0" (m128.all) , \ + "xm" (b.m128.all) \ + ); \ + return reinterpret_cast::arrtype REF >(retval128); \ +} + +#define sse_noncomm_binop(t,n,__op,__instr,__followup_instr) \ +inline simd::arrtype REF simd::arrtype::operator __op( \ + const simd::arrtype &b) const \ +{ \ + register __m128 retval128; \ + __asm__ ( __instr " %2,%1\n" __followup_instr \ + : "=x" (retval128) \ + : "0" (m128.all) , \ + "xm" (b.m128.all) \ + ); \ + return reinterpret_cast::arrtype REF >(retval128); \ +} + +#define sse_binop_const(t,n,__op,__instr,__followup_instr, __const_operand) \ +inline simd::arrtype REF simd::arrtype::operator __op() const \ +{ \ + register __m128 retval128; \ + __asm__ ( __instr " %2,%1\n" __followup_instr \ + : "=x" (retval128) \ + : "0" (__const_operand) , \ + "xm" (m128.all) \ + ); \ + return reinterpret_cast::arrtype REF >(retval128); \ +} + +#define sse_assign(t,n,__instr,__followup_instr) \ +inline simd::arrtype &simd::arrtype::operator =( \ + const simd::arrtype &b) \ +{ \ + __asm__ ( "/* nada */" \ + : "=x" (m128.all) \ + : "0" (b.m128.all) \ + ); \ + return *this; \ +} + +#define sse_assign_op(t,n,__op,__instr,__followup_instr) \ +inline simd::arrtype &simd::arrtype::operator __op( \ + const simd::arrtype &b) \ +{ \ + __asm__ ( __instr " %1,%0\n" __followup_instr \ + : "=x" (m128.all) \ + : "xm" (b.m128.all) \ + ); \ + return *this; \ +} + +#define sse_comp_op(t,n,__op,__op_mnem) \ +inline simd::arrtype REF simd::arrtype::operator __op(const \ + simd::arrtype &b) const \ +{ \ + register __m32 retval32; \ + __asm__ ( "cmpps %3,%2,%1\n" \ + "\tmovmskps %1,%0\n" \ + "\tmovl %4(%0),%0\n" \ + : "=r" (retval32) \ + : "%x" (m128.all), \ + "xm" (b.m128.all), \ + "i" (__op_mnem), \ + "m" (cmpps_results) \ + ); \ + return reinterpret_cast::arrtype REF>(retval32); \ +} + +sse_commutative_binop(float,4,+,"addps","") +sse_commutative_binop(float,4,*,"mulps","") + +sse_noncomm_binop(float,4,-,"subps","") +sse_noncomm_binop(float,4,/,"divps","") + +sse_binop_const(float,4,-,"subps","",zeros) + +sse_assign(float,4,"movaps","") +sse_assign_op(float,4,+=,"addps","") +sse_assign_op(float,4,*=,"mulps","") +sse_assign_op(float,4,-=,"subps","") +sse_assign_op(float,4,/=,"divps","") + +sse_comp_op(float,4,==,eq) +sse_comp_op(float,4,>,gt) +sse_comp_op(float,4,<,lt) +sse_comp_op(float,4,>=,geq) +sse_comp_op(float,4,<=,leq) +sse_comp_op(float,4,!=,ne) + +//-----------------------------sqrt-------------------------------- + +#define sse_sqrtps_macro(t,n) \ +inline simd::arrtype REF simd::arrtype::sqrt() \ + const \ +{ \ + register __m128 retval128; \ + __asm__ ( "sqrtps %1,%0\n" \ + : "=x" (retval128) \ + : "xm" (m128.all) \ + ); \ + return reinterpret_cast::arrtype &>(retval128); \ +} + +sse_sqrtps_macro(float,4) + +//-----------------------------reciprocal-------------------------------- + + +#define sse_rcpps_macro(t,n) \ +inline simd::arrtype REF simd::arrtype::aprx_recip() \ + const \ +{ \ + register __m128 retval128; \ + __asm__ ( "rcpps %1,%0\n" \ + : "=x" (retval128) \ + : "xm" (m128.all) \ + ); \ + return reinterpret_cast::arrtype REF>(retval128); \ +} +sse_rcpps_macro(float,4) + +//-----------------------------reciprocal sqrt-------------------------------- + +#define sse_rsqrtps_macro(t,n) \ +inline simd::arrtype REF simd::arrtype::aprx_rsqrt() \ + const \ +{ \ + register __m128 retval128; \ + __asm__ ( "rsqrtps %1,%0\n" \ + : "=x" (retval128) \ + : "xm" (m128.all) \ + ); \ + return reinterpret_cast::arrtype REF>(retval128); \ +} +sse_rsqrtps_macro(float,4) + +//-----------------------------max-------------------------------- + +#define sse_maxps_macro(t,n) \ +inline simd::arrtype REF simd::arrtype::max(const simd::arrtype &b) \ + const \ +{ \ + register __m128 retval128; \ + __asm__ ( "maxps %2,%1\n" \ + : "=x" (retval128) \ + : "%0" (m128.all), \ + "xm" (b.m128.all) \ + ); \ + return reinterpret_cast::arrtype REF>(retval128); \ +} +sse_maxps_macro(float,4) + +//-----------------------------min-------------------------------- + +#define sse_minps_macro(t,n) \ +inline simd::arrtype REF simd::arrtype::min(const simd::arrtype &b) \ + const \ +{ \ + register __m128 retval128; \ + __asm__ ( "minps %2,%1\n" \ + : "=x" (retval128) \ + : "%0" (m128.all), \ + "xm" (b.m128.all) \ + ); \ + return reinterpret_cast::arrtype REF>(retval128); \ +} +sse_minps_macro(float,4) + +//-----------------------------shuffle--------------------------------------- + +#define sse_shuffle_macro(t,n) \ +template \ +inline typename simd::arrtype REF shuffle(const typename simd::arrtype &v)\ +{ \ + register __m128 retval128; \ + __asm__ ("shufps %2,%1,%0\n" : \ + "=x" (retval128) : \ + "xm" (v.m128.all), \ + "i" (((order&0x3000)>>12)| \ + ((order&0x0300)>>6)| \ + (order&0x0030)| \ + ((order&0x0003)<<6)), \ + "0" (v.m128.all) \ + ); \ + return reinterpret_cast::arrtype REF >(retval128); \ +} + +sse_shuffle_macro(float,4) +sse_shuffle_macro(long,4) +sse_shuffle_macro(unsigned long,4) + +//-----------------------------interleave----------------------------------- +#define sse_interleave_macro(t,n) \ +template \ +inline typename simd::arrtype REF interleave( \ + const typename simd::arrtype &a, \ + const typename simd::arrtype &b) \ +{ \ + register __m128 retval128; \ + __asm__ ("shufps %3,%2,%0\n" : \ + "=x" (retval128) :\ + "0" (a.m128.all), \ + "xm" (b.m128.all), \ + "i" (((order & 0x3000)>>12)| \ + ((order & 0x0300)>> 6)| \ + ((order & 0x0030) )| \ + ((order & 0x0003)<<6 )) \ + ); \ + return reinterpret_cast::arrtype REF >(retval128); \ +} + +sse_interleave_macro(float,4) + +//-----------------------------ancillary------------------------------------- + +#define sse_start_macro(t,n) \ +inline volatile void simd::simd_mode_start() { \ +} +sse_start_macro(float,4) + +#ifndef USE_3DNOW +#define EMMS "emms\n" +#else +#define EMMS "femms\n" +#endif + +#define sse_end_macro(t,n) \ +inline volatile void simd::simd_mode_finish() { \ + __asm__(EMMS \ + : \ + : \ + : FP_STACK,MMX_REGS \ + ); \ +} +sse_end_macro(float,4) + +template +inline void simd::arrtype::prefetch() const { + __asm__ ( "prefetch %0" + : + : "m" (*(reinterpret_cast(this)+64))); +} + +template +inline void simd::arrtype::prefetchw() const { + __asm__ ( "prefetch %0" + : + : "m" (*(reinterpret_cast(this)+64))); +} + + +/* + * + * $Log: sse.h,v $ + * Revision 1.11.2.1 2007/03/22 00:04:00 korpela + * *** empty log message *** + * + * Revision 1.11 2004/12/08 00:19:23 korpela + * Fixed a signedness mismatch in pulsefind.cpp. + * Let win-config.h know that "glut.h" exists. + * Reduced windows includes to only "windows.h" in bmplib.cpp + * Added some prefetch support to the experimental vector template library. + * + * + * Revision 1.1 2004/09/17 01:42:36 korpela + * initial checkin of test code. + * + * + */ + diff --git a/vector_lib/t1.cpp b/vector_lib/t1.cpp new file mode 100644 index 0000000..08de45e --- /dev/null +++ b/vector_lib/t1.cpp @@ -0,0 +1,59 @@ +#include "../config.h" +#include "simd.h" +typedef float sah_complex[2]; + +sah_complex FreqData[512] __attribute__ ((aligned(16)))={{ 0,1},{2,3},{4,5},{6,7},{8,9},{1,1},{.70710678118654752440,.70710678118654752440}} ; +float PowerSpectrum[512] __attribute__ ((aligned(16))); + + +int main(void) { + register simd::ptr p3(PowerSpectrum); +register __m128 xmm0 asm("xmm0"); +register __m128 xmm1 asm("xmm1"); +register __m128 xmm2 asm("xmm2"); +register __m128 xmm3 asm("xmm3"); +register __m128 xmm4 asm("xmm4"); +register __m128 xmm5 asm("xmm5"); +register __m128 xmm6 asm("xmm6"); +register __m128 xmm7 asm("xmm7"); + for (unsigned int i=0;i<512;i+=4) { + /* + register simd::ptr p1(FreqData+i*2),p2(FreqData+i*2+4); + f1=(*p1*(*p1))+shuffle<0x1032>(*p1*(*p1)); + f2=(*p2*(*p2))+shuffle<0x1032>(*p2*(*p2)); + p3[i]=interleave<0x0202>(f1,f2); + */ + __asm__ ( + "mulps %0,%0\n\t" + "mulps %4,%4\n\t" + "movaps %0,%1\n\t" + "movaps %4,%2\n\t" + "shufps $177,%0,%0\n\t" + "shufps $177,%4,%4\n\t" + "addps %1,%0\n\t" + "addps %2,%4\n\t" + "shufps $136,%4,%0\n\t" + : "=x" (*(__m128 *)(&(PowerSpectrum[i]))), "=x" (xmm6), "=x" (xmm7) + : "0" (*(__m128 *)(&(FreqData[i]))), "x" (*(__m128 *)(&(FreqData[i+2]))) + ) ; +/* + * __asm__ ( + "mulps %0,%0\n\t" + "mulps %4,%4\n\t" + "movaps %0,%1\n\t" + "movaps %4,%2\n\t" + "shufps $177,%0,%0\n\t" + "shufps $177,%4,%4\n\t" + "addps %1,%0\n\t" + "addps %2,%4\n\t" + "shufps $136,%4,%0\n\t" + : "=x" (*(__m128 *)(PowerSpectrum+i)),"=x" (xmm6),"=x" (xmm7) + : "0" (*(__m128 *)(FreqData+i*2)), "x" (*(__m128 *)(FreqData+i*2+4)) + ) ; +*/ + } + simd::simd_mode_finish(); + printf("%f %f %f %f %f %f %f %f\n",PowerSpectrum[0],PowerSpectrum[1],PowerSpectrum[2],PowerSpectrum[3],PowerSpectrum[4],PowerSpectrum[5],PowerSpectrum[6],PowerSpectrum[7]); + return(0); +} + diff --git a/vector_lib/vis.h b/vector_lib/vis.h new file mode 100644 index 0000000..6356497 --- /dev/null +++ b/vector_lib/vis.h @@ -0,0 +1,1080 @@ +// Copyright 2004 Regents of the University of California +// +// libSIMD++ is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2, or (at your option) any later +// version. +// +// libSIMD++ is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along +// with libSIMD++; see the file COPYING. If not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// $Id: vis.h,v 1.1 2004/11/11 00:30:02 korpela Exp $ +// +// Specific template instances for VIS supported SIMD routines. This file +// is included from "simd.h" +// +// Original revision: 28-Jul-2004, Eric J. Korpela +// + + +static const char trueb[8]={1,1,1,1,1,1,1,1}; +static const short truew[4]={1,1,1,1}; +static const long trued[2]={1,1}; +static const v_i64 falsed=0; +static const v_i64 minus_one=(v_i64)(-1); +static const v_i64 hi_d=(v_i64)0xffffffff00000000LL; +static const v_i64 lo_d=(v_i64)0x00000000ffffffffLL; +static struct _gsr { + unsigned long align:3,scale:5,not_used:17,irnd:2,im:1,unused:4; +} gsr; +static unsigned long bmask; + + +// First lets do the easy operators...... +//--------------------- binary operators ------------------------------------- + +#define vis_deref(t,n) \ +inline simd::arrtype &simd::ptr::operator *() { \ + return reinterpret_cast::arrtype &>(*(__m64 *)(v)); \ +} + +vis_deref(char,8) +vis_deref(signed char,8) +vis_deref(unsigned char,8) +vis_deref(short,4) +vis_deref(unsigned short,4) +vis_deref(long,2) +vis_deref(unsigned long,2) + +#define vis_array_deref(t,n) \ +inline simd::arrtype &simd::ptr::operator [](int i) { \ + return reinterpret_cast::arrtype &>(*((__m64 *)(v)+i)); \ +} + +vis_deref(char,8) +vis_deref(signed char,8) +vis_deref(unsigned char,8) +vis_array_deref(short,4) +vis_array_deref(unsigned short,4) +vis_array_deref(long,2) +vis_array_deref(unsigned long,2) + +#define vis_commutative_binop(t,n,__op,__instr,__followup_instr) \ +inline simd::arrtype REF simd::arrtype::operator __op( \ + const simd::arrtype &b) const \ +{ \ + register __m64 retval64; \ + __asm__ ( __instr " %3,%2,%1\n" __followup_instr \ + : "=f" (retval64) \ + : "%f" (m64.all) , \ + "f" (b.m64.all) \ + ); \ + return reinterpret_cast::arrtype & >(retval64); \ +} + +#define vis_noncomm_binop(t,n,__op,__instr,__followup_instr) \ +inline simd::arrtype REF simd::arrtype::operator __op( \ + const simd::arrtype &b) const \ +{ \ + register __m64 retval64; \ + __asm__ ( __instr " %2,%3,%1\n" __followup_instr \ + : "=f" (retval64) \ + : "f" (m64.all) , \ + "f" (b.m64.all) \ + ); \ + return reinterpret_cast::arrtype & >(retval64); \ +} + +#define vis_unop(t,n,__op,__instr,__followup_instr) \ +inline simd::arrtype REF simd::arrtype::operator __op() const \ +{ \ + register __m64 retval64; \ + __asm__ ( __instr " %2,%1\n" __followup_instr \ + : "=f" (retval64) \ + : "f" (m64.all) \ + ); \ + return reinterpret_cast::arrtype & >(retval64); \ +} + +#define vis_assign(t,n,__op,__instr,__followup_instr) \ +inline simd::arrtype &simd::arrtype::operator __op( \ + const simd::arrtype &b) \ +{ \ + __asm__ volatile ( "" \ + : "=f" (m64.all) \ + : "f" (b.m64.all) \ + ); \ + return *static_cast::arrtype *>(this); \ +} + +//--------------------- addition ------------------------------------- + +vis_commutative_binop(short,4,+,"fpadd16","") +vis_commutative_binop(unsigned short,4,+,"fpadd16","") +vis_commutative_binop(long,2,+,"fpadd32","") +vis_commutative_binop(unsigned long,2,+,"fpadd32","") + +//---------------------- multiplication ------------------------------ + +inline simd::arrtype REF simd::arrtype::operator *( + const simd::arrtype &b) +{ + register __m64 retval64,high,low; + __asm__ ( "fmul8sux16 %3,%4,%1\n" + "\tfmul8ulx16 %3,%4,%2\n" + "\tfpadd16 %1,%2,%3\n" + : "=f" (retval), "=f" (high), + "=f" (low) + : "%f" (m64.all), + "f" (b.m64.all) + ); + return reinterpret_cast::arrtype &>(retval64); +} + +//---------------------- subtraction --------------------------------- +vis_noncomm_binop(short,4,-,"fpsub16","") +vis_noncomm_binop(unsigned short,4,-,"fpsub16","") +vis_noncomm_binop(long,2,-,"fpsub32","") +vis_noncomm_binop(unsigned long,2,-,"fpsub32","") + +//-----------------------------AND-------------------------------- +vis_commutative_binop(char,8,&,"fand","") +vis_commutative_binop(signed char,8,&,"fand","") +vis_commutative_binop(unsigned char,8,&,"fand","") +vis_commutative_binop(short,4,&,"fand","") +vis_commutative_binop(unsigned short,4,&,"fand","") +vis_commutative_binop(long,2,&,"fand","") +vis_commutative_binop(unsigned long,2,&,"fand","") +vis_commutative_binop(long long,1,&,"fand","") +vis_commutative_binop(unsigned long long,1,&,"fand","") + +//-----------------------------OR-------------------------------- +vis_commutative_binop(char,8,|,"for","") +vis_commutative_binop(signed char,8,|,"for","") +vis_commutative_binop(unsigned char,8,|,"for","") +vis_commutative_binop(short,4,|,"for","") +vis_commutative_binop(unsigned short,4,|,"for","") +vis_commutative_binop(long,2,|,"for","") +vis_commutative_binop(unsigned long,2,|,"for","") +vis_commutative_binop(long long,1,|,"for","") +vis_commutative_binop(unsigned long long,1,|,"for","") + +//-----------------------------XOR-------------------------------- +vis_commutative_binop(char,8,^,"fxor","") +vis_commutative_binop(signed char,8,^,"fxor","") +vis_commutative_binop(unsigned char,8,^,"fxor","") +vis_commutative_binop(short,4,^,"fxor","") +vis_commutative_binop(unsigned short,4,^,"fxor","") +vis_commutative_binop(long,2,^,"fxor","") +vis_commutative_binop(unsigned long,2,^,"fxor","") +vis_commutative_binop(long long,1,^,"fxor","") +vis_commutative_binop(unsigned long long,1,^,"fxor","") + +//-----------------------------NOT-------------------------------- +vis_unop(char,8,~,"fnot1",""); +vis_unop(unsigned char,8,~,"fnot1",""); +vis_unop(signed char,8,~,"fnot1",""); +vis_unop(short,4,~,"fnot1",""); +vis_unop(unsigned short,4,~,"fnot1",""); +vis_unop(long,2,~,"fnot1",""); +vis_unop(unsigned long,2,~,"fnot1",""); +vis_unop(long long,1,~,"fnot1",""); +vis_unop(unsigned long long,1,~,"fnot1",""); + +//-----------------------------negative-------------------------------- +vis_binop_const(short,4,-,"fpsub16","",falsed); +vis_binop_const(unsigned short,4,-,"fpsub16","",falsed); +vis_binop_const(long,2,-,"fpsub32","",falsed); +vis_binop_const(unsigned long,2,-,"fpsubd32","",falsed); + +//--------------------- assignment ----------------------------------- +vis_assign(char,8,=,"","") +vis_assign(unsigned char,8,=,"","") +vis_assign(signed char,8,=,"","") +vis_assign(short,4,=,"","") +vis_assign(unsigned short,4,=,"","") +vis_assign(long,2,=,"","") +vis_assign(unsigned long,2,=,"","") +vis_assign(float,2,=,"","") +vis_assign(long long,1,=,"","") +vis_assign(unsigned long long,1,=,"","") +vis_assign(double,1,=,"","") + +vis_assign(char,8,&=,"fand","") +vis_assign(unsigned char,8,&=,"fand","") +vis_assign(signed char,8,&=,"fand","") +vis_assign(short,4,&=,"fand","") +vis_assign(unsigned short,4,&=,"fand","") +vis_assign(long,2,&=,"fand","") +vis_assign(unsigned long,2,&=,"fand","") +vis_assign(long long,1,&=,"fand","") +vis_assign(unsigned long long,1,&=,"fand","") + +vis_assign(char,8,|=,"for","") +vis_assign(unsigned char,8,|=,"for","") +vis_assign(signed char,8,|=,"for","") +vis_assign(short,4,|=,"for","") +vis_assign(unsigned short,4,|=,"for","") +vis_assign(long,2,|=,"for","") +vis_assign(unsigned long,2,|=,"for","") +vis_assign(long long,1,|=,"for","") +vis_assign(unsigned long long,1,|=,"for","") + +vis_assign(char,8,^=,"fxor","") +vis_assign(unsigned char,8,^=,"fxor","") +vis_assign(signed char,8,^=,"fxor","") +vis_assign(short,4,^=,"fxor","") +vis_assign(unsigned short,4,^=,"fxor","") +vis_assign(long,2,^=,"fxor","") +vis_assign(unsigned long,2,^=,"fxor","") +vis_assign(long long,1,^=,"fxor","") +vis_assign(unsigned long long,1,^=,"fxor","") + +vis_assign(short,4,+=,"fpadd16","") +vis_assign(unsigned short,4,+=,"fpadd16","") +vis_assign(long,2,+=,"fpadd32","") +vis_assign(unsigned long,2,+=,"fpadd32","") + +vis_assign(short,4,-=,"fpsub16","") +vis_assign(unsigned short,4,-=,"fpsub16","") +vis_assign(long,2,-=,"fpsub32","") +vis_assign(unsigned long,2,-=,"fpsub32","") + +//vis_assign(short,4,*=,"pmullw","") +//vis_assign(unsigned short,4,*=,"pmullw","") + +// unfortunately logical ops require more fiddling +// ------------- generic logical ops +// +#define vis_logical_op(t,n,__op,__op_t,__instr,__conv_ops, __out_spec, __outvar) \ +inline simd::arrtype REF simd::arrtype::operator __op( \ + const simd<__op_t,n>::arrtype &b) const \ +{ \ + register __m64 retval64; \ + register __m32 retval32; \ + register __m16 retval16; \ + __asm__ ( __instr" %2,%1\n\t"__conv_ops"\n" \ + : __out_spec (__outvar) \ + : "y" (b.m64.all), \ + "ym" (m64.all) \ + ); \ + return reinterpret_cast::arrtype &>(__outvar); \ +} + +#define vis_logical_byteop(t,__op,__op_t,__instr) \ + vis_logical_op(t,8,__op,__op_t,__instr, \ + "pand _trueb,%1\n" \ + "\tmovq %1,%0", \ + "=y",retval64) + +#define vis_logical_wordop(t,__op,__op_t,__instr) \ + vis_logical_op(t,4,__op,__op_t,__instr, \ + "packssdw %1,%1\n" \ + "\tpand _trueb,%1\n" \ + "\tmovd %1,%0", \ + "=r",retval32) + +#define vis_logical_dwordop(t,__op,__op_t,__instr) \ + vis_logical_op(t,4,__op,__op_t,__instr, \ + "packssdw %1,%1\n" \ + "\tpacksswb %1,%1\n" \ + "\tpand _trueb,%1\n" \ + "\tmovd %1,%0", \ + "=a",retval16) + +#define vis_logical_notbyteop(t,__op,__op_t,__instr) \ + vis_logical_op(t,8,__op,__op_t,__instr, \ + "pandn _trueb,%1\n" \ + "\tmovq %1,%0", \ + "=y",retval64) + +#define vis_logical_notwordop(t,__op,__op_t,__instr) \ + vis_logical_op(t,4,__op,__op_t,__instr, \ + "packssdw %1,%1\n" \ + "\tpandn _trueb,%1\n" \ + "\tmovd %1,%0", \ + "=r",retval32) + +#define vis_logical_notdwordop(t,__op,__op_t,__instr) \ + vis_logical_op(t,4,__op,__op_t,__instr, \ + "packssdw %1,%1\n" \ + "\tpacksswb %1,%1\n" \ + "\tpandn _trueb,%1\n" \ + "\tmovd %1,%0", \ + "=a",retval16) + +//-----------------------------EQUALS-------------------------------- + +vis_logical_byteop(char,==,char,"pcmpeqb") +vis_logical_byteop(unsigned char,==,unsigned char, "pcmpeqb") +vis_logical_byteop(signed char,==,signed char, "pcmpeqb") + +vis_logical_wordop(short,==,short,"pcmpeqw") +vis_logical_wordop(unsigned short,==,unsigned short,"pcmpeqw") + +vis_logical_dwordop(long,==,long,"pcmpeqd") +vis_logical_dwordop(unsigned long,==,unsigned long,"pcmpeqd") + +//-----------------------------NOT EQUALS-------------------------------- + +vis_logical_notbyteop(char,!=,char, "pcmpeqb") +vis_logical_notbyteop(unsigned char,!=,unsigned char, "pcmpeqb") +vis_logical_notbyteop(signed char,!=,signed char, "pcmpeqb") + +vis_logical_notwordop(short,!=,short,"pcmpeqw") +vis_logical_notwordop(unsigned short,!=,unsigned short,"pcmpeqw") + +vis_logical_notdwordop(long,!=,long,"pcmpeqd") +vis_logical_notdwordop(unsigned long,!=,unsigned long,"pcmpeqd") + +//-----------------------------GREATER THAN-------------------------------- +#if (CHAR_MIN<0) +vis_logical_byteop(char,>,char, "pcmpgtb") +#endif +vis_logical_byteop(signed char,>,signed char, "pcmpgtb") + +vis_logical_wordop(short,>,short,"pcmpgtw") + +vis_logical_dwordop(long,>,long,"pcmpgtd") + + +//-----------------------------LESS THAN OR EQUAL---------------------------- +#if (CHAR_MIN<0) +vis_logical_notbyteop(char,<=,char, "pcmpgtb") +#endif +vis_logical_notbyteop(signed char,<=,signed char, "pcmpgtb") + +vis_logical_notwordop(short,<=,short,"pcmpgtw") + +vis_logical_notdwordop(long,<=,long,"pcmpgtd") + +//-----------------------------LESS THAN-------------------------------- +#if (CHAR_MIN<0) +vis_logical_byteop(char,<,char, "pcmpltb") +#endif +vis_logical_byteop(signed char,<,signed char, "pcmpltb") + +vis_logical_wordop(short,<,short,"pcmpltw") + +vis_logical_dwordop(long,<,long,"pcmpltd") + +//-----------------------------GREATER THAN OR EQUAL----------------------- +#if (CHAR_MIN<0) +vis_logical_notbyteop(char,>=,char, "pcmpltb") +#endif +vis_logical_notbyteop(signed char,>=,signed char, "pcmpltb") + +vis_logical_notwordop(short,>=,short,"pcmpltw") + +vis_logical_notdwordop(long,>=,long,"pcmpltd") + +//-------------------------LOGICAL OR-------------------------------- + +#define vis_por_macro(t,n) \ +inline simd::arrtype REF simd::arrtype::operator ||(const \ + simd::arrtype &b) const \ +{ \ + return ((*this)|b)!=reinterpret_cast::arrtype &>(falsed); \ +} + +vis_por_macro(char,8) +vis_por_macro(unsigned char,8) +vis_por_macro(signed char,8) + +vis_por_macro(short,4) +vis_por_macro(unsigned short,4) + +vis_por_macro(long,2) +vis_por_macro(unsigned long,2) + +//-------------------------LOGICAL AND-------------------------------- +#define vis_pand_macro(t,n) \ +inline simd::arrtype &simd::arrtype::operator &&(const \ + simd::arrtype &b) const \ +{ \ + return ((*this)&b)!=reinterpret_cast::arrtype &>(falsed); \ +} + +vis_pand_macro(char,8) +vis_pand_macro(unsigned char,8) +vis_pand_macro(signed char,8) + +vis_pand_macro(short,4) +vis_pand_macro(unsigned short,4) + +vis_pand_macro(long,2) +vis_pand_macro(unsigned long,2) + +//-----------------------------LOGICAL NOT-------------------------------- +#define vis_pnot_macro(t,n) \ +inline simd::arrtype REF simd::arrtype::operator !() const \ +{ \ + return (*this)!=reinterpret_cast::arrtype &>(falsed); \ +} + +vis_pnot_macro(char,8) +vis_pnot_macro(unsigned char,8) +vis_pnot_macro(signed char,8) + +vis_pnot_macro(short,4) +vis_pnot_macro(unsigned short,4) + +vis_pnot_macro(long,2) +vis_pnot_macro(unsigned long,2) +//---------------------------average---------------------------------- + +#if defined(USE_SSE) || defined(USE_SSE2) || defined(USE_3DNOW) +#define vis_avg_macro(t,n,instr) \ +inline simd::arrtype REF simd::arrtype::avg( \ + const simd::arrtype &b) const { \ + register __m64 retval64; \ + __asm__ ( instr" %2,%1\n" \ + : "=y" (retval64) \ + : "%0" (m128.all),\ + "ym" (b.m128.all) \ + ); \ + return reinterpret_cast::arrtype &>(retval64); \ +} +#endif + +#if defined(USE_3DNOW) +vis_avg_macro(unsigned char,8,"pavgusb") +#if (CHAR_MIN==0) +vis_avg_macro(char,8,"pavgusb") +#endif +#elif defined(USE_SSE) || defined(USE_SSE2) +vis_avg_macro(unsigned short,4,"pavgw") +vis_avg_macro(unsigned char,8,"pavgb") +#if (CHAR_MIN==0) +vis_avg_macro(char,8,"pavgb") +#endif +#endif + +//---------------------------max---------------------------------- + +#if defined(USE_SSE) || defined(USE_SSE2) +#define vis_max_macro(t,n,instr) \ +inline simd::arrtype REF simd::arrtype::max( \ + const simd::arrtype &b) const { \ + register __m64 retval64; \ + __asm__ ( instr" %2,%1\n" \ + : "=y" (retval64) \ + : "%0" (m128.all), \ + "ym" (b.m128.all) \ + ); \ + return reinterpret_cast::arrtype &>(retval64); \ +} + +#if (CHAR_MIN<0) +vis_max_macro(char,8,"pmaxsb") +#else +vis_max_macro(char,8,"pmaxub") +#endif +vis_max_macro(unsigned char,8,"pmaxub") +vis_max_macro(signed char,8,"pmaxsb") +vis_max_macro(short,4,"pmaxsw") +vis_max_macro(unsigned short,4,"pmaxuw") + +#endif +//---------------------------min---------------------------------- + +#if defined(USE_SSE) || defined(USE_SSE2) +#define vis_min_macro(t,n,instr) \ +inline simd::arrtype REF simd::arrtype::min( \ + const simd::arrtype &b) const { \ + register __m64 retval64; \ + __asm__ ( instr" %2,%1\n" \ + : "=y" (retval64) \ + : "%0" (m128.all), \ + "ym" (b.m128.all) \ + ); \ + return reinterpret_cast::arrtype &>(retval64); \ +} + +#if (CHAR_MIN<0) +vis_min_macro(char,8,"pminsb") +#else +vis_min_macro(char,8,"pminub") +#endif +vis_min_macro(unsigned char,8,"pminub") +vis_min_macro(signed char,8,"pminsb") +vis_min_macro(short,4,"pminsw") +vis_min_macro(unsigned short,4,"pminuw") + +#endif + +//-----------------------------shuffle--------------------------------------- +#if defined(USE_SSE) || defined(USE_SSE2) +#define vis_shuffle_macro(t,n) \ +template \ +inline typename simd::arrtype REF shuffle( \ + const typename simd::arrtype &v)\ +{ \ + register __m64 retval64; \ + __asm__ ("pshufw %2,%1,%0\n" : \ + "=y" (retval64) : \ + "ym" (v.m64.all), \ + "i" (((order&0x3000)>>12)| \ + ((order&0x0300)>>6)| \ + (order&0x0030)| \ + ((order&0x0003)<<6)) \ + ); \ + return reinterpret_cast::arrtype REF >(retval64); \ +} + +vis_shuffle_macro(short,4) +vis_shuffle_macro(unsigned short,4) +#endif +#undef vis_shuffle_macro + +#define vis_shuffle_macro(t,n) \ +template \ +extern typename simd::arrtype REF shuffle( \ + const typename simd::arrtype &v) ; + +#define vis_spec_shuffle_macro(t,n,order,instr) \ +template <> \ +inline simd::arrtype REF shuffle( \ + const simd::arrtype &v) \ +{ \ + register __m64 retval64; \ + __asm__ (instr" %2,%0\n" : \ + "=y" (retval64) : \ + "0" (v.m64.all) , \ + "ym" (v.m64.all) \ + ); \ + return reinterpret_cast::arrtype REF >(retval64); \ +} + +vis_spec_shuffle_macro(char,8,0x00112233,"punpcklbw"); +vis_spec_shuffle_macro(char,8,0x44556677,"punpckhbw"); +vis_spec_shuffle_macro(char,4,0x0011,"punpcklbw"); +vis_spec_shuffle_macro(char,4,0x4455,"punpckhbw"); +vis_spec_shuffle_macro(unsigned char,8,0x00112233,"punpcklbw"); +vis_spec_shuffle_macro(unsigned char,8,0x44556677,"punpckhbw"); +//vis_spec_shuffle_macro(unsigned char,4,0x0011,"punpcklbw"); +//vis_spec_shuffle_macro(unsigned char,4,0x4455,"punpckhbw"); +vis_spec_shuffle_macro(signed char,8,0x00112233,"punpcklbw"); +vis_spec_shuffle_macro(signed char,8,0x44556677,"punpckhbw"); +vis_spec_shuffle_macro(signed char,4,0x0011,"punpcklbw"); +vis_spec_shuffle_macro(signed char,4,0x4455,"punpckhbw"); + +vis_spec_shuffle_macro(short,4,0x0011,"punpcklwd"); +vis_spec_shuffle_macro(short,4,0x2233,"punpckhwd"); +vis_spec_shuffle_macro(unsigned short,4,0x0011,"punpcklwd"); +vis_spec_shuffle_macro(unsigned short,4,0x2233,"punpckhwd"); + +vis_spec_shuffle_macro(long,2,0x00,"punpckldq"); +vis_spec_shuffle_macro(long,2,0x11,"punpckhdq"); +vis_spec_shuffle_macro(unsigned long,2,0x00,"punpckldq"); +vis_spec_shuffle_macro(unsigned long,2,0x11,"punpckhdq"); +vis_spec_shuffle_macro(float,2,0x00,"punpckldq"); +vis_spec_shuffle_macro(float,2,0x11,"punpckhdq"); + +//-----------------------------interleave--------------------------------------- +#define vis_spec_interleave_macro(t,n,order,instr,mask) \ +template <> \ +inline simd::arrtype REF interleave( \ + const simd::arrtype &a,const simd::arrtype &b) \ +{ \ + register __m64 retval64,dummy; \ + __asm__ ("pand %4,%0\n" \ + "\tpand %4,%3\n" \ + "\t"instr" %3,%0\n" : \ + "=y" (retval64),"=y" (dummy) : \ + "0" (a.m64.all) , \ + "1" (b.m64.all), \ + "ym" (mask) \ + ); \ + return reinterpret_cast::arrtype REF >(retval64); \ +} + +vis_spec_interleave_macro(signed char,8,0x02460246,"packuswb",0x00ff00ff00ff00ffLL); +vis_spec_interleave_macro(unsigned char,8,0x02460246,"packuswb",0x00ff00ff00ff00ffLL); +vis_spec_interleave_macro(char,8,0x02460246,"packuswb",0x00ff00ff00ff00ffLL); + +#undef vis_spec_interleave_macro +#define vis_spec_interleave_macro(t,n,order,instr,shift_inst) \ +template <> \ +inline simd::arrtype REF interleave( \ + const simd::arrtype &a,const simd::arrtype &b) \ +{ \ + register __m64 retval64,dummy; \ + __asm__ ( \ + shift_inst",%0\n" \ + "\t"shift_inst",%3\n" \ + "\t"instr" %3,%0\n" : \ + "=y" (retval64),"=y" (dummy) : \ + "0" (a.m64.all) , \ + "1" (b.m64.all) \ + ); \ + return reinterpret_cast::arrtype REF >(retval64); \ +} + +vis_spec_interleave_macro(signed char,8,0x13571357,"packuswb","psraw $8"); +vis_spec_interleave_macro(unsigned char,8,0x13571357,"packuswb","psraw $8"); +vis_spec_interleave_macro(char,8,1357135746,"packuswb","psraw $8"); +vis_spec_interleave_macro(short,4,0x1313,"packssdw","psrad $16"); +vis_spec_interleave_macro(unsigned short,4,0x1313,"packssdw","psrad $16"); + +#undef vis_spec_interleave_macro +#define vis_spec_interleave_macro(t,n,order,instr,shift_inst1,shift_inst2) \ +template <> \ +inline simd::arrtype REF interleave( \ + const simd::arrtype &a,const simd::arrtype &b) \ +{ \ + register __m64 retval64,dummy; \ + __asm__ ( \ + shift_inst1",%0\n" \ + "\t"shift_inst1",%3\n" \ + "\t"shift_inst2",%0\n" \ + "\t"shift_inst2",%3\n" \ + "\t"instr" %3,%0\n" : \ + "=y" (retval64),"=y" (dummy) : \ + "0" (a.m64.all) , \ + "1" (b.m64.all) \ + ); \ + return reinterpret_cast::arrtype REF >(retval64); \ +} +vis_spec_interleave_macro(short,4,0x0202,"packssdw","pslld $16","psrad $16"); +vis_spec_interleave_macro(unsigned short,4,0x0202,"packssdw","pslld $16","psrad $16"); + +#undef vis_spec_interleave_macro +#define vis_spec_interleave_two(t,n) \ +template \ +inline simd::arrtype REF interleave( \ + const simd::arrtype &a,const simd::arrtype &b) \ +{ \ + register __m64 retval64,dummy; \ + __asm__ ( "psrlq %5,%0\n" \ + "\tpsllq %4,%1\n" \ + "\tpand %1,%0\n" \ + : "=y" (retval64), "=y" (dummy) \ + : "0" (a.m64.all),\ + "y" (b.m64.all),\ + "i" ((order & 1)<<5), \ + "i" (((order ^ 0x10) & 0x10)<<1) \ + ); \ + return reinterpret_cast::arrtype REF >(retval64); \ +} + +vis_spec_interleave_two(long,2); +vis_spec_interleave_two(unsigned long,2); +vis_spec_interleave_two(float,2); + +#define vis_spec_interleave_four(t,n) \ +template \ +inline simd::arrtype REF interleave( \ + const simd::arrtype &a,const simd::arrtype &b) \ +{ \ + register __m64 tmp1,tmp2,tmp3; \ + static const long long lowd=0x00000000ffffffffLL; \ + static const long long highd=0xffffffff00000000LL; \ + static __m64 retval128[2]; \ + switch (order & 0x3000) { \ + case 0x0000: \ + case 0x1000: \ + tmp1=*reinterpret_cast(&a); \ + break; \ + case 0x2000: \ + case 0x3000: \ + tmp1=*(reinterpret_cast(&a)+1); \ + break; \ + } \ + switch (order & 0x1000) { \ + case 0x0000: \ + __asm__ ( "pand %2,%0" \ + : "=y" (tmp1) \ + : "0" (tmp1), "ym" (lowd)); \ + break; \ + case 0x1000: \ + __asm__ ( "psrlq %2,%0" \ + : "=y" (tmp1) \ + : "0" (tmp1), "i" (32)); \ + break; \ + } \ + switch (order & 0x300) { \ + case 0x000: \ + case 0x100: \ + tmp2=*reinterpret_cast(&a); \ + break; \ + case 0x200: \ + case 0x300: \ + tmp2=*(reinterpret_cast(&a)+1); \ + break; \ + } \ + switch (order & 0x100) { \ + case 0x100: \ + __asm__ ( "pand %2,%0" \ + : "=y" (tmp2) \ + : "0" (tmp2), "ym" (highd)); \ + break; \ + case 0x000: \ + __asm__ ( "psllq %2,%0" \ + : "=y" (tmp2) \ + : "0" (tmp2), "i" (32)); \ + break; \ + } \ + __asm__ ( "por %2,%0" \ + : "=y" (retval128[0]) \ + : "0" (tmp1), "y" (tmp2)); \ + switch (order & 0x30) { \ + case 0x00: \ + case 0x10: \ + tmp3=*reinterpret_cast(&b); \ + break; \ + case 0x20: \ + case 0x30: \ + tmp3=*(reinterpret_cast(&b)+1); \ + break; \ + } \ + switch (order & 0x10) { \ + case 0x00: \ + __asm__ ( "pand %2,%0" \ + : "=y" (tmp3) \ + : "0" (tmp3), "ym" (lowd)); \ + break; \ + case 0x10: \ + __asm__ ( "psrlq %2,%0" \ + : "=y" (tmp3) \ + : "0" (tmp3), "i" (32)); \ + break; \ + } \ + switch (order & 0x3) { \ + case 0x0: \ + case 0x1: \ + tmp2=*reinterpret_cast(&b); \ + break; \ + case 0x2: \ + case 0x3: \ + tmp2=*(reinterpret_cast(&b)+1); \ + break; \ + } \ + switch (order & 0x1) { \ + case 0x1: \ + __asm__ ( "pand %2,%0" \ + : "=y" (tmp2) \ + : "0" (tmp2), "ym" (highd)); \ + break; \ + case 0x0: \ + __asm__ ( "psllq %2,%0" \ + : "=y" (tmp2) \ + : "0" (tmp2), "i" (32)); \ + break; \ + } \ + __asm__ ( "por %2,%0" \ + : "=y" (retval128[1]) \ + : "0" (tmp3), "y" (tmp2)); \ + return reinterpret_cast::arrtype &>(retval128); \ +} + +vis_spec_interleave_four(long,4); +vis_spec_interleave_four(unsigned long,4); +vis_spec_interleave_four(float,4); + +//---------------------------left shift------------------------------- +inline void vis_psllw(const vec_m64 *a, int b, vec_m64 *c) { +#ifdef __GNUC__ + __asm__ ("psllw %2,%1\n" + : "=y" (c->all) // outputs into c + : "%0" (a->all), // inputs a from memory + "iy" (b) // inputs b from mms register + ); +#endif +} + +#define _vis_psllw_macro(t,n) \ +inline simd::arrtype simd::arrtype::operator <<(const int &b) \ + const \ +{ \ + vec_m64 tmp; \ + vis_psllw(&m64,b,&tmp); \ + return simd::arrtype(tmp); \ +} +_vis_psllw_macro(short,4) +_vis_psllw_macro(unsigned short,4) +#undef _vis_psllw_macro + +inline void vis_pslleqw(const int a, vec_m64 *c) { +#ifdef __GNUC__ + __asm__ ("psllw %2,%1\n" + "\tmovq %1,%0\n" + : "=m" (c->all) // outputs into c + : "%y" (c->all), // inputs a from memory + "iy" (a) // inputs b from mms register + ); +#endif +} + +#define _vis_pslleqw_macro(t,n) \ +inline simd::arrtype &simd::arrtype::operator <<=(const int &b) \ +{ \ + vis_pslleqw(b,&m64); \ + return *this; \ +} +_vis_pslleqw_macro(short,4) +_vis_pslleqw_macro(unsigned short,4) +#undef _vis_pslleqw_macro + +inline void vis_pslld(const vec_m64 *a, int b, vec_m64 *c) { +#ifdef __GNUC__ + __asm__ ("pslld %2,%1\n" + : "=y" (c->all) // outputs into c + : "%0" (a->all), // inputs a from memory + "iy" (b) // inputs b from mms register + ); +#endif +} + +#define _vis_pslld_macro(t,n) \ +inline simd::arrtype simd::arrtype::operator <<(const int &b) \ + const \ +{ \ + vec_m64 tmp; \ + vis_pslld(&m64,b,&tmp); \ + return simd::arrtype(tmp); \ +} +_vis_pslld_macro(long,2) +_vis_pslld_macro(unsigned long,2) +#undef _vis_pslld_macro + +inline void vis_pslleqd(int a, vec_m64 *c) { +#ifdef __GNUC__ + __asm__ ("pslld %2,%1\n" + "\tmovq %1,%0\n" + : "=m" (c->all) // outputs into c + : "%y" (c->all), // inputs a from memory + "iy" (a) // inputs b from mms register + ); +#endif +} + +#define _vis_pslleqd_macro(t,n) \ +inline simd::arrtype &simd::arrtype::operator <<=(const int &b) \ +{ \ + vis_pslleqd(b,&m64); \ + return *this; \ +} +_vis_pslleqd_macro(long,2) +_vis_pslleqd_macro(unsigned long,2) +#undef _vis_pslleqd_macro + +//---------------------------right unsigned shift------------------------------- +inline void vis_psrlw(const vec_m64 *a, int b, vec_m64 *c) { +#ifdef __GNUC__ + __asm__ ("psrlw %2,%1\n" + : "=y" (c->all) // outputs into c + : "%0" (a->all), // inputs a from memory + "iy" (b) // inputs b from mms register + ); +#endif +} + +#define _vis_psrlw_macro(t,n) \ +inline simd::arrtype simd::arrtype::operator >>(const int &b) \ + const \ +{ \ + vec_m64 tmp; \ + vis_psrlw(&m64,b,&tmp); \ + return simd::arrtype(tmp); \ +} +_vis_psrlw_macro(unsigned short,4) +#undef _vis_psrlw_macro + +inline void vis_psrleqw(const int a, vec_m64 *c) { +#ifdef __GNUC__ + __asm__ ("psrlw %2,%1\n" + "\tmovq %1,%0\n" + : "=m" (c->all) // outputs into c + : "%y" (c->all), // inputs a from memory + "iy" (a) // inputs b from mms register + ); +#endif +} + +#define _vis_psrleqw_macro(t,n) \ +inline simd::arrtype &simd::arrtype::operator >>=(const int &b) \ +{ \ + vis_psrleqw(b,&m64); \ + return *this; \ +} +_vis_psrleqw_macro(unsigned short,4) +#undef _vis_psrleqw_macro + +inline void vis_psrld(const vec_m64 *a, int b, vec_m64 *c) { +#ifdef __GNUC__ + __asm__ ("psrld %2,%1\n" + : "=y" (c->all) // outputs into c + : "%0" (a->all), // inputs a from memory + "iy" (b) // inputs b from mms register + ); +#endif +} + +#define _vis_psrld_macro(t,n) \ +inline simd::arrtype simd::arrtype::operator >>(const int &b) \ + const \ +{ \ + vec_m64 tmp; \ + vis_psrld(&m64,b,&tmp); \ + return simd::arrtype(tmp); \ +} +_vis_psrld_macro(unsigned long,2) +#undef _vis_psrld_macro + +inline void vis_psrleqd(int a, vec_m64 *c) { +#ifdef __GNUC__ + __asm__ ("psrld %2,%1\n" + "\tmovq %1,%0\n" + : "=m" (c->all) // outputs into c + : "%y" (c->all), // inputs a from memory + "iy" (a) // inputs b from mms register + ); +#endif +} + +#define _vis_psrleqd_macro(t,n) \ +inline simd::arrtype &simd::arrtype::operator >>=(const int &b) \ +{ \ + vis_psrleqd(b,&m64); \ + return *this; \ +} +_vis_psrleqd_macro(unsigned long,2) +#undef _vis_psrleqd_macro + +//---------------------------right signed shift------------------------------- +inline void vis_psraw(const vec_m64 *a, int b, vec_m64 *c) { +#ifdef __GNUC__ + __asm__ ("psraw %2,%1\n" + : "=y" (c->all) // outputs into c + : "%0" (a->all), // inputs a from memory + "iy" (b) // inputs b from mms register + ); +#endif +} + +#define _vis_psraw_macro(t,n) \ +inline simd::arrtype simd::arrtype::operator >>(const int &b) \ + const \ +{ \ + vec_m64 tmp; \ + vis_psraw(&m64,b,&tmp); \ + return simd::arrtype(tmp); \ +} +_vis_psraw_macro(short,4) +#undef _vis_psraw_macro + +inline void vis_psraeqw(const int a, vec_m64 *c) { +#ifdef __GNUC__ + __asm__ ("psraw %2,%1\n" + "\tmovq %1,%0\n" + : "=m" (c->all) // outputs into c + : "%y" (c->all), // inputs a from memory + "iy" (a) // inputs b from mms register + ); +#endif +} + +#define _vis_psraeqw_macro(t,n) \ +inline simd::arrtype &simd::arrtype::operator >>=(const int &b) \ +{ \ + vis_psraeqw(b,&m64); \ + return *this; \ +} +_vis_psraeqw_macro(short,4) +#undef _vis_psraeqw_macro + +inline void vis_psrad(const vec_m64 *a, int b, vec_m64 *c) { +#ifdef __GNUC__ + __asm__ ("psrad %2,%1\n" + : "=y" (c->all) // outputs into c + : "%0" (a->all), // inputs a from memory + "iy" (b) // inputs b from mms register + ); +#endif +} + +#define _vis_psrad_macro(t,n) \ +inline simd::arrtype simd::arrtype::operator >>(const int &b) \ + const \ +{ \ + vec_m64 tmp; \ + vis_psrad(&m64,b,&tmp); \ + return simd::arrtype(tmp); \ +} +_vis_psrad_macro(long,2) +#undef _vis_psrad_macro + +inline void vis_psraeqd(int a, vec_m64 *c) { +#ifdef __GNUC__ + __asm__ ("psrad %2,%1\n" + "\tmovq %1,%0\n" + : "=m" (c->all) // outputs into c + : "%y" (c->all), // inputs a from memory + "iy" (a) // inputs b from mms register + ); +#endif +} + +#define _vis_psraeqd_macro(t,n) \ +inline simd::arrtype &simd::arrtype::operator >>=(const int &b) \ +{ \ + vis_psraeqd(b,&m64); \ + return *this; \ +} +_vis_psraeqd_macro(long,2) +#undef _vis_psraeqd_macro + +//-----------------------------ancillary------------------------------------- + +#define _vis_start_macro(t,n) \ +inline volatile void simd::simd_mode_start() { \ +} +_vis_start_macro(char,8) +_vis_start_macro(unsigned char,8) +_vis_start_macro(signed char,8) +_vis_start_macro(short,4) +_vis_start_macro(unsigned short,4) +_vis_start_macro(long,2) +_vis_start_macro(unsigned long,2) +_vis_start_macro(float,2) + +#ifndef USE_3DNOW +#define EMMS "emms\n" +#else +#define EMMS "femms\n" +#endif + +#define _vis_end_macro(t,n) \ +inline volatile void simd::simd_mode_finish() { \ + __asm__("emms\n" \ + : \ + : \ + : MMX_REGS, FP_STACK \ + ); \ +} +_vis_end_macro(char,8) +_vis_end_macro(unsigned char,8) +_vis_end_macro(signed char,8) +_vis_end_macro(short,4) +_vis_end_macro(unsigned short,4) +_vis_end_macro(long,2) +_vis_end_macro(unsigned long,2) +_vis_end_macro(float,2) +#if !defined(USE_SSE) && !defined(USE_SSE2) && !defined(USE_3DNOW) +_vis_end_macro(float,4) +#endif + +/* + * + * Revision 1.1 2004/09/17 01:42:36 korpela + * initial checkin of test code. + * + */ + diff --git a/win_build/win_version.h b/win_build/win_version.h new file mode 100644 index 0000000..28fbdc8 --- /dev/null +++ b/win_build/win_version.h @@ -0,0 +1,5 @@ +/* SETI@home major version number */ +#define VERSION_MAJOR 5 + +/* SETI@home minor version number */ +#define VERSION_MINOR 17 -- 2.30.2

    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%0A#c^9t>16ZZ;%oU8!sun@_ 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 MW}>;zi6-y +#include +#include +#include +#include +#include +#include +#include + +#include "splitparms.h" +#include "splittypes.h" +#include "splitter.h" +#include "message.h" + +int tapebuffd; +char tapebufname[30]; + +void delbuffer(void) { + munmap((char *)tapebuffer,TAPE_BUFFER_SIZE); + close(tapebuffd); + unlink(tapebufname); +} + +void delbuffer_sig(int i) { + munmap((char *)tapebuffer,TAPE_BUFFER_SIZE); + close(tapebuffd); + unlink(tapebufname); + exit(1); +} + + + +void makebuffers(unsigned char **tapebuffer) { + char buf[1024]; +/* + * Allocate temp files for tape and wu buffers. Memory mapping these + * files will prevent us from running out of virtual memory + */ +/* sprintf(tapebufname,"tape%d",getpid()); + + if ((tapebuffd=open(tapebufname,O_RDWR|O_CREAT,0777))==-1) { + fprintf(stderr,"Unable to open temp file!\n"); + fprintf(errorlog,"Unable to open temp file!\n"); + exit(EXIT_FAILURE); + } + + if (ftruncate(tapebuffd,TAPE_BUFFER_SIZE) == -1) { + fprintf(stderr,"ftruncate failure\n"); + fprintf(stderr," errno=%d\n",errno); + fprintf(errorlog,"ftruncate failure\n"); + fprintf(errorlog," errno=%d\n",errno); + exit(EXIT_FAILURE); + } + + if (((*tapebuffer= + mmap(0,TAPE_BUFFER_SIZE,PROT_READ|PROT_WRITE,MAP_SHARED,tapebuffd,0))==(char *)-1)) + { + fprintf(stderr,"mmap failure\n"); + fprintf(errorlog,"mmap failure\n"); + exit(EXIT_FAILURE); + } + + atexit(delbuffer); + signal(SIGINT,delbuffer_sig); +*/ + if (!(*tapebuffer=(unsigned char *)malloc(TAPE_BUFFER_SIZE))) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"unable to allocate memory for tape buffer\n"); + exit(0); + } +} + +/* + * $Log: makebufs.cpp,v $ + * Revision 1.3.2.2 2006/12/14 22:24:39 korpela + * *** empty log message *** + * + * Revision 1.3.2.1 2006/01/13 00:37:57 korpela + * Moved splitter to using standard BOINC logging mechanisms. All stderr now + * goes to "error.log" + * + * Added command line parameters "-iterations=" (number of workunit groups to + * create before exiting), "-trigger_file_path=" (path to the splitter_stop trigger + * file. Default is /disks/setifiler1/wutape/tapedir/splitter_stop). + * + * Reduced deadlines by a factor of three. We now need a 30 MFLOP machine to meet + * the deadline. + * + * Revision 1.3 2004/06/16 20:57:18 jeffc + * *** empty log message *** + * + * Revision 1.2 2003/09/11 18:53:38 korpela + * *** empty log message *** + * + * Revision 1.1 2003/07/29 20:35:42 korpela + * + * renames .C files to .cpp + * + * Revision 1.1 2003/06/03 00:16:13 korpela + * + * Initial splitter under CVS control. + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.3 1998/12/14 23:41:44 korpela + * *** empty log message *** + * + * Revision 2.2 1998/11/02 21:20:58 korpela + * Added signal handler for removal of temporary files on SIGINT. + * + * Revision 2.1 1998/11/02 16:41:21 korpela + * Minor Change. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.4 1998/10/30 20:26:03 korpela + * Bug Fixes. Now mostly working. + * + * Revision 1.3 1998/10/27 00:55:43 korpela + * Bug Fixes + * + * Revision 1.2 1998/10/20 20:40:54 korpela + * Removed wu buffer. + * + * Revision 1.1 1998/10/19 19:01:56 korpela + * Initial revision + * + */ diff --git a/splitter/makebufs.h b/splitter/makebufs.h new file mode 100644 index 0000000..3e1aa59 --- /dev/null +++ b/splitter/makebufs.h @@ -0,0 +1,38 @@ +/* + * makebufs.h + * + * Creates temporary files and buffers for use in processing.... + * + * $Id: makebufs.h,v 1.1 2003/06/03 00:16:14 korpela Exp $ + * + */ + +#ifndef MAKEBUFS_H +#define MAKEBUFS_H + +void makebuffers(unsigned char **tapebuffer); + +#endif + +/* + * $Log: makebufs.h,v $ + * Revision 1.1 2003/06/03 00:16:14 korpela + * + * Initial splitter under CVS control. + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.1 1998/11/02 16:41:21 korpela + * Minor Change. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.2 1998/10/20 20:41:45 korpela + * Remove wu buffer. + * + * Revision 1.1 1998/10/19 19:02:36 korpela + * Initial revision + * + */ diff --git a/splitter/mb_angdist.cpp b/splitter/mb_angdist.cpp new file mode 100644 index 0000000..02f5bd9 --- /dev/null +++ b/splitter/mb_angdist.cpp @@ -0,0 +1,88 @@ +/* + * angdist.c + * + * Computes angular distance between two lat/lon points + * + * $Id: mb_angdist.cpp,v 1.1.2.1 2006/12/14 22:24:39 korpela Exp $ + * + */ + +#include "sah_config.h" +#include +#include +#include +#include "seti_header.h" +#include "sqlrow.h" +#include "sqlblob.h" +#include "sqlapi.h" +#include "db_table.h" +#include "schema_master.h" +#include "xml_util.h" +#include "db/app_config.h" + + +#define DTOR (M_PI/180) + +double angdist(double r1, double d1, double r2, double d2) { + double alpha,dist,d; + + r1*=DTOR; + r2*=DTOR; + d1*=DTOR; + d2*=DTOR; + alpha=r1-r2; + dist=sin(d2)*sin(d1)+cos(d1)*cos(d2)*cos(alpha); + if ((dist*dist)<1) { + d=sqrt(1.0-dist*dist); + } else { + dist=1.0; + d=0.0; + } + dist=atan2(d,dist); + dist=dist/DTOR; + return (dist); +} + +double angdist(const coordinate_t &a, const coordinate_t &b) { + return angdist(a.ra*15,a.dec,b.ra*15,b.dec); +} + + +/* + * $Log: mb_angdist.cpp,v $ + * Revision 1.1.2.1 2006/12/14 22:24:39 korpela + * *** empty log message *** + * + * Revision 1.3 2003/09/11 18:53:37 korpela + * *** empty log message *** + * + * Revision 1.2 2003/08/05 17:23:39 korpela + * More work on database stuff. + * Further tweaks. + * + * Revision 1.1 2003/07/29 20:35:31 korpela + * + * renames .C files to .cpp + * + * Revision 1.2 2003/06/03 01:01:15 korpela + * + * First working splitter under CVS. + * + * Revision 1.1 2003/06/03 00:16:08 korpela + * + * Initial splitter under CVS control. + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.1 1998/11/02 16:41:21 korpela + * Minor Change. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.1 1998/10/27 00:47:33 korpela + * Initial revision + * + * + */ diff --git a/splitter/mb_angdist.h b/splitter/mb_angdist.h new file mode 100644 index 0000000..c96b664 --- /dev/null +++ b/splitter/mb_angdist.h @@ -0,0 +1,36 @@ +/* + * angdist.h + * + * Computes angular distance between two lat/lon points + * + * $Id: mb_angdist.h,v 1.1.2.1 2006/12/14 22:24:40 korpela Exp $ + * + */ + +double angdist(double r1, double d1, double r2, double d2) ; +double angdist(const coordinate_t &a,const coordinate_t &b); + +/* + * $Log: mb_angdist.h,v $ + * Revision 1.1.2.1 2006/12/14 22:24:40 korpela + * *** empty log message *** + * + * Revision 1.1 2003/06/03 00:16:09 korpela + * + * Initial splitter under CVS control. + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.1 1998/11/02 16:41:21 korpela + * Minor Change. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.1 1998/10/27 01:03:21 korpela + * Initial revision + * + * + */ + diff --git a/splitter/mb_dotransform.cpp b/splitter/mb_dotransform.cpp new file mode 100644 index 0000000..dbd7115 --- /dev/null +++ b/splitter/mb_dotransform.cpp @@ -0,0 +1,259 @@ +/* + * + * dotransform.c + * + * Functions for division by frequency into work units. + * + * $Id: mb_dotransform.cpp,v 1.1.2.3 2007/06/06 15:58:29 korpela Exp $ + * + */ + +#include "sah_config.h" +#include +#include +#include +#include +#include +#include +#include + +#include "setilib.h" +#include "splitparms.h" +#include "splittypes.h" +#include "mb_splitter.h" +#include "fftw3.h" +#include "mb_wufiles.h" + +/* buffer for ftt output before data writes, needs to be multiple + * of three bytes long for encode to work. + */ +#define SAMPLES_PER_OBUF (FFT_LEN*2*3/CHAR_BIT) + + +int obuf_pos; /* Tracks current postition in the output buffers */ + + +void output_samples(float *data, int i, int buf_pos) { + int j,k; + unsigned short s=0; + float *p=data; + + for (k=0; k<8; k++) { + s >>= 2; + if (*p>0) s |= 0x8000; + if (*(p+1)>0) s |= 0x4000; + p+=2; + } + bin_data[i].push_back((s>>8) & 0xff); + bin_data[i].push_back(s & 0xff); +} + +void splitter_bits_to_float(unsigned short *raw, float *data, int nsamples) { + unsigned int i, j; + unsigned short s; + static int first_time=1; + static float lut[65536][16]; + + assert(!(nsamples % 8)); + + if (first_time) { + for (i=0;i<65536;i++) { + s=(unsigned short)i; + for (j=0;j<8;j++) { + lut[i][j*2]=(float)2*(s & 1)-1; + s >>= 1; + lut[i][j*2+1]=(float)2*(s & 1)-1; + s >>= 1; + } + } + first_time--; + } + + for (i=0;i<(nsamples/8);i++) { + memcpy(data+16*i,lut[raw[i]],16*sizeof(float)); + } +} + + +float randu() { +// Uniform random numbers between 0 and 1 + static bool first=true; + if (first) { + srand(time(0)); + first=false; + } + return static_cast(rand())/RAND_MAX; +} + +float randn() { +// normally distributed random numbers + static float last=0; + float a,b,h=0; + if (last==0) { + while (h==0 || h>=1) { + a=2*randu()-1; + b=2*randu()-1; + h=a*a+b*b; + } + h=sqrt(-2*log(h)/h); + last=a*h; + return b*h; + } else { + a=last; + last=0; + return a; + } +} + +void process_seg(std::vector > &data,int offset) { + int i; + static complex *dbuff=(complex *)fftwf_malloc(FFT_LEN*sizeof(complex)); + memset(dbuff,0,FFT_LEN*sizeof(complex)); + float* fbuff = (float *)dbuff; + fftwf_complex *fcbuff=(fftwf_complex *)dbuff; + static fftwf_plan planfwd,planinverse; + + + if (!planfwd) { + planfwd=fftwf_plan_dft_1d(FFT_LEN, fcbuff, fcbuff, FFTW_BACKWARD, + FFTW_MEASURE ); + int n=IFFT_LEN; + planinverse=fftwf_plan_many_dft(1, &n, FFT_LEN/IFFT_LEN, + fcbuff, &n, 1, n, + fcbuff, &n, 1, n, + FFTW_FORWARD, FFTW_MEASURE ); + } + + for (i=0;i( + static_cast(data[i+offset].real()), + static_cast(data[i+offset].imag()) + ); + } + + fftwf_execute(planfwd); + dbuff[0]=complex(0.0f,0.0f); // null the DC bin + + + // highpass filter the rest + if (splitter_settings.splitter_cfg->highpass != 0) { + float filter_bins=FFT_LEN*splitter_settings.splitter_cfg->highpass/splitter_settings.recorder_cfg->sample_rate; + complex stddev=0,avg=0; + for (i=0;i temp(dbuff[i]); + avg+=temp; + stddev+=complex(temp.real()*temp.real(),temp.imag()*temp.imag()); + } + avg/=(float)FFT_LEN; + stddev-=(float)FFT_LEN*complex(avg.real()*avg.real(),avg.imag()*avg.imag()); + stddev=complex(sqrt(stddev.real()),sqrt(stddev.imag()))/(float)FFT_LEN; + for (i=0;i(randn()*stddev.real(),randn()*stddev.imag())*(n+0.25f); + dbuff[FFT_LEN-(i+1)]+=complex(randn()*stddev.real(),randn()*stddev.imag())*(n+0.25f); + } + } + + dbuff[0]=complex(0.0f,0.0f); // null the DC bin + + fftwf_execute(planinverse); + for (i=0; i &tapebuffer) { + int i,j; + // long sum=0,sum0; + for (i=0;i &data,int offset) ; +void do_transform(std::vector &tapebuffer) ; + +/* + * + * $Log: mb_dotransform.h,v $ + * Revision 1.1.2.2 2007/04/25 17:20:28 korpela + * *** empty log message *** + * + * Revision 1.1.2.1 2006/12/14 22:24:41 korpela + * *** empty log message *** + * + * Revision 1.1 2003/06/03 00:16:11 korpela + * + * Initial splitter under CVS control. + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.3 1999/02/01 22:28:52 korpela + * FFTW version. + * + * Revision 2.2 1998/11/04 23:08:25 korpela + * Byte and bit order change. + * + * Revision 2.1 1998/11/02 16:41:21 korpela + * Minor Change. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.1 1998/10/27 01:05:22 korpela + * Initial revision + * + * + */ diff --git a/splitter/mb_message.cpp b/splitter/mb_message.cpp new file mode 100644 index 0000000..022fbf7 --- /dev/null +++ b/splitter/mb_message.cpp @@ -0,0 +1,73 @@ +/* + * Functions for sending messages to stderr and log files. + * + * $Id: mb_message.cpp,v 1.1.2.1 2006/12/14 22:24:42 korpela Exp $ + */ + +#include "sah_config.h" +#include +#include +#include +#include "setilib.h" +#include "sqlrow.h" +#include "sqlblob.h" +#include "sqlapi.h" +#include "db_table.h" +#include "schema_master.h" +#include "xml_util.h" + + +#include "boinc_db.h" +#include "sched_config.h" +#include "sched_msgs.h" +#include "mb_splitter.h" + +void message(char *msg) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"%s %s",tapebuffer[0].header.name,msg); +} + + + +/* + * $Log: mb_message.cpp,v $ + * Revision 1.1.2.1 2006/12/14 22:24:42 korpela + * *** empty log message *** + * + * Revision 1.2.4.1 2006/01/13 00:37:57 korpela + * Moved splitter to using standard BOINC logging mechanisms. All stderr now + * goes to "error.log" + * + * Added command line parameters "-iterations=" (number of workunit groups to + * create before exiting), "-trigger_file_path=" (path to the splitter_stop trigger + * file. Default is /disks/setifiler1/wutape/tapedir/splitter_stop). + * + * Reduced deadlines by a factor of three. We now need a 30 MFLOP machine to meet + * the deadline. + * + * Revision 1.2 2003/09/11 18:53:38 korpela + * *** empty log message *** + * + * Revision 1.1 2003/07/29 20:35:43 korpela + * + * renames .C files to .cpp + * + * Revision 1.1 2003/06/03 00:16:14 korpela + * + * Initial splitter under CVS control. + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.2 2000/12/01 01:13:29 korpela + * *** empty log message *** + * + * Revision 2.1 1998/11/02 16:41:21 korpela + * Minor Change. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.1 1998/10/27 00:56:16 korpela + * Initial revision + * + */ diff --git a/splitter/mb_polyphase.cpp b/splitter/mb_polyphase.cpp new file mode 100644 index 0000000..6df3548 --- /dev/null +++ b/splitter/mb_polyphase.cpp @@ -0,0 +1,150 @@ + +#include "sah_config.h" +#include +#include +#include +#include +#include +#include +#include +#include "setilib.h" + +#include "splitparms.h" +#include "splittypes.h" +#include "mb_splitter.h" +#include "mb_fftw.h" +#include "mb_wufiles.h" +#include "mb_polyphase.h" +#include "mb_dotransform.h" + +/* buffer for fft input/output */ +//float databuf[FFT_LEN*2]; + +/* buffer for ftt output before data writes, needs to be multiple + * of three bytes long for encode to work. + */ +#define SAMPLES_PER_OBUF (FFT_LEN*2*3/CHAR_BIT) + +extern unsigned char output_buf[NSTRIPS][SAMPLES_PER_OBUF]; + +double *filter_r, *filter_i; +float *f_data; + +extern int obuf_pos; /* Tracks current postition in the output buffers */ + +void make_FIR (int n_points, int M, int window, double *output) { + /* Create Mth band lowpass FIR filter, n_points long. */ + + /* Modify this to give 8-bit quantized filter. */ + /* Also generate Hilbert transformed filter */ + + int n; + double q, p; + + for (n=0; n TAPE_DATA_SIZE) { + // End of frame crossed need to trasfer correctly + end_trans.frame++; + end_trans.byte-=TAPE_DATA_SIZE; + nsamp=(TAPE_DATA_SIZE-start_trans.byte)*(CHAR_BIT/2); + assert((nsamp+end_trans.byte*(CHAR_BIT/2)) == FFT_LEN); + splitter_bits_to_float((unsigned short *)TBUF_OFFSET(start_trans.frame,start_trans.byte), + databuf, nsamp); + splitter_bits_to_float((unsigned short *)TBUF_OFFSET(end_trans.frame,0),databuf+nsamp*2, + end_trans.byte*(CHAR_BIT/2)); + } else { + splitter_bits_to_float((unsigned short *)TBUF_OFFSET(start_trans.frame,start_trans.byte), + databuf,FFT_LEN); + } + polyphase_seg(databuf); + // Go on to next transform + start_trans=end_trans; + } + // Check if we're at the end of the wu file. If so we print less bytes + if ((end_trans.frame>=end_of_wu->frame) && + (end_trans.byte>=end_of_wu->byte)) { + write_wufile_blocks(NBYTES % SAMPLES_PER_OBUF); + } else { + write_wufile_blocks(SAMPLES_PER_OBUF); + } + } while (!((end_trans.frame>=end_of_wu->frame) && (end_trans.byte>=end_of_wu->byte))); + + // Move the data in the buffer so we don't have to reread portions of the + // tape. + // + { + unsigned char *record_offset; + int copysize; + end_of_wu->frame-=WU_OVERLAP_FRAMES; + records_in_buffer=TAPE_RECORDS_IN_BUFFER- + (end_of_wu->frame/TAPE_FRAMES_PER_RECORD); + record_offset=tapebuffer+ + (end_of_wu->frame/TAPE_FRAMES_PER_RECORD)*TAPE_RECORD_SIZE; + copysize=records_in_buffer*TAPE_RECORD_SIZE; + bcopy(record_offset,tapebuffer,copysize); + } +} + + diff --git a/splitter/mb_splitter.cpp b/splitter/mb_splitter.cpp new file mode 100644 index 0000000..0fd71e7 --- /dev/null +++ b/splitter/mb_splitter.cpp @@ -0,0 +1,957 @@ +/* + * + * The splitter main program. + * + * $Id: mb_splitter.cpp,v 1.1.2.6 2007/08/16 23:03:19 jeffc Exp $ + * + */ + +#include "sah_config.h" +#undef USE_MYSQL +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "boinc_db.h" +#include "backend_lib.h" +#include "sched_config.h" +#include "setilib.h" +#include "str_util.h" +#include "str_replace.h" +#include "splitparms.h" +#include "splittypes.h" +#include "mb_splitter.h" +#include "mb_validrun.h" +#include "mb_wufiles.h" +#include "mb_dotransform.h" +#include "message.h" +#include "sqlrow.h" +#include "sqlapi.h" +#include "db/db_table.h" +#include "db/schema_master.h" +#include "db/app_config.h" + +extern "C" { + int sqldetach(); +} + +char trigger_file_path[1024]="/disks/setifiler1/wutape/tapedir/splitter_stop"; + +SCHED_CONFIG boinc_config; +DB_APP app; +R_RSA_PRIVATE_KEY key; + +// configuration tables +receiver_config rcvr; +settings splitter_settings; + +// TEMPLATE DEFS ------------------------------------------------------ +// IMPORTANT: a change to a template should *always* include a change +// to the template filename. Only the result template is used now. +const char *wu_template_filename_id = "wu_0.xml"; +const char *wu_template= + "\n" + " 0\n" + "\n" + "\n" + " \n" + " 0\n" + " work_unit.sah\n" + " \n" + "\n"; + +const char *result_template_filename_id = "result_0.xml"; +const char *result_template= + "\n" + " \n" + " \n" + " \n" + " 65536\n" + " http://setiboincdata.ssl.berkeley.edu/sah_cgi/file_upload_handler\n" + "\n" + "\n" + " \n" + " \n" + " result.sah\n" + " \n" + "\n"; +// END TEMPLATE DEFS -------------------------------------------------- + +std::vector tapebuffer; +std::map coord_history; +std::vector wuheaders; +int max_wus_ondisk=MAX_WUS_ONDISK; +int nodb; +int noencode; +int resumetape; +int norewind; +int startblock; +int dataclass; +int atnight; +int gregorian; +int output_xml; +int polyphase; +int iters=-1; +int beam; +int pol; +int alfa; +int useanalysiscfgid = 0; +int usereceivercfgid = 0; +int userecordercfgid = 0; +int usesplittercfgid = 0; +int filter_window = 0; +double start_time; +double stop_time; +unsigned long minvfsbuf=-1; +char wd[1024]; +//char * scidb = NULL; +char * projectdir = NULL; + +APP_CONFIG sah_config; + +//const char *result_template_filename="projectdir"/"SAH_APP_NAME"_result.tpl"; +char result_template_filename[1024]; +char result_template_filepath[1024]; +char wu_template_filename[1024]; + +int check_for_halt(); +int wait_until_night(); +int check_free_disk_space(); +int wait_for_db_wus_ondisk(); + +void cprint(char *p) { + printf("%s\n",p); +} + +/* wulog: File for logging names of completed wu files */ +/* errorlog: File for logging errors */ + +FILE *wulog,*errorlog; +buffer_pos_t start_of_wu,end_of_wu; /* position of start and end of wu in + tape buffer */ +int seqno; + +void cleanup(void) { + FILE *tmpfile; + if ((tmpfile=fopen("seqno.dat","w"))) { + fprintf(tmpfile,"%d\n",seqno); + fclose(tmpfile); + } else { + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Unable to open seqno.dat for write\n"); + } +} + + +int process_command_line(int argc, char *argv[],char **tape_device, + int *norewind, int *startblock, int *resumetape, + int *nodb, int *dataclass, int *atnight, + int *max_wus_ondisk, char **projectdir, + int *iters, int *beam, int *pol, int *alfa, + int *useanalysiscfgid, int *usereceivercfgid, + int *userecordercfgid, int *usesplittercfgid) { + int nargs=0,i; + char *ep; + for (i=1;i6)) || + ((*pol<0) || (*pol>1))) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"ALFA receivers must be specified with beam (0-6) and polarization (0-1), i.e. -alfa=4,0\n"); + exit(EXIT_FAILURE); + } + + *alfa=1; + } else if (!strncmp(argv[i],"-iterations",MAX(ep-argv[i],2))) { + sscanf(ep+1,"%d",iters); + } else if (!strncmp(argv[i],"-startblock",MAX(ep-argv[i],2))) { + if (*norewind || *resumetape) { + return(1); + } + sscanf(ep+1,"%d",startblock); + } else if (!strncmp(argv[i],"-max_wus_ondisk",MAX(ep-argv[i],2))) { + sscanf(ep+1,"%d",max_wus_ondisk); + } else if (!strncmp(argv[i],"-dataclass",MAX(ep-argv[i],2))) { + sscanf(ep+1,"%d",dataclass); + } else if (!strncmp(argv[i],"-projectdir",MAX(ep-argv[i],2))) { + *projectdir=(char *)calloc(strlen(ep+1)+5,1); + strlcpy(*projectdir,ep+1,strlen(ep+1)+5); + strlcat(*projectdir,"/",strlen(ep+1)+5); + } else if (!strncmp(argv[i],"-analysis_config",MAX(ep-argv[i],2))) { + sscanf(ep+1,"%d",useanalysiscfgid); + } else if (!strncmp(argv[i],"-recorder_config",MAX(ep-argv[i],2))) { + sscanf(ep+1,"%d",userecordercfgid); + } else if (!strncmp(argv[i],"-receiver_config",MAX(ep-argv[i],2))) { + sscanf(ep+1,"%d",usereceivercfgid); + } else if (!strncmp(argv[i],"-splitter_config",MAX(ep-argv[i],2))) { + sscanf(ep+1,"%d",usesplittercfgid); + } else { + return(1); + } + } else { + return(1); + } + } else { + *tape_device=argv[i]; + nargs++; + } + } + //return(nargs!=1); + + // check for required cmd line + //if (! *scidb) return (1); + if (! *projectdir) return (1); + if (! *tape_device) return (1); + + return 0; +} + +int main(int argc, char *argv[]) { + int tape_fd; + char *tape_device; + FILE *tmpfile; + int retval; + char keyfile[1024]; + char tmpstr[1024]; + char buf[1024]; + + + /* Process command line arguments */ + if (process_command_line(argc,argv,&tape_device,&norewind,&startblock,&resumetape, + &nodb,&dataclass,&atnight,&max_wus_ondisk,&projectdir,&iters, + &beam,&pol,&alfa,&useanalysiscfgid,&usereceivercfgid, + &userecordercfgid,&usesplittercfgid)) { + fprintf(stderr,"Usage: splitter tape_device -projectdir=s [-atnight] [-nodb]\n" + "[-xml] [-gregorian] [-resumetape | -norewind | -startblock=n] [-dataclass=n]\n" + "[-max_wus_on_disk=n] [-iterations=n] [-trigger_file_path=filename]\n" + "[-alfa=beam,pol] [-analysis_config=id] [-receiver_config=id]\n" + "[-recorder_config=id] [-splitter_config=id]\n"); + exit(EXIT_FAILURE); + } + + // MATTL + if (blanking_bit == SOFTWARE_BLANKING_BIT) log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"blanking bit: %d (SOFTWARE)\n",blanking_bit); + else log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"blanking bit: %d (HARDWARE)\n",blanking_bit); + + /* Open log files */ + log_messages.set_debug_level(3); + + retval = sah_config.parse_file(projectdir); + if (retval) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Can't parse config file\n"); + exit(EXIT_FAILURE); + } else { + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Using configuration:\n"); + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"scidb_name = %s\n", sah_config.scidb_name); + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"max_wus_ondisk = %d\n", sah_config.max_wus_ondisk); + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"min_quorum = %d\n", sah_config.min_quorum); + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"target_nresults = %d\n", sah_config.target_nresults); + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"max_error_results = %d\n", sah_config.max_error_results); + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"max_success_results = %d\n", sah_config.max_success_results); + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"max_total_results = %d\n", sah_config.max_total_results); + } + + // Will initially open + if (!db_change(sah_config.scidb_name)) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Could not open science database %s\n", sah_config.scidb_name); + if (!nodb) exit(EXIT_FAILURE); + } else { + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Using science database %s\n", sah_config.scidb_name); + } + + + boinc_config.parse_file(projectdir); + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Using boinc config dir %s\n", projectdir); + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Using boinc database %s\n", boinc_config.db_name); + + // check / commit result template + strcpy(result_template_filename, "templates/"SAH_APP_NAME"_"); + strcat(result_template_filename, result_template_filename_id); + strcpy(result_template_filepath, projectdir); + strcat(result_template_filepath, result_template_filename); + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"%s %s\n", result_template_filename, result_template_filepath); + if (!(tmpfile=fopen(result_template_filepath,"r"))) { + if (!(tmpfile=fopen(result_template_filepath,"w"))) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Cannot open result file template : %s\n", result_template_filepath); + exit(1); + } + fprintf(tmpfile,result_template); + } + fclose(tmpfile); + + if (boinc_db.open(boinc_config.db_name,boinc_config.db_host,boinc_config.db_user,boinc_config.db_passwd)) { + boinc_db.print_error("boinc_db.open"); + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"boinc_db.open\n"); + exit(1); + } + + if (app.lookup("where name ='"SAH_APP_NAME"'")) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Error looking up appname\n"); + boinc_db.print_error("boinc_app lookup"); + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"boinc_app lookup\n"); + exit(1); + } else { + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Splitting for application %s (ID = %d)\n", SAH_APP_NAME, app.id); + } + + boinc_db.close(); + + telescope_id tel= + channel_to_receiverid[beam_pol_to_channel[bmpol_t(beam,pol)]]; + + sprintf(buf,"where active=%d and receiver_cfg=(select id from receiver_config where s4_id=%d)",app.id,AO_ALFA_0_0); + if (usereceivercfgid > 0) { + sprintf(buf,"where active=%d and receiver_cfg=%d",app.id,usereceivercfgid); + } + if (!splitter_settings.fetch(std::string(buf))) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Unable to find active settings for app.id=%d\n",app.id); + exit(1); + } + + sprintf(buf,"where s4_id=%d and id>=%d",tel,splitter_settings.receiver_cfg.id); + if (usereceivercfgid > 0) { sprintf(buf,"where id=%d",usereceivercfgid); } + rcvr.fetch(buf); + if (usereceivercfgid > 0) { + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Using receiver cfg id: %d (set by user)\n",usereceivercfgid); + splitter_settings.receiver_cfg = usereceivercfgid; + splitter_settings.receiver_cfg->fetch(); + } else { + splitter_settings.receiver_cfg->fetch(buf); + } + if (userecordercfgid > 0) { + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Using recorder cfg id: %d (set by user)\n",userecordercfgid); + splitter_settings.recorder_cfg = userecordercfgid; + } + splitter_settings.recorder_cfg->fetch(); + if (usesplittercfgid > 0) { + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Using splitter cfg id: %d (set by user)\n",usesplittercfgid); + splitter_settings.splitter_cfg = usesplittercfgid; + } + splitter_settings.splitter_cfg->fetch(); + if (useanalysiscfgid > 0) { + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Using analysis cfg id: %d (set by user)\n",useanalysiscfgid); + splitter_settings.analysis_cfg = useanalysiscfgid; + } + splitter_settings.analysis_cfg->fetch(); + + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL, "settings: \n\n%s\n", splitter_settings.print_xml(1,1,0).c_str()); + + strcpy(keyfile, projectdir); + strcat(keyfile, "/keys/upload_private"); + if (read_key_file(keyfile,key)) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Error reading keyfile.\n"); + exit(1); + } + + check_for_halt(); + + if ((tape_fd=open(tape_device,O_RDONLY|0x2000, 0777))<0) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Unable to open tape device\n"); + exit(EXIT_FAILURE); + } + + // In early tapes there was a bug where the first N blocks would be duplicates + // of data from previous files. So we need to fast forward until we see a + // frame sequence number of 1. + int i,readbytes=HeaderSize; + dataheader_t header; + header.frameseq=100000; + + while ((readbytes==HeaderSize) && (header.frameseq>10)) { + char buffer[HeaderSize]; + int nread; + readbytes=0; + while ((readbytes!=HeaderSize) && (nread = read(tape_fd,buffer,HeaderSize-readbytes))) { + readbytes+=nread; + } + if (nread < 0) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"File error %d.\n", errno); + exit(1); + } + if (readbytes == HeaderSize) { + header.populate_from_data(buffer); + if (header.frameseq>10) { + lseek64(tape_fd,DataSize,SEEK_CUR); + } else { + lseek64(tape_fd,-1*(off64_t)HeaderSize,SEEK_CUR); + } + } + } + + if (readbytes != HeaderSize) { + // we fast forwarded through the entire tape without finding the first frame + // maybe this is one of the really early tapes that was split into chunks. + lseek64(tape_fd,0,SEEK_SET); + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Warning: First block not found\n"); + } + + if (resumetape) { + tape thistape; + thistape.id=0; + readbytes=HeaderSize; + sprintf(buf,"%d",rcvr.s4_id-AO_ALFA_0_0); + if (thistape.fetch(std::string("where name=\'")+header.name+"\' and beam="+buf)) { + log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG,"Resuming tape %s beam %d pol %d\n",thistape.name,beam,pol ); + while ((readbytes==HeaderSize) && (header.dataseq!=thistape.last_block_done)) { + int nread=0; + char buffer[HeaderSize]; + readbytes=0; + while ((readbytes!=HeaderSize) && + ((nread = read(tape_fd,buffer,HeaderSize-readbytes)) > 0 )) { + readbytes+=nread; + } + if (readbytes == HeaderSize) { + header.populate_from_data(buffer); + if (header.dataseq!=thistape.last_block_done) { + lseek64(tape_fd,(off64_t)(DataSize+HeaderSize)*(thistape.last_block_done-header.dataseq)-HeaderSize,SEEK_CUR); + } else { + lseek64(tape_fd,-1*(off_t)HeaderSize,SEEK_CUR); + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Found starting point"); + } + } + if (nread == 0) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"End of file.\n"); + exit(0); + } + if (nread < 0) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"File error %d.\n",errno); + exit(1); + } + } + } + } + + /* Start of main loop */ + + + atexit(cleanup); + + getcwd(wd,1024); + + if (polyphase) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Polyphase not implemented\n" ); + exit(1); +#if 0 + int filter_len; + + filter_len = P_FFT_LEN*N_WINDOWS; + + filter_r = (double *)malloc(sizeof(double)*filter_len); + filter_i = (double *)malloc(sizeof(double)*filter_len); + + f_data = (float *)malloc(sizeof(float)*P_FFT_LEN*2); + + make_FIR(filter_len, N_WINDOWS, filter_window, filter_r); + make_FIR(filter_len, N_WINDOWS, filter_window, filter_i); + + /* + int i; + float *data; + data = (float*)malloc(sizeof(float)*2*2048); + for (double n=-20;n<20;n+=.05) { + for (i=0;i<2*2048;i+=2) { + data[i] = cos(2*(24+n)*3.1415926535*i/(2*2048)); + data[i+1] = sin(2*(24+n)*3.1415926535*i/(2*2048)); + } + polyphase_seg(data); + //fprintf( stderr, "%f\n", 3+n/8); + } + exit(0); + for(i=0;i > blanker_filter; + if (strcmp(splitter_settings.splitter_cfg->blanker_filter, "randomize") == 0) { + log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG,"Setting blanker filter to randomize\n" ); + blanker_filter = randomize; + } else { + log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG,"Setting blanker filter to null\n" ); + blanker_filter = NULLC; // no blanking + } + while (iters-- && + ((512-tapebuffer.size())==seti_StructureDr2Data(tape_fd, beam, pol, + 512-tapebuffer.size(), tapebuffer, blanker_filter))) { + /* check if we should be running now */ + fflush(stderr); + if (atnight) wait_until_night(); + + sprintf(buf,"where active=%d and receiver_cfg=(select id from receiver_config where s4_id=%d)",app.id,AO_ALFA_0_0); + if (usereceivercfgid > 0) { + sprintf(buf,"where active=%d and receiver_cfg=%d",app.id,usereceivercfgid); + } + if (!splitter_settings.fetch(std::string(buf))) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Unable to find active settings for app.id=%d\n",app.id); + exit(1); + } + + sprintf(buf,"where s4_id=%d and id>=%d",tel,splitter_settings.receiver_cfg.id); + if (usereceivercfgid > 0) { sprintf(buf,"where id=%d",usereceivercfgid); } + rcvr.fetch(buf); + if (usereceivercfgid > 0) { + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Using receiver cfg id: %d (set by user)\n",usereceivercfgid); + splitter_settings.receiver_cfg = usereceivercfgid; + splitter_settings.receiver_cfg->fetch(); + } else { + splitter_settings.receiver_cfg->fetch(buf); + } + if (userecordercfgid > 0) { + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Using recorder cfg id: %d (set by user)\n",userecordercfgid); + splitter_settings.recorder_cfg = userecordercfgid; + } + splitter_settings.recorder_cfg->fetch(); + if (usesplittercfgid > 0) { + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Using splitter cfg id: %d (set by user)\n",usesplittercfgid); + splitter_settings.splitter_cfg = usesplittercfgid; + } + splitter_settings.splitter_cfg->fetch(); + if (useanalysiscfgid > 0) { + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Using analysis cfg id: %d (set by user)\n",useanalysiscfgid); + splitter_settings.analysis_cfg = useanalysiscfgid; + } + splitter_settings.analysis_cfg->fetch(); + + log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG, "settings: \n\n%s\n", splitter_settings.print_xml(1,1,0).c_str()); + + check_for_halt(); + + // Make sure we have enough free disk space + check_free_disk_space(); + + // Wait for ondisk wus in the database to drop below the threshold + if (!nodb) wait_for_db_wus_ondisk(); + //fprintf( stderr, "Read data\n" ); + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"less than max wus on disk, continuing\n" ); + fflush(stderr); + + //printf( "Read tape data, analyzing\n" ); + check_for_halt(); + + //check for an uninterrupted run + if (valid_run(tapebuffer,splitter_settings.receiver_cfg->min_vgc)) { + std::vector::iterator i=tapebuffer.begin(); + // insert telescope coordinates into the coordinate history. + // this should be converted to a more accurate routine. + for (;i!=tapebuffer.end();i++) { + coord_history[i->header.coord_time].ra = i->header.ra; + coord_history[i->header.coord_time].dec = i->header.dec; + coord_history[i->header.coord_time].time = i->header.coord_time.jd().uval(); + } + if (make_wu_headers(tapebuffer,tel,wuheaders)) { + int child_pid=-1; + switch (polyphase) { + case 1: + #if 0 + do_polyphase(&start_of_wu,&end_of_wu); + #endif + break; + default: + log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG,"doing transform..." ); + do_transform(tapebuffer); + log_messages.printf(SCHED_MSG_LOG::MSG_DEBUG," done\n" ); + } + wait(0); + if (!nodb) sql_finish(); + + do { + sleep(1); + child_pid=fork(); + if (child_pid<0) log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"splitter cannot fork"); + //fprintf( stderr, "child pid: %d\n", child_pid); + } while (child_pid<0); + + if (!child_pid) { + if (!nodb) { + sqldetach(); + while (!sql_database(sah_config.scidb_name)) { + //fprintf(stderr,"child sleeping\n"); + sleep(10); + } + } + rename_wu_files(); + if (!nodb) sql_finish(); + _exit(0); + } + + if (!nodb) { + while (!sql_database(sah_config.scidb_name)) { + //fprintf(stderr,"parent sleeping\n"); + sleep(10); + } + } + } + } + } + + // iters is initalized to -1. If the -iters flag is specified on the command + // line, iters is re-initialized to the user desired number of interations. + // Each time a WUG is proccessed iters is decremineted. If the user specifies + // iters and we do that number of iterations without reaching EOF then iters + // here will be zero. !Zero means we have reached EOF prior to performing the user + // desired number of iterations. + // + // On the other hand, if iters is not specified by the user, iters is decrmented + // downward from -1. It will never be zero in this case. But since we are not + // limiting the number of iterations, the only way will get here is if we reach EOF. + // + // Thus in both cases, a non-zero iters means we have reached EOF. + if (iters != 0) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"End of file.\n"); + // clean stop at EOF + return (EXIT_NORMAL_EOF); + } else { + // clean stop, but not EOF (iters satisfied or triggered stop) + // (A return of 1 is an error exit somewhere else in the code.) + return(EXIT_NORMAL_NOT_EOF); + } +} + +int check_for_halt() { + FILE *tf; + + tf = fopen(trigger_file_path, "r"); + // tf=0; + if (tf != NULL) { // Stop program + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Found splitter_stop, exiting.\n" ); + exit(EXIT_NORMAL_NOT_EOF); + } + return(0); // Keep going +} + +int wait_until_night() { + time_t t; + struct tm *lt; + do { + t=time(0); + lt=localtime(&t); + // Don't run M-F 8AM-6PM + if ((lt->tm_wday>0) && (lt->tm_wday<6) && (lt->tm_hour>8) && (lt->tm_hour<18)) { + sleep(100); + } + } while ((lt->tm_wday>0) && (lt->tm_wday<6) && (lt->tm_hour>8) && (lt->tm_hour<18)); + return 0; +} + +int check_free_disk_space() { + struct statvfs vfsbuf; + + /* check disk free space in working directory */ + statvfs("wu_inbox/.",&vfsbuf); + if (vfsbuf.f_frsize==0) vfsbuf.f_frsize=512; + if (vfsbuf.f_bavail < (100000*1024/vfsbuf.f_frsize)) { + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Not enough free disk space in working directory to continue\n"); + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Not enough free disk space in working directory to continue\n"); + exit(EXIT_FAILURE); + } + + /* check free disk space in download directory tree */ + std::string download_dir(boinc_config.download_dir); + int waited=0; + download_dir+="/."; + /* wait here if the disk is more than N% full */ + statvfs(download_dir.c_str(),&vfsbuf); + if (vfsbuf.f_blocks > vfsbuf.f_bfree*100/sah_config.min_disk_free_pct) { + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Waiting for free space in download directory\n"); + while (vfsbuf.f_blocks > vfsbuf.f_bfree*100/sah_config.min_disk_free_pct) { + waited+=10; + sleep(10); + statvfs(download_dir.c_str(),&vfsbuf); + } + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Waited %d seconds\n", waited); + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Continuing...\n"); + } + return 0; +} + +int wait_for_db_wus_ondisk() { + //int wus_ondisk,rv; + DB_STATE_COUNTS state_counts; + int retval; + + // No need to check the DB for every single WUG iteration. + static int check_count = 100; + if (check_count < 100) { + check_count++; + return 0; + } else { + check_count = 0; + } + + if (boinc_db.open(boinc_config.db_name,boinc_config.db_host,boinc_config.db_user,boinc_config.db_passwd)) { + boinc_db.print_error("boinc_db.open"); + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"boinc_db.open\n"); + exit(1); + } +#if 0 + retval = boinc_db.set_isolation_level(READ_UNCOMMITTED); + if (retval) { + log_messages.printf(MSG_CRITICAL, "boinc_db.set_isolation_level: %d; %s\n", rv, boinc_db.error_string()); + exit(EXIT_FAILURE); + } + else { + log_messages.printf(MSG_NORMAL, "setting read uncommitted isolation level\n"); + } +#endif + do { + char query[1024]; + sprintf(query,"where appid=%d",app.id); + retval=state_counts.lookup(query); + if (retval) { + boinc_db.print_error("state_counts.lookup"); + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"DB Error, unable to count workunits on disk\n"); + exit(EXIT_FAILURE); + } + check_for_halt(); + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"%d WUs ondisk\n", state_counts.result_server_state_2); + if (state_counts.result_server_state_2>sah_config.max_wus_ondisk) sleep(600); + +#if 0 + sprintf(query,"where appid=%d and server_state=2",app.id); + rv=boinc_result.count(wus_ondisk,query); + if (rv) { + boinc_db.print_error("boinc_result.count"); + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"DB Error, unable to count workunits on disk\n"); + exit(EXIT_FAILURE); + } + check_for_halt(); + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"%d WUs ondisk\n", wus_ondisk); + if (wus_ondisk>sah_config.max_wus_ondisk) sleep(600); + } while (wus_ondisk>sah_config.max_wus_ondisk); +#endif + + } while (state_counts.result_server_state_2>sah_config.max_wus_ondisk); + + boinc_db.close(); + return 0; +} + +/* + * $Log: mb_splitter.cpp,v $ + * Revision 1.1.2.6 2007/08/16 23:03:19 jeffc + * *** empty log message *** + * + * Revision 1.1.2.5 2007/08/10 19:29:40 jeffc + * *** empty log message *** + * + * Revision 1.1.2.4 2007/06/07 20:01:52 mattl + * *** empty log message *** + * + * Revision 1.1.2.3 2007/06/06 15:58:29 korpela + * *** empty log message *** + * + * Revision 1.1.2.2 2007/04/25 17:27:30 korpela + * *** empty log message *** + * + * Revision 1.1.2.1 2006/12/14 22:24:43 korpela + * *** empty log message *** + * + * Revision 1.22.2.4 2006/11/08 20:16:26 vonkorff + * Fixes an error message. + * + * Revision 1.22.2.3 2006/11/07 19:26:37 vonkorff + * Fixed lcgf + * + * Revision 1.22.2.2 2006/01/13 00:37:58 korpela + * Moved splitter to using standard BOINC logging mechanisms. All stderr now + * goes to "error.log" + * + * Added command line parameters "-iterations=" (number of workunit groups to + * create before exiting), "-trigger_file_path=" (path to the splitter_stop trigger + * file. Default is /disks/setifiler1/wutape/tapedir/splitter_stop). + * + * Reduced deadlines by a factor of three. We now need a 30 MFLOP machine to meet + * the deadline. + * + * Revision 1.22.2.1 2005/08/01 21:16:25 jeffc + * *** empty log message *** + * + * Revision 1.22 2005/01/27 23:03:27 mattl + * + * commented out tf=0 in check_for_halt + * + * Revision 1.21 2004/12/27 20:48:54 jeffc + * *** empty log message *** + * + * Revision 1.20 2004/08/12 15:45:41 jeffc + * *** empty log message *** + * + * Revision 1.19 2004/07/09 22:35:39 jeffc + * *** empty log message *** + * + * Revision 1.18 2004/06/27 21:07:04 jeffc + * *** empty log message *** + * + * Revision 1.17 2004/06/20 18:56:48 jeffc + * *** empty log message *** + * + * Revision 1.16 2004/06/18 23:23:32 jeffc + * *** empty log message *** + * + * Revision 1.15 2004/06/16 20:57:19 jeffc + * *** empty log message *** + * + * Revision 1.14 2004/04/08 22:25:47 jeffc + * *** empty log message *** + * + * Revision 1.13 2004/01/22 00:57:53 korpela + * *** empty log message *** + * + * Revision 1.12 2004/01/01 18:42:01 korpela + * *** empty log message *** + * + * Revision 1.11 2003/12/03 23:46:41 korpela + * WU count is now only for SAH workunits. + * + * Revision 1.10 2003/11/25 21:59:52 korpela + * *** empty log message *** + * + * Revision 1.9 2003/11/01 20:54:02 korpela + * *** empty log message *** + * + * Revision 1.8 2003/10/24 16:57:03 korpela + * *** empty log message *** + * + * Revision 1.7 2003/09/26 20:48:51 jeffc + * jeffc - merge in branch setiathome-4_all_platforms_beta. + * + * Revision 1.5.2.2 2003/09/23 00:49:12 korpela + * *** empty log message *** + * + * Revision 1.5.2.1 2003/09/22 17:39:34 korpela + * *** empty log message *** + * + * Revision 1.6 2003/09/22 17:05:38 korpela + * *** empty log message *** + * + * Revision 1.5 2003/09/13 20:48:38 korpela + * directory reorg. Moved client files to ./client + * + * Revision 1.4 2003/09/11 18:53:38 korpela + * *** empty log message *** + * + * Revision 1.3 2003/08/13 23:18:47 korpela + * *** empty log message *** + * + * Revision 1.2 2003/08/05 17:23:42 korpela + * More work on database stuff. + * Further tweaks. + * + * Revision 1.1 2003/07/29 20:35:50 korpela + * + * renames .C files to .cpp + * + * Revision 1.2 2003/06/03 01:01:17 korpela + * + * First working splitter under CVS. + * + * Revision 1.1 2003/06/03 00:23:40 korpela + * + * Again + * + * Revision 3.6 2003/05/21 00:41:42 korpela + * *** empty log message *** + * + * Revision 3.5 2003/05/19 17:40:59 eheien + * *** empty log message *** + * + * Revision 3.4 2003/04/09 17:46:54 korpela + * *** empty log message *** + * + * Revision 3.3 2002/06/20 22:09:17 eheien + * *** empty log message *** + * + * Revision 3.2 2001/11/07 00:51:47 korpela + * Added splitter version to database. + * Added max_wus_ondisk option. + * + * Revision 3.1 2001/08/16 23:42:08 korpela + * Mods for splitter to make binary workunits. + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.7 2000/12/01 01:13:29 korpela + * *** empty log message *** + * + * Revision 2.6 1999/06/07 21:00:52 korpela + * *** empty log message *** + * + * Revision 2.5 1999/03/27 16:19:35 korpela + * *** empty log message *** + * + * Revision 2.4 1999/03/05 01:47:18 korpela + * Added dataclass paramter. + * + * Revision 2.3 1999/02/22 22:21:09 korpela + * added -nodb option + * + * Revision 2.2 1999/02/11 16:46:28 korpela + * Added some db access functions. + * + * Revision 2.1 1998/11/02 16:41:21 korpela + * Minor Change. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.2 1998/10/30 20:26:03 korpela + * Bug Fixes. Now mostly working. + * + * Revision 1.1 1998/10/27 00:58:16 korpela + * Initial revision + * + * + */ diff --git a/splitter/mb_splitter.h b/splitter/mb_splitter.h new file mode 100644 index 0000000..3bff91a --- /dev/null +++ b/splitter/mb_splitter.h @@ -0,0 +1,144 @@ +/* + * splitter.h + * + * Global definitions from the splitter main program. + * + * $Id: mb_splitter.h,v 1.1.2.2 2007/04/25 17:20:28 korpela Exp $ + * + */ + +#ifndef SPLITTER_H +#define SPLITTER_H + +#include "splitparms.h" +#include "splittypes.h" + +#define MAX(x,y) ( ((x)<(y)) ? (y) : (x) ) +#define MIN(x,y) ( ((y)<(x)) ? (y) : (x) ) + +/* wulog: File for logging names of completed wu files */ +/* errorlog: File for logging errors */ +#include "boinc_db.h" +#include "crypt.h" +#include "backend_lib.h" +#include "sched_config.h" + +extern SCHED_CONFIG boinc_config; +extern DB_APP app; +extern R_RSA_PRIVATE_KEY key; +extern FILE *wulog,*errorlog; +extern std::vector wuheaders; +extern int noencode; +extern int dataclass; +extern int nodb; +extern int resumetape; +extern int startblock; +extern int norewind; +extern int output_xml; +extern int polyphase; +extern std::vector wu_database_id; +extern int gregorian; +extern char * projectdir; +extern char trigger_file_name[1024]; +extern receiver_config rcvr; +extern settings splitter_settings; + + +/* Buffer that holds tape data */ +extern std::vector tapebuffer; +extern std::map coord_history; + +/* Number of records remaining in the buffer after WU creations is complete */ +extern int records_in_buffer; + +extern const char *wu_template; +extern const char *result_template; +// jeffc +//extern const char *result_template_filename; +extern char result_template_filename[]; +extern char result_template_filepath[]; +extern char wu_template_filename[]; + +// exit values not defined elsewhere +const int EXIT_NORMAL_EOF = 0; +const int EXIT_NORMAL_NOT_EOF = 2; + +/* Persistant sequence number of wu file */ +extern int seqno; + +#endif + +/* + * $Log: mb_splitter.h,v $ + * Revision 1.1.2.2 2007/04/25 17:20:28 korpela + * *** empty log message *** + * + * Revision 1.1.2.1 2006/12/14 22:24:43 korpela + * *** empty log message *** + * + * Revision 1.6.2.1 2006/01/13 00:37:58 korpela + * Moved splitter to using standard BOINC logging mechanisms. All stderr now + * goes to "error.log" + * + * Added command line parameters "-iterations=" (number of workunit groups to + * create before exiting), "-trigger_file_path=" (path to the splitter_stop trigger + * file. Default is /disks/setifiler1/wutape/tapedir/splitter_stop). + * + * Reduced deadlines by a factor of three. We now need a 30 MFLOP machine to meet + * the deadline. + * + * Revision 1.6 2004/07/09 22:35:39 jeffc + * *** empty log message *** + * + * Revision 1.5 2004/06/16 20:57:19 jeffc + * *** empty log message *** + * + * Revision 1.4 2003/09/26 20:48:52 jeffc + * jeffc - merge in branch setiathome-4_all_platforms_beta. + * + * Revision 1.2.2.1 2003/09/22 17:39:35 korpela + * *** empty log message *** + * + * Revision 1.3 2003/09/22 17:05:38 korpela + * *** empty log message *** + * + * Revision 1.2 2003/08/05 17:23:42 korpela + * More work on database stuff. + * Further tweaks. + * + * Revision 1.1 2003/06/03 00:23:40 korpela + * + * Again + * + * Revision 3.2 2003/05/19 17:40:59 eheien + * *** empty log message *** + * + * Revision 3.1 2001/08/16 23:42:08 korpela + * Mods for splitter to make binary workunits. + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.5 1999/10/20 19:20:26 korpela + * *** empty log message *** + * + * Revision 2.4 1999/03/05 01:47:18 korpela + * Added data_class field. + * + * Revision 2.3 1999/02/22 22:21:09 korpela + * Added nodb option + * + * Revision 2.2 1999/02/11 16:46:28 korpela + * Added startblock and norewind support, and wu_database_id. + * + * Revision 2.1 1998/11/02 16:41:21 korpela + * Minor Change. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.1 1998/10/27 01:10:32 korpela + * Initial revision + * + * + */ diff --git a/splitter/mb_splittypes.h b/splitter/mb_splittypes.h new file mode 100644 index 0000000..540fd74 --- /dev/null +++ b/splitter/mb_splittypes.h @@ -0,0 +1,114 @@ +/* splittypes.h + * + * Type definitions specific to the splitter. + * + * + * $Id: mb_splittypes.h,v 1.1.2.1 2006/12/14 22:24:44 korpela Exp $ + * + */ +#ifndef SPLITTYPES_H +#define SPLITTYPES_H + +#include + +#include "splitparms.h" +#include "s_util.h" +#include "seti_header.h" + +//typedef struct wuheader { + //WU_INFO wuhead; + //SETI_WU_INFO wuinfo; +//} wuheader_t; + +typedef struct tapeheader { + char name[36]; + int rcdtype; + int numringbufs; + int numdiskbufs; + unsigned long frameseq; + unsigned long dataseq; + int missed; + TIME st; + SCOPE_STRING telstr; + int source; + double centerfreq,samplerate; + char version[16]; +} tapeheader_t; + +typedef struct buffer_pos { + int frame; + long offset; +} buffer_pos_t; + +#endif +/* + * $Log: mb_splittypes.h,v $ + * Revision 1.1.2.1 2006/12/14 22:24:44 korpela + * *** empty log message *** + * + * Revision 1.4 2003/08/05 17:23:43 korpela + * More work on database stuff. + * Further tweaks. + * + * Revision 1.3 2003/07/29 20:35:51 korpela + * + * renames .C files to .cpp + * + * Revision 1.2 2003/06/03 01:01:17 korpela + * + * First working splitter under CVS. + * + * Revision 1.1 2003/06/03 00:23:41 korpela + * + * Again + * + * Revision 3.1 2003/05/19 17:40:59 eheien + * *** empty log message *** + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.5 1999/02/11 16:46:28 korpela + * Added startblock and norewind support, and wu_database_id. + * + * Revision 2.4 1998/11/10 00:02:44 korpela + * Moved remaining wuheader fields into a WU_INFO structure. + * + * Revision 2.3 1998/11/05 21:18:41 korpela + * Moved name field from header to seti header. + * + * Revision 2.2 1998/11/02 21:20:58 korpela + * Moved tape_version and encoding_type into SETI_WU_INFO. + * + * Revision 2.1 1998/11/02 16:38:29 korpela + * Variable type changes. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.7 1998/10/30 21:01:13 davea + * *** empty log message *** + * + * Revision 1.6 1998/10/27 01:10:58 korpela + * Modified tapeheader_t to match new tape header fields. + * + * Revision 1.5 1998/10/19 23:04:32 korpela + * Moved times in telstr_t into an st_t. + * Changed name of ast_t to st_t. + * Added time zone (tz) field to ast_t. + * + * Revision 1.4 1998/10/15 19:13:30 korpela + * Renamed "unix" fields to "unix_time" because of GCC #define. + * Added position_history field to wuheader_t. + * + * Revision 1.3 1998/10/15 18:58:50 korpela + * Added time_t unix to ast_t and telstr_t types. + * Changed times in wuheader_t to time_t types. + * + * Revision 1.2 1998/10/15 18:01:19 korpela + * Removed month field from ast_t and telstr_t. + * + * Revision 1.1 1998/10/15 16:20:24 korpela + * Initial revision + * + */ diff --git a/splitter/mb_validrun.cpp b/splitter/mb_validrun.cpp new file mode 100644 index 0000000..9bf7230 --- /dev/null +++ b/splitter/mb_validrun.cpp @@ -0,0 +1,147 @@ +/* + * validrun.c + * + * Functions for determining if a section of the tape buffer can be + * turned into a valid work unit + * + * $Id: mb_validrun.cpp,v 1.1.2.1 2006/12/14 22:24:45 korpela Exp $ + * + */ + +#include "sah_config.h" +#include +#include +#include +#include +#include "setilib.h" +#include "splitparms.h" +#include "splittypes.h" +#include "splitter.h" +#include "message.h" + + +bool valid_run(std::vector &tapebuffer, int min_vgc) { + unsigned long start_dataseq=tapebuffer[0].header.dataseq; + unsigned long end_dataseq=tapebuffer[tapebuffer.size()-1].header.dataseq; + bool valid=true; + int i; + + // check for missing frames + if(!(end_dataseq-start_dataseq)==(tapebuffer.size()-1)) { + valid = false; + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Missing frames between %lu and %lu\n", + tapebuffer[0].header.dataseq,tapebuffer[tapebuffer.size()-1].header.dataseq); + for (i=tapebuffer.size()-1;i>0;i--) { // find the last "in sequence" frame + if (tapebuffer[i-1].header.dataseq != (tapebuffer[i].header.dataseq-1)) { + tapebuffer.erase(tapebuffer.begin(),tapebuffer.begin()+i); // delete all frames prior to the miss + } + } + } + + // if still valid, check for failed blanking signal acquisition + if (valid) { + for (i=0;valid && (i 0) { + for (i=0;valid && (i +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_ERRNO_H +#include +#endif + +#include "boinc_db.h" +#include "sched_util.h" +#include "setilib.h" +#include "splitparms.h" +#include "splittypes.h" +#include "s_util.h" +#include "util.h" +#include "str_util.h" +#include "str_replace.h" +#include "mb_splitter.h" +#include "message.h" +#include "mb_angdist.h" +#include "cmap_interp.h" +#include "lcgamm.h" +#include "sqlrow.h" +#include "sqlblob.h" +#include "sqlapi.h" +#include "db_table.h" +#include "schema_master.h" +#include "xml_util.h" +#include "db/app_config.h" +#include "str_util.h" + +std::vector wu_database_id; +std::vector > bin_data; + +extern APP_CONFIG sah_config; + +int make_wu_headers(std::vector &tapebuffer, telescope_id +tel, std::vector &wuheader) { + int procid=getpid(); + double receiver_freq; + int bandno; + FILE *tmpfile; + char tmpstr[256]; + char buf[64]; + static const receiver_config &r(rcvr); + static const settings &s(splitter_settings); + bool group_is_vlar; + + if (!strncmp(s.splitter_cfg->data_type,"encoded", + std::min(static_cast(7),sizeof(s.splitter_cfg->data_type)))) { + noencode=0; + } else { + noencode=1; + } + + tapebuffer[0].header.samplerate*=1e+6; + seconds sample_time(1.0/tapebuffer[0].header.samplerate); + seti_time start_time(tapebuffer[0].header.data_time + -tapebuffer[0].data.size()*0.5*sample_time); + seti_time end_time(tapebuffer[tapebuffer.size()-1].header.data_time); + + + workunit_grp wugrp; + sprintf(wugrp.name,"%s.%ld.%d.%ld.%d", + tapebuffer[0].header.name, + procid, + tapebuffer[0].header.dataseq, + tel, + s.id); + wugrp.receiver_cfg=r; + wugrp.recorder_cfg=s.recorder_cfg; + wugrp.splitter_cfg=s.splitter_cfg; + wugrp.analysis_cfg=s.analysis_cfg; + + wugrp.data_desc.nsamples=NSAMPLES; + wugrp.data_desc.true_angle_range=0; + coordinate_t start_coord(cmap_interp(coord_history,start_time)); + coordinate_t end_coord(cmap_interp(coord_history,end_time)); + wugrp.data_desc.start_ra=start_coord.ra; + wugrp.data_desc.end_ra=end_coord.ra; + wugrp.data_desc.start_dec=start_coord.dec; + wugrp.data_desc.end_dec=end_coord.dec; + coordinate_t last_coord=start_coord; + double sample_rate=tapebuffer[0].header.samplerate/NSTRIPS; + + // find the bracketing entries in the coordinate history + std::map::iterator above(coord_history.upper_bound(end_time)); + std::map::iterator below(coord_history.lower_bound(start_time)); + std::map::iterator p; + if (above==coord_history.begin()) { + above++; + } + if (below==coord_history.end()) { + below=above; + below--; + } + if (above==below) { + below--; + } + // Calculate the angular distance the beam has traveled + for (p=below;p!=above;p++) + { + wugrp.data_desc.true_angle_range+=angdist(last_coord,p->second); + last_coord=p->second; + } + wugrp.data_desc.true_angle_range+=angdist(last_coord,end_coord); + if (wugrp.data_desc.true_angle_range==0) wugrp.data_desc.true_angle_range=1e-10; + // Calculate the number of unique signals that could be found in a workunit. + // We will use these numbers to calculate thresholds. + double numgauss=2.36368e+08/std::min(wugrp.data_desc.true_angle_range,10.0); + double numpulse=std::min(4.52067e+10/std::min(wugrp.data_desc.true_angle_range,10.0),2.00382e+11); + double numtrip=std::min(3.25215e+12/std::min(wugrp.data_desc.true_angle_range,10.0),1.44774e+13); + + // check for VLAR workunits + if (wugrp.data_desc.true_angle_range < 0.12) { + group_is_vlar=true; + } else { + group_is_vlar=false; + } + + + // if (useanalysiscfgid > 0) { + // log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Re-reading analysis cfg id: %d (set by user):\n",useanalysiscfgid); + // s.analysis_cfg = useanalysiscfgid; + // } + + // Calculate a unique key to describe this analysis config. + long keyuniq=floor(std::min(wugrp.data_desc.true_angle_range*100,1000.0)+0.5)+ + s.analysis_cfg.id*1024; + if ((keyuniq>((s.analysis_cfg.id+1)*1024)) ||(keyuniq<(s.analysis_cfg.id)*1024)) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Invalid keyuniq value!\n"); + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"%d %d %f\n",keyuniq,s.analysis_cfg.id,wugrp.data_desc.true_angle_range); + exit(1); + } + + keyuniq*=-1; + long save_keyuniq=keyuniq; + splitter_settings.analysis_cfg=wugrp.analysis_cfg; + sprintf(tmpstr,"where keyuniq=%d",keyuniq); + // Check if we've already done this analysis_config... + // Fetch through splitter_settings, since it's alias (s) is const. + splitter_settings.analysis_cfg.id=0; + splitter_settings.analysis_cfg->fetch(tmpstr); + + if (s.analysis_cfg->id==0) { + if (keyuniq != save_keyuniq) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"keyuniq value changed!\n"); + exit(1); + } + + // If not calculate the thresholds based upon the input analysis_config + // Triplets are distributed exponentially... + wugrp.analysis_cfg->triplet_thresh+=(log(numtrip)-29.0652); + + // Gaussians are based upon chisqr... + double p_gauss=lcgf(32.0,wugrp.analysis_cfg->gauss_null_chi_sq_thresh*32.0); + p_gauss-=(log(numgauss)-19.5358); + wugrp.analysis_cfg->gauss_null_chi_sq_thresh=invert_lcgf(p_gauss,32,1e-4)*0.03125; + + // Pulses thresholds are log of the probability + wugrp.analysis_cfg->pulse_thresh+=(log(numpulse)-24.7894); + + wugrp.analysis_cfg->keyuniq=keyuniq; + wugrp.analysis_cfg->insert(); + } else { + wugrp.analysis_cfg=s.analysis_cfg; + } + + strlcpy(wugrp.data_desc.time_recorded, + short_jd_string(start_time.jd().uval()), + sizeof(wugrp.data_desc.time_recorded)); + wugrp.data_desc.time_recorded_jd=start_time.jd().uval(); + wugrp.data_desc.coords.clear(); + + wugrp.data_desc.coords.push_back(start_coord); + for (p=below;p!=above;p++) + { + wugrp.data_desc.coords.push_back(p->second); + } + wugrp.data_desc.coords.push_back(end_coord); + + wugrp.tape_info->id=0; + sprintf(buf,"%d",tel-AO_ALFA_0_0); + wugrp.tape_info->fetch(std::string("where name=\'")+tapebuffer[0].header.name+"\' and beam="+buf); + wugrp.tape_info->start_time=tapebuffer[0].header.data_time.jd().uval(); + wugrp.tape_info->last_block_time=wugrp.tape_info->start_time; + wugrp.tape_info->last_block_done=tapebuffer[0].header.dataseq; + wugrp.tape_info->beam=tel-AO_ALFA_0_0; + + if (!nodb) { + if (wugrp.tape_info.id) { + if (!(wugrp.tape_info->update())) { + char buf[1024]; + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"%s",sql_error_message()); + exit(1); + } + } else { + strlcpy(wugrp.tape_info->name,tapebuffer[0].header.name,sizeof(wugrp.tape_info->name)); + wugrp.tape_info->insert(); + } + } + + if (!nodb) { + sqlint8_t wgid; + if ((wgid=wugrp.insert())<=0) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Workunit_grp insert failed\nwgid=%d\nSQLCODE=%d\nLAST_NON_ZERO_SQLCODE=%d\n",wgid,sql_error_code(),sql_last_error_code()); + exit( 1 ); + } + wugrp.id=wgid; + } + int i; + wu_database_id.resize(NSTRIPS); + bin_data.resize(NSTRIPS); + wuheader.resize(NSTRIPS); + for (i=0;i\n"); + fprintf(tmpfile,wuheader[i].print_xml().c_str()); + fclose(tmpfile); + } else { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Unable to open file ./wu_inbox/%s, errno=%d\n",wuheader[i].name,errno); + exit(1); + } + bin_data[i].reserve(wuheaders[i].group_info->recorder_cfg->bits_per_sample* + wuheaders[i].group_info->data_desc.nsamples/8); + } + return(1); +} + + +void write_wufile_blocks(int nbytes) { + // doesn't do anything anymore. What was done here is done in output_samples. +} + +int filecopy(char *oldname,char *newname) { + FILE *oldfile,*newfile; + char buffer[16384]; + int nread; + if ((oldfile=fopen(oldname,"rb")) && (newfile=fopen(newname,"wb"))) { + do { + nread=fread(buffer,1,16384,oldfile); + fwrite(buffer,1,nread,newfile); + } while (nread>0); + fclose(oldfile); + fclose(newfile); + return 0; + } else { + return 1; + } +} + + + +void rename_wu_files() { + int i, retval; + char oldname[256],newname[1024]; + unsigned long sz; + DB_WORKUNIT db_wu; + const char *name[1]; + char *wudir="./wu_inbox"; + xml_encoding encoding=(noencode?_binary:_x_setiathome); + FILE *tmpfile; + + if (boinc_db.open(boinc_config.db_name,boinc_config.db_host,boinc_config.db_user,boinc_config.db_passwd)) { + boinc_db.print_error("boinc_db.open"); + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Fatal error in boinc_db.open\n"); + exit(1); + } + + for (i=0;i",tmpstr.size(), + xml_encoding_names[encoding]); + fwrite(tmpstr.c_str(),tmpstr.size(),1,tmpfile); + fprintf(tmpfile,"\n"); + fprintf(tmpfile,"\n"); + sz=bin_data[i].size(); + + fclose(tmpfile); + } else { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Header file no longer exists! splitter start script may be failing\n "); + exit(1); + } + if (!nodb) { + if (!filecopy(oldname,newname)) { + db_wu.clear(); + db_wu.opaque=wuheaders[i].id; + strncpy(db_wu.name,name[0],sizeof(db_wu.name)-2); + db_wu.appid=app.id; + //db_wu.rsc_fpops_est=2.79248e+13*6; + //db_wu.rsc_fpops_bound=4.46797e+14*6; + double beam=wuheaders[i].group_info->receiver_cfg->beam_width; + double ar=wuheaders[i].group_info->data_desc.true_angle_range; + double dur=(double)(wuheaders[i].group_info->data_desc.nsamples)/wuheaders[i].subband_desc.sample_rate; + double min_slew=wuheaders[i].group_info->analysis_cfg->pot_min_slew; + double max_slew=wuheaders[i].group_info->analysis_cfg->pot_max_slew; + if ( ar <= beam ) { + db_wu.rsc_fpops_est=8.036e+13; + } else if ( ar <= ( dur*min_slew ) ) { + db_wu.rsc_fpops_est=4.805e+13+2.296e+12/ar; + } else if ( ar <= ( dur*max_slew ) ) { + db_wu.rsc_fpops_est=4.592e+13+1.476e+13/ar; + } else { + db_wu.rsc_fpops_est=2.378e+13; + } + db_wu.rsc_fpops_est*=(0.333/wuheaders[i].group_info->analysis_cfg->chirp_resolution); + db_wu.rsc_fpops_bound=db_wu.rsc_fpops_est*10; + db_wu.rsc_memory_bound=33554432; + db_wu.rsc_disk_bound=33554432; + // Our minimum is a 40 MFLOP machine + db_wu.delay_bound=std::max(86400.0*7,db_wu.rsc_fpops_est/4e+7); + db_wu.min_quorum=sah_config.min_quorum; + db_wu.target_nresults=sah_config.target_nresults; + db_wu.max_error_results=sah_config.max_error_results; + db_wu.max_total_results=sah_config.max_total_results; + db_wu.max_success_results=sah_config.max_success_results; + strncpy(db_wu.app_name,SAH_APP_NAME,sizeof(db_wu.app_name)-2); + if (create_work(db_wu, + wu_template, + result_template_filename, + result_template_filepath, + name, + 1, + boinc_config, + NULL + ) + ) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"create work failed\n"); + exit(1); + } + //unlink(oldname); // we now *always* unlink + } else { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"file copy failed\n"); + exit(1); + } + unlink(oldname); + } + } + boinc_db.close(); +} + +/* + * $Log: mb_wufiles.cpp,v $ + * Revision 1.1.2.6 2007/08/10 18:21:13 korpela + * *** empty log message *** + * + * Revision 1.1.2.5 2007/08/09 21:31:08 korpela + * *** empty log message *** + * + * Revision 1.1.2.4 2007/06/07 20:01:52 mattl + * *** empty log message *** + * + * Revision 1.1.2.3 2007/06/06 15:58:30 korpela + * *** empty log message *** + * + * Revision 1.1.2.2 2007/04/25 17:27:31 korpela + * *** empty log message *** + * + * Revision 1.1.2.1 2006/12/14 22:24:45 korpela + * *** empty log message *** + * + * Revision 1.29.2.14 2006/05/03 19:14:31 korpela + * Updated work estimates. + * + * Revision 1.29.2.13 2006/04/24 18:41:02 korpela + * *** empty log message *** + * + * Revision 1.29.2.12 2006/01/13 00:37:58 korpela + * Moved splitter to using standard BOINC logging mechanisms. All stderr now + * goes to "error.log" + * + * Added command line parameters "-iterations=" (number of workunit groups to + * create before exiting), "-trigger_file_path=" (path to the splitter_stop trigger + * file. Default is /disks/setifiler1/wutape/tapedir/splitter_stop). + * + * Reduced deadlines by a factor of three. We now need a 30 MFLOP machine to meet + * the deadline. + * + * Revision 1.29.2.11 2006/01/10 00:39:04 jeffc + * *** empty log message *** + * + * Revision 1.29.2.10 2006/01/05 23:55:22 korpela + * *** empty log message *** + * + * Revision 1.29.2.9 2005/12/05 22:11:40 korpela + * Fixed bug in flops estimate. + * + * Revision 1.29.2.8 2005/10/05 16:22:17 jeffc + * removed reference to old/new boolean for directory hash. + * + * Revision 1.29.2.7 2005/09/22 23:05:22 korpela + * Fixed threshold calculation. Was using chisqr rather than reduced chisqr. + * + * Revision 1.29.2.6 2005/09/21 22:11:23 korpela + * Updated Makefile.in for OpenSSL. + * Added dynamic threshold generation to wufiles.cpp. + * + * Revision 1.29.2.5 2005/08/01 17:47:38 korpela + * Type fixed. + * + * Revision 1.29.2.4 2005/08/01 17:43:20 korpela + * Refinement of FLOPS estimate for workunits. + * + * Revision 1.29.2.3 2005/07/26 17:17:01 korpela + * Typo fix + * + * Revision 1.29.2.2 2005/07/19 00:15:19 korpela + * Revised delay bound and FLOP estimate for setiathome_enhanced. + * + * Revision 1.29.2.1 2005/07/06 01:30:17 korpela + * Updated estimates of FPOPS per workunit for setiathome enhanced. + * + * Revision 1.29 2005/03/08 22:36:15 jeffc + * jeffc - fixed call to create_work() + * + * Revision 1.28 2005/02/15 23:06:47 korpela + * Fixed missing dir_hier symbol. + * + * Revision 1.27 2004/12/27 20:48:54 jeffc + * *** empty log message *** + * + * Revision 1.26 2004/11/18 22:24:48 korpela + * *** empty log message *** + * + * Revision 1.25 2004/08/25 22:42:11 jeffc + * *** empty log message *** + * + * Revision 1.24 2004/08/14 04:44:26 jeffc + * *** empty log message *** + * + * Revision 1.23 2004/08/12 15:45:41 jeffc + * *** empty log message *** + * + * Revision 1.22 2004/07/15 17:54:20 jeffc + * *** empty log message *** + * + * Revision 1.21 2004/07/09 22:35:39 jeffc + * *** empty log message *** + * + * Revision 1.20 2004/07/01 17:56:51 korpela + * *** empty log message *** + * + * Revision 1.19 2004/06/25 13:49:33 jeffc + * *** empty log message *** + * + * Revision 1.18 2004/06/18 23:23:32 jeffc + * *** empty log message *** + * + * Revision 1.17 2004/06/16 20:57:19 jeffc + * *** empty log message *** + * + * Revision 1.16 2004/06/02 20:51:32 jeffc + * *** empty log message *** + * + * Revision 1.15 2004/01/22 00:57:54 korpela + * *** empty log message *** + * + * Revision 1.14 2004/01/20 22:33:44 korpela + * *** empty log message *** + * + * Revision 1.13 2004/01/06 22:44:05 korpela + * *** empty log message *** + * + * Revision 1.12 2004/01/01 18:42:01 korpela + * *** empty log message *** + * + * Revision 1.11 2003/12/12 01:51:39 korpela + * Now using the opaque field in workunit to store SAH wuid. + * + * Revision 1.10 2003/12/03 23:46:41 korpela + * WU count is now only for SAH workunits. + * + * Revision 1.9 2003/11/25 21:59:53 korpela + * *** empty log message *** + * + * Revision 1.8 2003/11/11 06:20:30 korpela + * Increased max fpops_max to prevent timeout on windows clients + * + * Revision 1.7 2003/10/25 18:19:44 korpela + * *** empty log message *** + * + * Revision 1.6 2003/10/24 16:57:03 korpela + * *** empty log message *** + * + * Revision 1.5 2003/09/26 20:48:52 jeffc + * jeffc - merge in branch setiathome-4_all_platforms_beta. + * + * Revision 1.3.2.2 2003/09/22 19:00:31 korpela + * *** empty log message *** + * + * Revision 1.3.2.1 2003/09/22 17:39:35 korpela + * *** empty log message *** + * + * Revision 1.4 2003/09/22 17:05:38 korpela + * *** empty log message *** + * + * Revision 1.3 2003/09/11 18:53:38 korpela + * *** empty log message *** + * + * Revision 1.2 2003/08/05 17:23:44 korpela + * More work on database stuff. + * Further tweaks. + * + * Revision 1.1 2003/07/29 20:36:00 korpela + * + * renames .C files to .cpp + * + * Revision 1.3 2003/06/05 15:52:47 korpela + * + * Fixed coordinate bug that was using the wrong zenith angle from the telescope + * strings when handling units from the gregorian. + * + * Revision 1.2 2003/06/03 01:01:18 korpela + * + * First working splitter under CVS. + * + * Revision 1.1 2003/06/03 00:23:44 korpela + * + * Again + * + * Revision 3.8 2003/05/19 17:40:59 eheien + * *** empty log message *** + * + * Revision 3.7 2003/04/10 17:32:25 korpela + * *** empty log message *** + * + * Revision 3.6 2002/06/21 01:42:15 eheien + * *** empty log message *** + * + * Revision 3.5 2001/11/07 00:51:47 korpela + * Added splitter version to database. + * Added max_wus_ondisk option. + * + * Revision 3.4 2001/08/17 22:20:54 korpela + * *** empty log message *** + * + * Revision 3.3 2001/08/17 01:22:31 korpela + * *** empty log message *** + * + * Revision 3.2 2001/08/17 01:16:53 korpela + * *** empty log message *** + * + * Revision 3.1 2001/08/16 23:42:08 korpela + * Mods for splitter to make binary workunits. + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.18 2000/12/01 01:13:29 korpela + * *** empty log message *** + * + * Revision 2.17 1999/06/07 21:00:52 korpela + * *** empty log message *** + * + * Revision 2.16 1999/03/27 16:19:35 korpela + * *** empty log message *** + * + * Revision 2.15 1999/03/05 01:47:18 korpela + * Added data_class field. + * + * Revision 2.14 1999/02/22 22:21:09 korpela + * added -nodb option + * + * Revision 2.13 1999/02/11 16:46:28 korpela + * Added db access functions. + * + * Revision 2.12 1999/01/04 22:27:55 korpela + * Updated return codes. + * + * Revision 2.11 1998/12/14 23:41:44 korpela + * Added subband_base to work unit header. + * Changed frequency calculation. + * + * Revision 2.10 1998/12/14 21:55:07 korpela + * Added fft_len and ifft_len to work unit header. + * + * Revision 2.9 1998/11/13 23:58:52 korpela + * Modified for move of name field between structures. + * + * Revision 2.8 1998/11/13 22:18:12 davea + * *** empty log message *** + * + * Revision 2.7 1998/11/10 01:55:26 korpela + * Server requires a CR at the end of a WU file + * ??? + * + * Revision 2.6 1998/11/10 00:02:44 korpela + * Moved remaining wuheader fields into a WU_INFO structure. + * + * Revision 2.5 1998/11/05 21:33:02 korpela + * Fixed angle_range bug. + * + * Revision 2.4 1998/11/05 21:18:41 korpela + * Moved name field from header to seti header. + * + * Revision 2.3 1998/11/02 21:20:58 korpela + * Modified for (internal) integer receiver ID. + * + * Revision 2.2 1998/11/02 18:45:39 korpela + * Changed location of timecvt.h + * + * Revision 2.1 1998/11/02 16:38:29 korpela + * Variable type changes. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.2 1998/10/30 20:26:03 korpela + * Bug Fixes. Now mostly working. + * + * Revision 1.1 1998/10/27 01:01:16 korpela + * Initial revision + * + * + */ diff --git a/splitter/mb_wufiles.h b/splitter/mb_wufiles.h new file mode 100644 index 0000000..5fb95e2 --- /dev/null +++ b/splitter/mb_wufiles.h @@ -0,0 +1,46 @@ +/* + * + * Functions for managing wufiles and their data + * + * $Id: mb_wufiles.h,v 1.1.2.2 2007/04/25 17:20:28 korpela Exp $ + * + */ + + +extern std::vector > bin_data; + +int make_wu_headers(std::vector &tapebuffer, telescope_id tel, + std::vector &wuheader) ; +void write_wufile_blocks(int nbytes) ; +void rename_wu_files(); + +/* + * $Log: mb_wufiles.h,v $ + * Revision 1.1.2.2 2007/04/25 17:20:28 korpela + * *** empty log message *** + * + * Revision 1.1.2.1 2006/12/14 22:24:46 korpela + * *** empty log message *** + * + * Revision 1.2 2003/08/05 17:23:45 korpela + * More work on database stuff. + * Further tweaks. + * + * Revision 1.1 2003/06/03 00:23:44 korpela + * + * Again + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.1 1998/11/02 16:41:21 korpela + * Minor Change. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.1 1998/10/27 01:13:16 korpela + * Initial revision + * + * + */ diff --git a/splitter/message.cpp b/splitter/message.cpp new file mode 100644 index 0000000..d15181e --- /dev/null +++ b/splitter/message.cpp @@ -0,0 +1,65 @@ +/* + * Functions for sending messages to stderr and log files. + * + * $Id: message.cpp,v 1.2.4.2 2006/12/14 22:24:46 korpela Exp $ + */ + +#include "sah_config.h" +#include +#include +#include + +#include "boinc_db.h" +#include "sched_config.h" +#include "sched_msgs.h" +#include "splitter.h" + +void message(char *msg) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"%s %s",tapeheaders[0].name,msg); +} + + + +/* + * $Log: message.cpp,v $ + * Revision 1.2.4.2 2006/12/14 22:24:46 korpela + * *** empty log message *** + * + * Revision 1.2.4.1 2006/01/13 00:37:57 korpela + * Moved splitter to using standard BOINC logging mechanisms. All stderr now + * goes to "error.log" + * + * Added command line parameters "-iterations=" (number of workunit groups to + * create before exiting), "-trigger_file_path=" (path to the splitter_stop trigger + * file. Default is /disks/setifiler1/wutape/tapedir/splitter_stop). + * + * Reduced deadlines by a factor of three. We now need a 30 MFLOP machine to meet + * the deadline. + * + * Revision 1.2 2003/09/11 18:53:38 korpela + * *** empty log message *** + * + * Revision 1.1 2003/07/29 20:35:43 korpela + * + * renames .C files to .cpp + * + * Revision 1.1 2003/06/03 00:16:14 korpela + * + * Initial splitter under CVS control. + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.2 2000/12/01 01:13:29 korpela + * *** empty log message *** + * + * Revision 2.1 1998/11/02 16:41:21 korpela + * Minor Change. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.1 1998/10/27 00:56:16 korpela + * Initial revision + * + */ diff --git a/splitter/message.h b/splitter/message.h new file mode 100644 index 0000000..6c51713 --- /dev/null +++ b/splitter/message.h @@ -0,0 +1,40 @@ +/* + * Functions for sending messages to stderr and log files. + * + * $Id: message.h,v 1.1.4.1 2006/01/13 00:37:57 korpela Exp $ + */ + +#include "sched_msgs.h" + +void message(char *msg); + +/* + * $Log: message.h,v $ + * Revision 1.1.4.1 2006/01/13 00:37:57 korpela + * Moved splitter to using standard BOINC logging mechanisms. All stderr now + * goes to "error.log" + * + * Added command line parameters "-iterations=" (number of workunit groups to + * create before exiting), "-trigger_file_path=" (path to the splitter_stop trigger + * file. Default is /disks/setifiler1/wutape/tapedir/splitter_stop). + * + * Reduced deadlines by a factor of three. We now need a 30 MFLOP machine to meet + * the deadline. + * + * Revision 1.1 2003/06/03 00:16:14 korpela + * + * Initial splitter under CVS control. + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.1 1998/11/02 16:41:21 korpela + * Minor Change. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.1 1998/10/27 01:09:00 korpela + * Initial revision + * + */ diff --git a/splitter/polyphase.cpp b/splitter/polyphase.cpp new file mode 100644 index 0000000..57cbdd8 --- /dev/null +++ b/splitter/polyphase.cpp @@ -0,0 +1,149 @@ + +#include "sah_config.h" +#include +#include +#include +#include +#include +#include +#include + +#include "splitparms.h" +#include "splittypes.h" +#include "splitter.h" +#include "fftw.h" +#include "wufiles.h" +#include "polyphase.h" +#include "dotransform.h" + +/* buffer for fft input/output */ +//float databuf[FFT_LEN*2]; + +/* buffer for ftt output before data writes, needs to be multiple + * of three bytes long for encode to work. + */ +#define SAMPLES_PER_OBUF (FFT_LEN*2*3/CHAR_BIT) + +extern unsigned char output_buf[NSTRIPS][SAMPLES_PER_OBUF]; + +double *filter_r, *filter_i; +float *f_data; + +extern int obuf_pos; /* Tracks current postition in the output buffers */ + +void make_FIR (int n_points, int M, int window, double *output) { + /* Create Mth band lowpass FIR filter, n_points long. */ + + /* Modify this to give 8-bit quantized filter. */ + /* Also generate Hilbert transformed filter */ + + int n; + double q, p; + + for (n=0; n TAPE_DATA_SIZE) { + // End of frame crossed need to trasfer correctly + end_trans.frame++; + end_trans.byte-=TAPE_DATA_SIZE; + nsamp=(TAPE_DATA_SIZE-start_trans.byte)*(CHAR_BIT/2); + assert((nsamp+end_trans.byte*(CHAR_BIT/2)) == FFT_LEN); + splitter_bits_to_float((unsigned short *)TBUF_OFFSET(start_trans.frame,start_trans.byte), + databuf, nsamp); + splitter_bits_to_float((unsigned short *)TBUF_OFFSET(end_trans.frame,0),databuf+nsamp*2, + end_trans.byte*(CHAR_BIT/2)); + } else { + splitter_bits_to_float((unsigned short *)TBUF_OFFSET(start_trans.frame,start_trans.byte), + databuf,FFT_LEN); + } + polyphase_seg(databuf); + // Go on to next transform + start_trans=end_trans; + } + // Check if we're at the end of the wu file. If so we print less bytes + if ((end_trans.frame>=end_of_wu->frame) && + (end_trans.byte>=end_of_wu->byte)) { + write_wufile_blocks(NBYTES % SAMPLES_PER_OBUF); + } else { + write_wufile_blocks(SAMPLES_PER_OBUF); + } + } while (!((end_trans.frame>=end_of_wu->frame) && (end_trans.byte>=end_of_wu->byte))); + + // Move the data in the buffer so we don't have to reread portions of the + // tape. + // + { + unsigned char *record_offset; + int copysize; + end_of_wu->frame-=WU_OVERLAP_FRAMES; + records_in_buffer=TAPE_RECORDS_IN_BUFFER- + (end_of_wu->frame/TAPE_FRAMES_PER_RECORD); + record_offset=tapebuffer+ + (end_of_wu->frame/TAPE_FRAMES_PER_RECORD)*TAPE_RECORD_SIZE; + copysize=records_in_buffer*TAPE_RECORD_SIZE; + bcopy(record_offset,tapebuffer,copysize); + } +} + + diff --git a/splitter/polyphase.h b/splitter/polyphase.h new file mode 100644 index 0000000..0393c38 --- /dev/null +++ b/splitter/polyphase.h @@ -0,0 +1,26 @@ +#define NONE 0 +#define WELCH 1 +#define HANNING 2 + +#define N_WINDOWS 8 +#define P_FFT_LEN 256 + +/* buffer for fft input/output */ +extern float databuf[FFT_LEN*2]; + +/* buffer for ftt output before data writes, needs to be multiple + * of three bytes long for encode to work. + */ +#define SAMPLES_PER_OBUF (FFT_LEN*2*3/CHAR_BIT) +#define TBUF_OFFSET(frame,byte) (tapebuffer+(frame)*TAPE_FRAME_SIZE+(byte)) +extern unsigned char output_buf[NSTRIPS][SAMPLES_PER_OBUF]; + +extern double *filter_r, *filter_i; +extern float *f_data; + +extern int obuf_pos; /* Tracks current postition in the output buffers */ + +void make_FIR (int n_points, int M, int window, double *output); +void polyphase_seg(float *data); +void do_polyphase(buffer_pos_t *start_of_wu, buffer_pos_t *end_of_wu); + diff --git a/splitter/randomdata.cpp b/splitter/randomdata.cpp new file mode 100644 index 0000000..094315d --- /dev/null +++ b/splitter/randomdata.cpp @@ -0,0 +1,77 @@ +#include "sah_config.h" +#include +#include +#include +#include +#include +#include + +#define NUM_FRAMES 200L +#define FRAME_DATA_SIZE (1024L*1024) +#define HEADER_SIZE 1024 +#define FILESIZE (NUM_FRAMES*(FRAME_DATA_SIZE+HEADER_SIZE)) + +char header[HEADER_SIZE]; + +int main(void) { + int i; + int datapos=0; + int frameseq=0; + long written=0; + int on=0; + struct tm *tm; + unsigned char data; + + char tmpstr[256]; + char telstr[256]; + double time0=(double)time(0); + time_t clock; + + srandom(time(0)); + + for (written=0;writtentm_year,tm->tm_yday,tm->tm_hour,tm->tm_min,tm->tm_sec,(int)((time0-floor(time0))*100)); + strcpy(header+headerpos,tmpstr); + headerpos+=strlen(tmpstr)+1; + if (!((frameseq-1)%5)) { + sprintf(telstr,"TELSTR=%.2d%.3d%.2d%.2d%.2d 0.0 0.0 15.0",tm->tm_year,tm->tm_yday,tm->tm_hour,tm->tm_min,tm->tm_sec); + } + strcpy(header+headerpos,telstr); + headerpos+=strlen(telstr)+1; + strcpy(header+headerpos,"RECEIVER=ao1420"); + headerpos+=strlen("RECEIVER=ao1420")+1; + strcpy(header+headerpos,"SAMPLERATE=2.5000"); + headerpos+=strlen("SAMPLERATE=2.5000")+1; + strcpy(header+headerpos,"CENTERFREQ=1420.0"); + headerpos+=strlen("CENTERFREQ=1420.0")+1; + strcpy(header+headerpos,"VER=1.00"); + headerpos+=strlen("VER=1.00")+1; + strcpy(header+headerpos,"NUMRINGBUFS=4"); + headerpos+=strlen("NUMRINGBUFS=4")+1; + strcpy(header+headerpos,"NUMDISKBUFS=2"); + headerpos+=strlen("NUMDISKBUFS=2")+1; + strcpy(header+headerpos,"EOH="); + write(stdout->_file, header, HEADER_SIZE); + for(i=0;i_file, &data, 1); + } + time0+=(1024.0*1024.0*4.0/2.5e6); + } +} + diff --git a/splitter/readheader.cpp b/splitter/readheader.cpp new file mode 100644 index 0000000..6a82fc2 --- /dev/null +++ b/splitter/readheader.cpp @@ -0,0 +1,225 @@ +/* + * Functions for reading tape and work unit headers + * + * This file currently assumes that the reciever is at Arecibo. + * + * $Id: readheader.cpp,v 1.3.4.2 2006/12/14 22:24:47 korpela Exp $ + * + */ + +#include "sah_config.h" +#include +#include +#include +#include +#include +#include + +#include "splitter.h" +#include "splitparms.h" +#include "splittypes.h" +#include "message.h" +#include "timecvt.h" +#include "coordcvt.h" + +/* Read a tape header at buffer into a tapeheader_t */ +int read_tape_header(char *buffer, tapeheader_t *header) +{ + static char *receivers[]={"","synthetic","ao1420"}; + int done=0,len; + int pos=0,i; + char tmpstr[256]; + double dummy; + unsigned int firstdata; + + do { + len=strlen(buffer+pos)+1; + if (!strncmp(buffer+pos,"EOH=",4)) { + done=1; + } else if (!strncmp(buffer+pos,"NAME=",5)) { + strncpy(tmpstr,buffer+pos+5,36); + i=0; + while(!isalnum(tmpstr[i])) i++; + strncpy(header->name,tmpstr+i,36); + } else if (!strncmp(buffer+pos,"RCDTYPE=",8)) { + sscanf(buffer+pos+8,"%d",&(header->rcdtype)); + } else if (!strncmp(buffer+pos,"FRAMESEQ=",9)) { + sscanf(buffer+pos+9,"%lu",&(header->frameseq)); + } else if (!strncmp(buffer+pos,"DATASEQ=",8)) { + sscanf(buffer+pos+8,"%lu",&(header->dataseq)); + } else if (!strncmp(buffer+pos,"NUMRINGBUFS=",12)) { + sscanf(buffer+pos+12,"%d",&(header->numringbufs)); + } else if (!strncmp(buffer+pos,"NUMDISKBUFS=",12)) { + sscanf(buffer+pos+12,"%d",&(header->numdiskbufs)); + } else if (!strncmp(buffer+pos,"MISSED=",7)) { + sscanf(buffer+pos+7,"%d",&(header->missed)); + } else if (!strncmp(buffer+pos,"AST=",4)) { + sscanf(buffer+pos+4,"%2d%3d%2d%2d%2d%2d", + &(header->st.y), &(header->st.d), &(header->st.h), + &(header->st.m), &(header->st.s), &(header->st.c)); + header->st.tz=AST; + } else if (!strncmp(buffer+pos,"TELSTR=",7)) { + sscanf(buffer+pos+7,"%2d%3d%2d%2d%2d %lf %lf %lf", + &(header->telstr.st.y), &(header->telstr.st.d), + &(header->telstr.st.h), &(header->telstr.st.m), + &(header->telstr.st.s), &(header->telstr.az), + gregorian?&(header->telstr.alt):&dummy, + gregorian?&dummy:&(header->telstr.alt)); + header->telstr.alt=90.0-header->telstr.alt; + header->telstr.st.tz=AST; + header->telstr.st.c=0; + } else if (!strncmp(buffer+pos,"RECEIVER=",9)) { + i=1; + while ((!strstr(buffer+pos+9,receivers[i])) && (++isource=0; + } else { + header->source=i; + } + } else if (!strncmp(buffer+pos,"CENTERFREQ=",11)) { + sscanf(buffer+pos+11,"%lf",&(header->centerfreq)); + header->centerfreq*=1e6; + } else if (!strncmp(buffer+pos,"SAMPLERATE=",11)) { + sscanf(buffer+pos+11,"%lf",&(header->samplerate)); + header->samplerate*=1e6; + } else if (!strncmp(buffer+pos,"VER=",4)) { + strncpy(&(header->version[0]),&(buffer[pos+4]),16); + } else if (len>1) { + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Unknown header field: %40s\n",buffer+pos); + } + pos+=len; + } while (!done && (posst)); + header->st.jd-=(float)RECORDER_BUFFER_SAMPLES/header->samplerate/86400; + st_time_convert(&(header->telstr.st)); + telstr_coord_convert(&(header->telstr),ARECIBO_LAT,ARECIBO_LON); + +/* + * Fix a bug in recorder versions prior to 1.30 + */ + + if (atof(&(header->version[0]))<1.299) { + header->centerfreq-=2.0; + } + +/* + * Check for blank tape + */ + firstdata=*(unsigned int *)(buffer+TAPE_HEADER_SIZE); + if (!(firstdata & 0x55555555) || !(firstdata & 0xaaaaaaaa) || + ((firstdata & 0x55555555) == 0x55555555) || + ((firstdata & 0xaaaaaaaa) == 0xaaaaaaaa)) { + header->missed++; + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Possible data problem...data[0] = 0x%x\n",firstdata); + } + + return(1); +} + +/* Read a work unit header from a FILE into a wuheader_t */ +//int read_wu_header(FILE *file, wuheader_t *header) { +/* to be implemented. Don't need it yet. */ +// return(0); +//} + +int parse_tape_headers(unsigned char *tapebuffer, tapeheader_t *tapeheaders) { + int i; + + for (i=0;i +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "util.h" +#include "splitparms.h" +#include "splitter.h" +#include "message.h" +#include "readheader.h" +#include "readtape.h" +#include "sqlrow.h" +#include "sqlblob.h" +#include "sqlapi.h" +#include "db_table.h" +#include "schema_master.h" +#include "str_util.h" +#include "str_replace.h" + +int is_tape; + +static tape tape_info; + +int current_record; +static int tape_fd; +struct mtget tape_status; + +static void update_checkpoint() { + FILE *file=fopen("rcd.chk","w"); + if (file) { + fprintf(file,"%d\n",current_record); + fclose(file); + } +} + +int read_checkpoint() { + FILE *file=fopen("rcd.chk","r"); + int retval=0; + if (file) { + fscanf(file,"%d",&retval); + fclose(file); + } + return(retval); +} + +int tape_busy() { +/* Check if tape is busy. If so return 1 else return 0 + */ + if (is_tape) { + if (ioctl(tape_fd,MTIOCGET,&tape_status) != -1) { + return (tape_status.mt_dsreg); + } else { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Unable to get tape status\n"); + return (1); + } + } else { + return (0); + } +} + +int tape_eject() { +/* Rewind and eject the tape. Return 1 if sucessful else return 0 + */ + struct mtop op={MTOFFL,1}; + + close(tape_fd); + if (is_tape) { + while (tape_busy()) sleep(1); + if (ioctl(tape_fd,MTIOCTOP,&op)==-1) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Unable to eject tape\n"); + return(0); + } else { + return(1); + } + } else { + return(1); + } +} + + +int tape_rewind() { +/* Rewind to beginning of tape. Return 1 if sucessful, 0 if failure + */ + struct mtop op={MTREW, 1}; + if (is_tape) { + while (tape_busy()) sleep(1); + if (ioctl(tape_fd,MTIOCTOP,&op)!=-1) { + current_record=0; + update_checkpoint(); + } else { + current_record=-1; + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Tape rewind failed\n"); + } + } else { + if (lseek(tape_fd, 0, SEEK_SET)!=-1) { + current_record=0; + update_checkpoint(); + } else { + current_record=-1; + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"File rewind failed\n"); + } + } + return (!current_record); +} + + + +int open_tape_device(char *device) { +/* opens a device, checks if it is a tape device. If so, sets is_tape + * flag. If not, it resets the flag. All tape routines check this flag + * so routines will work for both tapes and files + */ + + + int fd, errcnt=0; + struct mtop op={MTNOP,1}; + + if ((fd=open(device, O_RDONLY|0x2000, 0777))!=-1) { + tape_fd=fd; + if (ioctl(tape_fd,MTIOCGET,&tape_status) != -1) { + is_tape = 1; + } else { + is_tape = 0; + } + while (!norewind && !tape_rewind() && errcnt<10 ) errcnt++; + if (!nodb && resumetape) { + tape_rewind(); + fill_tape_buffer(tapebuffer,TAPE_RECORDS_IN_BUFFER); + parse_tape_headers(tapebuffer, &(tapeheaders[0])); + if (!tape_info.id) { + if (!tape_info.fetch(std::string("where name=\'")+tapeheaders->name+"\'")) { + tape_info.start_time=tapeheaders->st.jd; + tape_info.last_block_time=tapeheaders->st.jd; + tape_info.last_block_done=tapeheaders->frameseq; + strlcpy(tape_info.name,tapeheaders->name,sizeof(tape_info.name)); + tape_info.insert(); + } + } + startblock=tape_info.last_block_done/TAPE_FRAMES_PER_RECORD; + } + if (norewind) { + startblock=MAX(read_checkpoint()-TAPE_RECORDS_IN_BUFFER,0); + tape_rewind(); + } + if (startblock) { + return select_record(startblock); + } + return (1); + } else { + perror( NULL ); + return (0); + } +} + +int select_record(int record_number) { +/* seeks to a specific record number returns 1 if successful */ + int diff; + struct mtop op; + char tmpstr[100]; + off64_t off,offset; + + if ((current_record<0) && !tape_rewind()) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Tape error: position lost and unable to rewind!\n"); + return(0); + } + + diff=record_number-current_record; + + if (is_tape) { + if (diff==0) return (1); + if (diff>0) { + op.mt_op=MTFSR; + op.mt_count=diff; + } else { + op.mt_op=MTBSR; + op.mt_count=diff; + } + if (ioctl(tape_fd,MTIOCTOP,&op)==-1) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Tape error: unable to position to record %d errno=%d\n", + record_number,errno); + current_record=-1; + return(0); + } else { + current_record+=diff; + update_checkpoint(); + return(1); + } + } else { + current_record=record_number; + update_checkpoint(); + offset = record_number; + offset *= TAPE_RECORD_SIZE; + //fprintf( stderr, "offset: %lld", offset ); + off=lseek64(tape_fd,offset,SEEK_SET) ; + //fprintf( stderr, "off: %lld", offset ); + return (off != -1); + } +} + +int tape_read_record(char *buffer) { + int bytesread=0; + int i; + + while (tape_busy()) sleep(1); + + do { + i=read(tape_fd,buffer+bytesread,TAPE_RECORD_SIZE); + if (i>0) bytesread+=i; + } while ((bytesread0)); + + if (i==0) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"End of tape. Please insert new tape\n"); + current_record=-1; + return(0); + } + + if (i<0) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Tape error.\n"); + current_record=-1; + return(0); + } + + current_record++; + update_checkpoint(); + return(1); +} + +int fill_tape_buffer(unsigned char *buffer, int n_records) { + int i; + long record; + char tmpstr[100]; + + for (i=0;i + +#define WU_SUBDIR "/download" + +#define SPLITTER_VERSION 0x0012 +#define MAX_WUS_ONDISK 500000 +#define N_SIMULT_SPLITTERS 6 + +/* Work Unit Parameters */ +#define NBYTES 262144L +#define NSAMPLES (NBYTES*CHAR_BIT/2) +#define MAX_POSITION_HISTORY 40 +#define WU_FILESIZE (360L*1024) + +/* FFT Parameters */ +#define FFT_LEN 2048 +#define IFFT_LEN 8 +#define NSTRIPS (FFT_LEN/IFFT_LEN) + +/* Tape format parameters */ +#define TAPE_HEADER_SIZE 1024L +#define TAPE_DATA_SIZE 1048576L +#define TAPE_FRAMES_PER_RECORD 8L +#define TAPE_FRAME_SIZE (TAPE_HEADER_SIZE+TAPE_DATA_SIZE) +#define TAPE_RECORD_SIZE (TAPE_FRAMES_PER_RECORD*TAPE_FRAME_SIZE) +#define TAPE_BUFFER_SIZE (((NSTRIPS*NBYTES*7/4)/TAPE_RECORD_SIZE+1)*TAPE_RECORD_SIZE) +#define TAPE_RECORDS_IN_BUFFER (TAPE_BUFFER_SIZE/TAPE_RECORD_SIZE) +#define TAPE_FRAMES_IN_BUFFER (TAPE_RECORDS_IN_BUFFER*8) +#define TAPE_FRAMES_PER_WU (NBYTES*NSTRIPS/TAPE_DATA_SIZE) +#define WU_OVERLAP_RECORDS 2 +#define WU_OVERLAP_FRAMES (TAPE_FRAMES_PER_RECORD*WU_OVERLAP_RECORDS) +#define WU_OVERLAP_BYTES (WU_OVERLAP_FRAMES*TAPE_DATA_SIZE) +#define RECORDER_BUFFER_BYTES (1024L*1024L) +#define RECORDER_BUFFER_SAMPLES (RECORDER_BUFFER_BYTES*4) + + +/* Time Zone Parameters */ +#define UTC 0.0 +#define AST (UTC-4.0) + +/* Arecibo Observatory Parameters */ +#define ARECIBO_LAT 18.3538056 +#define ARECIBO_LON (-66.7552222) + +#endif +/* + * $Log: splitparms.h,v $ + * Revision 1.10 2004/11/23 21:26:29 jeffc + * *** empty log message *** + * + * Revision 1.9 2004/08/14 04:44:26 jeffc + * *** empty log message *** + * + * Revision 1.8 2004/06/16 20:57:19 jeffc + * *** empty log message *** + * + * Revision 1.7 2004/05/22 18:12:18 korpela + * *** empty log message *** + * + * Revision 1.6 2003/10/27 17:53:21 korpela + * *** empty log message *** + * + * Revision 1.5 2003/09/26 20:48:51 jeffc + * jeffc - merge in branch setiathome-4_all_platforms_beta. + * + * Revision 1.3.2.1 2003/09/22 17:39:34 korpela + * *** empty log message *** + * + * Revision 1.4 2003/09/22 17:05:38 korpela + * *** empty log message *** + * + * Revision 1.3 2003/09/11 18:53:38 korpela + * *** empty log message *** + * + * Revision 1.2 2003/08/05 17:23:42 korpela + * More work on database stuff. + * Further tweaks. + * + * Revision 1.1 2003/06/03 00:23:40 korpela + * + * Again + * + * Revision 3.1 2001/11/07 00:51:47 korpela + * Added splitter version to database. + * Added max_wus_ondisk option. + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.9 2000/12/01 01:13:29 korpela + * *** empty log message *** + * + * Revision 2.8 1999/10/20 19:20:26 korpela + * *** empty log message *** + * + * Revision 2.7 1999/06/07 21:00:52 korpela + * *** empty log message *** + * + * Revision 2.6 1999/03/27 16:19:35 korpela + * *** empty log message *** + * + * Revision 2.5 1999/03/05 01:47:18 korpela + * Added data_class field. + * + * Revision 2.4 1999/02/23 18:57:09 korpela + * *** empty log message *** + * + * Revision 2.3 1999/02/22 22:21:09 korpela + * Changed version number. + * + * Revision 2.2 1999/02/11 16:46:28 korpela + * Added WU_FILESIZE, RECORDER_BUFFER_BYTES, RECORDER_BUFFER_SAMPLES.` + * + * Revision 2.1 1998/11/02 16:38:29 korpela + * Variable type changes. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.4 1998/10/27 01:10:04 korpela + * Bug fixes. + * + * Revision 1.3 1998/10/19 23:06:40 korpela + * Added UTC and AST definition. + * Added ARECIBO_LAT and ARECIBO_LON definitions. + * + * Revision 1.2 1998/10/16 19:22:14 korpela + * Reduced WU file size from 512K to 256K. + * + * Revision 1.1 1998/10/15 16:39:51 korpela + * Initial revision + * + */ + diff --git a/splitter/splitter.cpp b/splitter/splitter.cpp new file mode 100644 index 0000000..c4cea44 --- /dev/null +++ b/splitter/splitter.cpp @@ -0,0 +1,717 @@ +/* + * + * The splitter main program. + * + * $Id: splitter.cpp,v 1.22.2.6 2007/06/06 15:58:30 korpela Exp $ + * + */ + +#include "sah_config.h" +#undef USE_MYSQL +#include +#include +#include +#include +#include +#include +#include + +#include "boinc_db.h" +#include "crypt.h" +#include "backend_lib.h" +#include "sched_config.h" +#include "splitparms.h" +#include "splittypes.h" +#include "splitter.h" +#include "validrun.h" +#include "makebufs.h" +#include "readtape.h" +#include "readheader.h" +#include "wufiles.h" +#include "dotransform.h" +#include "polyphase.h" +#include "message.h" +#include "sqlrow.h" +#include "sqlapi.h" +#include "db/db_table.h" +#include "db/schema_master.h" +#include "db/app_config.h" + +extern "C" { + int sqldetach(); +} + +char trigger_file_path[1024]="/disks/setifiler1/wutape/tapedir/splitter_stop"; + +SCHED_CONFIG boinc_config; +DB_APP app; +R_RSA_PRIVATE_KEY key; + + +// TEMPLATE DEFS ------------------------------------------------------ +// IMPORTANT: a change to a template should *always* include a change +// to the template filename. Only the result template is used now. +const char *wu_template_filename_id = "wu_0.xml"; +const char *wu_template= + "\n" + " 0\n" + "\n" + "\n" + " \n" + " 0\n" + " work_unit.sah\n" + " \n" + "\n"; + +const char *result_template_filename_id = "result_0.xml"; +const char *result_template= + "\n" + " \n" + " \n" + " \n" + " 65536\n" + " http://setiboincdata.ssl.berkeley.edu/sah_cgi/file_upload_handler\n" + "\n" + "\n" + " \n" + " \n" + " result.sah\n" + " \n" + "\n"; +// END TEMPLATE DEFS -------------------------------------------------- + +unsigned char *tapebuffer; /* A buffer for a tape section */ +workunit wuheaders[NSTRIPS]; +tapeheader_t tapeheaders[TAPE_FRAMES_IN_BUFFER]; +int max_wus_ondisk=MAX_WUS_ONDISK; +int nodb; +int noencode; +int resumetape; +int norewind; +int startblock; +int dataclass; +int atnight; +int gregorian; +int output_xml; +int polyphase; +int iters=-1; +int filter_window = 0; +double start_time; +double stop_time; +unsigned long minvfsbuf=-1; +char wd[1024]; +//char * scidb = NULL; +char * projectdir = NULL; + +APP_CONFIG sah_config; + +//const char *result_template_filename="projectdir"/"SAH_APP_NAME"_result.tpl"; +char result_template_filename[1024]; +char result_template_filepath[1024]; +char wu_template_filename[1024]; + +int check_for_halt(); +int wait_until_night(); +int check_free_disk_space(); +int wait_for_db_wus_ondisk(); + +void cprint(char *p) { + printf("%s\n",p); +} + +/* wulog: File for logging names of completed wu files */ +/* errorlog: File for logging errors */ + +FILE *wulog,*errorlog; +buffer_pos_t start_of_wu,end_of_wu; /* position of start and end of wu in + tape buffer */ +int seqno; +int records_in_buffer; + +void cleanup(void) { + FILE *tmpfile; + if ((tmpfile=fopen("seqno.dat","w"))) { + fprintf(tmpfile,"%d\n",seqno); + fclose(tmpfile); + } else { + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Unable to open seqno.dat for write\n"); + } +} + + +int process_command_line(int argc, char *argv[],char **tape_device, + int *norewind, int *startblock, int *resumetape, + int *nodb, int *dataclass, int *atnight, + int *max_wus_ondisk, char **projectdir, + int *iters) { + int nargs=0,i; + char *ep; + for (i=1;itm_wday>0) && (lt->tm_wday<6) && (lt->tm_hour>8) && (lt->tm_hour<18)) { + sleep(100); + } + } while ((lt->tm_wday>0) && (lt->tm_wday<6) && (lt->tm_hour>8) && (lt->tm_hour<18)); + return 0; +} + +int check_free_disk_space() { + struct statvfs vfsbuf; + + /* check disk free space */ + statvfs("wu_inbox/.",&vfsbuf); + if (vfsbuf.f_bavail < (100000*1024/vfsbuf.f_frsize)) { + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Not enough free disk space in working directory to continue\n"); + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Not enough free disk space in working directory to continue\n"); + exit(EXIT_FAILURE); + } + return 0; +} + +int wait_for_db_wus_ondisk() { + int wus_ondisk,rv; + + // The boinc db query below takes a long time. Until we fix this, + // we will do it only every 100 times into this routine. All other + // calls here will assume that we need to add WUs. -- jeffc + static int check_count = 100; + if (check_count < 100) { + check_count++; + return 0; + } else { + check_count = 0; + } + + if (boinc_db.open(boinc_config.db_name,boinc_config.db_host,boinc_config.db_user,boinc_config.db_passwd)) { + boinc_db.print_error("boinc_db.open"); + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"boinc_db.open\n"); + exit(1); + } + do { + DB_RESULT boinc_result; + char query[1024]; + sprintf(query,"where appid=%d and server_state=2",app.id); + rv=boinc_result.count(wus_ondisk,query); + if (rv) { + boinc_db.print_error("boinc_result.count"); + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"DB Error, unable to count workunits on disk\n"); + exit(EXIT_FAILURE); + } + check_for_halt(); + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"%d WUs ondisk\n", wus_ondisk); + if (wus_ondisk>sah_config.max_wus_ondisk) sleep(600); + } while (wus_ondisk>sah_config.max_wus_ondisk); + + return 0; +} + +/* + * $Log: splitter.cpp,v $ + * Revision 1.22.2.6 2007/06/06 15:58:30 korpela + * *** empty log message *** + * + * Revision 1.22.2.5 2006/12/14 22:24:48 korpela + * *** empty log message *** + * + * Revision 1.22.2.4 2006/11/08 20:16:26 vonkorff + * Fixes an error message. + * + * Revision 1.22.2.3 2006/11/07 19:26:37 vonkorff + * Fixed lcgf + * + * Revision 1.22.2.2 2006/01/13 00:37:58 korpela + * Moved splitter to using standard BOINC logging mechanisms. All stderr now + * goes to "error.log" + * + * Added command line parameters "-iterations=" (number of workunit groups to + * create before exiting), "-trigger_file_path=" (path to the splitter_stop trigger + * file. Default is /disks/setifiler1/wutape/tapedir/splitter_stop). + * + * Reduced deadlines by a factor of three. We now need a 30 MFLOP machine to meet + * the deadline. + * + * Revision 1.22.2.1 2005/08/01 21:16:25 jeffc + * *** empty log message *** + * + * Revision 1.22 2005/01/27 23:03:27 mattl + * + * commented out tf=0 in check_for_halt + * + * Revision 1.21 2004/12/27 20:48:54 jeffc + * *** empty log message *** + * + * Revision 1.20 2004/08/12 15:45:41 jeffc + * *** empty log message *** + * + * Revision 1.19 2004/07/09 22:35:39 jeffc + * *** empty log message *** + * + * Revision 1.18 2004/06/27 21:07:04 jeffc + * *** empty log message *** + * + * Revision 1.17 2004/06/20 18:56:48 jeffc + * *** empty log message *** + * + * Revision 1.16 2004/06/18 23:23:32 jeffc + * *** empty log message *** + * + * Revision 1.15 2004/06/16 20:57:19 jeffc + * *** empty log message *** + * + * Revision 1.14 2004/04/08 22:25:47 jeffc + * *** empty log message *** + * + * Revision 1.13 2004/01/22 00:57:53 korpela + * *** empty log message *** + * + * Revision 1.12 2004/01/01 18:42:01 korpela + * *** empty log message *** + * + * Revision 1.11 2003/12/03 23:46:41 korpela + * WU count is now only for SAH workunits. + * + * Revision 1.10 2003/11/25 21:59:52 korpela + * *** empty log message *** + * + * Revision 1.9 2003/11/01 20:54:02 korpela + * *** empty log message *** + * + * Revision 1.8 2003/10/24 16:57:03 korpela + * *** empty log message *** + * + * Revision 1.7 2003/09/26 20:48:51 jeffc + * jeffc - merge in branch setiathome-4_all_platforms_beta. + * + * Revision 1.5.2.2 2003/09/23 00:49:12 korpela + * *** empty log message *** + * + * Revision 1.5.2.1 2003/09/22 17:39:34 korpela + * *** empty log message *** + * + * Revision 1.6 2003/09/22 17:05:38 korpela + * *** empty log message *** + * + * Revision 1.5 2003/09/13 20:48:38 korpela + * directory reorg. Moved client files to ./client + * + * Revision 1.4 2003/09/11 18:53:38 korpela + * *** empty log message *** + * + * Revision 1.3 2003/08/13 23:18:47 korpela + * *** empty log message *** + * + * Revision 1.2 2003/08/05 17:23:42 korpela + * More work on database stuff. + * Further tweaks. + * + * Revision 1.1 2003/07/29 20:35:50 korpela + * + * renames .C files to .cpp + * + * Revision 1.2 2003/06/03 01:01:17 korpela + * + * First working splitter under CVS. + * + * Revision 1.1 2003/06/03 00:23:40 korpela + * + * Again + * + * Revision 3.6 2003/05/21 00:41:42 korpela + * *** empty log message *** + * + * Revision 3.5 2003/05/19 17:40:59 eheien + * *** empty log message *** + * + * Revision 3.4 2003/04/09 17:46:54 korpela + * *** empty log message *** + * + * Revision 3.3 2002/06/20 22:09:17 eheien + * *** empty log message *** + * + * Revision 3.2 2001/11/07 00:51:47 korpela + * Added splitter version to database. + * Added max_wus_ondisk option. + * + * Revision 3.1 2001/08/16 23:42:08 korpela + * Mods for splitter to make binary workunits. + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.7 2000/12/01 01:13:29 korpela + * *** empty log message *** + * + * Revision 2.6 1999/06/07 21:00:52 korpela + * *** empty log message *** + * + * Revision 2.5 1999/03/27 16:19:35 korpela + * *** empty log message *** + * + * Revision 2.4 1999/03/05 01:47:18 korpela + * Added dataclass paramter. + * + * Revision 2.3 1999/02/22 22:21:09 korpela + * added -nodb option + * + * Revision 2.2 1999/02/11 16:46:28 korpela + * Added some db access functions. + * + * Revision 2.1 1998/11/02 16:41:21 korpela + * Minor Change. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.2 1998/10/30 20:26:03 korpela + * Bug Fixes. Now mostly working. + * + * Revision 1.1 1998/10/27 00:58:16 korpela + * Initial revision + * + * + */ diff --git a/splitter/splitter.h b/splitter/splitter.h new file mode 100644 index 0000000..46b73b3 --- /dev/null +++ b/splitter/splitter.h @@ -0,0 +1,132 @@ +/* + * splitter.h + * + * Global definitions from the splitter main program. + * + * $Id: splitter.h,v 1.6.2.1 2006/01/13 00:37:58 korpela Exp $ + * + */ + +#ifndef SPLITTER_H +#define SPLITTER_H + +#include "splitparms.h" +#include "splittypes.h" + +#define MAX(x,y) ( ((x)<(y)) ? (y) : (x) ) +#define MIN(x,y) ( ((y)<(x)) ? (y) : (x) ) + +/* wulog: File for logging names of completed wu files */ +/* errorlog: File for logging errors */ +#include "boinc_db.h" +#include "crypt.h" +#include "backend_lib.h" +#include "sched_config.h" + +extern SCHED_CONFIG boinc_config; +extern DB_APP app; +extern R_RSA_PRIVATE_KEY key; +extern FILE *wulog,*errorlog; +extern workunit wuheaders[NSTRIPS]; +extern tapeheader_t tapeheaders[TAPE_FRAMES_IN_BUFFER]; +extern int noencode; +extern int dataclass; +extern int nodb; +extern int resumetape; +extern int startblock; +extern int norewind; +extern int output_xml; +extern int polyphase; +extern int wu_database_id[NSTRIPS]; +extern int gregorian; +extern char * projectdir; +extern char trigger_file_name[1024]; + + +/* Buffer that holds tape data */ +extern unsigned char *tapebuffer; + +/* Number of records remaining in the buffer after WU creations is complete */ +extern int records_in_buffer; + +extern const char *wu_template; +extern const char *result_template; +// jeffc +//extern const char *result_template_filename; +extern char result_template_filename[]; +extern char result_template_filepath[]; +extern char wu_template_filename[]; + +/* Persistant sequence number of wu file */ +extern int seqno; + +#endif + +/* + * $Log: splitter.h,v $ + * Revision 1.6.2.1 2006/01/13 00:37:58 korpela + * Moved splitter to using standard BOINC logging mechanisms. All stderr now + * goes to "error.log" + * + * Added command line parameters "-iterations=" (number of workunit groups to + * create before exiting), "-trigger_file_path=" (path to the splitter_stop trigger + * file. Default is /disks/setifiler1/wutape/tapedir/splitter_stop). + * + * Reduced deadlines by a factor of three. We now need a 30 MFLOP machine to meet + * the deadline. + * + * Revision 1.6 2004/07/09 22:35:39 jeffc + * *** empty log message *** + * + * Revision 1.5 2004/06/16 20:57:19 jeffc + * *** empty log message *** + * + * Revision 1.4 2003/09/26 20:48:52 jeffc + * jeffc - merge in branch setiathome-4_all_platforms_beta. + * + * Revision 1.2.2.1 2003/09/22 17:39:35 korpela + * *** empty log message *** + * + * Revision 1.3 2003/09/22 17:05:38 korpela + * *** empty log message *** + * + * Revision 1.2 2003/08/05 17:23:42 korpela + * More work on database stuff. + * Further tweaks. + * + * Revision 1.1 2003/06/03 00:23:40 korpela + * + * Again + * + * Revision 3.2 2003/05/19 17:40:59 eheien + * *** empty log message *** + * + * Revision 3.1 2001/08/16 23:42:08 korpela + * Mods for splitter to make binary workunits. + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.5 1999/10/20 19:20:26 korpela + * *** empty log message *** + * + * Revision 2.4 1999/03/05 01:47:18 korpela + * Added data_class field. + * + * Revision 2.3 1999/02/22 22:21:09 korpela + * Added nodb option + * + * Revision 2.2 1999/02/11 16:46:28 korpela + * Added startblock and norewind support, and wu_database_id. + * + * Revision 2.1 1998/11/02 16:41:21 korpela + * Minor Change. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.1 1998/10/27 01:10:32 korpela + * Initial revision + * + * + */ diff --git a/splitter/splittypes.h b/splitter/splittypes.h new file mode 100644 index 0000000..46e4b37 --- /dev/null +++ b/splitter/splittypes.h @@ -0,0 +1,111 @@ +/* splittypes.h + * + * Type definitions specific to the splitter. + * + * + * $Id: splittypes.h,v 1.4 2003/08/05 17:23:43 korpela Exp $ + * + */ +#ifndef SPLITTYPES_H +#define SPLITTYPES_H + +#include + +#include "splitparms.h" +#include "s_util.h" +#include "seti_header.h" + +//typedef struct wuheader { + //WU_INFO wuhead; + //SETI_WU_INFO wuinfo; +//} wuheader_t; + +typedef struct tapeheader { + char name[36]; + int rcdtype; + int numringbufs; + int numdiskbufs; + unsigned long frameseq; + unsigned long dataseq; + int missed; + TIME st; + SCOPE_STRING telstr; + int source; + double centerfreq,samplerate; + char version[16]; +} tapeheader_t; + +typedef struct buffer_pos { + int frame; + long byte; +} buffer_pos_t; + +#endif +/* + * $Log: splittypes.h,v $ + * Revision 1.4 2003/08/05 17:23:43 korpela + * More work on database stuff. + * Further tweaks. + * + * Revision 1.3 2003/07/29 20:35:51 korpela + * + * renames .C files to .cpp + * + * Revision 1.2 2003/06/03 01:01:17 korpela + * + * First working splitter under CVS. + * + * Revision 1.1 2003/06/03 00:23:41 korpela + * + * Again + * + * Revision 3.1 2003/05/19 17:40:59 eheien + * *** empty log message *** + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.5 1999/02/11 16:46:28 korpela + * Added startblock and norewind support, and wu_database_id. + * + * Revision 2.4 1998/11/10 00:02:44 korpela + * Moved remaining wuheader fields into a WU_INFO structure. + * + * Revision 2.3 1998/11/05 21:18:41 korpela + * Moved name field from header to seti header. + * + * Revision 2.2 1998/11/02 21:20:58 korpela + * Moved tape_version and encoding_type into SETI_WU_INFO. + * + * Revision 2.1 1998/11/02 16:38:29 korpela + * Variable type changes. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.7 1998/10/30 21:01:13 davea + * *** empty log message *** + * + * Revision 1.6 1998/10/27 01:10:58 korpela + * Modified tapeheader_t to match new tape header fields. + * + * Revision 1.5 1998/10/19 23:04:32 korpela + * Moved times in telstr_t into an st_t. + * Changed name of ast_t to st_t. + * Added time zone (tz) field to ast_t. + * + * Revision 1.4 1998/10/15 19:13:30 korpela + * Renamed "unix" fields to "unix_time" because of GCC #define. + * Added position_history field to wuheader_t. + * + * Revision 1.3 1998/10/15 18:58:50 korpela + * Added time_t unix to ast_t and telstr_t types. + * Changed times in wuheader_t to time_t types. + * + * Revision 1.2 1998/10/15 18:01:19 korpela + * Removed month field from ast_t and telstr_t. + * + * Revision 1.1 1998/10/15 16:20:24 korpela + * Initial revision + * + */ diff --git a/splitter/squarewave.cpp b/splitter/squarewave.cpp new file mode 100644 index 0000000..7ac379d --- /dev/null +++ b/splitter/squarewave.cpp @@ -0,0 +1,75 @@ +#include "sah_config.h" +#include +#include +#include +#include +#include +#include + +#define NUM_FRAMES 200L +#define FRAME_DATA_SIZE (1024L*1024) +#define HEADER_SIZE 1024 +#define FILESIZE (NUM_FRAMES*(FRAME_DATA_SIZE+HEADER_SIZE)) + +char header[HEADER_SIZE]; + +int main(void) { + int i; + int datapos=0; + int frameseq=0; + long written=0; + int on=0; + struct tm *tm; + char data; + + char tmpstr[256]; + char telstr[256]; + double time0=(double)time(0); + time_t clock; + + for (written=0;writtentm_year,tm->tm_yday,tm->tm_hour,tm->tm_min,tm->tm_sec,(int)((time0-floor(time0))*100)); + strcpy(header+headerpos,tmpstr); + headerpos+=strlen(tmpstr)+1; + if (!((frameseq-1)%5)) { + sprintf(telstr,"TELSTR=%.2d%.3d%.2d%.2d%.2d 0.0 0.0 15.0",tm->tm_year,tm->tm_yday,tm->tm_hour,tm->tm_min+(tm->tm_sec>57),(tm->tm_sec+2)%60); + } + strcpy(header+headerpos,telstr); + headerpos+=strlen(telstr)+1; + strcpy(header+headerpos,"RECEIVER=ao1420"); + headerpos+=strlen("RECEIVER=ao1420")+1; + strcpy(header+headerpos,"SAMPLERATE=2.5000"); + headerpos+=strlen("SAMPLERATE=2.5000")+1; + strcpy(header+headerpos,"VER=1.00"); + headerpos+=strlen("VER=1.00")+1; + strcpy(header+headerpos,"CENTERFREQ=1420.0"); + headerpos+=strlen("CENTERFREQ=1420.0")+1; + strcpy(header+headerpos,"NUMRINGBUFS=4"); + headerpos+=strlen("NUMRINGBUFS=4")+1; + strcpy(header+headerpos,"NUMDISKBUFS=2"); + headerpos+=strlen("NUMDISKBUFS=2")+1; + strcpy(header+headerpos,"EOH="); + write(stdout->_file, header, HEADER_SIZE); + for(i=0;i_file, &data, 1); + } + time0+=(1024.0*1024.0*4.0/2.5e6); + } +} + diff --git a/splitter/tools/disksplitter b/splitter/tools/disksplitter new file mode 100755 index 0000000..a4bc323 --- /dev/null +++ b/splitter/tools/disksplitter @@ -0,0 +1,121 @@ +#! /bin/tcsh -x + +set PATH=/opt/misc:/opt/misc/bin:/usr/ccs/bin:/usr/openwin/bin:/usr/openwin/bin/xview:/usr/lang:/usr/ucb:/bin:/usr/bin:/usr/local/bin:/usr/hosts:/usr/bin/X11:/usr/casual/sparc:/usr/etc:/usr/local/lib/tex/bin:/usr/local/lib/frame/bin:/disks/asimov/a/apps/informix/bin:.:/disks/albert/d/office/bin:/usr/ucb:/disks/albert/e/users/eurd/data_analysis/bin:/usr/local/lib/g++-include.bak:/disks/siren/a/users/seti/s4/siren/bin:/disks/albert/d/orfeus:/disks/albert/d/chips:/disks/asimov/a/apps/informix/bin:/usr/local/tex +# export PATH +set LD_LIBRARY_PATH=/usr/lib/X11:/usr/openwin/lib:/usr/lib:/lib:/disks/islay/a/users/korpela/bin/lib:/disks/asimov/a/apps/informix/lib:/disks/asimov/a/apps/informix/lib/esql +# export LD_LIBRARY_PATH +set INFORMIXDIR=/disks/asimov/a/apps/informix +# export INFORMIXDIR +set INFORMIXSERVER=ejk_tcp +# export INFORMIXSERVER + +set SPLIT_PROG_LOC=/disks/milkyway/a/users/anderson/seti/splitter/bin/ +set SPLIT_PROG_NAME=splitter +set SPLIT_LOG_LOC=/disks/milkyway/a/users/anderson/seti/sethi/hi_tape_logs/ +# set HI_TAPE_DIR=/disks/philmor/a/users/eheien/hitest/ +set SPLIT_TAPE_DIR=/disks/setifiler1/wutape/tapedir/ +set SPLIT_SUFFIX=.split +set HIDONE_SUFFIX=.hidone +set SPLITDONE_SUFFIX=.splitdone +set EMAIL_LIST="jeffc@ssl.berkeley.edu mattl@ssl.berkeley.edu" +set FOUND_FILE=0 +set HOST=`hostname` +set SPLIT_HALT_MSG=splitter_stop + +# Check to see if this machine is already running the splitter program +set PROG_RUNNING=`/usr/ucb/ps -auxww | grep "$SPLIT_PROG_NAME" | grep -v "disksplitter" | wc | awk '{print $1}'` +echo "$PROG_RUNNING" +if( $PROG_RUNNING > 1 ) then + echo "Splitter is already running on this machine. Quitting." + exit +endif + +# Get rid of all .split files here with HOSTNAME in them(?) + +while ( ! -f $SPLIT_TAPE_DIR$SPLIT_HALT_MSG ) + +set FOUND_FILE=0 +cd $SPLIT_TAPE_DIR + +set FILE_LIST=`ls . | grep ".tape" | grep -v "done" | grep -v "reading" | grep -v "hi" | grep -v "msg" | grep -v "split"` + +if( -z "$FILE_LIST" ) then + exit +endif + +foreach file ($FILE_LIST) + if ( $FOUND_FILE == 0 && ! -f $file$SPLITDONE_SUFFIX ) then + if( -f $file$SPLIT_SUFFIX ) then + set FOUND_FILE=0 + else + echo $HOST > $file$SPLIT_SUFFIX + set TAPE_FILE=$file + set SPLIT_FILE=$SPLIT_TAPE_DIR$file + set SPLIT_MARK_FILE=$SPLIT_TAPE_DIR$file$SPLIT_SUFFIX + set HI_DONE_FILE=$SPLIT_TAPE_DIR$file$HIDONE_SUFFIX + set SPLIT_DONE_FILE=$SPLIT_TAPE_DIR$file$SPLITDONE_SUFFIX + set FOUND_FILE=1 + endif + endif +end + +cd /mydisks/a/servers/splitter/ +/bin/rm -f error.log rcd.chk +touch error.log +touch rcd.chk + +if ( $FOUND_FILE == 0 ) then +# echo "" | /usr/ucb/mail -s"no more splitter tape files" $EMAIL_LIST + exit +else + if( -f /disks/milkyway/a/users/anderson/seti/watchdogs/go_spliiter ) then + /bin/rm -f wu_inbox/.* +#set START_MSG=`echo "Splitter is starting on tape" $SPLIT_FILE "on" $HOST` + cat error.log rcd.chk | /usr/ucb/mail -s""$HOST" splitter starting" $EMAIL_LIST + /bin/nice $SPLIT_PROG_LOC$SPLIT_PROG_NAME $SPLIT_FILE $1 -resume >>& splitterlog + set TEMP=`grep -i "end" error.log` + if( "$TEMP" != "" ) then + sleep 60 # wait for it to finish moving the files from wu_inbox + cat error.log rcd.chk | /usr/ucb/mail -s""$HOST" splitter finished" $EMAIL_LIST + /bin/rm -f error.log rcd.chk + /bin/rm -f wu_inbox/.* + /bin/rm -f $SPLIT_MARK_FILE + if( -f $HI_DONE_FILE ) then + /bin/rm -f $HI_DONE_FILE + /bin/rm -f `cd $SPLIT_TAPE_DIR; ls -l | grep $TAPE_FILE | awk '{print $NF}'` + /bin/rm -f $SPLIT_FILE + else + touch -f $SPLIT_DONE_FILE + endif + endif + /bin/rm -f $SPLIT_MARK_FILE + exit + else + /bin/rm -f $SPLIT_MARK_FILE + exit + endif +endif + +#if ( 0 == 1 ) then +# if ( grep -i done hi_log ) then +# cat error.log rcd.chk | /usr/ucb/mail -s"end of tape on $HOST" $EMAIL_LIST +# touch $HI_FILE$HIDONE_SUFFIX +# if ( -f $HI_FILE$HIDONE_SUFFIX ) then +# unlink $SPLITFILE +# fi +# unlink .$SPLITFILE +# /bin/rm error.log rcd.chk +# /bin/rm wu_inbox/.* +# nice -10 $SPLITTER_PROG_LOC $SPLITFILE -resume 2>> splitterlog & +#else +# if [ -f $MARKER$HOST ] +# then +# /bin/rm wu_inbox/.* +# cat error.log rcd.chk | /usr/ucb/mail -s"restarting HI analysis on $HOST" $EMAIL_LIST +# nice -10 $SPLITTER_PROG_LOC $SPLITFILE -resume 2>> splitterlog & +# else +# cat error.log rcd.chk | /usr/ucb/mail -s"hi analysis disabled on $HOST" $EMAIL_LIST +# fi +#endif +end + diff --git a/splitter/tools/sah_splitter.sh b/splitter/tools/sah_splitter.sh new file mode 100755 index 0000000..2ff1d34 --- /dev/null +++ b/splitter/tools/sah_splitter.sh @@ -0,0 +1,150 @@ +#! /bin/sh +PATH=/opt/misc:/opt/misc/bin:/usr/ccs/bin:/usr/openwin/bin:/usr/openwin/bin/xview:/usr/lang:/usr/ucb:/bin:/usr/bin:/usr/local/bin:/usr/hosts:/usr/bin/X11:/usr/casual/sparc:/usr/etc:/usr/local/lib/tex/bin:/usr/local/lib/frame/bin:/disks/asimov/a/apps/informix/bin:.:/disks/albert/d/office/bin:/usr/ucb:/disks/albert/e/users/eurd/data_analysis/bin:/usr/local/lib/g++-include.bak:/disks/siren/a/users/seti/s4/siren/bin:/disks/albert/d/orfeus:/disks/albert/d/chips:/disks/asimov/a/apps/informix/bin:/usr/local/tex +export PATH +LD_LIBRARY_PATH=/lib:/disks/asimov/a/apps/informix/lib:/disks/asimov/a/apps/informix/lib/esql::/usr/ucblib:/lib:/usr/lib:/usr/openwin/lib:/usr/ccs/lib:/usr/local/gcc/lib:/disks/asimov/a/lang/gnu/H-sparc-sun-solaris2/lib:/opt/misc/lib:/usr/local/lib:/disks/ellie/a/users/korpela/lib:/usr/dt/lib +export LD_LIBRARY_PATH +INFORMIXDIR=/disks/asimov/a/apps/informix/ +export INFORMIXDIR +INFORMIXSERVER=ejk_tcp +export INFORMIXSERVER +S4_RECEIVER_CONFIG=/usr/local/warez/projects/s4/siren/db/ReceiverConfig.tab +export S4_RECEIVER_CONFIG + +PROJECTDIR=/disks/koloth/a/inet_services/boinc_www/share/projects/sah +SPLIT_PROG_LOC=${PROJECTDIR}/bin/ +SPLIT_PROG_NAME=sah_splitter +SPLIT_TAPE_DIR=/disks/setifiler1/wutape/tapedir/seti_boinc_public/ +SPLIT_SUFFIX=.split +#HIDONE_SUFFIX=.hidone +SPLITDONE_SUFFIX=.splitdone +EMAIL_LIST="korpela@ssl.berkeley.edu jeffc@ssl.berkeley.edu mattl@ssl.berkeley.edu davea@ssl.berkeley.edu" +FOUND_FILE=0 +HOST=`hostname` +SPLIT_HALT_MSG=splitter_stop + +# Check to see if this machine is already running the splitter program +PROG_RUNNING=`/usr/ucb/ps -auxww | grep "$SPLIT_PROG_NAME " | grep -v grep` +if [ ! -z "$PROG_RUNNING" ] +then + echo "Splitter is already running on this machine. Quitting." + exit 1 +fi + +# Get rid of all .split files here with HOSTNAME in them(?) + +TAPE_FILE= + +# get list of all tapes in the sah classic tape directory +cd $SPLIT_TAPE_DIR/.. +FILE_LIST=`ls *.tape` + +cd $SPLIT_TAPE_DIR + +# if no sah classic tapes then bail +if [ -z "$FILE_LIST" ] +then + exit 2 +fi + +# for each sah classic tape... +for file in $FILE_LIST +do + # if we have already split it... + if [ -f $file$SPLITDONE_SUFFIX ] + then + # ... then remove it ("it" being a hard link upward into the sah classic dir) + if [ -f $file ] + then + /bin/rm $file + fi + else + # if we are in the process of splitting it... + if [ -f $file$SPLIT_SUFFIX ] + then + # and are splitting it from this host... (this logic prevents one host from repeating another host's tape) + if grep $HOST $file$SPLIT_SUFFIX + then + # trigger to restart the split + /bin/rm $file$SPLIT_SUFFIX + fi + fi + # if a restart or a brand new tape... + if [ ! -f $file$SPLIT_SUFFIX ] + then + # claim it for this host (there is certainly a race condition here) + echo $HOST > $file$SPLIT_SUFFIX + ln ../$file + TAPE_FILE=$file + SPLIT_FILE=$SPLIT_TAPE_DIR$file + SPLIT_MARK_FILE=$SPLIT_TAPE_DIR$file$SPLIT_SUFFIX +# HI_DONE_FILE=$SPLIT_TAPE_DIR$file$HIDONE_SUFFIX + SPLIT_DONE_FILE=$SPLIT_TAPE_DIR$file$SPLITDONE_SUFFIX + break + fi + fi +done + +cd /tmp/splitter/sah +if [ ! -d splitter ] +then + mkdir splitter +fi +cd splitter +if [ ! -d wu_inbox ] +then + mkdir wu_inbox +fi +/bin/rm -f error.log rcd.chk +touch error.log +touch rcd.chk + +if [ -z "$TAPE_FILE" ] +then + exit 3 +else + /bin/rm -f wu_inbox/.* + cat error.log rcd.chk | /usr/ucb/mail -s""$HOST" boinc_splitter starting" $EMAIL_LIST + /bin/nice $SPLIT_PROG_LOC$SPLIT_PROG_NAME $SPLIT_FILE $* -resume -projectdir=$PROJECTDIR + if grep -i "end" error.log >/dev/null 2>&1 + then + /bin/nice $SPLIT_PROG_LOC$SPLIT_PROG_NAME $SPLIT_FILE $* -resume -projectdir=$PROJECTDIR + fi + if grep -i "end" error.log >/dev/null 2>&1 + then + cat error.log rcd.chk | /usr/ucb/mail -s""$HOST" boinc_splitter finished" $EMAIL_LIST + /bin/rm -f error.log rcd.chk + /bin/rm -f wu_inbox/.* + /bin/rm -f $SPLIT_MARK_FILE + /bin/rm -f `cd $SPLIT_TAPE_DIR; ls -l | grep $TAPE_FILE | awk '{print $NF}'` + /bin/rm -f $SPLIT_FILE + touch -f $SPLIT_DONE_FILE + exit + else + /bin/rm -f $SPLIT_MARK_FILE + exit 4 + fi +fi + +#if ( 0 == 1 ) then +# if ( grep -i done hi_log ) then +# cat error.log rcd.chk | /usr/ucb/mail -s"end of tape on $HOST" $EMAIL_LIST +# touch $HI_FILE$HIDONE_SUFFIX +# if ( -f $HI_FILE$HIDONE_SUFFIX ) then +# unlink $SPLITFILE +# fi +# unlink .$SPLITFILE +# /bin/rm error.log rcd.chk +# /bin/rm wu_inbox/.* +# nice -10 $SPLITTER_PROG_LOC $SPLITFILE -resume 2>> splitterlog & +#else +# if [ -f $MARKER$HOST ] +# then +# /bin/rm wu_inbox/.* +# cat error.log rcd.chk | /usr/ucb/mail -s"restarting HI analysis on $HOST" $EMAIL_LIST +# nice -10 $SPLITTER_PROG_LOC $SPLITFILE -resume 2>> splitterlog & +# else +# cat error.log rcd.chk | /usr/ucb/mail -s"hi analysis disabled on $HOST" $EMAIL_LIST +# fi +#endif +end + diff --git a/splitter/uttolst.h b/splitter/uttolst.h new file mode 100644 index 0000000..8f29efb --- /dev/null +++ b/splitter/uttolst.h @@ -0,0 +1,2 @@ +double tm_UtToLst(double ddtime, double longitude, + long mon, long day, long year); diff --git a/splitter/validrun.cpp b/splitter/validrun.cpp new file mode 100644 index 0000000..45d3854 --- /dev/null +++ b/splitter/validrun.cpp @@ -0,0 +1,181 @@ +/* + * validrun.c + * + * Functions for determining if a section of the tape buffer can be + * turned into a valid work unit + * + * $Id: validrun.cpp,v 1.2.4.2 2006/12/14 22:24:48 korpela Exp $ + * + */ + +#include "sah_config.h" +#include +#include +#include +#include +#include "splitparms.h" +#include "splittypes.h" +#include "splitter.h" +#include "message.h" + + +int valid_run(tapeheader_t tapeheader[],buffer_pos_t *start_of_wu, + buffer_pos_t *end_of_wu) { + + int i=0,valid=1; + SCOPE_STRING *first_telstr; + double first_telstr_time=0; + double first_jd=tapeheader[0].st.jd; + char tmpstr[256]; + + /* find the first telstr that refers to valid data */ + + do { + first_telstr=&(tapeheader[++i].telstr); + first_telstr_time=first_telstr->st.jd; + } while ((first_telstr_time<=first_jd) && (iframe=1+WU_OVERLAP_FRAMES; + end_of_wu->byte=0; + return(0); + } + + /* find the correct byte offset for the start of the work unit */ + + start_of_wu->frame=i; + start_of_wu->byte=(long)((tapeheader[i].telstr.st.jd-tapeheader[i].st.jd)*86400.0*tapeheader[i].samplerate*2/CHAR_BIT); + start_of_wu->byte &= 0xfffffffe; + + + while (start_of_wu->byte<0) { + start_of_wu->frame--; + start_of_wu->byte+=TAPE_DATA_SIZE; + } + + while (start_of_wu->byte>TAPE_DATA_SIZE) { + start_of_wu->frame++; + start_of_wu->byte-=TAPE_DATA_SIZE; + } + + if (start_of_wu->frame<0) { + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Missing telescope strings near %lu\n", + tapeheader[0].frameseq); + end_of_wu->frame=0; + end_of_wu->byte=0; + records_in_buffer=0; + return(0); + } + + if ((start_of_wu->frame+TAPE_FRAMES_PER_WU)>TAPE_FRAMES_IN_BUFFER) { + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Missing telescope strings near %lu\n", + tapeheader[0].frameseq); + end_of_wu->frame=0; + end_of_wu->byte=0; + records_in_buffer=0; + return(0); + } + + /* check for frames in error */ + for (i=0; iframe+i; + // missed frames + if (tapeheader[j].missed) { + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Missing frames between %lu and %lu\n", + tapeheader[j-1].frameseq,tapeheader[j].frameseq); + valid=0; + } + // failed blanking signal acquisition + if (tapeheader[j].blanking_failed) { + log_messages.printf(SCHED_MSG_LOG::MSG_NORMAL,"Failed blanking between frames %lu and %lu\n", + tapeheader[j-1].frameseq,tapeheader[j].frameseq); + valid=0; + } + if(!valid) { + end_of_wu->frame=j+WU_OVERLAP_FRAMES+1; + end_of_wu->byte=0; + assert((j+WU_OVERLAP_FRAMES)<=TAPE_FRAMES_IN_BUFFER); + } + } + + if (!valid) { + end_of_wu->frame=0; + records_in_buffer=0; + return(valid); + } + + end_of_wu->frame=start_of_wu->frame+TAPE_FRAMES_PER_WU; + end_of_wu->byte=start_of_wu->byte; + + return(valid); +} + + +/* + * $Log: validrun.cpp,v $ + * Revision 1.2.4.2 2006/12/14 22:24:48 korpela + * *** empty log message *** + * + * Revision 1.2.4.1 2006/01/13 00:37:58 korpela + * Moved splitter to using standard BOINC logging mechanisms. All stderr now + * goes to "error.log" + * + * Added command line parameters "-iterations=" (number of workunit groups to + * create before exiting), "-trigger_file_path=" (path to the splitter_stop trigger + * file. Default is /disks/setifiler1/wutape/tapedir/splitter_stop). + * + * Reduced deadlines by a factor of three. We now need a 30 MFLOP machine to meet + * the deadline. + * + * Revision 1.2 2003/09/11 18:53:38 korpela + * *** empty log message *** + * + * Revision 1.1 2003/07/29 20:35:57 korpela + * + * renames .C files to .cpp + * + * Revision 1.1 2003/06/03 00:23:43 korpela + * + * Again + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.7 2000/12/01 01:13:29 korpela + * *** empty log message *** + * + * Revision 2.6 1999/06/07 21:00:52 korpela + * *** empty log message *** + * + * Revision 2.5 1999/03/27 16:19:35 korpela + * *** empty log message *** + * + * Revision 2.4 1999/02/22 22:21:09 korpela + * added -nodb option + * + * Revision 2.3 1999/02/11 16:46:28 korpela + * Added checkpointing. + * + * Revision 2.2 1998/11/04 23:08:25 korpela + * Byte and bit order change. + * + * Revision 2.1 1998/11/02 16:41:21 korpela + * Minor Change. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.3 1998/10/30 20:26:03 korpela + * Bug Fixes. Now mostly working. + * + * Revision 1.2 1998/10/27 00:59:22 korpela + * Bug fixes. + * + * Revision 1.1 1998/10/22 17:48:20 korpela + * Initial revision + * + * + */ diff --git a/splitter/validrun.h b/splitter/validrun.h new file mode 100644 index 0000000..89f7c6d --- /dev/null +++ b/splitter/validrun.h @@ -0,0 +1,33 @@ +/* + * validrun.h + * + * Functions for determining if a section of the tape buffer can be + * turned into a valid work unit + * + * $Id: validrun.h,v 1.1 2003/06/03 00:23:43 korpela Exp $ + * + */ + +int valid_run(tapeheader_t tapeheader[],buffer_pos_t *start_of_wu, + buffer_pos_t *end_of_wu); + +/* + * $Log: validrun.h,v $ + * Revision 1.1 2003/06/03 00:23:43 korpela + * + * Again + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.1 1998/11/02 16:41:21 korpela + * Minor Change. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.1 1998/10/22 17:49:15 korpela + * Initial revision + * + * + */ diff --git a/splitter/writeheader.cpp b/splitter/writeheader.cpp new file mode 100644 index 0000000..89296c3 --- /dev/null +++ b/splitter/writeheader.cpp @@ -0,0 +1,105 @@ +/* + * Functions for writing tape and work unit headers + * + * $Id: writeheader.cpp,v 1.3.4.1 2006/12/14 22:24:49 korpela Exp $ + * + */ + +#include "sah_config.h" +#include +#include +#include +#include + +#include "splitparms.h" +#include "splittypes.h" +#include "timecvt.h" +#include "seti_header.h" + +extern int output_xml; + +/* Write a tape header into a buffer */ +int write_tape_header(char *buffer, tapeheader_t *header) { +/* Unimplemented as yet */ +return(0); +} + +char *monthnames[]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep" + "Oct","Nov","Dec"}; +char *daynames[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"}; + +/* Write a work unit header into a FILE */ +/*int splitter_write_wu_header(FILE *file, wuheader_t *header) { + if (!output_xml) + write_wu_header(file, header->wuhead); + return (seti_write_wu_header(file,header->wuinfo,output_xml)); + +} +*/ + +/* + * $Log: writeheader.cpp,v $ + * Revision 1.3.4.1 2006/12/14 22:24:49 korpela + * *** empty log message *** + * + * Revision 1.3 2003/09/11 18:53:38 korpela + * *** empty log message *** + * + * Revision 1.2 2003/08/05 17:23:44 korpela + * More work on database stuff. + * Further tweaks. + * + * Revision 1.1 2003/07/29 20:35:59 korpela + * + * renames .C files to .cpp + * + * Revision 1.2 2003/06/03 01:01:18 korpela + * + * First working splitter under CVS. + * + * Revision 1.1 2003/06/03 00:23:43 korpela + * + * Again + * + * Revision 3.1 2003/05/19 17:40:59 eheien + * *** empty log message *** + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.6 1999/01/04 22:27:55 korpela + * Updated return codes. + * + * Revision 2.5 1998/11/10 00:02:44 korpela + * Moved remaining wuheader fields into a WU_INFO structure. + * + * Revision 2.4 1998/11/09 23:26:27 korpela + * Added generic version= to default header. + * + * Revision 2.3 1998/11/05 21:18:41 korpela + * Moved name field from header to seti header. + * + * Revision 2.2 1998/11/02 18:42:03 korpela + * Changed write_wu_header to call seti_write_wu_header + * + * Revision 2.1 1998/11/02 16:38:29 korpela + * Will be transfered to client. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.4 1998/10/30 20:26:03 korpela + * Bug Fixes. Now mostly working. + * + * Revision 1.3 1998/10/27 00:59:43 korpela + * Bug fixes. + * / + * + * Revision 1.2 1998/10/20 16:32:03 korpela + * Fixed syntax error. + * + * Revision 1.1 1998/10/20 16:27:41 korpela + * Initial revision + * + * + */ diff --git a/splitter/writeheader.h b/splitter/writeheader.h new file mode 100644 index 0000000..c3d6d4a --- /dev/null +++ b/splitter/writeheader.h @@ -0,0 +1,39 @@ +/* + * Functions for writing tape and work unit headers + * + * $Id: writeheader.h,v 1.2 2003/08/05 17:23:44 korpela Exp $ + * + */ + +/* Write a tape header into a buffer */ +int write_tape_header(char *buffer, tapeheader_t *header); + +/* Write a work unit header into a FILE */ +// int splitter_write_wu_header(FILE *file, wuheader_t *header); + +/* + * $Log: writeheader.h,v $ + * Revision 1.2 2003/08/05 17:23:44 korpela + * More work on database stuff. + * Further tweaks. + * + * Revision 1.1 2003/06/03 00:23:44 korpela + * + * Again + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.2 1999/01/04 22:27:55 korpela + * Updated return codes. + * + * Revision 2.1 1998/11/02 16:41:21 korpela + * Minor Change. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.1 1998/10/15 17:20:01 korpela + * Initial revision + * + */ diff --git a/splitter/wufiles.cpp b/splitter/wufiles.cpp new file mode 100644 index 0000000..d8663ce --- /dev/null +++ b/splitter/wufiles.cpp @@ -0,0 +1,679 @@ +/* + * + * Functions for managing wufiles and their data + * + * $Id: wufiles.cpp,v 1.29.2.18 2007/08/10 18:21:13 korpela Exp $ + * + */ + +#include "sah_config.h" +#undef USE_MYSQL +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_ERRNO_H +#include +#endif + +#include "boinc_db.h" +#include "sched_util.h" +#include "splitparms.h" +#include "splittypes.h" +#include "timecvt.h" +#include "s_util.h" +#include "util.h" +#include "str_util.h" +#include "str_replace.h" +#include "splitter.h" +#include "writeheader.h" +#include "message.h" +#include "encode.h" +#include "dotransform.h" +#include "angdist.h" +#include "lcgamm.h" +#include "readtape.h" +#include "sqlrow.h" +#include "sqlblob.h" +#include "sqlapi.h" +#include "db_table.h" +#include "schema_master.h" +#include "seti_tel.h" +#include "seti_cfg.h" +#include "xml_util.h" +#include "db/app_config.h" +#include "str_util.h" +#include + +int wu_database_id[NSTRIPS]; +static std::vector bin_data[NSTRIPS]; + +extern APP_CONFIG sah_config; + +int make_wu_headers(tapeheader_t tapeheader[],workunit wuheader[], + buffer_pos_t *start_of_wu) { + int procid=getpid(); + int i,j,startframe=start_of_wu->frame; + double receiver_freq; + int bandno; + SCOPE_STRING *lastpos; + FILE *tmpfile; + char tmpstr[256]; + char buf[64]; + static int HaveConfigTable=0; + static ReceiverConfig_t ReceiverConfig; + static receiver_config r; + static settings s; + + if(!HaveConfigTable) { + sprintf(buf,"where s4_id=%d",gregorian?AOGREG_1420:AO_1420); + r.fetch(std::string(buf)); + ReceiverConfig.ReceiverID=r.s4_id; + strlcpy(ReceiverConfig.ReceiverName,r.name, + sizeof(ReceiverConfig.ReceiverName)); + ReceiverConfig.Latitude=r.latitude; + ReceiverConfig.Longitude=r.longitude; + ReceiverConfig.WLongitude=-r.longitude; + ReceiverConfig.Elevation=r.elevation; + ReceiverConfig.Diameter=r.diameter; + ReceiverConfig.BeamWidth=r.beam_width; + ReceiverConfig.CenterFreq=r.center_freq; + ReceiverConfig.AzOrientation=r.az_orientation; + for (i=0;i<(sizeof(ReceiverConfig.ZenCorrCoeff)/sizeof(ReceiverConfig.ZenCorrCoeff[0]));i++) { + ReceiverConfig.ZenCorrCoeff[i]=r.zen_corr_coeff[i]; + ReceiverConfig.AzCorrCoeff[i]=r.az_corr_coeff[i]; + } + HaveConfigTable=1; + } + sprintf(buf,"where active=%d",app.id); + if (!s.fetch(std::string(buf))) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Unable to find active settings for app.id=%d\n",app.id); + exit(1); + } + if (s.receiver_cfg->id != r.id) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Receiver config does not match settings (%d != %d)\n",s.receiver_cfg->id, r.id); + exit(1); + } + s.recorder_cfg->fetch(); + s.splitter_cfg->fetch(); + s.analysis_cfg->fetch(); + if (!strncmp(s.splitter_cfg->data_type,"encoded", + std::min(static_cast(7),sizeof(s.splitter_cfg->data_type)))) { + noencode=0; + } else { + noencode=1; + } + + workunit_grp wugrp; + sprintf(wugrp.name,"%s.%ld.%d.%ld.%d",tapeheader[startframe].name, + procid, + (current_record-TAPE_RECORDS_IN_BUFFER)*8+startframe, + start_of_wu->byte,s.id); + wugrp.receiver_cfg=r; + wugrp.recorder_cfg=s.recorder_cfg; + wugrp.splitter_cfg=s.splitter_cfg; + wugrp.analysis_cfg=s.analysis_cfg; + + wugrp.data_desc.start_ra=tapeheader[startframe+1].telstr.ra; + wugrp.data_desc.start_dec=tapeheader[startframe+1].telstr.dec; + wugrp.data_desc.end_ra=tapeheader[startframe+TAPE_FRAMES_PER_WU].telstr.ra; + wugrp.data_desc.end_dec=tapeheader[startframe+TAPE_FRAMES_PER_WU].telstr.dec; + wugrp.data_desc.nsamples=NSAMPLES; + wugrp.data_desc.true_angle_range=0; + { + double sample_rate=tapeheader[startframe].samplerate/NSTRIPS; + /* startframe+1 contains the first valid RA and Dec */ + TIME st=tapeheader[startframe+1].telstr.st; + TIME et=tapeheader[startframe+TAPE_FRAMES_PER_WU].telstr.st; + double diff=(et-st).jd*86400.0; + for (j=2;j(13*1024)) ||(keyuniq<12*1024)) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Invalid keyuniq value!\n"); + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"%d %d %f\n",keyuniq,s.analysis_cfg.id,wugrp.data_desc.true_angle_range); + exit(1); + } + + keyuniq*=-1; + long save_keyuniq=keyuniq; + s.analysis_cfg=wugrp.analysis_cfg; + sprintf(tmpstr,"where keyuniq=%d",keyuniq); + // Check if we've already done this analysis_config... + s.analysis_cfg.id=0; + s.analysis_cfg->fetch(tmpstr); + + if (s.analysis_cfg->id==0) { + if (keyuniq != save_keyuniq) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"keyuniq value changed!\n"); + exit(1); + } + + // If not calculate the thresholds based upon the input analysis_config + // Triplets are distributed exponentially... + wugrp.analysis_cfg->triplet_thresh+=(log(numtrip)-29.0652); + + // Gaussians are based upon chisqr... + double p_gauss=lcgf(32.0,wugrp.analysis_cfg->gauss_null_chi_sq_thresh*32.0); + p_gauss-=(log(numgauss)-19.5358); + wugrp.analysis_cfg->gauss_null_chi_sq_thresh=invert_lcgf(p_gauss,32,1e-4)*0.03125; + + // Pulses thresholds are log of the probability + wugrp.analysis_cfg->pulse_thresh+=(log(numpulse)-24.7894); + + wugrp.analysis_cfg->keyuniq=keyuniq; + wugrp.analysis_cfg->insert(); + } else { + wugrp.analysis_cfg=s.analysis_cfg; + } + + strlcpy(wugrp.data_desc.time_recorded, + short_jd_string(tapeheader[startframe+1].telstr.st.jd), + sizeof(wugrp.data_desc.time_recorded)); + wugrp.data_desc.time_recorded_jd=tapeheader[startframe+1].telstr.st.jd; + + lastpos=&(tapeheader[startframe].telstr); + coordinate_t tmpcoord; + tmpcoord.time=tapeheader[startframe].telstr.st.jd; + tmpcoord.ra=tapeheader[startframe].telstr.ra; + tmpcoord.dec=tapeheader[startframe].telstr.dec; + wugrp.data_desc.coords.push_back(tmpcoord); + + for (j=1;jst.jd) > (1.0/86400.0)) + { + lastpos=&(tapeheader[startframe+j].telstr); + tmpcoord.time=tapeheader[startframe+j].telstr.st.jd; + tmpcoord.ra=tapeheader[startframe+j].telstr.ra; + tmpcoord.dec=tapeheader[startframe+j].telstr.dec; + wugrp.data_desc.coords.push_back(tmpcoord); + } + } + + wugrp.tape_info->id=0; + wugrp.tape_info->fetch(std::string("where name=\'")+tapeheader[startframe].name+"\'"); + wugrp.tape_info->start_time=tapeheader[startframe].st.jd; + wugrp.tape_info->last_block_time=tapeheader[startframe].st.jd; + wugrp.tape_info->last_block_done=tapeheader[startframe].frameseq; + + if (!nodb) { + if (wugrp.tape_info.id) { + if (!(wugrp.tape_info->update())) { + char buf[1024]; + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"%s",sql_error_message()); + exit(1); + } + } else { + strlcpy(wugrp.tape_info->name,tapeheader[startframe].name,sizeof(wugrp.tape_info->name)); + wugrp.tape_info->insert(); + } + } + + if (!nodb) wugrp.insert(); + + for (i=0;ibyte,s.id,i); + wuheader[i].subband_desc.sample_rate=tapeheader[startframe].samplerate/NSTRIPS; + + receiver_freq=tapeheader[startframe].centerfreq; + + bandno=((i+NSTRIPS/2)%NSTRIPS)-NSTRIPS/2; + + wuheader[i].subband_desc.base=receiver_freq+ + (double)(bandno)*wuheader[i].subband_desc.sample_rate; + wuheader[i].subband_desc.center=receiver_freq+wuheader[i].subband_desc.sample_rate*NSTRIPS*((double)IFFT_LEN*bandno/FFT_LEN+(double)IFFT_LEN/(2*FFT_LEN)-1.0/(2*FFT_LEN)); + wuheader[i].subband_desc.number=i; + + if (!nodb ) { + if (!(wu_database_id[i]=wuheader[i].insert())) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Database error in make_wu_headers()\n"); + exit(EXIT_FAILURE); + } + } + + sprintf(tmpstr,"./wu_inbox/%s",wuheader[i].name); + if ((tmpfile=fopen(tmpstr,"w"))) { + fprintf(tmpfile,"\n"); + fprintf(tmpfile,wuheader[i].print_xml().c_str()); + fclose(tmpfile); + } else { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Unable to open file ./wu_inbox/%s, errno=%d\n",wuheader[i].name,errno); + exit(1); + } + bin_data[i].reserve(wuheaders[i].group_info->recorder_cfg->bits_per_sample* + wuheaders[i].group_info->data_desc.nsamples/8); + } + return(1); +} + + +void write_wufile_blocks(int nbytes) { + static bool first_call=true; + int i,j; + + + for (i=0;i0); + fclose(oldfile); + fclose(newfile); + return 0; + } else { + return 1; + } +} + + + +void rename_wu_files() { + int i, retval; + char oldname[256],newname[1024]; + unsigned long sz; + DB_WORKUNIT db_wu; + const char *name[1]; + char *wudir="./wu_inbox"; + xml_encoding encoding=(noencode?_binary:_x_setiathome); + FILE *tmpfile; + + if (boinc_db.open(boinc_config.db_name,boinc_config.db_host,boinc_config.db_user,boinc_config.db_passwd)) { + boinc_db.print_error("boinc_db.open"); + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Fatal error in boinc_db.open\n"); + exit(1); + } + + for (i=0;i",tmpstr.size(), + xml_encoding_names[encoding]); + fwrite(tmpstr.c_str(),tmpstr.size(),1,tmpfile); + fprintf(tmpfile,"\n"); + fprintf(tmpfile,"\n"); + sz=bin_data[i].size(); + + fclose(tmpfile); + } else { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"Header file no longer exists! splitter start script may be failing\n "); + exit(1); + } + if (!nodb) { + if (!filecopy(oldname,newname)) { + db_wu.clear(); + db_wu.opaque=wuheaders[i].id; + strncpy(db_wu.name,name[0],sizeof(db_wu.name)-2); + db_wu.appid=app.id; + //db_wu.rsc_fpops_est=2.79248e+13*6; + //db_wu.rsc_fpops_bound=4.46797e+14*6; + double ar=wuheaders[i].group_info->data_desc.true_angle_range; + double dur=(double)(wuheaders[i].group_info->data_desc.nsamples)/wuheaders[i].subband_desc.sample_rate; + double min_slew=wuheaders[i].group_info->analysis_cfg->pot_min_slew; + double max_slew=wuheaders[i].group_info->analysis_cfg->pot_max_slew; + if ( ar < ( dur*min_slew )/2 ) { + db_wu.rsc_fpops_est=4.95e+13; + } else { + if ( ar < ( dur*min_slew ) ) { + db_wu.rsc_fpops_est=(2.85e+13+2.0e+14*ar); + } else { + if ( ar <= (dur*max_slew) ) { + db_wu.rsc_fpops_est=(2.22e+13/pow(ar,1.25)); + } else { + db_wu.rsc_fpops_est=1.125e+13; + } + } + } + db_wu.rsc_fpops_bound=db_wu.rsc_fpops_est*10; + db_wu.rsc_memory_bound=32505856; + db_wu.rsc_disk_bound=500000; + // Our minimum is 10% of a 100 MFLOP machine + db_wu.delay_bound=db_wu.rsc_fpops_est/3e+7; + db_wu.min_quorum=sah_config.min_quorum; + db_wu.target_nresults=sah_config.target_nresults; + db_wu.max_error_results=sah_config.max_error_results; + db_wu.max_total_results=sah_config.max_total_results; + db_wu.max_success_results=sah_config.max_success_results; + strncpy(db_wu.app_name,SAH_APP_NAME,sizeof(db_wu.app_name)-2); + if (create_work(db_wu, + wu_template, + result_template_filename, + result_template_filepath, + name, + 1, + boinc_config, + NULL + ) + ) { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"create work failed\n"); + exit(1); + } + //unlink(oldname); // we now *always* unlink + } else { + log_messages.printf(SCHED_MSG_LOG::MSG_CRITICAL,"file copy failed\n"); + exit(1); + } + unlink(oldname); + } + } + boinc_db.close(); +} + +/* + * $Log: wufiles.cpp,v $ + * Revision 1.29.2.18 2007/08/10 18:21:13 korpela + * *** empty log message *** + * + * Revision 1.29.2.17 2007/06/07 20:01:52 mattl + * *** empty log message *** + * + * Revision 1.29.2.16 2007/06/06 15:58:30 korpela + * *** empty log message *** + * + * Revision 1.29.2.15 2006/12/14 22:24:49 korpela + * *** empty log message *** + * + * Revision 1.29.2.14 2006/05/03 19:14:31 korpela + * Updated work estimates. + * + * Revision 1.29.2.13 2006/04/24 18:41:02 korpela + * *** empty log message *** + * + * Revision 1.29.2.12 2006/01/13 00:37:58 korpela + * Moved splitter to using standard BOINC logging mechanisms. All stderr now + * goes to "error.log" + * + * Added command line parameters "-iterations=" (number of workunit groups to + * create before exiting), "-trigger_file_path=" (path to the splitter_stop trigger + * file. Default is /disks/setifiler1/wutape/tapedir/splitter_stop). + * + * Reduced deadlines by a factor of three. We now need a 30 MFLOP machine to meet + * the deadline. + * + * Revision 1.29.2.11 2006/01/10 00:39:04 jeffc + * *** empty log message *** + * + * Revision 1.29.2.10 2006/01/05 23:55:22 korpela + * *** empty log message *** + * + * Revision 1.29.2.9 2005/12/05 22:11:40 korpela + * Fixed bug in flops estimate. + * + * Revision 1.29.2.8 2005/10/05 16:22:17 jeffc + * removed reference to old/new boolean for directory hash. + * + * Revision 1.29.2.7 2005/09/22 23:05:22 korpela + * Fixed threshold calculation. Was using chisqr rather than reduced chisqr. + * + * Revision 1.29.2.6 2005/09/21 22:11:23 korpela + * Updated Makefile.in for OpenSSL. + * Added dynamic threshold generation to wufiles.cpp. + * + * Revision 1.29.2.5 2005/08/01 17:47:38 korpela + * Type fixed. + * + * Revision 1.29.2.4 2005/08/01 17:43:20 korpela + * Refinement of FLOPS estimate for workunits. + * + * Revision 1.29.2.3 2005/07/26 17:17:01 korpela + * Typo fix + * + * Revision 1.29.2.2 2005/07/19 00:15:19 korpela + * Revised delay bound and FLOP estimate for setiathome_enhanced. + * + * Revision 1.29.2.1 2005/07/06 01:30:17 korpela + * Updated estimates of FPOPS per workunit for setiathome enhanced. + * + * Revision 1.29 2005/03/08 22:36:15 jeffc + * jeffc - fixed call to create_work() + * + * Revision 1.28 2005/02/15 23:06:47 korpela + * Fixed missing dir_hier symbol. + * + * Revision 1.27 2004/12/27 20:48:54 jeffc + * *** empty log message *** + * + * Revision 1.26 2004/11/18 22:24:48 korpela + * *** empty log message *** + * + * Revision 1.25 2004/08/25 22:42:11 jeffc + * *** empty log message *** + * + * Revision 1.24 2004/08/14 04:44:26 jeffc + * *** empty log message *** + * + * Revision 1.23 2004/08/12 15:45:41 jeffc + * *** empty log message *** + * + * Revision 1.22 2004/07/15 17:54:20 jeffc + * *** empty log message *** + * + * Revision 1.21 2004/07/09 22:35:39 jeffc + * *** empty log message *** + * + * Revision 1.20 2004/07/01 17:56:51 korpela + * *** empty log message *** + * + * Revision 1.19 2004/06/25 13:49:33 jeffc + * *** empty log message *** + * + * Revision 1.18 2004/06/18 23:23:32 jeffc + * *** empty log message *** + * + * Revision 1.17 2004/06/16 20:57:19 jeffc + * *** empty log message *** + * + * Revision 1.16 2004/06/02 20:51:32 jeffc + * *** empty log message *** + * + * Revision 1.15 2004/01/22 00:57:54 korpela + * *** empty log message *** + * + * Revision 1.14 2004/01/20 22:33:44 korpela + * *** empty log message *** + * + * Revision 1.13 2004/01/06 22:44:05 korpela + * *** empty log message *** + * + * Revision 1.12 2004/01/01 18:42:01 korpela + * *** empty log message *** + * + * Revision 1.11 2003/12/12 01:51:39 korpela + * Now using the opaque field in workunit to store SAH wuid. + * + * Revision 1.10 2003/12/03 23:46:41 korpela + * WU count is now only for SAH workunits. + * + * Revision 1.9 2003/11/25 21:59:53 korpela + * *** empty log message *** + * + * Revision 1.8 2003/11/11 06:20:30 korpela + * Increased max fpops_max to prevent timeout on windows clients + * + * Revision 1.7 2003/10/25 18:19:44 korpela + * *** empty log message *** + * + * Revision 1.6 2003/10/24 16:57:03 korpela + * *** empty log message *** + * + * Revision 1.5 2003/09/26 20:48:52 jeffc + * jeffc - merge in branch setiathome-4_all_platforms_beta. + * + * Revision 1.3.2.2 2003/09/22 19:00:31 korpela + * *** empty log message *** + * + * Revision 1.3.2.1 2003/09/22 17:39:35 korpela + * *** empty log message *** + * + * Revision 1.4 2003/09/22 17:05:38 korpela + * *** empty log message *** + * + * Revision 1.3 2003/09/11 18:53:38 korpela + * *** empty log message *** + * + * Revision 1.2 2003/08/05 17:23:44 korpela + * More work on database stuff. + * Further tweaks. + * + * Revision 1.1 2003/07/29 20:36:00 korpela + * + * renames .C files to .cpp + * + * Revision 1.3 2003/06/05 15:52:47 korpela + * + * Fixed coordinate bug that was using the wrong zenith angle from the telescope + * strings when handling units from the gregorian. + * + * Revision 1.2 2003/06/03 01:01:18 korpela + * + * First working splitter under CVS. + * + * Revision 1.1 2003/06/03 00:23:44 korpela + * + * Again + * + * Revision 3.8 2003/05/19 17:40:59 eheien + * *** empty log message *** + * + * Revision 3.7 2003/04/10 17:32:25 korpela + * *** empty log message *** + * + * Revision 3.6 2002/06/21 01:42:15 eheien + * *** empty log message *** + * + * Revision 3.5 2001/11/07 00:51:47 korpela + * Added splitter version to database. + * Added max_wus_ondisk option. + * + * Revision 3.4 2001/08/17 22:20:54 korpela + * *** empty log message *** + * + * Revision 3.3 2001/08/17 01:22:31 korpela + * *** empty log message *** + * + * Revision 3.2 2001/08/17 01:16:53 korpela + * *** empty log message *** + * + * Revision 3.1 2001/08/16 23:42:08 korpela + * Mods for splitter to make binary workunits. + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.18 2000/12/01 01:13:29 korpela + * *** empty log message *** + * + * Revision 2.17 1999/06/07 21:00:52 korpela + * *** empty log message *** + * + * Revision 2.16 1999/03/27 16:19:35 korpela + * *** empty log message *** + * + * Revision 2.15 1999/03/05 01:47:18 korpela + * Added data_class field. + * + * Revision 2.14 1999/02/22 22:21:09 korpela + * added -nodb option + * + * Revision 2.13 1999/02/11 16:46:28 korpela + * Added db access functions. + * + * Revision 2.12 1999/01/04 22:27:55 korpela + * Updated return codes. + * + * Revision 2.11 1998/12/14 23:41:44 korpela + * Added subband_base to work unit header. + * Changed frequency calculation. + * + * Revision 2.10 1998/12/14 21:55:07 korpela + * Added fft_len and ifft_len to work unit header. + * + * Revision 2.9 1998/11/13 23:58:52 korpela + * Modified for move of name field between structures. + * + * Revision 2.8 1998/11/13 22:18:12 davea + * *** empty log message *** + * + * Revision 2.7 1998/11/10 01:55:26 korpela + * Server requires a CR at the end of a WU file + * ??? + * + * Revision 2.6 1998/11/10 00:02:44 korpela + * Moved remaining wuheader fields into a WU_INFO structure. + * + * Revision 2.5 1998/11/05 21:33:02 korpela + * Fixed angle_range bug. + * + * Revision 2.4 1998/11/05 21:18:41 korpela + * Moved name field from header to seti header. + * + * Revision 2.3 1998/11/02 21:20:58 korpela + * Modified for (internal) integer receiver ID. + * + * Revision 2.2 1998/11/02 18:45:39 korpela + * Changed location of timecvt.h + * + * Revision 2.1 1998/11/02 16:38:29 korpela + * Variable type changes. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.2 1998/10/30 20:26:03 korpela + * Bug Fixes. Now mostly working. + * + * Revision 1.1 1998/10/27 01:01:16 korpela + * Initial revision + * + * + */ diff --git a/splitter/wufiles.h b/splitter/wufiles.h new file mode 100644 index 0000000..046c378 --- /dev/null +++ b/splitter/wufiles.h @@ -0,0 +1,39 @@ +/* + * + * Functions for managing wufiles and their data + * + * $Id: wufiles.h,v 1.2 2003/08/05 17:23:45 korpela Exp $ + * + */ + + + +int make_wu_headers(tapeheader_t tapeheader[],workunit wuheaders[], + buffer_pos_t *start_of_wu) ; +void write_wufile_blocks(int nbytes) ; +void rename_wu_files(); + +/* + * $Log: wufiles.h,v $ + * Revision 1.2 2003/08/05 17:23:45 korpela + * More work on database stuff. + * Further tweaks. + * + * Revision 1.1 2003/06/03 00:23:44 korpela + * + * Again + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.1 1998/11/02 16:41:21 korpela + * Minor Change. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.1 1998/10/27 01:13:16 korpela + * Initial revision + * + * + */ diff --git a/splitter_old/Makefile.in b/splitter_old/Makefile.in new file mode 100644 index 0000000..11b8a06 --- /dev/null +++ b/splitter_old/Makefile.in @@ -0,0 +1,92 @@ +CC=gcc +BOINCDIR=@BOINCDIR@ +SSLDIR=@SSLDIR@ +INFORMIXDIR=@INFORMIXDIR@ +S4PATH=@S4PATH@ +S4LIBS=@S4LIBS@ +SETIHOME=.. + +LINKOPTIONS= + +INCLUDE_DIRS= -I$(SETIHOME) -I$(SETIHOME)/client -I$(SETIHOME)/db \ + @MYSQL_CFLAGS@ \ + @INFORMIX_CFLAGS@ @S4CFLAGS@ @RSA_CFLAGS@ \ + -I$(BOINCDIR)/api -I$(BOINCDIR)/sched -I$(BOINCDIR)/db -I$(BOINCDIR)/tools -I$(BOINCDIR)/lib + +DBLIBS=@INFORMIX_LIBS@ -lsocket -lm -lstdc++ + + +LINKOPTIONS=-Xlinker -R -Xlinker $(INFORMIXDIR)/lib:$(INFORMIXDIR)/lib/esql:$(LD_LIBRARY_PATH) + + +CFLAGS= -g -Wall $(INCLUDE_DIRS) -DUSE_INFORMIX @PTHREAD_CFLAGS@ + + +SUFFIXES = .cpp .o + +.cpp.o: + $(CC) $(CFLAGS) -c $< + + + +all: depend sah_splitter + +depend: *.cpp *.h Makefile + makedepend $(INCLUDE_DIRS) -I/usr/local/gcc/include/g++-v3/sparc-sun-solaris2.7 -I/usr/local/gcc/include/g++-v3 *.cpp + touch depend + +OBJECTS=angdist.o encode.o message.o splitter.o writeheader.o coordcvt.o \ + four1.o readheader.o wufiles.o polyphase.o dotransform.o \ + makebufs.o readtape.o validrun.o $(SETIHOME)/db/schema_master.o \ + $(SETIHOME)/db/sqlifx.o $(SETIHOME)/db/sqlrow.o \ + $(SETIHOME)/db/sqlblob.o $(SETIHOME)/db/sqlint8.o \ + $(SETIHOME)/db/xml_util.o \ + $(SETIHOME)/db/app_config.o \ + $(SETIHOME)/client/seti_boinc-seti_header.o \ + $(SETIHOME)/client/seti_boinc-timecvt.o \ + $(SETIHOME)/client/seti_boinc-lcgamm.o + +#BOINC_OBJS= ../boinc_client/s_util.o ../client/header.o \ +# ../boinc_client/seti_header.o ../boinc_client/timecvt.o \ +# /disks/philmor/a/users/eheien/boinc/lib/parse.o \ +# /disks/philmor/a/users/eheien/boinc/lib/util.o +# + +SYSLIBS = -lcrypto -ldl + +BOINCLIBS= -L$(BOINCDIR)/sched -lsched @MYSQL_LIBS@ @PTHREAD_LIBS@ -L$(BOINCDIR)/lib -lboinc -L$(SSLDIR) -lcrypto -lssl + +SPLITLIBS= -L. -lfftw \ + $(S4LIBS) \ + $(DBLIBS) \ + $(BOINCLIBS) \ + $(SYSLIBS) + +#SAH_OBJS= ../client/util.o ../client/header.o ../client/timecvt.o \ +# ../client/seti_header.o ../client/filesys.o ../client/socks.o ../client/network.o + +SAH_OBJS= hr_min_sec.o + +splitter: $(OBJECTS) $(SAH_OBJS) + gcc -o splitter $(OBJECTS) $(SAH_OBJS) $(SPLITLIBS) + +sah_splitter: $(OBJECTS) $(SAH_OBJS) + gcc -o sah_splitter $(LINKOPTIONS) $(OBJECTS) $(SAH_OBJS) $(SPLITLIBS) + +TESTDBLIBS= -L$(ZLIBDIR) -L. -lz -lfftw \ + -L /disks/asimov/a/apps/informix/lib \ + -L /disks/asimov/a/apps/informix/lib/esql \ + -lifsql -lifasf -lifgen -lifos -lifgls \ + -lnsl -lsocket -laio -lm -ldl -lelf \ + /disks/asimov/a/apps/informix/lib/esql/checkapi.o \ + -lifglx + + +testdb: testdb.o + gcc -o testdb testdb.o ../db/db.o $(TESTDBLIBS) + + +clean: + /bin/rm -f *.o sah_splitter splitter + +# DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/splitter_old/angdist.cpp b/splitter_old/angdist.cpp new file mode 100644 index 0000000..4da7132 --- /dev/null +++ b/splitter_old/angdist.cpp @@ -0,0 +1,79 @@ +/* + * angdist.c + * + * Computes angular distance between two lat/lon points + * + * $Id: angdist.cpp,v 1.1.2.1 2006/01/13 00:24:48 jeffc Exp $ + * + */ + +#include "config.h" +#include +#include +#include +#include "seti_header.h" + +#define DTOR (M_PI/180) + +double angdist(double r1, double d1, double r2, double d2) { + double alpha,dist,d; + + r1*=DTOR; + r2*=DTOR; + d1*=DTOR; + d2*=DTOR; + alpha=r1-r2; + dist=sin(d2)*sin(d1)+cos(d1)*cos(d2)*cos(alpha); + if ((dist*dist)<1) { + d=sqrt(1.0-dist*dist); + } else { + dist=1.0; + d=0.0; + } + dist=atan2(d,dist); + dist=dist/DTOR; + return (dist); +} + +double angdist(const SCOPE_STRING &a, const SCOPE_STRING &b) { + return angdist(a.ra*15,a.dec,b.ra*15,b.dec); +} + +/* + * $Log: angdist.cpp,v $ + * Revision 1.1.2.1 2006/01/13 00:24:48 jeffc + * *** empty log message *** + * + * Revision 1.3 2003/09/11 18:53:37 korpela + * *** empty log message *** + * + * Revision 1.2 2003/08/05 17:23:39 korpela + * More work on database stuff. + * Further tweaks. + * + * Revision 1.1 2003/07/29 20:35:31 korpela + * + * renames .C files to .cpp + * + * Revision 1.2 2003/06/03 01:01:15 korpela + * + * First working splitter under CVS. + * + * Revision 1.1 2003/06/03 00:16:08 korpela + * + * Initial splitter under CVS control. + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.1 1998/11/02 16:41:21 korpela + * Minor Change. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.1 1998/10/27 00:47:33 korpela + * Initial revision + * + * + */ diff --git a/splitter_old/angdist.h b/splitter_old/angdist.h new file mode 100644 index 0000000..76719f5 --- /dev/null +++ b/splitter_old/angdist.h @@ -0,0 +1,36 @@ +/* + * angdist.h + * + * Computes angular distance between two lat/lon points + * + * $Id: angdist.h,v 1.1.2.1 2006/01/13 00:24:48 jeffc Exp $ + * + */ + +double angdist(double r1, double d1, double r2, double d2) ; +double angdist(const SCOPE_STRING &a,const SCOPE_STRING &b); + +/* + * $Log: angdist.h,v $ + * Revision 1.1.2.1 2006/01/13 00:24:48 jeffc + * *** empty log message *** + * + * Revision 1.1 2003/06/03 00:16:09 korpela + * + * Initial splitter under CVS control. + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.1 1998/11/02 16:41:21 korpela + * Minor Change. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.1 1998/10/27 01:03:21 korpela + * Initial revision + * + * + */ + diff --git a/splitter_old/coordcvt.cpp b/splitter_old/coordcvt.cpp new file mode 100644 index 0000000..c1d09aa --- /dev/null +++ b/splitter_old/coordcvt.cpp @@ -0,0 +1,173 @@ +/* + * coordcvt.c + * + * Celestial coordinate conversion routines. + * + * $Id: coordcvt.cpp,v 1.1.2.1 2006/01/13 00:24:49 jeffc Exp $ + * + */ + +#include "config.h" +#include +#include +#include + +#include +#include +#include +#include + +#include "splitparms.h" +#include "splittypes.h" +#include "coordcvt.h" + +extern int gregorian; + +namespace SPLITTER { + +double jd_to_lmst(double jd, double longitude) { +/* + * converts from julian date/time to local mean siderial time + * + */ + + double tu; /* time, in centuries from Jan 0, 2000 */ + double tusqr; + double tucb; + double g; /* derrived from tu, used to calculate gmst */ + double gmst; /* Greenwich Mean Sidereal Time */ + double lmst; /* Local Mean Sidereal Time */ + double jd0=floor(jd+0.5)-0.5; /* jd at noon GMT */ + double ddtime=fmod((jd-jd0)*24,24); /* GMT hours */ + + tu = (jd0 - 2451545.0)/36525; + tusqr = tu * tu; + tucb = tusqr * tu; + +/* computation of the gmst at ddtime UT */ + + g = 24110.54841 + 8640184.812866 * tu + 0.093104 * tusqr - 6.62E-6 * tucb; + + for (gmst = g; gmst < 0; gmst += 86400) ; + + gmst /= 3600; /* GMST at 0h UT */ + gmst += (1.0027379093 * ddtime); /* GMST at utime UT */ + + gmst=fmod(gmst,24); + +/* computation of lmst given gmst and longitude */ + + lmst = gmst + ((longitude/360) * 24); + + if (lmst < 0) + lmst += 24; + lmst = fmod(lmst,24); + return(lmst); +} + + +void horz_to_equatorial(double alt, double azimuth, double lsthour, + double lat, double *ra, double *dec) { + double dec_rad, hour_ang_rad, zenith_ang=90.0-alt; + double temp; + + zenith_ang*=(M_PI/180.0); + azimuth*=(M_PI/180.0); + + dec_rad = asin ((cos(zenith_ang) * sin(lat*M_PI/180)) + + (sin(zenith_ang) * cos(lat*M_PI/180) * cos(azimuth))); + + *dec = dec_rad * 180.0/M_PI; /* radians to decimal degrees */ + + temp = (cos(zenith_ang) - sin(lat*M_PI/180) * sin(dec_rad)) / + (cos(lat*M_PI/180) * cos(dec_rad)); + if (temp > 1) + temp = 1; + else if (temp < -1) + temp = -1; + hour_ang_rad = acos (temp); + + if (sin(azimuth) > 0.0) /* insure correct quadrant */ + hour_ang_rad = (2 * M_PI) - hour_ang_rad; + + + /* to get ra, we convert hour angle to decimal degrees, */ + /* convert degrees to decimal hours, and subtract the */ + /* result from local sidereal decimal hours. */ + *ra = lsthour - ((hour_ang_rad * 180.0/M_PI) / 15.0); + + // Take care of wrap situations in RA + if (*ra < 0.0) + *ra += 24.0; + *ra=fmod(*ra,24); +} +#define D2R 0.017453292 + +void AltAzCorrection(double *alt, double *az) { + double zen=90-*alt; + co_ZenAzCorrection(gregorian?AOGREG_1420:AO_1420,&zen,az); + *alt=90-zen; +} +} + +void telstr_coord_convert(SCOPE_STRING *telstr, double lat, double lon) { + + double lmst=SPLITTER::jd_to_lmst(telstr->st.jd,lon); + + SPLITTER::AltAzCorrection(&(telstr->alt),&(telstr->az)); + SPLITTER::horz_to_equatorial(telstr->alt, telstr->az, lmst, lat, &(telstr->ra), + &(telstr->dec)); +} + +/* + * $Log: coordcvt.cpp,v $ + * Revision 1.1.2.1 2006/01/13 00:24:49 jeffc + * *** empty log message *** + * + * Revision 1.2 2003/09/11 18:53:37 korpela + * *** empty log message *** + * + * Revision 1.1 2003/07/29 20:35:33 korpela + * + * renames .C files to .cpp + * + * Revision 1.3 2003/06/05 19:01:45 korpela + * + * Fixed coordiate bug that allowed RA>24 hours. + * + * Revision 1.2 2003/06/05 15:52:46 korpela + * + * Fixed coordinate bug that was using the wrong zenith angle from the telescope + * strings when handling units from the gregorian. + * + * Revision 1.1 2003/06/03 00:16:09 korpela + * + * Initial splitter under CVS control. + * + * Revision 3.1 2003/05/20 16:01:54 eheien + * *** empty log message *** + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.3 1999/03/05 01:47:18 korpela + * New zenith angle correction. + * + * Revision 2.2 1999/02/22 22:21:09 korpela + * Fixed half-day error. + * + * Revision 2.1 1998/11/02 16:41:21 korpela + * Minor Change. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.2 1998/10/27 00:48:48 korpela + * Bug fixes. + * + * Revision 1.1 1998/10/19 23:02:43 korpela + * Initial revision + * + * + */ + diff --git a/splitter_old/coordcvt.h b/splitter_old/coordcvt.h new file mode 100644 index 0000000..d49d03d --- /dev/null +++ b/splitter_old/coordcvt.h @@ -0,0 +1,43 @@ +/* + * coordcvt.h + * + * Celestial coordinate conversion routines. + * + * $Id: coordcvt.h,v 1.1.2.1 2006/01/13 00:24:49 jeffc Exp $ + * + */ + +#ifndef COORDCVT_H +#define COORDCVT_H + +double jd_to_lmst(double jd, double longitude); + +void horz_to_equatorial(double alt, double azimuth, double lsthour, + double lat, double *ra, double *dec); + +void telstr_coord_convert(SCOPE_STRING *telstr, double lat, double lon); + +#endif + +/* + * $Log: coordcvt.h,v $ + * Revision 1.1.2.1 2006/01/13 00:24:49 jeffc + * *** empty log message *** + * + * Revision 1.1 2003/06/03 00:16:09 korpela + * + * Initial splitter under CVS control. + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.1 1998/11/02 16:41:21 korpela + * Minor Change. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.1 1998/10/19 23:03:18 korpela + * Initial revision + * + */ diff --git a/splitter_old/db_fns.cpp b/splitter_old/db_fns.cpp new file mode 100644 index 0000000..979873b --- /dev/null +++ b/splitter_old/db_fns.cpp @@ -0,0 +1,193 @@ +/* + * $Id: db_fns.cpp,v 1.1.2.1 2006/01/13 00:24:50 jeffc Exp $ + * + */ + + +#include "config.h" +#include +#include +#include +#include + +#include "splitparms.h" +#include "splittypes.h" +#include "splitter.h" +#include "message.h" +#include "readtape.h" +#include "sqlrow.h" +#include "sqlblob.h" +#include "db_table.h" +#include "schema_master.h" + + +static tape tape_struct; + +int update_tape_entry( tapeheader_t *tapeheader) ; + +int get_last_block(tapeheader_t *tapeheader) { + int err; + strncat(tape_struct.tapename,tapeheader->name,20); + fprintf( stderr, "Point 0: %s\n", tape_struct.tapename ); + if (!db_tape_lookup_name(&tape_struct)) { + return(tape_struct.last_block_done/TAPE_FRAMES_PER_RECORD); + } else { + if ((err=db_tape_new(&tape_struct))) { + char tmpstr[256]; + fprintf( stderr, "Point 1: %d\n", err ); + sprintf(tmpstr,"Unable to create db entry for tape %s.\n",tapeheader->name +); + message(tmpstr); + exit(1); + } + return 0; + } +} + + +/* returns id number of tape db entry or zero if failure */ +/*int update_tape_entry( tapeheader_t *tapeheader) { + if (strncmp(tapeheader->name,tape_struct.tapename,20)) { + strncat(tape_struct.tapename,tapeheader->name,20); + if (db_tape_lookup_name(&tape_struct)) { + tape_struct.id=0; + strncpy(tape_struct.tapename,tapeheader->name,20); + tape_struct.start_time=tapeheader->st.jd; + tape_struct.last_block_time=tapeheader->st.jd; + tape_struct.last_block_done=tapeheader->frameseq; + if (db_tape_new(&tape_struct)) { + char tmpstr[256]; + fprintf( stderr, "Point 2\n" ); + sprintf(tmpstr,"Unable to create db entry for tape %s.",tapeheader->name); + message(tmpstr); + return(0); + } + } + } + tape_struct.last_block_time=tapeheader->st.jd; + tape_struct.last_block_done=tapeheader->frameseq; + if (db_tape_update(&tape_struct)) { + char tmpstr[256]; + sprintf(tmpstr,"Unable to update db entry for tape %s.",tapeheader->name); + message(tmpstr); + return(0); + } + return(tape_struct.id); +} +*/ + +/* returns workunit group id number on success, 0 on failure */ +/* +int create_wugrp_entry(workunit_grp &wugrp, int tapenum, tapeheader_t *tapeheader) { + int i,n; + + wugrp.tapenum=tapenum; + strncpy(wugrp.wugrpname,wugrpname,64); + wugrp.splitter_version=wuheader->wuinfo.splitter_version; + wugrp.start_ra=wuheader->wuinfo.start_ra; + wugrp.start_dec=wuheader->wuinfo.start_dec; + wugrp.end_ra=wuheader->wuinfo.end_ra; + wugrp.end_dec=wuheader->wuinfo.end_dec; + wugrp.angle_range=wuheader->wuinfo.angle_range; + wugrp.true_angle_range=wuheader->wuinfo.true_angle_range; + wugrp.beam_width=wuheader->wuinfo.beam_width; + wugrp.time_recorded=wuheader->wuinfo.time_recorded; + wugrp.fft_len=wuheader->wuinfo.fft_len; + wugrp.ifft_len=wuheader->wuinfo.ifft_len; + wugrp.receiver=wuheader->wuinfo.source; + wugrp.nsamples=wuheader->wuinfo.nsamples; + wugrp.sample_rate=tapeheader->samplerate; + wugrp.data_class=wuheader->wuinfo.data_class; + strncpy(wugrp.tape_version,wuheader->wuinfo.tape_version,13); + wugrp.num_positions=wuheader->wuinfo.num_positions; + if (db_workunit_grp_new(&wugrp)) { + char tmpstr[256]; + sprintf(tmpstr,"Unable to create db entry for workunit_grp %s\n",wugrpname); + message(tmpstr); + return(0); + } + for (i=0;iwuinfo.position_history[i].st.jd, + wuheader->wuinfo.position_history[i].ra, + wuheader->wuinfo.position_history[i].dec + ); + if (n=db_workunit_grp_update_position(wugrp.id,i,tmpstr)) { + fprintf( stderr, "%d\n", n ); + sprintf(tmpstr,"Unable to add position %d to workunit_grp %s\n",i,wugrpname); + message(tmpstr); + } + } + return (wugrp.id); +} + +int create_workunit_entry(wuheader_t *wuheader, int wugrpid, int subband_number) { + WORKUNIT wu; + + memset(&wu,0,sizeof(wu)); + strncpy(wu.name,wuheader->wuhead.name,63); + wu.grpnum=wugrpid; + wu.subb_center=wuheader->wuinfo.subband_center; + wu.subb_base=wuheader->wuinfo.subband_base; + wu.subb_sample_rate=wuheader->wuinfo.subband_sample_rate; + wu.subband_number=subband_number; + wu.data_class=wuheader->wuinfo.data_class; + if (db_workunit_new(&wu)) { + char tmpstr[256]; + sprintf(tmpstr,"Unable to create workunit entry %s\n",wu.name); + message(tmpstr); + return(0); + } + return(wu.id); +} +*/ + +/* + * $Log: db_fns.cpp,v $ + * Revision 1.1.2.1 2006/01/13 00:24:50 jeffc + * *** empty log message *** + * + * Revision 1.3 2003/09/11 18:53:37 korpela + * *** empty log message *** + * + * Revision 1.2 2003/08/05 17:23:40 korpela + * More work on database stuff. + * Further tweaks. + * + * Revision 1.1 2003/07/29 20:35:35 korpela + * + * renames .C files to .cpp + * + * Revision 1.2 2003/06/03 01:01:16 korpela + * + * First working splitter under CVS. + * + * Revision 1.1 2003/06/03 00:16:10 korpela + * + * Initial splitter under CVS control. + * + * Revision 3.2 2003/05/19 17:40:59 eheien + * *** empty log message *** + * + * Revision 3.1 2001/11/07 00:51:47 korpela + * Added splitter version to database. + * Added max_wus_ondisk option. + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 1.4 2000/12/01 01:13:29 korpela + * *** empty log message *** + * +// Revision 1.3 1999/03/05 01:47:18 korpela +// Added data_class field. +// +// Revision 1.2 1999/02/22 22:21:09 korpela +// Fixed half-day error. +// +// Revision 1.1 1999/02/11 16:46:28 korpela +// Initial revision +// + * + */ diff --git a/splitter_old/db_fns.h b/splitter_old/db_fns.h new file mode 100644 index 0000000..5e3e6ee --- /dev/null +++ b/splitter_old/db_fns.h @@ -0,0 +1,51 @@ +/* + * $Id: db_fns.h,v 1.1.2.1 2006/01/13 00:24:50 jeffc Exp $ + * + */ + + +#ifndef DB_FNS_H +#define DB_FNS_H + +#include "schema_master.h" + +int get_last_block(tapeheader_t *tapeheader) ; + +//int update_tape_entry( tapeheader_t *tapeheader) ; + +/* returns workunit group id number on success, 0 on failure */ +//int create_wugrp_entry(char *wugrpname,wuheader_t *wuheader, int tapenum, tapeheader_t *tapeheader) ; + +//int create_workunit_entry(wuheader_t *wuheader, int wugrpid, int subband_number) ; + +#endif + +/* + * + * $Log: db_fns.h,v $ + * Revision 1.1.2.1 2006/01/13 00:24:50 jeffc + * *** empty log message *** + * + * Revision 1.3 2003/08/05 17:23:40 korpela + * More work on database stuff. + * Further tweaks. + * + * Revision 1.2 2003/06/03 01:01:16 korpela + * + * First working splitter under CVS. + * + * Revision 1.1 2003/06/03 00:16:10 korpela + * + * Initial splitter under CVS control. + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 1.2 1999/02/22 22:21:09 korpela + * added -nodb option + * + * Revision 1.1 1999/02/11 16:46:28 korpela + * Initial revision + * + * + */ diff --git a/splitter_old/dotransform.cpp b/splitter_old/dotransform.cpp new file mode 100644 index 0000000..ea3c717 --- /dev/null +++ b/splitter_old/dotransform.cpp @@ -0,0 +1,218 @@ +/* + * + * dotransform.c + * + * Functions for division by frequency into work units. + * + * $Id: dotransform.cpp,v 1.1.2.1 2006/01/13 00:24:50 jeffc Exp $ + * + */ + +#include "config.h" +#include +#include +#include +#include +#include +#include +#include + +#include "splitparms.h" +#include "splittypes.h" +#include "splitter.h" +#include "fftw.h" +#include "wufiles.h" + +/* buffer for fft input/output */ +float databuf[FFT_LEN*2]; + +/* buffer for ftt output before data writes, needs to be multiple + * of three bytes long for encode to work. + */ +#define SAMPLES_PER_OBUF (FFT_LEN*2*3/CHAR_BIT) +unsigned char output_buf[NSTRIPS][SAMPLES_PER_OBUF]; + + +int obuf_pos; /* Tracks current postition in the output buffers */ + + +void output_samples(float *data, int i, int buf_pos) { + int j,k; + unsigned short s; + float *p=data; + + for (j=0;j<2;j++) { + s=0; + for (k=0; k<8; k++) { + s >>= 2; + if (*p>0) s |= 0x8000; + if (*(p+1)>0) s |= 0x4000; + p+=2; + } + output_buf[i][buf_pos++]=*(char *)(&s); + output_buf[i][buf_pos++]=*(((char *)(&s))+1); + } +} + +void splitter_bits_to_float(unsigned short *raw, float *data, int nsamples) { + unsigned int i, j; + unsigned short s; + static int first_time=1; + static float lut[65536][16]; + + assert(!(nsamples % 8)); + + if (first_time) { + for (i=0;i<65536;i++) { + s=(unsigned short)i; + for (j=0;j<8;j++) { + lut[i][j*2]=(float)2*(s & 1)-1; + s >>= 1; + lut[i][j*2+1]=(float)2*(s & 1)-1; + s >>= 1; + } + } + first_time--; + } + + for (i=0;i<(nsamples/8);i++) { + memcpy(data+16*i,lut[raw[i]],16*sizeof(float)); + } +} + +void process_seg(float* data) { + int i; + float* p = data; + static float dbuff[FFT_LEN*2]; + static fftw_plan planfwd,planinverse; + + if (!planfwd) { + planfwd=fftw_create_plan(FFT_LEN, FFTW_BACKWARD, + FFTW_MEASURE | FFTW_IN_PLACE | FFTW_USE_WISDOM ); + planinverse=fftw_create_plan(IFFT_LEN, FFTW_FORWARD, + FFTW_MEASURE | FFTW_IN_PLACE | FFTW_USE_WISDOM ); + } + + fftw_one(planfwd, (fftw_complex *)data, (fftw_complex *)NULL); + data[0]=0; + data[1]=0; + fftw(planinverse, NSTRIPS, (fftw_complex *)data, 1, IFFT_LEN, + (fftw_complex *)NULL, 1, IFFT_LEN); + for (i=0; i TAPE_DATA_SIZE) { + /* End of frame crossed need to trasfer correctly */ + end_trans.frame++; + end_trans.byte-=TAPE_DATA_SIZE; + nsamp=(TAPE_DATA_SIZE-start_trans.byte)*(CHAR_BIT/2); + assert((nsamp+end_trans.byte*(CHAR_BIT/2)) == FFT_LEN); + splitter_bits_to_float((unsigned short *)TBUF_OFFSET(start_trans.frame,start_trans.byte), + databuf, nsamp); + splitter_bits_to_float((unsigned short *)TBUF_OFFSET(end_trans.frame,0),databuf+nsamp*2, + end_trans.byte*(CHAR_BIT/2)); + } else { + splitter_bits_to_float((unsigned short *)TBUF_OFFSET(start_trans.frame,start_trans.byte), + databuf,FFT_LEN); + } + process_seg(databuf); + /* Go on to next transform */ + start_trans=end_trans; + } + /* Check if we're at the end of the wu file. If so we print less bytes */ + if ((end_trans.frame>=end_of_wu->frame) && + (end_trans.byte>=end_of_wu->byte)) { + write_wufile_blocks(NBYTES % SAMPLES_PER_OBUF); + } else { + write_wufile_blocks(SAMPLES_PER_OBUF); + } + } while (!((end_trans.frame>=end_of_wu->frame) && (end_trans.byte>=end_of_wu->byte))); + + /* Move the data in the buffer so we don't have to reread portions of the + * tape. + */ + { + unsigned char *record_offset; + int copysize; + end_of_wu->frame-=WU_OVERLAP_FRAMES; + records_in_buffer=TAPE_RECORDS_IN_BUFFER- + (end_of_wu->frame/TAPE_FRAMES_PER_RECORD); + record_offset=tapebuffer+ + (end_of_wu->frame/TAPE_FRAMES_PER_RECORD)*TAPE_RECORD_SIZE; + copysize=records_in_buffer*TAPE_RECORD_SIZE; + bcopy(record_offset,tapebuffer,copysize); + } +} + +/* + * + * $Log: dotransform.cpp,v $ + * Revision 1.1.2.1 2006/01/13 00:24:50 jeffc + * *** empty log message *** + * + * Revision 1.2 2003/09/11 18:53:37 korpela + * *** empty log message *** + * + * Revision 1.1 2003/07/29 20:35:36 korpela + * + * renames .C files to .cpp + * + * Revision 1.1 2003/06/03 00:16:10 korpela + * + * Initial splitter under CVS control. + * + * Revision 3.2 2003/05/19 17:40:59 eheien + * *** empty log message *** + * + * Revision 3.1 2003/04/10 22:09:00 korpela + * *** empty log message *** + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.7 1999/03/27 16:19:35 korpela + * *** empty log message *** + * + * Revision 2.6 1999/02/22 19:02:50 korpela + * Revered input real & imaginary. + * + * Revision 2.5 1999/02/10 21:49:44 korpela + * Zeroed DC component of forward transform. + * + * Revision 2.4 1999/02/01 22:28:52 korpela + * FFTW version. + * + * Revision 2.3 1998/12/14 23:41:44 korpela + * *** empty log message *** + * + * Revision 2.2 1998/11/04 23:08:25 korpela + * Byte and bit order change. + * + * Revision 2.1 1998/11/02 16:41:21 korpela + * Minor Change. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.2 1998/10/30 20:26:03 korpela + * Bug Fixes. Now mostly working. + * + * Revision 1.1 1998/10/27 00:51:08 korpela + * Initial revision + * + * + */ diff --git a/splitter_old/dotransform.h b/splitter_old/dotransform.h new file mode 100644 index 0000000..6653812 --- /dev/null +++ b/splitter_old/dotransform.h @@ -0,0 +1,59 @@ +/* + * + * dotransform.h + * + * Functions for division by frequency into work units. + * + * $Id: dotransform.h,v 1.1.2.1 2006/01/13 00:24:51 jeffc Exp $ + * + */ + +/* buffer for fft input/output */ +extern float databuf[FFT_LEN*2]; + +/* buffer for ftt output before data writes, needs to be multiple + * of three bytes long for encode to work. + */ +#define SAMPLES_PER_OBUF (FFT_LEN*2*3/CHAR_BIT) +#define TBUF_OFFSET(frame,byte) (tapebuffer+(frame)*TAPE_FRAME_SIZE+(byte)) +extern unsigned char output_buf[NSTRIPS][SAMPLES_PER_OBUF]; + + +extern int obuf_pos; /* Tracks current postition in the output buffers */ + + +void output_samples(float *data, int i, int buf_pos); +void splitter_bits_to_float(unsigned short *raw, float *data, int nsamples) ; +void process_seg(float* data) ; +void do_transform(buffer_pos_t *start_of_wu, buffer_pos_t *end_of_wu) ; + +/* + * + * $Log: dotransform.h,v $ + * Revision 1.1.2.1 2006/01/13 00:24:51 jeffc + * *** empty log message *** + * + * Revision 1.1 2003/06/03 00:16:11 korpela + * + * Initial splitter under CVS control. + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.3 1999/02/01 22:28:52 korpela + * FFTW version. + * + * Revision 2.2 1998/11/04 23:08:25 korpela + * Byte and bit order change. + * + * Revision 2.1 1998/11/02 16:41:21 korpela + * Minor Change. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.1 1998/10/27 01:05:22 korpela + * Initial revision + * + * + */ diff --git a/splitter_old/encode.cpp b/splitter_old/encode.cpp new file mode 100644 index 0000000..ad9f4df --- /dev/null +++ b/splitter_old/encode.cpp @@ -0,0 +1,88 @@ +/* + * + * binary to ascii encoding for work unit files + * + * $Id: encode.cpp,v 1.1.2.1 2006/01/13 00:24:51 jeffc Exp $ + * + */ + +#include "config.h" +#include +#include +#include +#include + +/* Write a range of bytes encoded into printable chars. + * Encodes 3 bytes into 4 chars. + * May read up to two bytes past end + */ + +void splitter_encode(unsigned char *bin, int nbytes, FILE *f) { + int count=0, offset=0, nleft, count1=0; + unsigned char c[4*1024+64]; + unsigned char nl=10; + assert(nbytes<=(3*1024)); + for (nleft = nbytes; nleft > 0; nleft -= 3) { + c[0+count1] = bin[offset]&0x3f; // 6 + c[1+count1] = (bin[offset]>>6) | (bin[offset+1]<<2)&0x3f; // 2+4 + c[2+count1] = ((bin[offset+1]>>4)&0xf) | (bin[offset+2]<<4)&0x3f;// 4+2 + c[3+count1] = bin[offset+2]>>2; // 6 + c[0+count1] += 0x20; + c[1+count1] += 0x20; + c[2+count1] += 0x20; + c[3+count1] += 0x20; + offset += 3; + count += 4; + count1 +=4; + if (count == 64) { + count = 0; + c[count1++]=nl; + } + } + write(f->_file,c,count1); +} + +/* + * + * $Log: encode.cpp,v $ + * Revision 1.1.2.1 2006/01/13 00:24:51 jeffc + * *** empty log message *** + * + * Revision 1.2 2003/09/11 18:53:37 korpela + * *** empty log message *** + * + * Revision 1.1 2003/07/29 20:35:37 korpela + * + * renames .C files to .cpp + * + * Revision 1.1 2003/06/03 00:16:11 korpela + * + * Initial splitter under CVS control. + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.3 1998/11/04 23:08:25 korpela + * Byte and bit order change. + * + * Revision 2.2 1998/11/02 21:20:58 korpela + * changed function name from encode() to splitter_encode() to avoid + * conflict with encode routine in ../client/util.C. Will investigate + * if merging of two functions is possible. + * + * Revision 2.1 1998/11/02 16:41:21 korpela + * Minor Change. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.2 1998/10/30 20:26:03 korpela + * Bug Fixes. Now mostly working. + * + * Revision 1.1 1998/10/27 00:52:56 korpela + * Initial revision + * + * + */ + + diff --git a/splitter_old/encode.h b/splitter_old/encode.h new file mode 100644 index 0000000..d842027 --- /dev/null +++ b/splitter_old/encode.h @@ -0,0 +1,42 @@ +/* + * + * binary to ascii encoding for work unit files + * + * $Id: encode.h,v 1.1.2.1 2006/01/13 00:24:52 jeffc Exp $ + * + */ + +/* Write a range of bytes encoded into printable chars. + * Encodes 3 bytes into 4 chars. + * May read up to two bytes past end + */ + +void splitter_encode(unsigned char *bin, int nbytes, FILE *f); + +/* + * $Log: encode.h,v $ + * Revision 1.1.2.1 2006/01/13 00:24:52 jeffc + * *** empty log message *** + * + * Revision 1.1 2003/06/03 00:16:11 korpela + * + * Initial splitter under CVS control. + * + * Revision 3.0 2001/08/01 19:04:57 korpela + * Check this in before Paul screws it up. + * + * Revision 2.2 1998/11/02 21:20:58 korpela + * Changed routine name from encode() to splitter_encode(). See encode.C + * for details. + * + * Revision 2.1 1998/11/02 16:41:21 korpela + * Minor Change. + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.1 1998/10/27 01:06:46 korpela + * Initial revision + * + * + */ diff --git a/splitter_old/fftw.h b/splitter_old/fftw.h new file mode 100644 index 0000000..9e0b72d --- /dev/null +++ b/splitter_old/fftw.h @@ -0,0 +1,413 @@ +/* fftw/fftw.h. Generated automatically by configure. */ +/* -*- C -*- */ +/* + * Copyright (c) 1997,1998 Massachusetts Institute of Technology + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/* fftw.h -- system-wide definitions */ +/* $Id: fftw.h,v 1.1.2.1 2006/01/13 00:24:52 jeffc Exp $ */ + +#ifndef FFTW_H +#define FFTW_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Define for using single precision */ +/* + * If you can, use configure --enable-float instead of changing this + * flag directly + */ +#define FFTW_ENABLE_FLOAT 1 + +/* our real numbers */ +#ifdef FFTW_ENABLE_FLOAT +typedef float fftw_real; +#else +typedef double fftw_real; +#endif + +/********************************************* + * Complex numbers and operations + *********************************************/ +typedef struct { + fftw_real re, im; +} fftw_complex; + +#define c_re(c) ((c).re) +#define c_im(c) ((c).im) + +typedef enum { + FFTW_FORWARD = -1, FFTW_BACKWARD = 1 +} fftw_direction; + +/* backward compatibility with FFTW-1.3 */ +typedef fftw_complex FFTW_COMPLEX; +typedef fftw_real FFTW_REAL; + +#ifndef FFTW_1_0_COMPATIBILITY +#define FFTW_1_0_COMPATIBILITY 0 +#endif + +#if FFTW_1_0_COMPATIBILITY +/* backward compatibility with FFTW-1.0 */ +#define REAL fftw_real +#define COMPLEX fftw_complex +#endif + +/********************************************* + * Success or failure status + *********************************************/ + +typedef enum { + FFTW_SUCCESS = 0, FFTW_FAILURE = -1 +} fftw_status; + +/********************************************* + * Codelets + *********************************************/ +typedef void (fftw_notw_codelet) + (const fftw_complex *, fftw_complex *, int, int); +typedef void (fftw_twiddle_codelet) + (fftw_complex *, const fftw_complex *, int, + int, int); +typedef void (fftw_generic_codelet) + (fftw_complex *, const fftw_complex *, int, + int, int, int); +typedef void (fftw_real2hc_codelet) + (const fftw_real *, fftw_real *, fftw_real *, + int, int, int); +typedef void (fftw_hc2real_codelet) + (const fftw_real *, const fftw_real *, + fftw_real *, int, int, int); +typedef void (fftw_hc2hc_codelet) + (fftw_real *, const fftw_complex *, + int, int, int); +typedef void (fftw_rgeneric_codelet) + (fftw_real *, const fftw_complex *, int, + int, int, int); + +/********************************************* + * Configurations + *********************************************/ +/* + * A configuration is a database of all known codelets + */ + +enum fftw_node_type { + FFTW_NOTW, FFTW_TWIDDLE, FFTW_GENERIC, FFTW_RADER, + FFTW_REAL2HC, FFTW_HC2REAL, FFTW_HC2HC, FFTW_RGENERIC +}; + +/* description of a codelet */ +typedef struct { + const char *name; /* name of the codelet */ + void (*codelet) (); /* pointer to the codelet itself */ + int size; /* size of the codelet */ + fftw_direction dir; /* direction */ + enum fftw_node_type type; /* TWIDDLE or NO_TWIDDLE */ + int signature; /* unique id */ + int ntwiddle; /* number of twiddle factors */ + const int *twiddle_order; /* + * array that determines the order + * in which the codelet expects + * the twiddle factors + */ +} fftw_codelet_desc; + +/* On Win32, you need to do funny things to access global variables + in shared libraries. Thanks to Andrew Sterian for this hack. */ +#if defined(__WIN32__) || defined(WIN32) || defined(_WINDOWS) +# if defined(BUILD_FFTW_DLL) +# define DL_IMPORT(type) __declspec(dllexport) type +# elif defined(USE_FFTW_DLL) +# define DL_IMPORT(type) __declspec(dllimport) type +# else +# define DL_IMPORT(type) type +# endif +#else +# define DL_IMPORT(type) type +#endif + +extern DL_IMPORT(const char *) fftw_version; + +/***************************** + * Plans + *****************************/ +/* + * A plan is a sequence of reductions to compute a FFT of + * a given size. At each step, the FFT algorithm can: + * + * 1) apply a notw codelet, or + * 2) recurse and apply a twiddle codelet, or + * 3) apply the generic codelet. + */ + +/* structure that contains twiddle factors */ +typedef struct fftw_twiddle_struct { + int n; + const fftw_codelet_desc *cdesc; + fftw_complex *twarray; + struct fftw_twiddle_struct *next; + int refcnt; +} fftw_twiddle; + +typedef struct fftw_rader_data_struct { + struct fftw_plan_struct *plan; + fftw_complex *omega; + int g, ginv; + int p, flags, refcount; + struct fftw_rader_data_struct *next; + fftw_codelet_desc *cdesc; +} fftw_rader_data; + +typedef void (fftw_rader_codelet) + (fftw_complex *, const fftw_complex *, int, + int, int, fftw_rader_data *); + +/* structure that holds all the data needed for a given step */ +typedef struct fftw_plan_node_struct { + enum fftw_node_type type; + + union { + /* nodes of type FFTW_NOTW */ + struct { + int size; + fftw_notw_codelet *codelet; + const fftw_codelet_desc *codelet_desc; + } notw; + + /* nodes of type FFTW_TWIDDLE */ + struct { + int size; + fftw_twiddle_codelet *codelet; + fftw_twiddle *tw; + struct fftw_plan_node_struct *recurse; + const fftw_codelet_desc *codelet_desc; + } twiddle; + + /* nodes of type FFTW_GENERIC */ + struct { + int size; + fftw_generic_codelet *codelet; + fftw_twiddle *tw; + struct fftw_plan_node_struct *recurse; + } generic; + + /* nodes of type FFTW_RADER */ + struct { + int size; + fftw_rader_codelet *codelet; + fftw_rader_data *rader_data; + fftw_twiddle *tw; + struct fftw_plan_node_struct *recurse; + } rader; + + /* nodes of type FFTW_REAL2HC */ + struct { + int size; + fftw_real2hc_codelet *codelet; + const fftw_codelet_desc *codelet_desc; + } real2hc; + + /* nodes of type FFTW_HC2REAL */ + struct { + int size; + fftw_hc2real_codelet *codelet; + const fftw_codelet_desc *codelet_desc; + } hc2real; + + /* nodes of type FFTW_HC2HC */ + struct { + int size; + fftw_direction dir; + fftw_hc2hc_codelet *codelet; + fftw_twiddle *tw; + struct fftw_plan_node_struct *recurse; + const fftw_codelet_desc *codelet_desc; + } hc2hc; + + /* nodes of type FFTW_RGENERIC */ + struct { + int size; + fftw_direction dir; + fftw_rgeneric_codelet *codelet; + fftw_twiddle *tw; + struct fftw_plan_node_struct *recurse; + } rgeneric; + } nodeu; + + int refcnt; +} fftw_plan_node; + +struct fftw_plan_struct { + int n; + int refcnt; + fftw_direction dir; + int flags; + int wisdom_signature; + enum fftw_node_type wisdom_type; + struct fftw_plan_struct *next; + fftw_plan_node *root; + double cost; +}; + +/* a plan is just an array of instructions */ +typedef struct fftw_plan_struct *fftw_plan; + +/* flags for the planner */ +#define FFTW_ESTIMATE (0) +#define FFTW_MEASURE (1) + +#define FFTW_OUT_OF_PLACE (0) +#define FFTW_IN_PLACE (8) +#define FFTW_USE_WISDOM (16) + +#define FFTW_THREADSAFE (128) /* guarantee plan is read-only so that the + same plan can be used in parallel by + multiple threads */ + +#define FFTWND_FORCE_BUFFERED (256) /* internal, undocumented flag */ + +extern fftw_plan fftw_create_plan_specific(int n, fftw_direction dir, + int flags, + fftw_complex *in, int istride, + fftw_complex *out, int ostride); +#define FFTW_HAS_PLAN_SPECIFIC +extern fftw_plan fftw_create_plan(int n, fftw_direction dir, int flags); +extern void fftw_print_plan(fftw_plan plan); +extern void fftw_destroy_plan(fftw_plan plan); +extern void fftw(fftw_plan plan, int howmany, fftw_complex *in, int istride, + int idist, fftw_complex *out, int ostride, int odist); +extern void fftw_one(fftw_plan plan, fftw_complex *in, fftw_complex *out); +extern void fftw_die(const char *s); +extern void *fftw_malloc(size_t n); +extern void fftw_free(void *p); +extern void fftw_check_memory_leaks(void); +extern void fftw_print_max_memory_usage(void); + +typedef void *(*fftw_malloc_type_function) (size_t n); +typedef void (*fftw_free_type_function) (void *p); +typedef void (*fftw_die_type_function) (const char *errString); +extern DL_IMPORT(fftw_malloc_type_function) fftw_malloc_hook; +extern DL_IMPORT(fftw_free_type_function) fftw_free_hook; +extern DL_IMPORT(fftw_die_type_function) fftw_die_hook; + +extern size_t fftw_sizeof_fftw_real(void); + +/* Wisdom: */ +/* + * define this symbol so that users know we are using a version of FFTW + * with wisdom + */ +#define FFTW_HAS_WISDOM +extern void fftw_forget_wisdom(void); +extern void fftw_export_wisdom(void (*emitter) (char c, void *), void *data); +extern fftw_status fftw_import_wisdom(int (*g) (void *), void *data); +extern void fftw_export_wisdom_to_file(FILE *output_file); +extern fftw_status fftw_import_wisdom_from_file(FILE *input_file); +extern char *fftw_export_wisdom_to_string(void); +extern fftw_status fftw_import_wisdom_from_string(const char *input_string); + +/* + * define symbol so we know this function is available (it is not in + * older FFTWs) + */ +#define FFTW_HAS_FPRINT_PLAN +extern void fftw_fprint_plan(FILE *f, fftw_plan plan); + +/***************************** + * N-dimensional code + *****************************/ +typedef struct { + int is_in_place; /* 1 if for in-place FFTs, 0 otherwise */ + + int rank; /* + * the rank (number of dimensions) of the + * array to be FFTed + */ + int *n; /* + * the dimensions of the array to the + * FFTed + */ + fftw_direction dir; + + int *n_before; /* + * n_before[i] = product of n[j] for j < i + */ + int *n_after; /* n_after[i] = product of n[j] for j > i */ + + fftw_plan *plans; /* 1d fftw plans for each dimension */ + + int nbuffers, nwork; + fftw_complex *work; /* + * work array big enough to hold + * nbuffers+1 of the largest dimension + * (has nwork elements) + */ +} fftwnd_data; + +typedef fftwnd_data *fftwnd_plan; + +/* Initializing the FFTWND plan: */ +extern fftwnd_plan fftw2d_create_plan(int nx, int ny, fftw_direction dir, + int flags); +extern fftwnd_plan fftw3d_create_plan(int nx, int ny, int nz, + fftw_direction dir, int flags); +extern fftwnd_plan fftwnd_create_plan(int rank, const int *n, + fftw_direction dir, + int flags); + +extern fftwnd_plan fftw2d_create_plan_specific(int nx, int ny, + fftw_direction dir, + int flags, + fftw_complex *in, int istride, + fftw_complex *out, int ostride); +extern fftwnd_plan fftw3d_create_plan_specific(int nx, int ny, int nz, + fftw_direction dir, int flags, + fftw_complex *in, int istride, + fftw_complex *out, int ostride); +extern fftwnd_plan fftwnd_create_plan_specific(int rank, const int *n, + fftw_direction dir, + int flags, + fftw_complex *in, int istride, + fftw_complex *out, int ostride); + +/* Freeing the FFTWND plan: */ +extern void fftwnd_destroy_plan(fftwnd_plan plan); + +/* Printing the plan: */ +extern void fftwnd_fprint_plan(FILE *f, fftwnd_plan p); +extern void fftwnd_print_plan(fftwnd_plan p); +#define FFTWND_HAS_PRINT_PLAN + +/* Computing the N-Dimensional FFT */ +extern void fftwnd(fftwnd_plan plan, int howmany, + fftw_complex *in, int istride, int idist, + fftw_complex *out, int ostride, int odist); +extern void fftwnd_one(fftwnd_plan p, fftw_complex *in, fftw_complex *out); + +#ifdef __cplusplus +} /* extern "C" */ + +#endif /* __cplusplus */ +#endif /* FFTW_H */ diff --git a/splitter_old/four1.cpp b/splitter_old/four1.cpp new file mode 100644 index 0000000..29f613a --- /dev/null +++ b/splitter_old/four1.cpp @@ -0,0 +1,88 @@ +/* + * + * Fourier transform routine from numerical recipes. + * + * $Id: four1.cpp,v 1.1.2.1 2006/01/13 00:24:52 jeffc Exp $ + * + */ + +#include "config.h" +#include +#define SWAP(a,b) tempr=(a);(a)=(b);(b)=tempr + +void four1(float data[], unsigned long nn, int isign) { + unsigned long n,mmax,m,j,istep,i; + double wtemp,wr,wpr,wpi,wi,theta; + float tempr,tempi; + + n=nn << 1; + j=1; + for (i=1;i i) { + SWAP(data[j],data[i]); + SWAP(data[j+1],data[i+1]); + } + m=n >> 1; + while (m >= 2 && j > m) { + j -= m; + m >>= 1; + } + j += m; + } + mmax=2; + while (n > mmax) { + istep=mmax << 1; + theta=isign*(6.28318530717959/mmax); + wtemp=sin(0.5*theta); + wpr = -2.0*wtemp*wtemp; + wpi=sin(theta); + wr=1.0; + wi=0.0; + for (m=1;m +#include + +char* hr_min_sec (double x) { + static char buf[256]; + int hr = (int)(x / 3600); + int min = (int)((x/3600-(double)hr)*60); + float s = (float)(x - ((double)hr)*3600 - ((double)min)*60); + + // the "-.05" below is to prevent it from printing 60.0 sec + // when the real value is e.g. 59.91 + // + sprintf(buf, "%d hr %02d min %04.1f sec", hr, min, s-.05); + return buf; +} + + +/* + * $Log: hr_min_sec.cpp,v $ + * Revision 1.1.2.1 2006/01/13 00:24:53 jeffc + * *** empty log message *** + * + * Revision 1.2 2003/09/11 18:53:38 korpela + * *** empty log message *** + * + * Revision 1.1 2003/07/29 20:35:40 korpela + * + * renames .C files to .cpp + * + * Revision 1.1 2003/06/03 01:01:16 korpela + * + * First working splitter under CVS. + * + * Revision 4.4 2003/03/10 02:50:03 jeffc + * jeffc - t_strncpy() + * + * Revision 4.3 2003/01/22 20:51:58 korpela + * Changed all strcpy to strncpy. + * Changed all gets to fgets. + * + * Revision 4.2 2001/12/27 21:35:57 davea + * *** empty log message *** + * + * Revision 4.1 2001/09/10 00:25:17 davea + * *** empty log message *** + * + * Revision 4.0 2000/10/05 18:12:12 korpela + * Synchronized versions to 4.0 following release of 3.0 client + * + * Revision 3.8 2000/09/14 01:01:31 korpela + * *** empty log message *** + * + * Revision 3.7 2000/04/24 08:39:06 charlief + * eliminate compiler warning in hr_min_sec() function. + * + * Revision 3.6 2000/01/19 08:32:32 davea + * *** empty log message *** + * + * Revision 3.5 1999/10/19 08:07:24 davea + * *** empty log message *** + * + * Revision 3.4 1999/06/26 06:56:44 hiramc + * Hiram 99/06/25 23:59 moved the include out of the + * ifdef _WIN32 to define strcpy() for all compiles + * + * Revision 3.3 1999/06/22 09:40:36 charlief + * Reverse last change:restore jd_string() as it was before. + * Add new function short_jd_string(), which does not print + * Julian Date as a floating point value. + * + * Revision 3.1 1999/06/10 00:44:11 korpela + * *** empty log message *** + * + * Revision 3.0 1999/05/14 19:17:35 korpela + * 1.0(Win/Mac) 1.1(Unix) Release Version + * + * Revision 2.11 1999/03/14 00:23:02 davea + * *** empty log message *** + * + * Revision 2.10 1999/03/11 21:46:58 korpela + * Fixed rounding error in st_to_ut(). + * + * Revision 2.9 1999/03/05 09:15:07 kyleg + * *** empty log message *** + * + * Revision 2.8 1999/02/18 19:36:49 korpela + * *** empty log message *** + * + * Revision 2.7 1999/02/13 23:54:44 kyleg + * *** empty log message *** + * + * Revision 2.6 1999/02/11 08:36:54 davea + * *** empty log message *** + * + * Revision 2.5 1998/11/17 21:47:02 korpela + * *** empty log message *** + * + * Revision 2.4 1998/11/05 21:25:21 davea + * replace floor() with (int) + * + * Revision 2.3 1998/11/05 02:00:06 kyleg + * *** empty log message *** + * + * Revision 2.2 1998/11/02 17:59:06 korpela + * *** empty log message *** + * + * Revision 2.1 1998/11/02 17:23:29 korpela + * .` + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.2 1998/10/27 00:58:56 korpela + * Bug fixes. + * + * Revision 1.1 1998/10/19 18:57:56 korpela + * Initial revision + * + * + */ diff --git a/splitter_old/hr_min_sec.h b/splitter_old/hr_min_sec.h new file mode 100644 index 0000000..4070b47 --- /dev/null +++ b/splitter_old/hr_min_sec.h @@ -0,0 +1,109 @@ +/* + * + * timecvt.c + * + * Time conversion routines. + * + * $Id: hr_min_sec.h,v 1.1.2.1 2006/01/13 00:24:53 jeffc Exp $ + * + */ + +char* hr_min_sec (double x) ; + + +/* + * $Log: hr_min_sec.h,v $ + * Revision 1.1.2.1 2006/01/13 00:24:53 jeffc + * *** empty log message *** + * + * Revision 1.1 2003/06/03 01:01:16 korpela + * + * First working splitter under CVS. + * + * Revision 4.4 2003/03/10 02:50:03 jeffc + * jeffc - t_strncpy() + * + * Revision 4.3 2003/01/22 20:51:58 korpela + * Changed all strcpy to strncpy. + * Changed all gets to fgets. + * + * Revision 4.2 2001/12/27 21:35:57 davea + * *** empty log message *** + * + * Revision 4.1 2001/09/10 00:25:17 davea + * *** empty log message *** + * + * Revision 4.0 2000/10/05 18:12:12 korpela + * Synchronized versions to 4.0 following release of 3.0 client + * + * Revision 3.8 2000/09/14 01:01:31 korpela + * *** empty log message *** + * + * Revision 3.7 2000/04/24 08:39:06 charlief + * eliminate compiler warning in hr_min_sec() function. + * + * Revision 3.6 2000/01/19 08:32:32 davea + * *** empty log message *** + * + * Revision 3.5 1999/10/19 08:07:24 davea + * *** empty log message *** + * + * Revision 3.4 1999/06/26 06:56:44 hiramc + * Hiram 99/06/25 23:59 moved the include out of the + * ifdef _WIN32 to define strcpy() for all compiles + * + * Revision 3.3 1999/06/22 09:40:36 charlief + * Reverse last change:restore jd_string() as it was before. + * Add new function short_jd_string(), which does not print + * Julian Date as a floating point value. + * + * Revision 3.1 1999/06/10 00:44:11 korpela + * *** empty log message *** + * + * Revision 3.0 1999/05/14 19:17:35 korpela + * 1.0(Win/Mac) 1.1(Unix) Release Version + * + * Revision 2.11 1999/03/14 00:23:02 davea + * *** empty log message *** + * + * Revision 2.10 1999/03/11 21:46:58 korpela + * Fixed rounding error in st_to_ut(). + * + * Revision 2.9 1999/03/05 09:15:07 kyleg + * *** empty log message *** + * + * Revision 2.8 1999/02/18 19:36:49 korpela + * *** empty log message *** + * + * Revision 2.7 1999/02/13 23:54:44 kyleg + * *** empty log message *** + * + * Revision 2.6 1999/02/11 08:36:54 davea + * *** empty log message *** + * + * Revision 2.5 1998/11/17 21:47:02 korpela + * *** empty log message *** + * + * Revision 2.4 1998/11/05 21:25:21 davea + * replace floor() with (int) + * + * Revision 2.3 1998/11/05 02:00:06 kyleg + * *** empty log message *** + * + * Revision 2.2 1998/11/02 17:59:06 korpela + * *** empty log message *** + * + * Revision 2.1 1998/11/02 17:23:29 korpela + * .` + * + * Revision 2.0 1998/10/30 22:00:04 korpela + * Conversion to C++ and merger with client source tree. + * + * Revision 1.2 1998/10/27 00:58:56 korpela + * Bug fixes. + * + * Revision 1.1 1998/10/19 18:57:56 korpela + * Initial revision + * + * + */ diff --git a/splitter_old/libfftw.a b/splitter_old/libfftw.a new file mode 100644 index 0000000000000000000000000000000000000000..dce9aec4bb1a561042dd930b0bcdbcba49756ffa GIT binary patch literal 248165 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