summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArtem Fedoskin <afedoskin3@gmail.com>2016-10-16 16:55:53 (GMT)
committerArtem Fedoskin <afedoskin3@gmail.com>2016-10-16 17:38:13 (GMT)
commit5686e05ec8054ede67445fa5f8476466b1f67b7f (patch)
treeb117a3feb07ecfde22a28e1b978bbd797a642c6a
parent504a286a820900e76a02664c1facc422cd829b38 (diff)
Added KStars Lite building script
-rw-r--r--.gitignore4
-rw-r--r--build_kstarslite/android_libs_src/AndroidToolchain.cmake226
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/CMakeLists.txt112
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/FindPthreads.cmake98
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/License.txt25
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/Makefile.in192
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/README109
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/README.MacOS75
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/README.win136
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/README_OLD.win83
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/buffers.c1377
-rwxr-xr-xbuild_kstarslite/android_libs_src/cfitsio/build.sh41
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/cfileio.c7333
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/cfitsio.pc.in11
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/cfortran.h2521
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/checksum.c508
-rwxr-xr-xbuild_kstarslite/android_libs_src/cfitsio/config.guess1530
-rwxr-xr-xbuild_kstarslite/android_libs_src/cfitsio/config.sub1779
-rwxr-xr-xbuild_kstarslite/android_libs_src/cfitsio/configure7495
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/configure.in588
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/cookbook.c571
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/cookbook.f772
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/docs/cfitsio.doc9680
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/docs/cfitsio.pdfbin0 -> 962650 bytes
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/docs/cfitsio.ps15462
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/docs/cfitsio.tex10800
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/docs/cfitsio.toc123
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/docs/cfortran.doc2088
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/docs/changes.txt4345
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/docs/fitsio.doc6622
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/docs/fitsio.pdfbin0 -> 691982 bytes
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/docs/fitsio.ps11388
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/docs/fitsio.tex7712
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/docs/fitsio.toc95
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/docs/fpackguide.pdfbin0 -> 478114 bytes
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/docs/quick.pdfbin0 -> 232878 bytes
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/docs/quick.ps5291
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/docs/quick.tex2157
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/docs/quick.toc25
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/drvrfile.c1003
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/drvrgsiftp.c522
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/drvrgsiftp.h21
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/drvrmem.c1301
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/drvrnet.c2741
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/drvrsmem.c973
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/drvrsmem.h179
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/editcol.c2493
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/edithdu.c883
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/eval.l545
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/eval.y5721
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/eval_defs.h163
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/eval_f.c2839
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/eval_l.c2487
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/eval_tab.h138
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/eval_y.c8365
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/f77.inc31
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/f77_wrap.h287
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/f77_wrap1.c346
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/f77_wrap2.c711
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/f77_wrap3.c860
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/f77_wrap4.c572
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/fits_hcompress.c1859
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/fits_hdecompress.c2614
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/fitscopy.c60
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/fitscore.c9459
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/fitsio.h2000
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/fitsio2.h1216
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/fpack.c411
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/fpack.h189
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/fpackutil.c2332
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/funpack.c168
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/getcol.c1053
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/getcolb.c2008
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/getcold.c1683
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/getcole.c1686
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/getcoli.c1908
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/getcolj.c3746
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/getcolk.c1901
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/getcoll.c621
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/getcols.c852
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/getcolsb.c1991
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/getcolui.c1914
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/getcoluj.c1915
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/getcoluk.c1923
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/getkey.c3471
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/group.c6463
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/group.h65
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/grparser.c1379
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/grparser.h185
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/histo.c2364
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/imcompress.c9751
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/imcopy.c233
-rwxr-xr-xbuild_kstarslite/android_libs_src/cfitsio/install-sh250
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/iraffits.c2093
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/iter_a.c147
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/iter_a.f224
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/iter_a.fit1111
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/iter_b.c114
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/iter_b.f193
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/iter_b.fitbin0 -> 408960 bytes
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/iter_c.c171
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/iter_c.f347
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/iter_image.c93
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/iter_var.c100
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/longnam.h (renamed from android_lib/include/longnam.h)0
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/makefile.bc588
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/makefile.vcc793
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/makepc.bat87
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/modkey.c1747
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/pliocomp.c331
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/putcol.c1929
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/putcolb.c1017
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/putcold.c1064
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/putcole.c1078
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/putcoli.c988
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/putcolj.c2000
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/putcolk.c1017
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/putcoll.c372
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/putcols.c304
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/putcolsb.c974
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/putcolu.c629
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/putcolui.c969
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/putcoluj.c977
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/putcoluk.c993
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/putkey.c3103
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/quantize.c3955
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/region.c1764
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/region.h82
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/ricecomp.c1353
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/sample.tpl121
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/scalnull.c229
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/simplerng.c461
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/simplerng.h27
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/smem.c77
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/speed.c511
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/swapproc.c247
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/testf77.f2488
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/testf77.out746
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/testf77.stdbin0 -> 66240 bytes
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/testprog.c2589
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/testprog.out797
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/testprog.std48
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/testprog.tpt12
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/vmsieee.c130
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/wcssub.c1043
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/wcsutil.c502
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/winDumpExts.mak191
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/windumpexts.c502
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/zlib/adler32.c167
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/zlib/crc32.c440
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/zlib/crc32.h441
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/zlib/deflate.c1832
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/zlib/deflate.h340
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/zlib/infback.c632
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/zlib/inffast.c340
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/zlib/inffast.h11
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/zlib/inffixed.h94
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/zlib/inflate.c1480
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/zlib/inflate.h122
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/zlib/inftrees.c330
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/zlib/inftrees.h62
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/zlib/trees.c1242
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/zlib/trees.h128
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/zlib/uncompr.c57
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/zlib/zcompress.c504
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/zlib/zconf.h426
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/zlib/zlib.h1613
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/zlib/zuncompress.c603
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/zlib/zutil.c316
-rw-r--r--build_kstarslite/android_libs_src/cfitsio/zlib/zutil.h272
-rw-r--r--build_kstarslite/android_libs_src/deployment-file.json.in15
-rw-r--r--build_kstarslite/android_libs_src/libnova/.gitignore53
-rw-r--r--build_kstarslite/android_libs_src/libnova/AUTHORS33
-rw-r--r--build_kstarslite/android_libs_src/libnova/CMakeLists.txt73
-rw-r--r--build_kstarslite/android_libs_src/libnova/COPYING481
-rw-r--r--build_kstarslite/android_libs_src/libnova/ChangeLog974
-rw-r--r--build_kstarslite/android_libs_src/libnova/INSTALL182
-rw-r--r--build_kstarslite/android_libs_src/libnova/Makefile.am7
-rw-r--r--build_kstarslite/android_libs_src/libnova/NEWS33
-rw-r--r--build_kstarslite/android_libs_src/libnova/README5
-rwxr-xr-xbuild_kstarslite/android_libs_src/libnova/autogen.sh6
-rw-r--r--build_kstarslite/android_libs_src/libnova/configure.ac118
-rw-r--r--build_kstarslite/android_libs_src/libnova/debian/changelog50
-rw-r--r--build_kstarslite/android_libs_src/libnova/debian/compat1
-rw-r--r--build_kstarslite/android_libs_src/libnova/debian/control29
-rw-r--r--build_kstarslite/android_libs_src/libnova/debian/copyright24
-rw-r--r--build_kstarslite/android_libs_src/libnova/debian/dirs2
-rw-r--r--build_kstarslite/android_libs_src/libnova/debian/docs2
-rw-r--r--build_kstarslite/android_libs_src/libnova/debian/libnova-dev.dirs4
-rw-r--r--build_kstarslite/android_libs_src/libnova/debian/libnova-dev.install4
-rw-r--r--build_kstarslite/android_libs_src/libnova/debian/libnova.dirs1
-rw-r--r--build_kstarslite/android_libs_src/libnova/debian/libnova.install2
-rw-r--r--build_kstarslite/android_libs_src/libnova/debian/libnova.postinst6
-rw-r--r--build_kstarslite/android_libs_src/libnova/debian/libnova.postrm6
-rw-r--r--build_kstarslite/android_libs_src/libnova/debian/rules103
-rw-r--r--build_kstarslite/android_libs_src/libnova/doc/Makefile.am10
-rw-r--r--build_kstarslite/android_libs_src/libnova/doc/doxyfile.in1162
-rw-r--r--build_kstarslite/android_libs_src/libnova/doc/libnova-logo.jpgbin0 -> 19965 bytes
-rw-r--r--build_kstarslite/android_libs_src/libnova/examples/CMakeLists.txt15
-rw-r--r--build_kstarslite/android_libs_src/libnova/examples/Makefile.am48
-rw-r--r--build_kstarslite/android_libs_src/libnova/examples/asteroid.c148
-rw-r--r--build_kstarslite/android_libs_src/libnova/examples/comet.c197
-rw-r--r--build_kstarslite/android_libs_src/libnova/examples/lunar.c121
-rw-r--r--build_kstarslite/android_libs_src/libnova/examples/mars.c100
-rw-r--r--build_kstarslite/android_libs_src/libnova/examples/sun.c81
-rw-r--r--build_kstarslite/android_libs_src/libnova/examples/transforms.c92
-rw-r--r--build_kstarslite/android_libs_src/libnova/git-version-gen153
-rw-r--r--build_kstarslite/android_libs_src/libnova/lntest/CMakeLists.txt5
-rw-r--r--build_kstarslite/android_libs_src/libnova/lntest/Makefile.am26
-rw-r--r--build_kstarslite/android_libs_src/libnova/lntest/libnova_config.c57
-rw-r--r--build_kstarslite/android_libs_src/libnova/lntest/test.c2094
-rw-r--r--build_kstarslite/android_libs_src/libnova/m4/Makefile.am1
-rw-r--r--build_kstarslite/android_libs_src/libnova/m4/ax_check_compile_flag.m472
-rw-r--r--build_kstarslite/android_libs_src/libnova/macros/Makefile.am16
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/CMakeLists.txt110
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/Makefile.am56
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/aberration.c365
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/airmass.c50
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/angular_separation.c84
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/apparent_position.c52
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/asteroid.c104
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/comet.c83
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/confdefs.h1
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/constellation.c1584
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/dynamical_time.c222
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/earth.c2822
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/elliptic_motion.c613
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/elp/Makefile.am44
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/elp/elp.h36
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/elp/elp1.c1026
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/elp/elp10.c14331
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/elp/elp11.c5236
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/elp/elp12.c6634
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/elp/elp13.c4387
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/elp/elp14.c836
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/elp/elp15.c1718
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/elp/elp16.c173
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/elp/elp17.c153
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/elp/elp18.c117
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/elp/elp19.c229
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/elp/elp2.c921
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/elp/elp20.c191
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/elp/elp21.c172
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/elp/elp22.c6
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/elp/elp23.c5
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/elp/elp24.c5
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/elp/elp25.c9
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/elp/elp26.c7
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/elp/elp27.c8
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/elp/elp28.c23
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/elp/elp29.c15
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/elp/elp3.c707
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/elp/elp30.c17
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/elp/elp31.c14
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/elp/elp32.c7
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/elp/elp33.c13
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/elp/elp34.c31
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/elp/elp35.c16
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/elp/elp36.c22
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/elp/elp4.c350
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/elp/elp5.c319
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/elp/elp6.c240
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/elp/elp7.c17
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/elp/elp8.c14
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/elp/elp9.c11
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/heliocentric_time.c55
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/hyperbolic_motion.c459
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/julian_day.c438
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/jupiter.c4055
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/libnova/Makefile.am39
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/libnova/aberration.h56
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/libnova/airmass.h45
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/libnova/angular_separation.h54
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/libnova/apparent_position.h47
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/libnova/asteroid.h57
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/libnova/comet.h55
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/libnova/confdefs.h0
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/libnova/constellation.h40
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/libnova/dynamical_time.h50
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/libnova/earth.h74
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/libnova/elliptic_motion.h205
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/libnova/heliocentric_time.h44
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/libnova/hyperbolic_motion.h150
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/libnova/julian_day.h129
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/libnova/jupiter.h122
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/libnova/libnova.h (renamed from android_lib/include/libnova.h)2
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/libnova/ln_types.h357
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/libnova/lunar.h174
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/libnova/mars.h115
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/libnova/mercury.h116
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/libnova/neptune.h115
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/libnova/nutation.h54
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/libnova/parabolic_motion.h150
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/libnova/parallax.h48
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/libnova/pluto.h115
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/libnova/precession.h66
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/libnova/proper_motion.h57
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/libnova/refraction.h47
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/libnova/rise_set.h121
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/libnova/saturn.h121
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/libnova/sidereal_time.h51
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/libnova/solar.h93
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/libnova/transform.h126
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/libnova/uranus.h116
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/libnova/utility.h275
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/libnova/venus.h115
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/libnova/vsop87.h58
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/lunar-priv.h28
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/lunar.c1674
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/mars.c6823
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/mercury.c7559
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/misc.c304
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/neptune.c2408
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/nutation.c305
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/parabolic_motion.c416
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/parallax.c86
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/pluto.c504
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/precession.c194
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/proper_motion.c69
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/refraction.c50
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/rise_set.c853
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/saturn.c6796
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/sidereal_time.c80
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/solar.c167
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/transform.c371
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/uranus.c5660
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/utility.c818
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/venus.c2132
-rw-r--r--build_kstarslite/android_libs_src/libnova/src/vsop87.c68
-rw-r--r--build_kstarslite/android_libs_src/libnova/tools/Makefile.am9
-rw-r--r--build_kstarslite/android_libs_src/libnova/tools/elp82.c232
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/!!!your_code_here!!!/Android.mk14
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/!!!your_code_here!!!/example.cpp13
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/Android.mk3
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/Application.mk17
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/build.bat1
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/build.sh2
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libcms/Android.mk15
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libcms/include/lcms2.h1889
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libcms/include/lcms2_plugin.h637
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libcms/src/cmscam02.c486
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libcms/src/cmscgats.c2773
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libcms/src/cmscnvrt.c1160
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libcms/src/cmserr.c661
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libcms/src/cmsgamma.c1275
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libcms/src/cmsgmt.c590
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libcms/src/cmshalf.c535
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libcms/src/cmsintrp.c1506
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libcms/src/cmsio0.c1901
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libcms/src/cmsio1.c1022
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libcms/src/cmslut.c1811
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libcms/src/cmsmd5.c317
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libcms/src/cmsmtrx.c176
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libcms/src/cmsnamed.c931
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libcms/src/cmsopt.c1917
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libcms/src/cmspack.c3352
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libcms/src/cmspcs.c940
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libcms/src/cmsplugin.c964
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libcms/src/cmsps2.c1597
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libcms/src/cmssamp.c547
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libcms/src/cmssm.c735
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libcms/src/cmstypes.c5564
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libcms/src/cmsvirt.c1203
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libcms/src/cmswtpnt.c351
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libcms/src/cmsxform.c1138
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libcms/src/lcms2_internal.h1038
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libcms/version.txt3
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/Android.mk16
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/cderror.h134
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/cdjpeg.c181
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/cdjpeg.h187
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/cjpeg.c664
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/ckconfig.c402
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/djpeg.c622
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/example.c433
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jaricom.c153
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jcapimin.c288
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jcapistd.c162
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jcarith.c944
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jccoefct.c454
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jccolor.c604
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jcdctmgr.c477
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jchuff.c1573
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jcinit.c84
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jcmainct.c297
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jcmarker.c719
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jcmaster.c856
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jcomapi.c106
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jconfig.h172
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jcparam.c675
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jcprepct.c358
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jcsample.c545
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jctrans.c385
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jdapimin.c399
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jdapistd.c276
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jdarith.c796
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jdatadst.c270
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jdatasrc.c275
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jdcoefct.c741
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jdcolor.c725
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jdct.h417
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jddctmgr.c384
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jdhuff.c1554
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jdinput.c662
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jdmainct.c513
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jdmarker.c1511
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jdmaster.c539
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jdmerge.c445
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jdpostct.c290
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jdsample.c358
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jdtrans.c140
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jerror.c253
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jerror.h304
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jfdctflt.c176
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jfdctfst.c232
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jfdctint.c4409
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jidctflt.c238
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jidctfst.c351
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jidctint.c5239
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jinclude.h91
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jmemansi.c167
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jmemmgr.c1119
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jmemname.c276
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jmemnobs.c109
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jmemsys.h198
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jmorecfg.h446
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jpegint.h426
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jpeglib.h1180
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jpegtran.c577
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jquant1.c857
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jquant2.c1311
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jutils.c227
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/jversion.h14
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/rdbmp.c480
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/rdcolmap.c253
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/rdgif.c38
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/rdjpgcom.c515
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/rdppm.c459
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/rdrle.c387
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/rdswitch.c367
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/rdtarga.c500
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/transupp.c1763
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/transupp.h219
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/wrbmp.c442
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/wrgif.c400
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/wrjpgcom.c599
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/wrppm.c269
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/wrrle.c305
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/src/wrtarga.c254
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libjpeg/version.txt3
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libraw/Android.mk31
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libraw/swab.c16
-rw-r--r--build_kstarslite/android_libs_src/libraw/Android/jni/libraw/swab.h12
-rw-r--r--build_kstarslite/android_libs_src/libraw/COPYRIGHT30
-rw-r--r--build_kstarslite/android_libs_src/libraw/Changelog.txt1725
-rw-r--r--build_kstarslite/android_libs_src/libraw/DEVELOPER-NOTES43
-rw-r--r--build_kstarslite/android_libs_src/libraw/INSTALL81
-rw-r--r--build_kstarslite/android_libs_src/libraw/LICENSE.CDDL340
-rw-r--r--build_kstarslite/android_libs_src/libraw/LICENSE.LGPL458
-rw-r--r--build_kstarslite/android_libs_src/libraw/LICENSE.LibRaw.pdfbin0 -> 246384 bytes
-rw-r--r--build_kstarslite/android_libs_src/libraw/LibRaw.pro15
-rw-r--r--build_kstarslite/android_libs_src/libraw/LibRaw.sln82
-rw-r--r--build_kstarslite/android_libs_src/libraw/Makefile-preprocess.msvc11
-rw-r--r--build_kstarslite/android_libs_src/libraw/Makefile.am100
-rw-r--r--build_kstarslite/android_libs_src/libraw/Makefile.devel177
-rw-r--r--build_kstarslite/android_libs_src/libraw/Makefile.dist155
-rw-r--r--build_kstarslite/android_libs_src/libraw/Makefile.mingw119
-rw-r--r--build_kstarslite/android_libs_src/libraw/Makefile.msvc137
-rw-r--r--build_kstarslite/android_libs_src/libraw/README28
-rw-r--r--build_kstarslite/android_libs_src/libraw/README.RawSpeed.txt54
-rw-r--r--build_kstarslite/android_libs_src/libraw/README.cmake9
-rw-r--r--build_kstarslite/android_libs_src/libraw/README.demosaic-packs46
-rw-r--r--build_kstarslite/android_libs_src/libraw/README.md52
-rw-r--r--build_kstarslite/android_libs_src/libraw/RawSpeed/rawspeed.cpucount-unix.patch15
-rw-r--r--build_kstarslite/android_libs_src/libraw/RawSpeed/rawspeed.qmake-pro-files.patch84
-rw-r--r--build_kstarslite/android_libs_src/libraw/RawSpeed/rawspeed.uncompressed-color-dng.patch13
-rw-r--r--build_kstarslite/android_libs_src/libraw/RawSpeed/rawspeed.win32-dll.patch186
-rw-r--r--build_kstarslite/android_libs_src/libraw/RawSpeed/rawspeed_xmldata.cpp4115
-rw-r--r--build_kstarslite/android_libs_src/libraw/bin/.keep_me2
-rw-r--r--build_kstarslite/android_libs_src/libraw/buildIncr.pl12
-rw-r--r--build_kstarslite/android_libs_src/libraw/clist2c.pl12
-rw-r--r--build_kstarslite/android_libs_src/libraw/clist2html.pl54
-rw-r--r--build_kstarslite/android_libs_src/libraw/configure.ac215
-rw-r--r--build_kstarslite/android_libs_src/libraw/dcraw/.gdbinit2
-rw-r--r--build_kstarslite/android_libs_src/libraw/dcraw/dcraw.1.html440
-rw-r--r--build_kstarslite/android_libs_src/libraw/dcraw/dcraw.c16941
-rw-r--r--build_kstarslite/android_libs_src/libraw/doc/API-C.html201
-rw-r--r--build_kstarslite/android_libs_src/libraw/doc/API-CXX.html985
-rw-r--r--build_kstarslite/android_libs_src/libraw/doc/API-datastruct.html1239
-rw-r--r--build_kstarslite/android_libs_src/libraw/doc/API-notes.html353
-rw-r--r--build_kstarslite/android_libs_src/libraw/doc/API-overview.html66
-rw-r--r--build_kstarslite/android_libs_src/libraw/doc/Install-LibRaw.html181
-rw-r--r--build_kstarslite/android_libs_src/libraw/doc/Samples-LibRaw.html249
-rw-r--r--build_kstarslite/android_libs_src/libraw/doc/Why-LibRaw.html117
-rw-r--r--build_kstarslite/android_libs_src/libraw/doc/index.html49
-rw-r--r--build_kstarslite/android_libs_src/libraw/export-dist.sh28
-rw-r--r--build_kstarslite/android_libs_src/libraw/internal/aahd_demosaic.cpp706
-rw-r--r--build_kstarslite/android_libs_src/libraw/internal/dcb_demosaicing.c710
-rw-r--r--build_kstarslite/android_libs_src/libraw/internal/dcraw_common.cpp15082
-rw-r--r--build_kstarslite/android_libs_src/libraw/internal/dcraw_fileio.cpp236
-rw-r--r--build_kstarslite/android_libs_src/libraw/internal/defines.h165
-rw-r--r--build_kstarslite/android_libs_src/libraw/internal/demosaic_packs.cpp99
-rw-r--r--build_kstarslite/android_libs_src/libraw/internal/dht_demosaic.cpp873
-rw-r--r--build_kstarslite/android_libs_src/libraw/internal/libraw_internal_funcs.h294
-rw-r--r--build_kstarslite/android_libs_src/libraw/internal/libraw_x3f.cpp1919
-rw-r--r--build_kstarslite/android_libs_src/libraw/internal/preprocess.pl99
-rw-r--r--build_kstarslite/android_libs_src/libraw/internal/var_defines.h216
-rw-r--r--build_kstarslite/android_libs_src/libraw/internal/wf_filtering.cpp1950
-rw-r--r--build_kstarslite/android_libs_src/libraw/lib/Makefile3
-rw-r--r--build_kstarslite/android_libs_src/libraw/libraw.pc.in11
-rw-r--r--[-rwxr-xr-x]build_kstarslite/android_libs_src/libraw/libraw/libraw.h (renamed from android_lib/include/libraw/libraw.h)0
-rw-r--r--build_kstarslite/android_libs_src/libraw/libraw/libraw_alloc.h (renamed from android_lib/include/libraw/libraw_alloc.h)0
-rw-r--r--build_kstarslite/android_libs_src/libraw/libraw/libraw_const.h (renamed from android_lib/include/libraw/libraw_const.h)0
-rw-r--r--build_kstarslite/android_libs_src/libraw/libraw/libraw_datastream.h (renamed from android_lib/include/libraw/libraw_datastream.h)0
-rw-r--r--build_kstarslite/android_libs_src/libraw/libraw/libraw_internal.h (renamed from android_lib/include/libraw/libraw_internal.h)0
-rw-r--r--build_kstarslite/android_libs_src/libraw/libraw/libraw_types.h (renamed from android_lib/include/libraw/libraw_types.h)0
-rw-r--r--build_kstarslite/android_libs_src/libraw/libraw/libraw_version.h (renamed from android_lib/include/libraw/libraw_version.h)0
-rw-r--r--build_kstarslite/android_libs_src/libraw/libraw_build.h3
-rw-r--r--build_kstarslite/android_libs_src/libraw/libraw_r.pc.in11
-rw-r--r--build_kstarslite/android_libs_src/libraw/m4/ax_openmp.m499
-rw-r--r--build_kstarslite/android_libs_src/libraw/mkdist.sh21
-rw-r--r--build_kstarslite/android_libs_src/libraw/object/.keep_me0
-rw-r--r--build_kstarslite/android_libs_src/libraw/rsxml2c.sh6
-rw-r--r--build_kstarslite/android_libs_src/libraw/samples/4channels.cpp179
-rw-r--r--build_kstarslite/android_libs_src/libraw/samples/Makefile2
-rw-r--r--build_kstarslite/android_libs_src/libraw/samples/README-samples.rus3
-rw-r--r--build_kstarslite/android_libs_src/libraw/samples/dcraw_emu.cpp544
-rw-r--r--build_kstarslite/android_libs_src/libraw/samples/dcraw_half.c83
-rw-r--r--build_kstarslite/android_libs_src/libraw/samples/half_mt.c173
-rw-r--r--build_kstarslite/android_libs_src/libraw/samples/half_mt_win32.c211
-rw-r--r--build_kstarslite/android_libs_src/libraw/samples/mem_image.cpp199
-rw-r--r--build_kstarslite/android_libs_src/libraw/samples/multirender_test.cpp111
-rw-r--r--build_kstarslite/android_libs_src/libraw/samples/postprocessing_benchmark.cpp222
-rw-r--r--build_kstarslite/android_libs_src/libraw/samples/raw-identify.cpp470
-rw-r--r--build_kstarslite/android_libs_src/libraw/samples/simple_dcraw.cpp173
-rw-r--r--build_kstarslite/android_libs_src/libraw/samples/unprocessed_raw.cpp290
-rw-r--r--build_kstarslite/android_libs_src/libraw/shlib-version.sh11
-rw-r--r--build_kstarslite/android_libs_src/libraw/src/Makefile2
-rw-r--r--build_kstarslite/android_libs_src/libraw/src/libraw_c_api.cpp349
-rw-r--r--build_kstarslite/android_libs_src/libraw/src/libraw_cxx.cpp5590
-rw-r--r--build_kstarslite/android_libs_src/libraw/src/libraw_datastream.cpp704
-rw-r--r--build_kstarslite/android_libs_src/libraw/version.sh16
-rw-r--r--build_kstarslite/android_libs_src/libraw/win32pre.cmd4
-rw-r--r--build_kstarslite/android_libs_src/specifydependencies.cmake45
-rw-r--r--build_kstarslite/build-config33
-rwxr-xr-xbuild_kstarslite/build-kstarslite.sh286
-rw-r--r--build_kstarslite/include/fitsio.h (renamed from android_lib/include/fitsio.h)0
-rw-r--r--build_kstarslite/include/libnova.h137
-rw-r--r--build_kstarslite/include/libnova/aberration.h54
-rw-r--r--build_kstarslite/include/libnova/airmass.h45
-rw-r--r--build_kstarslite/include/libnova/angular_separation.h52
-rw-r--r--build_kstarslite/include/libnova/apparent_position.h46
-rw-r--r--build_kstarslite/include/libnova/asteroid.h55
-rw-r--r--build_kstarslite/include/libnova/comet.h53
-rw-r--r--build_kstarslite/include/libnova/dynamical_time.h50
-rw-r--r--build_kstarslite/include/libnova/earth.h71
-rw-r--r--build_kstarslite/include/libnova/elliptic_motion.h186
-rw-r--r--build_kstarslite/include/libnova/heliocentric_time.h43
-rw-r--r--build_kstarslite/include/libnova/hyperbolic_motion.h133
-rw-r--r--build_kstarslite/include/libnova/julian_day.h131
-rw-r--r--build_kstarslite/include/libnova/jupiter.h118
-rw-r--r--build_kstarslite/include/libnova/libnova.h137
-rw-r--r--build_kstarslite/include/libnova/ln_types.h363
-rw-r--r--build_kstarslite/include/libnova/lunar.h115
-rw-r--r--build_kstarslite/include/libnova/mars.h111
-rw-r--r--build_kstarslite/include/libnova/mercury.h113
-rw-r--r--build_kstarslite/include/libnova/neptune.h111
-rw-r--r--build_kstarslite/include/libnova/nutation.h48
-rw-r--r--build_kstarslite/include/libnova/parabolic_motion.h133
-rw-r--r--build_kstarslite/include/libnova/parallax.h44
-rw-r--r--build_kstarslite/include/libnova/pluto.h111
-rw-r--r--build_kstarslite/include/libnova/precession.h63
-rw-r--r--build_kstarslite/include/libnova/proper_motion.h53
-rw-r--r--build_kstarslite/include/libnova/refraction.h46
-rw-r--r--build_kstarslite/include/libnova/rise_set.h114
-rw-r--r--build_kstarslite/include/libnova/saturn.h117
-rw-r--r--build_kstarslite/include/libnova/sidereal_time.h51
-rw-r--r--build_kstarslite/include/libnova/solar.h87
-rw-r--r--build_kstarslite/include/libnova/transform.h114
-rw-r--r--build_kstarslite/include/libnova/uranus.h112
-rw-r--r--build_kstarslite/include/libnova/utility.h258
-rw-r--r--build_kstarslite/include/libnova/venus.h111
-rw-r--r--build_kstarslite/include/libnova/vsop87.h57
-rwxr-xr-xbuild_kstarslite/include/libraw/libraw.h377
-rw-r--r--build_kstarslite/include/libraw/libraw_alloc.h99
-rw-r--r--build_kstarslite/include/libraw/libraw_const.h298
-rw-r--r--build_kstarslite/include/libraw/libraw_datastream.h297
-rw-r--r--build_kstarslite/include/libraw/libraw_internal.h230
-rw-r--r--build_kstarslite/include/libraw/libraw_types.h650
-rw-r--r--build_kstarslite/include/libraw/libraw_version.h62
-rw-r--r--build_kstarslite/include/longnam.h596
591 files changed, 506252 insertions, 1 deletions
diff --git a/.gitignore b/.gitignore
index 85ac1c7..b2dccb9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,4 +17,8 @@
# Vim swapfiles
.*.swp
+# KStars Lite Android libraries
+build_kstarslite/android_libs/*
+build_kstarslite/android_libs_src/libnova/build/*
+
CMakeLists.txt.user \ No newline at end of file
diff --git a/build_kstarslite/android_libs_src/AndroidToolchain.cmake b/build_kstarslite/android_libs_src/AndroidToolchain.cmake
new file mode 100644
index 0000000..7fe58af
--- /dev/null
+++ b/build_kstarslite/android_libs_src/AndroidToolchain.cmake
@@ -0,0 +1,226 @@
+
+#.rst:
+# AndroidToolchain
+# ----------------
+#
+# Enable easy compilation of cmake projects on Android.
+#
+# By using this android toolchain, the projects will be set up to compile the
+# specified project targeting an Android platform, depending on its input.
+# Furthermore, if desired, an APK can be directly generated by using the
+# `androiddeployqt <http://doc.qt.io/qt-5/deployment-android.html>`_ tool.
+#
+# .. note::
+#
+# This module requires CMake 3.1.
+#
+# Since 1.7.0.
+#
+# Usage
+# =====
+#
+# To use this file, you need to set the ``CMAKE_TOOLCHAIN_FILE`` to point to
+# ``AndroidToolchain.cmake`` on the command line::
+#
+# cmake -DCMAKE_TOOLCHAIN_FILE=/usr/share/ECM/toolchain/AndroidToolchain.cmake
+#
+# You will also need to provide the locations of the Android NDK and SDK. This
+# can be done on the commandline or with environment variables; in either case
+# the variable names are:
+#
+# ``ANDROID_NDK``
+# The NSK root path.
+# ``ANDROID_SDK_ROOT``
+# The SDK root path.
+#
+# Additional options are specified as cache variables (eg: on the command line):
+#
+# ``ANDROID_ARCHITECTURE``
+# The architecture to compile for. Default: ``arm``.
+# ``ANDROID_TOOLCHAIN``
+# The toolchain to use. See the ``toolchains`` directory of the NDK.
+# Default: ``arm-linux-androideabi``.
+# ``ANDROID_ABI``
+# The ABI to use. See the ``sources/cxx-stl/gnu-libstdc++/*/libs``
+# directories in the NDK. Default: ``armeabi-v7a``.
+# ``ANDROID_GCC_VERSION``
+# The GCC version to use. Default: ``4.9``.
+# ``ANDROID_API_LEVEL``
+# The `API level
+# <http://developer.android.com/guide/topics/manifest/uses-sdk-element.html>`_
+# to require. Default: ``14``.
+# ``ANDROID_SDK_BUILD_TOOLS_REVISION``
+# The build tools version to use. Default: ``21.1.1``.
+#
+# Deploying Qt Applications
+# =========================
+#
+# After building the application, you will need to generate an APK that can be
+# deployed to an Android device. This module integrates androiddeployqt support
+# to help with this for Qt-based projects. To enable this, set the
+# ``QTANDROID_EXPORTED_TARGET`` variable to the target you wish to export as an
+# APK, as well as ``ANDROID_APK_DIR`` to a directory containing some basic
+# information. This will create a ``create-apk-<target>`` target that will
+# generate the APK file. See the `Qt on Android deployment documentation
+# <http://doc.qt.io/qt-5/deployment-android.html>`_ for more information.
+#
+# For example, you could do::
+#
+# cmake \
+# -DCMAKE_TOOLCHAIN_FILE=/usr/share/ECM/toolchain/AndroidToolchain.cmake \
+# -DQTANDROID_EXPORTED_TARGET=myapp \
+# -DANDROID_APK_DIR=myapp-apk
+# make
+# make create-apk-myapp
+#
+# The APK would then be found in ``myapp_build_apk/bin`` in the build directory.
+#
+# The create-apk-myapp target will be able to take an ARGS parameter with further
+# arguments for androiddeployqt. For example, one can use::
+#
+# make create-apk-myapp ARGS="--install"
+#
+# To install the apk to test. To generate a signed apk, one can do it with the
+# following syntax::
+#
+# make create-apk-myapp ARGS="--sign ~/my.keystore alias_name"
+#
+# See Android documentation on how to create a keystore to use
+
+# =============================================================================
+# Copyright 2014 Aleix Pol i Gonzalez <aleixpol@kde.org>
+#
+# 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 copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. The name of the author may not be used to endorse or promote products
+# derived from this software without specific prior written permission.
+#
+# 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.
+
+cmake_minimum_required(VERSION "3.1")
+
+#input
+set(ANDROID_NDK "$ENV{ANDROID_NDK}" CACHE path "Android NDK path")
+set(ANDROID_SDK_ROOT "$ENV{ANDROID_SDK_ROOT}" CACHE path "Android SDK path")
+set(ANDROID_ARCHITECTURE "$ENV{ANDROID_ARCHITECTURE}" CACHE string "Used Architecture, related to the ABI and TOOLCHAIN")
+set(ANDROID_TOOLCHAIN "$ENV{ANDROID_TOOLCHAIN}" CACHE string "Used SDK")
+set(ANDROID_ABI "$ENV{ANDROID_ABI}" CACHE string "Used ABI")
+set(ANDROID_GCC_VERSION "4.9" CACHE string "Used GCC version" )
+set(ANDROID_API_LEVEL "$ENV{ANDROID_API_LEVEL}" CACHE string "Android API Level")
+set(ANDROID_SDK_BUILD_TOOLS_REVISION "21.1.1" CACHE string "Android API Level")
+
+set(_HOST "${CMAKE_HOST_SYSTEM_NAME}-${CMAKE_HOST_SYSTEM_PROCESSOR}")
+string(TOLOWER "${_HOST}" _HOST)
+
+get_filename_component(_CMAKE_ANDROID_DIR "${CMAKE_TOOLCHAIN_FILE}" PATH)
+
+cmake_policy(SET CMP0011 OLD)
+cmake_policy(SET CMP0017 OLD)
+
+set(CMAKE_SYSROOT
+ "${ANDROID_NDK}/platforms/android-${ANDROID_API_LEVEL}/arch-${ANDROID_ARCHITECTURE}")
+if(NOT EXISTS ${CMAKE_SYSROOT})
+ message(FATAL_ERROR "Couldn't find the Android NDK Root in ${CMAKE_SYSROOT}")
+endif()
+
+#actual code
+SET(CMAKE_SYSTEM_NAME Android)
+SET(CMAKE_SYSTEM_VERSION 1)
+
+if(${ANDROID_ARCHITECTURE} STREQUAL "x86" OR ${ANDROID_ARCHITECTURE} STREQUAL "x86_64")
+ set(ANDROID_TOOLCHAIN_ROOT "${ANDROID_NDK}/toolchains/${ANDROID_ARCHITECTURE}-${ANDROID_GCC_VERSION}/prebuilt/${_HOST}/bin")
+else()
+ set(ANDROID_TOOLCHAIN_ROOT "${ANDROID_NDK}/toolchains/${ANDROID_TOOLCHAIN}-${ANDROID_GCC_VERSION}/prebuilt/${_HOST}/bin")
+endif()
+set(ANDROID_LIBS_ROOT "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${ANDROID_GCC_VERSION}")
+
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM "${ANDROID_TOOLCHAIN_ROOT}")
+set(ANDROID_LIBRARIES_PATH
+ "${CMAKE_SYSROOT}/usr/lib")
+set(CMAKE_SYSTEM_LIBRARY_PATH
+ ${ANDROID_LIBRARIES_PATH}
+ "${ANDROID_LIBS_ROOT}/libs/${ANDROID_ABI}/"
+)
+set(CMAKE_FIND_LIBRARY_SUFFIXES ".so")
+set(CMAKE_FIND_LIBRARY_PREFIXES "lib")
+find_library(GNUSTL_SHARED gnustl_shared)
+if(NOT GNUSTL_SHARED)
+ message(FATAL_ERROR "you need gnustl_shared: ${CMAKE_SYSTEM_LIBRARY_PATH}")
+endif()
+include_directories(SYSTEM
+ "${ANDROID_LIBS_ROOT}/libs/${ANDROID_ABI}/include"
+ "${ANDROID_LIBS_ROOT}/include/"
+ "${CMAKE_SYSROOT}/usr/include"
+)
+
+# needed for Qt to define Q_OS_ANDROID
+add_definitions(-DANDROID)
+
+link_directories(${CMAKE_SYSTEM_LIBRARY_PATH})
+
+if(${ANDROID_ARCHITECTURE} STREQUAL "x86")
+ set(CMAKE_C_COMPILER "${ANDROID_TOOLCHAIN_ROOT}/i686-linux-android-gcc")
+ set(CMAKE_CXX_COMPILER "${ANDROID_TOOLCHAIN_ROOT}/i686-linux-android-g++")
+else()
+ set(CMAKE_C_COMPILER "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN}-gcc")
+ set(CMAKE_CXX_COMPILER "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN}-g++")
+endif()
+
+SET(CMAKE_FIND_ROOT_PATH ${ANDROID_NDK})
+SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH)
+SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH)
+
+set(CMAKE_EXE_LINKER_FLAGS "${GNUSTL_SHARED} -Wl,-rpath-link,${ANDROID_LIBRARIES_PATH} -llog -lz -lm -ldl -lc -lgcc" CACHE STRING "")
+set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}" CACHE STRING "")
+set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}" CACHE STRING "")
+
+#we want executables to be shared libraries, hooks will invoke the exported cmake function
+set(CMAKE_CXX_LINK_EXECUTABLE
+ "<CMAKE_CXX_COMPILER> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>"
+)
+
+if(NOT ${QTANDROID_EXPORTED_TARGET} STREQUAL "") # Build APK only when QTANDROID_EXPORTED_TARGET is set
+set(CREATEAPK_TARGET_NAME "create-apk-${QTANDROID_EXPORTED_TARGET}")
+# Need to ensure we only get in here once, as this file is included twice:
+# from CMakeDetermineSystem.cmake and from CMakeSystem.cmake generated within the
+# build directory.
+if(DEFINED QTANDROID_EXPORTED_TARGET AND NOT TARGET ${CREATEAPK_TARGET_NAME})
+ if(NOT EXISTS "${ANDROID_APK_DIR}/AndroidManifest.xml")
+ message(FATAL_ERROR "Define an apk dir to initialize from using -DANDROID_APK_DIR=<path>. The specified directory must contain the AndroidManifest.xml file.")
+ endif()
+
+ find_package(Qt5Core REQUIRED)
+
+ set(EXPORT_DIR "${CMAKE_BINARY_DIR}/${QTANDROID_EXPORTED_TARGET}_build_apk/")
+ set(EXECUTABLE_DESTINATION_PATH "${EXPORT_DIR}/libs/${ANDROID_ABI}/lib${QTANDROID_EXPORTED_TARGET}.so")
+ configure_file("${_CMAKE_ANDROID_DIR}/deployment-file.json.in" "${QTANDROID_EXPORTED_TARGET}-deployment.json.in")
+
+ add_custom_target(${CREATEAPK_TARGET_NAME}
+ COMMAND cmake -E echo "Generating $<TARGET_NAME:${QTANDROID_EXPORTED_TARGET}> with $<TARGET_FILE_DIR:Qt5::qmake>/androiddeployqt"
+ COMMAND cmake -E remove_directory "${EXPORT_DIR}"
+ COMMAND cmake -E copy_directory "${ANDROID_APK_DIR}" "${EXPORT_DIR}"
+ COMMAND cmake -E copy "$<TARGET_FILE:${QTANDROID_EXPORTED_TARGET}>" "${EXECUTABLE_DESTINATION_PATH}"
+ COMMAND cmake -DINPUT_FILE="${QTANDROID_EXPORTED_TARGET}-deployment.json.in" -DOUTPUT_FILE="${QTANDROID_EXPORTED_TARGET}-deployment.json" "-DTARGET_DIR=$<TARGET_FILE_DIR:${QTANDROID_EXPORTED_TARGET}>" "-DTARGET_NAME=${QTANDROID_EXPORTED_TARGET}" "-DEXPORT_DIR=${CMAKE_INSTALL_PREFIX}" -P ${_CMAKE_ANDROID_DIR}/specifydependencies.cmake
+ COMMAND $<TARGET_FILE_DIR:Qt5::qmake>/androiddeployqt --input "${QTANDROID_EXPORTED_TARGET}-deployment.json" --output "${EXPORT_DIR}" --deployment bundled "\\$(ARGS)"
+ )
+else()
+ message(STATUS "You can export a target by specifying -DQTANDROID_EXPORTED_TARGET=<targetname>")
+endif()
+endif(NOT ${QTANDROID_EXPORTED_TARGET} STREQUAL "")
diff --git a/build_kstarslite/android_libs_src/cfitsio/CMakeLists.txt b/build_kstarslite/android_libs_src/cfitsio/CMakeLists.txt
new file mode 100644
index 0000000..90af770
--- /dev/null
+++ b/build_kstarslite/android_libs_src/cfitsio/CMakeLists.txt
@@ -0,0 +1,112 @@
+PROJECT(CFITSIO)
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8.0)
+
+# Allow the developer to select if Dynamic or Static libraries are built
+OPTION (BUILD_SHARED_LIBS "Build Shared Libraries" ON)
+OPTION (USE_PTHREADS "Thread-safe build (using pthreads)" OFF)
+
+set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}")
+set (LIB_DESTINATION "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}")
+set (INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/include/")
+
+# Define project version
+SET(${PROJECT_NAME}_MAJOR_VERSION 3)
+SET(${PROJECT_NAME}_MINOR_VERSION 39)
+SET(${PROJECT_NAME}_VERSION ${${PROJECT_NAME}_MAJOR_VERSION}.${${PROJECT_NAME}_MINOR_VERSION})
+SET(LIB_NAME cfitsio)
+
+# Microsoft Visual Studio:
+IF(MSVC OR BORLAND)
+ # Define
+ ADD_DEFINITIONS(-D_CRT_SECURE_NO_DEPRECATE)
+ # Need an empty unistd.h in MSVC for flex-generated eval_l.c:
+ FILE(WRITE ${CMAKE_SOURCE_DIR}/unistd.h "")
+ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR})
+ENDIF()
+
+IF(BORLAND)
+ # Suppress spurious Borland compiler warnings about "Suspicious
+ # pointer arithmetic", "Possibly incorrect assignment", and
+ # "Comparing signed and unsigned values".
+ ADD_DEFINITIONS(-w-spa)
+ ADD_DEFINITIONS(-w-pia)
+ ADD_DEFINITIONS(-w-csu)
+ENDIF()
+
+#add_subdirectory (src)
+
+SET (LIB_TYPE STATIC)
+IF (BUILD_SHARED_LIBS)
+ SET (LIB_TYPE SHARED)
+ENDIF (BUILD_SHARED_LIBS)
+
+
+FILE(GLOB H_FILES "*.h")
+
+IF (USE_PTHREADS)
+ FIND_PACKAGE(pthreads REQUIRED)
+ INCLUDE_DIRECTORIES(${PTHREADS_INCLUDE_DIR})
+ ADD_DEFINITIONS(-D_REENTRANT)
+ENDIF()
+
+# Math library (not available in MSVC)
+IF (NOT MSVC)
+ FIND_LIBRARY(M_LIB m)
+ELSE()
+ SET(M_LIB "")
+ENDIF()
+
+SET(SRC_FILES
+ buffers.c cfileio.c checksum.c drvrfile.c drvrmem.c
+ drvrnet.c drvrsmem.c drvrgsiftp.c editcol.c edithdu.c eval_l.c
+ eval_y.c eval_f.c fitscore.c getcol.c getcolb.c getcold.c getcole.c
+ getcoli.c getcolj.c getcolk.c getcoll.c getcols.c getcolsb.c
+ getcoluk.c getcolui.c getcoluj.c getkey.c group.c grparser.c
+ histo.c iraffits.c
+ modkey.c putcol.c putcolb.c putcold.c putcole.c putcoli.c
+ putcolj.c putcolk.c putcoluk.c putcoll.c putcols.c putcolsb.c
+ putcolu.c putcolui.c putcoluj.c putkey.c region.c scalnull.c
+ swapproc.c wcssub.c wcsutil.c imcompress.c quantize.c ricecomp.c
+ pliocomp.c fits_hcompress.c fits_hdecompress.c zlib/zuncompress.c
+ zlib/zcompress.c zlib/adler32.c zlib/crc32.c zlib/inffast.c
+ zlib/inftrees.c zlib/trees.c zlib/zutil.c zlib/deflate.c
+ zlib/infback.c zlib/inflate.c zlib/uncompr.c simplerng.c
+ f77_wrap1.c f77_wrap2.c f77_wrap3.c f77_wrap4.c
+)
+
+ADD_LIBRARY(${LIB_NAME} ${LIB_TYPE} ${H_FILES} ${SRC_FILES})
+TARGET_LINK_LIBRARIES(${LIB_NAME} ${PTHREADS_LIBRARY} ${M_LIB})
+
+SET_TARGET_PROPERTIES(${LIB_NAME} PROPERTIES VERSION ${${PROJECT_NAME}_VERSION} SOVERSION ${${PROJECT_NAME}_MAJOR_VERSION})
+install(TARGETS ${LIB_NAME} DESTINATION ${LIB_DESTINATION})
+install(FILES ${H_FILES} DESTINATION ${INCLUDE_INSTALL_DIR} COMPONENT Devel)
+
+ENABLE_TESTING()
+
+ADD_EXECUTABLE(TestProg testprog.c)
+TARGET_LINK_LIBRARIES(TestProg ${LIB_NAME})
+ADD_TEST(TestProg TestProg)
+# Copy testprog.tpt to build directory to allow quick test
+# of ./TestProg (or .\Release\TestProg.exe in MSVC):
+FILE(COPY ${CMAKE_SOURCE_DIR}/testprog.tpt DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+
+ADD_EXECUTABLE(cookbook cookbook.c)
+TARGET_LINK_LIBRARIES(cookbook ${LIB_NAME})
+ADD_TEST(cookbook cookbook)
+
+ADD_EXECUTABLE(FPack fpack.c fpackutil.c)
+TARGET_LINK_LIBRARIES(FPack ${LIB_NAME})
+
+ADD_EXECUTABLE(Funpack funpack.c fpackutil.c)
+TARGET_LINK_LIBRARIES(Funpack ${LIB_NAME})
+
+ADD_EXECUTABLE(Fitscopy fitscopy.c)
+TARGET_LINK_LIBRARIES(Fitscopy ${LIB_NAME})
+
+# To expands the command line arguments in Windows, see:
+# http://msdn.microsoft.com/en-us/library/8bch7bkk.aspx
+if(MSVC)
+ set_target_properties(FPack Funpack PROPERTIES
+ LINK_FLAGS "setargv.obj"
+ )
+endif(MSVC)
diff --git a/build_kstarslite/android_libs_src/cfitsio/FindPthreads.cmake b/build_kstarslite/android_libs_src/cfitsio/FindPthreads.cmake
new file mode 100644
index 0000000..d9426d4
--- /dev/null
+++ b/build_kstarslite/android_libs_src/cfitsio/FindPthreads.cmake
@@ -0,0 +1,98 @@
+# - Find the Pthreads library
+# This module searches for the Pthreads library (including the
+# pthreads-win32 port).
+#
+# This module defines these variables:
+#
+# PTHREADS_FOUND
+# True if the Pthreads library was found
+# PTHREADS_LIBRARY
+# The location of the Pthreads library
+# PTHREADS_INCLUDE_DIR
+# The include path of the Pthreads library
+# PTHREADS_DEFINITIONS
+# Preprocessor definitions to define
+#
+# This module responds to the PTHREADS_EXCEPTION_SCHEME
+# variable on Win32 to allow the user to control the
+# library linked against. The Pthreads-win32 port
+# provides the ability to link against a version of the
+# library with exception handling. IT IS NOT RECOMMENDED
+# THAT YOU USE THIS because most POSIX thread implementations
+# do not support stack unwinding.
+#
+# PTHREADS_EXCEPTION_SCHEME
+# C = no exceptions (default)
+# (NOTE: This is the default scheme on most POSIX thread
+# implementations and what you should probably be using)
+# CE = C++ Exception Handling
+# SE = Structure Exception Handling (MSVC only)
+#
+
+#
+# Define a default exception scheme to link against
+# and validate user choice.
+#
+IF(NOT DEFINED PTHREADS_EXCEPTION_SCHEME)
+ # Assign default if needed
+ SET(PTHREADS_EXCEPTION_SCHEME "C")
+ELSE(NOT DEFINED PTHREADS_EXCEPTION_SCHEME)
+ # Validate
+ IF(NOT PTHREADS_EXCEPTION_SCHEME STREQUAL "C" AND
+ NOT PTHREADS_EXCEPTION_SCHEME STREQUAL "CE" AND
+ NOT PTHREADS_EXCEPTION_SCHEME STREQUAL "SE")
+
+ MESSAGE(FATAL_ERROR "See documentation for FindPthreads.cmake, only C, CE, and SE modes are allowed")
+
+ ENDIF(NOT PTHREADS_EXCEPTION_SCHEME STREQUAL "C" AND
+ NOT PTHREADS_EXCEPTION_SCHEME STREQUAL "CE" AND
+ NOT PTHREADS_EXCEPTION_SCHEME STREQUAL "SE")
+
+ IF(NOT MSVC AND PTHREADS_EXCEPTION_SCHEME STREQUAL "SE")
+ MESSAGE(FATAL_ERROR "Structured Exception Handling is only allowed for MSVC")
+ ENDIF(NOT MSVC AND PTHREADS_EXCEPTION_SCHEME STREQUAL "SE")
+
+ENDIF(NOT DEFINED PTHREADS_EXCEPTION_SCHEME)
+
+#
+# Find the header file
+#
+FIND_PATH(PTHREADS_INCLUDE_DIR pthread.h)
+
+#
+# Find the library
+#
+SET(names)
+IF(MSVC)
+ SET(names
+ pthreadV${PTHREADS_EXCEPTION_SCHEME}2
+ pthread
+ )
+ELSEIF(MINGW)
+ SET(names
+ pthreadG${PTHREADS_EXCEPTION_SCHEME}2
+ pthread
+ )
+ELSE(MSVC) # Unix / Cygwin / Apple
+ SET(names pthread)
+ENDIF(MSVC)
+
+FIND_LIBRARY(PTHREADS_LIBRARY ${names}
+ DOC "The Portable Threads Library")
+
+IF(PTHREADS_INCLUDE_DIR AND PTHREADS_LIBRARY)
+ SET(PTHREADS_FOUND true)
+ SET(PTHREADS_DEFINITIONS -DHAVE_PTHREAD_H)
+ SET(PTHREADS_INCLUDE_DIRS ${PTHREADS_INCLUDE_DIR})
+ SET(PTHREADS_LIBRARIES ${PTHREADS_LIBRARY})
+ENDIF(PTHREADS_INCLUDE_DIR AND PTHREADS_LIBRARY)
+
+IF(PTHREADS_FOUND)
+ IF(NOT PTHREADS_FIND_QUIETLY)
+ MESSAGE(STATUS "Found Pthreads: ${PTHREADS_LIBRARY}")
+ ENDIF(NOT PTHREADS_FIND_QUIETLY)
+ELSE(PTHREADS_FOUND)
+ IF(PTHREADS_FIND_REQUIRED)
+ MESSAGE(FATAL_ERROR "Could not find the Pthreads Library")
+ ENDIF(PTHREADS_FIND_REQUIRED)
+ENDIF(PTHREADS_FOUND)
diff --git a/build_kstarslite/android_libs_src/cfitsio/License.txt b/build_kstarslite/android_libs_src/cfitsio/License.txt
new file mode 100644
index 0000000..2f5f48d
--- /dev/null
+++ b/build_kstarslite/android_libs_src/cfitsio/License.txt
@@ -0,0 +1,25 @@
+Copyright (Unpublished--all rights reserved under the copyright laws of
+the United States), U.S. Government as represented by the Administrator
+of the National Aeronautics and Space Administration. No copyright is
+claimed in the United States under Title 17, U.S. Code.
+
+Permission to freely use, copy, modify, and distribute this software
+and its documentation without fee is hereby granted, provided that this
+copyright notice and disclaimer of warranty appears in all copies.
+
+DISCLAIMER:
+
+THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND,
+EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO,
+ANY WARRANTY THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY
+IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE, AND FREEDOM FROM INFRINGEMENT, AND ANY WARRANTY THAT THE
+DOCUMENTATION WILL CONFORM TO THE SOFTWARE, OR ANY WARRANTY THAT THE
+SOFTWARE WILL BE ERROR FREE. IN NO EVENT SHALL NASA BE LIABLE FOR ANY
+DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT, INDIRECT, SPECIAL OR
+CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM, OR IN ANY WAY
+CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY,
+CONTRACT, TORT , OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY
+PERSONS OR PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED
+FROM, OR AROSE OUT OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR
+SERVICES PROVIDED HEREUNDER.
diff --git a/build_kstarslite/android_libs_src/cfitsio/Makefile.in b/build_kstarslite/android_libs_src/cfitsio/Makefile.in
new file mode 100644
index 0000000..9fbb925
--- /dev/null
+++ b/build_kstarslite/android_libs_src/cfitsio/Makefile.in
@@ -0,0 +1,192 @@
+#
+# Makefile for cfitsio library:
+#
+# Oct-96 : original version by
+#
+# JDD/WDP
+# NASA GSFC
+# Oct 1996
+#
+# 25-Jan-01 : removed conditional drvrsmem.c compilation because this
+# is now handled within the source file itself.
+# 09-Mar-98 : modified to conditionally compile drvrsmem.c. Also
+# changes to target all (deleted clean), added DEFS, LIBS, added
+# DEFS to .c.o, added SOURCES_SHMEM and MY_SHMEM, expanded getcol*
+# and putcol* in SOURCES, modified OBJECTS, mv changed to /bin/mv
+# (to bypass aliasing), cp changed to /bin/cp, add smem and
+# testprog targets. See also changes and comments in configure.in
+
+
+# Default library name:
+PACKAGE = cfitsio
+
+# CFITSIO version numbers:
+CFITSIO_MAJOR = @CFITSIO_MAJOR@
+CFITSIO_MINOR = @CFITSIO_MINOR@
+CFITSIO_SONAME = @CFITSIO_SONAME@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+DESTDIR =
+CFITSIO_BIN = ${DESTDIR}@bindir@
+CFITSIO_LIB = ${DESTDIR}@libdir@
+CFITSIO_INCLUDE = ${DESTDIR}@includedir@
+INSTALL_DIRS = @INSTALL_ROOT@ ${CFITSIO_INCLUDE} ${CFITSIO_LIB} ${CFITSIO_LIB}/pkgconfig
+
+
+SHELL = /bin/sh
+ARCHIVE = @ARCHIVE@
+RANLIB = @RANLIB@
+CC = @CC@
+CFLAGS = @CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+SSE_FLAGS = @SSE_FLAGS@
+FC = @FC@
+LDFLAGS = @LDFLAGS@
+LDFLAGS_BIN = @LDFLAGS_BIN@
+DEFS = @DEFS@
+LIBS = @LIBS@
+FLEX = flex
+BISON = bison
+
+SHLIB_LD = @SHLIB_LD@
+SHLIB_SUFFIX = @SHLIB_SUFFIX@
+CFITSIO_SHLIB = @CFITSIO_SHLIB@
+CFITSIO_SHLIB_SONAME = @CFITSIO_SHLIB_SONAME@
+
+
+CORE_SOURCES = buffers.c cfileio.c checksum.c drvrfile.c drvrmem.c \
+ drvrnet.c drvrsmem.c drvrgsiftp.c editcol.c edithdu.c eval_l.c \
+ eval_y.c eval_f.c fitscore.c getcol.c getcolb.c getcold.c getcole.c \
+ getcoli.c getcolj.c getcolk.c getcoll.c getcols.c getcolsb.c \
+ getcoluk.c getcolui.c getcoluj.c getkey.c group.c grparser.c \
+ histo.c iraffits.c \
+ modkey.c putcol.c putcolb.c putcold.c putcole.c putcoli.c \
+ putcolj.c putcolk.c putcoluk.c putcoll.c putcols.c putcolsb.c \
+ putcolu.c putcolui.c putcoluj.c putkey.c region.c scalnull.c \
+ swapproc.c wcssub.c wcsutil.c imcompress.c quantize.c ricecomp.c \
+ pliocomp.c fits_hcompress.c fits_hdecompress.c \
+ simplerng.c
+
+ZLIB_SOURCES = zlib/adler32.c zlib/crc32.c zlib/deflate.c zlib/infback.c \
+ zlib/inffast.c zlib/inflate.c zlib/inftrees.c zlib/trees.c \
+ zlib/uncompr.c zlib/zcompress.c zlib/zuncompress.c zlib/zutil.c
+
+SOURCES = ${CORE_SOURCES} ${ZLIB_SOURCES} @F77_WRAPPERS@
+
+OBJECTS = ${SOURCES:.c=.o}
+
+CORE_OBJECTS = ${CORE_SOURCES:.c=.o} ${ZLIB_SOURCES:.c=.o}
+
+
+FITSIO_SRC = f77_wrap1.c f77_wrap2.c f77_wrap3.c f77_wrap4.c
+
+# ============ description of all targets =============
+# - <<-- ignore error code
+
+all:
+ @if [ "x${FC}" = x ]; then \
+ ${MAKE} all-nofitsio; \
+ else \
+ ${MAKE} stand_alone; \
+ fi
+
+all-nofitsio:
+ ${MAKE} stand_alone "FITSIO_SRC="
+
+stand_alone: lib${PACKAGE}.a
+
+lib${PACKAGE}.a: ${OBJECTS}
+ ${ARCHIVE} $@ ${OBJECTS}; \
+ ${RANLIB} $@;
+
+shared: lib${PACKAGE}${SHLIB_SUFFIX}
+
+lib${PACKAGE}${SHLIB_SUFFIX}: ${OBJECTS}
+ ${SHLIB_LD} ${LDFLAGS} -o ${CFITSIO_SHLIB} ${OBJECTS} -lm ${LIBS}
+ @if [ "x${CFITSIO_SHLIB_SONAME}" != x ]; then \
+ ln -sf ${CFITSIO_SHLIB} ${CFITSIO_SHLIB_SONAME}; \
+ ln -sf ${CFITSIO_SHLIB_SONAME} $@; \
+ fi
+
+install: lib${PACKAGE}.a ${INSTALL_DIRS}
+ /bin/cp -a lib${PACKAGE}* ${CFITSIO_LIB}
+ /bin/cp fitsio.h fitsio2.h longnam.h drvrsmem.h ${CFITSIO_INCLUDE}
+ /bin/cp cfitsio.pc ${CFITSIO_LIB}/pkgconfig
+ @for task in ${FPACK_UTILS} ${UTILS}; do \
+ if [ -f $$task ]; then \
+ if [ ! -d ${CFITSIO_BIN} ]; then mkdir -p ${CFITSIO_BIN}; fi; \
+ echo "/bin/cp $$task ${CFITSIO_BIN}"; \
+ /bin/cp $$task ${CFITSIO_BIN}; \
+ fi; \
+ done
+
+.c.o:
+ ${CC} -c -o ${<D}/${@F} ${CFLAGS} ${CPPFLAGS} ${DEFS} $<
+
+UTILS = cookbook fitscopy imcopy smem speed testprog
+
+FPACK_UTILS = fpack funpack
+
+utils: ${FPACK_UTILS} ${UTILS}
+
+swapproc.o: swapproc.c
+ ${CC} -c ${CFLAGS} ${CPPFLAGS} ${SSE_FLAGS} ${DEFS} $<
+
+smem: smem.o lib${PACKAGE}.a ${OBJECTS}
+ ${CC} ${LDFLAGS_BIN} ${DEFS} -o $@ ${@}.o -L. -l${PACKAGE} -lm
+
+testprog: testprog.o lib${PACKAGE}.a ${OBJECTS}
+ ${CC} ${LDFLAGS_BIN} ${DEFS} -o $@ ${@}.o -L. -l${PACKAGE} -lm ${LIBS}
+
+fpack: fpack.o fpackutil.o lib${PACKAGE}.a ${OBJECTS}
+ ${CC} ${LDFLAGS_BIN} ${DEFS} -o $@ ${@}.o fpackutil.o -L. -l${PACKAGE} -lm ${LIBS}
+
+funpack: funpack.o fpackutil.o lib${PACKAGE}.a ${OBJECTS}
+ ${CC} ${LDFLAGS_BIN} ${DEFS} -o $@ ${@}.o fpackutil.o -L. -l${PACKAGE} -lm ${LIBS}
+
+fitscopy: fitscopy.o lib${PACKAGE}.a ${OBJECTS}
+ ${CC} ${LDFLAGS_BIN} ${DEFS} -o $@ ${@}.o -L. -l${PACKAGE} -lm ${LIBS}
+
+speed: speed.o lib${PACKAGE}.a ${OBJECTS}
+ ${CC} ${LDFLAGS_BIN} ${DEFS} -o $@ ${@}.o -L. -l${PACKAGE} -lm ${LIBS}
+
+imcopy: imcopy.o lib${PACKAGE}.a ${OBJECTS}
+ ${CC} ${LDFLAGS_BIN} ${DEFS} -o $@ ${@}.o -L. -l${PACKAGE} -lm ${LIBS}
+
+cookbook: cookbook.o lib${PACKAGE}.a ${OBJECTS}
+ ${CC} ${LDFLAGS_BIN} ${DEFS} -o $@ ${@}.o -L. -l${PACKAGE} -lm ${LIBS}
+
+eval: # Rebuild eval_* files from flex/bison source
+ ${FLEX} -t eval.l > eval_l.c1
+ # Note workaround for yyfree=fffree conflict
+ /bin/sed -e 's/yy/ff/g' -e 's/YY/FF/g' eval_l.c1 -e 's/fffree/yyfffree/g' > eval_l.c
+ /bin/rm -f eval_l.c1
+ ${BISON} -d -v -y eval.y
+ /bin/sed -e 's/yy/ff/g' -e 's/YY/FF/g' y.tab.c > eval_y.c
+ /bin/sed -e 's/yy/ff/g' -e 's/YY/FF/g' y.tab.h > eval_tab.h
+ /bin/rm -f y.tab.c y.tab.h
+
+clean:
+ - /bin/rm -f *.o zlib/*.o lib${PACKAGE}* y.output so_locations \
+ ${UTILS} ${FPACK_UTILS} testprog.fit
+
+distclean: clean
+ - /bin/rm -f Makefile cfitsio.pc config.log config.status configure.lineno
+
+# Make target which outputs the list of the .o contained in the cfitsio lib
+# usefull to build a single big shared library containing Tcl/Tk and other
+# extensions. used for the Tcl Plugin.
+
+cfitsioLibObjs:
+ @echo ${CORE_OBJECTS}
+
+cfitsioLibSrcs:
+ @echo ${SOURCES}
+
+# This target actually builds the objects needed for the lib in the above
+# case
+objs: ${CORE_OBJECTS}
+
+${INSTALL_DIRS}:
+ @if [ ! -d $@ ]; then mkdir -p $@; fi
diff --git a/build_kstarslite/android_libs_src/cfitsio/README b/build_kstarslite/android_libs_src/cfitsio/README
new file mode 100644
index 0000000..a6682ce
--- /dev/null
+++ b/build_kstarslite/android_libs_src/cfitsio/README
@@ -0,0 +1,109 @@
+ CFITSIO Interface Library
+
+CFITSIO is a library of ANSI C routines for reading and writing FITS
+format data files. A set of Fortran-callable wrapper routines are also
+included for the convenience of Fortran programmers. This README file
+gives a brief summary of how to build and test CFITSIO, but the CFITSIO
+User's Guide, found in the files cfitsio.doc (plain text), cfitsio.tex
+(LaTeX source file), cfitsio.ps, or cfitsio.pdf should be
+referenced for the latest and most complete information.
+
+BUILDING CFITSIO
+----------------
+
+The CFITSIO code is contained in about 40 *.c source files and several *.h
+header files. CFITSIO should compile and run on most Unix platforms without
+modification, except that Cray supercomputers computers are currently not
+supported. The CFITSIO library is built on Unix systems by typing:
+
+ > ./configure [--prefix=/target/installation/path]
+ > make (or 'make shared')
+ > make install (this step is optional)
+
+at the operating system prompt. The configure command customizes the
+Makefile for the particular system, then the `make' command compiles the
+source files and builds the library. Type `./configure' and not simply
+`configure' to ensure that the configure script in the current directory
+is run and not some other system-wide configure script. The optional
+'prefix' argument to configure gives the path to the directory where
+the CFITSIO library and include files should be installed via the later
+'make install' command. For example,
+
+ > ./configure --prefix=/usr1/local
+
+will cause the 'make install' command to copy the CFITSIO libcfitsio file
+to /usr1/local/lib and the necessary include files to /usr1/local/include
+(assuming of course that the process has permission to write to these
+directories).
+
+All the available configure options can be seen by entering the command
+
+ > ./configure --help
+
+On VAX/VMS and ALPHA/VMS systems the make.com command file may be used
+to build the cfitsio.olb object library using the default G-floating
+point option for double variables. The make\_dfloat.com and make\_ieee.com
+files may be used instead to build the library with the other floating
+point options.
+
+A precompiled DLL version of CFITSIO is available for IBM-PC users of
+the Borland or Microsoft Visual C++ compilers in the files
+cfitsiodll_xxxx_borland.zip and cfitsiodll_xxxx_vcc.zip, where 'xxxx'
+represents the current release number. These zip archives also
+contains other files and instructions on how to use the CFITSIO DLL
+library. The CFITSIO library may also be built from the source code
+using the makefile.bc or makefile.vcc files. Finally, the makepc.bat
+file gives an example of building CFITSIO with the Borland C++ v4.5
+compiler using simpler DOS commands.
+
+Instructions for building CFITSIO on Mac OS can be found in
+the README.MacOS file.
+
+TESTING CFITSIO
+---------------
+
+The CFITSIO library should be tested by building and running
+the testprog.c program that is included with the release.
+On Unix systems, type:
+-
+ % make testprog
+ % testprog > testprog.lis
+ % diff testprog.lis testprog.out
+ % cmp testprog.fit testprog.std
+-
+ On VMS systems,
+(assuming cc is the name of the C compiler command), type:
+-
+ $ cc testprog.c
+ $ link testprog, cfitsio/lib
+ $ run testprog
+-
+The testprog program should produce a FITS file called `testprog.fit'
+that is identical to the testprog.std FITS file included in this
+release. The diagnostic messages (which were piped to the file
+testprog.lis in the Unix example) should be identical to the listing
+contained in the file testprog.out. The 'diff' and 'cmp' commands
+shown above should not report any differences in the files.
+
+USING CFITSIO
+-------------
+
+The CFITSIO User's Guide, contained in the files cfitsio.doc (plain
+text file) and cfitsio.ps (postscript file), provides detailed
+documentation about how to build and use the CFITSIO library.
+It contains a description of every user-callable routine in the
+CFITSIO interface.
+
+The cookbook.c file provides some sample routines for performing common
+operations on various types of FITS files. Programmers are urged to
+examine these routines for recommended programming practices when using
+CFITSIO. Users are free to copy or modify these routines for their own
+purposes.
+
+Any problem reports or suggestions for
+improvements are welcome and should be sent to the HEASARC
+help desk.
+
+-------------------------------------------------------------------------
+William D. Pence
+HEASARC, NASA/GSFC
diff --git a/build_kstarslite/android_libs_src/cfitsio/README.MacOS b/build_kstarslite/android_libs_src/cfitsio/README.MacOS
new file mode 100644
index 0000000..c17928f
--- /dev/null
+++ b/build_kstarslite/android_libs_src/cfitsio/README.MacOS
@@ -0,0 +1,75 @@
+By default, the CFITSIO library will be a "Universal Binary" (i.e.
+32- and 64-bit compatible) under Mac OS X when built in the standard
+way, i.e.
+
+- tar xzf cfitsio3370.tar.gz (or whatever version this is)
+- cd cfitsio/
+
+- ./configure
+- make
+- make install
+
+---------------------------------------------------------------------
+To install CFITSIO using MacPorts:
+---------------------------------------------------------------------
+
+If you have MacPorts installed, you may install CFITSIO simply with
+the command
+
+ $ sudo port install cfitsio +universal
+
+For more information, please visit:
+
+http://macports.org
+https://trac.macports.org/browser/trunk/dports/science/cfitsio/Portfile
+
+---------------------------------------------------------------------
+To install CFITSIO using Homebrew:
+---------------------------------------------------------------------
+
+If you have Homebrew installed, you may install CFITSIO simply with
+the command
+
+ $ brew install cfitsio
+
+For more information, please visit:
+
+http://brew.sh
+http://brewformulas.org/Cfitsio
+
+---------------------------------------------------------------------
+To build CFITSIO using the XCode GUI:
+---------------------------------------------------------------------
+
+- tar xzf cfitsio3370.tar.gz (or whatever version this is)
+- cd cfitsio/
+
+- Start Xcode and open cfitsio.xcodeproj/project.pbxproj,
+ or just "open" the file from a terminal command line,
+
+ $ open cfitsio.xcodeproj/project.pbxproj
+
+ and this will start up XCode for you.
+
+- Press the Build (or "Play") button in the upper left
+ corner of the GUI.
+
+---------------------------------------------------------------------
+---------------------------------------------------------------------
+
+Below, are the old (and now obsolete) instructions for building CFITSIO
+on classic Mac OS-9 or earlier versions:
+
+1. Un binhex and unstuff cfitsio_mac.sit.hqx
+2. put CFitsioPPC.mcp in the cfitsio directory.
+2. Load CFitsioPPC.mcp into CodeWarrior Pro 5 and make.
+ This builds the cfitsio library for PPC. There are also targets for both
+ the test program and the speed test program.
+
+To use the MacOS port you can add Cfitsio PPC.lib to your Codewarrior Pro 5
+project. Note that this only has been tested for the PPC. It probably
+won't work on 68k macs. Also note that the fortran bindings aren't
+included. I haven't worked with the codewarrior f2c plugin so I don't know
+how these would work. If one is interested, please write and I can look
+into this.
+
diff --git a/build_kstarslite/android_libs_src/cfitsio/README.win b/build_kstarslite/android_libs_src/cfitsio/README.win
new file mode 100644
index 0000000..934ecb6
--- /dev/null
+++ b/build_kstarslite/android_libs_src/cfitsio/README.win
@@ -0,0 +1,136 @@
+Instructions on building and using CFITSIO on Windows platforms
+for C programmers using Microsoft Visual Studio or Borland C++.
+
+These instructions for building the CFITSIO library under Windows use the
+CMake build system that is available from http://www.cmake.org.
+
+===============================================================================
+
+1. Build the CFITSIO dll library
+
+This step will create the cfitsio.dll, and cfitsio.lib files. If you have
+downloaded the CFITSIO DLL .zip file that already contains the pre-built
+versions of these files, then SKIP THIS STEP.
+
+ a. If CMAKE is not already installed on your machine, download it from
+ http://www.cmake.org. It is recommended that you choose the
+ "Add CMake to the system PATH for current user" option during the
+ installation setup process for convenience when running CMake later on.
+
+ b. Unzip the CFITSIO .zip file (e.g. cfit3360.zip) that was obtained from
+ the CFITSIO Web site (http://heasarc.gsfc.nasa.gov/fitsio/). This will
+ create a new \cfitsio subdirectory that contains the source code and
+ documentation files. It should also contain a CMakeLists.txt file that
+ will be used during the CMake build process.
+
+ c. Open the Visual Studio Command Prompt window, likely using a
+ desktop icon with this same name, (or the equivalent Borland command window)
+ and CD (change directory) into the parent directory that is one level
+ above the directory containing the CFITSIO source files that was created
+ in the previous step.
+
+ d. Create a new "cfitsio.build" subdirectory, and CD into it with the
+ following commands:
+
+ mkdir cfitsio.build
+ cd cfitsio.build
+
+ When using Visual Studio, all the files that are generated during the
+ CMake process will be created in or under this subdirectory.
+
+ e. Decide which CMake Generator you will want to use in the following step.
+ This depends on which C/C++ compiler you are using and will likely have
+ a name such as:
+
+ "Visual Studio 10"
+ "Visual Studio 10 Win64" (for 64-bit builds)
+ "Visual Studio 11"
+ "Visual Studio 11 Win64" (for 64-bit builds)
+ "Visual Studio 12"
+ "Visual Studio 12 Win64" (for 64-bit builds)
+ "Borland Makefiles"
+ "NMake Makefiles"
+
+ You can see a list of all the available CMake Generators by executing
+ the command
+
+ cmake.exe /?
+
+ Note that these names are case-sensitive and must be entered in the
+ following step exactly as displayed.
+
+ f. Execute the following commands to build the CFITSIO library:
+
+ cmake.exe -G "<cmake generator>" ..\cfitsio
+ cmake.exe --build . --config Release
+
+ Where the string <cmake generator> is the string that was selected
+ in step e. Note that the "..\cfitsio" argument in the first command
+ gives the path to the directory that contains the CFITSIO source files
+ and the CMakeLists.txt file. The "." argument in the second command
+ (following --build) tells CMake to build the files in the current
+ directory (i.e., the cfitsio.build directory).
+
+ If this process completes successfully, you should find the CFITSIO
+ library files that were created in the "cfitsio.build\Release"
+ subdirectory. To verify that CFITSIO is working correctly, execute the
+ testprog.exe file (in that Release directory). This should generate
+ a long stream of diagnostic messages ending with the line "Status = 0:
+ OK - no error".
+
+ g. Other CMake options.
+
+ CMake has many other build options that may be useful in some
+ situations. Refer to the CMake documentation for more
+ information.
+
+ For example, one can build a 'debug' version of the CFITSIO library
+ by executing the command "cmake.exe --build ." instead of the 2nd
+ command listed above in section f.
+
+ One can also make a thread safe version of CFITSIO using the
+ pthread library with the following procedure:
+
+ a. Download the precompiled files from the pthread-win32 project
+ (http://sourceware.org/pthreads-win32/). Put the files for your
+ specific platform (.h, .lib, .dll) into a folder 'pthread',
+ parallel to the cfitsio source folder.
+
+ b. For the compilation of cfitsio follow the cmake steps, but use
+ this change as a replacement for the commands in step f:
+
+ cmake.exe -G "<cmake generator>" ..\cfitsio -DUSE_PTHREADS=1
+ -DCMAKE_INCLUDE_PATH=..\pthread -DCMAKE_LIBRARY_PATH=..\pthread
+
+ cmake.exe --build . --config Release
+
+ You may need to adapt the paths for the source directory and
+ the pthread library.
+
+============================================================================
+
+2. Using CFITSIO when compiling and linking application programs
+
+First, depending on your particular programming environment, it may be
+necessary to copy the cfitsio.lib and cfitsio.dll files into another
+directory where your compiler expects to find them. Or equivalently, you
+may need to specify the directory path to the location of the CFITSIO
+library files when creating a project that uses them. You may also need to
+copy the fitsio.h and longnam.h include files from the \cfitsio source file
+directory to a standard 'include' directory on your system.
+
+When using the Visual Studio command line window, application programs can
+be compiled and linked with CFITSIO using the following command:
+
+ cl /MD your_program.c cfitsio.lib
+
+The /MD command line switch must be specified to force the compiler/linker
+to use the appropriate runtime library. If this switch is omitted, then
+the fits_report_error function in CFITSIO will likely crash.
+
+When building programs in the Visual Studio graphical environment, one can
+force the equivalent of the /MD switch by selecting 'Settings...' under the
+'Project' menu, then click on the C/C++ tab and select the 'Code Generator'
+category. Then under 'User Run-time Library' select 'Multithreaded DLL'.
+
+===============================================================================
diff --git a/build_kstarslite/android_libs_src/cfitsio/README_OLD.win b/build_kstarslite/android_libs_src/cfitsio/README_OLD.win
new file mode 100644
index 0000000..ca79c40
--- /dev/null
+++ b/build_kstarslite/android_libs_src/cfitsio/README_OLD.win
@@ -0,0 +1,83 @@
+===============================================================================
+===============================================================================
+= NOTE: This is the old version of the README.win32 file that was distributed
+= with CFITSIO up until version 3.35 in 2013. These instruction may still work
+= with more recent versions of CFITSIO, however, users are strongly urged to
+= use the CMake procedures that are now documented in the new README.win32 file.
+===============================================================================
+===============================================================================
+
+ Instructions on using CFITSIO on Windows platforms for C programmers
+
+These instructions use a simple DOS-style command window. It is also possible
+to build and use CFITSIO within a GUI programming environment such as Visual
+Studio, but this is not supported here.
+
+===============================================================================
+1. Build the CFITSIO dll library
+
+This step will create the cfitsio.def, cfitsio.dll, and cfitsio.lib files.
+(If you downloaded the CFITSIO .zip file that contains the pre-built binary
+.dll file, then SKIP THIS STEP).
+
+ A. With Microsoft Visual C++:
+
+ 1. Open a DOS command window and execute the vcvars32.bat file that
+ is distributed with older versions of Visual C++, or simply open
+ the Visual C++ command window (e.g., when using Visual Studio 2010).
+
+ 2. Unpack the CFITSIO source files (cfitxxxx.zip) into a new empty directory
+
+ 3. In the DOS command window, cd to that directory and enter the
+ following commands:
+
+ nmake winDumpExts.mak
+ nmake makefile.vcc
+ (ignore the compiler warning messages)
+
+ B: With Borland C++:
+
+ First, follow the instructions provided by Borland to set up
+ the proper environment variables and configure files for the compiler.
+
+ Unpack the cfitsio.zip source file distribution into a suitable directory.
+
+ In a DOS command window, cd to that directory and then execute the
+ makepc.bat batch file on the command line to build the CFITSIO library,
+ and the testprog and cookbook sample programs.
+
+===============================================================================
+2. Test the CFITSIO library with Visual C++
+
+ Compile and link the testprog.c test program. When using Visual Studio,
+ the command is:
+
+ cl /MD testprog.c cfitsio.lib
+
+
+ This will create the testprog.exe executable program. Running this
+ program should print out a long series of diagnostic messages
+ that should end with "Status = 0; OK - no error"
+
+===============================================================================
+3. Compile and link an application program that calls CFITSIO routines
+ with Visual C++
+
+ Include the fitsio.h and longnam.h header files in the C source code.
+
+ Link the program with the cfitsio.lib file:
+
+ cl /MD your_program.c cfitsio.lib
+
+
+ NOTE: The /MD command line switch must be specified on the cl
+ command line to force the compiler/linker to use the
+ appropriete runtime library. If this switch is omitted, then
+ the fits_report_error function in CFITSIO will likely crash.
+
+ When building programs in the Visual Studio environment, one
+ can force the equivalent of the /MD switch by selecting
+ 'Settings...' under the 'Project' menu, then click on the C/C++
+ tab and select the 'Code Generator' category. Then under 'User
+ Run-time Library' select 'Multithreaded DLL'.
+
diff --git a/build_kstarslite/android_libs_src/cfitsio/buffers.c b/build_kstarslite/android_libs_src/cfitsio/buffers.c
new file mode 100644
index 0000000..ca1c334
--- /dev/null
+++ b/build_kstarslite/android_libs_src/cfitsio/buffers.c
@@ -0,0 +1,1377 @@
+/* This file, buffers.c, contains the core set of FITSIO routines */
+/* that use or manage the internal set of IO buffers. */
+
+/* The FITSIO software was written by William Pence at the High Energy */
+/* Astrophysic Science Archive Research Center (HEASARC) at the NASA */
+/* Goddard Space Flight Center. */
+
+#include <string.h>
+#include <stdlib.h>
+#include "fitsio2.h"
+
+/*--------------------------------------------------------------------------*/
+int ffmbyt(fitsfile *fptr, /* I - FITS file pointer */
+ LONGLONG bytepos, /* I - byte position in file to move to */
+ int err_mode, /* I - 1=ignore error, 0 = return error */
+ int *status) /* IO - error status */
+{
+/*
+ Move to the input byte location in the file. When writing to a file, a move
+ may sometimes be made to a position beyond the current EOF. The err_mode
+ parameter determines whether such conditions should be returned as an error
+ or simply ignored.
+*/
+ long record;
+
+ if (*status > 0)
+ return(*status);
+
+ if (bytepos < 0)
+ return(*status = NEG_FILE_POS);
+
+ if (fptr->HDUposition != (fptr->Fptr)->curhdu)
+ ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
+
+ record = (long) (bytepos / IOBUFLEN); /* zero-indexed record number */
+
+ /* if this is not the current record, then load it */
+ if ( ((fptr->Fptr)->curbuf < 0) ||
+ (record != (fptr->Fptr)->bufrecnum[(fptr->Fptr)->curbuf]))
+ ffldrc(fptr, record, err_mode, status);
+
+ if (*status <= 0)
+ (fptr->Fptr)->bytepos = bytepos; /* save new file position */
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffpbyt(fitsfile *fptr, /* I - FITS file pointer */
+ LONGLONG nbytes, /* I - number of bytes to write */
+ void *buffer, /* I - buffer containing the bytes to write */
+ int *status) /* IO - error status */
+/*
+ put (write) the buffer of bytes to the output FITS file, starting at
+ the current file position. Write large blocks of data directly to disk;
+ write smaller segments to intermediate IO buffers to improve efficiency.
+*/
+{
+ int ii, nbuff;
+ LONGLONG filepos;
+ long recstart, recend;
+ long ntodo, bufpos, nspace, nwrite;
+ char *cptr;
+
+ if (*status > 0)
+ return(*status);
+
+ if (fptr->HDUposition != (fptr->Fptr)->curhdu)
+ ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
+
+ if (nbytes > LONG_MAX) {
+ ffpmsg("Number of bytes to write is greater than LONG_MAX (ffpbyt).");
+ *status = WRITE_ERROR;
+ return(*status);
+ }
+
+ ntodo = (long) nbytes;
+ cptr = (char *)buffer;
+
+ if ((fptr->Fptr)->curbuf < 0) /* no current data buffer for this file */
+ { /* so reload the last one that was used */
+ ffldrc(fptr, (long) (((fptr->Fptr)->bytepos) / IOBUFLEN), REPORT_EOF, status);
+ }
+
+ if (nbytes >= MINDIRECT)
+ {
+ /* write large blocks of data directly to disk instead of via buffers */
+ /* first, fill up the current IO buffer before flushing it to disk */
+
+ nbuff = (fptr->Fptr)->curbuf; /* current IO buffer number */
+ filepos = (fptr->Fptr)->bytepos; /* save the write starting position */
+ recstart = (fptr->Fptr)->bufrecnum[nbuff]; /* starting record */
+ recend = (long) ((filepos + nbytes - 1) / IOBUFLEN); /* ending record */
+
+ /* bufpos is the starting position within the IO buffer */
+ bufpos = (long) (filepos - ((LONGLONG)recstart * IOBUFLEN));
+ nspace = IOBUFLEN - bufpos; /* amount of space left in the buffer */
+
+ if (nspace)
+ { /* fill up the IO buffer */
+ memcpy((fptr->Fptr)->iobuffer + (nbuff * IOBUFLEN) + bufpos, cptr, nspace);
+ ntodo -= nspace; /* decrement remaining number of bytes */
+ cptr += nspace; /* increment user buffer pointer */
+ filepos += nspace; /* increment file position pointer */
+ (fptr->Fptr)->dirty[nbuff] = TRUE; /* mark record as having been modified */
+ }
+
+ for (ii = 0; ii < NIOBUF; ii++) /* flush any affected buffers to disk */
+ {
+ if ((fptr->Fptr)->bufrecnum[ii] >= recstart
+ && (fptr->Fptr)->bufrecnum[ii] <= recend )
+ {
+ if ((fptr->Fptr)->dirty[ii]) /* flush modified buffer to disk */
+ ffbfwt(fptr->Fptr, ii, status);
+
+ (fptr->Fptr)->bufrecnum[ii] = -1; /* disassociate buffer from the file */
+ }
+ }
+
+ /* move to the correct write position */
+ if ((fptr->Fptr)->io_pos != filepos)
+ ffseek(fptr->Fptr, filepos);
+
+ nwrite = ((ntodo - 1) / IOBUFLEN) * IOBUFLEN; /* don't write last buff */
+
+ ffwrite(fptr->Fptr, nwrite, cptr, status); /* write the data */
+ ntodo -= nwrite; /* decrement remaining number of bytes */
+ cptr += nwrite; /* increment user buffer pointer */
+ (fptr->Fptr)->io_pos = filepos + nwrite; /* update the file position */
+
+ if ((fptr->Fptr)->io_pos >= (fptr->Fptr)->filesize) /* at the EOF? */
+ {
+ (fptr->Fptr)->filesize = (fptr->Fptr)->io_pos; /* increment file size */
+
+ /* initialize the current buffer with the correct fill value */
+ if ((fptr->Fptr)->hdutype == ASCII_TBL)
+ memset((fptr->Fptr)->iobuffer + (nbuff * IOBUFLEN), 32, IOBUFLEN); /* blank fill */
+ else
+ memset((fptr->Fptr)->iobuffer + (nbuff * IOBUFLEN), 0, IOBUFLEN); /* zero fill */
+ }
+ else
+ {
+ /* read next record */
+ ffread(fptr->Fptr, IOBUFLEN, (fptr->Fptr)->iobuffer + (nbuff * IOBUFLEN), status);
+ (fptr->Fptr)->io_pos += IOBUFLEN;
+ }
+
+ /* copy remaining bytes from user buffer into current IO buffer */
+ memcpy((fptr->Fptr)->iobuffer + (nbuff * IOBUFLEN), cptr, ntodo);
+ (fptr->Fptr)->dirty[nbuff] = TRUE; /* mark record as having been modified */
+ (fptr->Fptr)->bufrecnum[nbuff] = recend; /* record number */
+
+ (fptr->Fptr)->logfilesize = maxvalue((fptr->Fptr)->logfilesize,
+ (LONGLONG)(recend + 1) * IOBUFLEN);
+ (fptr->Fptr)->bytepos = filepos + nwrite + ntodo;
+ }
+ else
+ {
+ /* bufpos is the starting position in IO buffer */
+ bufpos = (long) ((fptr->Fptr)->bytepos - ((LONGLONG)(fptr->Fptr)->bufrecnum[(fptr->Fptr)->curbuf] *
+ IOBUFLEN));
+ nspace = IOBUFLEN - bufpos; /* amount of space left in the buffer */
+
+ while (ntodo)
+ {
+ nwrite = minvalue(ntodo, nspace);
+
+ /* copy bytes from user's buffer to the IO buffer */
+ memcpy((fptr->Fptr)->iobuffer + ((fptr->Fptr)->curbuf * IOBUFLEN) + bufpos, cptr, nwrite);
+ ntodo -= nwrite; /* decrement remaining number of bytes */
+ cptr += nwrite;
+ (fptr->Fptr)->bytepos += nwrite; /* increment file position pointer */
+ (fptr->Fptr)->dirty[(fptr->Fptr)->curbuf] = TRUE; /* mark record as modified */
+
+ if (ntodo) /* load next record into a buffer */
+ {
+ ffldrc(fptr, (long) ((fptr->Fptr)->bytepos / IOBUFLEN), IGNORE_EOF, status);
+ bufpos = 0;
+ nspace = IOBUFLEN;
+ }
+ }
+ }
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffpbytoff(fitsfile *fptr, /* I - FITS file pointer */
+ long gsize, /* I - size of each group of bytes */
+ long ngroups, /* I - number of groups to write */
+ long offset, /* I - size of gap between groups */
+ void *buffer, /* I - buffer to be written */
+ int *status) /* IO - error status */
+/*
+ put (write) the buffer of bytes to the output FITS file, with an offset
+ between each group of bytes. This function combines ffmbyt and ffpbyt
+ for increased efficiency.
+*/
+{
+ int bcurrent;
+ long ii, bufpos, nspace, nwrite, record;
+ char *cptr, *ioptr;
+
+ if (*status > 0)
+ return(*status);
+
+ if (fptr->HDUposition != (fptr->Fptr)->curhdu)
+ ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
+
+ if ((fptr->Fptr)->curbuf < 0) /* no current data buffer for this file */
+ { /* so reload the last one that was used */
+ ffldrc(fptr, (long) (((fptr->Fptr)->bytepos) / IOBUFLEN), REPORT_EOF, status);
+ }
+
+ cptr = (char *)buffer;
+ bcurrent = (fptr->Fptr)->curbuf; /* number of the current IO buffer */
+ record = (fptr->Fptr)->bufrecnum[bcurrent]; /* zero-indexed record number */
+ bufpos = (long) ((fptr->Fptr)->bytepos - ((LONGLONG)record * IOBUFLEN)); /* start pos */
+ nspace = IOBUFLEN - bufpos; /* amount of space left in buffer */
+ ioptr = (fptr->Fptr)->iobuffer + (bcurrent * IOBUFLEN) + bufpos;
+
+ for (ii = 1; ii < ngroups; ii++) /* write all but the last group */
+ {
+ /* copy bytes from user's buffer to the IO buffer */
+ nwrite = minvalue(gsize, nspace);
+ memcpy(ioptr, cptr, nwrite);
+ cptr += nwrite; /* increment buffer pointer */
+
+ if (nwrite < gsize) /* entire group did not fit */
+ {
+ (fptr->Fptr)->dirty[bcurrent] = TRUE; /* mark record as having been modified */
+ record++;
+ ffldrc(fptr, record, IGNORE_EOF, status); /* load next record */
+ bcurrent = (fptr->Fptr)->curbuf;
+ ioptr = (fptr->Fptr)->iobuffer + (bcurrent * IOBUFLEN);
+
+ nwrite = gsize - nwrite;
+ memcpy(ioptr, cptr, nwrite);
+ cptr += nwrite; /* increment buffer pointer */
+ ioptr += (offset + nwrite); /* increment IO buffer pointer */
+ nspace = IOBUFLEN - offset - nwrite; /* amount of space left */
+ }
+ else
+ {
+ ioptr += (offset + nwrite); /* increment IO bufer pointer */
+ nspace -= (offset + nwrite);
+ }
+
+ if (nspace <= 0) /* beyond current record? */
+ {
+ (fptr->Fptr)->dirty[bcurrent] = TRUE;
+ record += ((IOBUFLEN - nspace) / IOBUFLEN); /* new record number */
+ ffldrc(fptr, record, IGNORE_EOF, status);
+ bcurrent = (fptr->Fptr)->curbuf;
+
+ bufpos = (-nspace) % IOBUFLEN; /* starting buffer pos */
+ nspace = IOBUFLEN - bufpos;
+ ioptr = (fptr->Fptr)->iobuffer + (bcurrent * IOBUFLEN) + bufpos;
+ }
+ }
+
+ /* now write the last group */
+ nwrite = minvalue(gsize, nspace);
+ memcpy(ioptr, cptr, nwrite);
+ cptr += nwrite; /* increment buffer pointer */
+
+ if (nwrite < gsize) /* entire group did not fit */
+ {
+ (fptr->Fptr)->dirty[bcurrent] = TRUE; /* mark record as having been modified */
+ record++;
+ ffldrc(fptr, record, IGNORE_EOF, status); /* load next record */
+ bcurrent = (fptr->Fptr)->curbuf;
+ ioptr = (fptr->Fptr)->iobuffer + (bcurrent * IOBUFLEN);
+
+ nwrite = gsize - nwrite;
+ memcpy(ioptr, cptr, nwrite);
+ }
+
+ (fptr->Fptr)->dirty[bcurrent] = TRUE; /* mark record as having been modified */
+ (fptr->Fptr)->bytepos = (fptr->Fptr)->bytepos + (ngroups * gsize)
+ + (ngroups - 1) * offset;
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffgbyt(fitsfile *fptr, /* I - FITS file pointer */
+ LONGLONG nbytes, /* I - number of bytes to read */
+ void *buffer, /* O - buffer to read into */
+ int *status) /* IO - error status */
+/*
+ get (read) the requested number of bytes from the file, starting at
+ the current file position. Read large blocks of data directly from disk;
+ read smaller segments via intermediate IO buffers to improve efficiency.
+*/
+{
+ int ii;
+ LONGLONG filepos;
+ long recstart, recend, ntodo, bufpos, nspace, nread;
+ char *cptr;
+
+ if (*status > 0)
+ return(*status);
+
+ if (fptr->HDUposition != (fptr->Fptr)->curhdu)
+ ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
+ cptr = (char *)buffer;
+
+ if (nbytes >= MINDIRECT)
+ {
+ /* read large blocks of data directly from disk instead of via buffers */
+ filepos = (fptr->Fptr)->bytepos; /* save the read starting position */
+
+/* note that in this case, ffmbyt has not been called, and so */
+/* bufrecnum[(fptr->Fptr)->curbuf] does not point to the intended */
+/* output buffer */
+
+ recstart = (long) (filepos / IOBUFLEN); /* starting record */
+ recend = (long) ((filepos + nbytes - 1) / IOBUFLEN); /* ending record */
+
+ for (ii = 0; ii < NIOBUF; ii++) /* flush any affected buffers to disk */
+ {
+ if ((fptr->Fptr)->dirty[ii] &&
+ (fptr->Fptr)->bufrecnum[ii] >= recstart && (fptr->Fptr)->bufrecnum[ii] <= recend)
+ {
+ ffbfwt(fptr->Fptr, ii, status); /* flush modified buffer to disk */
+ }
+ }
+
+ /* move to the correct read position */
+ if ((fptr->Fptr)->io_pos != filepos)
+ ffseek(fptr->Fptr, filepos);
+
+ ffread(fptr->Fptr, (long) nbytes, cptr, status); /* read the data */
+ (fptr->Fptr)->io_pos = filepos + nbytes; /* update the file position */
+ }
+ else
+ {
+ /* read small chucks of data using the IO buffers for efficiency */
+
+ if ((fptr->Fptr)->curbuf < 0) /* no current data buffer for this file */
+ { /* so reload the last one that was used */
+ ffldrc(fptr, (long) (((fptr->Fptr)->bytepos) / IOBUFLEN), REPORT_EOF, status);
+ }
+
+ /* bufpos is the starting position in IO buffer */
+ bufpos = (long) ((fptr->Fptr)->bytepos - ((LONGLONG)(fptr->Fptr)->bufrecnum[(fptr->Fptr)->curbuf] *
+ IOBUFLEN));
+ nspace = IOBUFLEN - bufpos; /* amount of space left in the buffer */
+
+ ntodo = (long) nbytes;
+ while (ntodo)
+ {
+ nread = minvalue(ntodo, nspace);
+
+ /* copy bytes from IO buffer to user's buffer */
+ memcpy(cptr, (fptr->Fptr)->iobuffer + ((fptr->Fptr)->curbuf * IOBUFLEN) + bufpos, nread);
+ ntodo -= nread; /* decrement remaining number of bytes */
+ cptr += nread;
+ (fptr->Fptr)->bytepos += nread; /* increment file position pointer */
+
+ if (ntodo) /* load next record into a buffer */
+ {
+ ffldrc(fptr, (long) ((fptr->Fptr)->bytepos / IOBUFLEN), REPORT_EOF, status);
+ bufpos = 0;
+ nspace = IOBUFLEN;
+ }
+ }
+ }
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffgbytoff(fitsfile *fptr, /* I - FITS file pointer */
+ long gsize, /* I - size of each group of bytes */
+ long ngroups, /* I - number of groups to read */
+ long offset, /* I - size of gap between groups (may be < 0) */
+ void *buffer, /* I - buffer to be filled */
+ int *status) /* IO - error status */
+/*
+ get (read) the requested number of bytes from the file, starting at
+ the current file position. This function combines ffmbyt and ffgbyt
+ for increased efficiency.
+*/
+{
+ int bcurrent;
+ long ii, bufpos, nspace, nread, record;
+ char *cptr, *ioptr;
+
+ if (*status > 0)
+ return(*status);
+
+ if (fptr->HDUposition != (fptr->Fptr)->curhdu)
+ ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
+
+ if ((fptr->Fptr)->curbuf < 0) /* no current data buffer for this file */
+ { /* so reload the last one that was used */
+ ffldrc(fptr, (long) (((fptr->Fptr)->bytepos) / IOBUFLEN), REPORT_EOF, status);
+ }
+
+ cptr = (char *)buffer;
+ bcurrent = (fptr->Fptr)->curbuf; /* number of the current IO buffer */
+ record = (fptr->Fptr)->bufrecnum[bcurrent]; /* zero-indexed record number */
+ bufpos = (long) ((fptr->Fptr)->bytepos - ((LONGLONG)record * IOBUFLEN)); /* start pos */
+ nspace = IOBUFLEN - bufpos; /* amount of space left in buffer */
+ ioptr = (fptr->Fptr)->iobuffer + (bcurrent * IOBUFLEN) + bufpos;
+
+ for (ii = 1; ii < ngroups; ii++) /* read all but the last group */
+ {
+ /* copy bytes from IO buffer to the user's buffer */
+ nread = minvalue(gsize, nspace);
+ memcpy(cptr, ioptr, nread);
+ cptr += nread; /* increment buffer pointer */
+
+ if (nread < gsize) /* entire group did not fit */
+ {
+ record++;
+ ffldrc(fptr, record, REPORT_EOF, status); /* load next record */
+ bcurrent = (fptr->Fptr)->curbuf;
+ ioptr = (fptr->Fptr)->iobuffer + (bcurrent * IOBUFLEN);
+
+ nread = gsize - nread;
+ memcpy(cptr, ioptr, nread);
+ cptr += nread; /* increment buffer pointer */
+ ioptr += (offset + nread); /* increment IO buffer pointer */
+ nspace = IOBUFLEN - offset - nread; /* amount of space left */
+ }
+ else
+ {
+ ioptr += (offset + nread); /* increment IO bufer pointer */
+ nspace -= (offset + nread);
+ }
+
+ if (nspace <= 0 || nspace > IOBUFLEN) /* beyond current record? */
+ {
+ if (nspace <= 0)
+ {
+ record += ((IOBUFLEN - nspace) / IOBUFLEN); /* new record number */
+ bufpos = (-nspace) % IOBUFLEN; /* starting buffer pos */
+ }
+ else
+ {
+ record -= ((nspace - 1 ) / IOBUFLEN); /* new record number */
+ bufpos = IOBUFLEN - (nspace % IOBUFLEN); /* starting buffer pos */
+ }
+
+ ffldrc(fptr, record, REPORT_EOF, status);
+ bcurrent = (fptr->Fptr)->curbuf;
+
+ nspace = IOBUFLEN - bufpos;
+ ioptr = (fptr->Fptr)->iobuffer + (bcurrent * IOBUFLEN) + bufpos;
+ }
+ }
+
+ /* now read the last group */
+ nread = minvalue(gsize, nspace);
+ memcpy(cptr, ioptr, nread);
+ cptr += nread; /* increment buffer pointer */
+
+ if (nread < gsize) /* entire group did not fit */
+ {
+ record++;
+ ffldrc(fptr, record, REPORT_EOF, status); /* load next record */
+ bcurrent = (fptr->Fptr)->curbuf;
+ ioptr = (fptr->Fptr)->iobuffer + (bcurrent * IOBUFLEN);
+
+ nread = gsize - nread;
+ memcpy(cptr, ioptr, nread);
+ }
+
+ (fptr->Fptr)->bytepos = (fptr->Fptr)->bytepos + (ngroups * gsize)
+ + (ngroups - 1) * offset;
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffldrc(fitsfile *fptr, /* I - FITS file pointer */
+ long record, /* I - record number to be loaded */
+ int err_mode, /* I - 1=ignore EOF, 0 = return EOF error */
+ int *status) /* IO - error status */
+{
+/*
+ low-level routine to load a specified record from a file into
+ a physical buffer, if it is not already loaded. Reset all
+ pointers to make this the new current record for that file.
+ Update ages of all the physical buffers.
+*/
+ int ibuff, nbuff;
+ LONGLONG rstart;
+
+ /* check if record is already loaded in one of the buffers */
+ /* search from youngest to oldest buffer for efficiency */
+
+ if (fptr->HDUposition != (fptr->Fptr)->curhdu)
+ ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
+
+ for (ibuff = NIOBUF - 1; ibuff >= 0; ibuff--)
+ {
+ nbuff = (fptr->Fptr)->ageindex[ibuff];
+ if (record == (fptr->Fptr)->bufrecnum[nbuff]) {
+ goto updatebuf; /* use 'goto' for efficiency */
+ }
+ }
+
+ /* record is not already loaded */
+ rstart = (LONGLONG)record * IOBUFLEN;
+
+ if ( !err_mode && (rstart >= (fptr->Fptr)->logfilesize) ) /* EOF? */
+ return(*status = END_OF_FILE);
+
+ if (ffwhbf(fptr, &nbuff) < 0) /* which buffer should we reuse? */
+ return(*status = TOO_MANY_FILES);
+
+ if ((fptr->Fptr)->dirty[nbuff])
+ ffbfwt(fptr->Fptr, nbuff, status); /* write dirty buffer to disk */
+
+ if (rstart >= (fptr->Fptr)->filesize) /* EOF? */
+ {
+ /* initialize an empty buffer with the correct fill value */
+ if ((fptr->Fptr)->hdutype == ASCII_TBL)
+ memset((fptr->Fptr)->iobuffer + (nbuff * IOBUFLEN), 32, IOBUFLEN); /* blank fill */
+ else
+ memset((fptr->Fptr)->iobuffer + (nbuff * IOBUFLEN), 0, IOBUFLEN); /* zero fill */
+
+ (fptr->Fptr)->logfilesize = maxvalue((fptr->Fptr)->logfilesize,
+ rstart + IOBUFLEN);
+
+ (fptr->Fptr)->dirty[nbuff] = TRUE; /* mark record as having been modified */
+ }
+ else /* not EOF, so read record from disk */
+ {
+ if ((fptr->Fptr)->io_pos != rstart)
+ ffseek(fptr->Fptr, rstart);
+
+ ffread(fptr->Fptr, IOBUFLEN, (fptr->Fptr)->iobuffer + (nbuff * IOBUFLEN), status);
+ (fptr->Fptr)->io_pos = rstart + IOBUFLEN; /* set new IO position */
+ }
+
+ (fptr->Fptr)->bufrecnum[nbuff] = record; /* record number contained in buffer */
+
+updatebuf:
+
+ (fptr->Fptr)->curbuf = nbuff; /* this is the current buffer for this file */
+
+ if (ibuff < 0)
+ {
+ /* find the current position of the buffer in the age index */
+ for (ibuff = 0; ibuff < NIOBUF; ibuff++)
+ if ((fptr->Fptr)->ageindex[ibuff] == nbuff)
+ break;
+ }
+
+ /* increment the age of all the buffers that were younger than it */
+ for (ibuff++; ibuff < NIOBUF; ibuff++)
+ (fptr->Fptr)->ageindex[ibuff - 1] = (fptr->Fptr)->ageindex[ibuff];
+
+ (fptr->Fptr)->ageindex[NIOBUF - 1] = nbuff; /* this is now the youngest buffer */
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffwhbf(fitsfile *fptr, /* I - FITS file pointer */
+ int *nbuff) /* O - which buffer to use */
+{
+/*
+ decide which buffer to (re)use to hold a new file record
+*/
+ return(*nbuff = (fptr->Fptr)->ageindex[0]); /* return oldest buffer */
+}
+/*--------------------------------------------------------------------------*/
+int ffflus(fitsfile *fptr, /* I - FITS file pointer */
+ int *status) /* IO - error status */
+/*
+ Flush all the data in the current FITS file to disk. This ensures that if
+ the program subsequently dies, the disk FITS file will be closed correctly.
+*/
+{
+ int hdunum, hdutype;
+
+ if (*status > 0)
+ return(*status);
+
+ ffghdn(fptr, &hdunum); /* get the current HDU number */
+
+ if (ffchdu(fptr,status) > 0) /* close out the current HDU */
+ ffpmsg("ffflus could not close the current HDU.");
+
+ ffflsh(fptr, FALSE, status); /* flush any modified IO buffers to disk */
+
+ if (ffgext(fptr, hdunum - 1, &hdutype, status) > 0) /* reopen HDU */
+ ffpmsg("ffflus could not reopen the current HDU.");
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffflsh(fitsfile *fptr, /* I - FITS file pointer */
+ int clearbuf, /* I - also clear buffer contents? */
+ int *status) /* IO - error status */
+{
+/*
+ flush all dirty IO buffers associated with the file to disk
+*/
+ int ii;
+
+/*
+ no need to move to a different HDU
+
+ if (fptr->HDUposition != (fptr->Fptr)->curhdu)
+ ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
+*/
+ for (ii = 0; ii < NIOBUF; ii++)
+ {
+ /* flush modified buffer to disk */
+ if ((fptr->Fptr)->bufrecnum[ii] >= 0 &&(fptr->Fptr)->dirty[ii])
+ ffbfwt(fptr->Fptr, ii, status);
+
+ if (clearbuf)
+ (fptr->Fptr)->bufrecnum[ii] = -1; /* set contents of buffer as undefined */
+ }
+
+ if (*status != READONLY_FILE)
+ ffflushx(fptr->Fptr); /* flush system buffers to disk */
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffbfeof(fitsfile *fptr, /* I - FITS file pointer */
+ int *status) /* IO - error status */
+{
+/*
+ clear any buffers beyond the end of file
+*/
+ int ii;
+
+ for (ii = 0; ii < NIOBUF; ii++)
+ {
+ if ( (LONGLONG) (fptr->Fptr)->bufrecnum[ii] * IOBUFLEN >= fptr->Fptr->filesize)
+ {
+ (fptr->Fptr)->bufrecnum[ii] = -1; /* set contents of buffer as undefined */
+ }
+ }
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffbfwt(FITSfile *Fptr, /* I - FITS file pointer */
+ int nbuff, /* I - which buffer to write */
+ int *status) /* IO - error status */
+{
+/*
+ write contents of buffer to file; If the position of the buffer
+ is beyond the current EOF, then the file may need to be extended
+ with fill values, and/or with the contents of some of the other
+ i/o buffers.
+*/
+ int ii,ibuff;
+ long jj, irec, minrec, nloop;
+ LONGLONG filepos;
+
+ static char zeros[IOBUFLEN]; /* initialized to zero by default */
+
+ if (!(Fptr->writemode) )
+ {
+ ffpmsg("Error: trying to write to READONLY file.");
+ if (Fptr->driver == 8) { /* gzip compressed file */
+ ffpmsg("Cannot write to a GZIP or COMPRESS compressed file.");
+ }
+ Fptr->dirty[nbuff] = FALSE; /* reset buffer status to prevent later probs */
+ *status = READONLY_FILE;
+ return(*status);
+ }
+
+ filepos = (LONGLONG)Fptr->bufrecnum[nbuff] * IOBUFLEN;
+
+ if (filepos <= Fptr->filesize)
+ {
+ /* record is located within current file, so just write it */
+
+ /* move to the correct write position */
+ if (Fptr->io_pos != filepos)
+ ffseek(Fptr, filepos);
+
+ ffwrite(Fptr, IOBUFLEN, Fptr->iobuffer + (nbuff * IOBUFLEN), status);
+ Fptr->io_pos = filepos + IOBUFLEN;
+
+ if (filepos == Fptr->filesize) /* appended new record? */
+ Fptr->filesize += IOBUFLEN; /* increment the file size */
+
+ Fptr->dirty[nbuff] = FALSE;
+ }
+
+ else /* if record is beyond the EOF, append any other records */
+ /* and/or insert fill values if necessary */
+ {
+ /* move to EOF */
+ if (Fptr->io_pos != Fptr->filesize)
+ ffseek(Fptr, Fptr->filesize);
+
+ ibuff = NIOBUF; /* initialize to impossible value */
+ while(ibuff != nbuff) /* repeat until requested buffer is written */
+ {
+ minrec = (long) (Fptr->filesize / IOBUFLEN);
+
+ /* write lowest record beyond the EOF first */
+
+ irec = Fptr->bufrecnum[nbuff]; /* initially point to the requested buffer */
+ ibuff = nbuff;
+
+ for (ii = 0; ii < NIOBUF; ii++)
+ {
+ if (Fptr->bufrecnum[ii] >= minrec &&
+ Fptr->bufrecnum[ii] < irec)
+ {
+ irec = Fptr->bufrecnum[ii]; /* found a lower record */
+ ibuff = ii;
+ }
+ }
+
+ filepos = (LONGLONG)irec * IOBUFLEN; /* byte offset of record in file */
+
+ /* append 1 or more fill records if necessary */
+ if (filepos > Fptr->filesize)
+ {
+ nloop = (long) ((filepos - (Fptr->filesize)) / IOBUFLEN);
+ for (jj = 0; jj < nloop && !(*status); jj++)
+ ffwrite(Fptr, IOBUFLEN, zeros, status);
+
+/*
+ffseek(Fptr, filepos);
+*/
+ Fptr->filesize = filepos; /* increment the file size */
+ }
+
+ /* write the buffer itself */
+ ffwrite(Fptr, IOBUFLEN, Fptr->iobuffer + (ibuff * IOBUFLEN), status);
+ Fptr->dirty[ibuff] = FALSE;
+
+ Fptr->filesize += IOBUFLEN; /* increment the file size */
+ } /* loop back if more buffers need to be written */
+
+ Fptr->io_pos = Fptr->filesize; /* currently positioned at EOF */
+ }
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffgrsz( fitsfile *fptr, /* I - FITS file pionter */
+ long *ndata, /* O - optimal amount of data to access */
+ int *status) /* IO - error status */
+/*
+ Returns an optimal value for the number of rows in a binary table
+ or the number of pixels in an image that should be read or written
+ at one time for maximum efficiency. Accessing more data than this
+ may cause excessive flushing and rereading of buffers to/from disk.
+*/
+{
+ int typecode, bytesperpixel;
+
+ /* There are NIOBUF internal buffers available each IOBUFLEN bytes long. */
+
+ if (fptr->HDUposition != (fptr->Fptr)->curhdu)
+ ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
+ else if ((fptr->Fptr)->datastart == DATA_UNDEFINED)
+ if ( ffrdef(fptr, status) > 0) /* rescan header to get hdu struct */
+ return(*status);
+
+ if ((fptr->Fptr)->hdutype == IMAGE_HDU ) /* calc pixels per buffer size */
+ {
+ /* image pixels are in column 2 of the 'table' */
+ ffgtcl(fptr, 2, &typecode, NULL, NULL, status);
+ bytesperpixel = typecode / 10;
+ *ndata = ((NIOBUF - 1) * IOBUFLEN) / bytesperpixel;
+ }
+ else /* calc number of rows that fit in buffers */
+ {
+ *ndata = (long) (((NIOBUF - 1) * IOBUFLEN) / maxvalue(1,
+ (fptr->Fptr)->rowlength));
+ *ndata = maxvalue(1, *ndata);
+ }
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffgtbb(fitsfile *fptr, /* I - FITS file pointer */
+ LONGLONG firstrow, /* I - starting row (1 = first row) */
+ LONGLONG firstchar, /* I - starting byte in row (1=first) */
+ LONGLONG nchars, /* I - number of bytes to read */
+ unsigned char *values, /* I - array of bytes to read */
+ int *status) /* IO - error status */
+/*
+ read a consecutive string of bytes from an ascii or binary table.
+ This will span multiple rows of the table if nchars + firstchar is
+ greater than the length of a row.
+*/
+{
+ LONGLONG bytepos, endrow;
+
+ if (*status > 0 || nchars <= 0)
+ return(*status);
+
+ else if (firstrow < 1)
+ return(*status=BAD_ROW_NUM);
+
+ else if (firstchar < 1)
+ return(*status=BAD_ELEM_NUM);
+
+ if (fptr->HDUposition != (fptr->Fptr)->curhdu)
+ ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
+
+ /* check that we do not exceed number of rows in the table */
+ endrow = ((firstchar + nchars - 2) / (fptr->Fptr)->rowlength) + firstrow;
+ if (endrow > (fptr->Fptr)->numrows)
+ {
+ ffpmsg("attempt to read past end of table (ffgtbb)");
+ return(*status=BAD_ROW_NUM);
+ }
+
+ /* move the i/o pointer to the start of the sequence of characters */
+ bytepos = (fptr->Fptr)->datastart +
+ ((fptr->Fptr)->rowlength * (firstrow - 1)) +
+ firstchar - 1;
+
+ ffmbyt(fptr, bytepos, REPORT_EOF, status);
+ ffgbyt(fptr, nchars, values, status); /* read the bytes */
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffgi1b(fitsfile *fptr, /* I - FITS file pointer */
+ LONGLONG byteloc, /* I - position within file to start reading */
+ long nvals, /* I - number of pixels to read */
+ long incre, /* I - byte increment between pixels */
+ unsigned char *values, /* O - returned array of values */
+ int *status) /* IO - error status */
+/*
+ get (read) the array of values from the FITS file, doing machine dependent
+ format conversion (e.g. byte-swapping) if necessary.
+*/
+{
+ LONGLONG postemp;
+
+ if (incre == 1) /* read all the values at once (contiguous bytes) */
+ {
+ if (nvals < MINDIRECT) /* read normally via IO buffers */
+ {
+ ffmbyt(fptr, byteloc, REPORT_EOF, status);
+ ffgbyt(fptr, nvals, values, status);
+ }
+ else /* read directly from disk, bypassing IO buffers */
+ {
+ postemp = (fptr->Fptr)->bytepos; /* store current file position */
+ (fptr->Fptr)->bytepos = byteloc; /* set to the desired position */
+ ffgbyt(fptr, nvals, values, status);
+ (fptr->Fptr)->bytepos = postemp; /* reset to original position */
+ }
+ }
+ else /* have to read each value individually (not contiguous ) */
+ {
+ ffmbyt(fptr, byteloc, REPORT_EOF, status);
+ ffgbytoff(fptr, 1, nvals, incre - 1, values, status);
+ }
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffgi2b(fitsfile *fptr, /* I - FITS file pointer */
+ LONGLONG byteloc, /* I - position within file to start reading */
+ long nvals, /* I - number of pixels to read */
+ long incre, /* I - byte increment between pixels */
+ short *values, /* O - returned array of values */
+ int *status) /* IO - error status */
+/*
+ get (read) the array of values from the FITS file, doing machine dependent
+ format conversion (e.g. byte-swapping) if necessary.
+*/
+{
+ LONGLONG postemp;
+
+ if (incre == 2) /* read all the values at once (contiguous bytes) */
+ {
+ if (nvals * 2 < MINDIRECT) /* read normally via IO buffers */
+ {
+ ffmbyt(fptr, byteloc, REPORT_EOF, status);
+ ffgbyt(fptr, nvals * 2, values, status);
+ }
+ else /* read directly from disk, bypassing IO buffers */
+ {
+ postemp = (fptr->Fptr)->bytepos; /* store current file position */
+ (fptr->Fptr)->bytepos = byteloc; /* set to the desired position */
+ ffgbyt(fptr, nvals * 2, values, status);
+ (fptr->Fptr)->bytepos = postemp; /* reset to original position */
+ }
+ }
+ else /* have to read each value individually (not contiguous ) */
+ {
+ ffmbyt(fptr, byteloc, REPORT_EOF, status);
+ ffgbytoff(fptr, 2, nvals, incre - 2, values, status);
+ }
+
+#if BYTESWAPPED
+ ffswap2(values, nvals); /* reverse order of bytes in each value */
+#endif
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffgi4b(fitsfile *fptr, /* I - FITS file pointer */
+ LONGLONG byteloc, /* I - position within file to start reading */
+ long nvals, /* I - number of pixels to read */
+ long incre, /* I - byte increment between pixels */
+ INT32BIT *values, /* O - returned array of values */
+ int *status) /* IO - error status */
+/*
+ get (read) the array of values from the FITS file, doing machine dependent
+ format conversion (e.g. byte-swapping) if necessary.
+*/
+{
+ LONGLONG postemp;
+
+ if (incre == 4) /* read all the values at once (contiguous bytes) */
+ {
+ if (nvals * 4 < MINDIRECT) /* read normally via IO buffers */
+ {
+ ffmbyt(fptr, byteloc, REPORT_EOF, status);
+ ffgbyt(fptr, nvals * 4, values, status);
+ }
+ else /* read directly from disk, bypassing IO buffers */
+ {
+ postemp = (fptr->Fptr)->bytepos; /* store current file position */
+ (fptr->Fptr)->bytepos = byteloc; /* set to the desired position */
+ ffgbyt(fptr, nvals * 4, values, status);
+ (fptr->Fptr)->bytepos = postemp; /* reset to original position */
+ }
+ }
+ else /* have to read each value individually (not contiguous ) */
+ {
+ ffmbyt(fptr, byteloc, REPORT_EOF, status);
+ ffgbytoff(fptr, 4, nvals, incre - 4, values, status);
+ }
+
+#if BYTESWAPPED
+ ffswap4(values, nvals); /* reverse order of bytes in each value */
+#endif
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffgi8b(fitsfile *fptr, /* I - FITS file pointer */
+ LONGLONG byteloc, /* I - position within file to start reading */
+ long nvals, /* I - number of pixels to read */
+ long incre, /* I - byte increment between pixels */
+ long *values, /* O - returned array of values */
+ int *status) /* IO - error status */
+/*
+ get (read) the array of values from the FITS file, doing machine dependent
+ format conversion (e.g. byte-swapping) if necessary.
+
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ This routine reads 'nvals' 8-byte integers into 'values'.
+ This works both on platforms that have sizeof(long) = 64, and 32,
+ as long as 'values' has been allocated to large enough to hold
+ 8 * nvals bytes of data.
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+*/
+{
+ LONGLONG postemp;
+
+ if (incre == 8) /* read all the values at once (contiguous bytes) */
+ {
+ if (nvals * 8 < MINDIRECT) /* read normally via IO buffers */
+ {
+ ffmbyt(fptr, byteloc, REPORT_EOF, status);
+ ffgbyt(fptr, nvals * 8, values, status);
+ }
+ else /* read directly from disk, bypassing IO buffers */
+ {
+ postemp = (fptr->Fptr)->bytepos; /* store current file position */
+ (fptr->Fptr)->bytepos = byteloc; /* set to the desired position */
+ ffgbyt(fptr, nvals * 8, values, status);
+ (fptr->Fptr)->bytepos = postemp; /* reset to original position */
+ }
+ }
+ else /* have to read each value individually (not contiguous ) */
+ {
+ ffmbyt(fptr, byteloc, REPORT_EOF, status);
+ ffgbytoff(fptr, 8, nvals, incre - 8, values, status);
+ }
+
+#if BYTESWAPPED
+ ffswap8((double *) values, nvals); /* reverse bytes in each value */
+#endif
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffgr4b(fitsfile *fptr, /* I - FITS file pointer */
+ LONGLONG byteloc, /* I - position within file to start reading */
+ long nvals, /* I - number of pixels to read */
+ long incre, /* I - byte increment between pixels */
+ float *values, /* O - returned array of values */
+ int *status) /* IO - error status */
+/*
+ get (read) the array of values from the FITS file, doing machine dependent
+ format conversion (e.g. byte-swapping) if necessary.
+*/
+{
+ LONGLONG postemp;
+
+#if MACHINE == VAXVMS
+ long ii;
+
+#elif (MACHINE == ALPHAVMS) && (FLOATTYPE == GFLOAT)
+ short *sptr;
+ long ii;
+
+#endif
+
+
+ if (incre == 4) /* read all the values at once (contiguous bytes) */
+ {
+ if (nvals * 4 < MINDIRECT) /* read normally via IO buffers */
+ {
+ ffmbyt(fptr, byteloc, REPORT_EOF, status);
+ ffgbyt(fptr, nvals * 4, values, status);
+ }
+ else /* read directly from disk, bypassing IO buffers */
+ {
+ postemp = (fptr->Fptr)->bytepos; /* store current file position */
+ (fptr->Fptr)->bytepos = byteloc; /* set to the desired position */
+ ffgbyt(fptr, nvals * 4, values, status);
+ (fptr->Fptr)->bytepos = postemp; /* reset to original position */
+ }
+ }
+ else /* have to read each value individually (not contiguous ) */
+ {
+ ffmbyt(fptr, byteloc, REPORT_EOF, status);
+ ffgbytoff(fptr, 4, nvals, incre - 4, values, status);
+ }
+
+
+#if MACHINE == VAXVMS
+
+ ii = nvals; /* call VAX macro routine to convert */
+ ieevur(values, values, &ii); /* from IEEE float -> F float */
+
+#elif (MACHINE == ALPHAVMS) && (FLOATTYPE == GFLOAT)
+
+ ffswap2( (short *) values, nvals * 2); /* swap pairs of bytes */
+
+ /* convert from IEEE float format to VMS GFLOAT float format */
+ sptr = (short *) values;
+ for (ii = 0; ii < nvals; ii++, sptr += 2)
+ {
+ if (!fnan(*sptr) ) /* test for NaN or underflow */
+ values[ii] *= 4.0;
+ }
+
+#elif BYTESWAPPED
+ ffswap4((INT32BIT *)values, nvals); /* reverse order of bytes in values */
+#endif
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffgr8b(fitsfile *fptr, /* I - FITS file pointer */
+ LONGLONG byteloc, /* I - position within file to start reading */
+ long nvals, /* I - number of pixels to read */
+ long incre, /* I - byte increment between pixels */
+ double *values, /* O - returned array of values */
+ int *status) /* IO - error status */
+/*
+ get (read) the array of values from the FITS file, doing machine dependent
+ format conversion (e.g. byte-swapping) if necessary.
+*/
+{
+ LONGLONG postemp;
+
+#if MACHINE == VAXVMS
+ long ii;
+
+#elif (MACHINE == ALPHAVMS) && (FLOATTYPE == GFLOAT)
+ short *sptr;
+ long ii;
+
+#endif
+
+ if (incre == 8) /* read all the values at once (contiguous bytes) */
+ {
+ if (nvals * 8 < MINDIRECT) /* read normally via IO buffers */
+ {
+ ffmbyt(fptr, byteloc, REPORT_EOF, status);
+ ffgbyt(fptr, nvals * 8, values, status);
+ }
+ else /* read directly from disk, bypassing IO buffers */
+ {
+ postemp = (fptr->Fptr)->bytepos; /* store current file position */
+ (fptr->Fptr)->bytepos = byteloc; /* set to the desired position */
+ ffgbyt(fptr, nvals * 8, values, status);
+ (fptr->Fptr)->bytepos = postemp; /* reset to original position */
+ }
+ }
+ else /* have to read each value individually (not contiguous ) */
+ {
+ ffmbyt(fptr, byteloc, REPORT_EOF, status);
+ ffgbytoff(fptr, 8, nvals, incre - 8, values, status);
+ }
+
+#if MACHINE == VAXVMS
+ ii = nvals; /* call VAX macro routine to convert */
+ ieevud(values, values, &ii); /* from IEEE float -> D float */
+
+#elif (MACHINE == ALPHAVMS) && (FLOATTYPE == GFLOAT)
+ ffswap2( (short *) values, nvals * 4); /* swap pairs of bytes */
+
+ /* convert from IEEE float format to VMS GFLOAT float format */
+ sptr = (short *) values;
+ for (ii = 0; ii < nvals; ii++, sptr += 4)
+ {
+ if (!dnan(*sptr) ) /* test for NaN or underflow */
+ values[ii] *= 4.0;
+ }
+
+#elif BYTESWAPPED
+ ffswap8(values, nvals); /* reverse order of bytes in each value */
+#endif
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffptbb(fitsfile *fptr, /* I - FITS file pointer */
+ LONGLONG firstrow, /* I - starting row (1 = first row) */
+ LONGLONG firstchar, /* I - starting byte in row (1=first) */
+ LONGLONG nchars, /* I - number of bytes to write */
+ unsigned char *values, /* I - array of bytes to write */
+ int *status) /* IO - error status */
+/*
+ write a consecutive string of bytes to an ascii or binary table.
+ This will span multiple rows of the table if nchars + firstchar is
+ greater than the length of a row.
+*/
+{
+ LONGLONG bytepos, endrow, nrows;
+ char message[81];
+
+ if (*status > 0 || nchars <= 0)
+ return(*status);
+
+ else if (firstrow < 1)
+ return(*status=BAD_ROW_NUM);
+
+ else if (firstchar < 1)
+ return(*status=BAD_ELEM_NUM);
+
+ if (fptr->HDUposition != (fptr->Fptr)->curhdu)
+ ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
+ else if ((fptr->Fptr)->datastart < 0) /* rescan header if data undefined */
+ ffrdef(fptr, status);
+
+ endrow = ((firstchar + nchars - 2) / (fptr->Fptr)->rowlength) + firstrow;
+
+ /* check if we are writing beyond the current end of table */
+ if (endrow > (fptr->Fptr)->numrows)
+ {
+ /* if there are more HDUs following the current one, or */
+ /* if there is a data heap, then we must insert space */
+ /* for the new rows. */
+ if ( !((fptr->Fptr)->lasthdu) || (fptr->Fptr)->heapsize > 0)
+ {
+ nrows = endrow - ((fptr->Fptr)->numrows);
+
+ /* ffirow also updates the heap address and numrows */
+ if (ffirow(fptr, (fptr->Fptr)->numrows, nrows, status) > 0)
+ {
+ sprintf(message,
+ "ffptbb failed to add space for %.0f new rows in table.",
+ (double) nrows);
+ ffpmsg(message);
+ return(*status);
+ }
+ }
+ else
+ {
+ /* manally update heap starting address */
+ (fptr->Fptr)->heapstart +=
+ ((LONGLONG)(endrow - (fptr->Fptr)->numrows) *
+ (fptr->Fptr)->rowlength );
+
+ (fptr->Fptr)->numrows = endrow; /* update number of rows */
+ }
+ }
+
+ /* move the i/o pointer to the start of the sequence of characters */
+ bytepos = (fptr->Fptr)->datastart +
+ ((fptr->Fptr)->rowlength * (firstrow - 1)) +
+ firstchar - 1;
+
+ ffmbyt(fptr, bytepos, IGNORE_EOF, status);
+ ffpbyt(fptr, nchars, values, status); /* write the bytes */
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffpi1b(fitsfile *fptr, /* I - FITS file pointer */
+ long nvals, /* I - number of pixels in the values array */
+ long incre, /* I - byte increment between pixels */
+ unsigned char *values, /* I - array of values to write */
+ int *status) /* IO - error status */
+/*
+ put (write) the array of values to the FITS file, doing machine dependent
+ format conversion (e.g. byte-swapping) if necessary.
+*/
+{
+ if (incre == 1) /* write all the values at once (contiguous bytes) */
+
+ ffpbyt(fptr, nvals, values, status);
+
+ else /* have to write each value individually (not contiguous ) */
+
+ ffpbytoff(fptr, 1, nvals, incre - 1, values, status);
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffpi2b(fitsfile *fptr, /* I - FITS file pointer */
+ long nvals, /* I - number of pixels in the values array */
+ long incre, /* I - byte increment between pixels */
+ short *values, /* I - array of values to write */
+ int *status) /* IO - error status */
+/*
+ put (write) the array of values to the FITS file, doing machine dependent
+ format conversion (e.g. byte-swapping) if necessary.
+*/
+{
+#if BYTESWAPPED
+ ffswap2(values, nvals); /* reverse order of bytes in each value */
+#endif
+
+ if (incre == 2) /* write all the values at once (contiguous bytes) */
+
+ ffpbyt(fptr, nvals * 2, values, status);
+
+ else /* have to write each value individually (not contiguous ) */
+
+ ffpbytoff(fptr, 2, nvals, incre - 2, values, status);
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffpi4b(fitsfile *fptr, /* I - FITS file pointer */
+ long nvals, /* I - number of pixels in the values array */
+ long incre, /* I - byte increment between pixels */
+ INT32BIT *values, /* I - array of values to write */
+ int *status) /* IO - error status */
+/*
+ put (write) the array of values to the FITS file, doing machine dependent
+ format conversion (e.g. byte-swapping) if necessary.
+*/
+{
+#if BYTESWAPPED
+ ffswap4(values, nvals); /* reverse order of bytes in each value */
+#endif
+
+ if (incre == 4) /* write all the values at once (contiguous bytes) */
+
+ ffpbyt(fptr, nvals * 4, values, status);
+
+ else /* have to write each value individually (not contiguous ) */
+
+ ffpbytoff(fptr, 4, nvals, incre - 4, values, status);
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffpi8b(fitsfile *fptr, /* I - FITS file pointer */
+ long nvals, /* I - number of pixels in the values array */
+ long incre, /* I - byte increment between pixels */
+ long *values, /* I - array of values to write */
+ int *status) /* IO - error status */
+/*
+ put (write) the array of values to the FITS file, doing machine dependent
+ format conversion (e.g. byte-swapping) if necessary.
+
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ This routine writes 'nvals' 8-byte integers from 'values'.
+ This works both on platforms that have sizeof(long) = 64, and 32,
+ as long as 'values' has been allocated to large enough to hold
+ 8 * nvals bytes of data.
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+*/
+{
+#if BYTESWAPPED
+ ffswap8((double *) values, nvals); /* reverse bytes in each value */
+#endif
+
+ if (incre == 8) /* write all the values at once (contiguous bytes) */
+
+ ffpbyt(fptr, nvals * 8, values, status);
+
+ else /* have to write each value individually (not contiguous ) */
+
+ ffpbytoff(fptr, 8, nvals, incre - 8, values, status);
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffpr4b(fitsfile *fptr, /* I - FITS file pointer */
+ long nvals, /* I - number of pixels in the values array */
+ long incre, /* I - byte increment between pixels */
+ float *values, /* I - array of values to write */
+ int *status) /* IO - error status */
+/*
+ put (write) the array of values to the FITS file, doing machine dependent
+ format conversion (e.g. byte-swapping) if necessary.
+*/
+{
+#if MACHINE == VAXVMS
+ long ii;
+
+ ii = nvals; /* call VAX macro routine to convert */
+ ieevpr(values, values, &ii); /* from F float -> IEEE float */
+
+#elif (MACHINE == ALPHAVMS) && (FLOATTYPE == GFLOAT)
+ long ii;
+
+ /* convert from VMS FFLOAT float format to IEEE float format */
+ for (ii = 0; ii < nvals; ii++)
+ values[ii] *= 0.25;
+
+ ffswap2( (short *) values, nvals * 2); /* swap pairs of bytes */
+
+#elif BYTESWAPPED
+ ffswap4((INT32BIT *) values, nvals); /* reverse order of bytes in values */
+#endif
+
+ if (incre == 4) /* write all the values at once (contiguous bytes) */
+
+ ffpbyt(fptr, nvals * 4, values, status);
+
+ else /* have to write each value individually (not contiguous ) */
+
+ ffpbytoff(fptr, 4, nvals, incre - 4, values, status);
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffpr8b(fitsfile *fptr, /* I - FITS file pointer */
+ long nvals, /* I - number of pixels in the values array */
+ long incre, /* I - byte increment between pixels */
+ double *values, /* I - array of values to write */
+ int *status) /* IO - error status */
+/*
+ put (write) the array of values to the FITS file, doing machine dependent
+ format conversion (e.g. byte-swapping) if necessary.
+*/
+{
+#if MACHINE == VAXVMS
+ long ii;
+
+ ii = nvals; /* call VAX macro routine to convert */
+ ieevpd(values, values, &ii); /* from D float -> IEEE float */
+
+#elif (MACHINE == ALPHAVMS) && (FLOATTYPE == GFLOAT)
+ long ii;
+
+ /* convert from VMS GFLOAT float format to IEEE float format */
+ for (ii = 0; ii < nvals; ii++)
+ values[ii] *= 0.25;
+
+ ffswap2( (short *) values, nvals * 4); /* swap pairs of bytes */
+
+#elif BYTESWAPPED
+ ffswap8(values, nvals); /* reverse order of bytes in each value */
+#endif
+
+ if (incre == 8) /* write all the values at once (contiguous bytes) */
+
+ ffpbyt(fptr, nvals * 8, values, status);
+
+ else /* have to write each value individually (not contiguous ) */
+
+ ffpbytoff(fptr, 8, nvals, incre - 8, values, status);
+
+ return(*status);
+}
+
diff --git a/build_kstarslite/android_libs_src/cfitsio/build.sh b/build_kstarslite/android_libs_src/cfitsio/build.sh
new file mode 100755
index 0000000..9fbfb53
--- /dev/null
+++ b/build_kstarslite/android_libs_src/cfitsio/build.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+# Use this script to compile cfitsio for the Android platform. It does a cross-compilation
+# using the Android NDK standalone toolchain. Consult STANDALONE-TOOLCHAIN.HTML in the
+# Android NDK documentation for more information
+#
+# There is one code issue that you'll need to fix. In fitscore.c there are two references
+# to the decimal_point member of the struct lconv type. With these builds, that struct is
+# actually empty. In methods ffc2rr and ffc2dd I replaced the variable decimalpt with
+# an explicit value of '.' and deleted the four lines starting "if (!decimalpt)".
+#
+#
+# wherever your ndk is
+export NDK_ROOT=$ANDROID_NDK
+#
+# where you'd like the temporary toolchain to be
+mkdir /tmp/androidToolchainC -p
+export PREFIX=/tmp/androidToolchainC
+#
+# N.B. This was developed on a Mac running Mac OSX 10.8.5 and Xcode 5.0.2. You may need
+# different variables on other systems. See STANDALONE-TOOLCHAIN.HTML
+$NDK_ROOT/build/tools/make-standalone-toolchain.sh --platform=android-${ANDROID_API_LEVEL} --install-dir=$PREFIX --toolchain=$ANDROID_TOOLCHAIN-clang
+export PATH="$PREFIX/bin:$PATH"
+# Using clang here. Gcc is an alternative, but there is currently an Android compiler bug # that prevents using gcc
+# https://code.google.com/p/android/issues/detail?id=59913
+
+if [ "$ANDROID_ARCHITECTURE" == "x86" ]
+then
+ ANDROID_TOOLCHAIN="i686-linux-android"
+fi
+
+export CC="$ANDROID_TOOLCHAIN-clang"
+export LD="$ANDROID_TOOLCHAIN-ld"
+export AR="$ANDROID_TOOLCHAIN-ar"
+export RANLIB="$ANDROID_TOOLCHAIN-ranlib"
+export STRIP="$ANDROID_TOOLCHAIN-strip"
+make distclean
+
+# configure will complain about the --host, but ignore it. This is indeed a
+# cross-compilation case
+./configure --prefix=$PREFIX --host=$ANDROID_TOOLCHAIN
+make install
diff --git a/build_kstarslite/android_libs_src/cfitsio/cfileio.c b/build_kstarslite/android_libs_src/cfitsio/cfileio.c
new file mode 100644
index 0000000..694ea0c
--- /dev/null
+++ b/build_kstarslite/android_libs_src/cfitsio/cfileio.c
@@ -0,0 +1,7333 @@
+/* This file, cfileio.c, contains the low-level file access routines. */
+
+/* The FITSIO software was written by William Pence at the High Energy */
+/* Astrophysic Science Archive Research Center (HEASARC) at the NASA */
+/* Goddard Space Flight Center. */
+
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stddef.h> /* apparently needed to define size_t */
+#include "fitsio2.h"
+#include "group.h"
+
+#define MAX_PREFIX_LEN 20 /* max length of file type prefix (e.g. 'http://') */
+#define MAX_DRIVERS 24 /* max number of file I/O drivers */
+
+typedef struct /* structure containing pointers to I/O driver functions */
+{ char prefix[MAX_PREFIX_LEN];
+ int (*init)(void);
+ int (*shutdown)(void);
+ int (*setoptions)(int option);
+ int (*getoptions)(int *options);
+ int (*getversion)(int *version);
+ int (*checkfile)(char *urltype, char *infile, char *outfile);
+ int (*open)(char *filename, int rwmode, int *driverhandle);
+ int (*create)(char *filename, int *drivehandle);
+ int (*truncate)(int drivehandle, LONGLONG size);
+ int (*close)(int drivehandle);
+ int (*remove)(char *filename);
+ int (*size)(int drivehandle, LONGLONG *size);
+ int (*flush)(int drivehandle);
+ int (*seek)(int drivehandle, LONGLONG offset);
+ int (*read)(int drivehandle, void *buffer, long nbytes);
+ int (*write)(int drivehandle, void *buffer, long nbytes);
+} fitsdriver;
+
+fitsdriver driverTable[MAX_DRIVERS]; /* allocate driver tables */
+
+FITSfile *FptrTable[NMAXFILES]; /* this table of Fptr pointers is */
+ /* used by fits_already_open */
+
+int need_to_initialize = 1; /* true if CFITSIO has not been initialized */
+int no_of_drivers = 0; /* number of currently defined I/O drivers */
+
+static int pixel_filter_helper(fitsfile **fptr, char *outfile,
+ char *expr, int *status);
+static int find_quote(char **string);
+static int find_doublequote(char **string);
+static int find_paren(char **string);
+static int find_bracket(char **string);
+static int find_curlybracket(char **string);
+int comma2semicolon(char *string);
+
+#ifdef _REENTRANT
+
+pthread_mutex_t Fitsio_InitLock = PTHREAD_MUTEX_INITIALIZER;
+
+#endif
+
+/*--------------------------------------------------------------------------*/
+int fitsio_init_lock(void)
+{
+ int status = 0;
+
+#ifdef _REENTRANT
+
+ static int need_to_init = 1;
+
+ pthread_mutexattr_t mutex_init;
+
+ FFLOCK1(Fitsio_InitLock);
+
+ if (need_to_init) {
+
+ /* Init the main fitsio lock here since we need a a recursive lock */
+
+ status = pthread_mutexattr_init(&mutex_init);
+ if (status) {
+ ffpmsg("pthread_mutexattr_init failed (fitsio_init_lock)");
+ return(status);
+ }
+
+#ifdef __GLIBC__
+ status = pthread_mutexattr_settype(&mutex_init,
+ PTHREAD_MUTEX_RECURSIVE_NP);
+#else
+ status = pthread_mutexattr_settype(&mutex_init,
+ PTHREAD_MUTEX_RECURSIVE);
+#endif
+ if (status) {
+ ffpmsg("pthread_mutexattr_settype failed (fitsio_init_lock)");
+ return(status);
+ }
+
+ status = pthread_mutex_init(&Fitsio_Lock,&mutex_init);
+ if (status) {
+ ffpmsg("pthread_mutex_init failed (fitsio_init_lock)");
+ return(status);
+ }
+
+ need_to_init = 0;
+ }
+
+ FFUNLOCK1(Fitsio_InitLock);
+
+#endif
+
+ return(status);
+}
+/*--------------------------------------------------------------------------*/
+int ffomem(fitsfile **fptr, /* O - FITS file pointer */
+ const char *name, /* I - name of file to open */
+ int mode, /* I - 0 = open readonly; 1 = read/write */
+ void **buffptr, /* I - address of memory pointer */
+ size_t *buffsize, /* I - size of buffer, in bytes */
+ size_t deltasize, /* I - increment for future realloc's */
+ void *(*mem_realloc)(void *p, size_t newsize), /* function */
+ int *status) /* IO - error status */
+/*
+ Open an existing FITS file in core memory. This is a specialized version
+ of ffopen.
+*/
+{
+ int ii, driver, handle, hdutyp, slen, movetotype, extvers, extnum;
+ char extname[FLEN_VALUE];
+ LONGLONG filesize;
+ char urltype[MAX_PREFIX_LEN], infile[FLEN_FILENAME], outfile[FLEN_FILENAME];
+ char extspec[FLEN_FILENAME], rowfilter[FLEN_FILENAME];
+ char binspec[FLEN_FILENAME], colspec[FLEN_FILENAME];
+ char imagecolname[FLEN_VALUE], rowexpress[FLEN_FILENAME];
+ char *url, errmsg[FLEN_ERRMSG];
+ char *hdtype[3] = {"IMAGE", "TABLE", "BINTABLE"};
+
+ if (*status > 0)
+ return(*status);
+
+ *fptr = 0; /* initialize null file pointer */
+
+ if (need_to_initialize) /* this is called only once */
+ {
+ *status = fits_init_cfitsio();
+
+ if (*status > 0)
+ return(*status);
+ }
+
+ url = (char *) name;
+ while (*url == ' ') /* ignore leading spaces in the file spec */
+ url++;
+
+ /* parse the input file specification */
+ fits_parse_input_url(url, urltype, infile, outfile, extspec,
+ rowfilter, binspec, colspec, status);
+
+ strcpy(urltype, "memkeep://"); /* URL type for pre-existing memory file */
+
+ *status = urltype2driver(urltype, &driver);
+
+ if (*status > 0)
+ {
+ ffpmsg("could not find driver for pre-existing memory file: (ffomem)");
+ return(*status);
+ }
+
+ /* call driver routine to open the memory file */
+ FFLOCK; /* lock this while searching for vacant handle */
+ *status = mem_openmem( buffptr, buffsize,deltasize,
+ mem_realloc, &handle);
+ FFUNLOCK;
+
+ if (*status > 0)
+ {
+ ffpmsg("failed to open pre-existing memory file: (ffomem)");
+ return(*status);
+ }
+
+ /* get initial file size */
+ *status = (*driverTable[driver].size)(handle, &filesize);
+
+ if (*status > 0)
+ {
+ (*driverTable[driver].close)(handle); /* close the file */
+ ffpmsg("failed get the size of the memory file: (ffomem)");
+ return(*status);
+ }
+
+ /* allocate fitsfile structure and initialize = 0 */
+ *fptr = (fitsfile *) calloc(1, sizeof(fitsfile));
+
+ if (!(*fptr))
+ {
+ (*driverTable[driver].close)(handle); /* close the file */
+ ffpmsg("failed to allocate structure for following file: (ffomem)");
+ ffpmsg(url);
+ return(*status = MEMORY_ALLOCATION);
+ }
+
+ /* allocate FITSfile structure and initialize = 0 */
+ (*fptr)->Fptr = (FITSfile *) calloc(1, sizeof(FITSfile));
+
+ if (!((*fptr)->Fptr))
+ {
+ (*driverTable[driver].close)(handle); /* close the file */
+ ffpmsg("failed to allocate structure for following file: (ffomem)");
+ ffpmsg(url);
+ free(*fptr);
+ *fptr = 0;
+ return(*status = MEMORY_ALLOCATION);
+ }
+
+ slen = strlen(url) + 1;
+ slen = maxvalue(slen, 32); /* reserve at least 32 chars */
+ ((*fptr)->Fptr)->filename = (char *) malloc(slen); /* mem for file name */
+
+ if ( !(((*fptr)->Fptr)->filename) )
+ {
+ (*driverTable[driver].close)(handle); /* close the file */
+ ffpmsg("failed to allocate memory for filename: (ffomem)");
+ ffpmsg(url);
+ free((*fptr)->Fptr);
+ free(*fptr);
+ *fptr = 0; /* return null file pointer */
+ return(*status = MEMORY_ALLOCATION);
+ }
+
+ /* mem for headstart array */
+ ((*fptr)->Fptr)->headstart = (LONGLONG *) calloc(1001, sizeof(LONGLONG));
+
+ if ( !(((*fptr)->Fptr)->headstart) )
+ {
+ (*driverTable[driver].close)(handle); /* close the file */
+ ffpmsg("failed to allocate memory for headstart array: (ffomem)");
+ ffpmsg(url);
+ free( ((*fptr)->Fptr)->filename);
+ free((*fptr)->Fptr);
+ free(*fptr);
+ *fptr = 0; /* return null file pointer */
+ return(*status = MEMORY_ALLOCATION);
+ }
+
+ /* mem for file I/O buffers */
+ ((*fptr)->Fptr)->iobuffer = (char *) calloc(NIOBUF, IOBUFLEN);
+
+ if ( !(((*fptr)->Fptr)->iobuffer) )
+ {
+ (*driverTable[driver].close)(handle); /* close the file */
+ ffpmsg("failed to allocate memory for iobuffer array: (ffomem)");
+ ffpmsg(url);
+ free( ((*fptr)->Fptr)->headstart); /* free memory for headstart array */
+ free( ((*fptr)->Fptr)->filename);
+ free((*fptr)->Fptr);
+ free(*fptr);
+ *fptr = 0; /* return null file pointer */
+ return(*status = MEMORY_ALLOCATION);
+ }
+
+ /* initialize the ageindex array (relative age of the I/O buffers) */
+ /* and initialize the bufrecnum array as being empty */
+ for (ii = 0; ii < NIOBUF; ii++) {
+ ((*fptr)->Fptr)->ageindex[ii] = ii;
+ ((*fptr)->Fptr)->bufrecnum[ii] = -1;
+ }
+
+ /* store the parameters describing the file */
+ ((*fptr)->Fptr)->MAXHDU = 1000; /* initial size of headstart */
+ ((*fptr)->Fptr)->filehandle = handle; /* file handle */
+ ((*fptr)->Fptr)->driver = driver; /* driver number */
+ strcpy(((*fptr)->Fptr)->filename, url); /* full input filename */
+ ((*fptr)->Fptr)->filesize = filesize; /* physical file size */
+ ((*fptr)->Fptr)->logfilesize = filesize; /* logical file size */
+ ((*fptr)->Fptr)->writemode = mode; /* read-write mode */
+ ((*fptr)->Fptr)->datastart = DATA_UNDEFINED; /* unknown start of data */
+ ((*fptr)->Fptr)->curbuf = -1; /* undefined current IO buffer */
+ ((*fptr)->Fptr)->open_count = 1; /* structure is currently used once */
+ ((*fptr)->Fptr)->validcode = VALIDSTRUC; /* flag denoting valid structure */
+
+ ffldrc(*fptr, 0, REPORT_EOF, status); /* load first record */
+
+ fits_store_Fptr( (*fptr)->Fptr, status); /* store Fptr address */
+
+ if (ffrhdu(*fptr, &hdutyp, status) > 0) /* determine HDU structure */
+ {
+ ffpmsg(
+ "ffomem could not interpret primary array header of file: (ffomem)");
+ ffpmsg(url);
+
+ if (*status == UNKNOWN_REC)
+ ffpmsg("This does not look like a FITS file.");
+
+ ffclos(*fptr, status);
+ *fptr = 0; /* return null file pointer */
+ }
+
+ /* ---------------------------------------------------------- */
+ /* move to desired extension, if specified as part of the URL */
+ /* ---------------------------------------------------------- */
+
+ imagecolname[0] = '\0';
+ rowexpress[0] = '\0';
+
+ if (*extspec)
+ {
+ /* parse the extension specifier into individual parameters */
+ ffexts(extspec, &extnum,
+ extname, &extvers, &movetotype, imagecolname, rowexpress, status);
+
+
+ if (*status > 0)
+ return(*status);
+
+ if (extnum)
+ {
+ ffmahd(*fptr, extnum + 1, &hdutyp, status);
+ }
+ else if (*extname) /* move to named extension, if specified */
+ {
+ ffmnhd(*fptr, movetotype, extname, extvers, status);
+ }
+
+ if (*status > 0)
+ {
+ ffpmsg("ffomem could not move to the specified extension:");
+ if (extnum > 0)
+ {
+ sprintf(errmsg,
+ " extension number %d doesn't exist or couldn't be opened.",extnum);
+ ffpmsg(errmsg);
+ }
+ else
+ {
+ sprintf(errmsg,
+ " extension with EXTNAME = %s,", extname);
+ ffpmsg(errmsg);
+
+ if (extvers)
+ {
+ sprintf(errmsg,
+ " and with EXTVERS = %d,", extvers);
+ ffpmsg(errmsg);
+ }
+
+ if (movetotype != ANY_HDU)
+ {
+ sprintf(errmsg,
+ " and with XTENSION = %s,", hdtype[movetotype]);
+ ffpmsg(errmsg);
+ }
+
+ ffpmsg(" doesn't exist or couldn't be opened.");
+ }
+ return(*status);
+ }
+ }
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffdkopn(fitsfile **fptr, /* O - FITS file pointer */
+ const char *name, /* I - full name of file to open */
+ int mode, /* I - 0 = open readonly; 1 = read/write */
+ int *status) /* IO - error status */
+/*
+ Open an existing FITS file on magnetic disk with either readonly or
+ read/write access. The routine does not support CFITSIO's extended
+ filename syntax and simply uses the entire input 'name' string as
+ the name of the file.
+*/
+{
+ if (*status > 0)
+ return(*status);
+
+ *status = OPEN_DISK_FILE;
+
+ ffopen(fptr, name, mode, status);
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffdopn(fitsfile **fptr, /* O - FITS file pointer */
+ const char *name, /* I - full name of file to open */
+ int mode, /* I - 0 = open readonly; 1 = read/write */
+ int *status) /* IO - error status */
+/*
+ Open an existing FITS file with either readonly or read/write access. and
+ move to the first HDU that contains 'interesting' data, if the primary
+ array contains a null image (i.e., NAXIS = 0).
+*/
+{
+ if (*status > 0)
+ return(*status);
+
+ *status = SKIP_NULL_PRIMARY;
+
+ ffopen(fptr, name, mode, status);
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffeopn(fitsfile **fptr, /* O - FITS file pointer */
+ const char *name, /* I - full name of file to open */
+ int mode, /* I - 0 = open readonly; 1 = read/write */
+ char *extlist, /* I - list of 'good' extensions to move to */
+ int *hdutype, /* O - type of extension that is moved to */
+ int *status) /* IO - error status */
+/*
+ Open an existing FITS file with either readonly or read/write access. and
+ if the primary array contains a null image (i.e., NAXIS = 0) then attempt to
+ move to the first extension named in the extlist of extension names. If
+ none are found, then simply move to the 2nd extension.
+*/
+{
+ int hdunum, naxis, thdutype, gotext=0;
+ char *ext, *textlist;
+
+ if (*status > 0)
+ return(*status);
+
+ if (ffopen(fptr, name, mode, status) > 0)
+ return(*status);
+
+ fits_get_hdu_num(*fptr, &hdunum);
+ fits_get_img_dim(*fptr, &naxis, status);
+
+ if( (hdunum == 1) && (naxis == 0) ){
+ /* look through the extension list */
+ if( extlist ){
+ gotext = 0;
+ textlist = malloc(strlen(extlist) + 1);
+ if (!textlist) {
+ *status = MEMORY_ALLOCATION;
+ return(*status);
+ }
+
+ strcpy(textlist, extlist);
+ for(ext=(char *)strtok(textlist, " "); ext != NULL;
+ ext=(char *)strtok(NULL," ")){
+ fits_movnam_hdu(*fptr, ANY_HDU, ext, 0, status);
+ if( *status == 0 ){
+ gotext = 1;
+ break;
+ } else {
+ *status = 0;
+ }
+ }
+ free(textlist);
+ }
+ if( !gotext ){
+ /* if all else fails, move to extension #2 and hope for the best */
+ fits_movabs_hdu(*fptr, 2, &thdutype, status);
+ }
+ }
+ fits_get_hdu_type(*fptr, hdutype, status);
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int fftopn(fitsfile **fptr, /* O - FITS file pointer */
+ const char *name, /* I - full name of file to open */
+ int mode, /* I - 0 = open readonly; 1 = read/write */
+ int *status) /* IO - error status */
+/*
+ Open an existing FITS file with either readonly or read/write access. and
+ move to the first HDU that contains 'interesting' table (not an image).
+*/
+{
+ int hdutype;
+
+ if (*status > 0)
+ return(*status);
+
+ *status = SKIP_IMAGE;
+
+ ffopen(fptr, name, mode, status);
+
+ if (ffghdt(*fptr, &hdutype, status) <= 0) {
+ if (hdutype == IMAGE_HDU)
+ *status = NOT_TABLE;
+ }
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffiopn(fitsfile **fptr, /* O - FITS file pointer */
+ const char *name, /* I - full name of file to open */
+ int mode, /* I - 0 = open readonly; 1 = read/write */
+ int *status) /* IO - error status */
+/*
+ Open an existing FITS file with either readonly or read/write access. and
+ move to the first HDU that contains 'interesting' image (not an table).
+*/
+{
+ int hdutype;
+
+ if (*status > 0)
+ return(*status);
+
+ *status = SKIP_TABLE;
+
+ ffopen(fptr, name, mode, status);
+
+ if (ffghdt(*fptr, &hdutype, status) <= 0) {
+ if (hdutype != IMAGE_HDU)
+ *status = NOT_IMAGE;
+ }
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffopentest(int soname, /* I - CFITSIO shared library version */
+ /* application program (fitsio.h file) */
+ fitsfile **fptr, /* O - FITS file pointer */
+ const char *name, /* I - full name of file to open */
+ int mode, /* I - 0 = open readonly; 1 = read/write */
+ int *status) /* IO - error status */
+/*
+ Open an existing FITS file with either readonly or read/write access.
+ First test that the SONAME of fitsio.h used to build the CFITSIO library
+ is the same as was used in compiling the application program that
+ links to the library.
+*/
+{
+ if (soname != CFITSIO_SONAME)
+ {
+ printf("\nERROR: Mismatch in the CFITSIO_SONAME value in the fitsio.h include file\n");
+ printf("that was used to build the CFITSIO library, and the value in the include file\n");
+ printf("that was used when compiling the application program:\n");
+ printf(" Version used to build the CFITSIO library = %d\n",CFITSIO_SONAME);
+ printf(" Version included by the application program = %d\n",soname);
+ printf("\nFix this by recompiling and then relinking this application program \n");
+ printf("with the CFITSIO library.\n");
+
+ *status = FILE_NOT_OPENED;
+ return(*status);
+ }
+
+ /* now call the normal file open routine */
+ ffopen(fptr, name, mode, status);
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffopen(fitsfile **fptr, /* O - FITS file pointer */
+ const char *name, /* I - full name of file to open */
+ int mode, /* I - 0 = open readonly; 1 = read/write */
+ int *status) /* IO - error status */
+/*
+ Open an existing FITS file with either readonly or read/write access.
+*/
+{
+ fitsfile *newptr;
+ int ii, driver, hdutyp, hdunum, slen, writecopy, isopen;
+ LONGLONG filesize;
+ long rownum, nrows, goodrows;
+ int extnum, extvers, handle, movetotype, tstatus = 0, only_one = 0;
+ char urltype[MAX_PREFIX_LEN], infile[FLEN_FILENAME], outfile[FLEN_FILENAME];
+ char origurltype[MAX_PREFIX_LEN], extspec[FLEN_FILENAME];
+ char extname[FLEN_VALUE], rowfilter[FLEN_FILENAME], tblname[FLEN_VALUE];
+ char imagecolname[FLEN_VALUE], rowexpress[FLEN_FILENAME];
+ char binspec[FLEN_FILENAME], colspec[FLEN_FILENAME], pixfilter[FLEN_FILENAME];
+ char histfilename[FLEN_FILENAME];
+ char filtfilename[FLEN_FILENAME], compspec[FLEN_FILENAME];
+ char wtcol[FLEN_VALUE];
+ char minname[4][FLEN_VALUE], maxname[4][FLEN_VALUE];
+ char binname[4][FLEN_VALUE];
+
+ char *url;
+ double minin[4], maxin[4], binsizein[4], weight;
+ int imagetype, naxis = 1, haxis, recip;
+ int skip_null = 0, skip_image = 0, skip_table = 0, open_disk_file = 0;
+ char colname[4][FLEN_VALUE];
+ char errmsg[FLEN_ERRMSG];
+ char *hdtype[3] = {"IMAGE", "TABLE", "BINTABLE"};
+ char *rowselect = 0;
+
+ if (*status > 0)
+ return(*status);
+
+ if (*status == SKIP_NULL_PRIMARY)
+ {
+ /* this special status value is used as a flag by ffdopn to tell */
+ /* ffopen to skip over a null primary array when opening the file. */
+
+ skip_null = 1;
+ *status = 0;
+ }
+ else if (*status == SKIP_IMAGE)
+ {
+ /* this special status value is used as a flag by fftopn to tell */
+ /* ffopen to move to 1st significant table when opening the file. */
+
+ skip_image = 1;
+ *status = 0;
+ }
+ else if (*status == SKIP_TABLE)
+ {
+ /* this special status value is used as a flag by ffiopn to tell */
+ /* ffopen to move to 1st significant image when opening the file. */
+
+ skip_table = 1;
+ *status = 0;
+ }
+ else if (*status == OPEN_DISK_FILE)
+ {
+ /* this special status value is used as a flag by ffdkopn to tell */
+ /* ffopen to not interpret the input filename using CFITSIO's */
+ /* extended filename syntax, and simply open the specified disk file */
+
+ open_disk_file = 1;
+ *status = 0;
+ }
+
+ *fptr = 0; /* initialize null file pointer */
+ writecopy = 0; /* have we made a write-able copy of the input file? */
+
+ if (need_to_initialize) { /* this is called only once */
+ *status = fits_init_cfitsio();
+ }
+
+ if (*status > 0)
+ return(*status);
+
+ url = (char *) name;
+ while (*url == ' ') /* ignore leading spaces in the filename */
+ url++;
+
+ if (*url == '\0')
+ {
+ ffpmsg("Name of file to open is blank. (ffopen)");
+ return(*status = FILE_NOT_OPENED);
+ }
+
+ if (open_disk_file)
+ {
+ /* treat the input URL literally as the name of the file to open */
+ /* and don't try to parse the URL using the extended filename syntax */
+
+ if (strlen(url) > FLEN_FILENAME - 1) {
+ ffpmsg("Name of file to open is too long. (ffopen)");
+ return(*status = FILE_NOT_OPENED);
+ }
+
+ strcpy(infile,url);
+ strcpy(urltype, "file://");
+ outfile[0] = '\0';
+ extspec[0] = '\0';
+ binspec[0] = '\0';
+ colspec[0] = '\0';
+ rowfilter[0] = '\0';
+ pixfilter[0] = '\0';
+ compspec[0] = '\0';
+ }
+ else
+ {
+ /* parse the input file specification */
+
+ /* NOTE: This routine tests that all the strings do not */
+ /* overflow the standard buffer sizes (FLEN_FILENAME, etc.) */
+ /* therefore in general we do not have to worry about buffer */
+ /* overflow of any of the returned strings. */
+
+ /* call the newer version of this parsing routine that supports 'compspec' */
+ ffifile2(url, urltype, infile, outfile, extspec,
+ rowfilter, binspec, colspec, pixfilter, compspec, status);
+ }
+
+ if (*status > 0)
+ {
+ ffpmsg("could not parse the input filename: (ffopen)");
+ ffpmsg(url);
+ return(*status);
+ }
+
+ imagecolname[0] = '\0';
+ rowexpress[0] = '\0';
+
+ if (*extspec)
+ {
+ slen = strlen(extspec);
+ if (extspec[slen - 1] == '#') { /* special symbol to mean only copy this extension */
+ extspec[slen - 1] = '\0';
+ only_one = 1;
+ }
+
+ /* parse the extension specifier into individual parameters */
+ ffexts(extspec, &extnum,
+ extname, &extvers, &movetotype, imagecolname, rowexpress, status);
+
+ if (*status > 0)
+ return(*status);
+ }
+
+ /*-------------------------------------------------------------------*/
+ /* special cases: */
+ /*-------------------------------------------------------------------*/
+
+ histfilename[0] = '\0';
+ filtfilename[0] = '\0';
+ if (*outfile && (*binspec || *imagecolname || *pixfilter))
+ {
+ /* if binspec or imagecolumn are specified, then the */
+ /* output file name is intended for the final image, */
+ /* and not a copy of the input file. */
+
+ strcpy(histfilename, outfile);
+ outfile[0] = '\0';
+ }
+ else if (*outfile && (*rowfilter || *colspec))
+ {
+ /* if rowfilter or colspece are specified, then the */
+ /* output file name is intended for the filtered file */
+ /* and not a copy of the input file. */
+
+ strcpy(filtfilename, outfile);
+ outfile[0] = '\0';
+ }
+
+ /*-------------------------------------------------------------------*/
+ /* check if this same file is already open, and if so, attach to it */
+ /*-------------------------------------------------------------------*/
+
+ FFLOCK;
+ if (fits_already_open(fptr, url, urltype, infile, extspec, rowfilter,
+ binspec, colspec, mode, &isopen, status) > 0)
+ {
+ FFUNLOCK;
+ return(*status);
+ }
+ FFUNLOCK;
+
+ if (isopen) {
+ goto move2hdu;
+ }
+
+ /* get the driver number corresponding to this urltype */
+ *status = urltype2driver(urltype, &driver);
+
+ if (*status > 0)
+ {
+ ffpmsg("could not find driver for this file: (ffopen)");
+ ffpmsg(urltype);
+ ffpmsg(url);
+ return(*status);
+ }
+
+ /*-------------------------------------------------------------------
+ deal with all those messy special cases which may require that
+ a different driver be used:
+ - is disk file compressed?
+ - are ftp:, gsiftp:, or http: files compressed?
+ - has user requested that a local copy be made of
+ the ftp or http file?
+ -------------------------------------------------------------------*/
+
+ if (driverTable[driver].checkfile)
+ {
+ strcpy(origurltype,urltype); /* Save the urltype */
+
+ /* 'checkfile' may modify the urltype, infile and outfile strings */
+ *status = (*driverTable[driver].checkfile)(urltype, infile, outfile);
+
+ if (*status)
+ {
+ ffpmsg("checkfile failed for this file: (ffopen)");
+ ffpmsg(url);
+ return(*status);
+ }
+
+ if (strcmp(origurltype, urltype)) /* did driver changed on us? */
+ {
+ *status = urltype2driver(urltype, &driver);
+ if (*status > 0)
+ {
+ ffpmsg("could not change driver for this file: (ffopen)");
+ ffpmsg(url);
+ ffpmsg(urltype);
+ return(*status);
+ }
+ }
+ }
+
+ /* call appropriate driver to open the file */
+ if (driverTable[driver].open)
+ {
+ FFLOCK; /* lock this while searching for vacant handle */
+ *status = (*driverTable[driver].open)(infile, mode, &handle);
+ FFUNLOCK;
+ if (*status > 0)
+ {
+ ffpmsg("failed to find or open the following file: (ffopen)");
+ ffpmsg(url);
+ return(*status);
+ }
+ }
+ else
+ {
+ ffpmsg("cannot open an existing file of this type: (ffopen)");
+ ffpmsg(url);
+ return(*status = FILE_NOT_OPENED);
+ }
+
+ /* get initial file size */
+ *status = (*driverTable[driver].size)(handle, &filesize);
+ if (*status > 0)
+ {
+ (*driverTable[driver].close)(handle); /* close the file */
+ ffpmsg("failed get the size of the following file: (ffopen)");
+ ffpmsg(url);
+ return(*status);
+ }
+
+ /* allocate fitsfile structure and initialize = 0 */
+ *fptr = (fitsfile *) calloc(1, sizeof(fitsfile));
+
+ if (!(*fptr))
+ {
+ (*driverTable[driver].close)(handle); /* close the file */
+ ffpmsg("failed to allocate structure for following file: (ffopen)");
+ ffpmsg(url);
+ return(*status = MEMORY_ALLOCATION);
+ }
+
+ /* allocate FITSfile structure and initialize = 0 */
+ (*fptr)->Fptr = (FITSfile *) calloc(1, sizeof(FITSfile));
+
+ if (!((*fptr)->Fptr))
+ {
+ (*driverTable[driver].close)(handle); /* close the file */
+ ffpmsg("failed to allocate structure for following file: (ffopen)");
+ ffpmsg(url);
+ free(*fptr);
+ *fptr = 0;
+ return(*status = MEMORY_ALLOCATION);
+ }
+
+ slen = strlen(url) + 1;
+ slen = maxvalue(slen, 32); /* reserve at least 32 chars */
+ ((*fptr)->Fptr)->filename = (char *) malloc(slen); /* mem for file name */
+
+ if ( !(((*fptr)->Fptr)->filename) )
+ {
+ (*driverTable[driver].close)(handle); /* close the file */
+ ffpmsg("failed to allocate memory for filename: (ffopen)");
+ ffpmsg(url);
+ free((*fptr)->Fptr);
+ free(*fptr);
+ *fptr = 0; /* return null file pointer */
+ return(*status = MEMORY_ALLOCATION);
+ }
+
+ /* mem for headstart array */
+ ((*fptr)->Fptr)->headstart = (LONGLONG *) calloc(1001, sizeof(LONGLONG));
+
+ if ( !(((*fptr)->Fptr)->headstart) )
+ {
+ (*driverTable[driver].close)(handle); /* close the file */
+ ffpmsg("failed to allocate memory for headstart array: (ffopen)");
+ ffpmsg(url);
+ free( ((*fptr)->Fptr)->filename);
+ free((*fptr)->Fptr);
+ free(*fptr);
+ *fptr = 0; /* return null file pointer */
+ return(*status = MEMORY_ALLOCATION);
+ }
+
+ /* mem for file I/O buffers */
+ ((*fptr)->Fptr)->iobuffer = (char *) calloc(NIOBUF, IOBUFLEN);
+
+ if ( !(((*fptr)->Fptr)->iobuffer) )
+ {
+ (*driverTable[driver].close)(handle); /* close the file */
+ ffpmsg("failed to allocate memory for iobuffer array: (ffopen)");
+ ffpmsg(url);
+ free( ((*fptr)->Fptr)->headstart); /* free memory for headstart array */
+ free( ((*fptr)->Fptr)->filename);
+ free((*fptr)->Fptr);
+ free(*fptr);
+ *fptr = 0; /* return null file pointer */
+ return(*status = MEMORY_ALLOCATION);
+ }
+
+ /* initialize the ageindex array (relative age of the I/O buffers) */
+ /* and initialize the bufrecnum array as being empty */
+ for (ii = 0; ii < NIOBUF; ii++) {
+ ((*fptr)->Fptr)->ageindex[ii] = ii;
+ ((*fptr)->Fptr)->bufrecnum[ii] = -1;
+ }
+
+ /* store the parameters describing the file */
+ ((*fptr)->Fptr)->MAXHDU = 1000; /* initial size of headstart */
+ ((*fptr)->Fptr)->filehandle = handle; /* file handle */
+ ((*fptr)->Fptr)->driver = driver; /* driver number */
+ strcpy(((*fptr)->Fptr)->filename, url); /* full input filename */
+ ((*fptr)->Fptr)->filesize = filesize; /* physical file size */
+ ((*fptr)->Fptr)->logfilesize = filesize; /* logical file size */
+ ((*fptr)->Fptr)->writemode = mode; /* read-write mode */
+ ((*fptr)->Fptr)->datastart = DATA_UNDEFINED; /* unknown start of data */
+ ((*fptr)->Fptr)->curbuf = -1; /* undefined current IO buffer */
+ ((*fptr)->Fptr)->open_count = 1; /* structure is currently used once */
+ ((*fptr)->Fptr)->validcode = VALIDSTRUC; /* flag denoting valid structure */
+ ((*fptr)->Fptr)->only_one = only_one; /* flag denoting only copy single extension */
+
+ ffldrc(*fptr, 0, REPORT_EOF, status); /* load first record */
+
+ fits_store_Fptr( (*fptr)->Fptr, status); /* store Fptr address */
+
+ if (ffrhdu(*fptr, &hdutyp, status) > 0) /* determine HDU structure */
+ {
+ ffpmsg(
+ "ffopen could not interpret primary array header of file: ");
+ ffpmsg(url);
+
+ if (*status == UNKNOWN_REC)
+ ffpmsg("This does not look like a FITS file.");
+
+ ffclos(*fptr, status);
+ *fptr = 0; /* return null file pointer */
+ return(*status);
+ }
+
+ /* ------------------------------------------------------------- */
+ /* At this point, the input file has been opened. If outfile was */
+ /* specified, then we have opened a copy of the file, not the */
+ /* original file so it is safe to modify it if necessary */
+ /* ------------------------------------------------------------- */
+
+ if (*outfile)
+ writecopy = 1;
+
+move2hdu:
+
+ /* ---------------------------------------------------------- */
+ /* move to desired extension, if specified as part of the URL */
+ /* ---------------------------------------------------------- */
+
+ if (*extspec)
+ {
+ if (extnum) /* extension number was specified */
+ {
+ ffmahd(*fptr, extnum + 1, &hdutyp, status);
+ }
+ else if (*extname) /* move to named extension, if specified */
+ {
+ ffmnhd(*fptr, movetotype, extname, extvers, status);
+ }
+
+ if (*status > 0) /* clean up after error */
+ {
+ ffpmsg("ffopen could not move to the specified extension:");
+ if (extnum > 0)
+ {
+ sprintf(errmsg,
+ " extension number %d doesn't exist or couldn't be opened.",extnum);
+ ffpmsg(errmsg);
+ }
+ else
+ {
+ sprintf(errmsg,
+ " extension with EXTNAME = %s,", extname);
+ ffpmsg(errmsg);
+
+ if (extvers)
+ {
+ sprintf(errmsg,
+ " and with EXTVERS = %d,", extvers);
+ ffpmsg(errmsg);
+ }
+
+ if (movetotype != ANY_HDU)
+ {
+ sprintf(errmsg,
+ " and with XTENSION = %s,", hdtype[movetotype]);
+ ffpmsg(errmsg);
+ }
+
+ ffpmsg(" doesn't exist or couldn't be opened.");
+ }
+
+ ffclos(*fptr, status);
+ *fptr = 0; /* return null file pointer */
+ return(*status);
+ }
+ }
+ else if (skip_null || skip_image || skip_table ||
+ (*imagecolname || *colspec || *rowfilter || *binspec))
+ {
+ /* ------------------------------------------------------------------
+
+ If no explicit extension specifier is given as part of the file
+ name, and, if a) skip_null is true (set if ffopen is called by
+ ffdopn) or b) skip_image or skip_table is true (set if ffopen is
+ called by fftopn or ffdopn) or c) other file filters are
+ specified, then CFITSIO will attempt to move to the first
+ 'interesting' HDU after opening an existing FITS file (or to
+ first interesting table HDU if skip_image is true);
+
+ An 'interesting' HDU is defined to be either an image with NAXIS
+ > 0 (i.e., not a null array) or a table which has an EXTNAME
+ value which does not contain any of the following strings:
+ 'GTI' - Good Time Interval extension
+ 'OBSTABLE' - used in Beppo SAX data files
+
+ The main purpose for this is to allow CFITSIO to skip over a null
+ primary and other non-interesting HDUs when opening an existing
+ file, and move directly to the first extension that contains
+ significant data.
+ ------------------------------------------------------------------ */
+
+ fits_get_hdu_num(*fptr, &hdunum);
+ if (hdunum == 1) {
+
+ fits_get_img_dim(*fptr, &naxis, status);
+
+ if (naxis == 0 || skip_image) /* skip primary array */
+ {
+ while(1)
+ {
+ /* see if the next HDU is 'interesting' */
+ if (fits_movrel_hdu(*fptr, 1, &hdutyp, status))
+ {
+ if (*status == END_OF_FILE)
+ *status = 0; /* reset expected error */
+
+ /* didn't find an interesting HDU so move back to beginning */
+ fits_movabs_hdu(*fptr, 1, &hdutyp, status);
+ break;
+ }
+
+ if (hdutyp == IMAGE_HDU && skip_image) {
+
+ continue; /* skip images */
+
+ } else if (hdutyp != IMAGE_HDU && skip_table) {
+
+ continue; /* skip tables */
+
+ } else if (hdutyp == IMAGE_HDU) {
+
+ fits_get_img_dim(*fptr, &naxis, status);
+ if (naxis > 0)
+ break; /* found a non-null image */
+
+ } else {
+
+ tstatus = 0;
+ tblname[0] = '\0';
+ fits_read_key(*fptr, TSTRING, "EXTNAME", tblname, NULL,&tstatus);
+
+ if ( (!strstr(tblname, "GTI") && !strstr(tblname, "gti")) &&
+ strncasecmp(tblname, "OBSTABLE", 8) )
+ break; /* found an interesting table */
+ }
+ } /* end while */
+ }
+ } /* end if (hdunum==1) */
+ }
+
+ if (*imagecolname)
+ {
+ /* ----------------------------------------------------------------- */
+ /* we need to open an image contained in a single table cell */
+ /* First, determine which row of the table to use. */
+ /* ----------------------------------------------------------------- */
+
+ if (isdigit((int) *rowexpress)) /* is the row specification a number? */
+ {
+ sscanf(rowexpress, "%ld", &rownum);
+ if (rownum < 1)
+ {
+ ffpmsg("illegal rownum for image cell:");
+ ffpmsg(rowexpress);
+ ffpmsg("Could not open the following image in a table cell:");
+ ffpmsg(extspec);
+ ffclos(*fptr, status);
+ *fptr = 0; /* return null file pointer */
+ return(*status = BAD_ROW_NUM);
+ }
+ }
+ else if (fits_find_first_row(*fptr, rowexpress, &rownum, status) > 0)
+ {
+ ffpmsg("Failed to find row matching this expression:");
+ ffpmsg(rowexpress);
+ ffpmsg("Could not open the following image in a table cell:");
+ ffpmsg(extspec);
+ ffclos(*fptr, status);
+ *fptr = 0; /* return null file pointer */
+ return(*status);
+ }
+
+ if (rownum == 0)
+ {
+ ffpmsg("row statisfying this expression doesn't exist::");
+ ffpmsg(rowexpress);
+ ffpmsg("Could not open the following image in a table cell:");
+ ffpmsg(extspec);
+ ffclos(*fptr, status);
+ *fptr = 0; /* return null file pointer */
+ return(*status = BAD_ROW_NUM);
+ }
+
+ /* determine the name of the new file to contain copy of the image */
+ if (*histfilename && !(*pixfilter) )
+ strcpy(outfile, histfilename); /* the original outfile name */
+ else
+ strcpy(outfile, "mem://_1"); /* create image file in memory */
+
+ /* Copy the image into new primary array and open it as the current */
+ /* fptr. This will close the table that contains the original image. */
+
+ /* create new empty file to hold copy of the image */
+ if (ffinit(&newptr, outfile, status) > 0)
+ {
+ ffpmsg("failed to create file for copy of image in table cell:");
+ ffpmsg(outfile);
+ return(*status);
+ }
+
+ if (fits_copy_cell2image(*fptr, newptr, imagecolname, rownum,
+ status) > 0)
+ {
+ ffpmsg("Failed to copy table cell to new primary array:");
+ ffpmsg(extspec);
+ ffclos(*fptr, status);
+ *fptr = 0; /* return null file pointer */
+ return(*status);
+ }
+
+ /* close the original file and set fptr to the new image */
+ ffclos(*fptr, status);
+
+ *fptr = newptr; /* reset the pointer to the new table */
+
+ writecopy = 1; /* we are now dealing with a copy of the original file */
+
+ /* add some HISTORY; fits_copy_image_cell also wrote HISTORY keywords */
+
+/* disable this; leave it up to calling routine to write any HISTORY keywords
+ if (*extname)
+ sprintf(card,"HISTORY in HDU '%.16s' of file '%.36s'",extname,infile);
+ else
+ sprintf(card,"HISTORY in HDU %d of file '%.45s'", extnum, infile);
+
+ ffprec(*fptr, card, status);
+*/
+ }
+
+ /* --------------------------------------------------------------------- */
+ /* edit columns (and/or keywords) in the table, if specified in the URL */
+ /* --------------------------------------------------------------------- */
+
+ if (*colspec)
+ {
+ /* the column specifier will modify the file, so make sure */
+ /* we are already dealing with a copy, or else make a new copy */
+
+ if (!writecopy) /* Is the current file already a copy? */
+ writecopy = fits_is_this_a_copy(urltype);
+
+ if (!writecopy)
+ {
+ if (*filtfilename && *outfile == '\0')
+ strcpy(outfile, filtfilename); /* the original outfile name */
+ else
+ strcpy(outfile, "mem://_1"); /* will create copy in memory */
+
+ writecopy = 1;
+ }
+ else
+ {
+ ((*fptr)->Fptr)->writemode = READWRITE; /* we have write access */
+ outfile[0] = '\0';
+ }
+
+ if (ffedit_columns(fptr, outfile, colspec, status) > 0)
+ {
+ ffpmsg("editing columns in input table failed (ffopen)");
+ ffpmsg(" while trying to perform the following operation:");
+ ffpmsg(colspec);
+ ffclos(*fptr, status);
+ *fptr = 0; /* return null file pointer */
+ return(*status);
+ }
+ }
+
+ /* ------------------------------------------------------------------- */
+ /* select rows from the table, if specified in the URL */
+ /* or select a subimage (if this is an image HDU and not a table) */
+ /* ------------------------------------------------------------------- */
+
+ if (*rowfilter)
+ {
+ fits_get_hdu_type(*fptr, &hdutyp, status); /* get type of HDU */
+ if (hdutyp == IMAGE_HDU)
+ {
+ /* this is an image so 'rowfilter' is an image section specification */
+
+ if (*filtfilename && *outfile == '\0')
+ strcpy(outfile, filtfilename); /* the original outfile name */
+ else if (*outfile == '\0') /* output file name not already defined? */
+ strcpy(outfile, "mem://_2"); /* will create file in memory */
+
+ /* create new file containing the image section, plus a copy of */
+ /* any other HDUs that exist in the input file. This routine */
+ /* will close the original image file and return a pointer */
+ /* to the new file. */
+
+ if (fits_select_image_section(fptr, outfile, rowfilter, status) > 0)
+ {
+ ffpmsg("on-the-fly selection of image section failed (ffopen)");
+ ffpmsg(" while trying to use the following section filter:");
+ ffpmsg(rowfilter);
+ ffclos(*fptr, status);
+ *fptr = 0; /* return null file pointer */
+ return(*status);
+ }
+ }
+ else
+ {
+ /* this is a table HDU, so the rowfilter is really a row filter */
+
+ if (*binspec)
+ {
+ /* since we are going to make a histogram of the selected rows, */
+ /* it would be a waste of time and memory to make a whole copy of */
+ /* the selected rows. Instead, just construct an array of TRUE */
+ /* or FALSE values that indicate which rows are to be included */
+ /* in the histogram and pass that to the histogram generating */
+ /* routine */
+
+ fits_get_num_rows(*fptr, &nrows, status); /* get no. of rows */
+
+ rowselect = (char *) calloc(nrows, 1);
+ if (!rowselect)
+ {
+ ffpmsg(
+ "failed to allocate memory for selected columns array (ffopen)");
+ ffpmsg(" while trying to select rows with the following filter:");
+ ffpmsg(rowfilter);
+ ffclos(*fptr, status);
+ *fptr = 0; /* return null file pointer */
+ return(*status = MEMORY_ALLOCATION);
+ }
+
+ if (fits_find_rows(*fptr, rowfilter, 1L, nrows, &goodrows,
+ rowselect, status) > 0)
+ {
+ ffpmsg("selection of rows in input table failed (ffopen)");
+ ffpmsg(" while trying to select rows with the following filter:");
+ ffpmsg(rowfilter);
+ free(rowselect);
+ ffclos(*fptr, status);
+ *fptr = 0; /* return null file pointer */
+ return(*status);
+ }
+ }
+ else
+ {
+ if (!writecopy) /* Is the current file already a copy? */
+ writecopy = fits_is_this_a_copy(urltype);
+
+ if (!writecopy)
+ {
+ if (*filtfilename && *outfile == '\0')
+ strcpy(outfile, filtfilename); /* the original outfile name */
+ else if (*outfile == '\0') /* output filename not already defined? */
+ strcpy(outfile, "mem://_2"); /* will create copy in memory */
+ }
+ else
+ {
+ ((*fptr)->Fptr)->writemode = READWRITE; /* we have write access */
+ outfile[0] = '\0';
+ }
+
+ /* select rows in the table. If a copy of the input file has */
+ /* not already been made, then this routine will make a copy */
+ /* and then close the input file, so that the modifications will */
+ /* only be made on the copy, not the original */
+
+ if (ffselect_table(fptr, outfile, rowfilter, status) > 0)
+ {
+ ffpmsg("on-the-fly selection of rows in input table failed (ffopen)");
+ ffpmsg(" while trying to select rows with the following filter:");
+ ffpmsg(rowfilter);
+ ffclos(*fptr, status);
+ *fptr = 0; /* return null file pointer */
+ return(*status);
+ }
+
+ /* write history records */
+ ffphis(*fptr,
+ "CFITSIO used the following filtering expression to create this table:",
+ status);
+ ffphis(*fptr, name, status);
+
+ } /* end of no binspec case */
+ } /* end of table HDU case */
+ } /* end of rowfilter exists case */
+
+ /* ------------------------------------------------------------------- */
+ /* make an image histogram by binning columns, if specified in the URL */
+ /* ------------------------------------------------------------------- */
+
+ if (*binspec)
+ {
+ if (*histfilename && !(*pixfilter) )
+ strcpy(outfile, histfilename); /* the original outfile name */
+ else
+ strcpy(outfile, "mem://_3"); /* create histogram in memory */
+ /* if not already copied the file */
+
+ /* parse the binning specifier into individual parameters */
+ ffbins(binspec, &imagetype, &haxis, colname,
+ minin, maxin, binsizein,
+ minname, maxname, binname,
+ &weight, wtcol, &recip, status);
+
+ /* Create the histogram primary array and open it as the current fptr */
+ /* This will close the table that was used to create the histogram. */
+ ffhist2(fptr, outfile, imagetype, haxis, colname, minin, maxin,
+ binsizein, minname, maxname, binname,
+ weight, wtcol, recip, rowselect, status);
+
+ if (rowselect)
+ free(rowselect);
+
+ if (*status > 0)
+ {
+ ffpmsg("on-the-fly histogramming of input table failed (ffopen)");
+ ffpmsg(" while trying to execute the following histogram specification:");
+ ffpmsg(binspec);
+ ffclos(*fptr, status);
+ *fptr = 0; /* return null file pointer */
+ return(*status);
+ }
+
+ /* write history records */
+ ffphis(*fptr,
+ "CFITSIO used the following expression to create this histogram:",
+ status);
+ ffphis(*fptr, name, status);
+ }
+
+ if (*pixfilter)
+ {
+ if (*histfilename)
+ strcpy(outfile, histfilename); /* the original outfile name */
+ else
+ strcpy(outfile, "mem://_4"); /* create in memory */
+ /* if not already copied the file */
+
+ /* Ensure type of HDU is consistent with pixel filtering */
+ fits_get_hdu_type(*fptr, &hdutyp, status); /* get type of HDU */
+ if (hdutyp == IMAGE_HDU) {
+
+ pixel_filter_helper(fptr, outfile, pixfilter, status);
+
+ if (*status > 0) {
+ ffpmsg("pixel filtering of input image failed (ffopen)");
+ ffpmsg(" while trying to execute the following:");
+ ffpmsg(pixfilter);
+ ffclos(*fptr, status);
+ *fptr = 0; /* return null file pointer */
+ return(*status);
+ }
+
+ /* write history records */
+ ffphis(*fptr,
+ "CFITSIO used the following expression to create this image:",
+ status);
+ ffphis(*fptr, name, status);
+ }
+ else
+ {
+ ffpmsg("cannot use pixel filter on non-IMAGE HDU");
+ ffpmsg(pixfilter);
+ ffclos(*fptr, status);
+ *fptr = 0; /* return null file pointer */
+ *status = NOT_IMAGE;
+ return(*status);
+ }
+ }
+
+ /* parse and save image compression specification, if given */
+ if (*compspec) {
+ ffparsecompspec(*fptr, compspec, status);
+ }
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffreopen(fitsfile *openfptr, /* I - FITS file pointer to open file */
+ fitsfile **newfptr, /* O - pointer to new re opened file */
+ int *status) /* IO - error status */
+/*
+ Reopen an existing FITS file with either readonly or read/write access.
+ The reopened file shares the same FITSfile structure but may point to a
+ different HDU within the file.
+*/
+{
+ if (*status > 0)
+ return(*status);
+
+ /* check that the open file pointer is valid */
+ if (!openfptr)
+ return(*status = NULL_INPUT_PTR);
+ else if ((openfptr->Fptr)->validcode != VALIDSTRUC) /* check magic value */
+ return(*status = BAD_FILEPTR);
+
+ /* allocate fitsfile structure and initialize = 0 */
+ *newfptr = (fitsfile *) calloc(1, sizeof(fitsfile));
+
+ (*newfptr)->Fptr = openfptr->Fptr; /* both point to the same structure */
+ (*newfptr)->HDUposition = 0; /* set initial position to primary array */
+ (((*newfptr)->Fptr)->open_count)++; /* increment the file usage counter */
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int fits_store_Fptr(FITSfile *Fptr, /* O - FITS file pointer */
+ int *status) /* IO - error status */
+/*
+ store the new Fptr address for future use by fits_already_open
+*/
+{
+ int ii;
+
+ if (*status > 0)
+ return(*status);
+
+ FFLOCK;
+ for (ii = 0; ii < NMAXFILES; ii++) {
+ if (FptrTable[ii] == 0) {
+ FptrTable[ii] = Fptr;
+ break;
+ }
+ }
+ FFUNLOCK;
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int fits_clear_Fptr(FITSfile *Fptr, /* O - FITS file pointer */
+ int *status) /* IO - error status */
+/*
+ clear the Fptr address from the Fptr Table
+*/
+{
+ int ii;
+
+ FFLOCK;
+ for (ii = 0; ii < NMAXFILES; ii++) {
+ if (FptrTable[ii] == Fptr) {
+ FptrTable[ii] = 0;
+ break;
+ }
+ }
+ FFUNLOCK;
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int fits_already_open(fitsfile **fptr, /* I/O - FITS file pointer */
+ char *url,
+ char *urltype,
+ char *infile,
+ char *extspec,
+ char *rowfilter,
+ char *binspec,
+ char *colspec,
+ int mode, /* I - 0 = open readonly; 1 = read/write */
+ int *isopen, /* O - 1 = file is already open */
+ int *status) /* IO - error status */
+/*
+ Check if the file to be opened is already open. If so, then attach to it.
+*/
+
+ /* the input strings must not exceed the standard lengths */
+ /* of FLEN_FILENAME, MAX_PREFIX_LEN, etc. */
+
+ /*
+ this function was changed so that for files of access method FILE://
+ the file paths are compared using standard URL syntax and absolute
+ paths (as opposed to relative paths). This eliminates some instances
+ where a file is already opened but it is not realized because it
+ was opened with another file path. For instance, if the CWD is
+ /a/b/c and I open /a/b/c/foo.fits then open ./foo.fits the previous
+ version of this function would not have reconized that the two files
+ were the same. This version does recognize that the two files are
+ the same.
+ */
+{
+ FITSfile *oldFptr;
+ int ii;
+ char oldurltype[MAX_PREFIX_LEN], oldinfile[FLEN_FILENAME];
+ char oldextspec[FLEN_FILENAME], oldoutfile[FLEN_FILENAME];
+ char oldrowfilter[FLEN_FILENAME];
+ char oldbinspec[FLEN_FILENAME], oldcolspec[FLEN_FILENAME];
+ char cwd[FLEN_FILENAME];
+ char tmpStr[FLEN_FILENAME];
+ char tmpinfile[FLEN_FILENAME];
+
+ *isopen = 0;
+
+/* When opening a file with readonly access then we simply let
+ the operating system open the file again, instead of using the CFITSIO
+ trick of attaching to the previously opened file. This is required
+ if CFITSIO is running in a multi-threaded environment, because 2 different
+ threads cannot share the same FITSfile pointer.
+
+ If the file is opened/reopened with write access, then the file MUST
+ only be physically opened once..
+*/
+ if (mode == 0)
+ return(*status);
+
+ if(strcasecmp(urltype,"FILE://") == 0)
+ {
+ fits_path2url(infile,tmpinfile,status);
+
+ if(tmpinfile[0] != '/')
+ {
+ fits_get_cwd(cwd,status);
+ strcat(cwd,"/");
+
+ if (strlen(cwd) + strlen(tmpinfile) > FLEN_FILENAME-1) {
+ ffpmsg("File name is too long. (fits_already_open)");
+ return(*status = FILE_NOT_OPENED);
+ }
+
+ strcat(cwd,tmpinfile);
+ fits_clean_url(cwd,tmpinfile,status);
+ }
+ }
+ else
+ strcpy(tmpinfile,infile);
+
+ for (ii = 0; ii < NMAXFILES; ii++) /* check every buffer */
+ {
+ if (FptrTable[ii] != 0)
+ {
+ oldFptr = FptrTable[ii];
+
+ fits_parse_input_url(oldFptr->filename, oldurltype,
+ oldinfile, oldoutfile, oldextspec, oldrowfilter,
+ oldbinspec, oldcolspec, status);
+
+ if (*status > 0)
+ {
+ ffpmsg("could not parse the previously opened filename: (ffopen)");
+ ffpmsg(oldFptr->filename);
+ return(*status);
+ }
+
+ if(strcasecmp(oldurltype,"FILE://") == 0)
+ {
+ fits_path2url(oldinfile,tmpStr,status);
+
+ if(tmpStr[0] != '/')
+ {
+ fits_get_cwd(cwd,status);
+ strcat(cwd,"/");
+
+
+ strcat(cwd,tmpStr);
+ fits_clean_url(cwd,tmpStr,status);
+ }
+
+ strcpy(oldinfile,tmpStr);
+ }
+
+ if (!strcmp(urltype, oldurltype) && !strcmp(tmpinfile, oldinfile) )
+ {
+ /* identical type of file and root file name */
+
+ if ( (!rowfilter[0] && !oldrowfilter[0] &&
+ !binspec[0] && !oldbinspec[0] &&
+ !colspec[0] && !oldcolspec[0])
+
+ /* no filtering or binning specs for either file, so */
+ /* this is a case where the same file is being reopened. */
+ /* It doesn't matter if the extensions are different */
+
+ || /* or */
+
+ (!strcmp(rowfilter, oldrowfilter) &&
+ !strcmp(binspec, oldbinspec) &&
+ !strcmp(colspec, oldcolspec) &&
+ !strcmp(extspec, oldextspec) ) )
+
+ /* filtering specs are given and are identical, and */
+ /* the same extension is specified */
+
+ {
+ if (mode == READWRITE && oldFptr->writemode == READONLY)
+ {
+ /*
+ cannot assume that a file previously opened with READONLY
+ can now be written to (e.g., files on CDROM, or over the
+ the network, or STDIN), so return with an error.
+ */
+
+ ffpmsg(
+ "cannot reopen file READWRITE when previously opened READONLY");
+ ffpmsg(url);
+ return(*status = FILE_NOT_OPENED);
+ }
+
+ *fptr = (fitsfile *) calloc(1, sizeof(fitsfile));
+
+ if (!(*fptr))
+ {
+ ffpmsg(
+ "failed to allocate structure for following file: (ffopen)");
+ ffpmsg(url);
+ return(*status = MEMORY_ALLOCATION);
+ }
+
+ (*fptr)->Fptr = oldFptr; /* point to the structure */
+ (*fptr)->HDUposition = 0; /* set initial position */
+ (((*fptr)->Fptr)->open_count)++; /* increment usage counter */
+
+ if (binspec[0]) /* if binning specified, don't move */
+ extspec[0] = '\0';
+
+ /* all the filtering has already been applied, so ignore */
+ rowfilter[0] = '\0';
+ binspec[0] = '\0';
+ colspec[0] = '\0';
+
+ *isopen = 1;
+ }
+ }
+ }
+ }
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int fits_is_this_a_copy(char *urltype) /* I - type of file */
+/*
+ specialized routine that returns 1 if the file is known to be a temporary
+ copy of the originally opened file. Otherwise it returns 0.
+*/
+{
+ int iscopy;
+
+ if (!strncmp(urltype, "mem", 3) )
+ iscopy = 1; /* file copy is in memory */
+ else if (!strncmp(urltype, "compress", 8) )
+ iscopy = 1; /* compressed diskfile that is uncompressed in memory */
+ else if (!strncmp(urltype, "http", 4) )
+ iscopy = 1; /* copied file using http protocol */
+ else if (!strncmp(urltype, "ftp", 3) )
+ iscopy = 1; /* copied file using ftp protocol */
+ else if (!strncmp(urltype, "gsiftp", 6) )
+ iscopy = 1; /* copied file using gsiftp protocol */
+ else if (!strncpy(urltype, "stdin", 5) )
+ iscopy = 1; /* piped stdin has been copied to memory */
+ else
+ iscopy = 0; /* file is not known to be a copy */
+
+ return(iscopy);
+}
+/*--------------------------------------------------------------------------*/
+static int find_quote(char **string)
+
+/*
+ look for the closing single quote character in the input string
+*/
+{
+ char *tstr;
+
+ tstr = *string;
+
+ while (*tstr) {
+ if (*tstr == '\'') { /* found the closing quote */
+ *string = tstr + 1; /* set pointer to next char */
+ return(0);
+ } else { /* skip over any other character */
+ tstr++;
+ }
+ }
+ return(1); /* opps, didn't find the closing character */
+}
+/*--------------------------------------------------------------------------*/
+static int find_doublequote(char **string)
+
+/*
+ look for the closing double quote character in the input string
+*/
+{
+ char *tstr;
+
+ tstr = *string;
+
+ while (*tstr) {
+ if (*tstr == '"') { /* found the closing quote */
+ *string = tstr + 1; /* set pointer to next char */
+ return(0);
+ } else { /* skip over any other character */
+ tstr++;
+ }
+ }
+ return(1); /* opps, didn't find the closing character */
+}
+
+/*--------------------------------------------------------------------------*/
+static int find_paren(char **string)
+
+/*
+ look for the closing parenthesis character in the input string
+*/
+{
+ char *tstr;
+
+ tstr = *string;
+
+ while (*tstr) {
+
+ if (*tstr == ')') { /* found the closing parens */
+ *string = tstr + 1; /* set pointer to next char */
+ return(0);
+ } else if (*tstr == '(') { /* found another level of parens */
+ tstr++;
+ if (find_paren(&tstr)) return(1);
+ } else if (*tstr == '[') {
+ tstr++;
+ if (find_bracket(&tstr)) return(1);
+ } else if (*tstr == '{') {
+ tstr++;
+ if (find_curlybracket(&tstr)) return(1);
+ } else if (*tstr == '"') {
+ tstr++;
+ if (find_doublequote(&tstr)) return(1);
+ } else if (*tstr == '\'') {
+ tstr++;
+ if (find_quote(&tstr)) return(1);
+ } else {
+ tstr++;
+ }
+ }
+ return(1); /* opps, didn't find the closing character */
+}
+/*--------------------------------------------------------------------------*/
+static int find_bracket(char **string)
+
+/*
+ look for the closing bracket character in the input string
+*/
+{
+ char *tstr;
+
+ tstr = *string;
+
+ while (*tstr) {
+ if (*tstr == ']') { /* found the closing bracket */
+ *string = tstr + 1; /* set pointer to next char */
+ return(0);
+ } else if (*tstr == '(') { /* found another level of parens */
+ tstr++;
+ if (find_paren(&tstr)) return(1);
+ } else if (*tstr == '[') {
+ tstr++;
+ if (find_bracket(&tstr)) return(1);
+ } else if (*tstr == '{') {
+ tstr++;
+ if (find_curlybracket(&tstr)) return(1);
+ } else if (*tstr == '"') {
+ tstr++;
+ if (find_doublequote(&tstr)) return(1);
+ } else if (*tstr == '\'') {
+ tstr++;
+ if (find_quote(&tstr)) return(1);
+ } else {
+ tstr++;
+ }
+ }
+ return(1); /* opps, didn't find the closing character */
+}
+/*--------------------------------------------------------------------------*/
+static int find_curlybracket(char **string)
+
+/*
+ look for the closing curly bracket character in the input string
+*/
+{
+ char *tstr;
+
+ tstr = *string;
+
+ while (*tstr) {
+ if (*tstr == '}') { /* found the closing curly bracket */
+ *string = tstr + 1; /* set pointer to next char */
+ return(0);
+ } else if (*tstr == '(') { /* found another level of parens */
+ tstr++;
+ if (find_paren(&tstr)) return(1);
+ } else if (*tstr == '[') {
+ tstr++;
+ if (find_bracket(&tstr)) return(1);
+ } else if (*tstr == '{') {
+ tstr++;
+ if (find_curlybracket(&tstr)) return(1);
+ } else if (*tstr == '"') {
+ tstr++;
+ if (find_doublequote(&tstr)) return(1);
+ } else if (*tstr == '\'') {
+ tstr++;
+ if (find_quote(&tstr)) return(1);
+ } else {
+ tstr++;
+ }
+ }
+ return(1); /* opps, didn't find the closing character */
+}
+/*--------------------------------------------------------------------------*/
+int comma2semicolon(char *string)
+
+/*
+ replace commas with semicolons, unless the comma is within a quoted or bracketed expression
+*/
+{
+ char *tstr;
+
+ tstr = string;
+
+ while (*tstr) {
+
+ if (*tstr == ',') { /* found a comma */
+ *tstr = ';';
+ tstr++;
+ } else if (*tstr == '(') { /* found another level of parens */
+ tstr++;
+ if (find_paren(&tstr)) return(1);
+ } else if (*tstr == '[') {
+ tstr++;
+ if (find_bracket(&tstr)) return(1);
+ } else if (*tstr == '{') {
+ tstr++;
+ if (find_curlybracket(&tstr)) return(1);
+ } else if (*tstr == '"') {
+ tstr++;
+ if (find_doublequote(&tstr)) return(1);
+ } else if (*tstr == '\'') {
+ tstr++;
+ if (find_quote(&tstr)) return(1);
+ } else {
+ tstr++;
+ }
+ }
+ return(0); /* reached end of string */
+}
+/*--------------------------------------------------------------------------*/
+int ffedit_columns(
+ fitsfile **fptr, /* IO - pointer to input table; on output it */
+ /* points to the new selected rows table */
+ char *outfile, /* I - name for output file */
+ char *expr, /* I - column edit expression */
+ int *status)
+/*
+ modify columns in a table and/or header keywords in the HDU
+*/
+{
+ fitsfile *newptr;
+ int ii, hdunum, slen, colnum = -1, testnum, deletecol = 0, savecol = 0;
+ int numcols = 0, *colindex = 0, tstatus = 0;
+ char *cptr, *cptr2, *cptr3, *clause = NULL, keyname[FLEN_KEYWORD];
+ char colname[FLEN_VALUE], oldname[FLEN_VALUE], colformat[FLEN_VALUE];
+ char *file_expr = NULL, testname[FLEN_VALUE], card[FLEN_CARD];
+
+ if (*outfile)
+ {
+ /* create new empty file in to hold the selected rows */
+ if (ffinit(&newptr, outfile, status) > 0)
+ {
+ ffpmsg("failed to create file for copy (ffedit_columns)");
+ return(*status);
+ }
+
+ fits_get_hdu_num(*fptr, &hdunum); /* current HDU number in input file */
+
+ /* copy all HDUs to the output copy, if the 'only_one' flag is not set */
+ if (!((*fptr)->Fptr)->only_one) {
+ for (ii = 1; 1; ii++)
+ {
+ if (fits_movabs_hdu(*fptr, ii, NULL, status) > 0)
+ break;
+
+ fits_copy_hdu(*fptr, newptr, 0, status);
+ }
+
+ if (*status == END_OF_FILE)
+ {
+ *status = 0; /* got the expected EOF error; reset = 0 */
+ }
+ else if (*status > 0)
+ {
+ ffclos(newptr, status);
+ ffpmsg("failed to copy all HDUs from input file (ffedit_columns)");
+ return(*status);
+ }
+
+
+ } else {
+ /* only copy the primary array and the designated table extension */
+ fits_movabs_hdu(*fptr, 1, NULL, status);
+ fits_copy_hdu(*fptr, newptr, 0, status);
+ fits_movabs_hdu(*fptr, hdunum, NULL, status);
+ fits_copy_hdu(*fptr, newptr, 0, status);
+ if (*status > 0)
+ {
+ ffclos(newptr, status);
+ ffpmsg("failed to copy all HDUs from input file (ffedit_columns)");
+ return(*status);
+ }
+ hdunum = 2;
+ }
+
+ /* close the original file and return ptr to the new image */
+ ffclos(*fptr, status);
+
+ *fptr = newptr; /* reset the pointer to the new table */
+
+ /* move back to the selected table HDU */
+ if (fits_movabs_hdu(*fptr, hdunum, NULL, status) > 0)
+ {
+ ffpmsg("failed to copy the input file (ffedit_columns)");
+ return(*status);
+ }
+ }
+
+ /* remove the "col " from the beginning of the column edit expression */
+ cptr = expr + 4;
+
+ while (*cptr == ' ')
+ cptr++; /* skip leading white space */
+
+ /* Check if need to import expression from a file */
+
+ if( *cptr=='@' ) {
+ if( ffimport_file( cptr+1, &file_expr, status ) ) return(*status);
+ cptr = file_expr;
+ while (*cptr == ' ')
+ cptr++; /* skip leading white space... again */
+ }
+
+ tstatus = 0;
+ ffgncl(*fptr, &numcols, &tstatus); /* get initial # of cols */
+
+ /* as of July 2012, the CFITSIO column filter syntax was modified */
+ /* so that commas may be used to separate clauses, as well as semi-colons. */
+ /* This was done because users cannot enter the semi-colon in the HEASARC's */
+ /* Hera on-line data processing system for computer security reasons. */
+ /* Therefore, we must convert those commas back to semi-colons here, but we */
+ /* must not convert any columns that occur within parenthesies. */
+
+ if (comma2semicolon(cptr)) {
+ ffpmsg("parsing error in column filter expression");
+ ffpmsg(cptr);
+ if( file_expr ) free( file_expr );
+ *status = PARSE_SYNTAX_ERR;
+ return(*status);
+ }
+
+ /* parse expression and get first clause, if more than 1 */
+ while ((slen = fits_get_token2(&cptr, ";", &clause, NULL, status)) > 0 )
+ {
+ if( *cptr==';' ) cptr++;
+ clause[slen] = '\0';
+
+ if (clause[0] == '!' || clause[0] == '-')
+ {
+ /* ===================================== */
+ /* Case I. delete this column or keyword */
+ /* ===================================== */
+
+ if (ffgcno(*fptr, CASEINSEN, &clause[1], &colnum, status) <= 0)
+ {
+ /* a column with this name exists, so try to delete it */
+ if (ffdcol(*fptr, colnum, status) > 0)
+ {
+ ffpmsg("failed to delete column in input file:");
+ ffpmsg(clause);
+ if( colindex ) free( colindex );
+ if( file_expr ) free( file_expr );
+ if( clause ) free(clause);
+ return(*status);
+ }
+ deletecol = 1; /* set flag that at least one col was deleted */
+ numcols--;
+ colnum = -1;
+ }
+ else
+ {
+ ffcmsg(); /* clear previous error message from ffgcno */
+ /* try deleting a keyword with this name */
+ *status = 0;
+ if (ffdkey(*fptr, &clause[1], status) > 0)
+ {
+ ffpmsg("column or keyword to be deleted does not exist:");
+ ffpmsg(clause);
+ if( colindex ) free( colindex );
+ if( file_expr ) free( file_expr );
+ if( clause ) free(clause);
+ return(*status);
+ }
+ }
+ }
+ else
+ {
+ /* ===================================================== */
+ /* Case II:
+ this is either a column name, (case 1)
+
+ or a new column name followed by double = ("==") followed
+ by the old name which is to be renamed. (case 2A)
+
+ or a column or keyword name followed by a single "=" and a
+ calculation expression (case 2B) */
+ /* ===================================================== */
+ cptr2 = clause;
+ slen = fits_get_token(&cptr2, "( =", colname, NULL);
+
+ if (slen == 0)
+ {
+ ffpmsg("error: column or keyword name is blank:");
+ ffpmsg(clause);
+ if( colindex ) free( colindex );
+ if( file_expr ) free( file_expr );
+ if (clause) free(clause);
+ return(*status= URL_PARSE_ERROR);
+ }
+
+ /* If this is a keyword of the form
+ #KEYWORD#
+ then transform to the form
+ #KEYWORDn
+ where n is the previously used column number
+ */
+ if (colname[0] == '#' &&
+ strstr(colname+1, "#") == (colname + strlen(colname) - 1))
+ {
+ if (colnum <= 0)
+ {
+ ffpmsg("The keyword name:");
+ ffpmsg(colname);
+ ffpmsg("is invalid unless a column has been previously");
+ ffpmsg("created or editted by a calculator command");
+ if( file_expr ) free( file_expr );
+ if (clause) free(clause);
+ return(*status = URL_PARSE_ERROR);
+ }
+ colname[strlen(colname)-1] = '\0';
+ /* Make keyword name and put it in oldname */
+ ffkeyn(colname+1, colnum, oldname, status);
+ if (*status) return (*status);
+ /* Re-copy back into colname */
+ strcpy(colname+1,oldname);
+ }
+ else if (strstr(colname, "#") == (colname + strlen(colname) - 1))
+ {
+ /* colname is of the form "NAME#"; if
+ a) colnum is defined, and
+ b) a column with literal name "NAME#" does not exist, and
+ c) a keyword with name "NAMEn" (where n=colnum) exists, then
+ transfrom the colname string to "NAMEn", otherwise
+ do nothing.
+ */
+ if (colnum > 0) { /* colnum must be defined */
+ tstatus = 0;
+ ffgcno(*fptr, CASEINSEN, colname, &testnum, &tstatus);
+ if (tstatus != 0 && tstatus != COL_NOT_UNIQUE)
+ {
+ /* OK, column doesn't exist, now see if keyword exists */
+ ffcmsg(); /* clear previous error message from ffgcno */
+ strcpy(testname, colname);
+ testname[strlen(testname)-1] = '\0';
+ /* Make keyword name and put it in oldname */
+ ffkeyn(testname, colnum, oldname, status);
+ if (*status) {
+ if( file_expr ) free( file_expr );
+ if (clause) free(clause);
+ return (*status);
+ }
+
+ tstatus = 0;
+ if (!fits_read_card(*fptr, oldname, card, &tstatus)) {
+ /* Keyword does exist; copy real name back into colname */
+ strcpy(colname,oldname);
+ }
+ }
+ }
+ }
+
+ /* if we encountered an opening parenthesis, then we need to */
+ /* find the closing parenthesis, and concatinate the 2 strings */
+ /* This supports expressions like:
+ [col #EXTNAME(Extension name)="GTI"]
+ */
+ if (*cptr2 == '(')
+ {
+ fits_get_token(&cptr2, ")", oldname, NULL);
+ strcat(colname, oldname);
+ strcat(colname, ")");
+ cptr2++;
+ }
+
+ while (*cptr2 == ' ')
+ cptr2++; /* skip white space */
+
+ if (*cptr2 != '=')
+ {
+ /* ------------------------------------ */
+ /* case 1 - simply the name of a column */
+ /* ------------------------------------ */
+
+ /* look for matching column */
+ ffgcno(*fptr, CASEINSEN, colname, &testnum, status);
+
+ while (*status == COL_NOT_UNIQUE)
+ {
+ /* the column name contained wild cards, and it */
+ /* matches more than one column in the table. */
+
+ colnum = testnum;
+
+ /* keep this column in the output file */
+ savecol = 1;
+
+ if (!colindex)
+ colindex = (int *) calloc(999, sizeof(int));
+
+ colindex[colnum - 1] = 1; /* flag this column number */
+
+ /* look for other matching column names */
+ ffgcno(*fptr, CASEINSEN, colname, &testnum, status);
+
+ if (*status == COL_NOT_FOUND)
+ *status = 999; /* temporary status flag value */
+ }
+
+ if (*status <= 0)
+ {
+ colnum = testnum;
+
+ /* keep this column in the output file */
+ savecol = 1;
+
+ if (!colindex)
+ colindex = (int *) calloc(999, sizeof(int));
+
+ colindex[colnum - 1] = 1; /* flag this column number */
+ }
+ else if (*status == 999)
+ {
+ /* this special flag value does not represent an error */
+ *status = 0;
+ }
+ else
+ {
+ ffpmsg("Syntax error in columns specifier in input URL:");
+ ffpmsg(cptr2);
+ if( colindex ) free( colindex );
+ if( file_expr ) free( file_expr );
+ if (clause) free(clause);
+ return(*status = URL_PARSE_ERROR);
+ }
+ }
+ else
+ {
+ /* ----------------------------------------------- */
+ /* case 2 where the token ends with an equals sign */
+ /* ----------------------------------------------- */
+
+ cptr2++; /* skip over the first '=' */
+
+ if (*cptr2 == '=')
+ {
+ /*................................................. */
+ /* Case A: rename a column or keyword; syntax is
+ "new_name == old_name" */
+ /*................................................. */
+
+ cptr2++; /* skip the 2nd '=' */
+ while (*cptr2 == ' ')
+ cptr2++; /* skip white space */
+
+ fits_get_token(&cptr2, " ", oldname, NULL);
+
+ /* get column number of the existing column */
+ if (ffgcno(*fptr, CASEINSEN, oldname, &colnum, status) <= 0)
+ {
+ /* modify the TTYPEn keyword value with the new name */
+ ffkeyn("TTYPE", colnum, keyname, status);
+
+ if (ffmkys(*fptr, keyname, colname, NULL, status) > 0)
+ {
+ ffpmsg("failed to rename column in input file");
+ ffpmsg(" oldname =");
+ ffpmsg(oldname);
+ ffpmsg(" newname =");
+ ffpmsg(colname);
+ if( colindex ) free( colindex );
+ if( file_expr ) free( file_expr );
+ if (clause) free(clause);
+ return(*status);
+ }
+ /* keep this column in the output file */
+ savecol = 1;
+ if (!colindex)
+ colindex = (int *) calloc(999, sizeof(int));
+
+ colindex[colnum - 1] = 1; /* flag this column number */
+ }
+ else
+ {
+ /* try renaming a keyword */
+ ffcmsg(); /* clear error message stack */
+ *status = 0;
+ if (ffmnam(*fptr, oldname, colname, status) > 0)
+ {
+ ffpmsg("column or keyword to be renamed does not exist:");
+ ffpmsg(clause);
+ if( colindex ) free( colindex );
+ if( file_expr ) free( file_expr );
+ if (clause) free(clause);
+ return(*status);
+ }
+ }
+ }
+ else
+ {
+ /*...................................................... */
+ /* Case B: */
+ /* this must be a general column/keyword calc expression */
+ /* "name = expression" or "colname(TFORM) = expression" */
+ /*...................................................... */
+
+ /* parse the name and TFORM values, if present */
+ colformat[0] = '\0';
+ cptr3 = colname;
+
+ fits_get_token(&cptr3, "(", oldname, NULL);
+
+ if (cptr3[0] == '(' )
+ {
+ cptr3++; /* skip the '(' */
+ fits_get_token(&cptr3, ")", colformat, NULL);
+ }
+
+ /* calculate values for the column or keyword */
+ /* cptr2 = the expression to be calculated */
+ /* oldname = name of the column or keyword */
+ /* colformat = column format, or keyword comment string */
+ if (fits_calculator(*fptr, cptr2, *fptr, oldname, colformat,
+ status) > 0) {
+
+ ffpmsg("Unable to calculate expression");
+ if( colindex ) free( colindex );
+ if( file_expr ) free( file_expr );
+ if (clause) free(clause);
+ return(*status);
+ }
+
+ /* test if this is a column and not a keyword */
+ tstatus = 0;
+ ffgcno(*fptr, CASEINSEN, oldname, &testnum, &tstatus);
+ if (tstatus == 0)
+ {
+ /* keep this column in the output file */
+ colnum = testnum;
+ savecol = 1;
+
+ if (!colindex)
+ colindex = (int *) calloc(999, sizeof(int));
+
+ colindex[colnum - 1] = 1;
+ if (colnum > numcols)numcols++;
+ }
+ else
+ {
+ ffcmsg(); /* clear the error message stack */
+ }
+ }
+ }
+ }
+ if (clause) free(clause); /* free old clause before getting new one */
+ clause = NULL;
+ }
+
+ if (savecol && !deletecol)
+ {
+ /* need to delete all but the specified columns */
+ for (ii = numcols; ii > 0; ii--)
+ {
+ if (!colindex[ii-1]) /* delete this column */
+ {
+ if (ffdcol(*fptr, ii, status) > 0)
+ {
+ ffpmsg("failed to delete column in input file:");
+ ffpmsg(clause);
+ if( colindex ) free( colindex );
+ if( file_expr ) free( file_expr );
+ if (clause) free(clause);
+ return(*status);
+ }
+ }
+ }
+ }
+
+ if( colindex ) free( colindex );
+ if( file_expr ) free( file_expr );
+ if (clause) free(clause);
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int fits_copy_cell2image(
+ fitsfile *fptr, /* I - point to input table */
+ fitsfile *newptr, /* O - existing output file; new image HDU
+ will be appended to it */
+ char *colname, /* I - column name / number containing the image*/
+ long rownum, /* I - number of the row containing the image */
+ int *status) /* IO - error status */
+
+/*
+ Copy a table cell of a given row and column into an image extension.
+ The output file must already have been created. A new image
+ extension will be created in that file.
+
+ This routine was written by Craig Markwardt, GSFC
+*/
+
+{
+ unsigned char buffer[30000];
+ int hdutype, colnum, typecode, bitpix, naxis, maxelem, tstatus;
+ LONGLONG naxes[9], nbytes, firstbyte, ntodo;
+ LONGLONG repeat, startpos, elemnum, rowlen, tnull;
+ long twidth, incre;
+ double scale, zero;
+ char tform[20];
+ char card[FLEN_CARD];
+ char templt[FLEN_CARD] = "";
+
+ /* Table-to-image keyword translation table */
+ /* INPUT OUTPUT */
+ /* 01234567 01234567 */
+ char *patterns[][2] = {{"TSCALn", "BSCALE" }, /* Standard FITS keywords */
+ {"TZEROn", "BZERO" },
+ {"TUNITn", "BUNIT" },
+ {"TNULLn", "BLANK" },
+ {"TDMINn", "DATAMIN" },
+ {"TDMAXn", "DATAMAX" },
+ {"iCTYPn", "CTYPEi" }, /* Coordinate labels */
+ {"iCTYna", "CTYPEia" },
+ {"iCUNIn", "CUNITi" }, /* Coordinate units */
+ {"iCUNna", "CUNITia" },
+ {"iCRVLn", "CRVALi" }, /* WCS keywords */
+ {"iCRVna", "CRVALia" },
+ {"iCDLTn", "CDELTi" },
+ {"iCDEna", "CDELTia" },
+ {"iCRPXn", "CRPIXi" },
+ {"iCRPna", "CRPIXia" },
+ {"ijPCna", "PCi_ja" },
+ {"ijCDna", "CDi_ja" },
+ {"iVn_ma", "PVi_ma" },
+ {"iSn_ma", "PSi_ma" },
+ {"iCRDna", "CRDERia" },
+ {"iCSYna", "CSYERia" },
+ {"iCROTn", "CROTAi" },
+ {"WCAXna", "WCSAXESa"},
+ {"WCSNna", "WCSNAMEa"},
+
+ {"LONPna", "LONPOLEa"},
+ {"LATPna", "LATPOLEa"},
+ {"EQUIna", "EQUINOXa"},
+ {"MJDOBn", "MJD-OBS" },
+ {"MJDAn", "MJD-AVG" },
+ {"RADEna", "RADESYSa"},
+ {"iCNAna", "CNAMEia" },
+ {"DAVGn", "DATE-AVG"},
+
+ /* Delete table keywords related to other columns */
+ {"T????#a", "-" },
+ {"TC??#a", "-" },
+ {"TWCS#a", "-" },
+ {"TDIM#", "-" },
+ {"iCTYPm", "-" },
+ {"iCUNIm", "-" },
+ {"iCRVLm", "-" },
+ {"iCDLTm", "-" },
+ {"iCRPXm", "-" },
+ {"iCTYma", "-" },
+ {"iCUNma", "-" },
+ {"iCRVma", "-" },
+ {"iCDEma", "-" },
+ {"iCRPma", "-" },
+ {"ijPCma", "-" },
+ {"ijCDma", "-" },
+ {"iVm_ma", "-" },
+ {"iSm_ma", "-" },
+ {"iCRDma", "-" },
+ {"iCSYma", "-" },
+ {"iCROTm", "-" },
+ {"WCAXma", "-" },
+ {"WCSNma", "-" },
+
+ {"LONPma", "-" },
+ {"LATPma", "-" },
+ {"EQUIma", "-" },
+ {"MJDOBm", "-" },
+ {"MJDAm", "-" },
+ {"RADEma", "-" },
+ {"iCNAma", "-" },
+ {"DAVGm", "-" },
+
+ {"EXTNAME", "-" }, /* Remove structural keywords*/
+ {"EXTVER", "-" },
+ {"EXTLEVEL","-" },
+ {"CHECKSUM","-" },
+ {"DATASUM", "-" },
+
+ {"*", "+" }}; /* copy all other keywords */
+ int npat;
+
+ if (*status > 0)
+ return(*status);
+
+ /* get column number */
+ if (ffgcno(fptr, CASEINSEN, colname, &colnum, status) > 0)
+ {
+ ffpmsg("column containing image in table cell does not exist:");
+ ffpmsg(colname);
+ return(*status);
+ }
+
+ /*---------------------------------------------------*/
+ /* Check input and get parameters about the column: */
+ /*---------------------------------------------------*/
+ if ( ffgcprll(fptr, colnum, rownum, 1L, 1L, 0, &scale, &zero,
+ tform, &twidth, &typecode, &maxelem, &startpos, &elemnum, &incre,
+ &repeat, &rowlen, &hdutype, &tnull, (char *) buffer, status) > 0 )
+ return(*status);
+
+ /* get the actual column name, in case a column number was given */
+ ffkeyn("", colnum, templt, &tstatus);
+ ffgcnn(fptr, CASEINSEN, templt, colname, &colnum, &tstatus);
+
+ if (hdutype != BINARY_TBL)
+ {
+ ffpmsg("This extension is not a binary table.");
+ ffpmsg(" Cannot open the image in a binary table cell.");
+ return(*status = NOT_BTABLE);
+ }
+
+ if (typecode < 0)
+ {
+ /* variable length array */
+ typecode *= -1;
+
+ /* variable length arrays are 1-dimensional by default */
+ naxis = 1;
+ naxes[0] = repeat;
+ }
+ else
+ {
+ /* get the dimensions of the image */
+ ffgtdmll(fptr, colnum, 9, &naxis, naxes, status);
+ }
+
+ if (*status > 0)
+ {
+ ffpmsg("Error getting the dimensions of the image");
+ return(*status);
+ }
+
+ /* determine BITPIX value for the image */
+ if (typecode == TBYTE)
+ {
+ bitpix = BYTE_IMG;
+ nbytes = repeat;
+ }
+ else if (typecode == TSHORT)
+ {
+ bitpix = SHORT_IMG;
+ nbytes = repeat * 2;
+ }
+ else if (typecode == TLONG)
+ {
+ bitpix = LONG_IMG;
+ nbytes = repeat * 4;
+ }
+ else if (typecode == TFLOAT)
+ {
+ bitpix = FLOAT_IMG;
+ nbytes = repeat * 4;
+ }
+ else if (typecode == TDOUBLE)
+ {
+ bitpix = DOUBLE_IMG;
+ nbytes = repeat * 8;
+ }
+ else if (typecode == TLONGLONG)
+ {
+ bitpix = LONGLONG_IMG;
+ nbytes = repeat * 8;
+ }
+ else if (typecode == TLOGICAL)
+ {
+ bitpix = BYTE_IMG;
+ nbytes = repeat;
+ }
+ else
+ {
+ ffpmsg("Error: the following image column has invalid datatype:");
+ ffpmsg(colname);
+ ffpmsg(tform);
+ ffpmsg("Cannot open an image in a single row of this column.");
+ return(*status = BAD_TFORM);
+ }
+
+ /* create new image in output file */
+ if (ffcrimll(newptr, bitpix, naxis, naxes, status) > 0)
+ {
+ ffpmsg("failed to write required primary array keywords in the output file");
+ return(*status);
+ }
+
+ npat = sizeof(patterns)/sizeof(patterns[0][0])/2;
+
+ /* skip over the first 8 keywords, starting just after TFIELDS */
+ fits_translate_keywords(fptr, newptr, 9, patterns, npat,
+ colnum, 0, 0, status);
+
+ /* add some HISTORY */
+ sprintf(card,"HISTORY This image was copied from row %ld of column '%s',",
+ rownum, colname);
+/* disable this; leave it up to the caller to write history if needed.
+ ffprec(newptr, card, status);
+*/
+ /* the use of ffread routine, below, requires that any 'dirty' */
+ /* buffers in memory be flushed back to the file first */
+
+ ffflsh(fptr, FALSE, status);
+
+ /* finally, copy the data, one buffer size at a time */
+ ffmbyt(fptr, startpos, TRUE, status);
+ firstbyte = 1;
+
+ /* the upper limit on the number of bytes must match the declaration */
+ /* read up to the first 30000 bytes in the normal way with ffgbyt */
+
+ ntodo = minvalue(30000, nbytes);
+ ffgbyt(fptr, ntodo, buffer, status);
+ ffptbb(newptr, 1, firstbyte, ntodo, buffer, status);
+
+ nbytes -= ntodo;
+ firstbyte += ntodo;
+
+ /* read any additional bytes with low-level ffread routine, for speed */
+ while (nbytes && (*status <= 0) )
+ {
+ ntodo = minvalue(30000, nbytes);
+ ffread((fptr)->Fptr, (long) ntodo, buffer, status);
+ ffptbb(newptr, 1, firstbyte, ntodo, buffer, status);
+ nbytes -= ntodo;
+ firstbyte += ntodo;
+ }
+
+ /* Re-scan the header so that CFITSIO knows about all the new keywords */
+ ffrdef(newptr,status);
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int fits_copy_image2cell(
+ fitsfile *fptr, /* I - pointer to input image extension */
+ fitsfile *newptr, /* I - pointer to output table */
+ char *colname, /* I - name of column containing the image */
+ long rownum, /* I - number of the row containing the image */
+ int copykeyflag, /* I - controls which keywords to copy */
+ int *status) /* IO - error status */
+
+/*
+ Copy an image extension into a table cell at a given row and
+ column. The table must have already been created. If the "colname"
+ column exists, it will be used, otherwise a new column will be created
+ in the table.
+
+ The "copykeyflag" parameter controls which keywords to copy from the
+ input image to the output table header (with any appropriate translation).
+
+ copykeyflag = 0 -- no keywords will be copied
+ copykeyflag = 1 -- essentially all keywords will be copied
+ copykeyflag = 2 -- copy only the WCS related keywords
+
+ This routine was written by Craig Markwardt, GSFC
+
+*/
+{
+ tcolumn *colptr;
+ unsigned char buffer[30000];
+ int ii, hdutype, colnum, typecode, bitpix, naxis, ncols, hdunum;
+ char tformchar, tform[20], card[FLEN_CARD];
+ LONGLONG imgstart, naxes[9], nbytes, repeat, ntodo,firstbyte;
+ char filename[FLEN_FILENAME+20];
+
+ int npat;
+
+ int naxis1;
+ LONGLONG naxes1[9] = {0,0,0,0,0,0,0,0,0}, repeat1, width1;
+ int typecode1;
+ unsigned char dummy = 0;
+
+ LONGLONG headstart, datastart, dataend;
+
+ /* Image-to-table keyword translation table */
+ /* INPUT OUTPUT */
+ /* 01234567 01234567 */
+ char *patterns[][2] = {{"BSCALE", "TSCALn" }, /* Standard FITS keywords */
+ {"BZERO", "TZEROn" },
+ {"BUNIT", "TUNITn" },
+ {"BLANK", "TNULLn" },
+ {"DATAMIN", "TDMINn" },
+ {"DATAMAX", "TDMAXn" },
+ {"CTYPEi", "iCTYPn" }, /* Coordinate labels */
+ {"CTYPEia", "iCTYna" },
+ {"CUNITi", "iCUNIn" }, /* Coordinate units */
+ {"CUNITia", "iCUNna" },
+ {"CRVALi", "iCRVLn" }, /* WCS keywords */
+ {"CRVALia", "iCRVna" },
+ {"CDELTi", "iCDLTn" },
+ {"CDELTia", "iCDEna" },
+ {"CRPIXj", "jCRPXn" },
+ {"CRPIXja", "jCRPna" },
+ {"PCi_ja", "ijPCna" },
+ {"CDi_ja", "ijCDna" },
+ {"PVi_ma", "iVn_ma" },
+ {"PSi_ma", "iSn_ma" },
+ {"WCSAXESa","WCAXna" },
+ {"WCSNAMEa","WCSNna" },
+ {"CRDERia", "iCRDna" },
+ {"CSYERia", "iCSYna" },
+ {"CROTAi", "iCROTn" },
+
+ {"LONPOLEa","LONPna"},
+ {"LATPOLEa","LATPna"},
+ {"EQUINOXa","EQUIna"},
+ {"MJD-OBS", "MJDOBn" },
+ {"MJD-AVG", "MJDAn" },
+ {"RADESYSa","RADEna"},
+ {"CNAMEia", "iCNAna" },
+ {"DATE-AVG","DAVGn"},
+
+ {"NAXISi", "-" }, /* Remove structural keywords*/
+ {"PCOUNT", "-" },
+ {"GCOUNT", "-" },
+ {"EXTEND", "-" },
+ {"EXTNAME", "-" },
+ {"EXTVER", "-" },
+ {"EXTLEVEL","-" },
+ {"CHECKSUM","-" },
+ {"DATASUM", "-" },
+ {"*", "+" }}; /* copy all other keywords */
+
+
+ if (*status > 0)
+ return(*status);
+
+ if (fptr == 0 || newptr == 0) return (*status = NULL_INPUT_PTR);
+
+ if (ffghdt(fptr, &hdutype, status) > 0) {
+ ffpmsg("could not get input HDU type");
+ return (*status);
+ }
+
+ if (hdutype != IMAGE_HDU) {
+ ffpmsg("The input extension is not an image.");
+ ffpmsg(" Cannot open the image.");
+ return(*status = NOT_IMAGE);
+ }
+
+ if (ffghdt(newptr, &hdutype, status) > 0) {
+ ffpmsg("could not get output HDU type");
+ return (*status);
+ }
+
+ if (hdutype != BINARY_TBL) {
+ ffpmsg("The output extension is not a table.");
+ return(*status = NOT_BTABLE);
+ }
+
+
+ if (ffgiprll(fptr, 9, &bitpix, &naxis, naxes, status) > 0) {
+ ffpmsg("Could not read image parameters.");
+ return (*status);
+ }
+
+ /* Determine total number of pixels in the image */
+ repeat = 1;
+ for (ii = 0; ii < naxis; ii++) repeat *= naxes[ii];
+
+ /* Determine the TFORM value for the table cell */
+ if (bitpix == BYTE_IMG) {
+ typecode = TBYTE;
+ tformchar = 'B';
+ nbytes = repeat;
+ } else if (bitpix == SHORT_IMG) {
+ typecode = TSHORT;
+ tformchar = 'I';
+ nbytes = repeat*2;
+ } else if (bitpix == LONG_IMG) {
+ typecode = TLONG;
+ tformchar = 'J';
+ nbytes = repeat*4;
+ } else if (bitpix == FLOAT_IMG) {
+ typecode = TFLOAT;
+ tformchar = 'E';
+ nbytes = repeat*4;
+ } else if (bitpix == DOUBLE_IMG) {
+ typecode = TDOUBLE;
+ tformchar = 'D';
+ nbytes = repeat*8;
+ } else if (bitpix == LONGLONG_IMG) {
+ typecode = TLONGLONG;
+ tformchar = 'K';
+ nbytes = repeat*8;
+ } else {
+ ffpmsg("Error: the image has an invalid datatype.");
+ return (*status = BAD_BITPIX);
+ }
+
+ /* get column number */
+ ffpmrk();
+ ffgcno(newptr, CASEINSEN, colname, &colnum, status);
+ ffcmrk();
+
+ /* Column does not exist; create it */
+ if (*status) {
+
+ *status = 0;
+ sprintf(tform, "%.0f%c", (double) repeat, tformchar);
+ ffgncl(newptr, &ncols, status);
+ colnum = ncols+1;
+ fficol(newptr, colnum, colname, tform, status);
+ ffptdmll(newptr, colnum, naxis, naxes, status);
+
+ if (*status) {
+ ffpmsg("Could not insert new column into output table.");
+ return *status;
+ }
+
+ } else {
+
+ ffgtdmll(newptr, colnum, 9, &naxis1, naxes1, status);
+ if (*status > 0 || naxis != naxis1) {
+ ffpmsg("Input image dimensions and output table cell dimensions do not match.");
+ return (*status = BAD_DIMEN);
+ }
+ for (ii=0; ii<naxis; ii++) if (naxes[ii] != naxes1[ii]) {
+ ffpmsg("Input image dimensions and output table cell dimensions do not match.");
+ return (*status = BAD_DIMEN);
+ }
+
+ ffgtclll(newptr, colnum, &typecode1, &repeat1, &width1, status);
+ if ((*status > 0) || (typecode1 != typecode) || (repeat1 != repeat)) {
+ ffpmsg("Input image data type does not match output table cell type.");
+ return (*status = BAD_TFORM);
+ }
+ }
+
+ /* copy keywords from input image to output table, if required */
+
+ if (copykeyflag) {
+
+ npat = sizeof(patterns)/sizeof(patterns[0][0])/2;
+
+ if (copykeyflag == 2) { /* copy only the WCS-related keywords */
+ patterns[npat-1][1] = "-";
+ }
+
+ /* The 3rd parameter value = 5 means skip the first 4 keywords in the image */
+ fits_translate_keywords(fptr, newptr, 5, patterns, npat,
+ colnum, 0, 0, status);
+ }
+
+ /* Here is all the code to compute offsets:
+ * * byte offset from start of row to column (dest table)
+ * * byte offset from start of file to image data (source image)
+ */
+
+ /* Force the writing of the row of the table by writing the last byte of
+ the array, which grows the table, and/or shifts following extensions */
+ ffpcl(newptr, TBYTE, colnum, rownum, repeat, 1, &dummy, status);
+
+ /* byte offset within the row to the start of the image column */
+ colptr = (newptr->Fptr)->tableptr; /* point to first column */
+ colptr += (colnum - 1); /* offset to correct column structure */
+ firstbyte = colptr->tbcol + 1;
+
+ /* get starting address of input image to be read */
+ ffghadll(fptr, &headstart, &datastart, &dataend, status);
+ imgstart = datastart;
+
+ sprintf(card, "HISTORY Table column '%s' row %ld copied from image",
+ colname, rownum);
+/*
+ Don't automatically write History keywords; leave this up to the caller.
+ ffprec(newptr, card, status);
+*/
+
+ /* write HISTORY keyword with the file name (this is now disabled)*/
+
+ filename[0] = '\0'; hdunum = 0;
+ strcpy(filename, "HISTORY ");
+ ffflnm(fptr, filename+strlen(filename), status);
+ ffghdn(fptr, &hdunum);
+ sprintf(filename+strlen(filename),"[%d]", hdunum-1);
+/*
+ ffprec(newptr, filename, status);
+*/
+
+ /* the use of ffread routine, below, requires that any 'dirty' */
+ /* buffers in memory be flushed back to the file first */
+
+ ffflsh(fptr, FALSE, status);
+
+ /* move to the first byte of the input image */
+ ffmbyt(fptr, imgstart, TRUE, status);
+
+ ntodo = minvalue(30000L, nbytes);
+ ffgbyt(fptr, ntodo, buffer, status); /* read input image */
+ ffptbb(newptr, rownum, firstbyte, ntodo, buffer, status); /* write to table */
+
+ nbytes -= ntodo;
+ firstbyte += ntodo;
+
+
+ /* read any additional bytes with low-level ffread routine, for speed */
+ while (nbytes && (*status <= 0) )
+ {
+ ntodo = minvalue(30000L, nbytes);
+ ffread(fptr->Fptr, (long) ntodo, buffer, status);
+ ffptbb(newptr, rownum, firstbyte, ntodo, buffer, status);
+ nbytes -= ntodo;
+ firstbyte += ntodo;
+ }
+
+ /* Re-scan the header so that CFITSIO knows about all the new keywords */
+ ffrdef(newptr,status);
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int fits_select_image_section(
+ fitsfile **fptr, /* IO - pointer to input image; on output it */
+ /* points to the new subimage */
+ char *outfile, /* I - name for output file */
+ char *expr, /* I - Image section expression */
+ int *status)
+{
+ /*
+ copies an image section from the input file to a new output file.
+ Any HDUs preceding or following the image are also copied to the
+ output file.
+ */
+
+ fitsfile *newptr;
+ int ii, hdunum;
+
+ /* create new empty file to hold the image section */
+ if (ffinit(&newptr, outfile, status) > 0)
+ {
+ ffpmsg(
+ "failed to create output file for image section:");
+ ffpmsg(outfile);
+ return(*status);
+ }
+
+ fits_get_hdu_num(*fptr, &hdunum); /* current HDU number in input file */
+
+ /* copy all preceding extensions to the output file, if 'only_one' flag not set */
+ if (!(((*fptr)->Fptr)->only_one)) {
+ for (ii = 1; ii < hdunum; ii++)
+ {
+ fits_movabs_hdu(*fptr, ii, NULL, status);
+ if (fits_copy_hdu(*fptr, newptr, 0, status) > 0)
+ {
+ ffclos(newptr, status);
+ return(*status);
+ }
+ }
+
+ /* move back to the original HDU position */
+ fits_movabs_hdu(*fptr, hdunum, NULL, status);
+ }
+
+ if (fits_copy_image_section(*fptr, newptr, expr, status) > 0)
+ {
+ ffclos(newptr, status);
+ return(*status);
+ }
+
+ /* copy any remaining HDUs to the output file, if 'only_one' flag not set */
+
+ if (!(((*fptr)->Fptr)->only_one)) {
+ for (ii = hdunum + 1; 1; ii++)
+ {
+ if (fits_movabs_hdu(*fptr, ii, NULL, status) > 0)
+ break;
+
+ fits_copy_hdu(*fptr, newptr, 0, status);
+ }
+
+ if (*status == END_OF_FILE)
+ *status = 0; /* got the expected EOF error; reset = 0 */
+ else if (*status > 0)
+ {
+ ffclos(newptr, status);
+ return(*status);
+ }
+ } else {
+ ii = hdunum + 1; /* this value of ii is required below */
+ }
+
+ /* close the original file and return ptr to the new image */
+ ffclos(*fptr, status);
+
+ *fptr = newptr; /* reset the pointer to the new table */
+
+ /* move back to the image subsection */
+ if (ii - 1 != hdunum)
+ fits_movabs_hdu(*fptr, hdunum, NULL, status);
+ else
+ {
+ /* may have to reset BSCALE and BZERO pixel scaling, */
+ /* since the keywords were previously turned off */
+
+ if (ffrdef(*fptr, status) > 0)
+ {
+ ffclos(*fptr, status);
+ return(*status);
+ }
+
+ }
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int fits_copy_image_section(
+ fitsfile *fptr, /* I - pointer to input image */
+ fitsfile *newptr, /* I - pointer to output image */
+ char *expr, /* I - Image section expression */
+ int *status)
+{
+ /*
+ copies an image section from the input file to a new output HDU
+ */
+
+ int bitpix, naxis, numkeys, nkey;
+ long naxes[] = {1,1,1,1,1,1,1,1,1}, smin, smax, sinc;
+ long fpixels[] = {1,1,1,1,1,1,1,1,1};
+ long lpixels[] = {1,1,1,1,1,1,1,1,1};
+ long incs[] = {1,1,1,1,1,1,1,1,1};
+ char *cptr, keyname[FLEN_KEYWORD], card[FLEN_CARD];
+ int ii, tstatus, anynull;
+ long minrow, maxrow, minslice, maxslice, mincube, maxcube;
+ long firstpix;
+ long ncubeiter, nsliceiter, nrowiter, kiter, jiter, iiter;
+ int klen, kk, jj;
+ long outnaxes[9], outsize, buffsize;
+ double *buffer, crpix, cdelt;
+
+ if (*status > 0)
+ return(*status);
+
+ /* get the size of the input image */
+ fits_get_img_type(fptr, &bitpix, status);
+ fits_get_img_dim(fptr, &naxis, status);
+ if (fits_get_img_size(fptr, naxis, naxes, status) > 0)
+ return(*status);
+
+ if (naxis < 1 || naxis > 4)
+ {
+ ffpmsg(
+ "Input image either had NAXIS = 0 (NULL image) or has > 4 dimensions");
+ return(*status = BAD_NAXIS);
+ }
+
+ /* create output image with same size and type as the input image */
+ /* Will update the size later */
+ fits_create_img(newptr, bitpix, naxis, naxes, status);
+
+ /* copy all other non-structural keywords from the input to output file */
+ fits_get_hdrspace(fptr, &numkeys, NULL, status);
+
+ for (nkey = 4; nkey <= numkeys; nkey++) /* skip the first few keywords */
+ {
+ fits_read_record(fptr, nkey, card, status);
+
+ if (fits_get_keyclass(card) > TYP_CMPRS_KEY)
+ {
+ /* write the record to the output file */
+ fits_write_record(newptr, card, status);
+ }
+ }
+
+ if (*status > 0)
+ {
+ ffpmsg("error copying header from input image to output image");
+ return(*status);
+ }
+
+ /* parse the section specifier to get min, max, and inc for each axis */
+ /* and the size of each output image axis */
+
+ cptr = expr;
+ for (ii=0; ii < naxis; ii++)
+ {
+ if (fits_get_section_range(&cptr, &smin, &smax, &sinc, status) > 0)
+ {
+ ffpmsg("error parsing the following image section specifier:");
+ ffpmsg(expr);
+ return(*status);
+ }
+
+ if (smax == 0)
+ smax = naxes[ii]; /* use whole axis by default */
+ else if (smin == 0)
+ smin = naxes[ii]; /* use inverted whole axis */
+
+ if (smin > naxes[ii] || smax > naxes[ii])
+ {
+ ffpmsg("image section exceeds dimensions of input image:");
+ ffpmsg(expr);
+ return(*status = BAD_NAXIS);
+ }
+
+ fpixels[ii] = smin;
+ lpixels[ii] = smax;
+ incs[ii] = sinc;
+
+ if (smin <= smax)
+ outnaxes[ii] = (smax - smin + sinc) / sinc;
+ else
+ outnaxes[ii] = (smin - smax + sinc) / sinc;
+
+ /* modify the NAXISn keyword */
+ fits_make_keyn("NAXIS", ii + 1, keyname, status);
+ fits_modify_key_lng(newptr, keyname, outnaxes[ii], NULL, status);
+
+ /* modify the WCS keywords if necessary */
+
+ if (fpixels[ii] != 1 || incs[ii] != 1)
+ {
+ for (kk=-1;kk<26; kk++) /* modify any alternate WCS keywords */
+ {
+ /* read the CRPIXn keyword if it exists in the input file */
+ fits_make_keyn("CRPIX", ii + 1, keyname, status);
+
+ if (kk != -1) {
+ klen = strlen(keyname);
+ keyname[klen]='A' + kk;
+ keyname[klen + 1] = '\0';
+ }
+
+ tstatus = 0;
+ if (fits_read_key(fptr, TDOUBLE, keyname,
+ &crpix, NULL, &tstatus) == 0)
+ {
+ /* calculate the new CRPIXn value */
+ if (fpixels[ii] <= lpixels[ii]) {
+ crpix = (crpix - (fpixels[ii])) / incs[ii] + 1.0;
+ /* crpix = (crpix - (fpixels[ii] - 1.0) - .5) / incs[ii] + 0.5; */
+ } else {
+ crpix = (fpixels[ii] - crpix) / incs[ii] + 1.0;
+ /* crpix = (fpixels[ii] - (crpix - 1.0) - .5) / incs[ii] + 0.5; */
+ }
+
+ /* modify the value in the output file */
+ fits_modify_key_dbl(newptr, keyname, crpix, 15, NULL, status);
+
+ if (incs[ii] != 1 || fpixels[ii] > lpixels[ii])
+ {
+ /* read the CDELTn keyword if it exists in the input file */
+ fits_make_keyn("CDELT", ii + 1, keyname, status);
+
+ if (kk != -1) {
+ klen = strlen(keyname);
+ keyname[klen]='A' + kk;
+ keyname[klen + 1] = '\0';
+ }
+
+ tstatus = 0;
+ if (fits_read_key(fptr, TDOUBLE, keyname,
+ &cdelt, NULL, &tstatus) == 0)
+ {
+ /* calculate the new CDELTn value */
+ if (fpixels[ii] <= lpixels[ii])
+ cdelt = cdelt * incs[ii];
+ else
+ cdelt = cdelt * (-incs[ii]);
+
+ /* modify the value in the output file */
+ fits_modify_key_dbl(newptr, keyname, cdelt, 15, NULL, status);
+ }
+
+ /* modify the CDi_j keywords if they exist in the input file */
+
+ fits_make_keyn("CD1_", ii + 1, keyname, status);
+
+ if (kk != -1) {
+ klen = strlen(keyname);
+ keyname[klen]='A' + kk;
+ keyname[klen + 1] = '\0';
+ }
+
+ for (jj=0; jj < 9; jj++) /* look for up to 9 dimensions */
+ {
+ keyname[2] = '1' + jj;
+
+ tstatus = 0;
+ if (fits_read_key(fptr, TDOUBLE, keyname,
+ &cdelt, NULL, &tstatus) == 0)
+ {
+ /* calculate the new CDi_j value */
+ if (fpixels[ii] <= lpixels[ii])
+ cdelt = cdelt * incs[ii];
+ else
+ cdelt = cdelt * (-incs[ii]);
+
+ /* modify the value in the output file */
+ fits_modify_key_dbl(newptr, keyname, cdelt, 15, NULL, status);
+ }
+ }
+
+ } /* end of if (incs[ii]... loop */
+ } /* end of fits_read_key loop */
+ } /* end of for (kk loop */
+ }
+ } /* end of main NAXIS loop */
+
+ if (ffrdef(newptr, status) > 0) /* force the header to be scanned */
+ {
+ return(*status);
+ }
+
+ /* turn off any scaling of the pixel values */
+ fits_set_bscale(fptr, 1.0, 0.0, status);
+ fits_set_bscale(newptr, 1.0, 0.0, status);
+
+ /* to reduce memory foot print, just read/write image 1 row at a time */
+
+ outsize = outnaxes[0];
+ buffsize = (abs(bitpix) / 8) * outsize;
+
+ buffer = (double *) malloc(buffsize); /* allocate memory for the image row */
+ if (!buffer)
+ {
+ ffpmsg("fits_copy_image_section: no memory for image section");
+ return(*status = MEMORY_ALLOCATION);
+ }
+
+ /* read the image section then write it to the output file */
+
+ minrow = fpixels[1];
+ maxrow = lpixels[1];
+ if (minrow > maxrow) {
+ nrowiter = (minrow - maxrow + incs[1]) / incs[1];
+ } else {
+ nrowiter = (maxrow - minrow + incs[1]) / incs[1];
+ }
+
+ minslice = fpixels[2];
+ maxslice = lpixels[2];
+ if (minslice > maxslice) {
+ nsliceiter = (minslice - maxslice + incs[2]) / incs[2];
+ } else {
+ nsliceiter = (maxslice - minslice + incs[2]) / incs[2];
+ }
+
+ mincube = fpixels[3];
+ maxcube = lpixels[3];
+ if (mincube > maxcube) {
+ ncubeiter = (mincube - maxcube + incs[3]) / incs[3];
+ } else {
+ ncubeiter = (maxcube - mincube + incs[3]) / incs[3];
+ }
+
+ firstpix = 1;
+ for (kiter = 0; kiter < ncubeiter; kiter++)
+ {
+ if (mincube > maxcube) {
+ fpixels[3] = mincube - (kiter * incs[3]);
+ } else {
+ fpixels[3] = mincube + (kiter * incs[3]);
+ }
+
+ lpixels[3] = fpixels[3];
+
+ for (jiter = 0; jiter < nsliceiter; jiter++)
+ {
+ if (minslice > maxslice) {
+ fpixels[2] = minslice - (jiter * incs[2]);
+ } else {
+ fpixels[2] = minslice + (jiter * incs[2]);
+ }
+
+ lpixels[2] = fpixels[2];
+
+ for (iiter = 0; iiter < nrowiter; iiter++)
+ {
+ if (minrow > maxrow) {
+ fpixels[1] = minrow - (iiter * incs[1]);
+ } else {
+ fpixels[1] = minrow + (iiter * incs[1]);
+ }
+
+ lpixels[1] = fpixels[1];
+
+ if (bitpix == 8)
+ {
+ ffgsvb(fptr, 1, naxis, naxes, fpixels, lpixels, incs, 0,
+ (unsigned char *) buffer, &anynull, status);
+
+ ffpprb(newptr, 1, firstpix, outsize, (unsigned char *) buffer, status);
+ }
+ else if (bitpix == 16)
+ {
+ ffgsvi(fptr, 1, naxis, naxes, fpixels, lpixels, incs, 0,
+ (short *) buffer, &anynull, status);
+
+ ffppri(newptr, 1, firstpix, outsize, (short *) buffer, status);
+ }
+ else if (bitpix == 32)
+ {
+ ffgsvk(fptr, 1, naxis, naxes, fpixels, lpixels, incs, 0,
+ (int *) buffer, &anynull, status);
+
+ ffpprk(newptr, 1, firstpix, outsize, (int *) buffer, status);
+ }
+ else if (bitpix == -32)
+ {
+ ffgsve(fptr, 1, naxis, naxes, fpixels, lpixels, incs, FLOATNULLVALUE,
+ (float *) buffer, &anynull, status);
+
+ ffppne(newptr, 1, firstpix, outsize, (float *) buffer, FLOATNULLVALUE, status);
+ }
+ else if (bitpix == -64)
+ {
+ ffgsvd(fptr, 1, naxis, naxes, fpixels, lpixels, incs, DOUBLENULLVALUE,
+ buffer, &anynull, status);
+
+ ffppnd(newptr, 1, firstpix, outsize, buffer, DOUBLENULLVALUE,
+ status);
+ }
+ else if (bitpix == 64)
+ {
+ ffgsvjj(fptr, 1, naxis, naxes, fpixels, lpixels, incs, 0,
+ (LONGLONG *) buffer, &anynull, status);
+
+ ffpprjj(newptr, 1, firstpix, outsize, (LONGLONG *) buffer, status);
+ }
+
+ firstpix += outsize;
+ }
+ }
+ }
+
+ free(buffer); /* finished with the memory */
+
+ if (*status > 0)
+ {
+ ffpmsg("fits_copy_image_section: error copying image section");
+ return(*status);
+ }
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int fits_get_section_range(char **ptr,
+ long *secmin,
+ long *secmax,
+ long *incre,
+ int *status)
+/*
+ Parse the input image section specification string, returning
+ the min, max and increment values.
+ Typical string = "1:512:2" or "1:512"
+*/
+{
+ int slen, isanumber;
+ char token[FLEN_VALUE];
+
+ if (*status > 0)
+ return(*status);
+
+ slen = fits_get_token(ptr, " ,:", token, &isanumber); /* get 1st token */
+
+ /* support [:2,:2] type syntax, where the leading * is implied */
+ if (slen==0) strcpy(token,"*");
+
+ if (*token == '*') /* wild card means to use the whole range */
+ {
+ *secmin = 1;
+ *secmax = 0;
+ }
+ else if (*token == '-' && *(token+1) == '*' ) /* invert the whole range */
+ {
+ *secmin = 0;
+ *secmax = 1;
+ }
+ else
+ {
+ if (slen == 0 || !isanumber || **ptr != ':')
+ return(*status = URL_PARSE_ERROR);
+
+ /* the token contains the min value */
+ *secmin = atol(token);
+
+ (*ptr)++; /* skip the colon between the min and max values */
+ slen = fits_get_token(ptr, " ,:", token, &isanumber); /* get token */
+
+ if (slen == 0 || !isanumber)
+ return(*status = URL_PARSE_ERROR);
+
+ /* the token contains the max value */
+ *secmax = atol(token);
+ }
+
+ if (**ptr == ':')
+ {
+ (*ptr)++; /* skip the colon between the max and incre values */
+ slen = fits_get_token(ptr, " ,", token, &isanumber); /* get token */
+
+ if (slen == 0 || !isanumber)
+ return(*status = URL_PARSE_ERROR);
+
+ *incre = atol(token);
+ }
+ else
+ *incre = 1; /* default increment if none is supplied */
+
+ if (**ptr == ',')
+ (*ptr)++;
+
+ while (**ptr == ' ') /* skip any trailing blanks */
+ (*ptr)++;
+
+ if (*secmin < 0 || *secmax < 0 || *incre < 1)
+ *status = URL_PARSE_ERROR;
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffselect_table(
+ fitsfile **fptr, /* IO - pointer to input table; on output it */
+ /* points to the new selected rows table */
+ char *outfile, /* I - name for output file */
+ char *expr, /* I - Boolean expression */
+ int *status)
+{
+ fitsfile *newptr;
+ int ii, hdunum;
+
+ if (*outfile)
+ {
+ /* create new empty file in to hold the selected rows */
+ if (ffinit(&newptr, outfile, status) > 0)
+ {
+ ffpmsg(
+ "failed to create file for selected rows from input table");
+ ffpmsg(outfile);
+ return(*status);
+ }
+
+ fits_get_hdu_num(*fptr, &hdunum); /* current HDU number in input file */
+
+ /* copy all preceding extensions to the output file, if the 'only_one' flag is not set */
+ if (!((*fptr)->Fptr)->only_one) {
+ for (ii = 1; ii < hdunum; ii++)
+ {
+ fits_movabs_hdu(*fptr, ii, NULL, status);
+ if (fits_copy_hdu(*fptr, newptr, 0, status) > 0)
+ {
+ ffclos(newptr, status);
+ return(*status);
+ }
+ }
+ } else {
+ /* just copy the primary array */
+ fits_movabs_hdu(*fptr, 1, NULL, status);
+ if (fits_copy_hdu(*fptr, newptr, 0, status) > 0)
+ {
+ ffclos(newptr, status);
+ return(*status);
+ }
+ }
+
+ fits_movabs_hdu(*fptr, hdunum, NULL, status);
+
+ /* copy all the header keywords from the input to output file */
+ if (fits_copy_header(*fptr, newptr, status) > 0)
+ {
+ ffclos(newptr, status);
+ return(*status);
+ }
+
+ /* set number of rows = 0 */
+ fits_modify_key_lng(newptr, "NAXIS2", 0, NULL,status);
+ (newptr->Fptr)->numrows = 0;
+ (newptr->Fptr)->origrows = 0;
+
+ if (ffrdef(newptr, status) > 0) /* force the header to be scanned */
+ {
+ ffclos(newptr, status);
+ return(*status);
+ }
+ }
+ else
+ newptr = *fptr; /* will delete rows in place in the table */
+
+ /* copy rows which satisfy the selection expression to the output table */
+ /* or delete the nonqualifying rows if *fptr = newptr. */
+ if (fits_select_rows(*fptr, newptr, expr, status) > 0)
+ {
+ if (*outfile)
+ ffclos(newptr, status);
+
+ return(*status);
+ }
+
+ if (*outfile)
+ {
+ /* copy any remaining HDUs to the output copy */
+
+ if (!((*fptr)->Fptr)->only_one) {
+ for (ii = hdunum + 1; 1; ii++)
+ {
+ if (fits_movabs_hdu(*fptr, ii, NULL, status) > 0)
+ break;
+
+ fits_copy_hdu(*fptr, newptr, 0, status);
+ }
+
+ if (*status == END_OF_FILE)
+ *status = 0; /* got the expected EOF error; reset = 0 */
+ else if (*status > 0)
+ {
+ ffclos(newptr, status);
+ return(*status);
+ }
+ } else {
+ hdunum = 2;
+ }
+
+ /* close the original file and return ptr to the new image */
+ ffclos(*fptr, status);
+
+ *fptr = newptr; /* reset the pointer to the new table */
+
+ /* move back to the selected table HDU */
+ fits_movabs_hdu(*fptr, hdunum, NULL, status);
+ }
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffparsecompspec(fitsfile *fptr, /* I - FITS file pointer */
+ char *compspec, /* I - image compression specification */
+ int *status) /* IO - error status */
+/*
+ Parse the image compression specification that was give in square brackets
+ following the output FITS file name, as in these examples:
+
+ myfile.fits[compress] - default Rice compression, row by row
+ myfile.fits[compress TYPE] - the first letter of TYPE defines the
+ compression algorithm:
+ R = Rice
+ G = GZIP
+ H = HCOMPRESS
+ HS = HCOMPRESS (with smoothing)
+ B - BZIP2
+ P = PLIO
+
+ myfile.fits[compress TYPE 100,100] - the numbers give the dimensions
+ of the compression tiles. Default
+ is NAXIS1, 1, 1, ...
+
+ other optional parameters may be specified following a semi-colon
+
+ myfile.fits[compress; q 8.0] q specifies the floating point
+ mufile.fits[compress TYPE; q -.0002] quantization level;
+ myfile.fits[compress TYPE 100,100; q 10, s 25] s specifies the HCOMPRESS
+ integer scaling parameter
+
+The compression parameters are saved in the fptr->Fptr structure for use
+when writing FITS images.
+
+*/
+{
+ char *ptr1;
+
+ /* initialize with default values */
+ int ii, compresstype = RICE_1, smooth = 0;
+ int quantize_method = SUBTRACTIVE_DITHER_1;
+ long tilesize[MAX_COMPRESS_DIM] = {0,0,0,0,0,0};
+ float qlevel = -99., scale = 0.;
+
+ ptr1 = compspec;
+ while (*ptr1 == ' ') /* ignore leading blanks */
+ ptr1++;
+
+ if (strncmp(ptr1, "compress", 8) && strncmp(ptr1, "COMPRESS", 8) )
+ {
+ /* apparently this string does not specify compression parameters */
+ return(*status = URL_PARSE_ERROR);
+ }
+
+ ptr1 += 8;
+ while (*ptr1 == ' ') /* ignore leading blanks */
+ ptr1++;
+
+ /* ========================= */
+ /* look for compression type */
+ /* ========================= */
+
+ if (*ptr1 == 'r' || *ptr1 == 'R')
+ {
+ compresstype = RICE_1;
+ while (*ptr1 != ' ' && *ptr1 != ';' && *ptr1 != '\0')
+ ptr1++;
+ }
+ else if (*ptr1 == 'g' || *ptr1 == 'G')
+ {
+ compresstype = GZIP_1;
+ while (*ptr1 != ' ' && *ptr1 != ';' && *ptr1 != '\0')
+ ptr1++;
+
+ }
+/*
+ else if (*ptr1 == 'b' || *ptr1 == 'B')
+ {
+ compresstype = BZIP2_1;
+ while (*ptr1 != ' ' && *ptr1 != ';' && *ptr1 != '\0')
+ ptr1++;
+
+ }
+*/
+ else if (*ptr1 == 'p' || *ptr1 == 'P')
+ {
+ compresstype = PLIO_1;
+ while (*ptr1 != ' ' && *ptr1 != ';' && *ptr1 != '\0')
+ ptr1++;
+ }
+ else if (*ptr1 == 'h' || *ptr1 == 'H')
+ {
+ compresstype = HCOMPRESS_1;
+ ptr1++;
+ if (*ptr1 == 's' || *ptr1 == 'S')
+ smooth = 1; /* apply smoothing when uncompressing HCOMPRESSed image */
+
+ while (*ptr1 != ' ' && *ptr1 != ';' && *ptr1 != '\0')
+ ptr1++;
+ }
+
+ /* ======================== */
+ /* look for tile dimensions */
+ /* ======================== */
+
+ while (*ptr1 == ' ') /* ignore leading blanks */
+ ptr1++;
+
+ ii = 0;
+ while (isdigit( (int) *ptr1) && ii < 9)
+ {
+ tilesize[ii] = atol(ptr1); /* read the integer value */
+ ii++;
+
+ while (isdigit((int) *ptr1)) /* skip over the integer */
+ ptr1++;
+
+ if (*ptr1 == ',')
+ ptr1++; /* skip over the comma */
+
+ while (*ptr1 == ' ') /* ignore leading blanks */
+ ptr1++;
+ }
+
+ /* ========================================================= */
+ /* look for semi-colon, followed by other optional parameters */
+ /* ========================================================= */
+
+ if (*ptr1 == ';') {
+ ptr1++;
+ while (*ptr1 == ' ') /* ignore leading blanks */
+ ptr1++;
+
+ while (*ptr1 != 0) { /* haven't reached end of string yet */
+
+ if (*ptr1 == 's' || *ptr1 == 'S') {
+ /* this should be the HCOMPRESS "scale" parameter; default = 1 */
+
+ ptr1++;
+ while (*ptr1 == ' ') /* ignore leading blanks */
+ ptr1++;
+
+ scale = (float) strtod(ptr1, &ptr1);
+
+ while (*ptr1 == ' ' || *ptr1 == ',') /* skip over blanks or comma */
+ ptr1++;
+
+ } else if (*ptr1 == 'q' || *ptr1 == 'Q') {
+ /* this should be the floating point quantization parameter */
+
+ ptr1++;
+ if (*ptr1 == 'z' || *ptr1 == 'Z') {
+ /* use the subtractive_dither_2 option */
+ quantize_method = SUBTRACTIVE_DITHER_2;
+ ptr1++;
+ } else if (*ptr1 == '0') {
+ /* do not dither */
+ quantize_method = NO_DITHER;
+ ptr1++;
+ }
+
+ while (*ptr1 == ' ') /* ignore leading blanks */
+ ptr1++;
+
+ qlevel = (float) strtod(ptr1, &ptr1);
+
+ while (*ptr1 == ' ' || *ptr1 == ',') /* skip over blanks or comma */
+ ptr1++;
+
+ } else {
+ return(*status = URL_PARSE_ERROR);
+ }
+ }
+ }
+
+ /* ================================= */
+ /* finished parsing; save the values */
+ /* ================================= */
+
+ fits_set_compression_type(fptr, compresstype, status);
+ fits_set_tile_dim(fptr, MAX_COMPRESS_DIM, tilesize, status);
+
+ if (compresstype == HCOMPRESS_1) {
+ fits_set_hcomp_scale (fptr, scale, status);
+ fits_set_hcomp_smooth(fptr, smooth, status);
+ }
+
+ if (qlevel != -99.) {
+ fits_set_quantize_level(fptr, qlevel, status);
+ fits_set_quantize_method(fptr, quantize_method, status);
+ }
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffdkinit(fitsfile **fptr, /* O - FITS file pointer */
+ const char *name, /* I - name of file to create */
+ int *status) /* IO - error status */
+/*
+ Create and initialize a new FITS file on disk. This routine differs
+ from ffinit in that the input 'name' is literally taken as the name
+ of the disk file to be created, and it does not support CFITSIO's
+ extended filename syntax.
+*/
+{
+ *fptr = 0; /* initialize null file pointer, */
+ /* regardless of the value of *status */
+ if (*status > 0)
+ return(*status);
+
+ *status = CREATE_DISK_FILE;
+
+ ffinit(fptr, name,status);
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffinit(fitsfile **fptr, /* O - FITS file pointer */
+ const char *name, /* I - name of file to create */
+ int *status) /* IO - error status */
+/*
+ Create and initialize a new FITS file.
+*/
+{
+ int ii, driver, slen, clobber = 0;
+ char *url;
+ char urltype[MAX_PREFIX_LEN], outfile[FLEN_FILENAME];
+ char tmplfile[FLEN_FILENAME], compspec[80];
+ int handle, create_disk_file = 0;
+
+ *fptr = 0; /* initialize null file pointer, */
+ /* regardless of the value of *status */
+ if (*status > 0)
+ return(*status);
+
+ if (*status == CREATE_DISK_FILE)
+ {
+ create_disk_file = 1;
+ *status = 0;
+ }
+
+ if (need_to_initialize) { /* this is called only once */
+ *status = fits_init_cfitsio();
+ }
+
+ if (*status > 0)
+ return(*status);
+
+ url = (char *) name;
+ while (*url == ' ') /* ignore leading spaces in the filename */
+ url++;
+
+ if (*url == '\0')
+ {
+ ffpmsg("Name of file to create is blank. (ffinit)");
+ return(*status = FILE_NOT_CREATED);
+ }
+
+ if (create_disk_file)
+ {
+ if (strlen(url) > FLEN_FILENAME - 1)
+ {
+ ffpmsg("Filename is too long. (ffinit)");
+ return(*status = FILE_NOT_CREATED);
+ }
+
+ strcpy(outfile, url);
+ strcpy(urltype, "file://");
+ tmplfile[0] = '\0';
+ compspec[0] = '\0';
+ }
+ else
+ {
+
+ /* check for clobber symbol, i.e, overwrite existing file */
+ if (*url == '!')
+ {
+ clobber = TRUE;
+ url++;
+ }
+ else
+ clobber = FALSE;
+
+ /* parse the output file specification */
+ /* this routine checks that the strings will not overflow */
+ ffourl(url, urltype, outfile, tmplfile, compspec, status);
+
+ if (*status > 0)
+ {
+ ffpmsg("could not parse the output filename: (ffinit)");
+ ffpmsg(url);
+ return(*status);
+ }
+ }
+
+ /* find which driver corresponds to the urltype */
+ *status = urltype2driver(urltype, &driver);
+
+ if (*status)
+ {
+ ffpmsg("could not find driver for this file: (ffinit)");
+ ffpmsg(url);
+ return(*status);
+ }
+
+ /* delete pre-existing file, if asked to do so */
+ if (clobber)
+ {
+ if (driverTable[driver].remove)
+ (*driverTable[driver].remove)(outfile);
+ }
+
+ /* call appropriate driver to create the file */
+ if (driverTable[driver].create)
+ {
+
+ FFLOCK; /* lock this while searching for vacant handle */
+ *status = (*driverTable[driver].create)(outfile, &handle);
+ FFUNLOCK;
+
+ if (*status)
+ {
+ ffpmsg("failed to create new file (already exists?):");
+ ffpmsg(url);
+ return(*status);
+ }
+ }
+ else
+ {
+ ffpmsg("cannot create a new file of this type: (ffinit)");
+ ffpmsg(url);
+ return(*status = FILE_NOT_CREATED);
+ }
+
+ /* allocate fitsfile structure and initialize = 0 */
+ *fptr = (fitsfile *) calloc(1, sizeof(fitsfile));
+
+ if (!(*fptr))
+ {
+ (*driverTable[driver].close)(handle); /* close the file */
+ ffpmsg("failed to allocate structure for following file: (ffopen)");
+ ffpmsg(url);
+ return(*status = MEMORY_ALLOCATION);
+ }
+
+ /* allocate FITSfile structure and initialize = 0 */
+ (*fptr)->Fptr = (FITSfile *) calloc(1, sizeof(FITSfile));
+
+ if (!((*fptr)->Fptr))
+ {
+ (*driverTable[driver].close)(handle); /* close the file */
+ ffpmsg("failed to allocate structure for following file: (ffopen)");
+ ffpmsg(url);
+ free(*fptr);
+ *fptr = 0;
+ return(*status = MEMORY_ALLOCATION);
+ }
+
+ slen = strlen(url) + 1;
+ slen = maxvalue(slen, 32); /* reserve at least 32 chars */
+ ((*fptr)->Fptr)->filename = (char *) malloc(slen); /* mem for file name */
+
+ if ( !(((*fptr)->Fptr)->filename) )
+ {
+ (*driverTable[driver].close)(handle); /* close the file */
+ ffpmsg("failed to allocate memory for filename: (ffinit)");
+ ffpmsg(url);
+ free((*fptr)->Fptr);
+ free(*fptr);
+ *fptr = 0; /* return null file pointer */
+ return(*status = FILE_NOT_CREATED);
+ }
+
+ /* mem for headstart array */
+ ((*fptr)->Fptr)->headstart = (LONGLONG *) calloc(1001, sizeof(LONGLONG));
+
+ if ( !(((*fptr)->Fptr)->headstart) )
+ {
+ (*driverTable[driver].close)(handle); /* close the file */
+ ffpmsg("failed to allocate memory for headstart array: (ffinit)");
+ ffpmsg(url);
+ free( ((*fptr)->Fptr)->filename);
+ free((*fptr)->Fptr);
+ free(*fptr);
+ *fptr = 0; /* return null file pointer */
+ return(*status = MEMORY_ALLOCATION);
+ }
+
+ /* mem for file I/O buffers */
+ ((*fptr)->Fptr)->iobuffer = (char *) calloc(NIOBUF, IOBUFLEN);
+
+ if ( !(((*fptr)->Fptr)->iobuffer) )
+ {
+ (*driverTable[driver].close)(handle); /* close the file */
+ ffpmsg("failed to allocate memory for iobuffer array: (ffinit)");
+ ffpmsg(url);
+ free( ((*fptr)->Fptr)->headstart); /* free memory for headstart array */
+ free( ((*fptr)->Fptr)->filename);
+ free((*fptr)->Fptr);
+ free(*fptr);
+ *fptr = 0; /* return null file pointer */
+ return(*status = MEMORY_ALLOCATION);
+ }
+
+ /* initialize the ageindex array (relative age of the I/O buffers) */
+ /* and initialize the bufrecnum array as being empty */
+ for (ii = 0; ii < NIOBUF; ii++) {
+ ((*fptr)->Fptr)->ageindex[ii] = ii;
+ ((*fptr)->Fptr)->bufrecnum[ii] = -1;
+ }
+
+ /* store the parameters describing the file */
+ ((*fptr)->Fptr)->MAXHDU = 1000; /* initial size of headstart */
+ ((*fptr)->Fptr)->filehandle = handle; /* store the file pointer */
+ ((*fptr)->Fptr)->driver = driver; /* driver number */
+ strcpy(((*fptr)->Fptr)->filename, url); /* full input filename */
+ ((*fptr)->Fptr)->filesize = 0; /* physical file size */
+ ((*fptr)->Fptr)->logfilesize = 0; /* logical file size */
+ ((*fptr)->Fptr)->writemode = 1; /* read-write mode */
+ ((*fptr)->Fptr)->datastart = DATA_UNDEFINED; /* unknown start of data */
+ ((*fptr)->Fptr)->curbuf = -1; /* undefined current IO buffer */
+ ((*fptr)->Fptr)->open_count = 1; /* structure is currently used once */
+ ((*fptr)->Fptr)->validcode = VALIDSTRUC; /* flag denoting valid structure */
+
+ ffldrc(*fptr, 0, IGNORE_EOF, status); /* initialize first record */
+
+ fits_store_Fptr( (*fptr)->Fptr, status); /* store Fptr address */
+
+ /* if template file was given, use it to define structure of new file */
+
+ if (tmplfile[0])
+ ffoptplt(*fptr, tmplfile, status);
+
+ /* parse and save image compression specification, if given */
+ if (compspec[0])
+ ffparsecompspec(*fptr, compspec, status);
+
+ return(*status); /* successful return */
+}
+/*--------------------------------------------------------------------------*/
+/* ffimem == fits_create_memfile */
+
+int ffimem(fitsfile **fptr, /* O - FITS file pointer */
+ void **buffptr, /* I - address of memory pointer */
+ size_t *buffsize, /* I - size of buffer, in bytes */
+ size_t deltasize, /* I - increment for future realloc's */
+ void *(*mem_realloc)(void *p, size_t newsize), /* function */
+ int *status) /* IO - error status */
+
+/*
+ Create and initialize a new FITS file in memory
+*/
+{
+ int ii, driver, slen;
+ char urltype[MAX_PREFIX_LEN];
+ int handle;
+
+ if (*status > 0)
+ return(*status);
+
+ *fptr = 0; /* initialize null file pointer */
+
+ if (need_to_initialize) { /* this is called only once */
+ *status = fits_init_cfitsio();
+ }
+
+ if (*status > 0)
+ return(*status);
+
+ strcpy(urltype, "memkeep://"); /* URL type for pre-existing memory file */
+
+ *status = urltype2driver(urltype, &driver);
+
+ if (*status > 0)
+ {
+ ffpmsg("could not find driver for pre-existing memory file: (ffimem)");
+ return(*status);
+ }
+
+ /* call driver routine to "open" the memory file */
+ FFLOCK; /* lock this while searching for vacant handle */
+ *status = mem_openmem( buffptr, buffsize, deltasize,
+ mem_realloc, &handle);
+ FFUNLOCK;
+
+ if (*status > 0)
+ {
+ ffpmsg("failed to open pre-existing memory file: (ffimem)");
+ return(*status);
+ }
+
+ /* allocate fitsfile structure and initialize = 0 */
+ *fptr = (fitsfile *) calloc(1, sizeof(fitsfile));
+
+ if (!(*fptr))
+ {
+ (*driverTable[driver].close)(handle); /* close the file */
+ ffpmsg("failed to allocate structure for memory file: (ffimem)");
+ return(*status = MEMORY_ALLOCATION);
+ }
+
+ /* allocate FITSfile structure and initialize = 0 */
+ (*fptr)->Fptr = (FITSfile *) calloc(1, sizeof(FITSfile));
+
+ if (!((*fptr)->Fptr))
+ {
+ (*driverTable[driver].close)(handle); /* close the file */
+ ffpmsg("failed to allocate structure for memory file: (ffimem)");
+ free(*fptr);
+ *fptr = 0;
+ return(*status = MEMORY_ALLOCATION);
+ }
+
+ slen = 32; /* reserve at least 32 chars */
+ ((*fptr)->Fptr)->filename = (char *) malloc(slen); /* mem for file name */
+
+ if ( !(((*fptr)->Fptr)->filename) )
+ {
+ (*driverTable[driver].close)(handle); /* close the file */
+ ffpmsg("failed to allocate memory for filename: (ffimem)");
+ free((*fptr)->Fptr);
+ free(*fptr);
+ *fptr = 0; /* return null file pointer */
+ return(*status = MEMORY_ALLOCATION);
+ }
+
+ /* mem for headstart array */
+ ((*fptr)->Fptr)->headstart = (LONGLONG *) calloc(1001, sizeof(LONGLONG));
+
+ if ( !(((*fptr)->Fptr)->headstart) )
+ {
+ (*driverTable[driver].close)(handle); /* close the file */
+ ffpmsg("failed to allocate memory for headstart array: (ffimem)");
+ free( ((*fptr)->Fptr)->filename);
+ free((*fptr)->Fptr);
+ free(*fptr);
+ *fptr = 0; /* return null file pointer */
+ return(*status = MEMORY_ALLOCATION);
+ }
+
+ /* mem for file I/O buffers */
+ ((*fptr)->Fptr)->iobuffer = (char *) calloc(NIOBUF, IOBUFLEN);
+
+ if ( !(((*fptr)->Fptr)->iobuffer) )
+ {
+ (*driverTable[driver].close)(handle); /* close the file */
+ ffpmsg("failed to allocate memory for iobuffer array: (ffimem)");
+ free( ((*fptr)->Fptr)->headstart); /* free memory for headstart array */
+ free( ((*fptr)->Fptr)->filename);
+ free((*fptr)->Fptr);
+ free(*fptr);
+ *fptr = 0; /* return null file pointer */
+ return(*status = MEMORY_ALLOCATION);
+ }
+
+ /* initialize the ageindex array (relative age of the I/O buffers) */
+ /* and initialize the bufrecnum array as being empty */
+ for (ii = 0; ii < NIOBUF; ii++) {
+ ((*fptr)->Fptr)->ageindex[ii] = ii;
+ ((*fptr)->Fptr)->bufrecnum[ii] = -1;
+ }
+
+ /* store the parameters describing the file */
+ ((*fptr)->Fptr)->MAXHDU = 1000; /* initial size of headstart */
+ ((*fptr)->Fptr)->filehandle = handle; /* file handle */
+ ((*fptr)->Fptr)->driver = driver; /* driver number */
+ strcpy(((*fptr)->Fptr)->filename, "memfile"); /* dummy filename */
+ ((*fptr)->Fptr)->filesize = *buffsize; /* physical file size */
+ ((*fptr)->Fptr)->logfilesize = *buffsize; /* logical file size */
+ ((*fptr)->Fptr)->writemode = 1; /* read-write mode */
+ ((*fptr)->Fptr)->datastart = DATA_UNDEFINED; /* unknown start of data */
+ ((*fptr)->Fptr)->curbuf = -1; /* undefined current IO buffer */
+ ((*fptr)->Fptr)->open_count = 1; /* structure is currently used once */
+ ((*fptr)->Fptr)->validcode = VALIDSTRUC; /* flag denoting valid structure */
+
+ ffldrc(*fptr, 0, IGNORE_EOF, status); /* initialize first record */
+ fits_store_Fptr( (*fptr)->Fptr, status); /* store Fptr address */
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int fits_init_cfitsio(void)
+/*
+ initialize anything that is required before using the CFITSIO routines
+*/
+{
+ int status;
+
+ union u_tag {
+ short ival;
+ char cval[2];
+ } u;
+
+ fitsio_init_lock();
+
+ FFLOCK; /* lockout other threads while executing this critical */
+ /* section of code */
+
+ if (need_to_initialize == 0) { /* already initialized? */
+ FFUNLOCK;
+ return(0);
+ }
+
+ /* test for correct byteswapping. */
+
+ u.ival = 1;
+ if ((BYTESWAPPED && u.cval[0] != 1) ||
+ (BYTESWAPPED == FALSE && u.cval[1] != 1) )
+ {
+ printf ("\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
+ printf(" Byteswapping is not being done correctly on this system.\n");
+ printf(" Check the MACHINE and BYTESWAPPED definitions in fitsio2.h\n");
+ printf(" Please report this problem to the CFITSIO developers.\n");
+ printf( "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
+ FFUNLOCK;
+ return(1);
+ }
+
+
+ /* test that LONGLONG is an 8 byte integer */
+
+ if (sizeof(LONGLONG) != 8)
+ {
+ printf ("\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
+ printf(" CFITSIO did not find an 8-byte long integer data type.\n");
+ printf(" sizeof(LONGLONG) = %d\n",(int)sizeof(LONGLONG));
+ printf(" Please report this problem to the CFITSIO developers.\n");
+ printf( "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
+ FFUNLOCK;
+ return(1);
+ }
+
+ /* register the standard I/O drivers that are always available */
+
+ /* 1--------------------disk file driver-----------------------*/
+ status = fits_register_driver("file://",
+ file_init,
+ file_shutdown,
+ file_setoptions,
+ file_getoptions,
+ file_getversion,
+ file_checkfile,
+ file_open,
+ file_create,
+#ifdef HAVE_FTRUNCATE
+ file_truncate,
+#else
+ NULL, /* no file truncate function */
+#endif
+ file_close,
+ file_remove,
+ file_size,
+ file_flush,
+ file_seek,
+ file_read,
+ file_write);
+
+ if (status)
+ {
+ ffpmsg("failed to register the file:// driver (init_cfitsio)");
+ FFUNLOCK;
+ return(status);
+ }
+
+ /* 2------------ output temporary memory file driver ----------------*/
+ status = fits_register_driver("mem://",
+ mem_init,
+ mem_shutdown,
+ mem_setoptions,
+ mem_getoptions,
+ mem_getversion,
+ NULL, /* checkfile not needed */
+ NULL, /* open function not allowed */
+ mem_create,
+ mem_truncate,
+ mem_close_free,
+ NULL, /* remove function not required */
+ mem_size,
+ NULL, /* flush function not required */
+ mem_seek,
+ mem_read,
+ mem_write);
+
+
+ if (status)
+ {
+ ffpmsg("failed to register the mem:// driver (init_cfitsio)");
+ FFUNLOCK;
+ return(status);
+ }
+
+ /* 3--------------input pre-existing memory file driver----------------*/
+ status = fits_register_driver("memkeep://",
+ NULL,
+ mem_shutdown,
+ mem_setoptions,
+ mem_getoptions,
+ mem_getversion,
+ NULL, /* checkfile not needed */
+ NULL, /* file open driver function is not used */
+ NULL, /* create function not allowed */
+ mem_truncate,
+ mem_close_keep,
+ NULL, /* remove function not required */
+ mem_size,
+ NULL, /* flush function not required */
+ mem_seek,
+ mem_read,
+ mem_write);
+
+
+ if (status)
+ {
+ ffpmsg("failed to register the memkeep:// driver (init_cfitsio)");
+ FFUNLOCK;
+ return(status);
+ }
+
+ /* 4-------------------stdin stream driver----------------------*/
+ /* the stdin stream is copied to memory then opened in memory */
+
+ status = fits_register_driver("stdin://",
+ NULL,
+ mem_shutdown,
+ mem_setoptions,
+ mem_getoptions,
+ mem_getversion,
+ stdin_checkfile,
+ stdin_open,
+ NULL, /* create function not allowed */
+ mem_truncate,
+ mem_close_free,
+ NULL, /* remove function not required */
+ mem_size,
+ NULL, /* flush function not required */
+ mem_seek,
+ mem_read,
+ mem_write);
+
+ if (status)
+ {
+ ffpmsg("failed to register the stdin:// driver (init_cfitsio)");
+ FFUNLOCK;
+ return(status);
+ }
+
+ /* 5-------------------stdin file stream driver----------------------*/
+ /* the stdin stream is copied to a disk file then the disk file is opened */
+
+ status = fits_register_driver("stdinfile://",
+ NULL,
+ mem_shutdown,
+ mem_setoptions,
+ mem_getoptions,
+ mem_getversion,
+ NULL, /* checkfile not needed */
+ stdin_open,
+ NULL, /* create function not allowed */
+#ifdef HAVE_FTRUNCATE
+ file_truncate,
+#else
+ NULL, /* no file truncate function */
+#endif
+ file_close,
+ file_remove,
+ file_size,
+ file_flush,
+ file_seek,
+ file_read,
+ file_write);
+
+ if (status)
+ {
+ ffpmsg("failed to register the stdinfile:// driver (init_cfitsio)");
+ FFUNLOCK;
+ return(status);
+ }
+
+
+ /* 6-----------------------stdout stream driver------------------*/
+ status = fits_register_driver("stdout://",
+ NULL,
+ mem_shutdown,
+ mem_setoptions,
+ mem_getoptions,
+ mem_getversion,
+ NULL, /* checkfile not needed */
+ NULL, /* open function not required */
+ mem_create,
+ mem_truncate,
+ stdout_close,
+ NULL, /* remove function not required */
+ mem_size,
+ NULL, /* flush function not required */
+ mem_seek,
+ mem_read,
+ mem_write);
+
+ if (status)
+ {
+ ffpmsg("failed to register the stdout:// driver (init_cfitsio)");
+ FFUNLOCK;
+ return(status);
+ }
+
+ /* 7------------------iraf disk file to memory driver -----------*/
+ status = fits_register_driver("irafmem://",
+ NULL,
+ mem_shutdown,
+ mem_setoptions,
+ mem_getoptions,
+ mem_getversion,
+ NULL, /* checkfile not needed */
+ mem_iraf_open,
+ NULL, /* create function not required */
+ mem_truncate,
+ mem_close_free,
+ NULL, /* remove function not required */
+ mem_size,
+ NULL, /* flush function not required */
+ mem_seek,
+ mem_read,
+ mem_write);
+
+ if (status)
+ {
+ ffpmsg("failed to register the irafmem:// driver (init_cfitsio)");
+ FFUNLOCK;
+ return(status);
+ }
+
+ /* 8------------------raw binary file to memory driver -----------*/
+ status = fits_register_driver("rawfile://",
+ NULL,
+ mem_shutdown,
+ mem_setoptions,
+ mem_getoptions,
+ mem_getversion,
+ NULL, /* checkfile not needed */
+ mem_rawfile_open,
+ NULL, /* create function not required */
+ mem_truncate,
+ mem_close_free,
+ NULL, /* remove function not required */
+ mem_size,
+ NULL, /* flush function not required */
+ mem_seek,
+ mem_read,
+ mem_write);
+
+ if (status)
+ {
+ ffpmsg("failed to register the rawfile:// driver (init_cfitsio)");
+ FFUNLOCK;
+ return(status);
+ }
+
+ /* 9------------------compressed disk file to memory driver -----------*/
+ status = fits_register_driver("compress://",
+ NULL,
+ mem_shutdown,
+ mem_setoptions,
+ mem_getoptions,
+ mem_getversion,
+ NULL, /* checkfile not needed */
+ mem_compress_open,
+ NULL, /* create function not required */
+ mem_truncate,
+ mem_close_free,
+ NULL, /* remove function not required */
+ mem_size,
+ NULL, /* flush function not required */
+ mem_seek,
+ mem_read,
+ mem_write);
+
+ if (status)
+ {
+ ffpmsg("failed to register the compress:// driver (init_cfitsio)");
+ FFUNLOCK;
+ return(status);
+ }
+
+ /* 10------------------compressed disk file to memory driver -----------*/
+ /* Identical to compress://, except it allows READWRITE access */
+
+ status = fits_register_driver("compressmem://",
+ NULL,
+ mem_shutdown,
+ mem_setoptions,
+ mem_getoptions,
+ mem_getversion,
+ NULL, /* checkfile not needed */
+ mem_compress_openrw,
+ NULL, /* create function not required */
+ mem_truncate,
+ mem_close_free,
+ NULL, /* remove function not required */
+ mem_size,
+ NULL, /* flush function not required */
+ mem_seek,
+ mem_read,
+ mem_write);
+
+ if (status)
+ {
+ ffpmsg("failed to register the compressmem:// driver (init_cfitsio)");
+ FFUNLOCK;
+ return(status);
+ }
+
+ /* 11------------------compressed disk file to disk file driver -------*/
+ status = fits_register_driver("compressfile://",
+ NULL,
+ file_shutdown,
+ file_setoptions,
+ file_getoptions,
+ file_getversion,
+ NULL, /* checkfile not needed */
+ file_compress_open,
+ file_create,
+#ifdef HAVE_FTRUNCATE
+ file_truncate,
+#else
+ NULL, /* no file truncate function */
+#endif
+ file_close,
+ file_remove,
+ file_size,
+ file_flush,
+ file_seek,
+ file_read,
+ file_write);
+
+ if (status)
+ {
+ ffpmsg("failed to register the compressfile:// driver (init_cfitsio)");
+ FFUNLOCK;
+ return(status);
+ }
+
+ /* 12---create file in memory, then compress it to disk file on close--*/
+ status = fits_register_driver("compressoutfile://",
+ NULL,
+ mem_shutdown,
+ mem_setoptions,
+ mem_getoptions,
+ mem_getversion,
+ NULL, /* checkfile not needed */
+ NULL, /* open function not allowed */
+ mem_create_comp,
+ mem_truncate,
+ mem_close_comp,
+ file_remove, /* delete existing compressed disk file */
+ mem_size,
+ NULL, /* flush function not required */
+ mem_seek,
+ mem_read,
+ mem_write);
+
+
+ if (status)
+ {
+ ffpmsg(
+ "failed to register the compressoutfile:// driver (init_cfitsio)");
+ FFUNLOCK;
+ return(status);
+ }
+
+ /* Register Optional drivers */
+
+#ifdef HAVE_NET_SERVICES
+
+ /* 13--------------------root driver-----------------------*/
+
+ status = fits_register_driver("root://",
+ root_init,
+ root_shutdown,
+ root_setoptions,
+ root_getoptions,
+ root_getversion,
+ NULL, /* checkfile not needed */
+ root_open,
+ root_create,
+ NULL, /* No truncate possible */
+ root_close,
+ NULL, /* No remove possible */
+ root_size, /* no size possible */
+ root_flush,
+ root_seek, /* Though will always succeed */
+ root_read,
+ root_write);
+
+ if (status)
+ {
+ ffpmsg("failed to register the root:// driver (init_cfitsio)");
+ FFUNLOCK;
+ return(status);
+ }
+
+ /* 14--------------------http driver-----------------------*/
+ status = fits_register_driver("http://",
+ NULL,
+ mem_shutdown,
+ mem_setoptions,
+ mem_getoptions,
+ mem_getversion,
+ http_checkfile,
+ http_open,
+ NULL, /* create function not required */
+ mem_truncate,
+ mem_close_free,
+ NULL, /* remove function not required */
+ mem_size,
+ NULL, /* flush function not required */
+ mem_seek,
+ mem_read,
+ mem_write);
+
+ if (status)
+ {
+ ffpmsg("failed to register the http:// driver (init_cfitsio)");
+ FFUNLOCK;
+ return(status);
+ }
+
+ /* 15--------------------http file driver-----------------------*/
+
+ status = fits_register_driver("httpfile://",
+ NULL,
+ file_shutdown,
+ file_setoptions,
+ file_getoptions,
+ file_getversion,
+ NULL, /* checkfile not needed */
+ http_file_open,
+ file_create,
+#ifdef HAVE_FTRUNCATE
+ file_truncate,
+#else
+ NULL, /* no file truncate function */
+#endif
+ file_close,
+ file_remove,
+ file_size,
+ file_flush,
+ file_seek,
+ file_read,
+ file_write);
+
+ if (status)
+ {
+ ffpmsg("failed to register the httpfile:// driver (init_cfitsio)");
+ FFUNLOCK;
+ return(status);
+ }
+
+ /* 16--------------------http memory driver-----------------------*/
+ /* same as http:// driver, except memory file can be opened READWRITE */
+ status = fits_register_driver("httpmem://",
+ NULL,
+ mem_shutdown,
+ mem_setoptions,
+ mem_getoptions,
+ mem_getversion,
+ http_checkfile,
+ http_file_open, /* this will simply call http_open */
+ NULL, /* create function not required */
+ mem_truncate,
+ mem_close_free,
+ NULL, /* remove function not required */
+ mem_size,
+ NULL, /* flush function not required */
+ mem_seek,
+ mem_read,
+ mem_write);
+
+ if (status)
+ {
+ ffpmsg("failed to register the httpmem:// driver (init_cfitsio)");
+ FFUNLOCK;
+ return(status);
+ }
+
+ /* 17--------------------httpcompress file driver-----------------------*/
+
+ status = fits_register_driver("httpcompress://",
+ NULL,
+ mem_shutdown,
+ mem_setoptions,
+ mem_getoptions,
+ mem_getversion,
+ NULL, /* checkfile not needed */
+ http_compress_open,
+ NULL, /* create function not required */
+ mem_truncate,
+ mem_close_free,
+ NULL, /* remove function not required */
+ mem_size,
+ NULL, /* flush function not required */
+ mem_seek,
+ mem_read,
+ mem_write);
+
+ if (status)
+ {
+ ffpmsg("failed to register the httpcompress:// driver (init_cfitsio)");
+ FFUNLOCK;
+ return(status);
+ }
+
+
+ /* 18--------------------ftp driver-----------------------*/
+ status = fits_register_driver("ftp://",
+ NULL,
+ mem_shutdown,
+ mem_setoptions,
+ mem_getoptions,
+ mem_getversion,
+ ftp_checkfile,
+ ftp_open,
+ NULL, /* create function not required */
+ mem_truncate,
+ mem_close_free,
+ NULL, /* remove function not required */
+ mem_size,
+ NULL, /* flush function not required */
+ mem_seek,
+ mem_read,
+ mem_write);
+
+ if (status)
+ {
+ ffpmsg("failed to register the ftp:// driver (init_cfitsio)");
+ FFUNLOCK;
+ return(status);
+ }
+
+ /* 19--------------------ftp file driver-----------------------*/
+ status = fits_register_driver("ftpfile://",
+ NULL,
+ file_shutdown,
+ file_setoptions,
+ file_getoptions,
+ file_getversion,
+ NULL, /* checkfile not needed */
+ ftp_file_open,
+ file_create,
+#ifdef HAVE_FTRUNCATE
+ file_truncate,
+#else
+ NULL, /* no file truncate function */
+#endif
+ file_close,
+ file_remove,
+ file_size,
+ file_flush,
+ file_seek,
+ file_read,
+ file_write);
+
+ if (status)
+ {
+ ffpmsg("failed to register the ftpfile:// driver (init_cfitsio)");
+ FFUNLOCK;
+ return(status);
+ }
+
+ /* 20--------------------ftp mem driver-----------------------*/
+ /* same as ftp:// driver, except memory file can be opened READWRITE */
+ status = fits_register_driver("ftpmem://",
+ NULL,
+ mem_shutdown,
+ mem_setoptions,
+ mem_getoptions,
+ mem_getversion,
+ ftp_checkfile,
+ ftp_file_open, /* this will simply call ftp_open */
+ NULL, /* create function not required */
+ mem_truncate,
+ mem_close_free,
+ NULL, /* remove function not required */
+ mem_size,
+ NULL, /* flush function not required */
+ mem_seek,
+ mem_read,
+ mem_write);
+
+ if (status)
+ {
+ ffpmsg("failed to register the ftpmem:// driver (init_cfitsio)");
+ FFUNLOCK;
+ return(status);
+ }
+
+ /* 21--------------------ftp compressed file driver------------------*/
+ status = fits_register_driver("ftpcompress://",
+ NULL,
+ mem_shutdown,
+ mem_setoptions,
+ mem_getoptions,
+ mem_getversion,
+ NULL, /* checkfile not needed */
+ ftp_compress_open,
+ 0, /* create function not required */
+ mem_truncate,
+ mem_close_free,
+ 0, /* remove function not required */
+ mem_size,
+ 0, /* flush function not required */
+ mem_seek,
+ mem_read,
+ mem_write);
+
+ if (status)
+ {
+ ffpmsg("failed to register the ftpcompress:// driver (init_cfitsio)");
+ FFUNLOCK;
+ return(status);
+ }
+ /* === End of net drivers section === */
+#endif
+
+/* ==================== SHARED MEMORY DRIVER SECTION ======================= */
+
+#ifdef HAVE_SHMEM_SERVICES
+
+ /* 22--------------------shared memory driver-----------------------*/
+ status = fits_register_driver("shmem://",
+ smem_init,
+ smem_shutdown,
+ smem_setoptions,
+ smem_getoptions,
+ smem_getversion,
+ NULL, /* checkfile not needed */
+ smem_open,
+ smem_create,
+ NULL, /* truncate file not supported yet */
+ smem_close,
+ smem_remove,
+ smem_size,
+ smem_flush,
+ smem_seek,
+ smem_read,
+ smem_write );
+
+ if (status)
+ {
+ ffpmsg("failed to register the shmem:// driver (init_cfitsio)");
+ FFUNLOCK;
+ return(status);
+ }
+
+#endif
+/* ==================== END OF SHARED MEMORY DRIVER SECTION ================ */
+
+
+#ifdef HAVE_GSIFTP
+ /* 23--------------------gsiftp driver-----------------------*/
+ status = fits_register_driver("gsiftp://",
+ gsiftp_init,
+ gsiftp_shutdown,
+ gsiftp_setoptions,
+ gsiftp_getoptions,
+ gsiftp_getversion,
+ gsiftp_checkfile,
+ gsiftp_open,
+ gsiftp_create,
+#ifdef HAVE_FTRUNCATE
+ gsiftp_truncate,
+#else
+ NULL,
+#endif
+ gsiftp_close,
+ NULL, /* remove function not yet implemented */
+ gsiftp_size,
+ gsiftp_flush,
+ gsiftp_seek,
+ gsiftp_read,
+ gsiftp_write);
+
+ if (status)
+ {
+ ffpmsg("failed to register the gsiftp:// driver (init_cfitsio)");
+ FFUNLOCK;
+ return(status);
+ }
+
+#endif
+
+ /* 24---------------stdin and stdout stream driver-------------------*/
+ status = fits_register_driver("stream://",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ stream_open,
+ stream_create,
+ NULL, /* no stream truncate function */
+ stream_close,
+ NULL, /* no stream remove */
+ stream_size,
+ stream_flush,
+ stream_seek,
+ stream_read,
+ stream_write);
+
+ if (status)
+ {
+ ffpmsg("failed to register the stream:// driver (init_cfitsio)");
+ FFUNLOCK;
+ return(status);
+ }
+
+ /* reset flag. Any other threads will now not need to call this routine */
+ need_to_initialize = 0;
+
+ FFUNLOCK;
+ return(status);
+}
+/*--------------------------------------------------------------------------*/
+int fits_register_driver(char *prefix,
+ int (*init)(void),
+ int (*shutdown)(void),
+ int (*setoptions)(int option),
+ int (*getoptions)(int *options),
+ int (*getversion)(int *version),
+ int (*checkfile) (char *urltype, char *infile, char *outfile),
+ int (*open)(char *filename, int rwmode, int *driverhandle),
+ int (*create)(char *filename, int *driverhandle),
+ int (*truncate)(int driverhandle, LONGLONG filesize),
+ int (*close)(int driverhandle),
+ int (*fremove)(char *filename),
+ int (*size)(int driverhandle, LONGLONG *sizex),
+ int (*flush)(int driverhandle),
+ int (*seek)(int driverhandle, LONGLONG offset),
+ int (*read) (int driverhandle, void *buffer, long nbytes),
+ int (*write)(int driverhandle, void *buffer, long nbytes) )
+/*
+ register all the functions needed to support an I/O driver
+*/
+{
+ int status;
+
+ if (no_of_drivers < 0 ) {
+ /* This is bad. looks like memory has been corrupted. */
+ ffpmsg("Vital CFITSIO parameters held in memory have been corrupted!!");
+ ffpmsg("Fatal condition detected in fits_register_driver.");
+ return(TOO_MANY_DRIVERS);
+ }
+
+ if (no_of_drivers + 1 > MAX_DRIVERS)
+ return(TOO_MANY_DRIVERS);
+
+ if (prefix == NULL)
+ return(BAD_URL_PREFIX);
+
+
+ if (init != NULL)
+ {
+ status = (*init)(); /* initialize the driver */
+ if (status)
+ return(status);
+ }
+
+ /* fill in data in table */
+ strncpy(driverTable[no_of_drivers].prefix, prefix, MAX_PREFIX_LEN);
+ driverTable[no_of_drivers].prefix[MAX_PREFIX_LEN - 1] = 0;
+ driverTable[no_of_drivers].init = init;
+ driverTable[no_of_drivers].shutdown = shutdown;
+ driverTable[no_of_drivers].setoptions = setoptions;
+ driverTable[no_of_drivers].getoptions = getoptions;
+ driverTable[no_of_drivers].getversion = getversion;
+ driverTable[no_of_drivers].checkfile = checkfile;
+ driverTable[no_of_drivers].open = open;
+ driverTable[no_of_drivers].create = create;
+ driverTable[no_of_drivers].truncate = truncate;
+ driverTable[no_of_drivers].close = close;
+ driverTable[no_of_drivers].remove = fremove;
+ driverTable[no_of_drivers].size = size;
+ driverTable[no_of_drivers].flush = flush;
+ driverTable[no_of_drivers].seek = seek;
+ driverTable[no_of_drivers].read = read;
+ driverTable[no_of_drivers].write = write;
+
+ no_of_drivers++; /* increment the number of drivers */
+ return(0);
+ }
+/*--------------------------------------------------------------------------*/
+/* fits_parse_input_url */
+int ffiurl(char *url, /* input filename */
+ char *urltype, /* e.g., 'file://', 'http://', 'mem://' */
+ char *infilex, /* root filename (may be complete path) */
+ char *outfile, /* optional output file name */
+ char *extspec, /* extension spec: +n or [extname, extver] */
+ char *rowfilterx, /* boolean row filter expression */
+ char *binspec, /* histogram binning specifier */
+ char *colspec, /* column or keyword modifier expression */
+ int *status)
+/*
+ parse the input URL into its basic components.
+ This routine does not support the pixfilter or compspec components.
+*/
+{
+ return ffifile2(url, urltype, infilex, outfile,
+ extspec, rowfilterx, binspec, colspec, 0, 0, status);
+}
+/*--------------------------------------------------------------------------*/
+/* fits_parse_input_file */
+int ffifile(char *url, /* input filename */
+ char *urltype, /* e.g., 'file://', 'http://', 'mem://' */
+ char *infilex, /* root filename (may be complete path) */
+ char *outfile, /* optional output file name */
+ char *extspec, /* extension spec: +n or [extname, extver] */
+ char *rowfilterx, /* boolean row filter expression */
+ char *binspec, /* histogram binning specifier */
+ char *colspec, /* column or keyword modifier expression */
+ char *pixfilter, /* pixel filter expression */
+ int *status)
+/*
+ fits_parse_input_filename
+ parse the input URL into its basic components.
+ This routine does not support the compspec component.
+*/
+{
+ return ffifile2(url, urltype, infilex, outfile,
+ extspec, rowfilterx, binspec, colspec, pixfilter, 0, status);
+
+}
+/*--------------------------------------------------------------------------*/
+int ffifile2(char *url, /* input filename */
+ char *urltype, /* e.g., 'file://', 'http://', 'mem://' */
+ char *infilex, /* root filename (may be complete path) */
+ char *outfile, /* optional output file name */
+ char *extspec, /* extension spec: +n or [extname, extver] */
+ char *rowfilterx, /* boolean row filter expression */
+ char *binspec, /* histogram binning specifier */
+ char *colspec, /* column or keyword modifier expression */
+ char *pixfilter, /* pixel filter expression */
+ char *compspec, /* image compression specification */
+ int *status)
+/*
+ fits_parse_input_filename
+ parse the input URL into its basic components.
+ This routine is big and ugly and should be redesigned someday!
+*/
+{
+ int ii, jj, slen, infilelen, plus_ext = 0, collen;
+ char *ptr1, *ptr2, *ptr3, *ptr4, *tmptr;
+ int hasAt, hasDot, hasOper, followingOper, spaceTerm, rowFilter;
+ int colStart, binStart, pixStart, compStart;
+
+
+ /* must have temporary variable for these, in case inputs are NULL */
+ char *infile;
+ char *rowfilter;
+ char *tmpstr;
+
+ if (*status > 0)
+ return(*status);
+
+ /* Initialize null strings */
+ if (infilex) *infilex = '\0';
+ if (urltype) *urltype = '\0';
+ if (outfile) *outfile = '\0';
+ if (extspec) *extspec = '\0';
+ if (binspec) *binspec = '\0';
+ if (colspec) *colspec = '\0';
+ if (rowfilterx) *rowfilterx = '\0';
+ if (pixfilter) *pixfilter = '\0';
+ if (compspec) *compspec = '\0';
+ slen = strlen(url);
+
+ if (slen == 0) /* blank filename ?? */
+ return(*status);
+
+ /* allocate memory for 3 strings, each as long as the input url */
+ infile = (char *) calloc(3, slen + 1);
+ if (!infile)
+ return(*status = MEMORY_ALLOCATION);
+
+ rowfilter = &infile[slen + 1];
+ tmpstr = &rowfilter[slen + 1];
+
+ ptr1 = url;
+
+ /* -------------------------------------------------------- */
+ /* get urltype (e.g., file://, ftp://, http://, etc.) */
+ /* --------------------------------------------------------- */
+
+ if (*ptr1 == '-' && ( *(ptr1 +1) == 0 || *(ptr1 +1) == ' ' ||
+ *(ptr1 +1) == '[' || *(ptr1 +1) == '(' ) )
+ {
+ /* "-" means read file from stdin. Also support "- ", */
+ /* "-[extname]" and '-(outfile.fits)" but exclude disk file */
+ /* names that begin with a minus sign, e.g., "-55d33m.fits" */
+
+ if (urltype)
+ strcat(urltype, "stdin://");
+ ptr1++;
+ }
+ else if (!strncasecmp(ptr1, "stdin", 5))
+ {
+ if (urltype)
+ strcat(urltype, "stdin://");
+ ptr1 = ptr1 + 5;
+ }
+ else
+ {
+ ptr2 = strstr(ptr1, "://");
+ ptr3 = strstr(ptr1, "(" );
+
+ if (ptr3 && (ptr3 < ptr2) )
+ {
+ /* the urltype follows a '(' character, so it must apply */
+ /* to the output file, and is not the urltype of the input file */
+ ptr2 = 0; /* so reset pointer to zero */
+ }
+
+ if (ptr2) /* copy the explicit urltype string */
+ {
+ if (urltype)
+ strncat(urltype, ptr1, ptr2 - ptr1 + 3);
+ ptr1 = ptr2 + 3;
+ }
+ else if (!strncmp(ptr1, "ftp:", 4) )
+ { /* the 2 //'s are optional */
+ if (urltype)
+ strcat(urltype, "ftp://");
+ ptr1 += 4;
+ }
+ else if (!strncmp(ptr1, "gsiftp:", 7) )
+ { /* the 2 //'s are optional */
+ if (urltype)
+ strcat(urltype, "gsiftp://");
+ ptr1 += 7;
+ }
+ else if (!strncmp(ptr1, "http:", 5) )
+ { /* the 2 //'s are optional */
+ if (urltype)
+ strcat(urltype, "http://");
+ ptr1 += 5;
+ }
+ else if (!strncmp(ptr1, "mem:", 4) )
+ { /* the 2 //'s are optional */
+ if (urltype)
+ strcat(urltype, "mem://");
+ ptr1 += 4;
+ }
+ else if (!strncmp(ptr1, "shmem:", 6) )
+ { /* the 2 //'s are optional */
+ if (urltype)
+ strcat(urltype, "shmem://");
+ ptr1 += 6;
+ }
+ else if (!strncmp(ptr1, "file:", 5) )
+ { /* the 2 //'s are optional */
+ if (urltype)
+ strcat(urltype, "file://");
+ ptr1 += 5;
+ }
+ else /* assume file driver */
+ {
+ if (urltype)
+ strcat(urltype, "file://");
+ }
+ }
+
+ /* ----------------------------------------------------------
+ If this is a http:// type file, then the cgi file name could
+ include the '[' character, which should not be interpreted
+ as part of CFITSIO's Extended File Name Syntax. Test for this
+ case by seeing if the last character is a ']' or ')'. If it
+ is not, then just treat the whole input string as the file name
+ and do not attempt to interprete the name using the extended
+ filename syntax.
+ ----------------------------------------------------------- */
+
+ if (urltype && !strncmp(urltype, "http://", 7) )
+ {
+ /* test for opening parenthesis or bracket in the file name */
+ if( strchr(ptr1, '(' ) || strchr(ptr1, '[' ) )
+ {
+ slen = strlen(ptr1);
+ ptr3 = ptr1 + slen - 1;
+ while (*ptr3 == ' ') /* ignore trailing blanks */
+ ptr3--;
+
+ if (*ptr3 != ']' && *ptr3 != ')' )
+ {
+ /* name doesn't end with a ']' or ')' so don't try */
+ /* to parse this unusual string (may be cgi string) */
+ if (infilex) {
+
+ if (strlen(ptr1) > FLEN_FILENAME - 1) {
+ ffpmsg("Name of file is too long.");
+ return(*status = URL_PARSE_ERROR);
+ }
+
+ strcpy(infilex, ptr1);
+ }
+
+ free(infile);
+ return(*status);
+ }
+ }
+ }
+
+ /* ----------------------------------------------------------
+ Look for VMS style filenames like:
+ disk:[directory.subdirectory]filename.ext, or
+ [directory.subdirectory]filename.ext
+
+ Check if the first character is a '[' and urltype != stdin
+ or if there is a ':[' string in the remaining url string. If
+ so, then need to move past this bracket character before
+ search for the opening bracket of a filter specification.
+ ----------------------------------------------------------- */
+
+ tmptr = ptr1;
+ if (*ptr1 == '[')
+ {
+ if (*url != '-')
+ tmptr = ptr1 + 1; /* this bracket encloses a VMS directory name */
+ }
+ else
+ {
+ tmptr = strstr(ptr1, ":[");
+ if (tmptr) /* these 2 chars are part of the VMS disk and directory */
+ tmptr += 2;
+ else
+ tmptr = ptr1;
+ }
+
+ /* ------------------------ */
+ /* get the input file name */
+ /* ------------------------ */
+
+ ptr2 = strchr(tmptr, '('); /* search for opening parenthesis ( */
+ ptr3 = strchr(tmptr, '['); /* search for opening bracket [ */
+
+ if (ptr2 == ptr3) /* simple case: no [ or ( in the file name */
+ {
+ strcat(infile, ptr1);
+ }
+ else if (!ptr3 || /* no bracket, so () enclose output file name */
+ (ptr2 && (ptr2 < ptr3)) ) /* () enclose output name before bracket */
+ {
+ strncat(infile, ptr1, ptr2 - ptr1);
+ ptr2++;
+
+ ptr1 = strchr(ptr2, ')' ); /* search for closing ) */
+ if (!ptr1)
+ {
+ free(infile);
+ return(*status = URL_PARSE_ERROR); /* error, no closing ) */
+ }
+
+ if (outfile) {
+
+ if (ptr1 - ptr2 > FLEN_FILENAME - 1)
+ {
+ free(infile);
+ return(*status = URL_PARSE_ERROR);
+ }
+
+ strncat(outfile, ptr2, ptr1 - ptr2);
+ }
+
+ /* the opening [ could have been part of output name, */
+ /* e.g., file(out[compress])[3][#row > 5] */
+ /* so search again for opening bracket following the closing ) */
+ ptr3 = strchr(ptr1, '[');
+
+ }
+ else /* bracket comes first, so there is no output name */
+ {
+ strncat(infile, ptr1, ptr3 - ptr1);
+ }
+
+ /* strip off any trailing blanks in the names */
+
+ slen = strlen(infile);
+ while ( (--slen) > 0 && infile[slen] == ' ')
+ infile[slen] = '\0';
+
+ if (outfile)
+ {
+ slen = strlen(outfile);
+ while ( (--slen) > 0 && outfile[slen] == ' ')
+ outfile[slen] = '\0';
+ }
+
+ /* --------------------------------------------- */
+ /* check if this is an IRAF file (.imh extension */
+ /* --------------------------------------------- */
+
+ ptr4 = strstr(infile, ".imh");
+
+ /* did the infile name end with ".imh" ? */
+ if (ptr4 && (*(ptr4 + 4) == '\0'))
+ {
+ if (urltype)
+ strcpy(urltype, "irafmem://");
+ }
+
+ /* --------------------------------------------- */
+ /* check if the 'filename+n' convention has been */
+ /* used to specifiy which HDU number to open */
+ /* --------------------------------------------- */
+
+ jj = strlen(infile);
+
+ for (ii = jj - 1; ii >= 0; ii--)
+ {
+ if (infile[ii] == '+') /* search backwards for '+' sign */
+ break;
+ }
+
+ if (ii > 0 && (jj - ii) < 7) /* limit extension numbers to 5 digits */
+ {
+ infilelen = ii;
+ ii++;
+ ptr1 = infile+ii; /* pointer to start of sequence */
+
+ for (; ii < jj; ii++)
+ {
+ if (!isdigit((int) infile[ii] ) ) /* are all the chars digits? */
+ break;
+ }
+
+ if (ii == jj)
+ {
+ /* yes, the '+n' convention was used. Copy */
+ /* the digits to the output extspec string. */
+ plus_ext = 1;
+
+ if (extspec) {
+ if (jj - infilelen > FLEN_FILENAME - 1)
+ {
+ free(infile);
+ return(*status = URL_PARSE_ERROR);
+ }
+
+ strncpy(extspec, ptr1, jj - infilelen);
+ }
+
+ infile[infilelen] = '\0'; /* delete the extension number */
+ }
+ }
+
+ /* -------------------------------------------------------------------- */
+ /* if '*' was given for the output name expand it to the root file name */
+ /* -------------------------------------------------------------------- */
+
+ if (outfile && outfile[0] == '*')
+ {
+ /* scan input name backwards to the first '/' character */
+ for (ii = jj - 1; ii >= 0; ii--)
+ {
+ if (infile[ii] == '/' || ii == 0)
+ {
+ if (strlen(&infile[ii + 1]) > FLEN_FILENAME - 1)
+ {
+ free(infile);
+ return(*status = URL_PARSE_ERROR);
+ }
+
+ strcpy(outfile, &infile[ii + 1]);
+ break;
+ }
+ }
+ }
+
+ /* ------------------------------------------ */
+ /* copy strings from local copy to the output */
+ /* ------------------------------------------ */
+ if (infilex) {
+ if (strlen(infile) > FLEN_FILENAME - 1)
+ {
+ free(infile);
+ return(*status = URL_PARSE_ERROR);
+ }
+
+ strcpy(infilex, infile);
+ }
+ /* ---------------------------------------------------------- */
+ /* if no '[' character in the input string, then we are done. */
+ /* ---------------------------------------------------------- */
+ if (!ptr3)
+ {
+ free(infile);
+ return(*status);
+ }
+
+ /* ------------------------------------------- */
+ /* see if [ extension specification ] is given */
+ /* ------------------------------------------- */
+
+ if (!plus_ext) /* extension no. not already specified? Then */
+ /* first brackets must enclose extension name or # */
+ /* or it encloses a image subsection specification */
+ /* or a raw binary image specifier */
+ /* or a image compression specifier */
+
+ /* Or, the extension specification may have been */
+ /* omitted and we have to guess what the user intended */
+ {
+ ptr1 = ptr3 + 1; /* pointer to first char after the [ */
+
+ ptr2 = strchr(ptr1, ']' ); /* search for closing ] */
+ if (!ptr2)
+ {
+ ffpmsg("input file URL is missing closing bracket ']'");
+ free(infile);
+ return(*status = URL_PARSE_ERROR); /* error, no closing ] */
+ }
+
+ /* ---------------------------------------------- */
+ /* First, test if this is a rawfile specifier */
+ /* which looks something like: '[ib512,512:2880]' */
+ /* Test if first character is b,i,j,d,r,f, or u, */
+ /* and optional second character is b or l, */
+ /* followed by one or more digits, */
+ /* finally followed by a ',', ':', or ']' */
+ /* ---------------------------------------------- */
+
+ if (*ptr1 == 'b' || *ptr1 == 'B' || *ptr1 == 'i' || *ptr1 == 'I' ||
+ *ptr1 == 'j' || *ptr1 == 'J' || *ptr1 == 'd' || *ptr1 == 'D' ||
+ *ptr1 == 'r' || *ptr1 == 'R' || *ptr1 == 'f' || *ptr1 == 'F' ||
+ *ptr1 == 'u' || *ptr1 == 'U')
+ {
+ /* next optional character may be a b or l (for Big or Little) */
+ ptr1++;
+ if (*ptr1 == 'b' || *ptr1 == 'B' || *ptr1 == 'l' || *ptr1 == 'L')
+ ptr1++;
+
+ if (isdigit((int) *ptr1)) /* must have at least 1 digit */
+ {
+ while (isdigit((int) *ptr1))
+ ptr1++; /* skip over digits */
+
+ if (*ptr1 == ',' || *ptr1 == ':' || *ptr1 == ']' )
+ {
+ /* OK, this looks like a rawfile specifier */
+
+ if (urltype)
+ {
+ if (strstr(urltype, "stdin") )
+ strcpy(urltype, "rawstdin://");
+ else
+ strcpy(urltype, "rawfile://");
+ }
+
+ /* append the raw array specifier to infilex */
+ if (infilex)
+ {
+
+ if (strlen(infilex) + strlen(ptr3) > FLEN_FILENAME - 1)
+ {
+ free(infile);
+ return(*status = URL_PARSE_ERROR);
+ }
+
+ strcat(infilex, ptr3);
+ ptr1 = strchr(infilex, ']'); /* find the closing ] char */
+ if (ptr1)
+ *(ptr1 + 1) = '\0'; /* terminate string after the ] */
+ }
+
+ if (extspec)
+ strcpy(extspec, "0"); /* the 0 ext number is implicit */
+
+ tmptr = strchr(ptr2 + 1, '[' ); /* search for another [ char */
+
+ /* copy any remaining characters into rowfilterx */
+ if (tmptr && rowfilterx)
+ {
+
+
+ if (strlen(rowfilterx) + strlen(tmptr + 1) > FLEN_FILENAME -1)
+ {
+ free(infile);
+ return(*status = URL_PARSE_ERROR);
+ }
+
+ strcat(rowfilterx, tmptr + 1);
+
+ tmptr = strchr(rowfilterx, ']' ); /* search for closing ] */
+ if (tmptr)
+ *tmptr = '\0'; /* overwrite the ] with null terminator */
+ }
+
+ free(infile); /* finished parsing, so return */
+ return(*status);
+ }
+ }
+ } /* end of rawfile specifier test */
+
+ /* -------------------------------------------------------- */
+ /* Not a rawfile, so next, test if this is an image section */
+ /* i.e., an integer followed by a ':' or a '*' or '-*' */
+ /* -------------------------------------------------------- */
+
+ ptr1 = ptr3 + 1; /* reset pointer to first char after the [ */
+ tmptr = ptr1;
+
+ while (*tmptr == ' ')
+ tmptr++; /* skip leading blanks */
+
+ while (isdigit((int) *tmptr))
+ tmptr++; /* skip over leading digits */
+
+ if (*tmptr == ':' || *tmptr == '*' || *tmptr == '-')
+ {
+ /* this is an image section specifier */
+ strcat(rowfilter, ptr3);
+/*
+ don't want to assume 0 extension any more; may imply an image extension.
+ if (extspec)
+ strcpy(extspec, "0");
+*/
+ }
+ else
+ {
+ /* -----------------------------------------------------------------
+ Not an image section or rawfile spec so may be an extension spec.
+
+ Examples of valid extension specifiers:
+ [3] - 3rd extension; 0 = primary array
+ [events] - events extension
+ [events, 2] - events extension, with EXTVER = 2
+ [events,2] - spaces are optional
+ [events, 3, b] - same as above, plus XTENSION = 'BINTABLE'
+ [PICS; colName(12)] - an image in row 12 of the colName column
+ in the PICS table extension
+ [PICS; colName(exposure > 1000)] - as above, but find image in
+ first row with with exposure column value > 1000.
+ [Rate Table] - extension name can contain spaces!
+ [Rate Table;colName(exposure>1000)]
+
+ Examples of other types of specifiers (Not extension specifiers)
+
+ [bin] !!! this is ambiguous, and can't be distinguished from
+ a valid extension specifier
+ [bini X=1:512:16] (also binb, binj, binr, and bind are allowed)
+ [binr (X,Y) = 5]
+ [bin @binfilter.txt]
+
+ [col Time;rate]
+ [col PI=PHA * 1.1]
+ [col -Time; status]
+
+ [X > 5]
+ [X>5]
+ [@filter.txt]
+ [StatusCol] !!! this is ambiguous, and can't be distinguished
+ from a valid extension specifier
+ [StatusCol==0]
+ [StatusCol || x>6]
+ [gtifilter()]
+ [regfilter("region.reg")]
+
+ [compress Rice]
+
+ There will always be some ambiguity between an extension name and
+ a boolean row filtering expression, (as in a couple of the above
+ examples). If there is any doubt, the expression should be treated
+ as an extension specification; The user can always add an explicit
+ expression specifier to override this interpretation.
+
+ The following decision logic will be used:
+
+ 1) locate the first token, terminated with a space, comma,
+ semi-colon, or closing bracket.
+
+ 2) the token is not part of an extension specifier if any of
+ the following is true:
+
+ - if the token begins with '@' and contains a '.'
+ - if the token contains an operator: = > < || &&
+ - if the token begins with "gtifilter(" or "regfilter("
+ - if the token is terminated by a space and is followed by
+ additional characters (not a ']') AND any of the following:
+ - the token is 'col'
+ - the token is 3 or 4 chars long and begins with 'bin'
+ - the second token begins with an operator:
+ ! = < > | & + - * / %
+
+
+ 3) otherwise, the string is assumed to be an extension specifier
+
+ ----------------------------------------------------------------- */
+
+ tmptr = ptr1;
+ while(*tmptr == ' ')
+ tmptr++;
+
+ hasAt = 0;
+ hasDot = 0;
+ hasOper = 0;
+ followingOper = 0;
+ spaceTerm = 0;
+ rowFilter = 0;
+ colStart = 0;
+ binStart = 0;
+ pixStart = 0;
+ compStart = 0;
+
+ if (*tmptr == '@') /* test for leading @ symbol */
+ hasAt = 1;
+
+ if ( !strncasecmp(tmptr, "col ", 4) )
+ colStart = 1;
+
+ if ( !strncasecmp(tmptr, "bin", 3) )
+ binStart = 1;
+
+ if ( !strncasecmp(tmptr, "pix", 3) )
+ pixStart = 1;
+
+ if ( !strncasecmp(tmptr, "compress ", 9) ||
+ !strncasecmp(tmptr, "compress]", 9) )
+ compStart = 1;
+
+ if ( !strncasecmp(tmptr, "gtifilter(", 10) ||
+ !strncasecmp(tmptr, "regfilter(", 10) )
+ {
+ rowFilter = 1;
+ }
+ else
+ {
+ /* parse the first token of the expression */
+ for (ii = 0; ii < ptr2 - ptr1 + 1; ii++, tmptr++)
+ {
+ if (*tmptr == '.')
+ hasDot = 1;
+ else if (*tmptr == '=' || *tmptr == '>' || *tmptr == '<' ||
+ (*tmptr == '|' && *(tmptr+1) == '|') ||
+ (*tmptr == '&' && *(tmptr+1) == '&') )
+ hasOper = 1;
+
+ else if (*tmptr == ',' || *tmptr == ';' || *tmptr == ']')
+ {
+ break;
+ }
+ else if (*tmptr == ' ') /* a space char? */
+ {
+ while(*tmptr == ' ') /* skip spaces */
+ tmptr++;
+
+ if (*tmptr == ']') /* is this the end? */
+ break;
+
+ spaceTerm = 1; /* 1st token is terminated by space */
+
+ /* test if this is a column or binning specifier */
+ if (colStart || (ii <= 4 && (binStart || pixStart)) )
+ rowFilter = 1;
+ else
+ {
+
+ /* check if next character is an operator */
+ if (*tmptr == '=' || *tmptr == '>' || *tmptr == '<' ||
+ *tmptr == '|' || *tmptr == '&' || *tmptr == '!' ||
+ *tmptr == '+' || *tmptr == '-' || *tmptr == '*' ||
+ *tmptr == '/' || *tmptr == '%')
+ followingOper = 1;
+ }
+ break;
+ }
+ }
+ }
+
+ /* test if this is NOT an extension specifier */
+ if ( rowFilter || (pixStart && spaceTerm) ||
+ (hasAt && hasDot) ||
+ hasOper ||
+ compStart ||
+ (spaceTerm && followingOper) )
+ {
+ /* this is (probably) not an extension specifier */
+ /* so copy all chars to filter spec string */
+ strcat(rowfilter, ptr3);
+ }
+ else
+ {
+ /* this appears to be a legit extension specifier */
+ /* copy the extension specification */
+ if (extspec) {
+ if (ptr2 - ptr1 > FLEN_FILENAME - 1) {
+ free(infile);
+ return(*status = URL_PARSE_ERROR);
+ }
+ strncat(extspec, ptr1, ptr2 - ptr1);
+ }
+
+ /* copy any remaining chars to filter spec string */
+ strcat(rowfilter, ptr2 + 1);
+ }
+ }
+ } /* end of if (!plus_ext) */
+ else
+ {
+ /* ------------------------------------------------------------------ */
+ /* already have extension, so this must be a filter spec of some sort */
+ /* ------------------------------------------------------------------ */
+
+ strcat(rowfilter, ptr3);
+ }
+
+ /* strip off any trailing blanks from filter */
+ slen = strlen(rowfilter);
+ while ( (--slen) >= 0 && rowfilter[slen] == ' ')
+ rowfilter[slen] = '\0';
+
+ if (!rowfilter[0])
+ {
+ free(infile);
+ return(*status); /* nothing left to parse */
+ }
+
+ /* ------------------------------------------------ */
+ /* does the filter contain a binning specification? */
+ /* ------------------------------------------------ */
+
+ ptr1 = strstr(rowfilter, "[bin"); /* search for "[bin" */
+ if (!ptr1)
+ ptr1 = strstr(rowfilter, "[BIN"); /* search for "[BIN" */
+ if (!ptr1)
+ ptr1 = strstr(rowfilter, "[Bin"); /* search for "[Bin" */
+
+ if (ptr1)
+ {
+ ptr2 = ptr1 + 4; /* end of the '[bin' string */
+ if (*ptr2 == 'b' || *ptr2 == 'i' || *ptr2 == 'j' ||
+ *ptr2 == 'r' || *ptr2 == 'd')
+ ptr2++; /* skip the datatype code letter */
+
+
+ if ( *ptr2 != ' ' && *ptr2 != ']')
+ ptr1 = NULL; /* bin string must be followed by space or ] */
+ }
+
+ if (ptr1)
+ {
+ /* found the binning string */
+ if (binspec)
+ {
+ if (strlen(ptr1 +1) > FLEN_FILENAME - 1)
+ {
+ free(infile);
+ return(*status = URL_PARSE_ERROR);
+ }
+
+ strcpy(binspec, ptr1 + 1);
+ ptr2 = strchr(binspec, ']');
+
+ if (ptr2) /* terminate the binning filter */
+ {
+ *ptr2 = '\0';
+
+ if ( *(--ptr2) == ' ') /* delete trailing spaces */
+ *ptr2 = '\0';
+ }
+ else
+ {
+ ffpmsg("input file URL is missing closing bracket ']'");
+ ffpmsg(rowfilter);
+ free(infile);
+ return(*status = URL_PARSE_ERROR); /* error, no closing ] */
+ }
+ }
+
+ /* delete the binning spec from the row filter string */
+ ptr2 = strchr(ptr1, ']');
+ strcpy(tmpstr, ptr2+1); /* copy any chars after the binspec */
+ strcpy(ptr1, tmpstr); /* overwrite binspec */
+ }
+
+ /* --------------------------------------------------------- */
+ /* does the filter contain a column selection specification? */
+ /* --------------------------------------------------------- */
+
+ ptr1 = strstr(rowfilter, "[col ");
+ if (!ptr1)
+ {
+ ptr1 = strstr(rowfilter, "[COL ");
+
+ if (!ptr1)
+ ptr1 = strstr(rowfilter, "[Col ");
+ }
+
+ if (ptr1)
+ { /* find the end of the column specifier */
+ ptr2 = ptr1 + 5;
+ while (*ptr2 != ']')
+ {
+ if (*ptr2 == '\0')
+ {
+ ffpmsg("input file URL is missing closing bracket ']'");
+ free(infile);
+ return(*status = URL_PARSE_ERROR); /* error, no closing ] */
+ }
+
+ if (*ptr2 == '\'') /* start of a literal string */
+ {
+ ptr2 = strchr(ptr2 + 1, '\''); /* find closing quote */
+ if (!ptr2)
+ {
+ ffpmsg
+ ("literal string in input file URL is missing closing single quote");
+ free(infile);
+ return(*status = URL_PARSE_ERROR); /* error, no closing ] */
+ }
+ }
+
+ if (*ptr2 == '[') /* set of nested square brackets */
+ {
+ ptr2 = strchr(ptr2 + 1, ']'); /* find closing bracket */
+ if (!ptr2)
+ {
+ ffpmsg
+ ("nested brackets in input file URL is missing closing bracket");
+ free(infile);
+ return(*status = URL_PARSE_ERROR); /* error, no closing ] */
+ }
+ }
+
+ ptr2++; /* continue search for the closing bracket character */
+ }
+
+ collen = ptr2 - ptr1 - 1;
+
+ if (colspec) /* copy the column specifier to output string */
+ {
+ if (collen > FLEN_FILENAME - 1) {
+ free(infile);
+ return(*status = URL_PARSE_ERROR);
+ }
+
+ strncpy(colspec, ptr1 + 1, collen);
+ colspec[collen] = '\0';
+
+ while (colspec[--collen] == ' ')
+ colspec[collen] = '\0'; /* strip trailing blanks */
+ }
+
+ /* delete the column selection spec from the row filter string */
+ strcpy(tmpstr, ptr2 + 1); /* copy any chars after the colspec */
+ strcpy(ptr1, tmpstr); /* overwrite binspec */
+ }
+
+ /* --------------------------------------------------------- */
+ /* does the filter contain a pixel filter specification? */
+ /* --------------------------------------------------------- */
+
+ ptr1 = strstr(rowfilter, "[pix");
+ if (!ptr1)
+ {
+ ptr1 = strstr(rowfilter, "[PIX");
+
+ if (!ptr1)
+ ptr1 = strstr(rowfilter, "[Pix");
+ }
+
+ if (ptr1)
+ {
+ ptr2 = ptr1 + 4; /* end of the '[pix' string */
+ if (*ptr2 == 'b' || *ptr2 == 'i' || *ptr2 == 'j' || *ptr2 == 'B' ||
+ *ptr2 == 'I' || *ptr2 == 'J' || *ptr2 == 'r' || *ptr2 == 'd' ||
+ *ptr2 == 'R' || *ptr2 == 'D')
+ ptr2++; /* skip the datatype code letter */
+
+ if (*ptr2 == '1')
+ ptr2++; /* skip the single HDU indicator */
+
+ if ( *ptr2 != ' ')
+ ptr1 = NULL; /* pix string must be followed by space */
+ }
+
+ if (ptr1)
+ { /* find the end of the pixel filter */
+ while (*ptr2 != ']')
+ {
+ if (*ptr2 == '\0')
+ {
+ ffpmsg("input file URL is missing closing bracket ']'");
+ free(infile);
+ return(*status = URL_PARSE_ERROR); /* error, no closing ] */
+ }
+
+ if (*ptr2 == '\'') /* start of a literal string */
+ {
+ ptr2 = strchr(ptr2 + 1, '\''); /* find closing quote */
+ if (!ptr2)
+ {
+ ffpmsg
+ ("literal string in input file URL is missing closing single quote");
+ free(infile);
+ return(*status = URL_PARSE_ERROR); /* error, no closing ] */
+ }
+ }
+
+ if (*ptr2 == '[') /* set of nested square brackets */
+ {
+ ptr2 = strchr(ptr2 + 1, ']'); /* find closing bracket */
+ if (!ptr2)
+ {
+ ffpmsg
+ ("nested brackets in input file URL is missing closing bracket");
+ free(infile);
+ return(*status = URL_PARSE_ERROR); /* error, no closing ] */
+ }
+ }
+
+ ptr2++; /* continue search for the closing bracket character */
+ }
+
+ collen = ptr2 - ptr1 - 1;
+
+ if (pixfilter) /* copy the column specifier to output string */
+ {
+ if (collen > FLEN_FILENAME - 1) {
+ free(infile);
+ return(*status = URL_PARSE_ERROR);
+ }
+
+ strncpy(pixfilter, ptr1 + 1, collen);
+ pixfilter[collen] = '\0';
+
+ while (pixfilter[--collen] == ' ')
+ pixfilter[collen] = '\0'; /* strip trailing blanks */
+ }
+
+ /* delete the pixel filter from the row filter string */
+ strcpy(tmpstr, ptr2 + 1); /* copy any chars after the pixel filter */
+ strcpy(ptr1, tmpstr); /* overwrite binspec */
+ }
+
+ /* ------------------------------------------------------------ */
+ /* does the filter contain an image compression specification? */
+ /* ------------------------------------------------------------ */
+
+ ptr1 = strstr(rowfilter, "[compress");
+
+ if (ptr1)
+ {
+ ptr2 = ptr1 + 9; /* end of the '[compress' string */
+
+ if ( *ptr2 != ' ' && *ptr2 != ']')
+ ptr1 = NULL; /* compress string must be followed by space or ] */
+ }
+
+ if (ptr1)
+ {
+ /* found the compress string */
+ if (compspec)
+ {
+ if (strlen(ptr1 +1) > FLEN_FILENAME - 1)
+ {
+ free(infile);
+ return(*status = URL_PARSE_ERROR);
+ }
+
+ strcpy(compspec, ptr1 + 1);
+ ptr2 = strchr(compspec, ']');
+
+ if (ptr2) /* terminate the binning filter */
+ {
+ *ptr2 = '\0';
+
+ if ( *(--ptr2) == ' ') /* delete trailing spaces */
+ *ptr2 = '\0';
+ }
+ else
+ {
+ ffpmsg("input file URL is missing closing bracket ']'");
+ ffpmsg(rowfilter);
+ free(infile);
+ return(*status = URL_PARSE_ERROR); /* error, no closing ] */
+ }
+ }
+
+ /* delete the compression spec from the row filter string */
+ ptr2 = strchr(ptr1, ']');
+ strcpy(tmpstr, ptr2+1); /* copy any chars after the binspec */
+ strcpy(ptr1, tmpstr); /* overwrite binspec */
+ }
+
+ /* copy the remaining string to the rowfilter output... should only */
+ /* contain a rowfilter expression of the form "[expr]" */
+
+ if (rowfilterx && rowfilter[0]) {
+ ptr2 = rowfilter + strlen(rowfilter) - 1;
+ if( rowfilter[0]=='[' && *ptr2==']' ) {
+ *ptr2 = '\0';
+
+ if (strlen(rowfilter + 1) > FLEN_FILENAME - 1)
+ {
+ free(infile);
+ return(*status = URL_PARSE_ERROR);
+ }
+
+ strcpy(rowfilterx, rowfilter+1);
+ } else {
+ ffpmsg("input file URL lacks valid row filter expression");
+ *status = URL_PARSE_ERROR;
+ }
+ }
+
+ free(infile);
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffexist(const char *infile, /* I - input filename or URL */
+ int *exists, /* O - 2 = a compressed version of file exists */
+ /* 1 = yes, disk file exists */
+ /* 0 = no, disk file could not be found */
+ /* -1 = infile is not a disk file (could */
+ /* be a http, ftp, gsiftp, smem, or stdin file) */
+ int *status) /* I/O status */
+
+/*
+ test if the input file specifier is an existing file on disk
+ If the specified file can't be found, it then searches for a
+ compressed version of the file.
+*/
+{
+ FILE *diskfile;
+ char rootname[FLEN_FILENAME];
+ char *ptr1;
+
+ if (*status > 0)
+ return(*status);
+
+ /* strip off any extname or filters from the name */
+ ffrtnm( (char *)infile, rootname, status);
+
+ ptr1 = strstr(rootname, "://");
+
+ if (ptr1 || *rootname == '-') {
+ if (!strncmp(rootname, "file", 4) ) {
+ ptr1 = ptr1 + 3; /* pointer to start of the disk file name */
+ } else {
+ *exists = -1; /* this is not a disk file */
+ return (*status);
+ }
+ } else {
+ ptr1 = rootname;
+ }
+
+ /* see if the disk file exists */
+ if (file_openfile(ptr1, 0, &diskfile)) {
+
+ /* no, couldn't open file, so see if there is a compressed version */
+ if (file_is_compressed(ptr1) ) {
+ *exists = 2; /* a compressed version of the file exists */
+ } else {
+ *exists = 0; /* neither file nor compressed version exist */
+ }
+
+ } else {
+
+ /* yes, file exists */
+ *exists = 1;
+ fclose(diskfile);
+ }
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffrtnm(char *url,
+ char *rootname,
+ int *status)
+/*
+ parse the input URL, returning the root name (filetype://basename).
+*/
+
+{
+ int ii, jj, slen, infilelen;
+ char *ptr1, *ptr2, *ptr3;
+ char urltype[MAX_PREFIX_LEN];
+ char infile[FLEN_FILENAME];
+
+ if (*status > 0)
+ return(*status);
+
+ ptr1 = url;
+ *rootname = '\0';
+ *urltype = '\0';
+ *infile = '\0';
+
+ /* get urltype (e.g., file://, ftp://, http://, etc.) */
+ if (*ptr1 == '-') /* "-" means read file from stdin */
+ {
+ strcat(urltype, "-");
+ ptr1++;
+ }
+ else if (!strncmp(ptr1, "stdin", 5) || !strncmp(ptr1, "STDIN", 5))
+ {
+ strcat(urltype, "-");
+ ptr1 = ptr1 + 5;
+ }
+ else
+ {
+ ptr2 = strstr(ptr1, "://");
+ ptr3 = strstr(ptr1, "(" );
+
+ if (ptr3 && (ptr3 < ptr2) )
+ {
+ /* the urltype follows a '(' character, so it must apply */
+ /* to the output file, and is not the urltype of the input file */
+ ptr2 = 0; /* so reset pointer to zero */
+ }
+
+
+ if (ptr2) /* copy the explicit urltype string */
+ {
+
+ if (ptr2 - ptr1 + 3 > MAX_PREFIX_LEN - 1)
+ {
+ return(*status = URL_PARSE_ERROR);
+ }
+ strncat(urltype, ptr1, ptr2 - ptr1 + 3);
+ ptr1 = ptr2 + 3;
+ }
+ else if (!strncmp(ptr1, "ftp:", 4) )
+ { /* the 2 //'s are optional */
+ strcat(urltype, "ftp://");
+ ptr1 += 4;
+ }
+ else if (!strncmp(ptr1, "gsiftp:", 7) )
+ { /* the 2 //'s are optional */
+ strcat(urltype, "gsiftp://");
+ ptr1 += 7;
+ }
+ else if (!strncmp(ptr1, "http:", 5) )
+ { /* the 2 //'s are optional */
+ strcat(urltype, "http://");
+ ptr1 += 5;
+ }
+ else if (!strncmp(ptr1, "mem:", 4) )
+ { /* the 2 //'s are optional */
+ strcat(urltype, "mem://");
+ ptr1 += 4;
+ }
+ else if (!strncmp(ptr1, "shmem:", 6) )
+ { /* the 2 //'s are optional */
+ strcat(urltype, "shmem://");
+ ptr1 += 6;
+ }
+ else if (!strncmp(ptr1, "file:", 5) )
+ { /* the 2 //'s are optional */
+ ptr1 += 5;
+ }
+
+ /* else assume file driver */
+ }
+
+ /* get the input file name */
+ ptr2 = strchr(ptr1, '('); /* search for opening parenthesis ( */
+ ptr3 = strchr(ptr1, '['); /* search for opening bracket [ */
+
+ if (ptr2 == ptr3) /* simple case: no [ or ( in the file name */
+ {
+
+ if (strlen(ptr1) > FLEN_FILENAME - 1)
+ {
+ return(*status = URL_PARSE_ERROR);
+ }
+
+ strcat(infile, ptr1);
+ }
+ else if (!ptr3) /* no bracket, so () enclose output file name */
+ {
+
+ if (ptr2 - ptr1 > FLEN_FILENAME - 1)
+ {
+ return(*status = URL_PARSE_ERROR);
+ }
+
+ strncat(infile, ptr1, ptr2 - ptr1);
+ ptr2++;
+
+ ptr1 = strchr(ptr2, ')' ); /* search for closing ) */
+ if (!ptr1)
+ return(*status = URL_PARSE_ERROR); /* error, no closing ) */
+
+ }
+ else if (ptr2 && (ptr2 < ptr3)) /* () enclose output name before bracket */
+ {
+
+ if (ptr2 - ptr1 > FLEN_FILENAME - 1)
+ {
+ return(*status = URL_PARSE_ERROR);
+ }
+
+ strncat(infile, ptr1, ptr2 - ptr1);
+ ptr2++;
+
+ ptr1 = strchr(ptr2, ')' ); /* search for closing ) */
+ if (!ptr1)
+ return(*status = URL_PARSE_ERROR); /* error, no closing ) */
+ }
+ else /* bracket comes first, so there is no output name */
+ {
+ if (ptr3 - ptr1 > FLEN_FILENAME - 1)
+ {
+ return(*status = URL_PARSE_ERROR);
+ }
+
+ strncat(infile, ptr1, ptr3 - ptr1);
+ }
+
+ /* strip off any trailing blanks in the names */
+ slen = strlen(infile);
+ for (ii = slen - 1; ii > 0; ii--)
+ {
+ if (infile[ii] == ' ')
+ infile[ii] = '\0';
+ else
+ break;
+ }
+
+ /* --------------------------------------------- */
+ /* check if the 'filename+n' convention has been */
+ /* used to specifiy which HDU number to open */
+ /* --------------------------------------------- */
+
+ jj = strlen(infile);
+
+ for (ii = jj - 1; ii >= 0; ii--)
+ {
+ if (infile[ii] == '+') /* search backwards for '+' sign */
+ break;
+ }
+
+ if (ii > 0 && (jj - ii) < 5) /* limit extension numbers to 4 digits */
+ {
+ infilelen = ii;
+ ii++;
+
+
+ for (; ii < jj; ii++)
+ {
+ if (!isdigit((int) infile[ii] ) ) /* are all the chars digits? */
+ break;
+ }
+
+ if (ii == jj)
+ {
+ /* yes, the '+n' convention was used. */
+
+ infile[infilelen] = '\0'; /* delete the extension number */
+ }
+ }
+
+ if (strlen(urltype) + strlen(infile) > FLEN_FILENAME - 1)
+ {
+ return(*status = URL_PARSE_ERROR);
+ }
+
+ strcat(rootname, urltype); /* construct the root name */
+ strcat(rootname, infile);
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffourl(char *url, /* I - full input URL */
+ char *urltype, /* O - url type */
+ char *outfile, /* O - base file name */
+ char *tpltfile, /* O - template file name, if any */
+ char *compspec, /* O - compression specification, if any */
+ int *status)
+/*
+ parse the output URL into its basic components.
+*/
+
+{
+ char *ptr1, *ptr2, *ptr3;
+
+ if (*status > 0)
+ return(*status);
+
+ if (urltype)
+ *urltype = '\0';
+ if (outfile)
+ *outfile = '\0';
+ if (tpltfile)
+ *tpltfile = '\0';
+ if (compspec)
+ *compspec = '\0';
+
+ ptr1 = url;
+ while (*ptr1 == ' ') /* ignore leading blanks */
+ ptr1++;
+
+ if ( ( (*ptr1 == '-') && ( *(ptr1 +1) == 0 || *(ptr1 +1) == ' ' ) )
+ || !strcmp(ptr1, "stdout")
+ || !strcmp(ptr1, "STDOUT"))
+
+ /* "-" means write to stdout; also support "- " */
+ /* but exclude disk file names that begin with a minus sign */
+ /* e.g., "-55d33m.fits" */
+ {
+ if (urltype)
+ strcpy(urltype, "stdout://");
+ }
+ else
+ {
+ /* not writing to stdout */
+ /* get urltype (e.g., file://, ftp://, http://, etc.) */
+
+ ptr2 = strstr(ptr1, "://");
+ if (ptr2) /* copy the explicit urltype string */
+ {
+ if (urltype) {
+ if (ptr2 - ptr1 + 3 > MAX_PREFIX_LEN - 1)
+ {
+ return(*status = URL_PARSE_ERROR);
+ }
+
+ strncat(urltype, ptr1, ptr2 - ptr1 + 3);
+ }
+
+ ptr1 = ptr2 + 3;
+ }
+ else /* assume file driver */
+ {
+ if (urltype)
+ strcat(urltype, "file://");
+ }
+
+ /* look for template file name, enclosed in parenthesis */
+ ptr2 = strchr(ptr1, '(');
+
+ /* look for image compression parameters, enclosed in sq. brackets */
+ ptr3 = strchr(ptr1, '[');
+
+ if (outfile)
+ {
+ if (ptr2) { /* template file was specified */
+ if (ptr2 - ptr1 > FLEN_FILENAME - 1)
+ {
+ return(*status = URL_PARSE_ERROR);
+ }
+
+ strncat(outfile, ptr1, ptr2 - ptr1);
+ } else if (ptr3) { /* compression was specified */
+ if (ptr3 - ptr1 > FLEN_FILENAME - 1)
+ {
+ return(*status = URL_PARSE_ERROR);
+ }
+ strncat(outfile, ptr1, ptr3 - ptr1);
+
+ } else { /* no template file or compression */
+ if (strlen(ptr1) > FLEN_FILENAME - 1)
+ {
+ return(*status = URL_PARSE_ERROR);
+ }
+ strcpy(outfile, ptr1);
+ }
+ }
+
+
+ if (ptr2) /* template file was specified */
+ {
+ ptr2++;
+
+ ptr1 = strchr(ptr2, ')' ); /* search for closing ) */
+
+ if (!ptr1)
+ {
+ return(*status = URL_PARSE_ERROR); /* error, no closing ) */
+ }
+
+ if (tpltfile) {
+ if (ptr1 - ptr2 > FLEN_FILENAME - 1)
+ {
+ return(*status = URL_PARSE_ERROR);
+ }
+ strncat(tpltfile, ptr2, ptr1 - ptr2);
+ }
+ }
+
+ if (ptr3) /* compression was specified */
+ {
+ ptr3++;
+
+ ptr1 = strchr(ptr3, ']' ); /* search for closing ] */
+
+ if (!ptr1)
+ {
+ return(*status = URL_PARSE_ERROR); /* error, no closing ] */
+ }
+
+ if (compspec) {
+
+ if (ptr1 - ptr3 > FLEN_FILENAME - 1)
+ {
+ return(*status = URL_PARSE_ERROR);
+ }
+
+ strncat(compspec, ptr3, ptr1 - ptr3);
+ }
+ }
+
+ /* check if a .gz compressed output file is to be created */
+ /* by seeing if the filename ends in '.gz' */
+ if (urltype && outfile)
+ {
+ if (!strcmp(urltype, "file://") )
+ {
+ ptr1 = strstr(outfile, ".gz");
+ if (ptr1)
+ { /* make sure the ".gz" is at the end of the file name */
+ ptr1 += 3;
+ if (*ptr1 == 0 || *ptr1 == ' ' )
+ strcpy(urltype, "compressoutfile://");
+ }
+ }
+ }
+ }
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffexts(char *extspec,
+ int *extnum,
+ char *extname,
+ int *extvers,
+ int *hdutype,
+ char *imagecolname,
+ char *rowexpress,
+ int *status)
+{
+/*
+ Parse the input extension specification string, returning either the
+ extension number or the values of the EXTNAME, EXTVERS, and XTENSION
+ keywords in desired extension. Also return the name of the column containing
+ an image, and an expression to be used to determine which row to use,
+ if present.
+*/
+ char *ptr1, *ptr2;
+ int slen, nvals;
+ int notint = 1; /* initially assume specified extname is not an integer */
+ char tmpname[FLEN_VALUE], *loc;
+
+ *extnum = 0;
+ *extname = '\0';
+ *extvers = 0;
+ *hdutype = ANY_HDU;
+ *imagecolname = '\0';
+ *rowexpress = '\0';
+
+ if (*status > 0)
+ return(*status);
+
+ ptr1 = extspec; /* pointer to first char */
+
+ while (*ptr1 == ' ') /* skip over any leading blanks */
+ ptr1++;
+
+ if (isdigit((int) *ptr1)) /* is the extension specification a number? */
+ {
+ notint = 0; /* looks like extname may actually be the ext. number */
+ errno = 0; /* reset this prior to calling strtol */
+ *extnum = strtol(ptr1, &loc, 10); /* read the string as an integer */
+
+ while (*loc == ' ') /* skip over trailing blanks */
+ loc++;
+
+ /* check for read error, or junk following the integer */
+ if ((*loc != '\0' && *loc != ';' ) || (errno == ERANGE) )
+ {
+ *extnum = 0;
+ notint = 1; /* no, extname was not a simple integer after all */
+ errno = 0; /* reset error condition flag if it was set */
+ }
+
+ if ( *extnum < 0 || *extnum > 99999)
+ {
+ *extnum = 0; /* this is not a reasonable extension number */
+ ffpmsg("specified extension number is out of range:");
+ ffpmsg(extspec);
+ return(*status = URL_PARSE_ERROR);
+ }
+ }
+
+
+/* This logic was too simple, and failed on extnames like '1000TEMP'
+ where it would try to move to the 1000th extension
+
+ if (isdigit((int) *ptr1))
+ {
+ sscanf(ptr1, "%d", extnum);
+ if (*extnum < 0 || *extnum > 9999)
+ {
+ *extnum = 0;
+ ffpmsg("specified extension number is out of range:");
+ ffpmsg(extspec);
+ return(*status = URL_PARSE_ERROR);
+ }
+ }
+*/
+
+ if (notint)
+ {
+ /* not a number, so EXTNAME must be specified, followed by */
+ /* optional EXTVERS and XTENSION values */
+
+ /* don't use space char as end indicator, because there */
+ /* may be imbedded spaces in the EXTNAME value */
+ slen = strcspn(ptr1, ",:;"); /* length of EXTNAME */
+
+ if (slen > FLEN_VALUE - 1)
+ {
+ return(*status = URL_PARSE_ERROR);
+ }
+
+ strncat(extname, ptr1, slen); /* EXTNAME value */
+
+ /* now remove any trailing blanks */
+ while (slen > 0 && *(extname + slen -1) == ' ')
+ {
+ *(extname + slen -1) = '\0';
+ slen--;
+ }
+
+ ptr1 += slen;
+ slen = strspn(ptr1, " ,:"); /* skip delimiter characters */
+ ptr1 += slen;
+
+ slen = strcspn(ptr1, " ,:;"); /* length of EXTVERS */
+ if (slen)
+ {
+ nvals = sscanf(ptr1, "%d", extvers); /* EXTVERS value */
+ if (nvals != 1)
+ {
+ ffpmsg("illegal EXTVER value in input URL:");
+ ffpmsg(extspec);
+ return(*status = URL_PARSE_ERROR);
+ }
+
+ ptr1 += slen;
+ slen = strspn(ptr1, " ,:"); /* skip delimiter characters */
+ ptr1 += slen;
+
+ slen = strcspn(ptr1, ";"); /* length of HDUTYPE */
+ if (slen)
+ {
+ if (*ptr1 == 'b' || *ptr1 == 'B')
+ *hdutype = BINARY_TBL;
+ else if (*ptr1 == 't' || *ptr1 == 'T' ||
+ *ptr1 == 'a' || *ptr1 == 'A')
+ *hdutype = ASCII_TBL;
+ else if (*ptr1 == 'i' || *ptr1 == 'I')
+ *hdutype = IMAGE_HDU;
+ else
+ {
+ ffpmsg("unknown type of HDU in input URL:");
+ ffpmsg(extspec);
+ return(*status = URL_PARSE_ERROR);
+ }
+ }
+ }
+ else
+ {
+ strcpy(tmpname, extname);
+ ffupch(tmpname);
+ if (!strcmp(tmpname, "PRIMARY") || !strcmp(tmpname, "P") )
+ *extname = '\0'; /* return extnum = 0 */
+ }
+ }
+
+ ptr1 = strchr(ptr1, ';');
+ if (ptr1)
+ {
+ /* an image is to be opened; the image is contained in a single */
+ /* cell of a binary table. A column name and an expression to */
+ /* determine which row to use has been entered. */
+
+ ptr1++; /* skip over the ';' delimiter */
+ while (*ptr1 == ' ') /* skip over any leading blanks */
+ ptr1++;
+
+ ptr2 = strchr(ptr1, '(');
+ if (!ptr2)
+ {
+ ffpmsg("illegal specification of image in table cell in input URL:");
+ ffpmsg(" did not find a row expression enclosed in ( )");
+ ffpmsg(extspec);
+ return(*status = URL_PARSE_ERROR);
+ }
+
+ if (ptr2 - ptr1 > FLEN_FILENAME - 1)
+ {
+ return(*status = URL_PARSE_ERROR);
+ }
+
+ strncat(imagecolname, ptr1, ptr2 - ptr1); /* copy column name */
+
+ ptr2++; /* skip over the '(' delimiter */
+ while (*ptr2 == ' ') /* skip over any leading blanks */
+ ptr2++;
+
+
+ ptr1 = strchr(ptr2, ')');
+ if (!ptr2)
+ {
+ ffpmsg("illegal specification of image in table cell in input URL:");
+ ffpmsg(" missing closing ')' character in row expression");
+ ffpmsg(extspec);
+ return(*status = URL_PARSE_ERROR);
+ }
+
+ if (ptr1 - ptr2 > FLEN_FILENAME - 1)
+ {
+ return(*status = URL_PARSE_ERROR);
+ }
+
+ strncat(rowexpress, ptr2, ptr1 - ptr2); /* row expression */
+ }
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffextn(char *url, /* I - input filename/URL */
+ int *extension_num, /* O - returned extension number */
+ int *status)
+{
+/*
+ Parse the input url string and return the number of the extension that
+ CFITSIO would automatically move to if CFITSIO were to open this input URL.
+ The extension numbers are one's based, so 1 = the primary array, 2 = the
+ first extension, etc.
+
+ The extension number that gets returned is determined by the following
+ algorithm:
+
+ 1. If the input URL includes a binning specification (e.g.
+ 'myfile.fits[3][bin X,Y]') then the returned extension number
+ will always = 1, since CFITSIO would create a temporary primary
+ image on the fly in this case. The same is true if an image
+ within a single cell of a binary table is opened.
+
+ 2. Else if the input URL specifies an extension number (e.g.,
+ 'myfile.fits[3]' or 'myfile.fits+3') then the specified extension
+ number (+ 1) is returned.
+
+ 3. Else if the extension name is specified in brackets
+ (e.g., this 'myfile.fits[EVENTS]') then the file will be opened and searched
+ for the extension number. If the input URL is '-' (reading from the stdin
+ file stream) this is not possible and an error will be returned.
+
+ 4. Else if the URL does not specify an extension (e.g. 'myfile.fits') then
+ a special extension number = -99 will be returned to signal that no
+ extension was specified. This feature is mainly for compatibility with
+ existing FTOOLS software. CFITSIO would open the primary array by default
+ (extension_num = 1) in this case.
+
+*/
+ fitsfile *fptr;
+ char urltype[20];
+ char infile[FLEN_FILENAME];
+ char outfile[FLEN_FILENAME];
+ char extspec[FLEN_FILENAME];
+ char extname[FLEN_FILENAME];
+ char rowfilter[FLEN_FILENAME];
+ char binspec[FLEN_FILENAME];
+ char colspec[FLEN_FILENAME];
+ char imagecolname[FLEN_VALUE], rowexpress[FLEN_FILENAME];
+ char *cptr;
+ int extnum, extvers, hdutype, tstatus = 0;
+
+ if (*status > 0)
+ return(*status);
+
+ /* parse the input URL into its basic components */
+ fits_parse_input_url(url, urltype, infile, outfile,
+ extspec, rowfilter,binspec, colspec, status);
+
+ if (*status > 0)
+ return(*status);
+
+ if (*binspec) /* is there a binning specification? */
+ {
+ *extension_num = 1; /* a temporary primary array image is created */
+ return(*status);
+ }
+
+ if (*extspec) /* is an extension specified? */
+ {
+ ffexts(extspec, &extnum,
+ extname, &extvers, &hdutype, imagecolname, rowexpress, status);
+
+ if (*status > 0)
+ return(*status);
+
+ if (*imagecolname) /* is an image within a table cell being opened? */
+ {
+ *extension_num = 1; /* a temporary primary array image is created */
+ return(*status);
+ }
+
+ if (*extname)
+ {
+ /* have to open the file to search for the extension name (curses!) */
+
+ if (!strcmp(urltype, "stdin://"))
+ /* opening stdin would destroying it! */
+ return(*status = URL_PARSE_ERROR);
+
+ /* First, strip off any filtering specification */
+ infile[0] = '\0';
+ strncat(infile, url, FLEN_FILENAME -1);
+
+ cptr = strchr(infile, ']'); /* locate the closing bracket */
+ if (!cptr)
+ {
+ return(*status = URL_PARSE_ERROR);
+ }
+ else
+ {
+ cptr++;
+ *cptr = '\0'; /* terminate URl after the extension spec */
+ }
+
+ if (ffopen(&fptr, infile, READONLY, status) > 0) /* open the file */
+ {
+ ffclos(fptr, &tstatus);
+ return(*status);
+ }
+
+ ffghdn(fptr, &extnum); /* where am I in the file? */
+ *extension_num = extnum;
+ ffclos(fptr, status);
+
+ return(*status);
+ }
+ else
+ {
+ *extension_num = extnum + 1; /* return the specified number (+ 1) */
+ return(*status);
+ }
+ }
+ else
+ {
+ *extension_num = -99; /* no specific extension was specified */
+ /* defaults to primary array */
+ return(*status);
+ }
+}
+/*--------------------------------------------------------------------------*/
+
+int ffurlt(fitsfile *fptr, char *urlType, int *status)
+/*
+ return the prefix string associated with the driver in use by the
+ fitsfile pointer fptr
+*/
+
+{
+ strcpy(urlType, driverTable[fptr->Fptr->driver].prefix);
+ return(*status);
+}
+
+/*--------------------------------------------------------------------------*/
+int ffimport_file( char *filename, /* Text file to read */
+ char **contents, /* Pointer to pointer to hold file */
+ int *status ) /* CFITSIO error code */
+/*
+ Read and concatenate all the lines from the given text file. User
+ must free the pointer returned in contents. Pointer is guaranteed
+ to hold 2 characters more than the length of the text... allows the
+ calling routine to append (or prepend) a newline (or quotes?) without
+ reallocating memory.
+*/
+{
+ int allocLen, totalLen, llen, eoline = 1;
+ char *lines,line[256];
+ FILE *aFile;
+
+ if( *status > 0 ) return( *status );
+
+ totalLen = 0;
+ allocLen = 1024;
+ lines = (char *)malloc( allocLen * sizeof(char) );
+ if( !lines ) {
+ ffpmsg("Couldn't allocate memory to hold ASCII file contents.");
+ return(*status = MEMORY_ALLOCATION );
+ }
+ lines[0] = '\0';
+
+ if( (aFile = fopen( filename, "r" ))==NULL ) {
+ sprintf(line,"Could not open ASCII file %s.",filename);
+ ffpmsg(line);
+ free( lines );
+ return(*status = FILE_NOT_OPENED);
+ }
+
+ while( fgets(line,256,aFile)!=NULL ) {
+ llen = strlen(line);
+ if ( eoline && (llen > 1) && (line[0] == '/' && line[1] == '/'))
+ continue; /* skip comment lines begging with // */
+
+ eoline = 0;
+
+ /* replace CR and newline chars at end of line with nulls */
+ if ((llen > 0) && (line[llen-1]=='\n' || line[llen-1] == '\r')) {
+ line[--llen] = '\0';
+ eoline = 1; /* found an end of line character */
+
+ if ((llen > 0) && (line[llen-1]=='\n' || line[llen-1] == '\r')) {
+ line[--llen] = '\0';
+ }
+ }
+
+ if( totalLen + llen + 3 >= allocLen ) {
+ allocLen += 256;
+ lines = (char *)realloc(lines, allocLen * sizeof(char) );
+ if( ! lines ) {
+ ffpmsg("Couldn't allocate memory to hold ASCII file contents.");
+ *status = MEMORY_ALLOCATION;
+ break;
+ }
+ }
+ strcpy( lines+totalLen, line );
+ totalLen += llen;
+
+ if (eoline) {
+ strcpy( lines+totalLen, " "); /* add a space between lines */
+ totalLen += 1;
+ }
+ }
+ fclose(aFile);
+
+ *contents = lines;
+ return( *status );
+}
+
+/*--------------------------------------------------------------------------*/
+int fits_get_token(char **ptr,
+ char *delimiter,
+ char *token,
+ int *isanumber) /* O - is this token a number? */
+/*
+ parse off the next token, delimited by a character in 'delimiter',
+ from the input ptr string; increment *ptr to the end of the token.
+ Returns the length of the token, not including the delimiter char;
+*/
+{
+ char *loc, tval[73];
+ int slen;
+ double dval;
+
+ *token = '\0';
+
+ while (**ptr == ' ') /* skip over leading blanks */
+ (*ptr)++;
+
+ slen = strcspn(*ptr, delimiter); /* length of next token */
+ if (slen)
+ {
+ strncat(token, *ptr, slen); /* copy token */
+
+ (*ptr) += slen; /* skip over the token */
+
+ if (isanumber) /* check if token is a number */
+ {
+ *isanumber = 1;
+
+ if (strchr(token, 'D')) {
+ strncpy(tval, token, 72);
+ tval[72] = '\0';
+
+ /* The C language does not support a 'D'; replace with 'E' */
+ if ((loc = strchr(tval, 'D'))) *loc = 'E';
+
+ dval = strtod(tval, &loc);
+ } else {
+ dval = strtod(token, &loc);
+ }
+
+ /* check for read error, or junk following the value */
+ if (*loc != '\0' && *loc != ' ' ) *isanumber = 0;
+ if (errno == ERANGE) *isanumber = 0;
+ }
+ }
+
+ return(slen);
+}
+/*--------------------------------------------------------------------------*/
+int fits_get_token2(char **ptr,
+ char *delimiter,
+ char **token,
+ int *isanumber, /* O - is this token a number? */
+ int *status)
+
+/*
+ parse off the next token, delimited by a character in 'delimiter',
+ from the input ptr string; increment *ptr to the end of the token.
+ Returns the length of the token, not including the delimiter char;
+
+ This routine allocates the *token string; the calling routine must free it
+*/
+{
+ char *loc, tval[73];
+ int slen;
+ double dval;
+
+ if (*status)
+ return(0);
+
+ while (**ptr == ' ') /* skip over leading blanks */
+ (*ptr)++;
+
+ slen = strcspn(*ptr, delimiter); /* length of next token */
+ if (slen)
+ {
+ *token = (char *) calloc(slen + 1, 1);
+ if (!(*token)) {
+ ffpmsg("Couldn't allocate memory to hold token string (fits_get_token2).");
+ *status = MEMORY_ALLOCATION ;
+ return(0);
+ }
+
+ strncat(*token, *ptr, slen); /* copy token */
+ (*ptr) += slen; /* skip over the token */
+
+ if (isanumber) /* check if token is a number */
+ {
+ *isanumber = 1;
+
+ if (strchr(*token, 'D')) {
+ strncpy(tval, *token, 72);
+ tval[72] = '\0';
+
+ /* The C language does not support a 'D'; replace with 'E' */
+ if ((loc = strchr(tval, 'D'))) *loc = 'E';
+
+ dval = strtod(tval, &loc);
+ } else {
+ dval = strtod(*token, &loc);
+ }
+
+ /* check for read error, or junk following the value */
+ if (*loc != '\0' && *loc != ' ' ) *isanumber = 0;
+ if (errno == ERANGE) *isanumber = 0;
+ }
+ }
+
+ return(slen);
+}
+/*---------------------------------------------------------------------------*/
+char *fits_split_names(
+ char *list) /* I - input list of names */
+{
+/*
+ A sequence of calls to fits_split_names will split the input string
+ into name tokens. The string typically contains a list of file or
+ column names. The names must be delimited by a comma and/or spaces.
+ This routine ignores spaces and commas that occur within parentheses,
+ brackets, or curly brackets. It also strips any leading and trailing
+ blanks from the returned name.
+
+ This routine is similar to the ANSI C 'strtok' function:
+
+ The first call to fits_split_names has a non-null input string.
+ It finds the first name in the string and terminates it by
+ overwriting the next character of the string with a '\0' and returns
+ a pointer to the name. Each subsequent call, indicated by a NULL
+ value of the input string, returns the next name, searching from
+ just past the end of the previous name. It returns NULL when no
+ further names are found.
+
+ The following line illustrates how a string would be split into 3 names:
+ myfile[1][bin (x,y)=4], file2.fits file3.fits
+ ^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^
+ 1st name 2nd name 3rd name
+
+
+NOTE: This routine is not thread-safe.
+This routine is simply provided as a utility routine for other external
+software. It is not used by any CFITSIO routine.
+
+*/
+ int depth = 0;
+ char *start;
+ static char *ptr;
+
+ if (list) /* reset ptr if a string is given */
+ ptr = list;
+
+ while (*ptr == ' ')ptr++; /* skip leading white space */
+
+ if (*ptr == '\0')return(0); /* no remaining file names */
+
+ start = ptr;
+
+ while (*ptr != '\0') {
+ if ((*ptr == '[') || (*ptr == '(') || (*ptr == '{')) depth ++;
+ else if ((*ptr == '}') || (*ptr == ')') || (*ptr == ']')) depth --;
+ else if ((depth == 0) && (*ptr == ',' || *ptr == ' ')) {
+ *ptr = '\0'; /* terminate the filename here */
+ ptr++; /* save pointer to start of next filename */
+ break;
+ }
+ ptr++;
+ }
+
+ return(start);
+}
+/*--------------------------------------------------------------------------*/
+int urltype2driver(char *urltype, int *driver)
+/*
+ compare input URL with list of known drivers, returning the
+ matching driver numberL.
+*/
+
+{
+ int ii;
+
+ /* find matching driver; search most recent drivers first */
+
+ for (ii=no_of_drivers - 1; ii >= 0; ii--)
+ {
+ if (0 == strcmp(driverTable[ii].prefix, urltype))
+ {
+ *driver = ii;
+ return(0);
+ }
+ }
+
+ return(NO_MATCHING_DRIVER);
+}
+/*--------------------------------------------------------------------------*/
+int ffclos(fitsfile *fptr, /* I - FITS file pointer */
+ int *status) /* IO - error status */
+/*
+ close the FITS file by completing the current HDU, flushing it to disk,
+ then calling the system dependent routine to physically close the FITS file
+*/
+{
+ int tstatus = NO_CLOSE_ERROR, zerostatus = 0;
+
+ if (!fptr)
+ return(*status = NULL_INPUT_PTR);
+ else if ((fptr->Fptr)->validcode != VALIDSTRUC) /* check for magic value */
+ return(*status = BAD_FILEPTR);
+
+ /* close and flush the current HDU */
+ if (*status > 0)
+ ffchdu(fptr, &tstatus); /* turn off the error message from ffchdu */
+ else
+ ffchdu(fptr, status);
+
+ ((fptr->Fptr)->open_count)--; /* decrement usage counter */
+
+ if ((fptr->Fptr)->open_count == 0) /* if no other files use structure */
+ {
+ ffflsh(fptr, TRUE, status); /* flush and disassociate IO buffers */
+
+ /* call driver function to actually close the file */
+ if ((*driverTable[(fptr->Fptr)->driver].close)((fptr->Fptr)->filehandle))
+ {
+ if (*status <= 0)
+ {
+ *status = FILE_NOT_CLOSED; /* report if no previous error */
+
+ ffpmsg("failed to close the following file: (ffclos)");
+ ffpmsg((fptr->Fptr)->filename);
+ }
+ }
+
+ fits_clear_Fptr( fptr->Fptr, status); /* clear Fptr address */
+ free((fptr->Fptr)->iobuffer); /* free memory for I/O buffers */
+ free((fptr->Fptr)->headstart); /* free memory for headstart array */
+ free((fptr->Fptr)->filename); /* free memory for the filename */
+ (fptr->Fptr)->filename = 0;
+ (fptr->Fptr)->validcode = 0; /* magic value to indicate invalid fptr */
+ free(fptr->Fptr); /* free memory for the FITS file structure */
+ free(fptr); /* free memory for the FITS file structure */
+ }
+ else
+ {
+ /*
+ to minimize the fallout from any previous error (e.g., trying to
+ open a non-existent extension in a already opened file),
+ always call ffflsh with status = 0.
+ */
+ /* just flush the buffers, don't disassociate them */
+ if (*status > 0)
+ ffflsh(fptr, FALSE, &zerostatus);
+ else
+ ffflsh(fptr, FALSE, status);
+
+ free(fptr); /* free memory for the FITS file structure */
+ }
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffdelt(fitsfile *fptr, /* I - FITS file pointer */
+ int *status) /* IO - error status */
+/*
+ close and DELETE the FITS file.
+*/
+{
+ char *basename;
+ int slen, tstatus = NO_CLOSE_ERROR, zerostatus = 0;
+
+ if (!fptr)
+ return(*status = NULL_INPUT_PTR);
+ else if ((fptr->Fptr)->validcode != VALIDSTRUC) /* check for magic value */
+ return(*status = BAD_FILEPTR);
+
+ if (*status > 0)
+ ffchdu(fptr, &tstatus); /* turn off the error message from ffchdu */
+ else
+ ffchdu(fptr, status);
+
+ ffflsh(fptr, TRUE, status); /* flush and disassociate IO buffers */
+
+ /* call driver function to actually close the file */
+ if ( (*driverTable[(fptr->Fptr)->driver].close)((fptr->Fptr)->filehandle) )
+ {
+ if (*status <= 0)
+ {
+ *status = FILE_NOT_CLOSED; /* report error if no previous error */
+
+ ffpmsg("failed to close the following file: (ffdelt)");
+ ffpmsg((fptr->Fptr)->filename);
+ }
+ }
+
+ /* call driver function to actually delete the file */
+ if ( (driverTable[(fptr->Fptr)->driver].remove) )
+ {
+ /* parse the input URL to get the base filename */
+ slen = strlen((fptr->Fptr)->filename);
+ basename = (char *) malloc(slen +1);
+ if (!basename)
+ return(*status = MEMORY_ALLOCATION);
+
+ fits_parse_input_url((fptr->Fptr)->filename, NULL, basename, NULL, NULL, NULL, NULL,
+ NULL, &zerostatus);
+
+ if ((*driverTable[(fptr->Fptr)->driver].remove)(basename))
+ {
+ ffpmsg("failed to delete the following file: (ffdelt)");
+ ffpmsg((fptr->Fptr)->filename);
+ if (!(*status))
+ *status = FILE_NOT_CLOSED;
+ }
+ free(basename);
+ }
+
+ fits_clear_Fptr( fptr->Fptr, status); /* clear Fptr address */
+ free((fptr->Fptr)->iobuffer); /* free memory for I/O buffers */
+ free((fptr->Fptr)->headstart); /* free memory for headstart array */
+ free((fptr->Fptr)->filename); /* free memory for the filename */
+ (fptr->Fptr)->filename = 0;
+ (fptr->Fptr)->validcode = 0; /* magic value to indicate invalid fptr */
+ free(fptr->Fptr); /* free memory for the FITS file structure */
+ free(fptr); /* free memory for the FITS file structure */
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int fftrun( fitsfile *fptr, /* I - FITS file pointer */
+ LONGLONG filesize, /* I - size to truncate the file */
+ int *status) /* O - error status */
+/*
+ low level routine to truncate a file to a new smaller size.
+*/
+{
+ if (driverTable[(fptr->Fptr)->driver].truncate)
+ {
+ ffflsh(fptr, FALSE, status); /* flush all the buffers first */
+ (fptr->Fptr)->filesize = filesize;
+ (fptr->Fptr)->io_pos = filesize;
+ (fptr->Fptr)->logfilesize = filesize;
+ (fptr->Fptr)->bytepos = filesize;
+ ffbfeof(fptr, status); /* eliminate any buffers beyond current EOF */
+ return (*status =
+ (*driverTable[(fptr->Fptr)->driver].truncate)((fptr->Fptr)->filehandle,
+ filesize) );
+ }
+ else
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffflushx( FITSfile *fptr) /* I - FITS file pointer */
+/*
+ low level routine to flush internal file buffers to the file.
+*/
+{
+ if (driverTable[fptr->driver].flush)
+ return ( (*driverTable[fptr->driver].flush)(fptr->filehandle) );
+ else
+ return(0); /* no flush function defined for this driver */
+}
+/*--------------------------------------------------------------------------*/
+int ffseek( FITSfile *fptr, /* I - FITS file pointer */
+ LONGLONG position) /* I - byte position to seek to */
+/*
+ low level routine to seek to a position in a file.
+*/
+{
+ return( (*driverTable[fptr->driver].seek)(fptr->filehandle, position) );
+}
+/*--------------------------------------------------------------------------*/
+int ffwrite( FITSfile *fptr, /* I - FITS file pointer */
+ long nbytes, /* I - number of bytes to write */
+ void *buffer, /* I - buffer to write */
+ int *status) /* O - error status */
+/*
+ low level routine to write bytes to a file.
+*/
+{
+ if ( (*driverTable[fptr->driver].write)(fptr->filehandle, buffer, nbytes) )
+ {
+ ffpmsg("Error writing data buffer to file:");
+ ffpmsg(fptr->filename);
+
+ *status = WRITE_ERROR;
+ }
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffread( FITSfile *fptr, /* I - FITS file pointer */
+ long nbytes, /* I - number of bytes to read */
+ void *buffer, /* O - buffer to read into */
+ int *status) /* O - error status */
+/*
+ low level routine to read bytes from a file.
+*/
+{
+ int readstatus;
+
+ readstatus = (*driverTable[fptr->driver].read)(fptr->filehandle,
+ buffer, nbytes);
+
+ if (readstatus == END_OF_FILE)
+ *status = END_OF_FILE;
+ else if (readstatus > 0)
+ {
+ ffpmsg("Error reading data buffer from file:");
+ ffpmsg(fptr->filename);
+
+ *status = READ_ERROR;
+ }
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int fftplt(fitsfile **fptr, /* O - FITS file pointer */
+ const char *filename, /* I - name of file to create */
+ const char *tempname, /* I - name of template file */
+ int *status) /* IO - error status */
+/*
+ Create and initialize a new FITS file based on a template file.
+ Uses C fopen and fgets functions.
+*/
+{
+ *fptr = 0; /* initialize null file pointer, */
+ /* regardless of the value of *status */
+ if (*status > 0)
+ return(*status);
+
+ if ( ffinit(fptr, filename, status) ) /* create empty file */
+ return(*status);
+
+ ffoptplt(*fptr, tempname, status); /* open and use template */
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffoptplt(fitsfile *fptr, /* O - FITS file pointer */
+ const char *tempname, /* I - name of template file */
+ int *status) /* IO - error status */
+/*
+ open template file and use it to create new file
+*/
+{
+ fitsfile *tptr;
+ int tstatus = 0, nkeys, nadd, ii;
+ char card[FLEN_CARD];
+
+ if (*status > 0)
+ return(*status);
+
+ if (tempname == NULL || *tempname == '\0') /* no template file? */
+ return(*status);
+
+ /* try opening template */
+ ffopen(&tptr, (char *) tempname, READONLY, &tstatus);
+
+ if (tstatus) /* not a FITS file, so treat it as an ASCII template */
+ {
+ ffxmsg(2, card); /* clear the error message */
+ fits_execute_template(fptr, (char *) tempname, status);
+
+ ffmahd(fptr, 1, 0, status); /* move back to the primary array */
+ return(*status);
+ }
+ else /* template is a valid FITS file */
+ {
+ ffmahd(tptr, 1, NULL, status); /* make sure we are at the beginning */
+ while (*status <= 0)
+ {
+ ffghsp(tptr, &nkeys, &nadd, status); /* get no. of keywords */
+
+ for (ii = 1; ii <= nkeys; ii++) /* copy keywords */
+ {
+ ffgrec(tptr, ii, card, status);
+
+ /* must reset the PCOUNT keyword to zero in the new output file */
+ if (strncmp(card, "PCOUNT ",8) == 0) { /* the PCOUNT keyword? */
+ if (strncmp(card+25, " 0", 5)) { /* non-zero value? */
+ strncpy(card, "PCOUNT = 0", 30);
+ }
+ }
+
+ ffprec(fptr, card, status);
+ }
+
+ ffmrhd(tptr, 1, 0, status); /* move to next HDU until error */
+ ffcrhd(fptr, status); /* create empty new HDU in output file */
+ }
+
+ if (*status == END_OF_FILE)
+ {
+ *status = 0; /* expected error condition */
+ }
+ ffclos(tptr, status); /* close the template file */
+ }
+
+ ffmahd(fptr, 1, 0, status); /* move to the primary array */
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+void ffrprt( FILE *stream, int status)
+/*
+ Print out report of cfitsio error status and messages on the error stack.
+ Uses C FILE stream.
+*/
+{
+ char status_str[FLEN_STATUS], errmsg[FLEN_ERRMSG];
+
+ if (status)
+ {
+
+ fits_get_errstatus(status, status_str); /* get the error description */
+ fprintf(stream, "\nFITSIO status = %d: %s\n", status, status_str);
+
+ while ( fits_read_errmsg(errmsg) ) /* get error stack messages */
+ fprintf(stream, "%s\n", errmsg);
+ }
+ return;
+}
+/*--------------------------------------------------------------------------*/
+int pixel_filter_helper(
+ fitsfile **fptr, /* IO - pointer to input image; on output it */
+ /* points to the new image */
+ char *outfile, /* I - name for output file */
+ char *expr, /* I - Image filter expression */
+ int *status)
+{
+ PixelFilter filter = { 0 };
+ char * DEFAULT_TAG = "X";
+ int ii, hdunum;
+ int singleHDU = 0;
+
+ filter.count = 1;
+ filter.ifptr = fptr;
+ filter.tag = &DEFAULT_TAG;
+
+ /* create new empty file for result */
+ if (ffinit(&filter.ofptr, outfile, status) > 0)
+ {
+ ffpmsg("failed to create output file for pixel filter:");
+ ffpmsg(outfile);
+ return(*status);
+ }
+
+ fits_get_hdu_num(*fptr, &hdunum); /* current HDU number in input file */
+
+ expr += 3; /* skip 'pix' */
+ switch (expr[0]) {
+ case 'b':
+ case 'B': filter.bitpix = BYTE_IMG; break;
+ case 'i':
+ case 'I': filter.bitpix = SHORT_IMG; break;
+ case 'j':
+ case 'J': filter.bitpix = LONG_IMG; break;
+ case 'r':
+ case 'R': filter.bitpix = FLOAT_IMG; break;
+ case 'd':
+ case 'D': filter.bitpix = DOUBLE_IMG; break;
+ }
+ if (filter.bitpix) /* skip bitpix indicator */
+ ++expr;
+
+ if (*expr == '1') {
+ ++expr;
+ singleHDU = 1;
+ }
+
+ if (((*fptr)->Fptr)->only_one)
+ singleHDU = 1;
+
+ if (*expr != ' ') {
+ ffpmsg("pixel filtering expression not space separated:");
+ ffpmsg(expr);
+ }
+ while (*expr == ' ')
+ ++expr;
+
+ /* copy all preceding extensions to the output file */
+ for (ii = 1; !singleHDU && ii < hdunum; ii++)
+ {
+ fits_movabs_hdu(*fptr, ii, NULL, status);
+ if (fits_copy_hdu(*fptr, filter.ofptr, 0, status) > 0)
+ {
+ ffclos(filter.ofptr, status);
+ return(*status);
+ }
+ }
+
+ /* move back to the original HDU position */
+ fits_movabs_hdu(*fptr, hdunum, NULL, status);
+
+ filter.expression = expr;
+ if (fits_pixel_filter(&filter, status)) {
+ ffpmsg("failed to execute image filter:");
+ ffpmsg(expr);
+ ffclos(filter.ofptr, status);
+ return(*status);
+ }
+
+
+ /* copy any remaining HDUs to the output file */
+
+ for (ii = hdunum + 1; !singleHDU; ii++)
+ {
+ if (fits_movabs_hdu(*fptr, ii, NULL, status) > 0)
+ break;
+
+ fits_copy_hdu(*fptr, filter.ofptr, 0, status);
+ }
+
+ if (*status == END_OF_FILE)
+ *status = 0; /* got the expected EOF error; reset = 0 */
+ else if (*status > 0)
+ {
+ ffclos(filter.ofptr, status);
+ return(*status);
+ }
+
+ /* close the original file and return ptr to the new image */
+ ffclos(*fptr, status);
+
+ *fptr = filter.ofptr; /* reset the pointer to the new table */
+
+ /* move back to the image subsection */
+ if (ii - 1 != hdunum)
+ fits_movabs_hdu(*fptr, hdunum, NULL, status);
+
+ return(*status);
+}
diff --git a/build_kstarslite/android_libs_src/cfitsio/cfitsio.pc.in b/build_kstarslite/android_libs_src/cfitsio/cfitsio.pc.in
new file mode 100644
index 0000000..2d884e0
--- /dev/null
+++ b/build_kstarslite/android_libs_src/cfitsio/cfitsio.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: cfitsio
+Description: FITS File Subroutine Library
+Version: @CFITSIO_MAJOR@.@CFITSIO_MINOR@
+Libs: -L${libdir} -lcfitsio @LIBS@
+Libs.private: -lm
+Cflags: -I${includedir}
diff --git a/build_kstarslite/android_libs_src/cfitsio/cfortran.h b/build_kstarslite/android_libs_src/cfitsio/cfortran.h
new file mode 100644
index 0000000..2142b18
--- /dev/null
+++ b/build_kstarslite/android_libs_src/cfitsio/cfortran.h
@@ -0,0 +1,2521 @@
+/* cfortran.h 4.4 */
+/* http://www-zeus.desy.de/~burow/cfortran/ */
+/* Burkhard Burow burow@desy.de 1990 - 2002. */
+
+#ifndef __CFORTRAN_LOADED
+#define __CFORTRAN_LOADED
+
+/*
+ THIS FILE IS PROPERTY OF BURKHARD BUROW. IF YOU ARE USING THIS FILE YOU
+ SHOULD ALSO HAVE ACCESS TO CFORTRAN.DOC WHICH PROVIDES TERMS FOR USING,
+ MODIFYING, COPYING AND DISTRIBUTING THE CFORTRAN.H PACKAGE.
+*/
+
+/* The following modifications were made by the authors of CFITSIO or by me.
+ * They are flagged below with CFITSIO, the author's initials, or KMCCARTY.
+ * PDW = Peter Wilson
+ * DM = Doug Mink
+ * LEB = Lee E Brotzman
+ * MR = Martin Reinecke
+ * WDP = William D Pence
+ * -- Kevin McCarty, for Debian (19 Dec. 2005) */
+
+/*******
+ Modifications:
+ Oct 1997: Changed symbol name extname to appendus (PDW/HSTX)
+ (Conflicted with a common variable name in FTOOLS)
+ Nov 1997: If g77Fortran defined, also define f2cFortran (PDW/HSTX)
+ Feb 1998: Let VMS see the NUM_ELEMS code. Lets programs treat
+ single strings as vectors with single elements
+ Nov 1999: If macintoxh defined, also define f2cfortran (for Mac OS-X)
+ Apr 2000: If WIN32 defined, also define PowerStationFortran and
+ VISUAL_CPLUSPLUS (Visual C++)
+ Jun 2000: If __GNUC__ and linux defined, also define f2cFortran
+ (linux/gcc environment detection)
+ Apr 2002: If __CYGWIN__ is defined, also define f2cFortran
+ Nov 2002: If __APPLE__ defined, also define f2cfortran (for Mac OS-X)
+
+ Nov 2003: If __INTEL_COMPILER or INTEL_COMPILER defined, also define
+ f2cFortran (KMCCARTY)
+ Dec 2005: If f2cFortran is defined, enforce REAL functions in FORTRAN
+ returning "double" in C. This was one of the items on
+ Burkhard's TODO list. (KMCCARTY)
+ Dec 2005: Modifications to support 8-byte integers. (MR)
+ USE AT YOUR OWN RISK!
+ Feb 2006 Added logic to typedef the symbol 'LONGLONG' to an appropriate
+ intrinsic 8-byte integer datatype (WDP)
+ Apr 2006: Modifications to support gfortran (and g77 with -fno-f2c flag)
+ since by default it returns "float" for FORTRAN REAL function.
+ (KMCCARTY)
+ May 2008: Revert commenting out of "extern" in COMMON_BLOCK_DEF macro.
+ Add braces around do-nothing ";" in 3 empty while blocks to
+ get rid of compiler warnings. Thanks to ROOT developers
+ Jacek Holeczek and Rene Brun for these suggestions. (KMCCARTY)
+ Dec 2008 Added typedef for LONGLONG to support Borland compiler (WDP)
+ *******/
+
+/*
+ Avoid symbols already used by compilers and system *.h:
+ __ - OSF1 zukal06 V3.0 347 alpha, cc -c -std1 cfortest.c
+
+*/
+
+/*
+ Determine what 8-byte integer data type is available.
+ 'long long' is now supported by most compilers, but older
+ MS Visual C++ compilers before V7.0 use '__int64' instead. (WDP)
+*/
+
+#ifndef LONGLONG_TYPE /* this may have been previously defined */
+#if defined(_MSC_VER) /* Microsoft Visual C++ */
+
+#if (_MSC_VER < 1300) /* versions earlier than V7.0 do not have 'long long' */
+ typedef __int64 LONGLONG;
+#else /* newer versions do support 'long long' */
+ typedef long long LONGLONG;
+#endif
+
+#elif defined( __BORLANDC__) /* (WDP) for the free Borland compiler, in particular */
+ typedef __int64 LONGLONG;
+#else
+ typedef long long LONGLONG;
+#endif
+
+#define LONGLONG_TYPE
+#endif
+
+/* Microsoft Visual C++ requires alternate form for static inline. */
+#if defined(_MSC_VER) /* Microsoft Visual C++ */
+#define STIN static __inline
+#else
+#define STIN static inline
+#endif
+
+/* First prepare for the C compiler. */
+
+#ifndef ANSI_C_preprocessor /* i.e. user can override. */
+#ifdef __CF__KnR
+#define ANSI_C_preprocessor 0
+#else
+#ifdef __STDC__
+#define ANSI_C_preprocessor 1
+#else
+#define _cfleft 1
+#define _cfright
+#define _cfleft_cfright 0
+#define ANSI_C_preprocessor _cfleft/**/_cfright
+#endif
+#endif
+#endif
+
+#if ANSI_C_preprocessor
+#define _0(A,B) A##B
+#define _(A,B) _0(A,B) /* see cat,xcat of K&R ANSI C p. 231 */
+#define _2(A,B) A##B /* K&R ANSI C p.230: .. identifier is not replaced */
+#define _3(A,B,C) _(A,_(B,C))
+#else /* if it turns up again during rescanning. */
+#define _(A,B) A/**/B
+#define _2(A,B) A/**/B
+#define _3(A,B,C) A/**/B/**/C
+#endif
+
+#if (defined(vax)&&defined(unix)) || (defined(__vax__)&&defined(__unix__))
+#define VAXUltrix
+#endif
+
+#include <stdio.h> /* NULL [in all machines stdio.h] */
+#include <string.h> /* strlen, memset, memcpy, memchr. */
+#if !( defined(VAXUltrix) || defined(sun) || (defined(apollo)&&!defined(__STDCPP__)) )
+#include <stdlib.h> /* malloc,free */
+#else
+#include <malloc.h> /* Had to be removed for DomainOS h105 10.4 sys5.3 425t*/
+#ifdef apollo
+#define __CF__APOLLO67 /* __STDCPP__ is in Apollo 6.8 (i.e. ANSI) and onwards */
+#endif
+#endif
+
+#if !defined(__GNUC__) && !defined(__sun) && (defined(sun)||defined(VAXUltrix)||defined(lynx))
+#define __CF__KnR /* Sun, LynxOS and VAX Ultrix cc only supports K&R. */
+ /* Manually define __CF__KnR for HP if desired/required.*/
+#endif /* i.e. We will generate Kernighan and Ritchie C. */
+/* Note that you may define __CF__KnR before #include cfortran.h, in order to
+generate K&R C instead of the default ANSI C. The differences are mainly in the
+function prototypes and declarations. All machines, except the Apollo, work
+with either style. The Apollo's argument promotion rules require ANSI or use of
+the obsolete std_$call which we have not implemented here. Hence on the Apollo,
+only C calling FORTRAN subroutines will work using K&R style.*/
+
+
+/* Remainder of cfortran.h depends on the Fortran compiler. */
+
+/* 11/29/2003 (KMCCARTY): add *INTEL_COMPILER symbols here */
+/* 04/05/2006 (KMCCARTY): add gFortran symbol here */
+#if defined(CLIPPERFortran) || defined(pgiFortran) || defined(__INTEL_COMPILER) || defined(INTEL_COMPILER) || defined(gFortran)
+#define f2cFortran
+#endif
+
+/* VAX/VMS does not let us \-split long #if lines. */
+/* Split #if into 2 because some HP-UX can't handle long #if */
+#if !(defined(NAGf90Fortran)||defined(f2cFortran)||defined(hpuxFortran)||defined(apolloFortran)||defined(sunFortran)||defined(IBMR2Fortran)||defined(CRAYFortran))
+#if !(defined(mipsFortran)||defined(DECFortran)||defined(vmsFortran)||defined(CONVEXFortran)||defined(PowerStationFortran)||defined(AbsoftUNIXFortran)||defined(AbsoftProFortran)||defined(SXFortran))
+/* If no Fortran compiler is given, we choose one for the machines we know. */
+#if defined(lynx) || defined(VAXUltrix)
+#define f2cFortran /* Lynx: Only support f2c at the moment.
+ VAXUltrix: f77 behaves like f2c.
+ Support f2c or f77 with gcc, vcc with f2c.
+ f77 with vcc works, missing link magic for f77 I/O.*/
+#endif
+/* 04/13/00 DM (CFITSIO): Add these lines for NT */
+/* with PowerStationFortran and and Visual C++ */
+#if defined(WIN32) && !defined(__CYGWIN__)
+#define PowerStationFortran
+#define VISUAL_CPLUSPLUS
+#endif
+#if defined(g77Fortran) /* 11/03/97 PDW (CFITSIO) */
+#define f2cFortran
+#endif
+#if defined(__CYGWIN__) /* 04/11/02 LEB (CFITSIO) */
+#define f2cFortran
+#endif
+#if defined(__GNUC__) && defined(linux) /* 06/21/00 PDW (CFITSIO) */
+#define f2cFortran
+#endif
+#if defined(macintosh) /* 11/1999 (CFITSIO) */
+#define f2cFortran
+#endif
+#if defined(__APPLE__) /* 11/2002 (CFITSIO) */
+#define f2cFortran
+#endif
+#if defined(__hpux) /* 921107: Use __hpux instead of __hp9000s300 */
+#define hpuxFortran /* Should also allow hp9000s7/800 use.*/
+#endif
+#if defined(apollo)
+#define apolloFortran /* __CF__APOLLO67 also defines some behavior. */
+#endif
+#if defined(sun) || defined(__sun)
+#define sunFortran
+#endif
+#if defined(_IBMR2)
+#define IBMR2Fortran
+#endif
+#if defined(_CRAY)
+#define CRAYFortran /* _CRAYT3E also defines some behavior. */
+#endif
+#if defined(_SX)
+#define SXFortran
+#endif
+#if defined(mips) || defined(__mips)
+#define mipsFortran
+#endif
+#if defined(vms) || defined(__vms)
+#define vmsFortran
+#endif
+#if defined(__alpha) && defined(__unix__)
+#define DECFortran
+#endif
+#if defined(__convex__)
+#define CONVEXFortran
+#endif
+#if defined(VISUAL_CPLUSPLUS)
+#define PowerStationFortran
+#endif
+#endif /* ...Fortran */
+#endif /* ...Fortran */
+
+/* Split #if into 2 because some HP-UX can't handle long #if */
+#if !(defined(NAGf90Fortran)||defined(f2cFortran)||defined(hpuxFortran)||defined(apolloFortran)||defined(sunFortran)||defined(IBMR2Fortran)||defined(CRAYFortran))
+#if !(defined(mipsFortran)||defined(DECFortran)||defined(vmsFortran)||defined(CONVEXFortran)||defined(PowerStationFortran)||defined(AbsoftUNIXFortran)||defined(AbsoftProFortran)||defined(SXFortran))
+/* If your compiler barfs on ' #error', replace # with the trigraph for # */
+ #error "cfortran.h: Can't find your environment among:\
+ - GNU gcc (g77) on Linux. \
+ - MIPS cc and f77 2.0. (e.g. Silicon Graphics, DECstations, ...) \
+ - IBM AIX XL C and FORTRAN Compiler/6000 Version 01.01.0000.0000 \
+ - VAX VMS CC 3.1 and FORTRAN 5.4. \
+ - Alpha VMS DEC C 1.3 and DEC FORTRAN 6.0. \
+ - Alpha OSF DEC C and DEC Fortran for OSF/1 AXP Version 1.2 \
+ - Apollo DomainOS 10.2 (sys5.3) with f77 10.7 and cc 6.7. \
+ - CRAY \
+ - NEC SX-4 SUPER-UX \
+ - CONVEX \
+ - Sun \
+ - PowerStation Fortran with Visual C++ \
+ - HP9000s300/s700/s800 Latest test with: HP-UX A.08.07 A 9000/730 \
+ - LynxOS: cc or gcc with f2c. \
+ - VAXUltrix: vcc,cc or gcc with f2c. gcc or cc with f77. \
+ - f77 with vcc works; but missing link magic for f77 I/O. \
+ - NO fort. None of gcc, cc or vcc generate required names.\
+ - f2c/g77: Use #define f2cFortran, or cc -Df2cFortran \
+ - gfortran: Use #define gFortran, or cc -DgFortran \
+ (also necessary for g77 with -fno-f2c option) \
+ - NAG f90: Use #define NAGf90Fortran, or cc -DNAGf90Fortran \
+ - Absoft UNIX F77: Use #define AbsoftUNIXFortran or cc -DAbsoftUNIXFortran \
+ - Absoft Pro Fortran: Use #define AbsoftProFortran \
+ - Portland Group Fortran: Use #define pgiFortran \
+ - Intel Fortran: Use #define INTEL_COMPILER"
+/* Compiler must throw us out at this point! */
+#endif
+#endif
+
+
+#if defined(VAXC) && !defined(__VAXC)
+#define OLD_VAXC
+#pragma nostandard /* Prevent %CC-I-PARAMNOTUSED. */
+#endif
+
+/* Throughout cfortran.h we use: UN = Uppercase Name. LN = Lowercase Name. */
+
+/* "extname" changed to "appendus" below (CFITSIO) */
+#if defined(f2cFortran) || defined(NAGf90Fortran) || defined(DECFortran) || defined(mipsFortran) || defined(apolloFortran) || defined(sunFortran) || defined(CONVEXFortran) || defined(SXFortran) || defined(appendus)
+#define CFC_(UN,LN) _(LN,_) /* Lowercase FORTRAN symbols. */
+#define orig_fcallsc(UN,LN) CFC_(UN,LN)
+#else
+#if defined(CRAYFortran) || defined(PowerStationFortran) || defined(AbsoftProFortran)
+#ifdef _CRAY /* (UN), not UN, circumvents CRAY preprocessor bug. */
+#define CFC_(UN,LN) (UN) /* Uppercase FORTRAN symbols. */
+#else /* At least VISUAL_CPLUSPLUS barfs on (UN), so need UN. */
+#define CFC_(UN,LN) UN /* Uppercase FORTRAN symbols. */
+#endif
+#define orig_fcallsc(UN,LN) CFC_(UN,LN) /* CRAY insists on arg.'s here. */
+#else /* For following machines one may wish to change the fcallsc default. */
+#define CF_SAME_NAMESPACE
+#ifdef vmsFortran
+#define CFC_(UN,LN) LN /* Either case FORTRAN symbols. */
+ /* BUT we usually use UN for C macro to FORTRAN routines, so use LN here,*/
+ /* because VAX/VMS doesn't do recursive macros. */
+#define orig_fcallsc(UN,LN) UN
+#else /* HP-UX without +ppu or IBMR2 without -qextname. NOT reccomended. */
+#define CFC_(UN,LN) LN /* Lowercase FORTRAN symbols. */
+#define orig_fcallsc(UN,LN) CFC_(UN,LN)
+#endif /* vmsFortran */
+#endif /* CRAYFortran PowerStationFortran */
+#endif /* ....Fortran */
+
+#define fcallsc(UN,LN) orig_fcallsc(UN,LN)
+#define preface_fcallsc(P,p,UN,LN) CFC_(_(P,UN),_(p,LN))
+#define append_fcallsc(P,p,UN,LN) CFC_(_(UN,P),_(LN,p))
+
+#define C_FUNCTION(UN,LN) fcallsc(UN,LN)
+#define FORTRAN_FUNCTION(UN,LN) CFC_(UN,LN)
+
+#ifndef COMMON_BLOCK
+#ifndef CONVEXFortran
+#ifndef CLIPPERFortran
+#if !(defined(AbsoftUNIXFortran)||defined(AbsoftProFortran))
+#define COMMON_BLOCK(UN,LN) CFC_(UN,LN)
+#else
+#define COMMON_BLOCK(UN,LN) _(_C,LN)
+#endif /* AbsoftUNIXFortran or AbsoftProFortran */
+#else
+#define COMMON_BLOCK(UN,LN) _(LN,__)
+#endif /* CLIPPERFortran */
+#else
+#define COMMON_BLOCK(UN,LN) _3(_,LN,_)
+#endif /* CONVEXFortran */
+#endif /* COMMON_BLOCK */
+
+#ifndef DOUBLE_PRECISION
+#if defined(CRAYFortran) && !defined(_CRAYT3E)
+#define DOUBLE_PRECISION long double
+#else
+#define DOUBLE_PRECISION double
+#endif
+#endif
+
+#ifndef FORTRAN_REAL
+#if defined(CRAYFortran) && defined(_CRAYT3E)
+#define FORTRAN_REAL double
+#else
+#define FORTRAN_REAL float
+#endif
+#endif
+
+#ifdef CRAYFortran
+#ifdef _CRAY
+#include <fortran.h>
+#else
+#include "fortran.h" /* i.e. if crosscompiling assume user has file. */
+#endif
+#define FLOATVVVVVVV_cfPP (FORTRAN_REAL *) /* Used for C calls FORTRAN. */
+/* CRAY's double==float but CRAY says pointers to doubles and floats are diff.*/
+#define VOIDP (void *) /* When FORTRAN calls C, we don't know if C routine
+ arg.'s have been declared float *, or double *. */
+#else
+#define FLOATVVVVVVV_cfPP
+#define VOIDP
+#endif
+
+#ifdef vmsFortran
+#if defined(vms) || defined(__vms)
+#include <descrip.h>
+#else
+#include "descrip.h" /* i.e. if crosscompiling assume user has file. */
+#endif
+#endif
+
+#ifdef sunFortran
+#if defined(sun) || defined(__sun)
+#include <math.h> /* Sun's FLOATFUNCTIONTYPE, ASSIGNFLOAT, RETURNFLOAT. */
+#else
+#include "math.h" /* i.e. if crosscompiling assume user has file. */
+#endif
+/* At least starting with the default C compiler SC3.0.1 of SunOS 5.3,
+ * FLOATFUNCTIONTYPE, ASSIGNFLOAT, RETURNFLOAT are not required and not in
+ * <math.h>, since sun C no longer promotes C float return values to doubles.
+ * Therefore, only use them if defined.
+ * Even if gcc is being used, assume that it exhibits the Sun C compiler
+ * behavior in order to be able to use *.o from the Sun C compiler.
+ * i.e. If FLOATFUNCTIONTYPE, etc. are in math.h, they required by gcc.
+ */
+#endif
+
+#ifndef apolloFortran
+#define COMMON_BLOCK_DEF(DEFINITION, NAME) extern DEFINITION NAME
+#define CF_NULL_PROTO
+#else /* HP doesn't understand #elif. */
+/* Without ANSI prototyping, Apollo promotes float functions to double. */
+/* Note that VAX/VMS, IBM, Mips choke on 'type function(...);' prototypes. */
+#define CF_NULL_PROTO ...
+#ifndef __CF__APOLLO67
+#define COMMON_BLOCK_DEF(DEFINITION, NAME) \
+ DEFINITION NAME __attribute((__section(NAME)))
+#else
+#define COMMON_BLOCK_DEF(DEFINITION, NAME) \
+ DEFINITION NAME #attribute[section(NAME)]
+#endif
+#endif
+
+#ifdef __cplusplus
+#undef CF_NULL_PROTO
+#define CF_NULL_PROTO ...
+#endif
+
+
+#ifndef USE_NEW_DELETE
+#ifdef __cplusplus
+#define USE_NEW_DELETE 1
+#else
+#define USE_NEW_DELETE 0
+#endif
+#endif
+#if USE_NEW_DELETE
+#define _cf_malloc(N) new char[N]
+#define _cf_free(P) delete[] P
+#else
+#define _cf_malloc(N) (char *)malloc(N)
+#define _cf_free(P) free(P)
+#endif
+
+#ifdef mipsFortran
+#define CF_DECLARE_GETARG int f77argc; char **f77argv
+#define CF_SET_GETARG(ARGC,ARGV) f77argc = ARGC; f77argv = ARGV
+#else
+#define CF_DECLARE_GETARG
+#define CF_SET_GETARG(ARGC,ARGV)
+#endif
+
+#ifdef OLD_VAXC /* Allow %CC-I-PARAMNOTUSED. */
+#pragma standard
+#endif
+
+#define AcfCOMMA ,
+#define AcfCOLON ;
+
+/*-------------------------------------------------------------------------*/
+
+/* UTILITIES USED WITHIN CFORTRAN.H */
+
+#define _cfMIN(A,B) (A<B?A:B)
+
+/* 970211 - XIX.145:
+ firstindexlength - better name is all_but_last_index_lengths
+ secondindexlength - better name is last_index_length
+ */
+#define firstindexlength(A) (sizeof(A[0])==1 ? 1 : (sizeof(A) / sizeof(A[0])) )
+#define secondindexlength(A) (sizeof(A[0])==1 ? sizeof(A) : sizeof(A[0]) )
+
+/* Behavior of FORTRAN LOGICAL. All machines' LOGICAL is same size as C's int.
+Conversion is automatic except for arrays which require F2CLOGICALV/C2FLOGICALV.
+f2c, MIPS f77 [DECstation, SGI], VAX Ultrix f77,
+HP-UX f77 : as in C.
+VAX/VMS FORTRAN, VAX Ultrix fort,
+Absoft Unix Fortran, IBM RS/6000 xlf : LS Bit = 0/1 = TRUE/FALSE.
+Apollo : neg. = TRUE, else FALSE.
+[Apollo accepts -1 as TRUE for function values, but NOT all other neg. values.]
+[DECFortran for Ultrix RISC is also called f77 but is the same as VAX/VMS.]
+[MIPS f77 treats .eqv./.neqv. as .eq./.ne. and hence requires LOGICAL_STRICT.]*/
+
+#if defined(NAGf90Fortran) || defined(f2cFortran) || defined(mipsFortran) || defined(PowerStationFortran) || defined(hpuxFortran800) || defined(AbsoftUNIXFortran) || defined(AbsoftProFortran) || defined(SXFortran)
+/* SX/PowerStationFortran have 0 and 1 defined, others are neither T nor F. */
+/* hpuxFortran800 has 0 and 0x01000000 defined. Others are unknown. */
+#define LOGICAL_STRICT /* Other Fortran have .eqv./.neqv. == .eq./.ne. */
+#endif
+
+#define C2FLOGICALV(A,I) \
+ do {int __i; for(__i=0;__i<I;__i++) A[__i]=C2FLOGICAL(A[__i]); } while (0)
+#define F2CLOGICALV(A,I) \
+ do {int __i; for(__i=0;__i<I;__i++) A[__i]=F2CLOGICAL(A[__i]); } while (0)
+
+#if defined(apolloFortran)
+#define C2FLOGICAL(L) ((L)?-1:(L)&~((unsigned)1<<sizeof(int)*8-1))
+#define F2CLOGICAL(L) ((L)<0?(L):0)
+#else
+#if defined(CRAYFortran)
+#define C2FLOGICAL(L) _btol(L)
+#define F2CLOGICAL(L) _ltob(&(L)) /* Strangely _ltob() expects a pointer. */
+#else
+#if defined(IBMR2Fortran) || defined(vmsFortran) || defined(DECFortran) || defined(AbsoftUNIXFortran)
+/* How come no AbsoftProFortran ? */
+#define C2FLOGICAL(L) ((L)?(L)|1:(L)&~(int)1)
+#define F2CLOGICAL(L) ((L)&1?(L):0)
+#else
+#if defined(CONVEXFortran)
+#define C2FLOGICAL(L) ((L) ? ~0 : 0 )
+#define F2CLOGICAL(L) (L)
+#else /* others evaluate LOGICALs as for C. */
+#define C2FLOGICAL(L) (L)
+#define F2CLOGICAL(L) (L)
+#ifndef LOGICAL_STRICT
+#undef C2FLOGICALV
+#undef F2CLOGICALV
+#define C2FLOGICALV(A,I)
+#define F2CLOGICALV(A,I)
+#endif /* LOGICAL_STRICT */
+#endif /* CONVEXFortran || All Others */
+#endif /* IBMR2Fortran vmsFortran DECFortran AbsoftUNIXFortran */
+#endif /* CRAYFortran */
+#endif /* apolloFortran */
+
+/* 970514 - In addition to CRAY, there may be other machines
+ for which LOGICAL_STRICT makes no sense. */
+#if defined(LOGICAL_STRICT) && !defined(CRAYFortran)
+/* Force C2FLOGICAL to generate only the values for either .TRUE. or .FALSE.
+ SX/PowerStationFortran only have 0 and 1 defined.
+ Elsewhere, only needed if you want to do:
+ logical lvariable
+ if (lvariable .eq. .true.) then ! (1)
+ instead of
+ if (lvariable .eqv. .true.) then ! (2)
+ - (1) may not even be FORTRAN/77 and that Apollo's f77 and IBM's xlf
+ refuse to compile (1), so you are probably well advised to stay away from
+ (1) and from LOGICAL_STRICT.
+ - You pay a (slight) performance penalty for using LOGICAL_STRICT. */
+#undef C2FLOGICAL
+#ifdef hpuxFortran800
+#define C2FLOGICAL(L) ((L)?0x01000000:0)
+#else
+#if defined(apolloFortran) || defined(vmsFortran) || defined(DECFortran)
+#define C2FLOGICAL(L) ((L)?-1:0) /* These machines use -1/0 for .true./.false.*/
+#else
+#define C2FLOGICAL(L) ((L)? 1:0) /* All others use +1/0 for .true./.false.*/
+#endif
+#endif
+#endif /* LOGICAL_STRICT */
+
+/* Convert a vector of C strings into FORTRAN strings. */
+#ifndef __CF__KnR
+static char *c2fstrv(char* cstr, char *fstr, int elem_len, int sizeofcstr)
+#else
+static char *c2fstrv( cstr, fstr, elem_len, sizeofcstr)
+ char* cstr; char *fstr; int elem_len; int sizeofcstr;
+#endif
+{ int i,j;
+/* elem_len includes \0 for C strings. Fortran strings don't have term. \0.
+ Useful size of string must be the same in both languages. */
+for (i=0; i<sizeofcstr/elem_len; i++) {
+ for (j=1; j<elem_len && *cstr; j++) *fstr++ = *cstr++;
+ cstr += 1+elem_len-j;
+ for (; j<elem_len; j++) *fstr++ = ' ';
+} /* 95109 - Seems to be returning the original fstr. */
+return fstr-sizeofcstr+sizeofcstr/elem_len; }
+
+/* Convert a vector of FORTRAN strings into C strings. */
+#ifndef __CF__KnR
+static char *f2cstrv(char *fstr, char* cstr, int elem_len, int sizeofcstr)
+#else
+static char *f2cstrv( fstr, cstr, elem_len, sizeofcstr)
+ char *fstr; char* cstr; int elem_len; int sizeofcstr;
+#endif
+{ int i,j;
+/* elem_len includes \0 for C strings. Fortran strings don't have term. \0.
+ Useful size of string must be the same in both languages. */
+cstr += sizeofcstr;
+fstr += sizeofcstr - sizeofcstr/elem_len;
+for (i=0; i<sizeofcstr/elem_len; i++) {
+ *--cstr = '\0';
+ for (j=1; j<elem_len; j++) *--cstr = *--fstr;
+} return cstr; }
+
+/* kill the trailing char t's in string s. */
+#ifndef __CF__KnR
+static char *kill_trailing(char *s, char t)
+#else
+static char *kill_trailing( s, t) char *s; char t;
+#endif
+{char *e;
+e = s + strlen(s);
+if (e>s) { /* Need this to handle NULL string.*/
+ while (e>s && *--e==t) {;} /* Don't follow t's past beginning. */
+ e[*e==t?0:1] = '\0'; /* Handle s[0]=t correctly. */
+} return s; }
+
+/* kill_trailingn(s,t,e) will kill the trailing t's in string s. e normally
+points to the terminating '\0' of s, but may actually point to anywhere in s.
+s's new '\0' will be placed at e or earlier in order to remove any trailing t's.
+If e<s string s is left unchanged. */
+#ifndef __CF__KnR
+static char *kill_trailingn(char *s, char t, char *e)
+#else
+static char *kill_trailingn( s, t, e) char *s; char t; char *e;
+#endif
+{
+if (e==s) *e = '\0'; /* Kill the string makes sense here.*/
+else if (e>s) { /* Watch out for neg. length string.*/
+ while (e>s && *--e==t){;} /* Don't follow t's past beginning. */
+ e[*e==t?0:1] = '\0'; /* Handle s[0]=t correctly. */
+} return s; }
+
+/* Note the following assumes that any element which has t's to be chopped off,
+does indeed fill the entire element. */
+#ifndef __CF__KnR
+static char *vkill_trailing(char* cstr, int elem_len, int sizeofcstr, char t)
+#else
+static char *vkill_trailing( cstr, elem_len, sizeofcstr, t)
+ char* cstr; int elem_len; int sizeofcstr; char t;
+#endif
+{ int i;
+for (i=0; i<sizeofcstr/elem_len; i++) /* elem_len includes \0 for C strings. */
+ kill_trailingn(cstr+elem_len*i,t,cstr+elem_len*(i+1)-1);
+return cstr; }
+
+#ifdef vmsFortran
+typedef struct dsc$descriptor_s fstring;
+#define DSC$DESCRIPTOR_A(DIMCT) \
+struct { \
+ unsigned short dsc$w_length; unsigned char dsc$b_dtype; \
+ unsigned char dsc$b_class; char *dsc$a_pointer; \
+ char dsc$b_scale; unsigned char dsc$b_digits; \
+ struct { \
+ unsigned : 3; unsigned dsc$v_fl_binscale : 1; \
+ unsigned dsc$v_fl_redim : 1; unsigned dsc$v_fl_column : 1; \
+ unsigned dsc$v_fl_coeff : 1; unsigned dsc$v_fl_bounds : 1; \
+ } dsc$b_aflags; \
+ unsigned char dsc$b_dimct; unsigned long dsc$l_arsize; \
+ char *dsc$a_a0; long dsc$l_m [DIMCT]; \
+ struct { \
+ long dsc$l_l; long dsc$l_u; \
+ } dsc$bounds [DIMCT]; \
+}
+typedef DSC$DESCRIPTOR_A(1) fstringvector;
+/*typedef DSC$DESCRIPTOR_A(2) fstringarrarr;
+ typedef DSC$DESCRIPTOR_A(3) fstringarrarrarr;*/
+#define initfstr(F,C,ELEMNO,ELEMLEN) \
+( (F).dsc$l_arsize= ( (F).dsc$w_length =(ELEMLEN) ) \
+ *( (F).dsc$l_m[0]=(F).dsc$bounds[0].dsc$l_u=(ELEMNO) ), \
+ (F).dsc$a_a0 = ( (F).dsc$a_pointer=(C) ) - (F).dsc$w_length ,(F))
+
+#endif /* PDW: 2/10/98 (CFITSIO) -- Let VMS see NUM_ELEMS definitions */
+#define _NUM_ELEMS -1
+#define _NUM_ELEM_ARG -2
+#define NUM_ELEMS(A) A,_NUM_ELEMS
+#define NUM_ELEM_ARG(B) *_2(A,B),_NUM_ELEM_ARG
+#define TERM_CHARS(A,B) A,B
+#ifndef __CF__KnR
+STIN int num_elem(char *strv, unsigned elem_len, int term_char, int num_term)
+#else
+STIN int num_elem( strv, elem_len, term_char, num_term)
+ char *strv; unsigned elem_len; int term_char; int num_term;
+#endif
+/* elem_len is the number of characters in each element of strv, the FORTRAN
+vector of strings. The last element of the vector must begin with at least
+num_term term_char characters, so that this routine can determine how
+many elements are in the vector. */
+{
+unsigned num,i;
+if (num_term == _NUM_ELEMS || num_term == _NUM_ELEM_ARG)
+ return term_char;
+if (num_term <=0) num_term = (int)elem_len;
+for (num=0; ; num++) {
+ for (i=0; i<(unsigned)num_term && *strv==term_char; i++,strv++){;}
+ if (i==(unsigned)num_term) break;
+ else strv += elem_len-i;
+}
+if (0) { /* to prevent not used warnings in gcc (added by ROOT) */
+ c2fstrv(0, 0, 0, 0); f2cstrv(0, 0, 0, 0); kill_trailing(0, 0);
+ vkill_trailing(0, 0, 0, 0); num_elem(0, 0, 0, 0);
+}
+return (int)num;
+}
+/* #endif removed 2/10/98 (CFITSIO) */
+
+/*-------------------------------------------------------------------------*/
+
+/* UTILITIES FOR C TO USE STRINGS IN FORTRAN COMMON BLOCKS */
+
+/* C string TO Fortran Common Block STRing. */
+/* DIM is the number of DIMensions of the array in terms of strings, not
+ characters. e.g. char a[12] has DIM = 0, char a[12][4] has DIM = 1, etc. */
+#define C2FCBSTR(CSTR,FSTR,DIM) \
+ c2fstrv((char *)CSTR, (char *)FSTR, sizeof(FSTR)/cfelementsof(FSTR,DIM)+1, \
+ sizeof(FSTR)+cfelementsof(FSTR,DIM))
+
+/* Fortran Common Block string TO C STRing. */
+#define FCB2CSTR(FSTR,CSTR,DIM) \
+ vkill_trailing(f2cstrv((char *)FSTR, (char *)CSTR, \
+ sizeof(FSTR)/cfelementsof(FSTR,DIM)+1, \
+ sizeof(FSTR)+cfelementsof(FSTR,DIM)), \
+ sizeof(FSTR)/cfelementsof(FSTR,DIM)+1, \
+ sizeof(FSTR)+cfelementsof(FSTR,DIM), ' ')
+
+#define cfDEREFERENCE0
+#define cfDEREFERENCE1 *
+#define cfDEREFERENCE2 **
+#define cfDEREFERENCE3 ***
+#define cfDEREFERENCE4 ****
+#define cfDEREFERENCE5 *****
+#define cfelementsof(A,D) (sizeof(A)/sizeof(_(cfDEREFERENCE,D)(A)))
+
+/*-------------------------------------------------------------------------*/
+
+/* UTILITIES FOR C TO CALL FORTRAN SUBROUTINES */
+
+/* Define lookup tables for how to handle the various types of variables. */
+
+#ifdef OLD_VAXC /* Prevent %CC-I-PARAMNOTUSED. */
+#pragma nostandard
+#endif
+
+#define ZTRINGV_NUM(I) I
+#define ZTRINGV_ARGFP(I) (*(_2(A,I))) /* Undocumented. For PINT, etc. */
+#define ZTRINGV_ARGF(I) _2(A,I)
+#ifdef CFSUBASFUN
+#define ZTRINGV_ARGS(I) ZTRINGV_ARGF(I)
+#else
+#define ZTRINGV_ARGS(I) _2(B,I)
+#endif
+
+#define PBYTE_cfVP(A,B) PINT_cfVP(A,B)
+#define PDOUBLE_cfVP(A,B)
+#define PFLOAT_cfVP(A,B)
+#ifdef ZTRINGV_ARGS_allows_Pvariables
+/* This allows Pvariables for ARGS. ARGF machinery is above ARGFP.
+ * B is not needed because the variable may be changed by the Fortran routine,
+ * but because B is the only way to access an arbitrary macro argument. */
+#define PINT_cfVP(A,B) int B = (int)A; /* For ZSTRINGV_ARGS */
+#else
+#define PINT_cfVP(A,B)
+#endif
+#define PLOGICAL_cfVP(A,B) int *B; /* Returning LOGICAL in FUNn and SUBn */
+#define PLONG_cfVP(A,B) PINT_cfVP(A,B)
+#define PSHORT_cfVP(A,B) PINT_cfVP(A,B)
+
+#define VCF_INT_S(T,A,B) _(T,VVVVVVV_cfTYPE) B = A;
+#define VCF_INT_F(T,A,B) _(T,_cfVCF)(A,B)
+/* _cfVCF table is directly mapped to _cfCCC table. */
+#define BYTE_cfVCF(A,B)
+#define DOUBLE_cfVCF(A,B)
+#if !defined(__CF__KnR)
+#define FLOAT_cfVCF(A,B)
+#else
+#define FLOAT_cfVCF(A,B) FORTRAN_REAL B = A;
+#endif
+#define INT_cfVCF(A,B)
+#define LOGICAL_cfVCF(A,B)
+#define LONG_cfVCF(A,B)
+#define SHORT_cfVCF(A,B)
+
+/* 980416
+ Cast (void (*)(CF_NULL_PROTO)) causes SunOS CC 4.2 occasionally to barf,
+ while the following equivalent typedef is fine.
+ For consistency use the typedef on all machines.
+ */
+typedef void (*cfCAST_FUNCTION)(CF_NULL_PROTO);
+
+#define VCF(TN,I) _Icf4(4,V,TN,_(A,I),_(B,I),F)
+#define VVCF(TN,AI,BI) _Icf4(4,V,TN,AI,BI,S)
+#define INT_cfV(T,A,B,F) _(VCF_INT_,F)(T,A,B)
+#define INTV_cfV(T,A,B,F)
+#define INTVV_cfV(T,A,B,F)
+#define INTVVV_cfV(T,A,B,F)
+#define INTVVVV_cfV(T,A,B,F)
+#define INTVVVVV_cfV(T,A,B,F)
+#define INTVVVVVV_cfV(T,A,B,F)
+#define INTVVVVVVV_cfV(T,A,B,F)
+#define PINT_cfV( T,A,B,F) _(T,_cfVP)(A,B)
+#define PVOID_cfV( T,A,B,F)
+#if defined(apolloFortran) || defined(hpuxFortran800) || defined(AbsoftUNIXFortran) || defined(AbsoftProFortran)
+#define ROUTINE_cfV(T,A,B,F) void (*B)(CF_NULL_PROTO) = (cfCAST_FUNCTION)A;
+#else
+#define ROUTINE_cfV(T,A,B,F)
+#endif
+#define SIMPLE_cfV(T,A,B,F)
+#ifdef vmsFortran
+#define STRING_cfV(T,A,B,F) static struct {fstring f; unsigned clen;} B = \
+ {{0,DSC$K_DTYPE_T,DSC$K_CLASS_S,NULL},0};
+#define PSTRING_cfV(T,A,B,F) static fstring B={0,DSC$K_DTYPE_T,DSC$K_CLASS_S,NULL};
+#define STRINGV_cfV(T,A,B,F) static fstringvector B = \
+ {sizeof(A),DSC$K_DTYPE_T,DSC$K_CLASS_A,NULL,0,0,{0,0,1,1,1},1,0,NULL,0,{1,0}};
+#define PSTRINGV_cfV(T,A,B,F) static fstringvector B = \
+ {0,DSC$K_DTYPE_T,DSC$K_CLASS_A,NULL,0,0,{0,0,1,1,1},1,0,NULL,0,{1,0}};
+#else
+#define STRING_cfV(T,A,B,F) struct {unsigned int clen, flen; char *nombre;} B;
+#define STRINGV_cfV(T,A,B,F) struct {char *s, *fs; unsigned flen; char *nombre;} B;
+#define PSTRING_cfV(T,A,B,F) int B;
+#define PSTRINGV_cfV(T,A,B,F) struct{char *fs; unsigned int sizeofA,flen;}B;
+#endif
+#define ZTRINGV_cfV(T,A,B,F) STRINGV_cfV(T,A,B,F)
+#define PZTRINGV_cfV(T,A,B,F) PSTRINGV_cfV(T,A,B,F)
+
+/* Note that the actions of the A table were performed inside the AA table.
+ VAX Ultrix vcc, and HP-UX cc, didn't evaluate arguments to functions left to
+ right, so we had to split the original table into the current robust two. */
+#define ACF(NAME,TN,AI,I) _(TN,_cfSTR)(4,A,NAME,I,AI,_(B,I),0)
+#define DEFAULT_cfA(M,I,A,B)
+#define LOGICAL_cfA(M,I,A,B) B=C2FLOGICAL(B);
+#define PLOGICAL_cfA(M,I,A,B) A=C2FLOGICAL(A);
+#define STRING_cfA(M,I,A,B) STRING_cfC(M,I,A,B,sizeof(A))
+#define PSTRING_cfA(M,I,A,B) PSTRING_cfC(M,I,A,B,sizeof(A))
+#ifdef vmsFortran
+#define AATRINGV_cfA( A,B, sA,filA,silA) \
+ initfstr(B,_cf_malloc((sA)-(filA)),(filA),(silA)-1), \
+ c2fstrv(A,B.dsc$a_pointer,(silA),(sA));
+#define APATRINGV_cfA( A,B, sA,filA,silA) \
+ initfstr(B,A,(filA),(silA)-1),c2fstrv(A,A,(silA),(sA));
+#else
+#define AATRINGV_cfA( A,B, sA,filA,silA) \
+ (B.s=_cf_malloc((sA)-(filA)),B.fs=c2fstrv(A,B.s,(B.flen=(silA)-1)+1,(sA)));
+#define APATRINGV_cfA( A,B, sA,filA,silA) \
+ B.fs=c2fstrv(A,A,(B.flen=(silA)-1)+1,B.sizeofA=(sA));
+#endif
+#define STRINGV_cfA(M,I,A,B) \
+ AATRINGV_cfA((char *)A,B,sizeof(A),firstindexlength(A),secondindexlength(A))
+#define PSTRINGV_cfA(M,I,A,B) \
+ APATRINGV_cfA((char *)A,B,sizeof(A),firstindexlength(A),secondindexlength(A))
+#define ZTRINGV_cfA(M,I,A,B) AATRINGV_cfA( (char *)A,B, \
+ (_3(M,_ELEMS_,I))*(( _3(M,_ELEMLEN_,I))+1), \
+ (_3(M,_ELEMS_,I)),(_3(M,_ELEMLEN_,I))+1)
+#define PZTRINGV_cfA(M,I,A,B) APATRINGV_cfA( (char *)A,B, \
+ (_3(M,_ELEMS_,I))*(( _3(M,_ELEMLEN_,I))+1), \
+ (_3(M,_ELEMS_,I)),(_3(M,_ELEMLEN_,I))+1)
+
+#define PBYTE_cfAAP(A,B) &A
+#define PDOUBLE_cfAAP(A,B) &A
+#define PFLOAT_cfAAP(A,B) FLOATVVVVVVV_cfPP &A
+#define PINT_cfAAP(A,B) &A
+#define PLOGICAL_cfAAP(A,B) B= &A /* B used to keep a common W table. */
+#define PLONG_cfAAP(A,B) &A
+#define PSHORT_cfAAP(A,B) &A
+
+#define AACF(TN,AI,I,C) _SEP_(TN,C,cfCOMMA) _Icf(3,AA,TN,AI,_(B,I))
+#define INT_cfAA(T,A,B) &B
+#define INTV_cfAA(T,A,B) _(T,VVVVVV_cfPP) A
+#define INTVV_cfAA(T,A,B) _(T,VVVVV_cfPP) A[0]
+#define INTVVV_cfAA(T,A,B) _(T,VVVV_cfPP) A[0][0]
+#define INTVVVV_cfAA(T,A,B) _(T,VVV_cfPP) A[0][0][0]
+#define INTVVVVV_cfAA(T,A,B) _(T,VV_cfPP) A[0][0][0][0]
+#define INTVVVVVV_cfAA(T,A,B) _(T,V_cfPP) A[0][0][0][0][0]
+#define INTVVVVVVV_cfAA(T,A,B) _(T,_cfPP) A[0][0][0][0][0][0]
+#define PINT_cfAA(T,A,B) _(T,_cfAAP)(A,B)
+#define PVOID_cfAA(T,A,B) (void *) A
+#if defined(apolloFortran) || defined(hpuxFortran800) || defined(AbsoftUNIXFortran)
+#define ROUTINE_cfAA(T,A,B) &B
+#else
+#define ROUTINE_cfAA(T,A,B) (cfCAST_FUNCTION)A
+#endif
+#define STRING_cfAA(T,A,B) STRING_cfCC(T,A,B)
+#define PSTRING_cfAA(T,A,B) PSTRING_cfCC(T,A,B)
+#ifdef vmsFortran
+#define STRINGV_cfAA(T,A,B) &B
+#else
+#ifdef CRAYFortran
+#define STRINGV_cfAA(T,A,B) _cptofcd(B.fs,B.flen)
+#else
+#define STRINGV_cfAA(T,A,B) B.fs
+#endif
+#endif
+#define PSTRINGV_cfAA(T,A,B) STRINGV_cfAA(T,A,B)
+#define ZTRINGV_cfAA(T,A,B) STRINGV_cfAA(T,A,B)
+#define PZTRINGV_cfAA(T,A,B) STRINGV_cfAA(T,A,B)
+
+#if defined(vmsFortran) || defined(CRAYFortran)
+#define JCF(TN,I)
+#define KCF(TN,I)
+#else
+#define JCF(TN,I) _(TN,_cfSTR)(1,J,_(B,I), 0,0,0,0)
+#if defined(AbsoftUNIXFortran)
+#define DEFAULT_cfJ(B) ,0
+#else
+#define DEFAULT_cfJ(B)
+#endif
+#define LOGICAL_cfJ(B) DEFAULT_cfJ(B)
+#define PLOGICAL_cfJ(B) DEFAULT_cfJ(B)
+#define STRING_cfJ(B) ,B.flen
+#define PSTRING_cfJ(B) ,B
+#define STRINGV_cfJ(B) STRING_cfJ(B)
+#define PSTRINGV_cfJ(B) STRING_cfJ(B)
+#define ZTRINGV_cfJ(B) STRING_cfJ(B)
+#define PZTRINGV_cfJ(B) STRING_cfJ(B)
+
+/* KCF is identical to DCF, except that KCF ZTRING is not empty. */
+#define KCF(TN,I) _(TN,_cfSTR)(1,KK,_(B,I), 0,0,0,0)
+#if defined(AbsoftUNIXFortran)
+#define DEFAULT_cfKK(B) , unsigned B
+#else
+#define DEFAULT_cfKK(B)
+#endif
+#define LOGICAL_cfKK(B) DEFAULT_cfKK(B)
+#define PLOGICAL_cfKK(B) DEFAULT_cfKK(B)
+#define STRING_cfKK(B) , unsigned B
+#define PSTRING_cfKK(B) STRING_cfKK(B)
+#define STRINGV_cfKK(B) STRING_cfKK(B)
+#define PSTRINGV_cfKK(B) STRING_cfKK(B)
+#define ZTRINGV_cfKK(B) STRING_cfKK(B)
+#define PZTRINGV_cfKK(B) STRING_cfKK(B)
+#endif
+
+#define WCF(TN,AN,I) _(TN,_cfSTR)(2,W,AN,_(B,I), 0,0,0)
+#define DEFAULT_cfW(A,B)
+#define LOGICAL_cfW(A,B)
+#define PLOGICAL_cfW(A,B) *B=F2CLOGICAL(*B);
+#define STRING_cfW(A,B) (B.nombre=A,B.nombre[B.clen]!='\0'?B.nombre[B.clen]='\0':0); /* A?="constnt"*/
+#define PSTRING_cfW(A,B) kill_trailing(A,' ');
+#ifdef vmsFortran
+#define STRINGV_cfW(A,B) _cf_free(B.dsc$a_pointer);
+#define PSTRINGV_cfW(A,B) \
+ vkill_trailing(f2cstrv((char*)A, (char*)A, \
+ B.dsc$w_length+1, B.dsc$l_arsize+B.dsc$l_m[0]), \
+ B.dsc$w_length+1, B.dsc$l_arsize+B.dsc$l_m[0], ' ');
+#else
+#define STRINGV_cfW(A,B) _cf_free(B.s);
+#define PSTRINGV_cfW(A,B) vkill_trailing( \
+ f2cstrv((char*)A,(char*)A,B.flen+1,B.sizeofA), B.flen+1,B.sizeofA,' ');
+#endif
+#define ZTRINGV_cfW(A,B) STRINGV_cfW(A,B)
+#define PZTRINGV_cfW(A,B) PSTRINGV_cfW(A,B)
+
+#define NCF(TN,I,C) _SEP_(TN,C,cfCOMMA) _Icf(2,N,TN,_(A,I),0)
+#define NNCF(TN,I,C) UUCF(TN,I,C)
+#define NNNCF(TN,I,C) _SEP_(TN,C,cfCOLON) _Icf(2,N,TN,_(A,I),0)
+#define INT_cfN(T,A) _(T,VVVVVVV_cfTYPE) * A
+#define INTV_cfN(T,A) _(T,VVVVVV_cfTYPE) * A
+#define INTVV_cfN(T,A) _(T,VVVVV_cfTYPE) * A
+#define INTVVV_cfN(T,A) _(T,VVVV_cfTYPE) * A
+#define INTVVVV_cfN(T,A) _(T,VVV_cfTYPE) * A
+#define INTVVVVV_cfN(T,A) _(T,VV_cfTYPE) * A
+#define INTVVVVVV_cfN(T,A) _(T,V_cfTYPE) * A
+#define INTVVVVVVV_cfN(T,A) _(T,_cfTYPE) * A
+#define PINT_cfN(T,A) _(T,_cfTYPE) * A
+#define PVOID_cfN(T,A) void * A
+#if defined(apolloFortran) || defined(hpuxFortran800) || defined(AbsoftUNIXFortran)
+#define ROUTINE_cfN(T,A) void (**A)(CF_NULL_PROTO)
+#else
+#define ROUTINE_cfN(T,A) void ( *A)(CF_NULL_PROTO)
+#endif
+#ifdef vmsFortran
+#define STRING_cfN(T,A) fstring * A
+#define STRINGV_cfN(T,A) fstringvector * A
+#else
+#ifdef CRAYFortran
+#define STRING_cfN(T,A) _fcd A
+#define STRINGV_cfN(T,A) _fcd A
+#else
+#define STRING_cfN(T,A) char * A
+#define STRINGV_cfN(T,A) char * A
+#endif
+#endif
+#define PSTRING_cfN(T,A) STRING_cfN(T,A) /* CRAY insists on arg.'s here. */
+#define PNSTRING_cfN(T,A) STRING_cfN(T,A) /* CRAY insists on arg.'s here. */
+#define PPSTRING_cfN(T,A) STRING_cfN(T,A) /* CRAY insists on arg.'s here. */
+#define PSTRINGV_cfN(T,A) STRINGV_cfN(T,A)
+#define ZTRINGV_cfN(T,A) STRINGV_cfN(T,A)
+#define PZTRINGV_cfN(T,A) PSTRINGV_cfN(T,A)
+
+
+/* Apollo 6.7, CRAY, old Sun, VAX/Ultrix vcc/cc and new ultrix
+ can't hack more than 31 arg's.
+ e.g. ultrix >= 4.3 gives message:
+ zow35> cc -c -DDECFortran cfortest.c
+ cfe: Fatal: Out of memory: cfortest.c
+ zow35>
+ Old __hpux had the problem, but new 'HP-UX A.09.03 A 9000/735' is fine
+ if using -Aa, otherwise we have a problem.
+ */
+#ifndef MAX_PREPRO_ARGS
+#if !defined(__GNUC__) && (defined(VAXUltrix) || defined(__CF__APOLLO67) || (defined(sun)&&!defined(__sun)) || defined(_CRAY) || defined(__ultrix__) || (defined(__hpux)&&defined(__CF__KnR)))
+#define MAX_PREPRO_ARGS 31
+#else
+#define MAX_PREPRO_ARGS 99
+#endif
+#endif
+
+#if defined(AbsoftUNIXFortran) || defined(AbsoftProFortran)
+/* In addition to explicit Absoft stuff, only Absoft requires:
+ - DEFAULT coming from _cfSTR.
+ DEFAULT could have been called e.g. INT, but keep it for clarity.
+ - M term in CFARGT14 and CFARGT14FS.
+ */
+#define ABSOFT_cf1(T0) _(T0,_cfSTR)(0,ABSOFT1,0,0,0,0,0)
+#define ABSOFT_cf2(T0) _(T0,_cfSTR)(0,ABSOFT2,0,0,0,0,0)
+#define ABSOFT_cf3(T0) _(T0,_cfSTR)(0,ABSOFT3,0,0,0,0,0)
+#define DEFAULT_cfABSOFT1
+#define LOGICAL_cfABSOFT1
+#define STRING_cfABSOFT1 ,MAX_LEN_FORTRAN_FUNCTION_STRING
+#define DEFAULT_cfABSOFT2
+#define LOGICAL_cfABSOFT2
+#define STRING_cfABSOFT2 ,unsigned D0
+#define DEFAULT_cfABSOFT3
+#define LOGICAL_cfABSOFT3
+#define STRING_cfABSOFT3 ,D0
+#else
+#define ABSOFT_cf1(T0)
+#define ABSOFT_cf2(T0)
+#define ABSOFT_cf3(T0)
+#endif
+
+/* _Z introduced to cicumvent IBM and HP silly preprocessor warning.
+ e.g. "Macro CFARGT14 invoked with a null argument."
+ */
+#define _Z
+
+#define CFARGT14S(S,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \
+ S(T1,1) S(T2,2) S(T3,3) S(T4,4) S(T5,5) S(T6,6) S(T7,7) \
+ S(T8,8) S(T9,9) S(TA,10) S(TB,11) S(TC,12) S(TD,13) S(TE,14)
+#define CFARGT27S(S,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) \
+ S(T1,1) S(T2,2) S(T3,3) S(T4,4) S(T5,5) S(T6,6) S(T7,7) \
+ S(T8,8) S(T9,9) S(TA,10) S(TB,11) S(TC,12) S(TD,13) S(TE,14) \
+ S(TF,15) S(TG,16) S(TH,17) S(TI,18) S(TJ,19) S(TK,20) S(TL,21) \
+ S(TM,22) S(TN,23) S(TO,24) S(TP,25) S(TQ,26) S(TR,27)
+
+#define CFARGT14FS(F,S,M,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \
+ F(T1,1,0) F(T2,2,1) F(T3,3,1) F(T4,4,1) F(T5,5,1) F(T6,6,1) F(T7,7,1) \
+ F(T8,8,1) F(T9,9,1) F(TA,10,1) F(TB,11,1) F(TC,12,1) F(TD,13,1) F(TE,14,1) \
+ M CFARGT14S(S,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE)
+#define CFARGT27FS(F,S,M,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) \
+ F(T1,1,0) F(T2,2,1) F(T3,3,1) F(T4,4,1) F(T5,5,1) F(T6,6,1) F(T7,7,1) \
+ F(T8,8,1) F(T9,9,1) F(TA,10,1) F(TB,11,1) F(TC,12,1) F(TD,13,1) F(TE,14,1) \
+ F(TF,15,1) F(TG,16,1) F(TH,17,1) F(TI,18,1) F(TJ,19,1) F(TK,20,1) F(TL,21,1) \
+ F(TM,22,1) F(TN,23,1) F(TO,24,1) F(TP,25,1) F(TQ,26,1) F(TR,27,1) \
+ M CFARGT27S(S,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR)
+
+#if !(defined(PowerStationFortran)||defined(hpuxFortran800))
+/* Old CFARGT14 -> CFARGT14FS as seen below, for Absoft cross-compile yields:
+ SunOS> cc -c -Xa -DAbsoftUNIXFortran c.c
+ "c.c", line 406: warning: argument mismatch
+ Haven't checked if this is ANSI C or a SunOS bug. SunOS -Xs works ok.
+ Behavior is most clearly seen in example:
+ #define A 1 , 2
+ #define C(X,Y,Z) x=X. y=Y. z=Z.
+ #define D(X,Y,Z) C(X,Y,Z)
+ D(x,A,z)
+ Output from preprocessor is: x = x . y = 1 . z = 2 .
+ #define CFARGT14(F,S,M,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \
+ CFARGT14FS(F,S,M,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE)
+*/
+#define CFARGT14(F,S,M,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \
+ F(T1,1,0) F(T2,2,1) F(T3,3,1) F(T4,4,1) F(T5,5,1) F(T6,6,1) F(T7,7,1) \
+ F(T8,8,1) F(T9,9,1) F(TA,10,1) F(TB,11,1) F(TC,12,1) F(TD,13,1) F(TE,14,1) \
+ M CFARGT14S(S,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE)
+#define CFARGT27(F,S,M,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) \
+ F(T1,1,0) F(T2,2,1) F(T3,3,1) F(T4,4,1) F(T5,5,1) F(T6,6,1) F(T7,7,1) \
+ F(T8,8,1) F(T9,9,1) F(TA,10,1) F(TB,11,1) F(TC,12,1) F(TD,13,1) F(TE,14,1) \
+ F(TF,15,1) F(TG,16,1) F(TH,17,1) F(TI,18,1) F(TJ,19,1) F(TK,20,1) F(TL,21,1) \
+ F(TM,22,1) F(TN,23,1) F(TO,24,1) F(TP,25,1) F(TQ,26,1) F(TR,27,1) \
+ M CFARGT27S(S,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR)
+
+#define CFARGT20(F,S,M,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK) \
+ F(T1,1,0) F(T2,2,1) F(T3,3,1) F(T4,4,1) F(T5,5,1) F(T6,6,1) F(T7,7,1) \
+ F(T8,8,1) F(T9,9,1) F(TA,10,1) F(TB,11,1) F(TC,12,1) F(TD,13,1) F(TE,14,1) \
+ F(TF,15,1) F(TG,16,1) F(TH,17,1) F(TI,18,1) F(TJ,19,1) F(TK,20,1) \
+ S(T1,1) S(T2,2) S(T3,3) S(T4,4) S(T5,5) S(T6,6) S(T7,7) \
+ S(T8,8) S(T9,9) S(TA,10) S(TB,11) S(TC,12) S(TD,13) S(TE,14) \
+ S(TF,15) S(TG,16) S(TH,17) S(TI,18) S(TJ,19) S(TK,20)
+#define CFARGTA14(F,S,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE) \
+ F(T1,A1,1,0) F(T2,A2,2,1) F(T3,A3,3,1) F(T4,A4,4,1) F(T5,A5,5,1) F(T6,A6,6,1) \
+ F(T7,A7,7,1) F(T8,A8,8,1) F(T9,A9,9,1) F(TA,AA,10,1) F(TB,AB,11,1) F(TC,AC,12,1) \
+ F(TD,AD,13,1) F(TE,AE,14,1) S(T1,1) S(T2,2) S(T3,3) S(T4,4) \
+ S(T5,5) S(T6,6) S(T7,7) S(T8,8) S(T9,9) S(TA,10) \
+ S(TB,11) S(TC,12) S(TD,13) S(TE,14)
+#if MAX_PREPRO_ARGS>31
+#define CFARGTA20(F,S,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK) \
+ F(T1,A1,1,0) F(T2,A2,2,1) F(T3,A3,3,1) F(T4,A4,4,1) F(T5,A5,5,1) F(T6,A6,6,1) \
+ F(T7,A7,7,1) F(T8,A8,8,1) F(T9,A9,9,1) F(TA,AA,10,1) F(TB,AB,11,1) F(TC,AC,12,1) \
+ F(TD,AD,13,1) F(TE,AE,14,1) F(TF,AF,15,1) F(TG,AG,16,1) F(TH,AH,17,1) F(TI,AI,18,1) \
+ F(TJ,AJ,19,1) F(TK,AK,20,1) S(T1,1) S(T2,2) S(T3,3) S(T4,4) \
+ S(T5,5) S(T6,6) S(T7,7) S(T8,8) S(T9,9) S(TA,10) \
+ S(TB,11) S(TC,12) S(TD,13) S(TE,14) S(TF,15) S(TG,16) \
+ S(TH,17) S(TI,18) S(TJ,19) S(TK,20)
+#define CFARGTA27(F,S,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO,AP,AQ,AR) \
+ F(T1,A1,1,0) F(T2,A2,2,1) F(T3,A3,3,1) F(T4,A4,4,1) F(T5,A5,5,1) F(T6,A6,6,1) \
+ F(T7,A7,7,1) F(T8,A8,8,1) F(T9,A9,9,1) F(TA,AA,10,1) F(TB,AB,11,1) F(TC,AC,12,1) \
+ F(TD,AD,13,1) F(TE,AE,14,1) F(TF,AF,15,1) F(TG,AG,16,1) F(TH,AH,17,1) F(TI,AI,18,1) \
+ F(TJ,AJ,19,1) F(TK,AK,20,1) F(TL,AL,21,1) F(TM,AM,22,1) F(TN,AN,23,1) F(TO,AO,24,1) \
+ F(TP,AP,25,1) F(TQ,AQ,26,1) F(TR,AR,27,1) S(T1,1) S(T2,2) S(T3,3) \
+ S(T4,4) S(T5,5) S(T6,6) S(T7,7) S(T8,8) S(T9,9) \
+ S(TA,10) S(TB,11) S(TC,12) S(TD,13) S(TE,14) S(TF,15) \
+ S(TG,16) S(TH,17) S(TI,18) S(TJ,19) S(TK,20) S(TL,21) \
+ S(TM,22) S(TN,23) S(TO,24) S(TP,25) S(TQ,26) S(TR,27)
+#endif
+#else
+#define CFARGT14(F,S,M,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \
+ F(T1,1,0) S(T1,1) F(T2,2,1) S(T2,2) F(T3,3,1) S(T3,3) F(T4,4,1) S(T4,4) \
+ F(T5,5,1) S(T5,5) F(T6,6,1) S(T6,6) F(T7,7,1) S(T7,7) F(T8,8,1) S(T8,8) \
+ F(T9,9,1) S(T9,9) F(TA,10,1) S(TA,10) F(TB,11,1) S(TB,11) F(TC,12,1) S(TC,12) \
+ F(TD,13,1) S(TD,13) F(TE,14,1) S(TE,14)
+#define CFARGT27(F,S,M,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) \
+ F(T1,1,0) S(T1,1) F(T2,2,1) S(T2,2) F(T3,3,1) S(T3,3) F(T4,4,1) S(T4,4) \
+ F(T5,5,1) S(T5,5) F(T6,6,1) S(T6,6) F(T7,7,1) S(T7,7) F(T8,8,1) S(T8,8) \
+ F(T9,9,1) S(T9,9) F(TA,10,1) S(TA,10) F(TB,11,1) S(TB,11) F(TC,12,1) S(TC,12) \
+ F(TD,13,1) S(TD,13) F(TE,14,1) S(TE,14) F(TF,15,1) S(TF,15) F(TG,16,1) S(TG,16) \
+ F(TH,17,1) S(TH,17) F(TI,18,1) S(TI,18) F(TJ,19,1) S(TJ,19) F(TK,20,1) S(TK,20) \
+ F(TL,21,1) S(TL,21) F(TM,22,1) S(TM,22) F(TN,23,1) S(TN,23) F(TO,24,1) S(TO,24) \
+ F(TP,25,1) S(TP,25) F(TQ,26,1) S(TQ,26) F(TR,27,1) S(TR,27)
+
+#define CFARGT20(F,S,M,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK) \
+ F(T1,1,0) S(T1,1) F(T2,2,1) S(T2,2) F(T3,3,1) S(T3,3) F(T4,4,1) S(T4,4) \
+ F(T5,5,1) S(T5,5) F(T6,6,1) S(T6,6) F(T7,7,1) S(T7,7) F(T8,8,1) S(T8,8) \
+ F(T9,9,1) S(T9,9) F(TA,10,1) S(TA,10) F(TB,11,1) S(TB,11) F(TC,12,1) S(TC,12) \
+ F(TD,13,1) S(TD,13) F(TE,14,1) S(TE,14) F(TF,15,1) S(TF,15) F(TG,16,1) S(TG,16) \
+ F(TH,17,1) S(TH,17) F(TI,18,1) S(TI,18) F(TJ,19,1) S(TJ,19) F(TK,20,1) S(TK,20)
+#define CFARGTA14(F,S,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE) \
+ F(T1,A1,1,0) S(T1,1) F(T2,A2,2,1) S(T2,2) F(T3,A3,3,1) S(T3,3) \
+ F(T4,A4,4,1) S(T4,4) F(T5,A5,5,1) S(T5,5) F(T6,A6,6,1) S(T6,6) \
+ F(T7,A7,7,1) S(T7,7) F(T8,A8,8,1) S(T8,8) F(T9,A9,9,1) S(T9,9) \
+ F(TA,AA,10,1) S(TA,10) F(TB,AB,11,1) S(TB,11) F(TC,AC,12,1) S(TC,12) \
+ F(TD,AD,13,1) S(TD,13) F(TE,AE,14,1) S(TE,14)
+#if MAX_PREPRO_ARGS>31
+#define CFARGTA20(F,S,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK) \
+ F(T1,A1,1,0) S(T1,1) F(T2,A2,2,1) S(T2,2) F(T3,A3,3,1) S(T3,3) \
+ F(T4,A4,4,1) S(T4,4) F(T5,A5,5,1) S(T5,5) F(T6,A6,6,1) S(T6,6) \
+ F(T7,A7,7,1) S(T7,7) F(T8,A8,8,1) S(T8,8) F(T9,A9,9,1) S(T9,9) \
+ F(TA,AA,10,1) S(TA,10) F(TB,AB,11,1) S(TB,11) F(TC,AC,12,1) S(TC,12) \
+ F(TD,AD,13,1) S(TD,13) F(TE,AE,14,1) S(TE,14) F(TF,AF,15,1) S(TF,15) \
+ F(TG,AG,16,1) S(TG,16) F(TH,AH,17,1) S(TH,17) F(TI,AI,18,1) S(TI,18) \
+ F(TJ,AJ,19,1) S(TJ,19) F(TK,AK,20,1) S(TK,20)
+#define CFARGTA27(F,S,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO,AP,AQ,AR) \
+ F(T1,A1,1,0) S(T1,1) F(T2,A2,2,1) S(T2,2) F(T3,A3,3,1) S(T3,3) \
+ F(T4,A4,4,1) S(T4,4) F(T5,A5,5,1) S(T5,5) F(T6,A6,6,1) S(T6,6) \
+ F(T7,A7,7,1) S(T7,7) F(T8,A8,8,1) S(T8,8) F(T9,A9,9,1) S(T9,9) \
+ F(TA,AA,10,1) S(TA,10) F(TB,AB,11,1) S(TB,11) F(TC,AC,12,1) S(TC,12) \
+ F(TD,AD,13,1) S(TD,13) F(TE,AE,14,1) S(TE,14) F(TF,AF,15,1) S(TF,15) \
+ F(TG,AG,16,1) S(TG,16) F(TH,AH,17,1) S(TH,17) F(TI,AI,18,1) S(TI,18) \
+ F(TJ,AJ,19,1) S(TJ,19) F(TK,AK,20,1) S(TK,20) F(TL,AL,21,1) S(TL,21) \
+ F(TM,AM,22,1) S(TM,22) F(TN,AN,23,1) S(TN,23) F(TO,AO,24,1) S(TO,24) \
+ F(TP,AP,25,1) S(TP,25) F(TQ,AQ,26,1) S(TQ,26) F(TR,AR,27,1) S(TR,27)
+#endif
+#endif
+
+
+#define PROTOCCALLSFSUB1( UN,LN,T1) \
+ PROTOCCALLSFSUB14(UN,LN,T1,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFSUB2( UN,LN,T1,T2) \
+ PROTOCCALLSFSUB14(UN,LN,T1,T2,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFSUB3( UN,LN,T1,T2,T3) \
+ PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFSUB4( UN,LN,T1,T2,T3,T4) \
+ PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,T4,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFSUB5( UN,LN,T1,T2,T3,T4,T5) \
+ PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFSUB6( UN,LN,T1,T2,T3,T4,T5,T6) \
+ PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFSUB7( UN,LN,T1,T2,T3,T4,T5,T6,T7) \
+ PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFSUB8( UN,LN,T1,T2,T3,T4,T5,T6,T7,T8) \
+ PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFSUB9( UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9) \
+ PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,CF_0,CF_0,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFSUB10(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA) \
+ PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,CF_0,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFSUB11(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB) \
+ PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFSUB12(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC) \
+ PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,CF_0,CF_0)
+#define PROTOCCALLSFSUB13(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD) \
+ PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,CF_0)
+
+
+#define PROTOCCALLSFSUB15(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF) \
+ PROTOCCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,CF_0,CF_0,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFSUB16(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG) \
+ PROTOCCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,CF_0,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFSUB17(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH) \
+ PROTOCCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFSUB18(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI) \
+ PROTOCCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,CF_0,CF_0)
+#define PROTOCCALLSFSUB19(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ) \
+ PROTOCCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,CF_0)
+
+#define PROTOCCALLSFSUB21(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL) \
+ PROTOCCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFSUB22(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM) \
+ PROTOCCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,CF_0,CF_0,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFSUB23(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN) \
+ PROTOCCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,CF_0,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFSUB24(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO) \
+ PROTOCCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFSUB25(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP) \
+ PROTOCCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,CF_0,CF_0)
+#define PROTOCCALLSFSUB26(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ) \
+ PROTOCCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,CF_0)
+
+
+#ifndef FCALLSC_QUALIFIER
+#ifdef VISUAL_CPLUSPLUS
+#define FCALLSC_QUALIFIER __stdcall
+#else
+#define FCALLSC_QUALIFIER
+#endif
+#endif
+
+#ifdef __cplusplus
+#define CFextern extern "C"
+#else
+#define CFextern extern
+#endif
+
+
+#ifdef CFSUBASFUN
+#define PROTOCCALLSFSUB0(UN,LN) \
+ PROTOCCALLSFFUN0( VOID,UN,LN)
+#define PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \
+ PROTOCCALLSFFUN14(VOID,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE)
+#define PROTOCCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK)\
+ PROTOCCALLSFFUN20(VOID,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK)
+#define PROTOCCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR)\
+ PROTOCCALLSFFUN27(VOID,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR)
+#else
+/* Note: Prevent compiler warnings, null #define PROTOCCALLSFSUB14/20 after
+ #include-ing cfortran.h if calling the FORTRAN wrapper within the same
+ source code where the wrapper is created. */
+#define PROTOCCALLSFSUB0(UN,LN) _(VOID,_cfPU)(CFC_(UN,LN))();
+#ifndef __CF__KnR
+#define PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \
+ _(VOID,_cfPU)(CFC_(UN,LN))( CFARGT14(NCF,KCF,_Z,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) );
+#define PROTOCCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK)\
+ _(VOID,_cfPU)(CFC_(UN,LN))( CFARGT20(NCF,KCF,_Z,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK) );
+#define PROTOCCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR)\
+ _(VOID,_cfPU)(CFC_(UN,LN))( CFARGT27(NCF,KCF,_Z,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) );
+#else
+#define PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \
+ PROTOCCALLSFSUB0(UN,LN)
+#define PROTOCCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK) \
+ PROTOCCALLSFSUB0(UN,LN)
+#define PROTOCCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) \
+ PROTOCCALLSFSUB0(UN,LN)
+#endif
+#endif
+
+
+#ifdef OLD_VAXC /* Allow %CC-I-PARAMNOTUSED. */
+#pragma standard
+#endif
+
+
+#define CCALLSFSUB1( UN,LN,T1, A1) \
+ CCALLSFSUB5 (UN,LN,T1,CF_0,CF_0,CF_0,CF_0,A1,0,0,0,0)
+#define CCALLSFSUB2( UN,LN,T1,T2, A1,A2) \
+ CCALLSFSUB5 (UN,LN,T1,T2,CF_0,CF_0,CF_0,A1,A2,0,0,0)
+#define CCALLSFSUB3( UN,LN,T1,T2,T3, A1,A2,A3) \
+ CCALLSFSUB5 (UN,LN,T1,T2,T3,CF_0,CF_0,A1,A2,A3,0,0)
+#define CCALLSFSUB4( UN,LN,T1,T2,T3,T4, A1,A2,A3,A4)\
+ CCALLSFSUB5 (UN,LN,T1,T2,T3,T4,CF_0,A1,A2,A3,A4,0)
+#define CCALLSFSUB5( UN,LN,T1,T2,T3,T4,T5, A1,A2,A3,A4,A5) \
+ CCALLSFSUB10(UN,LN,T1,T2,T3,T4,T5,CF_0,CF_0,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,0,0,0,0,0)
+#define CCALLSFSUB6( UN,LN,T1,T2,T3,T4,T5,T6, A1,A2,A3,A4,A5,A6) \
+ CCALLSFSUB10(UN,LN,T1,T2,T3,T4,T5,T6,CF_0,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,0,0,0,0)
+#define CCALLSFSUB7( UN,LN,T1,T2,T3,T4,T5,T6,T7, A1,A2,A3,A4,A5,A6,A7) \
+ CCALLSFSUB10(UN,LN,T1,T2,T3,T4,T5,T6,T7,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,0,0,0)
+#define CCALLSFSUB8( UN,LN,T1,T2,T3,T4,T5,T6,T7,T8, A1,A2,A3,A4,A5,A6,A7,A8) \
+ CCALLSFSUB10(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,0,0)
+#define CCALLSFSUB9( UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,A1,A2,A3,A4,A5,A6,A7,A8,A9)\
+ CCALLSFSUB10(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,0)
+#define CCALLSFSUB10(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA)\
+ CCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,CF_0,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,0,0,0,0)
+#define CCALLSFSUB11(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB)\
+ CCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,0,0,0)
+#define CCALLSFSUB12(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC)\
+ CCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,0,0)
+#define CCALLSFSUB13(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD)\
+ CCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,0)
+
+#ifdef __cplusplus
+#define CPPPROTOCLSFSUB0( UN,LN)
+#define CPPPROTOCLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE)
+#define CPPPROTOCLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK)
+#define CPPPROTOCLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR)
+#else
+#define CPPPROTOCLSFSUB0(UN,LN) \
+ PROTOCCALLSFSUB0(UN,LN)
+#define CPPPROTOCLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \
+ PROTOCCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE)
+#define CPPPROTOCLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK) \
+ PROTOCCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK)
+#define CPPPROTOCLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) \
+ PROTOCCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR)
+#endif
+
+#ifdef CFSUBASFUN
+#define CCALLSFSUB0(UN,LN) CCALLSFFUN0(UN,LN)
+#define CCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE)\
+ CCALLSFFUN14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE)
+#else
+/* do{...}while(0) allows if(a==b) FORT(); else BORT(); */
+#define CCALLSFSUB0( UN,LN) do{CPPPROTOCLSFSUB0(UN,LN) CFC_(UN,LN)();}while(0)
+#define CCALLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE)\
+do{VVCF(T1,A1,B1) VVCF(T2,A2,B2) VVCF(T3,A3,B3) VVCF(T4,A4,B4) VVCF(T5,A5,B5) \
+ VVCF(T6,A6,B6) VVCF(T7,A7,B7) VVCF(T8,A8,B8) VVCF(T9,A9,B9) VVCF(TA,AA,B10) \
+ VVCF(TB,AB,B11) VVCF(TC,AC,B12) VVCF(TD,AD,B13) VVCF(TE,AE,B14) \
+ CPPPROTOCLSFSUB14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \
+ ACF(LN,T1,A1,1) ACF(LN,T2,A2,2) ACF(LN,T3,A3,3) \
+ ACF(LN,T4,A4,4) ACF(LN,T5,A5,5) ACF(LN,T6,A6,6) ACF(LN,T7,A7,7) \
+ ACF(LN,T8,A8,8) ACF(LN,T9,A9,9) ACF(LN,TA,AA,10) ACF(LN,TB,AB,11) \
+ ACF(LN,TC,AC,12) ACF(LN,TD,AD,13) ACF(LN,TE,AE,14) \
+ CFC_(UN,LN)( CFARGTA14(AACF,JCF,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE) );\
+ WCF(T1,A1,1) WCF(T2,A2,2) WCF(T3,A3,3) WCF(T4,A4,4) WCF(T5,A5,5) \
+ WCF(T6,A6,6) WCF(T7,A7,7) WCF(T8,A8,8) WCF(T9,A9,9) WCF(TA,AA,10) \
+ WCF(TB,AB,11) WCF(TC,AC,12) WCF(TD,AD,13) WCF(TE,AE,14) }while(0)
+#endif
+
+
+#if MAX_PREPRO_ARGS>31
+#define CCALLSFSUB15(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF)\
+ CCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,CF_0,CF_0,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,0,0,0,0,0)
+#define CCALLSFSUB16(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG)\
+ CCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,CF_0,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,0,0,0,0)
+#define CCALLSFSUB17(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH)\
+ CCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,0,0,0)
+#define CCALLSFSUB18(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI)\
+ CCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,0,0)
+#define CCALLSFSUB19(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ)\
+ CCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,0)
+
+#ifdef CFSUBASFUN
+#define CCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH, \
+ TI,TJ,TK, A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK) \
+ CCALLSFFUN20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH, \
+ TI,TJ,TK, A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK)
+#else
+#define CCALLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH, \
+ TI,TJ,TK, A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK) \
+do{VVCF(T1,A1,B1) VVCF(T2,A2,B2) VVCF(T3,A3,B3) VVCF(T4,A4,B4) VVCF(T5,A5,B5) \
+ VVCF(T6,A6,B6) VVCF(T7,A7,B7) VVCF(T8,A8,B8) VVCF(T9,A9,B9) VVCF(TA,AA,B10) \
+ VVCF(TB,AB,B11) VVCF(TC,AC,B12) VVCF(TD,AD,B13) VVCF(TE,AE,B14) VVCF(TF,AF,B15) \
+ VVCF(TG,AG,B16) VVCF(TH,AH,B17) VVCF(TI,AI,B18) VVCF(TJ,AJ,B19) VVCF(TK,AK,B20) \
+ CPPPROTOCLSFSUB20(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK) \
+ ACF(LN,T1,A1,1) ACF(LN,T2,A2,2) ACF(LN,T3,A3,3) ACF(LN,T4,A4,4) \
+ ACF(LN,T5,A5,5) ACF(LN,T6,A6,6) ACF(LN,T7,A7,7) ACF(LN,T8,A8,8) \
+ ACF(LN,T9,A9,9) ACF(LN,TA,AA,10) ACF(LN,TB,AB,11) ACF(LN,TC,AC,12) \
+ ACF(LN,TD,AD,13) ACF(LN,TE,AE,14) ACF(LN,TF,AF,15) ACF(LN,TG,AG,16) \
+ ACF(LN,TH,AH,17) ACF(LN,TI,AI,18) ACF(LN,TJ,AJ,19) ACF(LN,TK,AK,20) \
+ CFC_(UN,LN)( CFARGTA20(AACF,JCF,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK) ); \
+ WCF(T1,A1,1) WCF(T2,A2,2) WCF(T3,A3,3) WCF(T4,A4,4) WCF(T5,A5,5) WCF(T6,A6,6) \
+ WCF(T7,A7,7) WCF(T8,A8,8) WCF(T9,A9,9) WCF(TA,AA,10) WCF(TB,AB,11) WCF(TC,AC,12) \
+ WCF(TD,AD,13) WCF(TE,AE,14) WCF(TF,AF,15) WCF(TG,AG,16) WCF(TH,AH,17) WCF(TI,AI,18) \
+ WCF(TJ,AJ,19) WCF(TK,AK,20) }while(0)
+#endif
+#endif /* MAX_PREPRO_ARGS */
+
+#if MAX_PREPRO_ARGS>31
+#define CCALLSFSUB21(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL)\
+ CCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,CF_0,CF_0,CF_0,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,0,0,0,0,0,0)
+#define CCALLSFSUB22(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM)\
+ CCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,CF_0,CF_0,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,0,0,0,0,0)
+#define CCALLSFSUB23(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN)\
+ CCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,CF_0,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,0,0,0,0)
+#define CCALLSFSUB24(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO)\
+ CCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO,0,0,0)
+#define CCALLSFSUB25(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO,AP)\
+ CCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO,AP,0,0)
+#define CCALLSFSUB26(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO,AP,AQ)\
+ CCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO,AP,AQ,0)
+
+#ifdef CFSUBASFUN
+#define CCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR, \
+ A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO,AP,AQ,AR) \
+ CCALLSFFUN27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR, \
+ A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO,AP,AQ,AR)
+#else
+#define CCALLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR, \
+ A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO,AP,AQ,AR) \
+do{VVCF(T1,A1,B1) VVCF(T2,A2,B2) VVCF(T3,A3,B3) VVCF(T4,A4,B4) VVCF(T5,A5,B5) \
+ VVCF(T6,A6,B6) VVCF(T7,A7,B7) VVCF(T8,A8,B8) VVCF(T9,A9,B9) VVCF(TA,AA,B10) \
+ VVCF(TB,AB,B11) VVCF(TC,AC,B12) VVCF(TD,AD,B13) VVCF(TE,AE,B14) VVCF(TF,AF,B15) \
+ VVCF(TG,AG,B16) VVCF(TH,AH,B17) VVCF(TI,AI,B18) VVCF(TJ,AJ,B19) VVCF(TK,AK,B20) \
+ VVCF(TL,AL,B21) VVCF(TM,AM,B22) VVCF(TN,AN,B23) VVCF(TO,AO,B24) VVCF(TP,AP,B25) \
+ VVCF(TQ,AQ,B26) VVCF(TR,AR,B27) \
+ CPPPROTOCLSFSUB27(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR) \
+ ACF(LN,T1,A1,1) ACF(LN,T2,A2,2) ACF(LN,T3,A3,3) ACF(LN,T4,A4,4) \
+ ACF(LN,T5,A5,5) ACF(LN,T6,A6,6) ACF(LN,T7,A7,7) ACF(LN,T8,A8,8) \
+ ACF(LN,T9,A9,9) ACF(LN,TA,AA,10) ACF(LN,TB,AB,11) ACF(LN,TC,AC,12) \
+ ACF(LN,TD,AD,13) ACF(LN,TE,AE,14) ACF(LN,TF,AF,15) ACF(LN,TG,AG,16) \
+ ACF(LN,TH,AH,17) ACF(LN,TI,AI,18) ACF(LN,TJ,AJ,19) ACF(LN,TK,AK,20) \
+ ACF(LN,TL,AL,21) ACF(LN,TM,AM,22) ACF(LN,TN,AN,23) ACF(LN,TO,AO,24) \
+ ACF(LN,TP,AP,25) ACF(LN,TQ,AQ,26) ACF(LN,TR,AR,27) \
+ CFC_(UN,LN)( CFARGTA27(AACF,JCF,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,TF,TG,TH,TI,TJ,TK,TL,TM,TN,TO,TP,TQ,TR,\
+ A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,AN,AO,AP,AQ,AR) ); \
+ WCF(T1,A1,1) WCF(T2,A2,2) WCF(T3,A3,3) WCF(T4,A4,4) WCF(T5,A5,5) WCF(T6,A6,6) \
+ WCF(T7,A7,7) WCF(T8,A8,8) WCF(T9,A9,9) WCF(TA,AA,10) WCF(TB,AB,11) WCF(TC,AC,12) \
+ WCF(TD,AD,13) WCF(TE,AE,14) WCF(TF,AF,15) WCF(TG,AG,16) WCF(TH,AH,17) WCF(TI,AI,18) \
+ WCF(TJ,AJ,19) WCF(TK,AK,20) WCF(TL,AL,21) WCF(TM,AM,22) WCF(TN,AN,23) WCF(TO,AO,24) \
+ WCF(TP,AP,25) WCF(TQ,AQ,26) WCF(TR,AR,27) }while(0)
+#endif
+#endif /* MAX_PREPRO_ARGS */
+
+/*-------------------------------------------------------------------------*/
+
+/* UTILITIES FOR C TO CALL FORTRAN FUNCTIONS */
+
+/*N.B. PROTOCCALLSFFUNn(..) generates code, whether or not the FORTRAN
+ function is called. Therefore, especially for creator's of C header files
+ for large FORTRAN libraries which include many functions, to reduce
+ compile time and object code size, it may be desirable to create
+ preprocessor directives to allow users to create code for only those
+ functions which they use. */
+
+/* The following defines the maximum length string that a function can return.
+ Of course it may be undefine-d and re-define-d before individual
+ PROTOCCALLSFFUNn(..) as required. It would also be nice to have this derived
+ from the individual machines' limits. */
+#define MAX_LEN_FORTRAN_FUNCTION_STRING 0x4FE
+
+/* The following defines a character used by CFORTRAN.H to flag the end of a
+ string coming out of a FORTRAN routine. */
+#define CFORTRAN_NON_CHAR 0x7F
+
+#ifdef OLD_VAXC /* Prevent %CC-I-PARAMNOTUSED. */
+#pragma nostandard
+#endif
+
+#define _SEP_(TN,C,cfCOMMA) _(__SEP_,C)(TN,cfCOMMA)
+#define __SEP_0(TN,cfCOMMA)
+#define __SEP_1(TN,cfCOMMA) _Icf(2,SEP,TN,cfCOMMA,0)
+#define INT_cfSEP(T,B) _(A,B)
+#define INTV_cfSEP(T,B) INT_cfSEP(T,B)
+#define INTVV_cfSEP(T,B) INT_cfSEP(T,B)
+#define INTVVV_cfSEP(T,B) INT_cfSEP(T,B)
+#define INTVVVV_cfSEP(T,B) INT_cfSEP(T,B)
+#define INTVVVVV_cfSEP(T,B) INT_cfSEP(T,B)
+#define INTVVVVVV_cfSEP(T,B) INT_cfSEP(T,B)
+#define INTVVVVVVV_cfSEP(T,B) INT_cfSEP(T,B)
+#define PINT_cfSEP(T,B) INT_cfSEP(T,B)
+#define PVOID_cfSEP(T,B) INT_cfSEP(T,B)
+#define ROUTINE_cfSEP(T,B) INT_cfSEP(T,B)
+#define SIMPLE_cfSEP(T,B) INT_cfSEP(T,B)
+#define VOID_cfSEP(T,B) INT_cfSEP(T,B) /* For FORTRAN calls C subr.s.*/
+#define STRING_cfSEP(T,B) INT_cfSEP(T,B)
+#define STRINGV_cfSEP(T,B) INT_cfSEP(T,B)
+#define PSTRING_cfSEP(T,B) INT_cfSEP(T,B)
+#define PSTRINGV_cfSEP(T,B) INT_cfSEP(T,B)
+#define PNSTRING_cfSEP(T,B) INT_cfSEP(T,B)
+#define PPSTRING_cfSEP(T,B) INT_cfSEP(T,B)
+#define ZTRINGV_cfSEP(T,B) INT_cfSEP(T,B)
+#define PZTRINGV_cfSEP(T,B) INT_cfSEP(T,B)
+
+#if defined(SIGNED_BYTE) || !defined(UNSIGNED_BYTE)
+#ifdef OLD_VAXC
+#define INTEGER_BYTE char /* Old VAXC barfs on 'signed char' */
+#else
+#define INTEGER_BYTE signed char /* default */
+#endif
+#else
+#define INTEGER_BYTE unsigned char
+#endif
+#define BYTEVVVVVVV_cfTYPE INTEGER_BYTE
+#define DOUBLEVVVVVVV_cfTYPE DOUBLE_PRECISION
+#define FLOATVVVVVVV_cfTYPE FORTRAN_REAL
+#define INTVVVVVVV_cfTYPE int
+#define LOGICALVVVVVVV_cfTYPE int
+#define LONGVVVVVVV_cfTYPE long
+#define LONGLONGVVVVVVV_cfTYPE LONGLONG /* added by MR December 2005 */
+#define SHORTVVVVVVV_cfTYPE short
+#define PBYTE_cfTYPE INTEGER_BYTE
+#define PDOUBLE_cfTYPE DOUBLE_PRECISION
+#define PFLOAT_cfTYPE FORTRAN_REAL
+#define PINT_cfTYPE int
+#define PLOGICAL_cfTYPE int
+#define PLONG_cfTYPE long
+#define PLONGLONG_cfTYPE LONGLONG /* added by MR December 2005 */
+#define PSHORT_cfTYPE short
+
+#define CFARGS0(A,T,V,W,X,Y,Z) _3(T,_cf,A)
+#define CFARGS1(A,T,V,W,X,Y,Z) _3(T,_cf,A)(V)
+#define CFARGS2(A,T,V,W,X,Y,Z) _3(T,_cf,A)(V,W)
+#define CFARGS3(A,T,V,W,X,Y,Z) _3(T,_cf,A)(V,W,X)
+#define CFARGS4(A,T,V,W,X,Y,Z) _3(T,_cf,A)(V,W,X,Y)
+#define CFARGS5(A,T,V,W,X,Y,Z) _3(T,_cf,A)(V,W,X,Y,Z)
+
+#define _Icf(N,T,I,X,Y) _(I,_cfINT)(N,T,I,X,Y,0)
+#define _Icf4(N,T,I,X,Y,Z) _(I,_cfINT)(N,T,I,X,Y,Z)
+#define BYTE_cfINT(N,A,B,X,Y,Z) DOUBLE_cfINT(N,A,B,X,Y,Z)
+#define DOUBLE_cfINT(N,A,B,X,Y,Z) _(CFARGS,N)(A,INT,B,X,Y,Z,0)
+#define FLOAT_cfINT(N,A,B,X,Y,Z) DOUBLE_cfINT(N,A,B,X,Y,Z)
+#define INT_cfINT(N,A,B,X,Y,Z) DOUBLE_cfINT(N,A,B,X,Y,Z)
+#define LOGICAL_cfINT(N,A,B,X,Y,Z) DOUBLE_cfINT(N,A,B,X,Y,Z)
+#define LONG_cfINT(N,A,B,X,Y,Z) DOUBLE_cfINT(N,A,B,X,Y,Z)
+#define LONGLONG_cfINT(N,A,B,X,Y,Z) DOUBLE_cfINT(N,A,B,X,Y,Z) /* added by MR December 2005 */
+#define SHORT_cfINT(N,A,B,X,Y,Z) DOUBLE_cfINT(N,A,B,X,Y,Z)
+#define PBYTE_cfINT(N,A,B,X,Y,Z) PDOUBLE_cfINT(N,A,B,X,Y,Z)
+#define PDOUBLE_cfINT(N,A,B,X,Y,Z) _(CFARGS,N)(A,PINT,B,X,Y,Z,0)
+#define PFLOAT_cfINT(N,A,B,X,Y,Z) PDOUBLE_cfINT(N,A,B,X,Y,Z)
+#define PINT_cfINT(N,A,B,X,Y,Z) PDOUBLE_cfINT(N,A,B,X,Y,Z)
+#define PLOGICAL_cfINT(N,A,B,X,Y,Z) PDOUBLE_cfINT(N,A,B,X,Y,Z)
+#define PLONG_cfINT(N,A,B,X,Y,Z) PDOUBLE_cfINT(N,A,B,X,Y,Z)
+#define PLONGLONG_cfINT(N,A,B,X,Y,Z) PDOUBLE_cfINT(N,A,B,X,Y,Z) /* added by MR December 2005 */
+#define PSHORT_cfINT(N,A,B,X,Y,Z) PDOUBLE_cfINT(N,A,B,X,Y,Z)
+#define BYTEV_cfINT(N,A,B,X,Y,Z) DOUBLEV_cfINT(N,A,B,X,Y,Z)
+#define BYTEVV_cfINT(N,A,B,X,Y,Z) DOUBLEVV_cfINT(N,A,B,X,Y,Z)
+#define BYTEVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVV_cfINT(N,A,B,X,Y,Z)
+#define BYTEVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVV_cfINT(N,A,B,X,Y,Z)
+#define BYTEVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVV_cfINT(N,A,B,X,Y,Z)
+#define BYTEVVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVVV_cfINT(N,A,B,X,Y,Z)
+#define BYTEVVVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVVVV_cfINT(N,A,B,X,Y,Z)
+#define DOUBLEV_cfINT(N,A,B,X,Y,Z) _(CFARGS,N)(A,INTV,B,X,Y,Z,0)
+#define DOUBLEVV_cfINT(N,A,B,X,Y,Z) _(CFARGS,N)(A,INTVV,B,X,Y,Z,0)
+#define DOUBLEVVV_cfINT(N,A,B,X,Y,Z) _(CFARGS,N)(A,INTVVV,B,X,Y,Z,0)
+#define DOUBLEVVVV_cfINT(N,A,B,X,Y,Z) _(CFARGS,N)(A,INTVVVV,B,X,Y,Z,0)
+#define DOUBLEVVVVV_cfINT(N,A,B,X,Y,Z) _(CFARGS,N)(A,INTVVVVV,B,X,Y,Z,0)
+#define DOUBLEVVVVVV_cfINT(N,A,B,X,Y,Z) _(CFARGS,N)(A,INTVVVVVV,B,X,Y,Z,0)
+#define DOUBLEVVVVVVV_cfINT(N,A,B,X,Y,Z) _(CFARGS,N)(A,INTVVVVVVV,B,X,Y,Z,0)
+#define FLOATV_cfINT(N,A,B,X,Y,Z) DOUBLEV_cfINT(N,A,B,X,Y,Z)
+#define FLOATVV_cfINT(N,A,B,X,Y,Z) DOUBLEVV_cfINT(N,A,B,X,Y,Z)
+#define FLOATVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVV_cfINT(N,A,B,X,Y,Z)
+#define FLOATVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVV_cfINT(N,A,B,X,Y,Z)
+#define FLOATVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVV_cfINT(N,A,B,X,Y,Z)
+#define FLOATVVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVVV_cfINT(N,A,B,X,Y,Z)
+#define FLOATVVVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVVVV_cfINT(N,A,B,X,Y,Z)
+#define INTV_cfINT(N,A,B,X,Y,Z) DOUBLEV_cfINT(N,A,B,X,Y,Z)
+#define INTVV_cfINT(N,A,B,X,Y,Z) DOUBLEVV_cfINT(N,A,B,X,Y,Z)
+#define INTVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVV_cfINT(N,A,B,X,Y,Z)
+#define INTVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVV_cfINT(N,A,B,X,Y,Z)
+#define INTVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVV_cfINT(N,A,B,X,Y,Z)
+#define INTVVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVVV_cfINT(N,A,B,X,Y,Z)
+#define INTVVVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVVVV_cfINT(N,A,B,X,Y,Z)
+#define LOGICALV_cfINT(N,A,B,X,Y,Z) DOUBLEV_cfINT(N,A,B,X,Y,Z)
+#define LOGICALVV_cfINT(N,A,B,X,Y,Z) DOUBLEVV_cfINT(N,A,B,X,Y,Z)
+#define LOGICALVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVV_cfINT(N,A,B,X,Y,Z)
+#define LOGICALVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVV_cfINT(N,A,B,X,Y,Z)
+#define LOGICALVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVV_cfINT(N,A,B,X,Y,Z)
+#define LOGICALVVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVVV_cfINT(N,A,B,X,Y,Z)
+#define LOGICALVVVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVVVV_cfINT(N,A,B,X,Y,Z)
+#define LONGV_cfINT(N,A,B,X,Y,Z) DOUBLEV_cfINT(N,A,B,X,Y,Z)
+#define LONGVV_cfINT(N,A,B,X,Y,Z) DOUBLEVV_cfINT(N,A,B,X,Y,Z)
+#define LONGVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVV_cfINT(N,A,B,X,Y,Z)
+#define LONGVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVV_cfINT(N,A,B,X,Y,Z)
+#define LONGVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVV_cfINT(N,A,B,X,Y,Z)
+#define LONGVVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVVV_cfINT(N,A,B,X,Y,Z)
+#define LONGVVVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVVVV_cfINT(N,A,B,X,Y,Z)
+#define LONGLONGV_cfINT(N,A,B,X,Y,Z) DOUBLEV_cfINT(N,A,B,X,Y,Z) /* added by MR December 2005 */
+#define LONGLONGVV_cfINT(N,A,B,X,Y,Z) DOUBLEVV_cfINT(N,A,B,X,Y,Z) /* added by MR December 2005 */
+#define LONGLONGVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVV_cfINT(N,A,B,X,Y,Z) /* added by MR December 2005 */
+#define LONGLONGVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVV_cfINT(N,A,B,X,Y,Z) /* added by MR December 2005 */
+#define LONGLONGVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVV_cfINT(N,A,B,X,Y,Z) /* added by MR December 2005 */
+#define LONGLONGVVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVVV_cfINT(N,A,B,X,Y,Z) /* added by MR December 2005 */
+#define LONGLONGVVVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVVVV_cfINT(N,A,B,X,Y,Z) /* added by MR December 2005 */
+#define SHORTV_cfINT(N,A,B,X,Y,Z) DOUBLEV_cfINT(N,A,B,X,Y,Z)
+#define SHORTVV_cfINT(N,A,B,X,Y,Z) DOUBLEVV_cfINT(N,A,B,X,Y,Z)
+#define SHORTVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVV_cfINT(N,A,B,X,Y,Z)
+#define SHORTVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVV_cfINT(N,A,B,X,Y,Z)
+#define SHORTVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVV_cfINT(N,A,B,X,Y,Z)
+#define SHORTVVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVVV_cfINT(N,A,B,X,Y,Z)
+#define SHORTVVVVVVV_cfINT(N,A,B,X,Y,Z) DOUBLEVVVVVVV_cfINT(N,A,B,X,Y,Z)
+#define PVOID_cfINT(N,A,B,X,Y,Z) _(CFARGS,N)(A,B,B,X,Y,Z,0)
+#define ROUTINE_cfINT(N,A,B,X,Y,Z) PVOID_cfINT(N,A,B,X,Y,Z)
+/*CRAY coughs on the first,
+ i.e. the usual trouble of not being able to
+ define macros to macros with arguments.
+ New ultrix is worse, it coughs on all such uses.
+ */
+/*#define SIMPLE_cfINT PVOID_cfINT*/
+#define SIMPLE_cfINT(N,A,B,X,Y,Z) PVOID_cfINT(N,A,B,X,Y,Z)
+#define VOID_cfINT(N,A,B,X,Y,Z) PVOID_cfINT(N,A,B,X,Y,Z)
+#define STRING_cfINT(N,A,B,X,Y,Z) PVOID_cfINT(N,A,B,X,Y,Z)
+#define STRINGV_cfINT(N,A,B,X,Y,Z) PVOID_cfINT(N,A,B,X,Y,Z)
+#define PSTRING_cfINT(N,A,B,X,Y,Z) PVOID_cfINT(N,A,B,X,Y,Z)
+#define PSTRINGV_cfINT(N,A,B,X,Y,Z) PVOID_cfINT(N,A,B,X,Y,Z)
+#define PNSTRING_cfINT(N,A,B,X,Y,Z) PVOID_cfINT(N,A,B,X,Y,Z)
+#define PPSTRING_cfINT(N,A,B,X,Y,Z) PVOID_cfINT(N,A,B,X,Y,Z)
+#define ZTRINGV_cfINT(N,A,B,X,Y,Z) PVOID_cfINT(N,A,B,X,Y,Z)
+#define PZTRINGV_cfINT(N,A,B,X,Y,Z) PVOID_cfINT(N,A,B,X,Y,Z)
+#define CF_0_cfINT(N,A,B,X,Y,Z)
+
+
+#define UCF(TN,I,C) _SEP_(TN,C,cfCOMMA) _Icf(2,U,TN,_(A,I),0)
+#define UUCF(TN,I,C) _SEP_(TN,C,cfCOMMA) _SEP_(TN,1,I)
+#define UUUCF(TN,I,C) _SEP_(TN,C,cfCOLON) _Icf(2,U,TN,_(A,I),0)
+#define INT_cfU(T,A) _(T,VVVVVVV_cfTYPE) A
+#define INTV_cfU(T,A) _(T,VVVVVV_cfTYPE) * A
+#define INTVV_cfU(T,A) _(T,VVVVV_cfTYPE) * A
+#define INTVVV_cfU(T,A) _(T,VVVV_cfTYPE) * A
+#define INTVVVV_cfU(T,A) _(T,VVV_cfTYPE) * A
+#define INTVVVVV_cfU(T,A) _(T,VV_cfTYPE) * A
+#define INTVVVVVV_cfU(T,A) _(T,V_cfTYPE) * A
+#define INTVVVVVVV_cfU(T,A) _(T,_cfTYPE) * A
+#define PINT_cfU(T,A) _(T,_cfTYPE) * A
+#define PVOID_cfU(T,A) void *A
+#define ROUTINE_cfU(T,A) void (*A)(CF_NULL_PROTO)
+#define VOID_cfU(T,A) void A /* Needed for C calls FORTRAN sub.s. */
+#define STRING_cfU(T,A) char *A /* via VOID and wrapper. */
+#define STRINGV_cfU(T,A) char *A
+#define PSTRING_cfU(T,A) char *A
+#define PSTRINGV_cfU(T,A) char *A
+#define ZTRINGV_cfU(T,A) char *A
+#define PZTRINGV_cfU(T,A) char *A
+
+/* VOID breaks U into U and UU. */
+#define INT_cfUU(T,A) _(T,VVVVVVV_cfTYPE) A
+#define VOID_cfUU(T,A) /* Needed for FORTRAN calls C sub.s. */
+#define STRING_cfUU(T,A) char *A
+
+
+#define BYTE_cfPU(A) CFextern INTEGER_BYTE FCALLSC_QUALIFIER A
+#define DOUBLE_cfPU(A) CFextern DOUBLE_PRECISION FCALLSC_QUALIFIER A
+#if ! (defined(FLOATFUNCTIONTYPE)&&defined(ASSIGNFLOAT)&&defined(RETURNFLOAT))
+#if defined (f2cFortran) && ! defined (gFortran)
+/* f2c/g77 return double from FORTRAN REAL functions. (KMCCARTY, 2005/12/09) */
+#define FLOAT_cfPU(A) CFextern DOUBLE_PRECISION FCALLSC_QUALIFIER A
+#else
+#define FLOAT_cfPU(A) CFextern FORTRAN_REAL FCALLSC_QUALIFIER A
+#endif
+#else
+#define FLOAT_cfPU(A) CFextern FLOATFUNCTIONTYPE FCALLSC_QUALIFIER A
+#endif
+#define INT_cfPU(A) CFextern int FCALLSC_QUALIFIER A
+#define LOGICAL_cfPU(A) CFextern int FCALLSC_QUALIFIER A
+#define LONG_cfPU(A) CFextern long FCALLSC_QUALIFIER A
+#define SHORT_cfPU(A) CFextern short FCALLSC_QUALIFIER A
+#define STRING_cfPU(A) CFextern void FCALLSC_QUALIFIER A
+#define VOID_cfPU(A) CFextern void FCALLSC_QUALIFIER A
+
+#define BYTE_cfE INTEGER_BYTE A0;
+#define DOUBLE_cfE DOUBLE_PRECISION A0;
+#if ! (defined(FLOATFUNCTIONTYPE)&&defined(ASSIGNFLOAT)&&defined(RETURNFLOAT))
+#define FLOAT_cfE FORTRAN_REAL A0;
+#else
+#define FLOAT_cfE FORTRAN_REAL AA0; FLOATFUNCTIONTYPE A0;
+#endif
+#define INT_cfE int A0;
+#define LOGICAL_cfE int A0;
+#define LONG_cfE long A0;
+#define SHORT_cfE short A0;
+#define VOID_cfE
+#ifdef vmsFortran
+#define STRING_cfE static char AA0[1+MAX_LEN_FORTRAN_FUNCTION_STRING]; \
+ static fstring A0 = \
+ {MAX_LEN_FORTRAN_FUNCTION_STRING,DSC$K_DTYPE_T,DSC$K_CLASS_S,AA0};\
+ memset(AA0, CFORTRAN_NON_CHAR, MAX_LEN_FORTRAN_FUNCTION_STRING);\
+ *(AA0+MAX_LEN_FORTRAN_FUNCTION_STRING)='\0';
+#else
+#ifdef CRAYFortran
+#define STRING_cfE static char AA0[1+MAX_LEN_FORTRAN_FUNCTION_STRING]; \
+ static _fcd A0; *(AA0+MAX_LEN_FORTRAN_FUNCTION_STRING)='\0';\
+ memset(AA0,CFORTRAN_NON_CHAR, MAX_LEN_FORTRAN_FUNCTION_STRING);\
+ A0 = _cptofcd(AA0,MAX_LEN_FORTRAN_FUNCTION_STRING);
+#else
+/* 'cc: SC3.0.1 13 Jul 1994' barfs on char A0[0x4FE+1];
+ * char A0[0x4FE +1]; char A0[1+0x4FE]; are both OK. */
+#define STRING_cfE static char A0[1+MAX_LEN_FORTRAN_FUNCTION_STRING]; \
+ memset(A0, CFORTRAN_NON_CHAR, \
+ MAX_LEN_FORTRAN_FUNCTION_STRING); \
+ *(A0+MAX_LEN_FORTRAN_FUNCTION_STRING)='\0';
+#endif
+#endif
+/* ESTRING must use static char. array which is guaranteed to exist after
+ function returns. */
+
+/* N.B.i) The diff. for 0 (Zero) and >=1 arguments.
+ ii)That the following create an unmatched bracket, i.e. '(', which
+ must of course be matched in the call.
+ iii)Commas must be handled very carefully */
+#define INT_cfGZ(T,UN,LN) A0=CFC_(UN,LN)(
+#define VOID_cfGZ(T,UN,LN) CFC_(UN,LN)(
+#ifdef vmsFortran
+#define STRING_cfGZ(T,UN,LN) CFC_(UN,LN)(&A0
+#else
+#if defined(CRAYFortran) || defined(AbsoftUNIXFortran) || defined(AbsoftProFortran)
+#define STRING_cfGZ(T,UN,LN) CFC_(UN,LN)( A0
+#else
+#define STRING_cfGZ(T,UN,LN) CFC_(UN,LN)( A0,MAX_LEN_FORTRAN_FUNCTION_STRING
+#endif
+#endif
+
+#define INT_cfG(T,UN,LN) INT_cfGZ(T,UN,LN)
+#define VOID_cfG(T,UN,LN) VOID_cfGZ(T,UN,LN)
+#define STRING_cfG(T,UN,LN) STRING_cfGZ(T,UN,LN), /*, is only diff. from _cfG*/
+
+#define BYTEVVVVVVV_cfPP
+#define INTVVVVVVV_cfPP /* These complement FLOATVVVVVVV_cfPP. */
+#define DOUBLEVVVVVVV_cfPP
+#define LOGICALVVVVVVV_cfPP
+#define LONGVVVVVVV_cfPP
+#define SHORTVVVVVVV_cfPP
+#define PBYTE_cfPP
+#define PINT_cfPP
+#define PDOUBLE_cfPP
+#define PLOGICAL_cfPP
+#define PLONG_cfPP
+#define PSHORT_cfPP
+#define PFLOAT_cfPP FLOATVVVVVVV_cfPP
+
+#define BCF(TN,AN,C) _SEP_(TN,C,cfCOMMA) _Icf(2,B,TN,AN,0)
+#define INT_cfB(T,A) (_(T,VVVVVVV_cfTYPE)) A
+#define INTV_cfB(T,A) A
+#define INTVV_cfB(T,A) (A)[0]
+#define INTVVV_cfB(T,A) (A)[0][0]
+#define INTVVVV_cfB(T,A) (A)[0][0][0]
+#define INTVVVVV_cfB(T,A) (A)[0][0][0][0]
+#define INTVVVVVV_cfB(T,A) (A)[0][0][0][0][0]
+#define INTVVVVVVV_cfB(T,A) (A)[0][0][0][0][0][0]
+#define PINT_cfB(T,A) _(T,_cfPP)&A
+#define STRING_cfB(T,A) (char *) A
+#define STRINGV_cfB(T,A) (char *) A
+#define PSTRING_cfB(T,A) (char *) A
+#define PSTRINGV_cfB(T,A) (char *) A
+#define PVOID_cfB(T,A) (void *) A
+#define ROUTINE_cfB(T,A) (cfCAST_FUNCTION)A
+#define ZTRINGV_cfB(T,A) (char *) A
+#define PZTRINGV_cfB(T,A) (char *) A
+
+#define SCF(TN,NAME,I,A) _(TN,_cfSTR)(3,S,NAME,I,A,0,0)
+#define DEFAULT_cfS(M,I,A)
+#define LOGICAL_cfS(M,I,A)
+#define PLOGICAL_cfS(M,I,A)
+#define STRING_cfS(M,I,A) ,sizeof(A)
+#define STRINGV_cfS(M,I,A) ,( (unsigned)0xFFFF*firstindexlength(A) \
+ +secondindexlength(A))
+#define PSTRING_cfS(M,I,A) ,sizeof(A)
+#define PSTRINGV_cfS(M,I,A) STRINGV_cfS(M,I,A)
+#define ZTRINGV_cfS(M,I,A)
+#define PZTRINGV_cfS(M,I,A)
+
+#define HCF(TN,I) _(TN,_cfSTR)(3,H,cfCOMMA, H,_(C,I),0,0)
+#define HHCF(TN,I) _(TN,_cfSTR)(3,H,cfCOMMA,HH,_(C,I),0,0)
+#define HHHCF(TN,I) _(TN,_cfSTR)(3,H,cfCOLON, H,_(C,I),0,0)
+#define H_CF_SPECIAL unsigned
+#define HH_CF_SPECIAL
+#define DEFAULT_cfH(M,I,A)
+#define LOGICAL_cfH(S,U,B)
+#define PLOGICAL_cfH(S,U,B)
+#define STRING_cfH(S,U,B) _(A,S) _(U,_CF_SPECIAL) B
+#define STRINGV_cfH(S,U,B) STRING_cfH(S,U,B)
+#define PSTRING_cfH(S,U,B) STRING_cfH(S,U,B)
+#define PSTRINGV_cfH(S,U,B) STRING_cfH(S,U,B)
+#define PNSTRING_cfH(S,U,B) STRING_cfH(S,U,B)
+#define PPSTRING_cfH(S,U,B) STRING_cfH(S,U,B)
+#define ZTRINGV_cfH(S,U,B)
+#define PZTRINGV_cfH(S,U,B)
+
+/* Need VOID_cfSTR because Absoft forced function types go through _cfSTR. */
+/* No spaces inside expansion. They screws up macro catenation kludge. */
+#define VOID_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define BYTE_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define DOUBLE_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define FLOAT_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define INT_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define LOGICAL_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,LOGICAL,A,B,C,D,E)
+#define LONG_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define LONGLONG_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) /* added by MR December 2005 */
+#define SHORT_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define BYTEV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define BYTEVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define BYTEVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define BYTEVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define BYTEVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define BYTEVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define BYTEVVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define DOUBLEV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define DOUBLEVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define DOUBLEVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define DOUBLEVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define DOUBLEVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define DOUBLEVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define DOUBLEVVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define FLOATV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define FLOATVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define FLOATVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define FLOATVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define FLOATVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define FLOATVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define FLOATVVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define INTV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define INTVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define INTVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define INTVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define INTVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define INTVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define INTVVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define LOGICALV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define LOGICALVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define LOGICALVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define LOGICALVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define LOGICALVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define LOGICALVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define LOGICALVVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define LONGV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define LONGVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define LONGVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define LONGVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define LONGVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define LONGVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define LONGVVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define LONGLONGV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) /* added by MR December 2005 */
+#define LONGLONGVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) /* added by MR December 2005 */
+#define LONGLONGVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) /* added by MR December 2005 */
+#define LONGLONGVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) /* added by MR December 2005 */
+#define LONGLONGVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) /* added by MR December 2005 */
+#define LONGLONGVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) /* added by MR December 2005 */
+#define LONGLONGVVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) /* added by MR December 2005 */
+#define SHORTV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define SHORTVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define SHORTVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define SHORTVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define SHORTVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define SHORTVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define SHORTVVVVVVV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define PBYTE_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define PDOUBLE_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define PFLOAT_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define PINT_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define PLOGICAL_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,PLOGICAL,A,B,C,D,E)
+#define PLONG_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define PLONGLONG_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E) /* added by MR December 2005 */
+#define PSHORT_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define STRING_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,STRING,A,B,C,D,E)
+#define PSTRING_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,PSTRING,A,B,C,D,E)
+#define STRINGV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,STRINGV,A,B,C,D,E)
+#define PSTRINGV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,PSTRINGV,A,B,C,D,E)
+#define PNSTRING_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,PNSTRING,A,B,C,D,E)
+#define PPSTRING_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,PPSTRING,A,B,C,D,E)
+#define PVOID_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define ROUTINE_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define SIMPLE_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,DEFAULT,A,B,C,D,E)
+#define ZTRINGV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,ZTRINGV,A,B,C,D,E)
+#define PZTRINGV_cfSTR(N,T,A,B,C,D,E) _(CFARGS,N)(T,PZTRINGV,A,B,C,D,E)
+#define CF_0_cfSTR(N,T,A,B,C,D,E)
+
+/* See ACF table comments, which explain why CCF was split into two. */
+#define CCF(NAME,TN,I) _(TN,_cfSTR)(5,C,NAME,I,_(A,I),_(B,I),_(C,I))
+#define DEFAULT_cfC(M,I,A,B,C)
+#define LOGICAL_cfC(M,I,A,B,C) A=C2FLOGICAL( A);
+#define PLOGICAL_cfC(M,I,A,B,C) *A=C2FLOGICAL(*A);
+#ifdef vmsFortran
+#define STRING_cfC(M,I,A,B,C) (B.clen=strlen(A),B.f.dsc$a_pointer=A, \
+ C==sizeof(char*)||C==(unsigned)(B.clen+1)?B.f.dsc$w_length=B.clen: \
+ (memset((A)+B.clen,' ',C-B.clen-1),A[B.f.dsc$w_length=C-1]='\0'));
+ /* PSTRING_cfC to beware of array A which does not contain any \0. */
+#define PSTRING_cfC(M,I,A,B,C) (B.dsc$a_pointer=A, C==sizeof(char*) ? \
+ B.dsc$w_length=strlen(A): (A[C-1]='\0',B.dsc$w_length=strlen(A), \
+ memset((A)+B.dsc$w_length,' ',C-B.dsc$w_length-1), B.dsc$w_length=C-1));
+#else
+#define STRING_cfC(M,I,A,B,C) (B.nombre=A,B.clen=strlen(A), \
+ C==sizeof(char*)||C==(unsigned)(B.clen+1)?B.flen=B.clen: \
+ (memset(B.nombre+B.clen,' ',C-B.clen-1),B.nombre[B.flen=C-1]='\0'));
+#define PSTRING_cfC(M,I,A,B,C) (C==sizeof(char*)? B=strlen(A): \
+ (A[C-1]='\0',B=strlen(A),memset((A)+B,' ',C-B-1),B=C-1));
+#endif
+ /* For CRAYFortran for (P)STRINGV_cfC, B.fs is set, but irrelevant. */
+#define STRINGV_cfC(M,I,A,B,C) \
+ AATRINGV_cfA( A,B,(C/0xFFFF)*(C%0xFFFF),C/0xFFFF,C%0xFFFF)
+#define PSTRINGV_cfC(M,I,A,B,C) \
+ APATRINGV_cfA( A,B,(C/0xFFFF)*(C%0xFFFF),C/0xFFFF,C%0xFFFF)
+#define ZTRINGV_cfC(M,I,A,B,C) \
+ AATRINGV_cfA( A,B, (_3(M,_ELEMS_,I))*((_3(M,_ELEMLEN_,I))+1), \
+ (_3(M,_ELEMS_,I)), (_3(M,_ELEMLEN_,I))+1 )
+#define PZTRINGV_cfC(M,I,A,B,C) \
+ APATRINGV_cfA( A,B, (_3(M,_ELEMS_,I))*((_3(M,_ELEMLEN_,I))+1), \
+ (_3(M,_ELEMS_,I)), (_3(M,_ELEMLEN_,I))+1 )
+
+#define BYTE_cfCCC(A,B) &A
+#define DOUBLE_cfCCC(A,B) &A
+#if !defined(__CF__KnR)
+#define FLOAT_cfCCC(A,B) &A
+ /* Although the VAX doesn't, at least the */
+#else /* HP and K&R mips promote float arg.'s of */
+#define FLOAT_cfCCC(A,B) &B /* unprototyped functions to double. Cannot */
+#endif /* use A here to pass the argument to FORTRAN. */
+#define INT_cfCCC(A,B) &A
+#define LOGICAL_cfCCC(A,B) &A
+#define LONG_cfCCC(A,B) &A
+#define SHORT_cfCCC(A,B) &A
+#define PBYTE_cfCCC(A,B) A
+#define PDOUBLE_cfCCC(A,B) A
+#define PFLOAT_cfCCC(A,B) A
+#define PINT_cfCCC(A,B) A
+#define PLOGICAL_cfCCC(A,B) B=A /* B used to keep a common W table. */
+#define PLONG_cfCCC(A,B) A
+#define PSHORT_cfCCC(A,B) A
+
+#define CCCF(TN,I,M) _SEP_(TN,M,cfCOMMA) _Icf(3,CC,TN,_(A,I),_(B,I))
+#define INT_cfCC(T,A,B) _(T,_cfCCC)(A,B)
+#define INTV_cfCC(T,A,B) A
+#define INTVV_cfCC(T,A,B) A
+#define INTVVV_cfCC(T,A,B) A
+#define INTVVVV_cfCC(T,A,B) A
+#define INTVVVVV_cfCC(T,A,B) A
+#define INTVVVVVV_cfCC(T,A,B) A
+#define INTVVVVVVV_cfCC(T,A,B) A
+#define PINT_cfCC(T,A,B) _(T,_cfCCC)(A,B)
+#define PVOID_cfCC(T,A,B) A
+#if defined(apolloFortran) || defined(hpuxFortran800) || defined(AbsoftUNIXFortran)
+#define ROUTINE_cfCC(T,A,B) &A
+#else
+#define ROUTINE_cfCC(T,A,B) A
+#endif
+#define SIMPLE_cfCC(T,A,B) A
+#ifdef vmsFortran
+#define STRING_cfCC(T,A,B) &B.f
+#define STRINGV_cfCC(T,A,B) &B
+#define PSTRING_cfCC(T,A,B) &B
+#define PSTRINGV_cfCC(T,A,B) &B
+#else
+#ifdef CRAYFortran
+#define STRING_cfCC(T,A,B) _cptofcd(A,B.flen)
+#define STRINGV_cfCC(T,A,B) _cptofcd(B.s,B.flen)
+#define PSTRING_cfCC(T,A,B) _cptofcd(A,B)
+#define PSTRINGV_cfCC(T,A,B) _cptofcd(A,B.flen)
+#else
+#define STRING_cfCC(T,A,B) A
+#define STRINGV_cfCC(T,A,B) B.fs
+#define PSTRING_cfCC(T,A,B) A
+#define PSTRINGV_cfCC(T,A,B) B.fs
+#endif
+#endif
+#define ZTRINGV_cfCC(T,A,B) STRINGV_cfCC(T,A,B)
+#define PZTRINGV_cfCC(T,A,B) PSTRINGV_cfCC(T,A,B)
+
+#define BYTE_cfX return A0;
+#define DOUBLE_cfX return A0;
+#if ! (defined(FLOATFUNCTIONTYPE)&&defined(ASSIGNFLOAT)&&defined(RETURNFLOAT))
+#define FLOAT_cfX return A0;
+#else
+#define FLOAT_cfX ASSIGNFLOAT(AA0,A0); return AA0;
+#endif
+#define INT_cfX return A0;
+#define LOGICAL_cfX return F2CLOGICAL(A0);
+#define LONG_cfX return A0;
+#define SHORT_cfX return A0;
+#define VOID_cfX return ;
+#if defined(vmsFortran) || defined(CRAYFortran)
+#define STRING_cfX return kill_trailing( \
+ kill_trailing(AA0,CFORTRAN_NON_CHAR),' ');
+#else
+#define STRING_cfX return kill_trailing( \
+ kill_trailing( A0,CFORTRAN_NON_CHAR),' ');
+#endif
+
+#define CFFUN(NAME) _(__cf__,NAME)
+
+/* Note that we don't use LN here, but we keep it for consistency. */
+#define CCALLSFFUN0(UN,LN) CFFUN(UN)()
+
+#ifdef OLD_VAXC /* Allow %CC-I-PARAMNOTUSED. */
+#pragma standard
+#endif
+
+#define CCALLSFFUN1( UN,LN,T1, A1) \
+ CCALLSFFUN5 (UN,LN,T1,CF_0,CF_0,CF_0,CF_0,A1,0,0,0,0)
+#define CCALLSFFUN2( UN,LN,T1,T2, A1,A2) \
+ CCALLSFFUN5 (UN,LN,T1,T2,CF_0,CF_0,CF_0,A1,A2,0,0,0)
+#define CCALLSFFUN3( UN,LN,T1,T2,T3, A1,A2,A3) \
+ CCALLSFFUN5 (UN,LN,T1,T2,T3,CF_0,CF_0,A1,A2,A3,0,0)
+#define CCALLSFFUN4( UN,LN,T1,T2,T3,T4, A1,A2,A3,A4)\
+ CCALLSFFUN5 (UN,LN,T1,T2,T3,T4,CF_0,A1,A2,A3,A4,0)
+#define CCALLSFFUN5( UN,LN,T1,T2,T3,T4,T5, A1,A2,A3,A4,A5) \
+ CCALLSFFUN10(UN,LN,T1,T2,T3,T4,T5,CF_0,CF_0,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,0,0,0,0,0)
+#define CCALLSFFUN6( UN,LN,T1,T2,T3,T4,T5,T6, A1,A2,A3,A4,A5,A6) \
+ CCALLSFFUN10(UN,LN,T1,T2,T3,T4,T5,T6,CF_0,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,0,0,0,0)
+#define CCALLSFFUN7( UN,LN,T1,T2,T3,T4,T5,T6,T7, A1,A2,A3,A4,A5,A6,A7) \
+ CCALLSFFUN10(UN,LN,T1,T2,T3,T4,T5,T6,T7,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,0,0,0)
+#define CCALLSFFUN8( UN,LN,T1,T2,T3,T4,T5,T6,T7,T8, A1,A2,A3,A4,A5,A6,A7,A8) \
+ CCALLSFFUN10(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,0,0)
+#define CCALLSFFUN9( UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,A1,A2,A3,A4,A5,A6,A7,A8,A9)\
+ CCALLSFFUN10(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,0)
+#define CCALLSFFUN10(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA)\
+ CCALLSFFUN14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,CF_0,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,0,0,0,0)
+#define CCALLSFFUN11(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB)\
+ CCALLSFFUN14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,CF_0,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,0,0,0)
+#define CCALLSFFUN12(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC)\
+ CCALLSFFUN14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,CF_0,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,0,0)
+#define CCALLSFFUN13(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD)\
+ CCALLSFFUN14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,CF_0,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,0)
+
+#define CCALLSFFUN14(UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE,A1,A2,A3,A4,A5,A6,A7,A8,A9,AA,AB,AC,AD,AE)\
+((CFFUN(UN)( BCF(T1,A1,0) BCF(T2,A2,1) BCF(T3,A3,1) BCF(T4,A4,1) BCF(T5,A5,1) \
+ BCF(T6,A6,1) BCF(T7,A7,1) BCF(T8,A8,1) BCF(T9,A9,1) BCF(TA,AA,1) \
+ BCF(TB,AB,1) BCF(TC,AC,1) BCF(TD,AD,1) BCF(TE,AE,1) \
+ SCF(T1,LN,1,A1) SCF(T2,LN,2,A2) SCF(T3,LN,3,A3) SCF(T4,LN,4,A4) \
+ SCF(T5,LN,5,A5) SCF(T6,LN,6,A6) SCF(T7,LN,7,A7) SCF(T8,LN,8,A8) \
+ SCF(T9,LN,9,A9) SCF(TA,LN,10,AA) SCF(TB,LN,11,AB) SCF(TC,LN,12,AC) \
+ SCF(TD,LN,13,AD) SCF(TE,LN,14,AE))))
+
+/* N.B. Create a separate function instead of using (call function, function
+value here) because in order to create the variables needed for the input
+arg.'s which may be const.'s one has to do the creation within {}, but these
+can never be placed within ()'s. Therefore one must create wrapper functions.
+gcc, on the other hand may be able to avoid the wrapper functions. */
+
+/* Prototypes are needed to correctly handle the value returned correctly. N.B.
+Can only have prototype arg.'s with difficulty, a la G... table since FORTRAN
+functions returning strings have extra arg.'s. Don't bother, since this only
+causes a compiler warning to come up when one uses FCALLSCFUNn and CCALLSFFUNn
+for the same function in the same source code. Something done by the experts in
+debugging only.*/
+
+#define PROTOCCALLSFFUN0(F,UN,LN) \
+_(F,_cfPU)( CFC_(UN,LN))(CF_NULL_PROTO); \
+static _Icf(2,U,F,CFFUN(UN),0)() {_(F,_cfE) _Icf(3,GZ,F,UN,LN) ABSOFT_cf1(F));_(F,_cfX)}
+
+#define PROTOCCALLSFFUN1( T0,UN,LN,T1) \
+ PROTOCCALLSFFUN5 (T0,UN,LN,T1,CF_0,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFFUN2( T0,UN,LN,T1,T2) \
+ PROTOCCALLSFFUN5 (T0,UN,LN,T1,T2,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFFUN3( T0,UN,LN,T1,T2,T3) \
+ PROTOCCALLSFFUN5 (T0,UN,LN,T1,T2,T3,CF_0,CF_0)
+#define PROTOCCALLSFFUN4( T0,UN,LN,T1,T2,T3,T4) \
+ PROTOCCALLSFFUN5 (T0,UN,LN,T1,T2,T3,T4,CF_0)
+#define PROTOCCALLSFFUN5( T0,UN,LN,T1,T2,T3,T4,T5) \
+ PROTOCCALLSFFUN10(T0,UN,LN,T1,T2,T3,T4,T5,CF_0,CF_0,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFFUN6( T0,UN,LN,T1,T2,T3,T4,T5,T6) \
+ PROTOCCALLSFFUN10(T0,UN,LN,T1,T2,T3,T4,T5,T6,CF_0,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFFUN7( T0,UN,LN,T1,T2,T3,T4,T5,T6,T7) \
+ PROTOCCALLSFFUN10(T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFFUN8( T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8) \
+ PROTOCCALLSFFUN10(T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,CF_0,CF_0)
+#define PROTOCCALLSFFUN9( T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9) \
+ PROTOCCALLSFFUN10(T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,CF_0)
+#define PROTOCCALLSFFUN10(T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA) \
+ PROTOCCALLSFFUN14(T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,CF_0,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFFUN11(T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB) \
+ PROTOCCALLSFFUN14(T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,CF_0,CF_0,CF_0)
+#define PROTOCCALLSFFUN12(T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC) \
+ PROTOCCALLSFFUN14(T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,CF_0,CF_0)
+#define PROTOCCALLSFFUN13(T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD) \
+ PROTOCCALLSFFUN14(T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,CF_0)
+
+/* HP/UX 9.01 cc requires the blank between '_Icf(3,G,T0,UN,LN) CCCF(T1,1,0)' */
+
+#ifndef __CF__KnR
+#define PROTOCCALLSFFUN14(T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \
+ _(T0,_cfPU)(CFC_(UN,LN))(CF_NULL_PROTO); static _Icf(2,U,T0,CFFUN(UN),0)( \
+ CFARGT14FS(UCF,HCF,_Z,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) ) \
+{ CFARGT14S(VCF,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) _(T0,_cfE) \
+ CCF(LN,T1,1) CCF(LN,T2,2) CCF(LN,T3,3) CCF(LN,T4,4) CCF(LN,T5,5) \
+ CCF(LN,T6,6) CCF(LN,T7,7) CCF(LN,T8,8) CCF(LN,T9,9) CCF(LN,TA,10) \
+ CCF(LN,TB,11) CCF(LN,TC,12) CCF(LN,TD,13) CCF(LN,TE,14) _Icf(3,G,T0,UN,LN) \
+ CFARGT14(CCCF,JCF,ABSOFT_cf1(T0),T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE)); \
+ WCF(T1,A1,1) WCF(T2,A2,2) WCF(T3,A3,3) WCF(T4,A4,4) WCF(T5,A5,5) \
+ WCF(T6,A6,6) WCF(T7,A7,7) WCF(T8,A8,8) WCF(T9,A9,9) WCF(TA,A10,10) \
+ WCF(TB,A11,11) WCF(TC,A12,12) WCF(TD,A13,13) WCF(TE,A14,14) _(T0,_cfX)}
+#else
+#define PROTOCCALLSFFUN14(T0,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) \
+ _(T0,_cfPU)(CFC_(UN,LN))(CF_NULL_PROTO); static _Icf(2,U,T0,CFFUN(UN),0)( \
+ CFARGT14FS(UUCF,HHCF,_Z,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) ) \
+ CFARGT14FS(UUUCF,HHHCF,_Z,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) ; \
+{ CFARGT14S(VCF,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE) _(T0,_cfE) \
+ CCF(LN,T1,1) CCF(LN,T2,2) CCF(LN,T3,3) CCF(LN,T4,4) CCF(LN,T5,5) \
+ CCF(LN,T6,6) CCF(LN,T7,7) CCF(LN,T8,8) CCF(LN,T9,9) CCF(LN,TA,10) \
+ CCF(LN,TB,11) CCF(LN,TC,12) CCF(LN,TD,13) CCF(LN,TE,14) _Icf(3,G,T0,UN,LN) \
+ CFARGT14(CCCF,JCF,ABSOFT_cf1(T0),T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC,TD,TE)); \
+ WCF(T1,A1,1) WCF(T2,A2,2) WCF(T3,A3,3) WCF(T4,A4,4) WCF(T5,A5,5) \
+ WCF(T6,A6,6) WCF(T7,A7,7) WCF(T8,A8,8) WCF(T9,A9,9) WCF(TA,A10,10) \
+ WCF(TB,A11,11) WCF(TC,A12,12) WCF(TD,A13,13) WCF(TE,A14,14) _(T0,_cfX)}
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+/* UTILITIES FOR FORTRAN TO CALL C ROUTINES */
+
+#ifdef OLD_VAXC /* Prevent %CC-I-PARAMNOTUSED. */
+#pragma nostandard
+#endif
+
+#if defined(vmsFortran) || defined(CRAYFortran)
+#define DCF(TN,I)
+#define DDCF(TN,I)
+#define DDDCF(TN,I)
+#else
+#define DCF(TN,I) HCF(TN,I)
+#define DDCF(TN,I) HHCF(TN,I)
+#define DDDCF(TN,I) HHHCF(TN,I)
+#endif
+
+#define QCF(TN,I) _(TN,_cfSTR)(1,Q,_(B,I), 0,0,0,0)
+#define DEFAULT_cfQ(B)
+#define LOGICAL_cfQ(B)
+#define PLOGICAL_cfQ(B)
+#define STRINGV_cfQ(B) char *B; unsigned int _(B,N);
+#define STRING_cfQ(B) char *B=NULL;
+#define PSTRING_cfQ(B) char *B=NULL;
+#define PSTRINGV_cfQ(B) STRINGV_cfQ(B)
+#define PNSTRING_cfQ(B) char *B=NULL;
+#define PPSTRING_cfQ(B)
+
+#ifdef __sgi /* Else SGI gives warning 182 contrary to its C LRM A.17.7 */
+#define ROUTINE_orig *(void**)&
+#else
+#define ROUTINE_orig (void *)
+#endif
+
+#define ROUTINE_1 ROUTINE_orig
+#define ROUTINE_2 ROUTINE_orig
+#define ROUTINE_3 ROUTINE_orig
+#define ROUTINE_4 ROUTINE_orig
+#define ROUTINE_5 ROUTINE_orig
+#define ROUTINE_6 ROUTINE_orig
+#define ROUTINE_7 ROUTINE_orig
+#define ROUTINE_8 ROUTINE_orig
+#define ROUTINE_9 ROUTINE_orig
+#define ROUTINE_10 ROUTINE_orig
+#define ROUTINE_11 ROUTINE_orig
+#define ROUTINE_12 ROUTINE_orig
+#define ROUTINE_13 ROUTINE_orig
+#define ROUTINE_14 ROUTINE_orig
+#define ROUTINE_15 ROUTINE_orig
+#define ROUTINE_16 ROUTINE_orig
+#define ROUTINE_17 ROUTINE_orig
+#define ROUTINE_18 ROUTINE_orig
+#define ROUTINE_19 ROUTINE_orig
+#define ROUTINE_20 ROUTINE_orig
+#define ROUTINE_21 ROUTINE_orig
+#define ROUTINE_22 ROUTINE_orig
+#define ROUTINE_23 ROUTINE_orig
+#define ROUTINE_24 ROUTINE_orig
+#define ROUTINE_25 ROUTINE_orig
+#define ROUTINE_26 ROUTINE_orig
+#define ROUTINE_27 ROUTINE_orig
+
+#define TCF(NAME,TN,I,M) _SEP_(TN,M,cfCOMMA) _(TN,_cfT)(NAME,I,_(A,I),_(B,I),_(C,I))
+#define BYTE_cfT(M,I,A,B,D) *A
+#define DOUBLE_cfT(M,I,A,B,D) *A
+#define FLOAT_cfT(M,I,A,B,D) *A
+#define INT_cfT(M,I,A,B,D) *A
+#define LOGICAL_cfT(M,I,A,B,D) F2CLOGICAL(*A)
+#define LONG_cfT(M,I,A,B,D) *A
+#define LONGLONG_cfT(M,I,A,B,D) *A /* added by MR December 2005 */
+#define SHORT_cfT(M,I,A,B,D) *A
+#define BYTEV_cfT(M,I,A,B,D) A
+#define DOUBLEV_cfT(M,I,A,B,D) A
+#define FLOATV_cfT(M,I,A,B,D) VOIDP A
+#define INTV_cfT(M,I,A,B,D) A
+#define LOGICALV_cfT(M,I,A,B,D) A
+#define LONGV_cfT(M,I,A,B,D) A
+#define LONGLONGV_cfT(M,I,A,B,D) A /* added by MR December 2005 */
+#define SHORTV_cfT(M,I,A,B,D) A
+#define BYTEVV_cfT(M,I,A,B,D) (void *)A /* We have to cast to void *,*/
+#define BYTEVVV_cfT(M,I,A,B,D) (void *)A /* since we don't know the */
+#define BYTEVVVV_cfT(M,I,A,B,D) (void *)A /* dimensions of the array. */
+#define BYTEVVVVV_cfT(M,I,A,B,D) (void *)A /* i.e. Unfortunately, can't */
+#define BYTEVVVVVV_cfT(M,I,A,B,D) (void *)A /* check that the type */
+#define BYTEVVVVVVV_cfT(M,I,A,B,D) (void *)A /* matches the prototype. */
+#define DOUBLEVV_cfT(M,I,A,B,D) (void *)A
+#define DOUBLEVVV_cfT(M,I,A,B,D) (void *)A
+#define DOUBLEVVVV_cfT(M,I,A,B,D) (void *)A
+#define DOUBLEVVVVV_cfT(M,I,A,B,D) (void *)A
+#define DOUBLEVVVVVV_cfT(M,I,A,B,D) (void *)A
+#define DOUBLEVVVVVVV_cfT(M,I,A,B,D) (void *)A
+#define FLOATVV_cfT(M,I,A,B,D) (void *)A
+#define FLOATVVV_cfT(M,I,A,B,D) (void *)A
+#define FLOATVVVV_cfT(M,I,A,B,D) (void *)A
+#define FLOATVVVVV_cfT(M,I,A,B,D) (void *)A
+#define FLOATVVVVVV_cfT(M,I,A,B,D) (void *)A
+#define FLOATVVVVVVV_cfT(M,I,A,B,D) (void *)A
+#define INTVV_cfT(M,I,A,B,D) (void *)A
+#define INTVVV_cfT(M,I,A,B,D) (void *)A
+#define INTVVVV_cfT(M,I,A,B,D) (void *)A
+#define INTVVVVV_cfT(M,I,A,B,D) (void *)A
+#define INTVVVVVV_cfT(M,I,A,B,D) (void *)A
+#define INTVVVVVVV_cfT(M,I,A,B,D) (void *)A
+#define LOGICALVV_cfT(M,I,A,B,D) (void *)A
+#define LOGICALVVV_cfT(M,I,A,B,D) (void *)A
+#define LOGICALVVVV_cfT(M,I,A,B,D) (void *)A
+#define LOGICALVVVVV_cfT(M,I,A,B,D) (void *)A
+#define LOGICALVVVVVV_cfT(M,I,A,B,D) (void *)A
+#define LOGICALVVVVVVV_cfT(M,I,A,B,D) (void *)A
+#define LONGVV_cfT(M,I,A,B,D) (void *)A
+#define LONGVVV_cfT(M,I,A,B,D) (void *)A
+#define LONGVVVV_cfT(M,I,A,B,D) (void *)A
+#define LONGVVVVV_cfT(M,I,A,B,D) (void *)A
+#define LONGVVVVVV_cfT(M,I,A,B,D) (void *)A
+#define LONGVVVVVVV_cfT(M,I,A,B,D) (void *)A
+#define LONGLONGVV_cfT(M,I,A,B,D) (void *)A /* added by MR December 2005 */
+#define LONGLONGVVV_cfT(M,I,A,B,D) (void *)A /* added by MR December 2005 */
+#define LONGLONGVVVV_cfT(M,I,A,B,D) (void *)A /* added by MR December 2005 */
+#define LONGLONGVVVVV_cfT(M,I,A,B,D) (void *)A /* added by MR December 2005 */
+#define LONGLONGVVVVVV_cfT(M,I,A,B,D) (void *)A /* added by MR December 2005 */
+#define LONGLONGVVVVVVV_cfT(M,I,A,B,D) (void *)A /* added by MR December 2005 */
+#define SHORTVV_cfT(M,I,A,B,D) (void *)A
+#define SHORTVVV_cfT(M,I,A,B,D) (void *)A
+#define SHORTVVVV_cfT(M,I,A,B,D) (void *)A
+#define SHORTVVVVV_cfT(M,I,A,B,D) (void *)A
+#define SHORTVVVVVV_cfT(M,I,A,B,D) (void *)A
+#define SHORTVVVVVVV_cfT(M,I,A,B,D) (void *)A
+#define PBYTE_cfT(M,I,A,B,D) A
+#define PDOUBLE_cfT(M,I,A,B,D) A
+#define PFLOAT_cfT(M,I,A,B,D) VOIDP A
+#define PINT_cfT(M,I,A,B,D) A
+#define PLOGICAL_cfT(M,I,A,B,D) ((*A=F2CLOGICAL(*A)),A)
+#define PLONG_cfT(M,I,A,B,D) A
+#define PLONGLONG_cfT(M,I,A,B,D) A /* added by MR December 2005 */
+#define PSHORT_cfT(M,I,A,B,D) A
+#define PVOID_cfT(M,I,A,B,D) A
+#if defined(apolloFortran) || defined(hpuxFortran800) || defined(AbsoftUNIXFortran)
+#define ROUTINE_cfT(M,I,A,B,D) _(ROUTINE_,I) (*A)
+#else
+#define ROUTINE_cfT(M,I,A,B,D) _(ROUTINE_,I) A
+#endif
+/* A == pointer to the characters
+ D == length of the string, or of an element in an array of strings
+ E == number of elements in an array of strings */
+#define TTSTR( A,B,D) \
+ ((B=_cf_malloc(D+1))[D]='\0', memcpy(B,A,D), kill_trailing(B,' '))
+#define TTTTSTR( A,B,D) (!(D<4||A[0]||A[1]||A[2]||A[3]))?NULL: \
+ memchr(A,'\0',D) ?A : TTSTR(A,B,D)
+#define TTTTSTRV( A,B,D,E) (_(B,N)=E,B=_cf_malloc(_(B,N)*(D+1)), (void *) \
+ vkill_trailing(f2cstrv(A,B,D+1, _(B,N)*(D+1)), D+1,_(B,N)*(D+1),' '))
+#ifdef vmsFortran
+#define STRING_cfT(M,I,A,B,D) TTTTSTR( A->dsc$a_pointer,B,A->dsc$w_length)
+#define STRINGV_cfT(M,I,A,B,D) TTTTSTRV(A->dsc$a_pointer, B, \
+ A->dsc$w_length , A->dsc$l_m[0])
+#define PSTRING_cfT(M,I,A,B,D) TTSTR( A->dsc$a_pointer,B,A->dsc$w_length)
+#define PPSTRING_cfT(M,I,A,B,D) A->dsc$a_pointer
+#else
+#ifdef CRAYFortran
+#define STRING_cfT(M,I,A,B,D) TTTTSTR( _fcdtocp(A),B,_fcdlen(A))
+#define STRINGV_cfT(M,I,A,B,D) TTTTSTRV(_fcdtocp(A),B,_fcdlen(A), \
+ num_elem(_fcdtocp(A),_fcdlen(A),_3(M,_STRV_A,I)))
+#define PSTRING_cfT(M,I,A,B,D) TTSTR( _fcdtocp(A),B,_fcdlen(A))
+#define PPSTRING_cfT(M,I,A,B,D) _fcdtocp(A)
+#else
+#define STRING_cfT(M,I,A,B,D) TTTTSTR( A,B,D)
+#define STRINGV_cfT(M,I,A,B,D) TTTTSTRV(A,B,D, num_elem(A,D,_3(M,_STRV_A,I)))
+#define PSTRING_cfT(M,I,A,B,D) TTSTR( A,B,D)
+#define PPSTRING_cfT(M,I,A,B,D) A
+#endif
+#endif
+#define PNSTRING_cfT(M,I,A,B,D) STRING_cfT(M,I,A,B,D)
+#define PSTRINGV_cfT(M,I,A,B,D) STRINGV_cfT(M,I,A,B,D)
+#define CF_0_cfT(M,I,A,B,D)
+
+#define RCF(TN,I) _(TN,_cfSTR)(3,R,_(A,I),_(B,I),_(C,I),0,0)
+#define DEFAULT_cfR(A,B,D)
+#define LOGICAL_cfR(A,B,D)
+#define PLOGICAL_cfR(A,B,D) *A=C2FLOGICAL(*A);
+#define STRING_cfR(A,B,D) if (B) _cf_free(B);
+#define STRINGV_cfR(A,B,D) _cf_free(B);
+/* A and D as defined above for TSTRING(V) */
+#define RRRRPSTR( A,B,D) if (B) memcpy(A,B, _cfMIN(strlen(B),D)), \
+ (D>strlen(B)?memset(A+strlen(B),' ', D-strlen(B)):0), _cf_free(B);
+#define RRRRPSTRV(A,B,D) c2fstrv(B,A,D+1,(D+1)*_(B,N)), _cf_free(B);
+#ifdef vmsFortran
+#define PSTRING_cfR(A,B,D) RRRRPSTR( A->dsc$a_pointer,B,A->dsc$w_length)
+#define PSTRINGV_cfR(A,B,D) RRRRPSTRV(A->dsc$a_pointer,B,A->dsc$w_length)
+#else
+#ifdef CRAYFortran
+#define PSTRING_cfR(A,B,D) RRRRPSTR( _fcdtocp(A),B,_fcdlen(A))
+#define PSTRINGV_cfR(A,B,D) RRRRPSTRV(_fcdtocp(A),B,_fcdlen(A))
+#else
+#define PSTRING_cfR(A,B,D) RRRRPSTR( A,B,D)
+#define PSTRINGV_cfR(A,B,D) RRRRPSTRV(A,B,D)
+#endif
+#endif
+#define PNSTRING_cfR(A,B,D) PSTRING_cfR(A,B,D)
+#define PPSTRING_cfR(A,B,D)
+
+#define BYTE_cfFZ(UN,LN) INTEGER_BYTE FCALLSC_QUALIFIER fcallsc(UN,LN)(
+#define DOUBLE_cfFZ(UN,LN) DOUBLE_PRECISION FCALLSC_QUALIFIER fcallsc(UN,LN)(
+#define INT_cfFZ(UN,LN) int FCALLSC_QUALIFIER fcallsc(UN,LN)(
+#define LOGICAL_cfFZ(UN,LN) int FCALLSC_QUALIFIER fcallsc(UN,LN)(
+#define LONG_cfFZ(UN,LN) long FCALLSC_QUALIFIER fcallsc(UN,LN)(
+#define LONGLONG_cfFZ(UN,LN) LONGLONG FCALLSC_QUALIFIER fcallsc(UN,LN)( /* added by MR December 2005 */
+#define SHORT_cfFZ(UN,LN) short FCALLSC_QUALIFIER fcallsc(UN,LN)(
+#define VOID_cfFZ(UN,LN) void FCALLSC_QUALIFIER fcallsc(UN,LN)(
+#ifndef __CF__KnR
+/* The void is req'd by the Apollo, to make this an ANSI function declaration.
+ The Apollo promotes K&R float functions to double. */
+#if defined (f2cFortran) && ! defined (gFortran)
+/* f2c/g77 return double from FORTRAN REAL functions. (KMCCARTY, 2005/12/09) */
+#define FLOAT_cfFZ(UN,LN) DOUBLE_PRECISION FCALLSC_QUALIFIER fcallsc(UN,LN)(void
+#else
+#define FLOAT_cfFZ(UN,LN) FORTRAN_REAL FCALLSC_QUALIFIER fcallsc(UN,LN)(void
+#endif
+#ifdef vmsFortran
+#define STRING_cfFZ(UN,LN) void FCALLSC_QUALIFIER fcallsc(UN,LN)(fstring *AS
+#else
+#ifdef CRAYFortran
+#define STRING_cfFZ(UN,LN) void FCALLSC_QUALIFIER fcallsc(UN,LN)(_fcd AS
+#else
+#if defined(AbsoftUNIXFortran) || defined(AbsoftProFortran)
+#define STRING_cfFZ(UN,LN) void FCALLSC_QUALIFIER fcallsc(UN,LN)(char *AS
+#else
+#define STRING_cfFZ(UN,LN) void FCALLSC_QUALIFIER fcallsc(UN,LN)(char *AS, unsigned D0
+#endif
+#endif
+#endif
+#else
+#if ! (defined(FLOATFUNCTIONTYPE)&&defined(ASSIGNFLOAT)&&defined(RETURNFLOAT))
+#if defined (f2cFortran) && ! defined (gFortran)
+/* f2c/g77 return double from FORTRAN REAL functions. (KMCCARTY, 2005/12/09) */
+#define FLOAT_cfFZ(UN,LN) DOUBLE_PRECISION FCALLSC_QUALIFIER fcallsc(UN,LN)(
+#else
+#define FLOAT_cfFZ(UN,LN) FORTRAN_REAL FCALLSC_QUALIFIER fcallsc(UN,LN)(
+#endif
+#else
+#define FLOAT_cfFZ(UN,LN) FLOATFUNCTIONTYPE FCALLSC_QUALIFIER fcallsc(UN,LN)(
+#endif
+#if defined(vmsFortran) || defined(CRAYFortran) || defined(AbsoftUNIXFortran)
+#define STRING_cfFZ(UN,LN) void FCALLSC_QUALIFIER fcallsc(UN,LN)(AS
+#else
+#define STRING_cfFZ(UN,LN) void FCALLSC_QUALIFIER fcallsc(UN,LN)(AS, D0
+#endif
+#endif
+
+#define BYTE_cfF(UN,LN) BYTE_cfFZ(UN,LN)
+#define DOUBLE_cfF(UN,LN) DOUBLE_cfFZ(UN,LN)
+#ifndef __CF_KnR
+#if defined (f2cFortran) && ! defined (gFortran)
+/* f2c/g77 return double from FORTRAN REAL functions. (KMCCARTY, 2005/12/09) */
+#define FLOAT_cfF(UN,LN) DOUBLE_PRECISION FCALLSC_QUALIFIER fcallsc(UN,LN)(
+#else
+#define FLOAT_cfF(UN,LN) FORTRAN_REAL FCALLSC_QUALIFIER fcallsc(UN,LN)(
+#endif
+#else
+#define FLOAT_cfF(UN,LN) FLOAT_cfFZ(UN,LN)
+#endif
+#define INT_cfF(UN,LN) INT_cfFZ(UN,LN)
+#define LOGICAL_cfF(UN,LN) LOGICAL_cfFZ(UN,LN)
+#define LONG_cfF(UN,LN) LONG_cfFZ(UN,LN)
+#define LONGLONG_cfF(UN,LN) LONGLONG_cfFZ(UN,LN) /* added by MR December 2005 */
+#define SHORT_cfF(UN,LN) SHORT_cfFZ(UN,LN)
+#define VOID_cfF(UN,LN) VOID_cfFZ(UN,LN)
+#define STRING_cfF(UN,LN) STRING_cfFZ(UN,LN),
+
+#define INT_cfFF
+#define VOID_cfFF
+#ifdef vmsFortran
+#define STRING_cfFF fstring *AS;
+#else
+#ifdef CRAYFortran
+#define STRING_cfFF _fcd AS;
+#else
+#define STRING_cfFF char *AS; unsigned D0;
+#endif
+#endif
+
+#define INT_cfL A0=
+#define STRING_cfL A0=
+#define VOID_cfL
+
+#define INT_cfK
+#define VOID_cfK
+/* KSTRING copies the string into the position provided by the caller. */
+#ifdef vmsFortran
+#define STRING_cfK \
+ memcpy(AS->dsc$a_pointer,A0,_cfMIN(AS->dsc$w_length,(A0==NULL?0:strlen(A0))));\
+ AS->dsc$w_length>(A0==NULL?0:strlen(A0))? \
+ memset(AS->dsc$a_pointer+(A0==NULL?0:strlen(A0)),' ', \
+ AS->dsc$w_length-(A0==NULL?0:strlen(A0))):0;
+#else
+#ifdef CRAYFortran
+#define STRING_cfK \
+ memcpy(_fcdtocp(AS),A0, _cfMIN(_fcdlen(AS),(A0==NULL?0:strlen(A0))) ); \
+ _fcdlen(AS)>(A0==NULL?0:strlen(A0))? \
+ memset(_fcdtocp(AS)+(A0==NULL?0:strlen(A0)),' ', \
+ _fcdlen(AS)-(A0==NULL?0:strlen(A0))):0;
+#else
+#define STRING_cfK memcpy(AS,A0, _cfMIN(D0,(A0==NULL?0:strlen(A0))) ); \
+ D0>(A0==NULL?0:strlen(A0))?memset(AS+(A0==NULL?0:strlen(A0)), \
+ ' ', D0-(A0==NULL?0:strlen(A0))):0;
+#endif
+#endif
+
+/* Note that K.. and I.. can't be combined since K.. has to access data before
+R.., in order for functions returning strings which are also passed in as
+arguments to work correctly. Note that R.. frees and hence may corrupt the
+string. */
+#define BYTE_cfI return A0;
+#define DOUBLE_cfI return A0;
+#if ! (defined(FLOATFUNCTIONTYPE)&&defined(ASSIGNFLOAT)&&defined(RETURNFLOAT))
+#define FLOAT_cfI return A0;
+#else
+#define FLOAT_cfI RETURNFLOAT(A0);
+#endif
+#define INT_cfI return A0;
+#ifdef hpuxFortran800
+/* Incredibly, functions must return true as 1, elsewhere .true.==0x01000000. */
+#define LOGICAL_cfI return ((A0)?1:0);
+#else
+#define LOGICAL_cfI return C2FLOGICAL(A0);
+#endif
+#define LONG_cfI return A0;
+#define LONGLONG_cfI return A0; /* added by MR December 2005 */
+#define SHORT_cfI return A0;
+#define STRING_cfI return ;
+#define VOID_cfI return ;
+
+#ifdef OLD_VAXC /* Allow %CC-I-PARAMNOTUSED. */
+#pragma standard
+#endif
+
+#define FCALLSCSUB0( CN,UN,LN) FCALLSCFUN0(VOID,CN,UN,LN)
+#define FCALLSCSUB1( CN,UN,LN,T1) FCALLSCFUN1(VOID,CN,UN,LN,T1)
+#define FCALLSCSUB2( CN,UN,LN,T1,T2) FCALLSCFUN2(VOID,CN,UN,LN,T1,T2)
+#define FCALLSCSUB3( CN,UN,LN,T1,T2,T3) FCALLSCFUN3(VOID,CN,UN,LN,T1,T2,T3)
+#define FCALLSCSUB4( CN,UN,LN,T1,T2,T3,T4) \
+ FCALLSCFUN4(VOID,CN,UN,LN,T1,T2,T3,T4)
+#define FCALLSCSUB5( CN,UN,LN,T1,T2,T3,T4,T5) \
+ FCALLSCFUN5(VOID,CN,UN,LN,T1,T2,T3,T4,T5)
+#define FCALLSCSUB6( CN,UN,LN,T1,T2,T3,T4,T5,T6) \
+ FCALLSCFUN6(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6)
+#define FCALLSCSUB7( CN,UN,LN,T1,T2,T3,T4,T5,T6,T7) \
+ FCALLSCFUN7(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7)
+#define FCALLSCSUB8( CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8) \
+ FCALLSCFUN8(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8)
+#define FCALLSCSUB9( CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9) \
+ FCALLSCFUN9(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9)
+#define FCALLSCSUB10(CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA) \
+ FCALLSCFUN10(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA)
+#define FCALLSCSUB11(CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB) \
+ FCALLSCFUN11(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB)
+#define FCALLSCSUB12(CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC) \
+ FCALLSCFUN12(VOID,CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC)
+#define FCALLSCSUB13(CN,UN,LN,T1,T2,T3,T4,T5,T6,T7,T8,T9,TA,TB,TC