From 23c7930d27fe11c4655e1291a07a821dbbaba78d Mon Sep 17 00:00:00 2001 From: William Joye Date: Thu, 27 Oct 2016 13:38:41 -0400 Subject: Squashed 'funtools/' content from commit 46f67fd git-subtree-dir: funtools git-subtree-split: 46f67fd2436f384d531fa6bf712d8e14f8491e40 --- .gitignore | 45 + COPYING | 504 + INSTALL | 312 + Makefile.in | 754 ++ README | 27 + ac_c_long_long.m4 | 36 + aclocal.m4 | 2 + bsearch.c | 68 + calc.h | 36 + calc.l | 802 ++ chandra.h | 5 + conf.h.in | 63 + config.guess | 1462 +++ config.sub | 1823 +++ configure-failsafe | 7001 ++++++++++++ configure.ac | 286 + copyright | 30 + doc/asc2fits.c | 86 + doc/changelog.html | 1182 ++ doc/changelog_beta.html | 953 ++ doc/combo.html | 117 + doc/doc40.fits | Bin 0 -> 5760 bytes doc/ds9.html | 105 + doc/env.html | 222 + doc/evcol.c | 130 + doc/evmerge.c | 77 + doc/evnext.c | 116 + doc/evread.c | 304 + doc/files.html | 627 + doc/filters.html | 325 + doc/funcalc.sed | 9 + doc/funtools.ds9 | 83 + doc/funtools.pdf | Bin 0 -> 447315 bytes doc/funtools.ps | 11446 +++++++++++++++++++ doc/help.html | 192 + doc/html2man | 258 + doc/idx.html | 216 + doc/imblank.c | 106 + doc/library.html | 2823 +++++ doc/pod/funcalc.pod | 572 + doc/pod/funcen.pod | 145 + doc/pod/funclose.pod | 53 + doc/pod/funcnts.pod | 657 ++ doc/pod/funcolumnactivate.pod | 239 + doc/pod/funcolumnlookup.pod | 188 + doc/pod/funcolumnselect.pod | 686 ++ doc/pod/funcombine.pod | 157 + doc/pod/funcone.pod | 191 + doc/pod/fundisp.pod | 484 + doc/pod/funds9.pod | 113 + doc/pod/funenv.pod | 349 + doc/pod/funfiles.pod | 1019 ++ doc/pod/funfilters.pod | 521 + doc/pod/funflush.pod | 107 + doc/pod/funhead.pod | 218 + doc/pod/funhist.pod | 252 + doc/pod/funidx.pod | 224 + doc/pod/funimage.pod | 314 + doc/pod/funimageget.pod | 237 + doc/pod/funimageput.pod | 145 + doc/pod/funimagerowget.pod | 137 + doc/pod/funimagerowput.pod | 122 + doc/pod/funindex.pod | 83 + doc/pod/funindexes.pod | 215 + doc/pod/funinfoget.pod | 226 + doc/pod/funinfoput.pod | 180 + doc/pod/funjoin.pod | 233 + doc/pod/funlib.pod | 542 + doc/pod/funmerge.pod | 122 + doc/pod/funopen.pod | 166 + doc/pod/funparamget.pod | 153 + doc/pod/funparamput.pod | 147 + doc/pod/funref.pod | 170 + doc/pod/funregions.pod | 571 + doc/pod/funsky.pod | 260 + doc/pod/funtable.pod | 296 + doc/pod/funtablerowget.pod | 111 + doc/pod/funtablerowput.pod | 200 + doc/pod/funtbl.pod | 137 + doc/pod/funtext.pod | 718 ++ doc/pod/funtools.pod | 542 + doc/pod/funview.pod | 407 + doc/pod/funvu.pod | 404 + doc/pod/regalgebra.pod | 286 + doc/pod/regbounds.pod | 203 + doc/pod/regcoords.pod | 247 + doc/pod/regdiff.pod | 99 + doc/pod/reggeometry.pod | 1156 ++ doc/programs.html | 3497 ++++++ doc/regalgebra.html | 278 + doc/regbounds.html | 179 + doc/regcoords.html | 239 + doc/regdiff.html | 71 + doc/reggeometry.html | 1148 ++ doc/regions.html | 563 + doc/sman/fun4.index | Bin 0 -> 695374 bytes doc/sman/fun4.index.prop | Bin 0 -> 137841 bytes doc/sman/fun4.index.version | 2 + doc/sman/fun8.index | Bin 0 -> 1125202 bytes doc/sman/fun8.index.prop | Bin 0 -> 138033 bytes doc/sman/fun8.index.version | 2 + doc/sman_conf.tmpl | 96 + doc/szlong.c | 8 + doc/tabcalc.c | 196 + doc/text.html | 564 + doc/twcs.c | 61 + doc/view.html | 376 + faq/Makefile.in | 135 + faq/faq.html | 49 + faq/faq1.html | 39 + faq/faq2.html | 381 + faq/faq3.html | 23 + faq/faq4.html | 211 + faq/tdisp | 15 + faq/tev.c | 56 + faq/tfaq.c | 41 + faq/tim.c | 55 + filter/Imakefile | 18 + filter/Makefile.in | 282 + filter/ZHTODO | 4 + filter/ac_c_long_long.m4 | 36 + filter/aclocal.m4 | 1 + filter/addld | 1 + filter/column.c | 36 + filter/column.h | 29 + filter/compat/install-sh | 238 + filter/conf.h.in | 62 + filter/config.guess | 1435 +++ filter/config.sub | 1807 +++ filter/configure-failsafe | 6399 +++++++++++ filter/configure.ac | 202 + filter/dl.c | 57 + filter/dl.h | 23 + filter/events_c.h | 1 + filter/events_py.h | 1 + filter/evfilter.c | 266 + filter/evfilter.py | 156 + filter/evregions.c | 1532 +++ filter/evregions_c.h | 1 + filter/evregions_c.tmpl | 1532 +++ filter/filt.l | 3228 ++++++ filter/filter.c | 1041 ++ filter/filter.h | 380 + filter/filter_pyh.py | 22 + filter/filtprog.c | 351 + filter/filtprog_c.c | 1033 ++ filter/idx.h | 166 + filter/idx.l | 559 + filter/idx.output | 1007 ++ filter/idx.tab.c | 2177 ++++ filter/idx.tab.h | 83 + filter/idx.y | 77 + filter/idxacts.c | 2368 ++++ filter/image_c.h | 1 + filter/imfilter.c | 335 + filter/imregions.c | 2585 +++++ filter/imregions_c.h | 1 + filter/imregions_c.tmpl | 2585 +++++ filter/inc.sed | 13 + filter/install-sh | 276 + filter/lex.filt.c | 8941 +++++++++++++++ filter/lex.idx.c | 2829 +++++ filter/regions.h | 408 + filter/regions_h.h | 1 + filter/sample.c | 83 + filter/swap.c | 92 + filter/swap_c.h | 1 + filter/symbols.c | 323 + filter/tfilt.c | 527 + filter/tfilt.ex | 24 + filter/tl.c | 190 + filter/tl.h | 25 + filter/xalloc_c.h | 1 + fitsy/Imakefile | 54 + fitsy/Makefile.in | 240 + fitsy/ac_c_long_long.m4 | 36 + fitsy/aclocal.m4 | 1 + fitsy/cardfind.c | 201 + fitsy/cardfmt.c | 367 + fitsy/cardins.c | 107 + fitsy/cardpar.c | 173 + fitsy/compat/install-sh | 238 + fitsy/conf.h.in | 59 + fitsy/config.guess | 1435 +++ fitsy/config.sub | 1807 +++ fitsy/configure-failsafe | 6199 ++++++++++ fitsy/configure.ac | 168 + fitsy/data | 95 + fitsy/dataimage.c | 221 + fitsy/datatable.c | 15 + fitsy/doc/basicval.html | 77 + fitsy/doc/basicval.wu | 62 + fitsy/doc/cardfind.html | 112 + fitsy/doc/cardfind.wu | 85 + fitsy/doc/cardfmt.html | 181 + fitsy/doc/cardfmt.wu | 144 + fitsy/doc/cardins.html | 99 + fitsy/doc/cardins.wu | 72 + fitsy/doc/cardpar.html | 134 + fitsy/doc/cardpar.wu | 99 + fitsy/doc/dataimage.html | 58 + fitsy/doc/dataimage.wu | 37 + fitsy/doc/examples.wu | 36 + fitsy/doc/fitsimage.html | 72 + fitsy/doc/fitsimage.wu | 49 + fitsy/doc/fitsy.html | 78 + fitsy/doc/fitsy.pnuts | 20 + fitsy/doc/fitsy.wu | 43 + fitsy/doc/ftimage.wu | 41 + fitsy/doc/fttable.wu | 35 + fitsy/doc/headdata.html | 63 + fitsy/doc/headdata.wu | 40 + fitsy/doc/headfile.html | 67 + fitsy/doc/headfile.wu | 45 + fitsy/doc/headfind.html | 96 + fitsy/doc/headfind.wu | 69 + fitsy/doc/headget.html | 104 + fitsy/doc/headget.wu | 79 + fitsy/doc/headimage.html | 99 + fitsy/doc/headimage.wu | 71 + fitsy/doc/headinit.html | 115 + fitsy/doc/headinit.wu | 86 + fitsy/doc/headins.html | 128 + fitsy/doc/headins.wu | 96 + fitsy/doc/headset.html | 103 + fitsy/doc/headset.wu | 78 + fitsy/doc/headtable.html | 60 + fitsy/doc/headtable.wu | 38 + fitsy/doc/imageval.html | 42 + fitsy/doc/imageval.wu | 27 + fitsy/doc/makefile-sao | 51 + fitsy/doc/tableval.html | 56 + fitsy/doc/tableval.wu | 41 + fitsy/fitsfile.c | 65 + fitsy/fitshead.c | 483 + fitsy/fitsimage.c | 392 + fitsy/fitsy.h | 393 + fitsy/ftacht.c | 112 + fitsy/ftacht2.c | 151 + fitsy/generic.h | 30 + fitsy/headdata.c | 67 + fitsy/headfile.c | 147 + fitsy/headfind.c | 86 + fitsy/headget.c | 126 + fitsy/headimage.c | 274 + fitsy/headinit.c | 256 + fitsy/headins.c | 205 + fitsy/headset.c | 132 + fitsy/headsimple.c | 30 + fitsy/headtable.c | 299 + fitsy/headwcs.c | 91 + fitsy/install-sh | 276 + fitsy/inverse.c | 93 + fitsy/longlong.h | 12 + fitsy/nd.c | 51 + fitsy/parse.c | 196 + fitsy/ptest.c | 28 + fitsy/tableheader.c | 230 + fitsy/xfile.h | 20 + fitsy/xos.h | 226 + fun2table | 7 + funcalc.c | 358 + funcalc.sed | 11 + funcen.c | 830 ++ funcnts.c | 1693 +++ funcnts_plot.tmpl | 171 + funcnts_sed.tmpl | 4 + funcol.c | 1461 +++ funcone.c | 1473 +++ funcopy.c | 364 + fundisp.c | 1126 ++ funds9.tmpl | 180 + funhead.c | 369 + funhist.c | 632 + funhist_plot.tmpl | 137 + funim.c | 1680 +++ funimage.c | 581 + funindex.tmpl | 98 + funinfo.c | 541 + funjoin.c | 1172 ++ funmainlib.c | 48 + funmerge.c | 539 + funopen.c | 806 ++ funopenp.c | 1065 ++ funparam.c | 804 ++ funsky.c | 618 + funtab.c | 1412 +++ funtable.c | 609 + funtbl.tmpl | 202 + funtclmainlib.c | 46 + funtest/Makefile.in | 274 + funtest/arg3.inc | 1 + funtest/asc2fits.c | 85 + funtest/ascii2fits.c | 99 + funtest/avg | 2 + funtest/bigfits.c | 87 + funtest/bpix.ev | 3 + funtest/cat.ls | 3 + funtest/cat.txt | 102 + funtest/comm | 15 + funtest/conf.h.in | 56 + funtest/evcol.c | 130 + funtest/evcre.c | 115 + funtest/evmerge.c | 77 + funtest/evmerge2.c | 124 + funtest/evnext.c | 116 + funtest/evread.c | 363 + funtest/evreplace.c | 96 + funtest/evtest.c | 82 + funtest/fctest | 4 + funtest/filt.c | 147 + funtest/funcalc.sed | 11 + funtest/funcheck | 10 + funtest/funchecks | 6 + funtest/funcones | 61 + funtest/fundisp1out | 0 funtest/funsky.c | 238 + funtest/funstack | 86 + funtest/funtest | 195 + funtest/funtesti | 18 + funtest/funtests | 127 + funtest/funtexts | 14 + funtest/funtools1.vu | 10 + funtest/funtools2.vu | 11 + funtest/goo.ls | 0 funtest/group.calc | 125 + funtest/imblank.c | 107 + funtest/imtest.c | 156 + funtest/install-sh | 276 + funtest/mif.lst | 4 + funtest/mif1.fits | 2 + funtest/mif2.fits | 2 + funtest/mif3.fits | 2 + funtest/mif4.fits | 2 + funtest/mkdim.c | 96 + funtest/mkev.c | 335 + funtest/mkev2.c | 53 + funtest/ntest.ev | 98 + funtest/nwcs | 109 + funtest/parse.in | 24 + funtest/pr | 8 + funtest/qcon.c | 123 + funtest/resample.fc | 70 + funtest/sample.fc | 13 + funtest/snr100.reg | 100 + funtest/snr400.reg | 400 + funtest/snr900.reg | 900 ++ funtest/swap | 5 + funtest/swap1 | 8 + funtest/t1.reg | 6 + funtest/t2.reg | 5 + funtest/t3.reg | 4 + funtest/t4.reg | 1 + funtest/tboxell.in | 50 + funtest/tcalc.in | 14 + funtest/tcols.in | 56 + funtest/tcone.in | 8 + funtest/tenv | 24 + funtest/test.asc | 298 + funtest/test.ev | 62 + funtest/test.fits | Bin 0 -> 5760 bytes funtest/test2.ev | 113 + funtest/test2.raw | Bin 0 -> 3770 bytes funtest/tevread | 93 + funtest/tfile.in | 17 + funtest/tfuncalc | 178 + funtest/tfuncnts | 307 + funtest/tfuncone | 131 + funtest/tfundisp | 227 + funtest/tfunhead | 241 + funtest/tfunimage | 227 + funtest/tfunmerge | 126 + funtest/tfuntext | 140 + funtest/tfunview | 163 + funtest/thead.in | 12 + funtest/timev | 264 + funtest/tmerge.in | 16 + funtest/tnum.in | 9 + funtest/tparen.in | 50 + funtest/tregions.in | 67 + funtest/tsections.in | 11 + funtest/ttext.in | 91 + funtest/tview.in | 11 + funtest/twcs.c | 61 + funtest/unwcs.in | 12 + funtest/wcs.in | 12 + funtest/wtest.c | 123 + funtest/x.fits | 1 + funtext.c | 1194 ++ funtools.h | 240 + funtools.pc.in | 10 + funtoolsP.h | 343 + funtools_ds9.tmpl | 143 + funutil.c | 857 ++ funview.c | 632 + funwcs.c | 130 + gnu/COPYING | 340 + gnu/Makefile.in | 150 + gnu/conf.h.in | 59 + gnu/copyright | 29 + gnu/install-sh | 276 + gnu/sort.c | 2879 +++++ gnu/sorttest.c | 152 + gnu/system.h | 187 + inc.sed | 12 + install-sh | 276 + jointable.c | 932 ++ lex.calc.c | 2951 +++++ man/man1/funcalc.1 | 622 + man/man1/funcen.1 | 250 + man/man1/funcnts.1 | 806 ++ man/man1/funcone.1 | 285 + man/man1/fundisp.1 | 589 + man/man1/funhead.1 | 287 + man/man1/funhist.1 | 370 + man/man1/funimage.1 | 428 + man/man1/funindex.1 | 179 + man/man1/funjoin.1 | 326 + man/man1/funmerge.1 | 215 + man/man1/funsky.1 | 385 + man/man1/funtable.1 | 356 + man/man1/funtbl.1 | 249 + man/man3/funclose.3 | 160 + man/man3/funcolumnactivate.3 | 330 + man/man3/funcolumnlookup.3 | 220 + man/man3/funcolumnselect.3 | 664 ++ man/man3/funflush.3 | 212 + man/man3/funimageget.3 | 332 + man/man3/funimageput.3 | 225 + man/man3/funimagerowget.3 | 215 + man/man3/funimagerowput.3 | 202 + man/man3/funinfoget.3 | 335 + man/man3/funinfoput.3 | 246 + man/man3/funlib.3 | 525 + man/man3/funopen.3 | 272 + man/man3/funparamget.3 | 262 + man/man3/funparamput.3 | 256 + man/man3/funref.3 | 287 + man/man3/funtablerowget.3 | 216 + man/man3/funtablerowput.3 | 297 + man/man7/funcombine.7 | 248 + man/man7/funds9.7 | 216 + man/man7/funenv.7 | 352 + man/man7/funfiles.7 | 802 ++ man/man7/funfilters.7 | 464 + man/man7/funidx.7 | 327 + man/man7/funregions.7 | 678 ++ man/man7/funtext.7 | 713 ++ man/man7/funtools.7 | 379 + man/man7/funview.7 | 523 + man/man7/regalgebra.7 | 400 + man/man7/regbounds.7 | 305 + man/man7/regcoords.7 | 345 + man/man7/regdiff.7 | 181 + man/man7/reggeometry.7 | 1271 ++ mkconfigure | 23 + mkfunmainlib | 68 + mklib | 880 ++ notes/ds9.notes | 90 + notes/index.notes | 30 + notes/mainlib.notes | 68 + notes/mingw.notes | 12 + notes/tcl.notes | 10 + notes/text.notes | 29 + notes/view.notes | 261 + ofuntools.h | 240 + pkgIndex.tcl | 11 + saoconfig | 235 + scan.c | 231 + search.c | 1107 ++ tabcalc.c | 296 + tabcalc_c.h | 1 + tcl.m4 | 2464 ++++ test.tcl | 13 + tfunjoin | 37 + tmain.c | 272 + tmain.tcl | 1 + tperl.c | 39 + txt/bar.txt | 23 + txt/blank.txt | 1 + txt/blank2.txt | 2 + txt/comma.txt | 24 + txt/comma2.txt | 24 + txt/comma3.txt | 33 + txt/crcomma.txt | 1 + txt/crnl | 20 + txt/crspace.txt | 1 + txt/crtab.txt | 1 + txt/eot.txt | 25 + txt/eot2.txt | 26 + txt/foo1 | 12 + txt/foo2 | 12 + txt/headone.txt | 2 + txt/int64.fits | Bin 0 -> 8640 bytes txt/int64.tab | 17 + txt/int64_Value.idx | Bin 0 -> 8640 bytes txt/nlcomma.txt | 23 + txt/nlcr | 20 + txt/nltab.txt | 23 + txt/null.tab | 6 + txt/one.txt | 1 + txt/rdb.txt | 26 + txt/sex.tab | 244 + txt/space.txt | 24 + txt/sptab.txt | 24 + txt/tab.txt | 26 + txt/test.fits | Bin 0 -> 14400 bytes txt/vis.tab | 175 + util/Makefile.in | 275 + util/NaN.h.in | 70 + util/ac_c_long_long.m4 | 36 + util/aclocal.m4 | 2 + util/conf.h.in | 80 + util/config.guess | 1435 +++ util/config.sub | 1807 +++ util/configure-failsafe | 7191 ++++++++++++ util/configure.ac | 196 + util/file.c | 629 + util/file.h | 53 + util/find.c | 456 + util/find.h | 40 + util/gcat.c | 284 + util/gio.c | 2314 ++++ util/gio.h | 162 + util/install-sh | 276 + util/iraf_zprocess.c | 469 + util/longlong.h | 12 + util/macro.c | 216 + util/macro.h | 43 + util/mainlib.c | 790 ++ util/mainlib.h | 130 + util/mkrtemp.c | 113 + util/mkrtemp.h | 56 + util/nan.c | 65 + util/parse.c | 1187 ++ util/parse.h | 171 + util/prsetup.h | 66 + util/strtod.c | 190 + util/strtod.h | 22 + util/swap.c | 228 + util/swap.h | 37 + util/tcl.m4 | 2464 ++++ util/tclmainlib.c | 504 + util/tclmainlib.h | 31 + util/tlaunch.c | 98 + util/tlaunch2.c | 59 + util/tparse.c | 89 + util/winprocess.c | 317 + util/winprocess.h | 44 + util/word.c | 1097 ++ util/word.h | 59 + util/xalloc.c | 117 + util/xalloc.h | 51 + util/xfileio.h | 23 + util/xlaunch.c | 657 ++ util/xlaunch.h | 84 + util/xport.h | 140 + util/zlib-1.2.3/ChangeLog | 855 ++ util/zlib-1.2.3/FAQ | 339 + util/zlib-1.2.3/INDEX | 51 + util/zlib-1.2.3/Makefile | 154 + util/zlib-1.2.3/Makefile.in | 154 + util/zlib-1.2.3/README | 125 + util/zlib-1.2.3/adler32.c | 149 + util/zlib-1.2.3/algorithm.txt | 209 + util/zlib-1.2.3/amiga/Makefile.pup | 66 + util/zlib-1.2.3/amiga/Makefile.sas | 65 + util/zlib-1.2.3/as400/bndsrc | 132 + util/zlib-1.2.3/as400/compile.clp | 123 + util/zlib-1.2.3/as400/readme.txt | 111 + util/zlib-1.2.3/as400/zlib.inc | 331 + util/zlib-1.2.3/compress.c | 79 + util/zlib-1.2.3/configure | 459 + util/zlib-1.2.3/contrib/README.contrib | 71 + util/zlib-1.2.3/contrib/ada/buffer_demo.adb | 106 + util/zlib-1.2.3/contrib/ada/mtest.adb | 156 + util/zlib-1.2.3/contrib/ada/read.adb | 156 + util/zlib-1.2.3/contrib/ada/readme.txt | 65 + util/zlib-1.2.3/contrib/ada/test.adb | 463 + util/zlib-1.2.3/contrib/ada/zlib-streams.adb | 225 + util/zlib-1.2.3/contrib/ada/zlib-streams.ads | 114 + util/zlib-1.2.3/contrib/ada/zlib-thin.adb | 141 + util/zlib-1.2.3/contrib/ada/zlib-thin.ads | 450 + util/zlib-1.2.3/contrib/ada/zlib.adb | 701 ++ util/zlib-1.2.3/contrib/ada/zlib.ads | 328 + util/zlib-1.2.3/contrib/ada/zlib.gpr | 20 + util/zlib-1.2.3/contrib/asm586/README.586 | 43 + util/zlib-1.2.3/contrib/asm586/match.S | 364 + util/zlib-1.2.3/contrib/asm686/README.686 | 34 + util/zlib-1.2.3/contrib/asm686/match.S | 329 + util/zlib-1.2.3/contrib/blast/Makefile | 8 + util/zlib-1.2.3/contrib/blast/README | 4 + util/zlib-1.2.3/contrib/blast/blast.c | 444 + util/zlib-1.2.3/contrib/blast/blast.h | 71 + util/zlib-1.2.3/contrib/blast/test.pk | Bin 0 -> 8 bytes util/zlib-1.2.3/contrib/blast/test.txt | 1 + util/zlib-1.2.3/contrib/delphi/ZLib.pas | 557 + util/zlib-1.2.3/contrib/delphi/ZLibConst.pas | 11 + util/zlib-1.2.3/contrib/delphi/readme.txt | 76 + util/zlib-1.2.3/contrib/delphi/zlibd32.mak | 93 + util/zlib-1.2.3/contrib/dotzlib/DotZLib.build | 33 + util/zlib-1.2.3/contrib/dotzlib/DotZLib.sln | 21 + .../contrib/dotzlib/DotZLib/AssemblyInfo.cs | 58 + .../contrib/dotzlib/DotZLib/ChecksumImpl.cs | 202 + .../contrib/dotzlib/DotZLib/CircularBuffer.cs | 83 + .../contrib/dotzlib/DotZLib/CodecBase.cs | 198 + .../zlib-1.2.3/contrib/dotzlib/DotZLib/Deflater.cs | 106 + util/zlib-1.2.3/contrib/dotzlib/DotZLib/DotZLib.cs | 288 + .../contrib/dotzlib/DotZLib/DotZLib.csproj | 141 + .../contrib/dotzlib/DotZLib/GZipStream.cs | 301 + .../zlib-1.2.3/contrib/dotzlib/DotZLib/Inflater.cs | 105 + .../contrib/dotzlib/DotZLib/UnitTests.cs | 274 + util/zlib-1.2.3/contrib/dotzlib/LICENSE_1_0.txt | 23 + util/zlib-1.2.3/contrib/dotzlib/readme.txt | 58 + util/zlib-1.2.3/contrib/infback9/README | 1 + util/zlib-1.2.3/contrib/infback9/infback9.c | 608 + util/zlib-1.2.3/contrib/infback9/infback9.h | 37 + util/zlib-1.2.3/contrib/infback9/inffix9.h | 107 + util/zlib-1.2.3/contrib/infback9/inflate9.h | 47 + util/zlib-1.2.3/contrib/infback9/inftree9.c | 323 + util/zlib-1.2.3/contrib/infback9/inftree9.h | 55 + util/zlib-1.2.3/contrib/inflate86/inffas86.c | 1157 ++ util/zlib-1.2.3/contrib/inflate86/inffast.S | 1368 +++ util/zlib-1.2.3/contrib/iostream/test.cpp | 24 + util/zlib-1.2.3/contrib/iostream/zfstream.cpp | 329 + util/zlib-1.2.3/contrib/iostream/zfstream.h | 128 + util/zlib-1.2.3/contrib/iostream2/zstream.h | 307 + util/zlib-1.2.3/contrib/iostream2/zstream_test.cpp | 25 + util/zlib-1.2.3/contrib/iostream3/README | 35 + util/zlib-1.2.3/contrib/iostream3/TODO | 17 + util/zlib-1.2.3/contrib/iostream3/test.cc | 50 + util/zlib-1.2.3/contrib/iostream3/zfstream.cc | 479 + util/zlib-1.2.3/contrib/iostream3/zfstream.h | 466 + util/zlib-1.2.3/contrib/masm686/match.asm | 413 + util/zlib-1.2.3/contrib/masmx64/bld_ml64.bat | 2 + util/zlib-1.2.3/contrib/masmx64/gvmat64.asm | 513 + util/zlib-1.2.3/contrib/masmx64/gvmat64.obj | Bin 0 -> 4119 bytes util/zlib-1.2.3/contrib/masmx64/inffas8664.c | 186 + util/zlib-1.2.3/contrib/masmx64/inffasx64.asm | 392 + util/zlib-1.2.3/contrib/masmx64/inffasx64.obj | Bin 0 -> 5913 bytes util/zlib-1.2.3/contrib/masmx64/readme.txt | 28 + util/zlib-1.2.3/contrib/masmx86/bld_ml32.bat | 2 + util/zlib-1.2.3/contrib/masmx86/gvmat32.asm | 972 ++ util/zlib-1.2.3/contrib/masmx86/gvmat32c.c | 62 + util/zlib-1.2.3/contrib/masmx86/inffas32.asm | 1083 ++ util/zlib-1.2.3/contrib/masmx86/mkasm.bat | 3 + util/zlib-1.2.3/contrib/masmx86/readme.txt | 21 + util/zlib-1.2.3/contrib/minizip/ChangeLogUnzip | 67 + util/zlib-1.2.3/contrib/minizip/Makefile | 25 + util/zlib-1.2.3/contrib/minizip/crypt.h | 132 + util/zlib-1.2.3/contrib/minizip/ioapi.c | 177 + util/zlib-1.2.3/contrib/minizip/ioapi.h | 75 + util/zlib-1.2.3/contrib/minizip/iowin32.c | 270 + util/zlib-1.2.3/contrib/minizip/iowin32.h | 21 + util/zlib-1.2.3/contrib/minizip/miniunz.c | 585 + util/zlib-1.2.3/contrib/minizip/minizip.c | 420 + util/zlib-1.2.3/contrib/minizip/mztools.c | 281 + util/zlib-1.2.3/contrib/minizip/mztools.h | 31 + util/zlib-1.2.3/contrib/minizip/unzip.c | 1598 +++ util/zlib-1.2.3/contrib/minizip/unzip.h | 354 + util/zlib-1.2.3/contrib/minizip/zip.c | 1219 ++ util/zlib-1.2.3/contrib/minizip/zip.h | 235 + util/zlib-1.2.3/contrib/pascal/example.pas | 599 + util/zlib-1.2.3/contrib/pascal/readme.txt | 76 + util/zlib-1.2.3/contrib/pascal/zlibd32.mak | 93 + util/zlib-1.2.3/contrib/pascal/zlibpas.pas | 236 + util/zlib-1.2.3/contrib/puff/Makefile | 8 + util/zlib-1.2.3/contrib/puff/README | 63 + util/zlib-1.2.3/contrib/puff/puff.c | 837 ++ util/zlib-1.2.3/contrib/puff/puff.h | 31 + util/zlib-1.2.3/contrib/puff/zeros.raw | Bin 0 -> 1213 bytes util/zlib-1.2.3/contrib/testzlib/testzlib.c | 275 + util/zlib-1.2.3/contrib/testzlib/testzlib.txt | 10 + util/zlib-1.2.3/contrib/untgz/Makefile | 14 + util/zlib-1.2.3/contrib/untgz/Makefile.msc | 17 + util/zlib-1.2.3/contrib/untgz/untgz.c | 674 ++ util/zlib-1.2.3/contrib/vstudio/readme.txt | 73 + util/zlib-1.2.3/contrib/vstudio/vc7/miniunz.vcproj | 126 + util/zlib-1.2.3/contrib/vstudio/vc7/minizip.vcproj | 126 + .../zlib-1.2.3/contrib/vstudio/vc7/testzlib.vcproj | 126 + util/zlib-1.2.3/contrib/vstudio/vc7/zlib.rc | 32 + .../zlib-1.2.3/contrib/vstudio/vc7/zlibstat.vcproj | 246 + util/zlib-1.2.3/contrib/vstudio/vc7/zlibvc.def | 92 + util/zlib-1.2.3/contrib/vstudio/vc7/zlibvc.sln | 78 + util/zlib-1.2.3/contrib/vstudio/vc7/zlibvc.vcproj | 445 + util/zlib-1.2.3/contrib/vstudio/vc8/miniunz.vcproj | 566 + util/zlib-1.2.3/contrib/vstudio/vc8/minizip.vcproj | 563 + .../zlib-1.2.3/contrib/vstudio/vc8/testzlib.vcproj | 948 ++ .../contrib/vstudio/vc8/testzlibdll.vcproj | 567 + util/zlib-1.2.3/contrib/vstudio/vc8/zlib.rc | 32 + .../zlib-1.2.3/contrib/vstudio/vc8/zlibstat.vcproj | 870 ++ util/zlib-1.2.3/contrib/vstudio/vc8/zlibvc.def | 92 + util/zlib-1.2.3/contrib/vstudio/vc8/zlibvc.sln | 144 + util/zlib-1.2.3/contrib/vstudio/vc8/zlibvc.vcproj | 1219 ++ util/zlib-1.2.3/crc32.c | 423 + util/zlib-1.2.3/crc32.h | 441 + util/zlib-1.2.3/deflate.c | 1736 +++ util/zlib-1.2.3/deflate.h | 331 + util/zlib-1.2.3/example.c | 565 + util/zlib-1.2.3/examples/README.examples | 42 + util/zlib-1.2.3/examples/fitblk.c | 233 + util/zlib-1.2.3/examples/gun.c | 693 ++ util/zlib-1.2.3/examples/gzappend.c | 500 + util/zlib-1.2.3/examples/gzjoin.c | 448 + util/zlib-1.2.3/examples/gzlog.c | 413 + util/zlib-1.2.3/examples/gzlog.h | 58 + util/zlib-1.2.3/examples/zlib_how.html | 523 + util/zlib-1.2.3/examples/zpipe.c | 191 + util/zlib-1.2.3/examples/zran.c | 404 + util/zlib-1.2.3/gzio.c | 1026 ++ util/zlib-1.2.3/infback.c | 623 + util/zlib-1.2.3/inffast.c | 318 + util/zlib-1.2.3/inffast.h | 11 + util/zlib-1.2.3/inffixed.h | 94 + util/zlib-1.2.3/inflate.c | 1368 +++ util/zlib-1.2.3/inflate.h | 115 + util/zlib-1.2.3/inftrees.c | 329 + util/zlib-1.2.3/inftrees.h | 55 + util/zlib-1.2.3/make_vms.com | 461 + util/zlib-1.2.3/minigzip.c | 322 + util/zlib-1.2.3/msdos/Makefile.bor | 109 + util/zlib-1.2.3/msdos/Makefile.dj2 | 104 + util/zlib-1.2.3/msdos/Makefile.emx | 69 + util/zlib-1.2.3/msdos/Makefile.msc | 106 + util/zlib-1.2.3/msdos/Makefile.tc | 94 + util/zlib-1.2.3/old/Makefile.riscos | 151 + util/zlib-1.2.3/old/README | 3 + util/zlib-1.2.3/old/descrip.mms | 48 + util/zlib-1.2.3/old/os2/Makefile.os2 | 136 + util/zlib-1.2.3/old/os2/zlib.def | 51 + util/zlib-1.2.3/old/visual-basic.txt | 160 + util/zlib-1.2.3/old/zlib.html | 971 ++ util/zlib-1.2.3/projects/README.projects | 41 + util/zlib-1.2.3/projects/visualc6/README.txt | 73 + util/zlib-1.2.3/projects/visualc6/example.dsp | 278 + util/zlib-1.2.3/projects/visualc6/minigzip.dsp | 278 + util/zlib-1.2.3/projects/visualc6/zlib.dsp | 609 + util/zlib-1.2.3/projects/visualc6/zlib.dsw | 59 + util/zlib-1.2.3/qnx/package.qpg | 141 + util/zlib-1.2.3/trees.c | 1219 ++ util/zlib-1.2.3/trees.h | 128 + util/zlib-1.2.3/uncompr.c | 61 + util/zlib-1.2.3/win32/DLL_FAQ.txt | 397 + util/zlib-1.2.3/win32/Makefile.bor | 107 + util/zlib-1.2.3/win32/Makefile.emx | 69 + util/zlib-1.2.3/win32/Makefile.gcc | 141 + util/zlib-1.2.3/win32/Makefile.msc | 126 + util/zlib-1.2.3/win32/VisualC.txt | 3 + util/zlib-1.2.3/win32/zlib.def | 60 + util/zlib-1.2.3/win32/zlib1.rc | 39 + util/zlib-1.2.3/zconf.h | 332 + util/zlib-1.2.3/zconf.in.h | 332 + util/zlib-1.2.3/zlib.3 | 159 + util/zlib-1.2.3/zlib.h | 1357 +++ util/zlib-1.2.3/zutil.c | 318 + util/zlib-1.2.3/zutil.h | 269 + util/zprocess.c | 373 + util/zprocess.h | 44 + wcs/COPYING | 460 + wcs/Files | 179 + wcs/Makefile-orig | 36 + wcs/Makefile.in | 206 + wcs/NEWS | 473 + wcs/Readme | 36 + wcs/cel.c | 474 + wcs/conf.h.in | 56 + wcs/config.guess | 1435 +++ wcs/config.sub | 1807 +++ wcs/configure-failsafe | 6222 ++++++++++ wcs/configure.ac | 177 + wcs/dateutil.c | 4554 ++++++++ wcs/distort.c | 407 + wcs/dsspos.c | 318 + wcs/fileutil.c | 818 ++ wcs/fitsfile.c | 2308 ++++ wcs/fitsfile.h | 1286 +++ wcs/fitshead.h | 438 + wcs/hget.c | 1913 ++++ wcs/hput.c | 1316 +++ wcs/iget.c | 531 + wcs/imhfile.c | 1941 ++++ wcs/imio.c | 1543 +++ wcs/imio.h | 64 + wcs/install-sh | 276 + wcs/lin.c | 448 + wcs/platepos.c | 391 + wcs/poly.c | 914 ++ wcs/proj.c | 4527 ++++++++ wcs/slasubs.c | 364 + wcs/sph.c | 234 + wcs/tnxpos.c | 1234 ++ wcs/wcs.c | 2994 +++++ wcs/wcs.h | 963 ++ wcs/wcscon.c | 2328 ++++ wcs/wcsinit.c | 1611 +++ wcs/wcslib.c | 1334 +++ wcs/wcslib.h | 476 + wcs/wcstrig.c | 189 + wcs/worldpos.c | 693 ++ wcs/zpxpos.c | 735 ++ 800 files changed, 314450 insertions(+) create mode 100644 .gitignore create mode 100644 COPYING create mode 100644 INSTALL create mode 100644 Makefile.in create mode 100644 README create mode 100644 ac_c_long_long.m4 create mode 100644 aclocal.m4 create mode 100644 bsearch.c create mode 100644 calc.h create mode 100644 calc.l create mode 100644 chandra.h create mode 100644 conf.h.in create mode 100755 config.guess create mode 100755 config.sub create mode 100755 configure-failsafe create mode 100644 configure.ac create mode 100644 copyright create mode 100644 doc/asc2fits.c create mode 100644 doc/changelog.html create mode 100644 doc/changelog_beta.html create mode 100644 doc/combo.html create mode 100644 doc/doc40.fits create mode 100644 doc/ds9.html create mode 100644 doc/env.html create mode 100644 doc/evcol.c create mode 100644 doc/evmerge.c create mode 100644 doc/evnext.c create mode 100644 doc/evread.c create mode 100644 doc/files.html create mode 100644 doc/filters.html create mode 100644 doc/funcalc.sed create mode 100644 doc/funtools.ds9 create mode 100644 doc/funtools.pdf create mode 100644 doc/funtools.ps create mode 100644 doc/help.html create mode 100755 doc/html2man create mode 100644 doc/idx.html create mode 100644 doc/imblank.c create mode 100644 doc/library.html create mode 100644 doc/pod/funcalc.pod create mode 100644 doc/pod/funcen.pod create mode 100644 doc/pod/funclose.pod create mode 100644 doc/pod/funcnts.pod create mode 100644 doc/pod/funcolumnactivate.pod create mode 100644 doc/pod/funcolumnlookup.pod create mode 100644 doc/pod/funcolumnselect.pod create mode 100644 doc/pod/funcombine.pod create mode 100644 doc/pod/funcone.pod create mode 100644 doc/pod/fundisp.pod create mode 100644 doc/pod/funds9.pod create mode 100644 doc/pod/funenv.pod create mode 100644 doc/pod/funfiles.pod create mode 100644 doc/pod/funfilters.pod create mode 100644 doc/pod/funflush.pod create mode 100644 doc/pod/funhead.pod create mode 100644 doc/pod/funhist.pod create mode 100644 doc/pod/funidx.pod create mode 100644 doc/pod/funimage.pod create mode 100644 doc/pod/funimageget.pod create mode 100644 doc/pod/funimageput.pod create mode 100644 doc/pod/funimagerowget.pod create mode 100644 doc/pod/funimagerowput.pod create mode 100644 doc/pod/funindex.pod create mode 100644 doc/pod/funindexes.pod create mode 100644 doc/pod/funinfoget.pod create mode 100644 doc/pod/funinfoput.pod create mode 100644 doc/pod/funjoin.pod create mode 100644 doc/pod/funlib.pod create mode 100644 doc/pod/funmerge.pod create mode 100644 doc/pod/funopen.pod create mode 100644 doc/pod/funparamget.pod create mode 100644 doc/pod/funparamput.pod create mode 100644 doc/pod/funref.pod create mode 100644 doc/pod/funregions.pod create mode 100644 doc/pod/funsky.pod create mode 100644 doc/pod/funtable.pod create mode 100644 doc/pod/funtablerowget.pod create mode 100644 doc/pod/funtablerowput.pod create mode 100644 doc/pod/funtbl.pod create mode 100644 doc/pod/funtext.pod create mode 100644 doc/pod/funtools.pod create mode 100644 doc/pod/funview.pod create mode 100644 doc/pod/funvu.pod create mode 100644 doc/pod/regalgebra.pod create mode 100644 doc/pod/regbounds.pod create mode 100644 doc/pod/regcoords.pod create mode 100644 doc/pod/regdiff.pod create mode 100644 doc/pod/reggeometry.pod create mode 100644 doc/programs.html create mode 100644 doc/regalgebra.html create mode 100644 doc/regbounds.html create mode 100644 doc/regcoords.html create mode 100644 doc/regdiff.html create mode 100644 doc/reggeometry.html create mode 100644 doc/regions.html create mode 100644 doc/sman/fun4.index create mode 100644 doc/sman/fun4.index.prop create mode 100644 doc/sman/fun4.index.version create mode 100644 doc/sman/fun8.index create mode 100644 doc/sman/fun8.index.prop create mode 100644 doc/sman/fun8.index.version create mode 100644 doc/sman_conf.tmpl create mode 100644 doc/szlong.c create mode 100644 doc/tabcalc.c create mode 100644 doc/text.html create mode 100644 doc/twcs.c create mode 100644 doc/view.html create mode 100644 faq/Makefile.in create mode 100644 faq/faq.html create mode 100644 faq/faq1.html create mode 100644 faq/faq2.html create mode 100644 faq/faq3.html create mode 100644 faq/faq4.html create mode 100755 faq/tdisp create mode 100644 faq/tev.c create mode 100644 faq/tfaq.c create mode 100644 faq/tim.c create mode 100644 filter/Imakefile create mode 100644 filter/Makefile.in create mode 100644 filter/ZHTODO create mode 100644 filter/ac_c_long_long.m4 create mode 100644 filter/aclocal.m4 create mode 100644 filter/addld create mode 100644 filter/column.c create mode 100644 filter/column.h create mode 100755 filter/compat/install-sh create mode 100644 filter/conf.h.in create mode 100644 filter/config.guess create mode 100644 filter/config.sub create mode 100755 filter/configure-failsafe create mode 100644 filter/configure.ac create mode 100644 filter/dl.c create mode 100644 filter/dl.h create mode 100644 filter/events_c.h create mode 100644 filter/events_py.h create mode 100644 filter/evfilter.c create mode 100644 filter/evfilter.py create mode 100644 filter/evregions.c create mode 100644 filter/evregions_c.h create mode 100644 filter/evregions_c.tmpl create mode 100644 filter/filt.l create mode 100644 filter/filter.c create mode 100644 filter/filter.h create mode 100644 filter/filter_pyh.py create mode 100644 filter/filtprog.c create mode 100644 filter/filtprog_c.c create mode 100644 filter/idx.h create mode 100644 filter/idx.l create mode 100644 filter/idx.output create mode 100644 filter/idx.tab.c create mode 100644 filter/idx.tab.h create mode 100644 filter/idx.y create mode 100644 filter/idxacts.c create mode 100644 filter/image_c.h create mode 100644 filter/imfilter.c create mode 100644 filter/imregions.c create mode 100644 filter/imregions_c.h create mode 100644 filter/imregions_c.tmpl create mode 100755 filter/inc.sed create mode 100755 filter/install-sh create mode 100644 filter/lex.filt.c create mode 100644 filter/lex.idx.c create mode 100644 filter/regions.h create mode 100644 filter/regions_h.h create mode 100644 filter/sample.c create mode 100644 filter/swap.c create mode 100644 filter/swap_c.h create mode 100644 filter/symbols.c create mode 100644 filter/tfilt.c create mode 100644 filter/tfilt.ex create mode 100644 filter/tl.c create mode 100644 filter/tl.h create mode 100644 filter/xalloc_c.h create mode 100644 fitsy/Imakefile create mode 100644 fitsy/Makefile.in create mode 100644 fitsy/ac_c_long_long.m4 create mode 100644 fitsy/aclocal.m4 create mode 100644 fitsy/cardfind.c create mode 100644 fitsy/cardfmt.c create mode 100644 fitsy/cardins.c create mode 100644 fitsy/cardpar.c create mode 100755 fitsy/compat/install-sh create mode 100644 fitsy/conf.h.in create mode 100644 fitsy/config.guess create mode 100644 fitsy/config.sub create mode 100755 fitsy/configure-failsafe create mode 100644 fitsy/configure.ac create mode 100644 fitsy/data create mode 100644 fitsy/dataimage.c create mode 100644 fitsy/datatable.c create mode 100644 fitsy/doc/basicval.html create mode 100644 fitsy/doc/basicval.wu create mode 100644 fitsy/doc/cardfind.html create mode 100644 fitsy/doc/cardfind.wu create mode 100644 fitsy/doc/cardfmt.html create mode 100644 fitsy/doc/cardfmt.wu create mode 100644 fitsy/doc/cardins.html create mode 100644 fitsy/doc/cardins.wu create mode 100644 fitsy/doc/cardpar.html create mode 100644 fitsy/doc/cardpar.wu create mode 100644 fitsy/doc/dataimage.html create mode 100644 fitsy/doc/dataimage.wu create mode 100644 fitsy/doc/examples.wu create mode 100644 fitsy/doc/fitsimage.html create mode 100644 fitsy/doc/fitsimage.wu create mode 100644 fitsy/doc/fitsy.html create mode 100644 fitsy/doc/fitsy.pnuts create mode 100644 fitsy/doc/fitsy.wu create mode 100644 fitsy/doc/ftimage.wu create mode 100644 fitsy/doc/fttable.wu create mode 100644 fitsy/doc/headdata.html create mode 100644 fitsy/doc/headdata.wu create mode 100644 fitsy/doc/headfile.html create mode 100644 fitsy/doc/headfile.wu create mode 100644 fitsy/doc/headfind.html create mode 100644 fitsy/doc/headfind.wu create mode 100644 fitsy/doc/headget.html create mode 100644 fitsy/doc/headget.wu create mode 100644 fitsy/doc/headimage.html create mode 100644 fitsy/doc/headimage.wu create mode 100644 fitsy/doc/headinit.html create mode 100644 fitsy/doc/headinit.wu create mode 100644 fitsy/doc/headins.html create mode 100644 fitsy/doc/headins.wu create mode 100644 fitsy/doc/headset.html create mode 100644 fitsy/doc/headset.wu create mode 100644 fitsy/doc/headtable.html create mode 100644 fitsy/doc/headtable.wu create mode 100644 fitsy/doc/imageval.html create mode 100644 fitsy/doc/imageval.wu create mode 100644 fitsy/doc/makefile-sao create mode 100644 fitsy/doc/tableval.html create mode 100644 fitsy/doc/tableval.wu create mode 100644 fitsy/fitsfile.c create mode 100644 fitsy/fitshead.c create mode 100644 fitsy/fitsimage.c create mode 100644 fitsy/fitsy.h create mode 100644 fitsy/ftacht.c create mode 100644 fitsy/ftacht2.c create mode 100644 fitsy/generic.h create mode 100644 fitsy/headdata.c create mode 100644 fitsy/headfile.c create mode 100644 fitsy/headfind.c create mode 100644 fitsy/headget.c create mode 100644 fitsy/headimage.c create mode 100644 fitsy/headinit.c create mode 100644 fitsy/headins.c create mode 100644 fitsy/headset.c create mode 100644 fitsy/headsimple.c create mode 100644 fitsy/headtable.c create mode 100644 fitsy/headwcs.c create mode 100755 fitsy/install-sh create mode 100644 fitsy/inverse.c create mode 100644 fitsy/longlong.h create mode 100644 fitsy/nd.c create mode 100644 fitsy/parse.c create mode 100644 fitsy/ptest.c create mode 100644 fitsy/tableheader.c create mode 100644 fitsy/xfile.h create mode 100644 fitsy/xos.h create mode 100755 fun2table create mode 100644 funcalc.c create mode 100644 funcalc.sed create mode 100644 funcen.c create mode 100644 funcnts.c create mode 100755 funcnts_plot.tmpl create mode 100755 funcnts_sed.tmpl create mode 100644 funcol.c create mode 100644 funcone.c create mode 100644 funcopy.c create mode 100644 fundisp.c create mode 100755 funds9.tmpl create mode 100644 funhead.c create mode 100644 funhist.c create mode 100755 funhist_plot.tmpl create mode 100644 funim.c create mode 100644 funimage.c create mode 100755 funindex.tmpl create mode 100644 funinfo.c create mode 100644 funjoin.c create mode 100644 funmainlib.c create mode 100644 funmerge.c create mode 100644 funopen.c create mode 100644 funopenp.c create mode 100644 funparam.c create mode 100644 funsky.c create mode 100644 funtab.c create mode 100644 funtable.c create mode 100755 funtbl.tmpl create mode 100644 funtclmainlib.c create mode 100644 funtest/Makefile.in create mode 100644 funtest/arg3.inc create mode 100644 funtest/asc2fits.c create mode 100644 funtest/ascii2fits.c create mode 100644 funtest/avg create mode 100644 funtest/bigfits.c create mode 100644 funtest/bpix.ev create mode 100644 funtest/cat.ls create mode 100644 funtest/cat.txt create mode 100644 funtest/comm create mode 100644 funtest/conf.h.in create mode 100644 funtest/evcol.c create mode 100644 funtest/evcre.c create mode 100644 funtest/evmerge.c create mode 100644 funtest/evmerge2.c create mode 100644 funtest/evnext.c create mode 100644 funtest/evread.c create mode 100644 funtest/evreplace.c create mode 100644 funtest/evtest.c create mode 100755 funtest/fctest create mode 100644 funtest/filt.c create mode 100644 funtest/funcalc.sed create mode 100755 funtest/funcheck create mode 100755 funtest/funchecks create mode 100755 funtest/funcones create mode 100644 funtest/fundisp1out create mode 100644 funtest/funsky.c create mode 100755 funtest/funstack create mode 100755 funtest/funtest create mode 100755 funtest/funtesti create mode 100755 funtest/funtests create mode 100755 funtest/funtexts create mode 100644 funtest/funtools1.vu create mode 100644 funtest/funtools2.vu create mode 100644 funtest/goo.ls create mode 100644 funtest/group.calc create mode 100644 funtest/imblank.c create mode 100644 funtest/imtest.c create mode 100755 funtest/install-sh create mode 100644 funtest/mif.lst create mode 100644 funtest/mif1.fits create mode 100644 funtest/mif2.fits create mode 100644 funtest/mif3.fits create mode 100644 funtest/mif4.fits create mode 100644 funtest/mkdim.c create mode 100644 funtest/mkev.c create mode 100644 funtest/mkev2.c create mode 100644 funtest/ntest.ev create mode 100755 funtest/nwcs create mode 100644 funtest/parse.in create mode 100644 funtest/pr create mode 100644 funtest/qcon.c create mode 100644 funtest/resample.fc create mode 100644 funtest/sample.fc create mode 100644 funtest/snr100.reg create mode 100644 funtest/snr400.reg create mode 100644 funtest/snr900.reg create mode 100644 funtest/swap create mode 100644 funtest/swap1 create mode 100644 funtest/t1.reg create mode 100644 funtest/t2.reg create mode 100644 funtest/t3.reg create mode 100644 funtest/t4.reg create mode 100644 funtest/tboxell.in create mode 100644 funtest/tcalc.in create mode 100644 funtest/tcols.in create mode 100644 funtest/tcone.in create mode 100755 funtest/tenv create mode 100644 funtest/test.asc create mode 100644 funtest/test.ev create mode 100644 funtest/test.fits create mode 100644 funtest/test2.ev create mode 100644 funtest/test2.raw create mode 100755 funtest/tevread create mode 100644 funtest/tfile.in create mode 100755 funtest/tfuncalc create mode 100755 funtest/tfuncnts create mode 100755 funtest/tfuncone create mode 100755 funtest/tfundisp create mode 100755 funtest/tfunhead create mode 100755 funtest/tfunimage create mode 100755 funtest/tfunmerge create mode 100755 funtest/tfuntext create mode 100755 funtest/tfunview create mode 100644 funtest/thead.in create mode 100755 funtest/timev create mode 100644 funtest/tmerge.in create mode 100644 funtest/tnum.in create mode 100644 funtest/tparen.in create mode 100644 funtest/tregions.in create mode 100644 funtest/tsections.in create mode 100644 funtest/ttext.in create mode 100644 funtest/tview.in create mode 100644 funtest/twcs.c create mode 100644 funtest/unwcs.in create mode 100644 funtest/wcs.in create mode 100644 funtest/wtest.c create mode 100644 funtest/x.fits create mode 100644 funtext.c create mode 100644 funtools.h create mode 100644 funtools.pc.in create mode 100644 funtoolsP.h create mode 100644 funtools_ds9.tmpl create mode 100644 funutil.c create mode 100644 funview.c create mode 100644 funwcs.c create mode 100644 gnu/COPYING create mode 100644 gnu/Makefile.in create mode 100644 gnu/conf.h.in create mode 100644 gnu/copyright create mode 100755 gnu/install-sh create mode 100644 gnu/sort.c create mode 100644 gnu/sorttest.c create mode 100644 gnu/system.h create mode 100755 inc.sed create mode 100755 install-sh create mode 100644 jointable.c create mode 100644 lex.calc.c create mode 100644 man/man1/funcalc.1 create mode 100644 man/man1/funcen.1 create mode 100644 man/man1/funcnts.1 create mode 100644 man/man1/funcone.1 create mode 100644 man/man1/fundisp.1 create mode 100644 man/man1/funhead.1 create mode 100644 man/man1/funhist.1 create mode 100644 man/man1/funimage.1 create mode 100644 man/man1/funindex.1 create mode 100644 man/man1/funjoin.1 create mode 100644 man/man1/funmerge.1 create mode 100644 man/man1/funsky.1 create mode 100644 man/man1/funtable.1 create mode 100644 man/man1/funtbl.1 create mode 100644 man/man3/funclose.3 create mode 100644 man/man3/funcolumnactivate.3 create mode 100644 man/man3/funcolumnlookup.3 create mode 100644 man/man3/funcolumnselect.3 create mode 100644 man/man3/funflush.3 create mode 100644 man/man3/funimageget.3 create mode 100644 man/man3/funimageput.3 create mode 100644 man/man3/funimagerowget.3 create mode 100644 man/man3/funimagerowput.3 create mode 100644 man/man3/funinfoget.3 create mode 100644 man/man3/funinfoput.3 create mode 100644 man/man3/funlib.3 create mode 100644 man/man3/funopen.3 create mode 100644 man/man3/funparamget.3 create mode 100644 man/man3/funparamput.3 create mode 100644 man/man3/funref.3 create mode 100644 man/man3/funtablerowget.3 create mode 100644 man/man3/funtablerowput.3 create mode 100644 man/man7/funcombine.7 create mode 100644 man/man7/funds9.7 create mode 100644 man/man7/funenv.7 create mode 100644 man/man7/funfiles.7 create mode 100644 man/man7/funfilters.7 create mode 100644 man/man7/funidx.7 create mode 100644 man/man7/funregions.7 create mode 100644 man/man7/funtext.7 create mode 100644 man/man7/funtools.7 create mode 100644 man/man7/funview.7 create mode 100644 man/man7/regalgebra.7 create mode 100644 man/man7/regbounds.7 create mode 100644 man/man7/regcoords.7 create mode 100644 man/man7/regdiff.7 create mode 100644 man/man7/reggeometry.7 create mode 100755 mkconfigure create mode 100755 mkfunmainlib create mode 100755 mklib create mode 100644 notes/ds9.notes create mode 100644 notes/index.notes create mode 100644 notes/mainlib.notes create mode 100644 notes/mingw.notes create mode 100644 notes/tcl.notes create mode 100644 notes/text.notes create mode 100644 notes/view.notes create mode 100644 ofuntools.h create mode 100644 pkgIndex.tcl create mode 100755 saoconfig create mode 100644 scan.c create mode 100644 search.c create mode 100644 tabcalc.c create mode 100644 tabcalc_c.h create mode 100644 tcl.m4 create mode 100644 test.tcl create mode 100755 tfunjoin create mode 100644 tmain.c create mode 100644 tmain.tcl create mode 100644 tperl.c create mode 100644 txt/bar.txt create mode 100644 txt/blank.txt create mode 100644 txt/blank2.txt create mode 100644 txt/comma.txt create mode 100644 txt/comma2.txt create mode 100644 txt/comma3.txt create mode 100644 txt/crcomma.txt create mode 100755 txt/crnl create mode 100644 txt/crspace.txt create mode 100644 txt/crtab.txt create mode 100644 txt/eot.txt create mode 100644 txt/eot2.txt create mode 100644 txt/foo1 create mode 100644 txt/foo2 create mode 100644 txt/headone.txt create mode 100644 txt/int64.fits create mode 100644 txt/int64.tab create mode 100644 txt/int64_Value.idx create mode 100644 txt/nlcomma.txt create mode 100755 txt/nlcr create mode 100644 txt/nltab.txt create mode 100644 txt/null.tab create mode 100644 txt/one.txt create mode 100644 txt/rdb.txt create mode 100644 txt/sex.tab create mode 100644 txt/space.txt create mode 100644 txt/sptab.txt create mode 100644 txt/tab.txt create mode 100644 txt/test.fits create mode 100644 txt/vis.tab create mode 100644 util/Makefile.in create mode 100644 util/NaN.h.in create mode 100644 util/ac_c_long_long.m4 create mode 100644 util/aclocal.m4 create mode 100644 util/conf.h.in create mode 100644 util/config.guess create mode 100644 util/config.sub create mode 100755 util/configure-failsafe create mode 100644 util/configure.ac create mode 100644 util/file.c create mode 100644 util/file.h create mode 100644 util/find.c create mode 100644 util/find.h create mode 100644 util/gcat.c create mode 100644 util/gio.c create mode 100644 util/gio.h create mode 100755 util/install-sh create mode 100644 util/iraf_zprocess.c create mode 100644 util/longlong.h create mode 100644 util/macro.c create mode 100644 util/macro.h create mode 100644 util/mainlib.c create mode 100644 util/mainlib.h create mode 100644 util/mkrtemp.c create mode 100644 util/mkrtemp.h create mode 100644 util/nan.c create mode 100644 util/parse.c create mode 100644 util/parse.h create mode 100644 util/prsetup.h create mode 100644 util/strtod.c create mode 100644 util/strtod.h create mode 100644 util/swap.c create mode 100644 util/swap.h create mode 100644 util/tcl.m4 create mode 100644 util/tclmainlib.c create mode 100644 util/tclmainlib.h create mode 100644 util/tlaunch.c create mode 100644 util/tlaunch2.c create mode 100644 util/tparse.c create mode 100644 util/winprocess.c create mode 100644 util/winprocess.h create mode 100644 util/word.c create mode 100644 util/word.h create mode 100644 util/xalloc.c create mode 100644 util/xalloc.h create mode 100644 util/xfileio.h create mode 100644 util/xlaunch.c create mode 100644 util/xlaunch.h create mode 100644 util/xport.h create mode 100644 util/zlib-1.2.3/ChangeLog create mode 100644 util/zlib-1.2.3/FAQ create mode 100644 util/zlib-1.2.3/INDEX create mode 100644 util/zlib-1.2.3/Makefile create mode 100644 util/zlib-1.2.3/Makefile.in create mode 100644 util/zlib-1.2.3/README create mode 100644 util/zlib-1.2.3/adler32.c create mode 100644 util/zlib-1.2.3/algorithm.txt create mode 100644 util/zlib-1.2.3/amiga/Makefile.pup create mode 100644 util/zlib-1.2.3/amiga/Makefile.sas create mode 100644 util/zlib-1.2.3/as400/bndsrc create mode 100644 util/zlib-1.2.3/as400/compile.clp create mode 100644 util/zlib-1.2.3/as400/readme.txt create mode 100644 util/zlib-1.2.3/as400/zlib.inc create mode 100644 util/zlib-1.2.3/compress.c create mode 100755 util/zlib-1.2.3/configure create mode 100644 util/zlib-1.2.3/contrib/README.contrib create mode 100644 util/zlib-1.2.3/contrib/ada/buffer_demo.adb create mode 100644 util/zlib-1.2.3/contrib/ada/mtest.adb create mode 100644 util/zlib-1.2.3/contrib/ada/read.adb create mode 100644 util/zlib-1.2.3/contrib/ada/readme.txt create mode 100644 util/zlib-1.2.3/contrib/ada/test.adb create mode 100644 util/zlib-1.2.3/contrib/ada/zlib-streams.adb create mode 100644 util/zlib-1.2.3/contrib/ada/zlib-streams.ads create mode 100644 util/zlib-1.2.3/contrib/ada/zlib-thin.adb create mode 100644 util/zlib-1.2.3/contrib/ada/zlib-thin.ads create mode 100644 util/zlib-1.2.3/contrib/ada/zlib.adb create mode 100644 util/zlib-1.2.3/contrib/ada/zlib.ads create mode 100644 util/zlib-1.2.3/contrib/ada/zlib.gpr create mode 100644 util/zlib-1.2.3/contrib/asm586/README.586 create mode 100644 util/zlib-1.2.3/contrib/asm586/match.S create mode 100644 util/zlib-1.2.3/contrib/asm686/README.686 create mode 100644 util/zlib-1.2.3/contrib/asm686/match.S create mode 100644 util/zlib-1.2.3/contrib/blast/Makefile create mode 100644 util/zlib-1.2.3/contrib/blast/README create mode 100644 util/zlib-1.2.3/contrib/blast/blast.c create mode 100644 util/zlib-1.2.3/contrib/blast/blast.h create mode 100644 util/zlib-1.2.3/contrib/blast/test.pk create mode 100644 util/zlib-1.2.3/contrib/blast/test.txt create mode 100644 util/zlib-1.2.3/contrib/delphi/ZLib.pas create mode 100644 util/zlib-1.2.3/contrib/delphi/ZLibConst.pas create mode 100644 util/zlib-1.2.3/contrib/delphi/readme.txt create mode 100644 util/zlib-1.2.3/contrib/delphi/zlibd32.mak create mode 100644 util/zlib-1.2.3/contrib/dotzlib/DotZLib.build create mode 100644 util/zlib-1.2.3/contrib/dotzlib/DotZLib.sln create mode 100644 util/zlib-1.2.3/contrib/dotzlib/DotZLib/AssemblyInfo.cs create mode 100644 util/zlib-1.2.3/contrib/dotzlib/DotZLib/ChecksumImpl.cs create mode 100644 util/zlib-1.2.3/contrib/dotzlib/DotZLib/CircularBuffer.cs create mode 100644 util/zlib-1.2.3/contrib/dotzlib/DotZLib/CodecBase.cs create mode 100644 util/zlib-1.2.3/contrib/dotzlib/DotZLib/Deflater.cs create mode 100644 util/zlib-1.2.3/contrib/dotzlib/DotZLib/DotZLib.cs create mode 100644 util/zlib-1.2.3/contrib/dotzlib/DotZLib/DotZLib.csproj create mode 100644 util/zlib-1.2.3/contrib/dotzlib/DotZLib/GZipStream.cs create mode 100644 util/zlib-1.2.3/contrib/dotzlib/DotZLib/Inflater.cs create mode 100644 util/zlib-1.2.3/contrib/dotzlib/DotZLib/UnitTests.cs create mode 100644 util/zlib-1.2.3/contrib/dotzlib/LICENSE_1_0.txt create mode 100644 util/zlib-1.2.3/contrib/dotzlib/readme.txt create mode 100644 util/zlib-1.2.3/contrib/infback9/README create mode 100644 util/zlib-1.2.3/contrib/infback9/infback9.c create mode 100644 util/zlib-1.2.3/contrib/infback9/infback9.h create mode 100644 util/zlib-1.2.3/contrib/infback9/inffix9.h create mode 100644 util/zlib-1.2.3/contrib/infback9/inflate9.h create mode 100644 util/zlib-1.2.3/contrib/infback9/inftree9.c create mode 100644 util/zlib-1.2.3/contrib/infback9/inftree9.h create mode 100644 util/zlib-1.2.3/contrib/inflate86/inffas86.c create mode 100644 util/zlib-1.2.3/contrib/inflate86/inffast.S create mode 100644 util/zlib-1.2.3/contrib/iostream/test.cpp create mode 100644 util/zlib-1.2.3/contrib/iostream/zfstream.cpp create mode 100644 util/zlib-1.2.3/contrib/iostream/zfstream.h create mode 100644 util/zlib-1.2.3/contrib/iostream2/zstream.h create mode 100644 util/zlib-1.2.3/contrib/iostream2/zstream_test.cpp create mode 100644 util/zlib-1.2.3/contrib/iostream3/README create mode 100644 util/zlib-1.2.3/contrib/iostream3/TODO create mode 100644 util/zlib-1.2.3/contrib/iostream3/test.cc create mode 100644 util/zlib-1.2.3/contrib/iostream3/zfstream.cc create mode 100644 util/zlib-1.2.3/contrib/iostream3/zfstream.h create mode 100644 util/zlib-1.2.3/contrib/masm686/match.asm create mode 100755 util/zlib-1.2.3/contrib/masmx64/bld_ml64.bat create mode 100644 util/zlib-1.2.3/contrib/masmx64/gvmat64.asm create mode 100644 util/zlib-1.2.3/contrib/masmx64/gvmat64.obj create mode 100644 util/zlib-1.2.3/contrib/masmx64/inffas8664.c create mode 100644 util/zlib-1.2.3/contrib/masmx64/inffasx64.asm create mode 100644 util/zlib-1.2.3/contrib/masmx64/inffasx64.obj create mode 100644 util/zlib-1.2.3/contrib/masmx64/readme.txt create mode 100755 util/zlib-1.2.3/contrib/masmx86/bld_ml32.bat create mode 100644 util/zlib-1.2.3/contrib/masmx86/gvmat32.asm create mode 100644 util/zlib-1.2.3/contrib/masmx86/gvmat32c.c create mode 100644 util/zlib-1.2.3/contrib/masmx86/inffas32.asm create mode 100755 util/zlib-1.2.3/contrib/masmx86/mkasm.bat create mode 100644 util/zlib-1.2.3/contrib/masmx86/readme.txt create mode 100644 util/zlib-1.2.3/contrib/minizip/ChangeLogUnzip create mode 100644 util/zlib-1.2.3/contrib/minizip/Makefile create mode 100644 util/zlib-1.2.3/contrib/minizip/crypt.h create mode 100644 util/zlib-1.2.3/contrib/minizip/ioapi.c create mode 100644 util/zlib-1.2.3/contrib/minizip/ioapi.h create mode 100644 util/zlib-1.2.3/contrib/minizip/iowin32.c create mode 100644 util/zlib-1.2.3/contrib/minizip/iowin32.h create mode 100644 util/zlib-1.2.3/contrib/minizip/miniunz.c create mode 100644 util/zlib-1.2.3/contrib/minizip/minizip.c create mode 100644 util/zlib-1.2.3/contrib/minizip/mztools.c create mode 100644 util/zlib-1.2.3/contrib/minizip/mztools.h create mode 100644 util/zlib-1.2.3/contrib/minizip/unzip.c create mode 100644 util/zlib-1.2.3/contrib/minizip/unzip.h create mode 100644 util/zlib-1.2.3/contrib/minizip/zip.c create mode 100644 util/zlib-1.2.3/contrib/minizip/zip.h create mode 100644 util/zlib-1.2.3/contrib/pascal/example.pas create mode 100644 util/zlib-1.2.3/contrib/pascal/readme.txt create mode 100644 util/zlib-1.2.3/contrib/pascal/zlibd32.mak create mode 100644 util/zlib-1.2.3/contrib/pascal/zlibpas.pas create mode 100644 util/zlib-1.2.3/contrib/puff/Makefile create mode 100644 util/zlib-1.2.3/contrib/puff/README create mode 100644 util/zlib-1.2.3/contrib/puff/puff.c create mode 100644 util/zlib-1.2.3/contrib/puff/puff.h create mode 100644 util/zlib-1.2.3/contrib/puff/zeros.raw create mode 100644 util/zlib-1.2.3/contrib/testzlib/testzlib.c create mode 100644 util/zlib-1.2.3/contrib/testzlib/testzlib.txt create mode 100644 util/zlib-1.2.3/contrib/untgz/Makefile create mode 100644 util/zlib-1.2.3/contrib/untgz/Makefile.msc create mode 100644 util/zlib-1.2.3/contrib/untgz/untgz.c create mode 100644 util/zlib-1.2.3/contrib/vstudio/readme.txt create mode 100644 util/zlib-1.2.3/contrib/vstudio/vc7/miniunz.vcproj create mode 100644 util/zlib-1.2.3/contrib/vstudio/vc7/minizip.vcproj create mode 100644 util/zlib-1.2.3/contrib/vstudio/vc7/testzlib.vcproj create mode 100644 util/zlib-1.2.3/contrib/vstudio/vc7/zlib.rc create mode 100644 util/zlib-1.2.3/contrib/vstudio/vc7/zlibstat.vcproj create mode 100644 util/zlib-1.2.3/contrib/vstudio/vc7/zlibvc.def create mode 100644 util/zlib-1.2.3/contrib/vstudio/vc7/zlibvc.sln create mode 100644 util/zlib-1.2.3/contrib/vstudio/vc7/zlibvc.vcproj create mode 100644 util/zlib-1.2.3/contrib/vstudio/vc8/miniunz.vcproj create mode 100644 util/zlib-1.2.3/contrib/vstudio/vc8/minizip.vcproj create mode 100644 util/zlib-1.2.3/contrib/vstudio/vc8/testzlib.vcproj create mode 100644 util/zlib-1.2.3/contrib/vstudio/vc8/testzlibdll.vcproj create mode 100644 util/zlib-1.2.3/contrib/vstudio/vc8/zlib.rc create mode 100644 util/zlib-1.2.3/contrib/vstudio/vc8/zlibstat.vcproj create mode 100644 util/zlib-1.2.3/contrib/vstudio/vc8/zlibvc.def create mode 100644 util/zlib-1.2.3/contrib/vstudio/vc8/zlibvc.sln create mode 100644 util/zlib-1.2.3/contrib/vstudio/vc8/zlibvc.vcproj create mode 100644 util/zlib-1.2.3/crc32.c create mode 100644 util/zlib-1.2.3/crc32.h create mode 100644 util/zlib-1.2.3/deflate.c create mode 100644 util/zlib-1.2.3/deflate.h create mode 100644 util/zlib-1.2.3/example.c create mode 100644 util/zlib-1.2.3/examples/README.examples create mode 100644 util/zlib-1.2.3/examples/fitblk.c create mode 100644 util/zlib-1.2.3/examples/gun.c create mode 100644 util/zlib-1.2.3/examples/gzappend.c create mode 100644 util/zlib-1.2.3/examples/gzjoin.c create mode 100644 util/zlib-1.2.3/examples/gzlog.c create mode 100644 util/zlib-1.2.3/examples/gzlog.h create mode 100644 util/zlib-1.2.3/examples/zlib_how.html create mode 100644 util/zlib-1.2.3/examples/zpipe.c create mode 100644 util/zlib-1.2.3/examples/zran.c create mode 100644 util/zlib-1.2.3/gzio.c create mode 100644 util/zlib-1.2.3/infback.c create mode 100644 util/zlib-1.2.3/inffast.c create mode 100644 util/zlib-1.2.3/inffast.h create mode 100644 util/zlib-1.2.3/inffixed.h create mode 100644 util/zlib-1.2.3/inflate.c create mode 100644 util/zlib-1.2.3/inflate.h create mode 100644 util/zlib-1.2.3/inftrees.c create mode 100644 util/zlib-1.2.3/inftrees.h create mode 100755 util/zlib-1.2.3/make_vms.com create mode 100644 util/zlib-1.2.3/minigzip.c create mode 100644 util/zlib-1.2.3/msdos/Makefile.bor create mode 100644 util/zlib-1.2.3/msdos/Makefile.dj2 create mode 100644 util/zlib-1.2.3/msdos/Makefile.emx create mode 100644 util/zlib-1.2.3/msdos/Makefile.msc create mode 100644 util/zlib-1.2.3/msdos/Makefile.tc create mode 100644 util/zlib-1.2.3/old/Makefile.riscos create mode 100644 util/zlib-1.2.3/old/README create mode 100644 util/zlib-1.2.3/old/descrip.mms create mode 100644 util/zlib-1.2.3/old/os2/Makefile.os2 create mode 100644 util/zlib-1.2.3/old/os2/zlib.def create mode 100644 util/zlib-1.2.3/old/visual-basic.txt create mode 100644 util/zlib-1.2.3/old/zlib.html create mode 100644 util/zlib-1.2.3/projects/README.projects create mode 100644 util/zlib-1.2.3/projects/visualc6/README.txt create mode 100644 util/zlib-1.2.3/projects/visualc6/example.dsp create mode 100644 util/zlib-1.2.3/projects/visualc6/minigzip.dsp create mode 100644 util/zlib-1.2.3/projects/visualc6/zlib.dsp create mode 100644 util/zlib-1.2.3/projects/visualc6/zlib.dsw create mode 100644 util/zlib-1.2.3/qnx/package.qpg create mode 100644 util/zlib-1.2.3/trees.c create mode 100644 util/zlib-1.2.3/trees.h create mode 100644 util/zlib-1.2.3/uncompr.c create mode 100644 util/zlib-1.2.3/win32/DLL_FAQ.txt create mode 100644 util/zlib-1.2.3/win32/Makefile.bor create mode 100644 util/zlib-1.2.3/win32/Makefile.emx create mode 100644 util/zlib-1.2.3/win32/Makefile.gcc create mode 100644 util/zlib-1.2.3/win32/Makefile.msc create mode 100644 util/zlib-1.2.3/win32/VisualC.txt create mode 100644 util/zlib-1.2.3/win32/zlib.def create mode 100644 util/zlib-1.2.3/win32/zlib1.rc create mode 100644 util/zlib-1.2.3/zconf.h create mode 100644 util/zlib-1.2.3/zconf.in.h create mode 100644 util/zlib-1.2.3/zlib.3 create mode 100644 util/zlib-1.2.3/zlib.h create mode 100644 util/zlib-1.2.3/zutil.c create mode 100644 util/zlib-1.2.3/zutil.h create mode 100644 util/zprocess.c create mode 100644 util/zprocess.h create mode 100644 wcs/COPYING create mode 100644 wcs/Files create mode 100644 wcs/Makefile-orig create mode 100644 wcs/Makefile.in create mode 100644 wcs/NEWS create mode 100644 wcs/Readme create mode 100644 wcs/cel.c create mode 100644 wcs/conf.h.in create mode 100644 wcs/config.guess create mode 100644 wcs/config.sub create mode 100755 wcs/configure-failsafe create mode 100644 wcs/configure.ac create mode 100644 wcs/dateutil.c create mode 100644 wcs/distort.c create mode 100644 wcs/dsspos.c create mode 100644 wcs/fileutil.c create mode 100644 wcs/fitsfile.c create mode 100644 wcs/fitsfile.h create mode 100644 wcs/fitshead.h create mode 100644 wcs/hget.c create mode 100644 wcs/hput.c create mode 100644 wcs/iget.c create mode 100644 wcs/imhfile.c create mode 100644 wcs/imio.c create mode 100644 wcs/imio.h create mode 100755 wcs/install-sh create mode 100644 wcs/lin.c create mode 100644 wcs/platepos.c create mode 100644 wcs/poly.c create mode 100644 wcs/proj.c create mode 100644 wcs/slasubs.c create mode 100644 wcs/sph.c create mode 100644 wcs/tnxpos.c create mode 100644 wcs/wcs.c create mode 100644 wcs/wcs.h create mode 100644 wcs/wcscon.c create mode 100644 wcs/wcsinit.c create mode 100644 wcs/wcslib.c create mode 100644 wcs/wcslib.h create mode 100644 wcs/wcstrig.c create mode 100644 wcs/worldpos.c create mode 100644 wcs/zpxpos.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b31e331 --- /dev/null +++ b/.gitignore @@ -0,0 +1,45 @@ +*.[oa] +*~ +*.so +*.bak +*.pyc +*-orig +*-sav +foo* +goo* +node.log +Makefile +conf.h +config.status +config.log +config.cache +debug.html +js9 +js9helper.pc +.DS_Store +funcalc +funcen +funcnts +funcnts.plot +funcnts.sed +funcone +fundisp +funds9 +funhead +funhist +funhist.plot +funimage +funindex +funjoin +funmerge +funsky +funtable +funtbl +funtools.ds9 +funtools.pc +gcat +configure +gnu/_funsort +util/NaN.h +autom4te.cache +a.out.dSYM diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..b1e3f5a --- /dev/null +++ b/COPYING @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..6301ff9 --- /dev/null +++ b/INSTALL @@ -0,0 +1,312 @@ +Quick Summary +============= + +To build and install the Funtools package, simply execute: + + ./mkconfigure # generate all configure scripts + ./configure # site-specific configuration + make # build the software + make install # install it + make clean # clean up unneeded temp files + +The configure scripts are not part of the GitHub repository, so you must +generate them for your site (you might need to install autoconf for this +purpose): + + ./mkconfigure + +You might want to install in a directory other than /usr/local, so as not to +require root access. To do this, configure for a different install directory: + + ./configure --prefix= +e.g., + ./configure --prefix=/soft/saord + +Programs will be installed in /soft/saord/bin, libraries in /soft/saord/lib, +and include files in /soft/saord/include. Indeed, we do this at SAO and +recommend it as a general rule, in order to keep SAORD software in one place +that does not conflict with other installations. Note that you will need to +add the bin directory to your path. + +The build ("make") takes only a minute or so on modern machines. To +monitor its progress and/or check for errors, redirect output to a file +and use the 'tail' command: + + make >& foo.log &; tail -f foo.log # csh +or + make 1>foo.log 2>&1 &; tail -f foo.log # sh, bash + + +NB: Windows users +================= + +To build funtools on a Windows platform, you first need to install +the Cygwin package from: + + http://cygwin.com/ + +From the Web page: + + Cygwin is a Linux-like environment for Windows. It consists of two + parts: A DLL (cygwin1.dll) which acts as a Linux API emulation layer + providing substantial Linux API functionality. A collection of tools + which provide Linux look and feel. + +When installing cygwin, make sure you install 'gcc' and 'make' from the +Development package. I think that's all you need ... + +Details of Installation +======================= + + + +NB: These are generic installation instructions, modified for Funtools. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, a file +`config.cache' that saves the results of its tests to speed up +reconfiguring, and a file `config.log' containing compiler output +(useful mainly for debugging `configure'). + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If at some point `config.cache' +contains results you don't want to keep, you may remove or edit it. + + The file `configure.in' is used to create `configure' by a program +called `autoconf'. You only need `configure.in' if you want to change +it or regenerate `configure' using a newer version of `autoconf'. + +The simplest way to compile this package is: + + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 1. `cd' to the directory containing the package's source code and type + "./configure". This runs a configuration script created by GNU + autoconf, which configures Funtools for your system and creates a + Makefile. The configure script allows you to customize the Funtools + configuration for your site; for details on how you can do this, + type "./configure -help" or refer to the autoconf documentation (not + included here). The Funtools "configure" script supports the following + special switch(es) in addition to the standard ones: + + --enable-shared=yes|link|no + Build shared libraries in addition to the + default static library. There are two options: + + If the value is "yes", shared libraries are + built but not used to link xpa programs. + + If the value is "link", shared libraries are + used to link xpa programs. If therefore becomes + your responsibility to put the shared library + where it can be found (or use LD_LIBRARY_PATH). + + --enable-dl=yes|no + With gcc available, perform on-the-fly filtering + by compiling a shared object and dynamically + loading it into the executable. The default is + to compile and link a separate slave program. + (Surprisingly, processing speed is about the + same for both methods.) + + --enable-mainlib=yes|no + Build funtools mainlib support, which allows + user programs to call funtools as subroutines. + This is an experimental interface. + + Standard options are listed below. the most important of which + is --prefix (to specify where to install) and --exec-prefix (where to + install executables, if the top level is different from where libraries + and include files are being installed. At SAO, we just use --prefix. + We recommend --prefix be set to a directory that will hold saord software + (e.g., --prefix=/soft/saord) in order to make management of our software + easier. + + NB: be sure to use only absolute path names (those starting with "/") + in the --prefix and --exec_prefix options. (The configure options we + use at SAO for various machines are given as examples in the script + file called "saoconfig" in this directory.) + + NB: Please avoid use of --prefix with 'make install' to change the + install directory. We use the original value of --prefix to determine + where compiled objects are located for linking slave filter programs. + The slave will look in that directory for imregions.o and evregions.o. + If you change the install directory, you will not be able to use these + precompiled objects. Instead, each filter will have to recompile the + region code. + + Compiler flags can be placed on the configure command line after the + switches. For example, to use the icc compiler under Linux, you can + configure this way: + + ./configure --prefix=... CC=icc CFLAGS="..." + + If you are going to be dealing with data files larger than 2Gb, + you will need to build in large file support. For gcc and many other + compilers, this is done using the following CFLAGS: + + ./configure CFLAGS="-D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64" + + Of course, you can put other switches into CFLAGS as needed: + + ./configure CFLAGS="-D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -Wall -g" + + 2. Type `make' to compile the package. This will create the libfuntools.a + library and the Funtools utility programs (funcnts, fundisp, etc.) + + 3. You can build the libxpa.so shared library manually by executing: + + make shlib + + at this point. + + 4. Type "make install" to install Funtools libraries and binaries in + standard places. You'll need write permission on the installation + directories to do this. The installation directories are + determined by the "configure" script and may be specified with + the --prefix option to "configure". See the Makefile for information + on what directories were chosen. + + 5. There are .html help files in the doc directory. You can copy + these files to a more convenient location, if you like. We + did not automate this step because we did not know where to + copy these files by default. (NB: The help.html file is the + top level index file.) + + 6. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make Distclean'. The latter + also removes all Makefiles (except the one at the top level). + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. You can give `configure' +initial values for variables by setting them in the environment: + + ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix + +You also can use this facility to specify a compiler other than the default +gcc (if it exists). + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/lib', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH': + +e.g., + ./configure --prefix=/soft/saord + +Programs will be installed in /soft/saord/bin, libraries in /soft/saord/lib, +and include files in /soft/saord/include. We recommend this as a general rule, +in order to keep SAORD software in one place that does not conflict with other +installations. Note that you will need to add the bin directory to your path. + + You can specify separate installation prefixes for architecture-specific +files and architecture-independent files. If you give `configure' the option +`--exec-prefix=PATH', the package will use PATH as the prefix for installing +programs and libraries. Documentation and other data files will still use the +regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=PATH' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + +Specifying the System Type +========================== + + There may be some features `configure' can not figure out +automatically, but needs to determine by the type of host the package +will run on. Usually `configure' can figure that out, but if it prints +a message saying it can not guess the host type, give it the +`--host=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name with three fields: + CPU-COMPANY-SYSTEM + +See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the host type. + + If you are building compiler tools for cross-compiling, you can also +use the `--target=TYPE' option to select the type of system they will +produce code for and the `--build=TYPE' option to select the type of +system on which you are compiling the package. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Operation Controls +================== + + `configure' recognizes the following options to control how it +operates. + +`--cache-file=FILE' + Use and save the results of the tests in FILE instead of + `./config.cache'. Set FILE to `/dev/null' to disable caching, for + debugging `configure'. + +`--help' + Print a summary of the options to `configure', and exit. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--version' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`configure' also accepts some other, not widely useful, options. + +If you have questions, please contact us at: saord@cfa.harvard.edu. + + Eric Mandel + diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..f935b9d --- /dev/null +++ b/Makefile.in @@ -0,0 +1,754 @@ +# +# This file is a Makefile for Funtools. If it has the name "Makefile.in" +# then it is a template for a Makefile; to generate the actual Makefile, +# run "./configure", which is a configuration script generated by the +# "autoconf" program (constructs like "@foo@" will get replaced in the +# actual Makefile. +# + +PACKAGE = @PACKAGE_NAME@ +VERSION = @PACKAGE_VERSION@ + +DISTNAME = funtools-${VERSION} +DISTDIR = ../export/${DISTNAME} +FTPDIR = ../ftp + +#---------------------------------------------------------------- +# Things you can change to personalize the Makefile for your own +# site (you can make these changes in either Makefile.in or +# Makefile, but changes to Makefile will get lost if you re-run +# the configuration script). +#---------------------------------------------------------------- + +# Default top-level directories in which to install architecture- +# specific files (exec_prefix) and machine-independent files such +# as scripts (prefix). The values specified here may be overridden +# at configure-time with the --exec-prefix and --prefix options +# to the "configure" script. + +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +# The following definition can be set to non-null for special systems +# like AFS with replication. It allows the pathnames used for installation +# to be different than those used for actually reference files at +# run-time. INSTALL_ROOT is prepended to $prefix and $exec_prefix +# when installing files. +INSTALL_ROOT = $(DESTDIR) + +# Directory in which to install the .a or .so binary for the FUNTOOLS library: +LIB_INSTALL_DIR = $(INSTALL_ROOT)$(exec_prefix)/lib + +# Directory in which to install the program wish: +BIN_INSTALL_DIR = $(INSTALL_ROOT)$(exec_prefix)/bin + +# Directory in which to install the funtools.h include file: +INCLUDE_INSTALL_DIR = $(INSTALL_ROOT)$(prefix)/include/funtools + +# Top-level directory for manual entries: +MAN_INSTALL_DIR = $(INSTALL_ROOT)$(prefix)/share/man + +# Top-level directory for share entries: +MAN_SHARE_DIR = $(INSTALL_ROOT)$(prefix)/share/funtools + +# util files are in the util subdirectory +UTIL_INC = -I./util +# UTIL_LIBS = -L./util -lutil + +# fitsy files are in the fitsy subdirectory +FITSY_INC = -I./fitsy +# FITSY_LIBS = -L./fitsy -lfitsy + +# wcs files are in the wcs subdirectory +WCS_INC = -I./wcs +# WCS_LIBS = -L./wcs -lwcs + +# filter files are in the filter subdirectory +FILTER_INC = -I./filter +# FILTER_LIBS = -L./filter -lfilter + +# extra includes for compiling +INCLUDES = $(UTIL_INC) $(FILTER_INC) $(WCS_INC) $(FITSY_INC) + +# extra libs +EXTRA_LIBS = @EXTRA_LIBS@ + +# the full set of libraries for linking +LIBS = $(UTIL_LIBS) $(FILTER_LIBS) $(WCS_LIBS) $(FITSY_LIBS) \ + $(EXTRA_LIBS) -lm + +# To change the compiler switches, for example to change from -O +# to -g, change the following line: +CFLAGS = @CFLAGS@ + +# To add ld switches, change the following line: +LDFLAGS = @LDFLAGS@ + +# whether to set the FPU in double round mode +USE_FPU_DOUBLE = @USE_FPU_DOUBLE@ + +# Some versions of make, like SGI's, use the following variable to +# determine which shell to use for executing commands: +SHELL = /bin/sh + +# extra modules added by configure.in to fix OS bugs +EXTRA_OBJS = @EXTRA_OBJS@ + +# special definitions for funcalc (based on filter configuration) +FUNCALC_CC = @FILTER_CC@ +FUNCALC_CFLAGS = @FILTER_CFLAGS@ + +# if enabled-shared was specified, this will exand to "shlib" and trigger +# building of the shared library +DOSHARED = @DOSHARED@ +DOMAINLIB = @DOMAINLIB@ + +# There are just too many different versions of "install" around; +# better to use the install-sh script that comes with the distribution, +# which is slower but guaranteed to work. + +INSTALL = @srcdir@/install-sh -c +INSTALL_PROGRAM = ${INSTALL} +INSTALL_DATA = ${INSTALL} -m 644 + +# which awk-like program do we have? +PRE= @PRE@ +POST= @POST@ +AWK = @AWK@ +PIPEGLUE = @PIPEGLUE@ +GUNZIP = @GUNZIP@ +GNUPLOT = @GNUPLOT@ + +#---------------------------------------------------------------- +# The information below is modified by the configure script when +# Makefile is generated from Makefile.in. You shouldn't normally +# modify any of this stuff by hand. +#---------------------------------------------------------------- + +AC_FLAGS = @DEFS@ +RANLIB = @RANLIB@ +EXE = @EXEEXT@ + +#---------------------------------------------------------------- +# The information below should be usable as is. The configure +# script won't modify it and you shouldn't need to modify it +# either. +#---------------------------------------------------------------- + +CC = @CC@ + +CC_SWITCHES = -I. ${CFLAGS} ${CPPFLAGS} @USE_DL@ ${INCLUDES} ${AC_FLAGS} + +DEPEND_SWITCHES = -I. ${CFLAGS} ${INCLUDES} ${AC_FLAGS} + +SRCS = funcol.c funcopy.c funtab.c funim.c funinfo.c \ + funopen.c funopenp.c funparam.c funtext.c funwcs.c \ + funview.c funutil.c + +OBJS = funcol.o funcopy.o funtab.o funim.o funinfo.o \ + funopen.o funopenp.o funparam.o funtext.o funwcs.o \ + funview.o funutil.o + +# these are all the modules going into the "normal" funtools library +LIBOBJS = ${OBJS} + +# the default library for this package +DEFLIB = @DEFLIB@ + +# the actual library we are building (if this is a subpackage) +LIB = @LIB@ + +# this is used in the link line +# LLIB = $(LIB) +LLIB = @LLIB@ + +# libraries containing main as subroutines +MAINLIB = lib$(PACKAGE)MainLib.a + +PROGS = funcalc funcen funcnts funcone fundisp funhead funhist \ + funimage funjoin funmerge funsky funtable + +MAINLIBOBJS = funcalc_main.o funcen_main.o funcnts_main.o funcone_main.o \ + fundisp_main.o funhead_main.o funhist_main.o \ + funimage_main.o funmerge_main.o funsky_main.o funtable_main.o \ + funjoin_main.o + +PROGS2 = _sort + +TEMPLATES = funcnts_plot.tmpl funhist_plot.tmpl funcnts_sed.tmpl \ + funtools_ds9.tmpl funds9.tmpl funtbl.tmpl funindex.tmpl + +SCRIPTS = funcnts.plot funhist.plot funcnts.sed funds9 funtbl funindex + +DS9HELPERS = funtools.ds9 + +FILES = funcalc.sed + +DEVEL = + +# Subdirectories to run make in for the primary targets. + +SUBLIBS = util fitsy wcs filter + +SUBDIRS = $(SUBLIBS) gnu funtest faq + +all: lib progs progs2 scripts ds9helpers + +progs: $(PROGS) + +progs2: $(PROGS2) + +scripts: $(SCRIPTS) + +ds9helpers: $(DS9HELPERS) + +devel: $(DEVEL) + +libutil: FORCE + @(echo Making libutil.a in util ...; \ + cd util; $(MAKE) libutil; mv libutil.a ..) + +sublib: FORCE + @for dir in $(SUBLIBS); do \ + echo " "; \ + echo Making library in $$dir ...; \ + (cd $$dir; $(MAKE)) ; \ + done + +lib: $(LIB) $(DOMAINLIB) $(DOSHARED) + +$(LIB): sublib $(LIBOBJS) + ar cruv $(LIB) $(LIBOBJS) + $(RANLIB) $(LIB) + +funmainlib.c: $(MAINLIBOBJS) mkfunmainlib + echo $(PROGS) | ./mkfunmainlib > funmainlib.c; + +shlib: sublib $(LIBOBJS) + @(rm -rf $(PACKAGE)tmp; mkdir $(PACKAGE)tmp; \ + (cd $(PACKAGE)tmp && ar x ../$(LIB)); \ + CC='$(CC)' CXX=$(CXX) \ + ./mklib -o $(PACKAGE) $(PACKAGE)tmp/*.o; \ + rm -rf $(PACKAGE)tmp;) + +mainlib: $(MAINLIBOBJS) funmainlib.o lex.calc.o + @(ar cruv lib$(PACKAGE)MainLib.a \ + $(MAINLIBOBJS) funmainlib.o lex.calc.o; \ + $(RANLIB) lib$(PACKAGE)MainLib.a) + +shmainlib: mainlib + @(rm -rf $(PACKAGE)tmp; mkdir $(PACKAGE)tmp; \ + (cd $(PACKAGE)tmp && ar x ../lib$(PACKAGE)MainLib.a); \ + CC='$(CC)' CXX='$(CXX)' \ + ./mklib -o $(PACKAGE)MainLib -L. -lfuntools $(PACKAGE)tmp/*.o;\ + rm -rf $(PACKAGE)tmp;) + +tclfun: $(LIB) tclmainlib.o tclfun.o + @(ar cruv libtclfun.a tclmainlib.o tclfun.o; \ + $(RANLIB) libtclfun.a) + +shtclfun: tclfun + @(rm -rf $(PACKAGE)tmp; mkdir $(PACKAGE)tmp; \ + (cd $(PACKAGE)tmp && ar x ../$(LIB) && ar x ../libtclfun.a); \ + CC='$(CC)' CXX='$(CXX)' \ + ./mklib -o tclfun $(PACKAGE)tmp/*.o; \ + rm -rf $(PACKAGE)tmp; \ + test -r pkgIndex.tcl && mv pkgIndex.tcl pkgIndex.tcl-old; \ + SHLIB=libtclfun.so; \ + test -r libtclfun.dylib && SHLIB=libtclfun.dylib; \ + echo "pkg_mkIndex -direct . $${SHLIB}; exit" | tclsh;) + +tclfun.c: FORCE + echo $(PROGS) | ./mkfunmainlib -tcl > tclfun.c + + +tclmainlib.o: util/tclmainlib.c + $(CC) -c $(CC_SWITCHES) util/tclmainlib.c + +funcalc: funcalc.o lex.calc.o lib + $(CC) $(LDFLAGS) funcalc.o lex.calc.o -o funcalc \ + $(LLIB) $(LIBS) + +funcen: funcen.o lib + $(CC) $(LDFLAGS) funcen.o -o funcen $(LLIB) $(LIBS) + +funcnts: funcnts.o lib + $(CC) $(LDFLAGS) funcnts.o -o funcnts $(LLIB) $(LIBS) + +funcone: funcone.o lib + $(CC) $(LDFLAGS) funcone.o -o funcone $(LLIB) $(LIBS) + +fundisp: fundisp.o lib + $(CC) $(LDFLAGS) fundisp.o -o fundisp $(LLIB) $(LIBS) + +funhist: funhist.o lib + $(CC) $(LDFLAGS) funhist.o -o funhist $(LLIB) $(LIBS) + +funhead: funhead.o lib + $(CC) $(LDFLAGS) funhead.o -o funhead $(LLIB) $(LIBS) + +funimage: funimage.o lib + $(CC) $(LDFLAGS) funimage.o -o funimage $(LLIB) $(LIBS) + +funjoin: funjoin.o lib + $(CC) $(LDFLAGS) funjoin.o -o funjoin $(LLIB) $(LIBS) + +funmerge: funmerge.o lib + $(CC) $(LDFLAGS) funmerge.o -o funmerge $(LLIB) $(LIBS) + +funsky: funsky.o lib + $(CC) $(LDFLAGS) funsky.o -o funsky $(LLIB) $(LIBS) + +funtable: funtable.o lib + $(CC) $(LDFLAGS) funtable.o -o funtable $(LLIB) $(LIBS) + +_sort: FORCE + @(echo " "; echo "Making in gnu ..."; cd gnu; $(MAKE)) + +funcalc_main.o: funcalc.c + $(CC) -c $(CC_SWITCHES) -Dmain="funcalc_main" \ + -o funcalc_main.o funcalc.c +funcen_main.o: funcen.c + $(CC) -c $(CC_SWITCHES) -Dmain="funcen_main" \ + -o funcen_main.o funcen.c + +funcnts_main.o: funcnts.c + $(CC) -c $(CC_SWITCHES) -Dmain="funcnts_main" \ + -o funcnts_main.o funcnts.c +funcone_main.o: funcone.c + $(CC) -c $(CC_SWITCHES) -Dmain="funcone_main" \ + -o funcone_main.o funcone.c +fundisp_main.o: fundisp.c + $(CC) -c $(CC_SWITCHES) -Dmain="fundisp_main" \ + -o fundisp_main.o fundisp.c +funhist_main.o: funhist.c + $(CC) -c $(CC_SWITCHES) -Dmain="funhist_main" \ + -o funhist_main.o funhist.c +funhead_main.o: funhead.c + $(CC) -c $(CC_SWITCHES) -Dmain="funhead_main" \ + -o funhead_main.o funhead.c +funimage_main.o: funimage.c + $(CC) -c $(CC_SWITCHES) -Dmain="funimage_main" \ + -o funimage_main.o funimage.c +funjoin_main.o: funjoin.c + $(CC) -c $(CC_SWITCHES) -Dmain="funjoin_main" \ + -o funjoin_main.o funjoin.c +funmerge_main.o: funmerge.c + $(CC) -c $(CC_SWITCHES) -Dmain="funmerge_main" \ + -o funmerge_main.o funmerge.c +funsky_main.o: funsky.c + $(CC) -c $(CC_SWITCHES) -Dmain="funsky_main" \ + -o funsky_main.o funsky.c + +funtable_main.o: funtable.c + $(CC) -c $(CC_SWITCHES) -Dmain="funtable_main" \ + -o funtable_main.o funtable.c + +funcnts.plot: funcnts_plot.tmpl + sed -e 's#AWK#$(AWK)#g' funcnts_plot.tmpl > funcnts.plot + chmod +x funcnts.plot + +funhist.plot: funhist_plot.tmpl + sed -e 's#AWK#$(AWK)#g' funhist_plot.tmpl > funhist.plot + chmod +x funhist.plot + +funds9: funds9.tmpl + sed -e 's#AWK#$(AWK)#g;s#GNUPLOT#$(GNUPLOT)#g' funds9.tmpl > funds9 + chmod +x funds9 + +funtbl: funtbl.tmpl + sed -e 's#AWK#$(AWK)#g;' funtbl.tmpl > funtbl + chmod +x funtbl + +funindex: funindex.tmpl + cp -p funindex.tmpl funindex + chmod +x funindex + +funcnts.sed: funcnts_sed.tmpl + cp funcnts_sed.tmpl funcnts.sed + chmod +x funcnts.sed + +funtools.ds9: funtools_ds9.tmpl + sed -e 's#PRE#$(PRE)#g;s#POST#$(POST)#g;s#GUNZIP#$(GUNZIP)#g' funtools_ds9.tmpl > funtools.ds9 + +diff: + @-(for file in "`ls *.c`"; \ + do \ + echo $$file; \ + diff /soft/saord/funtools-*/$$file .; \ + done;) + +install:: install-binaries + +install:: $(DOSHARED)_install + +install:: + @for dir in $(SUBDIRS); do \ + echo " "; \ + echo Installing in $$dir ...; \ + (cd $$dir; $(MAKE) INSTALL_ROOT=$(INSTALL_ROOT) INCLUDE_INSTALL_DIR=$(INCLUDE_INSTALL_DIR) $@) ; \ + done + +install:: install-man + +install:: install-share + +install:: install-data + +FORCE: + +# Note: before running ranlib below, must cd to target directory because +# some ranlibs write to current directory, and this might not always be +# possible (e.g. if installing as root). + +# this nop-op gets executed if we are not building shared libraries +_install: + +shlib_install: + @-(for i in `ls *.so* *.dylib *.sl 2>/dev/null` ; \ + do \ + if [ -h $$i ] ; then \ + echo "Installing link $$i" ; \ + tar cf - $$i | (cd $(LIB_INSTALL_DIR); tar xf -) ; \ + else \ + echo "Installing $$i" ; \ + $(INSTALL_DATA) $$i $(LIB_INSTALL_DIR)/$$i ; \ + chmod 555 $(LIB_INSTALL_DIR)/$$i; \ + fi; \ + done;) + +install-binaries: lib $(PROGS) $(SCRIPTS) $(DS9HELPERS) + @for i in $(LIB_INSTALL_DIR) $(INCLUDE_INSTALL_DIR) $(BIN_INSTALL_DIR) ; \ + do \ + if [ ! -d $$i ] ; then \ + echo "Making directory $$i"; \ + mkdir -p $$i; \ + chmod 755 $$i; \ + else true; \ + fi; \ + done; + @if [ "$(LIB)" ] ; then \ + XLIB=`basename $(LIB)`; \ + echo "Installing $$XLIB"; \ + $(INSTALL_DATA) $$XLIB $(LIB_INSTALL_DIR)/$$XLIB; \ + (cd $(LIB_INSTALL_DIR); $(RANLIB) $$XLIB); \ + chmod 555 $(LIB_INSTALL_DIR)/$$XLIB; \ + fi; + @echo "Installing funtools.h" + @$(INSTALL_DATA) funtools.h $(INCLUDE_INSTALL_DIR)/funtools.h + @echo "Installing funtoolsP.h" + @$(INSTALL_DATA) funtoolsP.h $(INCLUDE_INSTALL_DIR)/funtoolsP.h + @for i in $(PROGS) ; \ + do \ + echo "Installing $$i$(EXE)" ; \ + $(INSTALL_PROGRAM) $$i$(EXE) $(BIN_INSTALL_DIR)/$$i$(EXE) ; \ + done; + @for i in $(SCRIPTS) ; \ + do \ + echo "Installing $$i" ; \ + $(INSTALL_PROGRAM) $$i $(BIN_INSTALL_DIR)/$$i ; \ + done; + @for i in $(DS9HELPERS) ; \ + do \ + echo "Installing $$i" ; \ + $(INSTALL_DATA) $$i $(BIN_INSTALL_DIR)/$$i ; \ + done; + @for i in $(FILES) ; \ + do \ + echo "Installing $$i" ; \ + $(INSTALL_DATA) $$i $(BIN_INSTALL_DIR)/$$i ; \ + done; + +install-man: + @if [ ! -d $(MAN_INSTALL_DIR) ] ; then \ + echo "Making directory $(MAN_INSTALL_DIR)"; \ + mkdir $(MAN_INSTALL_DIR); \ + chmod 755 $(MAN_INSTALL_DIR); \ + else true; \ + fi; + @-(for i in `ls ./man/man?/*.?` ; \ + do \ + B=`basename $$i`; \ + E=`echo $$i | awk -F. '{print $$NF}'`; \ + M="$(MAN_INSTALL_DIR)/man$$E"; \ + if [ ! -d $$M ] ; then \ + echo "Making directory $$M"; \ + mkdir $$M; \ + chmod 755 $$M; \ + else true; \ + fi; \ + echo "Installing $$B" ; \ + $(INSTALL_DATA) $$i $$M/$$B; \ + done;) + +install-share: + @if [ ! -d $(MAN_SHARE_DIR) ] ; then \ + echo "Making directory $(MAN_SHARE_DIR)"; \ + mkdir -p $(MAN_SHARE_DIR); \ + chmod 755 $(MAN_SHARE_DIR); \ + else true; \ + fi; + @-(for i in `ls ./doc/sman/fun?.*` ; \ + do \ + B=`basename $$i`; \ + echo "Installing $$B" ; \ + $(INSTALL_DATA) $$i $(MAN_SHARE_DIR)/$$B; \ + done;) + +install-data: install-pkgconfig + +install-pkgconfig: + @-(mkdir -p $(LIB_INSTALL_DIR)/pkgconfig; \ + echo "Installing funtools.pc" ; \ + $(INSTALL_DATA) funtools.pc $(LIB_INSTALL_DIR)/pkgconfig;) + +Makefile: Makefile.in + $(SHELL) config.status + +RM = rm -f + +topclean: + $(RM) *.a *.so *.so.? *.so.?.? *.o *.dylib \ + $(PROGS) tmain \ + $(SCRIPTS) $(DS9HELPERS) \ + $(DEVEL) *.exe \ + core core.[0-9]* errs *pure* .nfs* \ + foo* *~ *.log \#* TAGS *.E a.out errors \ + gmon.out *.pg *.bak \ + config.info config.log \ + doc/*~ doc/*.bak + $(RM) -r autom4te.cache + +binclean: + $(RM) ./lib/* ./include/* ./bin/* + +subclean: + for dir in $(SUBDIRS); do \ + echo making clean in subdir $$dir ; \ + (cd $$dir; if [ -f Makefile ]; then $(MAKE) clean; fi); \ + done + +clean: topclean binclean subclean + +pclean: + $(RM) $(PROGS) $(DEVEL) + +distclean: clean + $(RM) Makefile config.status config.cache config.log funtools.pc + +Distclean: distclean + for dir in $(SUBDIRS); do \ + echo making clean in $$dir ; \ + (cd $$dir; if [ -f Makefile ]; then $(MAKE) distclean; fi); \ + done + + +depend: + makedepend -- $(DEPEND_SWITCHES) -- $(SRCS) + +.c.o: + $(CC) -c $(CC_SWITCHES) $< + +funopen.o: funopen.c funtools.h funtoolsP.h +funparam.o: funparam.c funtools.h funtoolsP.h +funim.o: funim.c funtools.h funtoolsP.h +funtab.o: funtab.c funtools.h funtoolsP.h +funcol.o: funcol.c funtools.h funtoolsP.h +funcopy.o: funcopy.c funtools.h funtoolsP.h +funutil.o: funutil.c funtools.h funtoolsP.h +funview.o: funview.c funtools.h funtoolsP.h +funwcs.o: funwcs.c funtools.h funtoolsP.h +funinfo.o: funinfo.c funtools.h funtoolsP.h +funimage.o: funimage.c funtools.h funtoolsP.h +funhist.o: funhist.c funtools.h funtoolsP.h +fundisp.o: fundisp.c funtools.h funtoolsP.h +funhead.o: funhead.c funtools.h funtoolsP.h +funcnts.o: funcnts.c funtools.h funtoolsP.h +funcen.o: funcen.c funtools.h funtoolsP.h +funcone.o: funcone.c funtools.h funtoolsP.h +funjoin.o: funjoin.c funtools.h funtoolsP.h +funmerge.o: funmerge.c funtools.h funtoolsP.h +funsky.o: funsky.c funtools.h funtoolsP.h +funtable.o: funtable.c funtools.h funtoolsP.h chandra.h +funcalc.o: funcalc.c calc.h funtools.h funtoolsP.h + $(CC) -c $(CC_SWITCHES) $< \ + -DFUN_INCLUDE="\"-I${prefix}/include\"" \ + -DFUNCALC_CC="$(FUNCALC_CC)" \ + -DFUNCALC_CFLAGS="$(FUNCALC_CFLAGS)" \ + -DFUN_LIB="\"-L${exec_prefix}/lib -lfuntools ${EXTRA_LIBS} -lm\"" +lex.calc.o: lex.calc.c tabcalc_c.h + +headers: tabcalc_c.h +tabcalc_c.h: tabcalc.c + $(RM) tabcalc_c.h + ./inc.sed TABCALC_C < tabcalc.c > tabcalc_c.h + +# remake the parser +LEX = flex -Pcalc + +parser: calc.l + @($(LEX) calc.l; \ + sed "s/yytext_ptr/calctext_ptr/g" < lex.calc.c > nlex.calc.c; \ + mv nlex.calc.c lex.calc.c) + +funtools.h: configure.ac + @($(RM) -r ofuntools.h; \ + MAJOR=`echo "${VERSION}" | awk -F. '{print $$1}'`; \ + MINOR=`echo "${VERSION}" | awk -F. '{print $$2}'`; \ + PATCH=`echo "${VERSION}" | awk -F. '{print $$3}'`; \ + sed "s/^#define FUN_VERSION.*/#define FUN_VERSION \"$(VERSION)\"/;s/^#define FUN_MAJOR_VERSION.*/#define FUN_MAJOR_VERSION $${MAJOR}/;s/^#define FUN_MINOR_VERSION.*/#define FUN_MINOR_VERSION $${MINOR}/;s/^#define FUN_PATCH_LEVEL.*/#define FUN_PATCH_LEVEL $${PATCH}/;" < funtools.h > nfuntools.h; \ + mv funtools.h ofuntools.h; \ + mv nfuntools.h funtools.h) + + +# +# Target to create a proper FUNTOOLS distribution from information in the +# master source directory. DISTDIR must be defined to indicate where +# to put the distribution. DISTDIR must be an absolute path name. +# + +configure: configure.ac + autoconf + +Configure: FORCE + @for dir in $(SUBDIRS); do \ + if [ -x $$dir/configure ]; then \ + echo " "; \ + echo Autoconf in $$dir ...; \ + (cd $$dir; autoconf) ; \ + fi; \ + done + +Confiles: + @(for dir in $(SUBDIRS); do \ + echo " "; \ + echo Copying configure files to $$dir ...; \ + cp -p aclocal.m4 tcl.m4 gcc33.m4 \ + conf.h.in config.sub config.guess install-sh $$dir; \ + done) + +dist: configure + ($(RM) -r $(DISTDIR); \ + mkdir $(DISTDIR); \ + cp -p README INSTALL COPYING $(DISTDIR)/.; \ + cp -p *.c *.h *.l $(DISTDIR)/.; \ + cp -p Makefile.in $(DISTDIR)/.; \ + chmod 664 $(DISTDIR)/Makefile.in; \ + cp -p conf.h.in $(DISTDIR)/.; \ + chmod 664 $(DISTDIR)/conf.h.in; \ + cp -p configure.ac $(DISTDIR)/.; \ + chmod 644 $(DISTDIR)/configure.ac; \ + cp -p *.m4 $(DISTDIR)/.; \ + chmod 644 $(DISTDIR)/*.m4; \ + cp -p configure $(DISTDIR)/.; \ + chmod 755 $(DISTDIR)/configure; \ + cp -p config.sub config.guess $(DISTDIR)/.; \ + chmod 755 $(DISTDIR)/config.sub $(DISTDIR)/config.guess; \ + cp -p saoconfig $(DISTDIR)/.; \ + chmod 775 $(DISTDIR)/saoconfig; \ + cp -p install-sh $(DISTDIR)/.; \ + chmod +x $(DISTDIR)/install-sh; \ + cp -p funtools.pc.in $(DISTDIR)/.; \ + chmod +x $(DISTDIR)/funtools.pc.in; \ + cp -p inc.sed $(DISTDIR)/.; \ + chmod +x $(DISTDIR)/inc.sed; \ + cp -p mklib $(DISTDIR)/.; \ + chmod +x $(DISTDIR)/mklib; \ + cp -p mkfunmainlib $(DISTDIR)/.; \ + chmod +x $(DISTDIR)/mkfunmainlib; \ + cp -pR util filter fitsy wcs gnu $(DISTDIR)/.;\ + cp -pR funtest txt faq $(DISTDIR)/.;\ + cp -p $(TEMPLATES) $(DISTDIR)/.; \ + cp -p $(FILES) $(DISTDIR)/.; \ + mkdir $(DISTDIR)/doc; \ + cp -p ./doc/*.html ./doc/*.c $(DISTDIR)/doc/.; \ + cp -p ./doc/*.ps ./doc/*.pdf $(DISTDIR)/doc/.; \ + cp -p ./doc/Makefile $(DISTDIR)/doc/.; \ + cp -p ./doc/szlong.c $(DISTDIR)/doc/.; \ + mkdir $(DISTDIR)/doc/sman; \ + cp -p ./doc/sman/* $(DISTDIR)/doc/sman/.; \ + mkdir $(DISTDIR)/man; \ + cp -p -R ./man/* $(DISTDIR)/man/.) + +release: dist + (cd $(DISTDIR); cd ..; \ + tar cf - $(DISTNAME) | \ + gzip -9 -c > $(FTPDIR)/$(DISTNAME).tar.gz) + +tar: + ($(RM) -r config.cache; \ + cd ..; \ + tar cf - $(DISTNAME) | gzip -9 -c > $(DISTNAME).tar.gz) + +errcheck: + @-egrep 'error|warning|ld:|collect2:|make:' foo | egrep -v "^lex.*but not used" + +itar: + (cd doc/sman; \ + tar cf - . | gzip -9 -c > ../../../$(DISTNAME)-iman.tar.gz) + +sman: + @(cd doc && $(MAKE) index) + +docs: + @(cd doc; $(MAKE)) + +untar: + (make clean; cd ..; \ + $(RM) -r o$(DISTNAME); mv $(DISTNAME) o$(DISTNAME); \ + tar xfz $(DISTNAME).tar.gz) + +pure: funcalc.pure funcen.pure funcnts.pure funcone.pure \ + fundisp.pure funhead.pure funimage.pure funhist.pure \ + funmerge.pure funsky.pure funtable.pure \ + funjoin.pure + +funcen.pure: lib funcen.o + purify $(CC) $(LDFLAGS) funcen.o -o funcen.pure \ + $(LLIB) $(LIBS) + +funcnts.pure: lib funcnts.o + purify $(CC) $(LDFLAGS) funcnts.o -o funcnts.pure \ + $(LLIB) $(LIBS) + +funcone.pure: lib funcone.o + purify $(CC) $(LDFLAGS) funcone.o -o funcone.pure \ + $(LLIB) $(LIBS) + +fundisp.pure: lib fundisp.o + purify $(CC) $(LDFLAGS) fundisp.o -o fundisp.pure \ + $(LLIB) $(LIBS) + +funhead.pure: lib funhead.o + purify $(CC) $(LDFLAGS) funhead.o -o funhead.pure \ + $(LLIB) $(LIBS) + +funsky.pure: lib funsky.o + purify $(CC) $(LDFLAGS) funsky.o -o funsky.pure \ + $(LLIB) $(LIBS) + +funtable.pure: lib funtable.o + purify $(CC) $(LDFLAGS) funtable.o -o funtable.pure \ + $(LLIB) $(LIBS) + +funimage.pure: lib funimage.o + purify $(CC) $(LDFLAGS) funimage.o -o funimage.pure \ + $(LLIB) $(LIBS) + +funhist.pure: lib funhist.o + purify $(CC) $(LDFLAGS) funhist.o -o funhist.pure \ + $(LLIB) $(LIBS) + +funjoin.pure: lib funjoin.o + purify $(CC) $(LDFLAGS) funjoin.o -o funjoin.pure \ + $(LLIB) $(LIBS) + +funmerge.pure: lib funmerge.o + purify $(CC) $(LDFLAGS) funmerge.o -o funmerge.pure \ + $(LLIB) $(LIBS) + +funcalc.pure: lib funcalc.o lex.calc.o + purify $(CC) $(LDFLAGS) funcalc.o lex.calc.o \ + -o funcalc.pure $(LLIB) $(LIBS) + +# DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/README b/README new file mode 100644 index 0000000..973e6b0 --- /dev/null +++ b/README @@ -0,0 +1,27 @@ +Funtools is a "minimal buy-in" FITS library and utility package +originally developed at the the High Energy Astrophysics Division of +SAO. Although no longer actively supported at SAO, it is still widely +used within the astronomical community, especially among X-ray astronomers. + +The Funtools library provides simplified access to a wide array +of file types: standard astronomical FITS images and binary tables, +raw arrays and binary event lists, and even tables of ASCII column +data. A sophisticated region filtering library (compatible with ds9) +filters images and tables using Boolean operations between geometric +shapes, support world coordinates, etc. Funtools also supports +advanced capabilities such as optimized data searching using index files. + +Because Funtools consists of a library and a set of user programs, it +is most appropriately built from source. Funtools has been ported to +Solaris, Linux, Mac OSX (Darwin) and Windows 98/NT/2000/XP. Once the +source code tar file is retrieved, Funtools can be built and installed +easily using standard commands: + + ./mkconfigure # generate all configure scripts + ./configure --prefix=[installdir] # configuration + make # build the software + make install # install in [installdir] + +See the INSTALL instructions (which are based on standard instructions +for building software using GNU configure) for more information about +building Funtools. diff --git a/ac_c_long_long.m4 b/ac_c_long_long.m4 new file mode 100644 index 0000000..fb6df1e --- /dev/null +++ b/ac_c_long_long.m4 @@ -0,0 +1,36 @@ +##### http://autoconf-archive.cryp.to/ac_c_long_long.html +# +# SYNOPSIS +# +# AC_C_LONG_LONG +# +# DESCRIPTION +# +# Provides a test for the existance of the long long int type and +# defines HAVE_LONG_LONG if it is found. +# +# LAST MODIFICATION +# +# 2006-10-30 +# +# COPYLEFT +# +# Copyright (c) 2006 Caolan McNamara +# +# Copying and distribution of this file, with or without +# modification, are permitted in any medium without royalty provided +# the copyright notice and this notice are preserved. + +AC_DEFUN([AC_C_LONG_LONG], +[AC_CACHE_CHECK(for long long int, ac_cv_c_long_long, +[if test "$GCC" = yes; then + ac_cv_c_long_long=yes + else + AC_TRY_COMPILE(,[long long int i;], + ac_cv_c_long_long=yes, + ac_cv_c_long_long=no) + fi]) + if test $ac_cv_c_long_long = yes; then + AC_DEFINE(HAVE_LONG_LONG, 1, [compiler understands long long]) + fi +]) diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 0000000..b4ee113 --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,2 @@ +builtin(include,tcl.m4) +builtin(include,ac_c_long_long.m4) diff --git a/bsearch.c b/bsearch.c new file mode 100644 index 0000000..df69ca2 --- /dev/null +++ b/bsearch.c @@ -0,0 +1,68 @@ +/* http://www.tbray.org/ongoing/When/200x/2003/03/22/Binary */ + +/* returns first target if more than one have same value */ +static public int search(int [] array, int target) +{ + int high = array.length, low = -1, probe; + while (high - low > 1) + { + probe = (high + low) / 2; + if (array[probe] < target) + low = probe; + else + high = probe; + } + if (high == array.length || array[high] != target) + return -1; + else + return high; +} + +/* returns last target if more than one have same value */ +static public int search2(int [] array, int target) +{ + int high = array.length, low = -1, probe; + while (high - low > 1) + { + probe = (high + low) / 2; + if (array[probe] > target) + high = probe; + else + low = probe; + } + if (low == -1 || array[low] != target) + return -1; + else + return low; +} + +static public int [] range(int [] array, int floor, int ceiling) +{ + int [] answer = new int[2]; + int high, low, probe; + + // work on floor + high = array.length; low = -1; + while (high - low > 1) + { + probe = (high + low) / 2; + if (array[probe] < floor) + low = probe; + else + high = probe; + } + answer[0] = low; + + // work on ceiling + high = array.length; low = -1; + while (high - low > 1) + { + probe = (high + low) / 2; + if (array[probe] > ceiling) + high = probe; + else + low = probe; + } + answer[1] = high; + return answer; +} diff --git a/calc.h b/calc.h new file mode 100644 index 0000000..f3d9c6a --- /dev/null +++ b/calc.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 1999-2003 Smithsonian Astrophysical Observatory + */ + +/* + * + * calc.h + * + */ +#ifndef __funcalc_h +#define __funcalc_h + +#include + +#ifndef FUNCALC_CC +#define FUNCALC_CC NULL +#endif + +#ifndef FUNCALC_CFLAGS +#define FUNCALC_CFLAGS NULL +#endif + +/* places to look for the compiler other than user's path */ +#define FUNCALC_PATH "/opt/SUNWspro/bin:/bin:/usr/bin:/usr/local/bin/:/opt/local/bin:" + +#define DEFAULT_FUNCALC_TMPDIR "/tmp" +#define FUNCALC_SED "funcalc.sed" + +/* library declarations */ +_PRbeg + +void _CalcCat _PRx((char *str, char **ostr, int *olen)); + +_PRend + +#endif /* __funtools.h */ diff --git a/calc.l b/calc.l new file mode 100644 index 0000000..7bd14d7 --- /dev/null +++ b/calc.l @@ -0,0 +1,802 @@ +%option caseless +%array + +%{ +#include +#include +#include +#include +#include + +/* define the types of event records we have to handle */ +#define REC_CUR 1 +#define REC_PREV 2 +#define REC_NEXT 4 + +/* misc */ +#define MAX_INCLUDE_DEPTH 100 +#define SEGINC 1024 +#define MAXCODE 4 + +/* symbols for each column we encounter */ +typedef struct calccoltab { + struct calccoltab *next; + char *name; + char *sname; + char *cname; + char *tdim; + int type; + int n; + double tlmin; + double tlmax; + double binsiz; + double tscale; + double tzero; + int scaled; + int exists; + int settype; +} *CalcCols, CalcColRec; + +static YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH]; +static int include_stack_ptr = 0; +static Fun ifun; +static CalcCols columns; +static int laststart; + +static char *prog; +static char *command; +static char *autodeclare; +static char *mbuf; +static int mlen; +static int n; +static int var; +static int rectype; +static int args; +static int doreplace=0; + +static char *code[MAXCODE]; +static char *expr; +static char **strptr=&expr; +static int ncode[MAXCODE]; +static int nexpr; +static int xnl; +static int *lenptr=&nexpr; + +static void setn _PRx((int newn)); +static char *_CalcMake _PRx((void)); +static int _CalcColProc _PRx((char *s, int expl)); +static int _CalcColName _PRx((char *sname)); +static CalcCols _CalcColNew _PRx((Fun fun, + char *name, char *sname, char *cname, + int type, int n, + double tlmin, double tlmax, double binsiz, + double tscale, double tzero, int scaled, + int exists, int settype)); +static CalcCols _CalcColLookup _PRx((char *cname)); + +int _calcerror _PRx((char *msg)); +%} + +DIG [0-9] +DIG2 [0-9a-fA-F] +BINARY 0[bB][01]+ +INT1 [-+]?{DIG}+L? +INT2 [-+]?0[xX]{DIG2}+L? +INT ({INT1}|{INT2}) +FLOAT1 [-+]?{DIG}+\.?([eE][-+]?{DIG}+)? +FLOAT2 [-+]?{DIG}*\.{DIG}+([eE][-+]?{DIG}+)? +FLOAT ({FLOAT1}|{FLOAT2}) +NUM ({INT}|{FLOAT}) + +SNAME (cur|prev|next) +NAME [A-Za-z~_][0-9A-Za-z~_]*(\[[0-9]+\])? +TYPE (\[{INT}\])?(:{NUM}?[a-z]?){1,4} +COL {SNAME}->{NAME}{TYPE}? +ECOL explicit +FILE @[0-9A-Za-z~_/\-\.]*(\[.*\])? +VAR [ \t]*(char|short|int|float|double) +INCL ^#[\t ]*include[ \t]*(\".*\"|<.*>) +DEF ^#[\t ]*define[ \t]+.* +XCOM # +BCOM "/*" +ECOM "*/" + +%x INCLUDE +%x VAR +%x COM +%x XCOM +%x ECOL +%% + +global { setn(0); var = 0; } +local { setn(1); var = 0; } +before { setn(2); var = 0; } +after { setn(3); var = 0; } +end { setn(-1); var = 0; } + +{FILE} { + char *s; + if ( include_stack_ptr >= MAX_INCLUDE_DEPTH ) + _calcerror("include files are nested too deeply"); + if( !(s = (char *)FileContents(yytext+1, 0, NULL)) ) + _calcerror("can't access include file"); + else { + include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER; + BEGIN INITIAL; yy_scan_string(s); BEGIN INITIAL; + if( s ) xfree(s); + } +} + +{VAR} { + if( var ){ BEGIN VAR; setn(1); } + _CalcCat(yytext, strptr, lenptr); +} +; { + _CalcCat(yytext, strptr, lenptr); + _CalcCat("\n", strptr, lenptr); + if( var ){ BEGIN INITIAL; setn(-1); } +} +. { _CalcCat(yytext, strptr, lenptr); } + +{INCL} { _CalcCat(yytext, strptr, lenptr); } + +{DEF} { _CalcCat(yytext, strptr, lenptr); } + +^[ \t]*{XCOM} { laststart = YY_START; xnl=0; BEGIN XCOM; } +{XCOM} { laststart = YY_START; xnl=1; BEGIN XCOM; } +\n { BEGIN laststart; if( xnl ) unput('\n'); } +. { /* ignore comments up to eol */ ; } + +{BCOM} { + _CalcCat(yytext, strptr, lenptr); + laststart = YY_START; BEGIN COM; +} +{ECOM} { _CalcCat(yytext, strptr, lenptr); BEGIN laststart; } +\n { _CalcCat(yytext, strptr, lenptr); } +. { _CalcCat(yytext, strptr, lenptr); } + +{COL} { _CalcColProc(yytext, 0); var=0;} + +{ECOL} { laststart = YY_START; BEGIN ECOL; } +{NAME} { _CalcColProc(yytext, 1); var=0; } +[, \t] { ; } +\n { BEGIN laststart; } + +\n { _CalcCat(yytext, strptr, lenptr);} + +[ \t]* { _CalcCat(yytext, strptr, lenptr);} + +. { _CalcCat(yytext, strptr, lenptr); var=0;} + +<> { + if ( --include_stack_ptr < 0 ){ + prog = _CalcMake(); + yy_delete_buffer( YY_CURRENT_BUFFER ); + yyterminate(); + } else { + yy_delete_buffer( YY_CURRENT_BUFFER ); + yy_switch_to_buffer(include_stack[include_stack_ptr] ); + } +} + +%% + +/* + * + * Private Routines + * + * + */ + +/* setn -- set pointer to where expression is stored */ +#ifdef YY_USE_PROTOS +static void setn(int newn) +#else +static void setn(newn) + int newn; +#endif +{ + if( newn >=0 ){ + n = newn; + strptr = &code[n]; lenptr = &ncode[n]; + } + else{ + strptr = &expr; lenptr = &nexpr; + } +} + +/* + * + * _CalcDatatype -- return C data type as a string + * + */ +#ifdef YY_USE_PROTOS +static char * +_CalcDatatype(int type) +#else +static char *_CalcDatatype(type) + int type; +#endif +{ + switch ( type ) { + case 'A': return "char"; + case 'X': return "char"; + case 'B': return "unsigned char"; + case 'I': return "short"; + case 'U': return "unsigned short"; + case 'J': return "int"; + case 'K': return "long long"; + case 'V': return "unsigned int"; + case 'L': return "char"; + case 'E': return "float"; + case 'D': return "double"; + } + _calcerror("unknown/illegal data type for new column"); + return "???"; +} + +/* + * + * _CalcColName -- see if sname is a recognized column name + * + */ +#ifdef YY_USE_PROTOS +static int +_CalcColName(char *sname) +#else +static int _CalcColName(sname) + char *sname; +#endif +{ + if( !strcasecmp(sname, "prev") ){ + strcpy(sname, "prev"); + rectype |= REC_PREV; + return REC_PREV; + } + if( !strcasecmp(sname, "cur") ){ + strcpy(sname, "cur"); + rectype |= REC_CUR; + return REC_CUR; + } + if( !strcasecmp(sname, "next") ){ + strcpy(sname, "next"); + rectype |= REC_NEXT; + return REC_NEXT; + } + else{ + return 0; + } +} + +/* + * + * _CalcCB -- macro expansion callback + * + */ +#ifdef YY_USE_PROTOS +static char * +_CalcCB(char *name, void *client_data) +#else +static char *_CalcCB(name, client_data) + char *name; + void *client_data; +#endif +{ + CalcCols cur; + char tbuf[SZ_LINE]; + char tbuf2[SZ_LINE*2]; + char tbuf3[SZ_LINE]; + int i, got, ip; + + /* start at beginning of macro buffer */ + /* allocate the macro buffer */ + if( mbuf ) xfree(mbuf); + mbuf = NULL; + mlen = SZ_LINE; + + if( !strcmp(name, "MEMBERS") ){ + if( !columns ){ + _CalcCat("int dummy;\n", &mbuf, &mlen); + return mbuf; + } + for(cur=columns; cur!=NULL; cur=cur->next){ + snprintf(tbuf, SZ_LINE, "%s %s", _CalcDatatype(cur->type), cur->cname); + _CalcCat(tbuf, &mbuf, &mlen); + if( cur->n > 1 ){ + /* if there is no tdim, just make it a simple array */ + /* (also, do the simple thing for bit-fields) */ + if( (cur->tdim == NULL) || (cur->type == 'X') ){ + switch(cur->type){ + case 'X': + i = (cur->n+7)/8; + break; + default: + i = cur->n; + break; + } + snprintf(tbuf, SZ_LINE, "[%d]", i); + } + /* tdim exists, so use it to declare a multidimensional array */ + else{ + newdtable(",()"); + /* I hear tdim is in Fortran order, so reverse it for C order */ + for(*tbuf = '\0', ip=0, got=0; word(cur->tdim, tbuf3, &ip); got++){ + snprintf(tbuf2, SZ_LINE, "[%s]", tbuf3); + if( *tbuf ) + strcat(tbuf2, tbuf); + strcpy(tbuf, tbuf2); + } + freedtable(); + /* but if we got nothing out of it, go back to simplicity */ + if( !got ) + snprintf(tbuf, SZ_LINE, "[%d]", cur->n); + } + _CalcCat(tbuf, &mbuf, &mlen); + } + _CalcCat(";", &mbuf, &mlen); + if( cur->next ) + _CalcCat("\n", &mbuf, &mlen); + } + return mbuf; + } + else if( !strcmp(name, "SELECT") ){ + if( !columns ){ + return ""; + } + for(cur=columns; cur!=NULL; cur=cur->next){ + *tbuf2 = '\0'; + if( (cur->tlmin != 0.0) || (cur->tlmax != 0.0) ){ + snprintf(tbuf2, SZ_LINE, "%f:%f", cur->tlmin, cur->tlmax); + if( cur->binsiz != 1.0 ){ + snprintf(tbuf3, SZ_LINE, ":%f", cur->binsiz); + strncat(tbuf2, tbuf3, SZ_LINE); + } + if( (cur->tscale != 1.0) || (cur->tzero != 0.0) ){ + snprintf(tbuf3, SZ_LINE, ";%f", cur->tscale); + strncat(tbuf2, tbuf3, SZ_LINE); + snprintf(tbuf3, SZ_LINE, ":%f", cur->tzero); + strncat(tbuf2, tbuf3, SZ_LINE); + } + } + if( *tbuf2 ){ + snprintf(tbuf, SZ_LINE, "\"%s\", \"%d%c:%s\", ", + cur->cname, cur->n, cur->type, tbuf2); + } + else{ + snprintf(tbuf, SZ_LINE, "\"%s\", \"%d%c\", ", + cur->cname, cur->n, cur->type); + } + _CalcCat(tbuf, &mbuf, &mlen); + if( cur->exists ) + _CalcCat("\"rw\", ", &mbuf, &mlen); + else + _CalcCat("\"w\", ", &mbuf, &mlen); + snprintf(tbuf, SZ_LINE, "FUN_OFFSET(Row, %s),", cur->cname); + _CalcCat(tbuf, &mbuf, &mlen); + if( cur->next ) + _CalcCat("\n", &mbuf, &mlen); + } + return mbuf; + } + else if( !strcmp(name, "RECTYPE") ){ + snprintf(tbuf, SZ_LINE, "%d", rectype); + _CalcCat(tbuf, &mbuf, &mlen); + return mbuf; + } + else if( !strcmp(name, "EXPR") ){ + if( expr && *expr ) + return(expr); + else + return ""; + } + else if( !strcmp(name, "COMMAND") ){ + if( command && *command ) + return(command); + else + return ""; + } + else if( !strcmp(name, "ARGS") ){ + if( args == 1 ) + return "1"; + else + return "2"; + } + else if( !strcmp(name, "AUTO") ){ + if( autodeclare && *autodeclare ) + return autodeclare; + else + return ""; + } + else if( !strcmp(name, "GLOBAL") ){ + if( code[0] && *code[0] ) + return(code[0]); + else + return ""; + } + else if( !strcmp(name, "LOCAL") ){ + if( code[1] && *code[1] ) + return(code[1]); + else + return ""; + } + else if( !strcmp(name, "BEFORE") ){ + if( code[2] && *code[2] ) + return(code[2]); + else + return ""; + } + else if( !strcmp(name, "AFTER") ){ + if( code[3] && *code[3] ) + return(code[3]); + else + return ""; + } + else if( !strcmp(name, "MERGE") ){ + if( doreplace ) + strncpy(tbuf, "replace", SZ_LINE); + else + strncpy(tbuf, "update", SZ_LINE); + _CalcCat(tbuf, &mbuf, &mlen); + return mbuf; + } + else{ + _CalcCat("$", &mbuf, &mlen); + _CalcCat(name, &mbuf, &mlen); + return mbuf; + } +} + +/* + * + * _CalcMake -- create the string containing the program by macro expansion + * + */ +#ifdef YY_USE_PROTOS +static char * +_CalcMake(void) +#else +static char *_CalcMake() +#endif +{ + char *s; + + /* make sure we have something */ + if( !expr || !*expr ) + expr = xstrdup(";"); + s = xstrdup(expr); + nowhite(s, expr); + if( s ) xfree(s); + /* add final ';' is necessary (but not if there is any compund statement) */ + if( !strchr(expr,';') && !strchr(expr,'{') ) + _CalcCat(";", &expr, &nexpr); + /* expand program body to add specifics of the expression */ + s = ExpandMacro(TABCALC_C, NULL, NULL, 0, _CalcCB, NULL); + return s; +} + +/* look up a column entry, add if not present */ +#ifdef YY_USE_PROTOS +CalcCols +_CalcColLookup(char *cname) +#else +CalcCols +_CalcColLookup(cname) + char *cname; +#endif +{ + CalcCols cur; + for(cur=columns; cur!=NULL; cur=cur->next){ + if( !strcasecmp(cname, cur->cname) ) + return cur; + } + return NULL; +} + +/* look up a symbol table entry, add if not present */ +#ifdef YY_USE_PROTOS +CalcCols +_CalcColNew(Fun fun, char *name, char *sname, char *cname, int type, int n, + double tlmin, double tlmax, double binsiz, + double tscale, double tzero, int scaled, + int exists, int settype) +#else +CalcCols +_CalcColNew(fun, name, sname, + cname, type, n, tlmin, tlmax, binsiz, + tscale, tzero, scaled, + exists, settype) + Fun fun; + char *name, *sname, *cname; + int type, n; + double tlmin, tlmax, binsiz; + double tscale, tzero; + int scaled, exists, settype; +#endif +{ + CalcCols sym, cur; + int got; + int enter=1; + + if( (sym=_CalcColLookup(cname)) ){ + if( !settype ) return sym; + enter=0; + } + else{ + /* allocate a new symbol record */ + if( !(sym = (CalcCols)xcalloc(1, sizeof(CalcColRec))) ) + return NULL; + } + + /* fill in the blanks */ + if( sym->name ) xfree(sym->name); + sym->name = xstrdup(name); + if( sym->sname ) xfree(sym->sname); + sym->sname = xstrdup(sname); + if( sym->cname ) xfree(sym->cname); + sym->cname = xstrdup(cname); + sym->type = type; + sym->n = n; + sym->tlmin = tlmin; + sym->tlmax = tlmax; + sym->binsiz = binsiz; + sym->tscale = tscale; + sym->tzero = tzero; + sym->scaled = scaled; + sym->exists = exists; + sym->settype = settype; + + /* get tdim value, if there is one */ + if( sym->exists && (sym->n>1) ) + sym->tdim = FunParamGets(fun, "TDIM", exists, NULL, &got); + + /* add to list, maintaining order */ + if( enter ){ + if( !columns ){ + columns = sym; + } + else{ + for(cur=columns; cur->next!=NULL; cur=cur->next) + ; + cur->next = sym; + } + } + return sym; +} + +/* process a column */ +#ifdef YY_USE_PROTOS +static int +_CalcColProc(char *s, int expl) +#else +static int _CalcColProc(s, expl) + char *s; + int expl; +#endif +{ + char *e; + char *t; + char name[SZ_LINE]; + char sname[SZ_LINE]; + char cname[SZ_LINE]; + char aname[SZ_LINE]; + char fname[SZ_LINE]; + int ptype; + int poff; + int exists; + int dims; + int settype=0; + int type=0; + int n=0; + int scaled=0; + double tlmin=0.0, tlmax=0.0, binsiz=1.0; + double tscale=1.0, tzero=0.0; + + /* save expression */ + e = s; + + /* gather struct name */ + for(t=sname; *s && (*s != '-');) + *t++ = *s++; + *t = '\0'; + /* skip past "->" */ + if( *s && (*s == '-') ) s += 2; + + /* if this is not a special name, just append it and exit */ + if( !_CalcColName(sname) ){ + if( !expl ){ + _CalcCat(e, &expr, &nexpr); + return 1; + } + } + + /* gather column name */ + for(t=cname; *s && (*s != '[') && (*s != ':');) + *t++ = *s++; + *t = '\0'; + + /* explicit columns don't have the prefix */ + if( expl && *sname && !*cname ){ + strncpy(cname, sname, SZ_LINE); + strncpy(sname, "cur", SZ_LINE); + } + + /* gather array part */ + if( *s && (*s == '[') ){ + for(t=aname; *s && (*s != ':');) + *t++ = *s++; + *t = '\0'; + } + else + *aname = '\0'; + if( *aname ) + snprintf(fname, SZ_LINE, "%s->%s%s", sname, cname, aname); + else + snprintf(fname, SZ_LINE, "%s->%s", sname, cname); + + /* the expression name is the combination of sname (which we will set to + a struct we know about) and cname (which is a struct member name) */ + snprintf(name, SZ_LINE, "%s->%s", sname, cname); + + /* see if this column exists or if its new */ + exists = FunColumnLookup(ifun, cname, 0, NULL, &type, NULL, NULL, &n, NULL); + + /* gather up specifier info */ + for(; *s; s++){ + if( *s == ':' ){ + _FunColumnType(s+1, &type, &n, &tlmin, &tlmax, &binsiz, &dims, + &tscale, &tzero, &scaled, &ptype, &poff); + settype = 1; + break; + } + } + if( !exists && !settype && !_CalcColLookup(cname) ) + _calcerror("new column requires a type"); + if( exists && settype ) + doreplace=1; + + /* add this column to the list */ + if(_CalcColNew(ifun, name, sname, cname, + type, n, tlmin, tlmax, binsiz, + tscale, tzero, scaled, + exists, settype)){ + if( !expl ) _CalcCat(fname, &expr, &nexpr); + return 1; + } + else{ + return _calcerror("could not enter new funcalc column"); + } +} + +/* + * + * Semi-public Routines + * + * + */ + +/* + * + * _CalcCat -- add a string to the filter string buffer + * + */ +#ifdef YY_USE_PROTOS +void +_CalcCat(char *str, char **ostr, int *olen) +#else +void _CalcCat(str, ostr, olen) + char *str; + char **ostr; + int *olen; +#endif +{ + int blen; + int slen; + + if( (str == NULL) || (*str == '\0') ) + return; + else + slen = strlen(str) + 1; + + if( (*ostr == NULL) || (**ostr == '\0') ) + blen = 0; + else + blen = strlen(*ostr); + + while( (blen + slen) >= *olen ){ + *olen += SEGINC; + } + if( blen == 0 ) + *ostr = (char *)xcalloc(*olen, sizeof(char)); + else + *ostr = (char *)xrealloc(*ostr, *olen); + strcat(*ostr, str); +} + +#ifdef YY_USE_PROTOS +char * +FunCalcParse(char *iname, char *oname, + char *cmd, char *ex, char *autod, int narg) +#else +char *FunCalcParse(iname, oname, cmd, ex, autod, narg) + char *iname; + char *oname; + char *cmd; + char *ex; + char *autod; + int narg; +#endif +{ + int i; + + /* initialize global variables */ + n = 0; + rectype = REC_CUR; + var = 1; + args = narg; + + /* save command */ + if( command ) xfree(command); + command = xstrdup(cmd); + + /* save autodeclare */ + if( autodeclare ) xfree(autodeclare); + autodeclare = xstrdup(autod); + + /* open the input FITS file */ + if( !(ifun = FunOpen(iname, "rc", NULL)) ) + gerror(stderr, "can't FunOpen input file (or find extension): %s\n", + iname); + + /* parse expression */ + yy_scan_string(ex); + yylex(); + + /* done with input FITS file */ + FunClose(ifun); + /* free up space */ + if( expr ){ + xfree(expr); + expr = NULL; + } + nexpr = 0; + for(i=0; i. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). +# +# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. +# +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess +# +# Please send patches to . + + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright 1992-2016 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +case "${UNAME_SYSTEM}" in +Linux|GNU|GNU/*) + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + LIBC=gnu + + eval $set_cc_for_build + cat <<-EOF > $dummy.c + #include + #if defined(__UCLIBC__) + LIBC=uclibc + #elif defined(__dietlibc__) + LIBC=dietlibc + #else + LIBC=gnu + #endif + EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` + ;; +esac + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ + /sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || \ + echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + earmv*) + arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'` + endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'` + machine=${arch}${endian}-unknown + ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently (or will in the future) and ABI. + case "${UNAME_MACHINE_ARCH}" in + earm*) + os=netbsdelf + ;; + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # Determine ABI tags. + case "${UNAME_MACHINE_ARCH}" in + earm*) + expr='s/^earmv[0-9]/-eabi/;s/eb$//' + abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"` + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}${abi}" + exit ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:LibertyBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:Sortix:*:*) + echo ${UNAME_MACHINE}-unknown-sortix + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE=alpha ;; + "EV4.5 (21064)") + UNAME_MACHINE=alpha ;; + "LCA4 (21066/21068)") + UNAME_MACHINE=alpha ;; + "EV5 (21164)") + UNAME_MACHINE=alphaev5 ;; + "EV5.6 (21164A)") + UNAME_MACHINE=alphaev56 ;; + "EV5.6 (21164PC)") + UNAME_MACHINE=alphapca56 ;; + "EV5.7 (21164PC)") + UNAME_MACHINE=alphapca57 ;; + "EV6 (21264)") + UNAME_MACHINE=alphaev6 ;; + "EV6.7 (21264A)") + UNAME_MACHINE=alphaev67 ;; + "EV6.8CB (21264C)") + UNAME_MACHINE=alphaev68 ;; + "EV6.8AL (21264B)") + UNAME_MACHINE=alphaev68 ;; + "EV6.8CX (21264D)") + UNAME_MACHINE=alphaev68 ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE=alphaev69 ;; + "EV7 (21364)") + UNAME_MACHINE=alphaev7 ;; + "EV7.9 (21364A)") + UNAME_MACHINE=alphaev79 ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm*:riscos:*:*|arm*:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH=i386 + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != no_compiler_found ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH=x86_64 + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = x && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/lslpp ] ; then + IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | + awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 + 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH=hppa2.0n ;; + 64) HP_ARCH=hppa2.0w ;; + '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS="" $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = hppa2.0w ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH=hppa2.0w + else + HP_ARCH=hppa64 + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`/usr/bin/uname -p` + case ${UNAME_PROCESSOR} in + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW64*:*) + echo ${UNAME_MACHINE}-pc-mingw64 + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + *:MSYS*:*) + echo ${UNAME_MACHINE}-pc-msys + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + aarch64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC=gnulibc1 ; fi + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + arc:Linux:*:* | arceb:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi + else + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + cris:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-${LIBC} + exit ;; + crisv32:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-${LIBC} + exit ;; + e2k:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + frv:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + hexagon:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + i*86:Linux:*:*) + echo ${UNAME_MACHINE}-pc-linux-${LIBC} + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + k1om:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } + ;; + mips64el:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + openrisc*:Linux:*:*) + echo or1k-unknown-linux-${LIBC} + exit ;; + or32:Linux:*:* | or1k*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-${LIBC} + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-${LIBC} + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; + PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; + *) echo hppa-unknown-linux-${LIBC} ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-${LIBC} + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-${LIBC} + exit ;; + ppc64le:Linux:*:*) + echo powerpc64le-unknown-linux-${LIBC} + exit ;; + ppcle:Linux:*:*) + echo powerpcle-unknown-linux-${LIBC} + exit ;; + riscv32:Linux:*:* | riscv64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux-${LIBC} + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + tile*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-${LIBC} + exit ;; + x86_64:Linux:*:*) + echo ${UNAME_MACHINE}-pc-linux-${LIBC} + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configure will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + x86_64:Haiku:*:*) + echo x86_64-unknown-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + SX-ACE:SUPER-UX:*:*) + echo sxace-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + eval $set_cc_for_build + if test "$UNAME_PROCESSOR" = unknown ; then + UNAME_PROCESSOR=powerpc + fi + if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then + if [ "$CC_FOR_BUILD" != no_compiler_found ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + fi + elif test "$UNAME_PROCESSOR" = i386 ; then + # Avoid executing cc on OS X 10.9, as it ships with a stub + # that puts up a graphical alert prompting to install + # developer tools. Any system running Mac OS X 10.7 or + # later (Darwin 11 and later) is required to have a 64-bit + # processor. This is not true of the ARM version of Darwin + # that Apple uses in portable devices. + UNAME_PROCESSOR=x86_64 + fi + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = x86; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NEO-?:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk${UNAME_RELEASE} + exit ;; + NSE-*:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = 386; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE} | sed -e 's/ .*$//'` + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; + x86_64:VMkernel:*:*) + echo ${UNAME_MACHINE}-unknown-esx + exit ;; + amd64:Isilon\ OneFS:*:*) + echo x86_64-unknown-onefs + exit ;; +esac + +cat >&2 </dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/config.sub b/config.sub new file mode 100755 index 0000000..cc69b06 --- /dev/null +++ b/config.sub @@ -0,0 +1,1823 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright 1992-2016 Free Software Foundation, Inc. + +timestamp='2016-09-05' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). + + +# Please send patches to . +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright 1992-2016 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ + linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ + kopensolaris*-gnu* | cloudabi*-eabi* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + android-linux) + os=-linux-android + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray | -microblaze*) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*178) + os=-lynxos178 + ;; + -lynx*5) + os=-lynxos5 + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | aarch64 | aarch64_be \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arceb \ + | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ + | avr | avr32 \ + | ba \ + | be32 | be64 \ + | bfin \ + | c4x | c8051 | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | e2k | epiphany \ + | fido | fr30 | frv | ft32 \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | k1om \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa32r6 | mipsisa32r6el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64r6 | mipsisa64r6el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nios | nios2 | nios2eb | nios2el \ + | ns16k | ns32k \ + | open8 | or1k | or1knd | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pyramid \ + | riscv32 | riscv64 \ + | rl78 | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ + | visium \ + | we32k \ + | x86 | xc16x | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + leon|leon[3-9]) + basic_machine=sparc-$basic_machine + ;; + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + xgate) + basic_machine=$basic_machine-unknown + os=-none + ;; + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | aarch64-* | aarch64_be-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | ba-* \ + | be32-* | be64-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ + | c8051-* | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | e2k-* | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | hexagon-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | k1om-* \ + | le32-* | le64-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ + | microblaze-* | microblazeel-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa32r6-* | mipsisa32r6el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64r6-* | mipsisa64r6el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipsr5900-* | mipsr5900el-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ + | nios-* | nios2-* | nios2eb-* | nios2el-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ + | or1k*-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pyramid-* \ + | riscv32-* | riscv64-* \ + | rl78-* | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \ + | tahoe-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile*-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ + | visium-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + asmjs) + basic_machine=asmjs-unknown + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16 | cr16-*) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + e500v[12]) + basic_machine=powerpc-unknown + os=$os"spe" + ;; + e500v[12]-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + os=$os"spe" + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + leon-*|leon[3-9]-*) + basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'` + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze*) + basic_machine=microblaze-xilinx + ;; + mingw64) + basic_machine=x86_64-pc + os=-mingw64 + ;; + mingw32) + basic_machine=i686-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + moxiebox) + basic_machine=moxie-unknown + os=-moxiebox + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + msys) + basic_machine=i686-pc + os=-msys + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc | ppcbe) basic_machine=powerpc-unknown + ;; + ppc-* | ppcbe-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos | rdos64) + basic_machine=x86_64-pc + os=-rdos + ;; + rdos32) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tile*) + basic_machine=$basic_machine-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + xscale-* | xscalee[bl]-*) + basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -auroraux) + os=-auroraux + ;; + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* | -plan9* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* | -cloudabi* | -sortix* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-musl* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \ + | -onefs* | -tirtos* | -phoenix*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -nacl*) + ;; + -ios) + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + c8051-*) + os=-elf + ;; + hexagon-*) + os=-elf + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -cnk*|-aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/configure-failsafe b/configure-failsafe new file mode 100755 index 0000000..e0441d4 --- /dev/null +++ b/configure-failsafe @@ -0,0 +1,7001 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.59 for funtools 1.4.6. +# +# Report bugs to . +# +# Copyright (C) 2003 Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi +DUALCASE=1; export DUALCASE # for MKS sh + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +exec 6>&1 + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_config_libobj_dir=. +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Maximum number of lines to put in a shell here document. +# This variable seems obsolete. It should probably be removed, and +# only ac_max_sed_lines should be used. +: ${ac_max_here_lines=38} + +# Identity of this package. +PACKAGE_NAME='funtools' +PACKAGE_TARNAME='funtools' +PACKAGE_VERSION='1.4.6' +PACKAGE_STRING='funtools 1.4.6' +PACKAGE_BUGREPORT='saord@cfa.harvard.edu' + +ac_unique_file="./funtools.h" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#if HAVE_SYS_TYPES_H +# include +#endif +#if HAVE_SYS_STAT_H +# include +#endif +#if STDC_HEADERS +# include +# include +#else +# if HAVE_STDLIB_H +# include +# endif +#endif +#if HAVE_STRING_H +# if !STDC_HEADERS && HAVE_MEMORY_H +# include +# endif +# include +#endif +#if HAVE_STRINGS_H +# include +#endif +#if HAVE_INTTYPES_H +# include +#else +# if HAVE_STDINT_H +# include +# endif +#endif +#if HAVE_UNISTD_H +# include +#endif" + +ac_subdirs_all="$ac_subdirs_all util" +ac_subdirs_all="$ac_subdirs_all fitsy" +ac_subdirs_all="$ac_subdirs_all filter" +ac_subdirs_all="$ac_subdirs_all wcs" +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT RANLIB ac_ct_RANLIB CPP EGREP FILTER_CC FILTER_CFLAGS LIB DEFLIB DOSHARED LLIB USE_DL USE_FPU_DOUBLE DOMAINLIB AWK gzip gnuplot EXTRA_LIBS EXTRA_OBJS PRE POST GUNZIP GNUPLOT PIPEGLUE subdirs LIBOBJS LTLIBOBJS' +ac_subst_files='' + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +ac_prev= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_option in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + eval "enable_$ac_feature=no" ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "enable_$ac_feature='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package| sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "with_$ac_package='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/-/_/g'` + eval "with_$ac_package=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` + eval "$ac_envvar='$ac_optarg'" + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute paths. +for ac_var in exec_prefix prefix +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* | NONE | '' ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# Be sure to have absolute paths. +for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ + localstatedir libdir includedir oldincludedir infodir mandir +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_confdir=`(dirname "$0") 2>/dev/null || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 + { (exit 1); exit 1; }; } + else + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } + fi +fi +(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || + { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 + { (exit 1); exit 1; }; } +srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` +ac_env_build_alias_set=${build_alias+set} +ac_env_build_alias_value=$build_alias +ac_cv_env_build_alias_set=${build_alias+set} +ac_cv_env_build_alias_value=$build_alias +ac_env_host_alias_set=${host_alias+set} +ac_env_host_alias_value=$host_alias +ac_cv_env_host_alias_set=${host_alias+set} +ac_cv_env_host_alias_value=$host_alias +ac_env_target_alias_set=${target_alias+set} +ac_env_target_alias_value=$target_alias +ac_cv_env_target_alias_set=${target_alias+set} +ac_cv_env_target_alias_value=$target_alias +ac_env_CC_set=${CC+set} +ac_env_CC_value=$CC +ac_cv_env_CC_set=${CC+set} +ac_cv_env_CC_value=$CC +ac_env_CFLAGS_set=${CFLAGS+set} +ac_env_CFLAGS_value=$CFLAGS +ac_cv_env_CFLAGS_set=${CFLAGS+set} +ac_cv_env_CFLAGS_value=$CFLAGS +ac_env_LDFLAGS_set=${LDFLAGS+set} +ac_env_LDFLAGS_value=$LDFLAGS +ac_cv_env_LDFLAGS_set=${LDFLAGS+set} +ac_cv_env_LDFLAGS_value=$LDFLAGS +ac_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_env_CPPFLAGS_value=$CPPFLAGS +ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_cv_env_CPPFLAGS_value=$CPPFLAGS +ac_env_CPP_set=${CPP+set} +ac_env_CPP_value=$CPP +ac_cv_env_CPP_set=${CPP+set} +ac_cv_env_CPP_value=$CPP + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures funtools 1.4.6 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +_ACEOF + + cat <<_ACEOF +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data [PREFIX/share] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --infodir=DIR info documentation [PREFIX/info] + --mandir=DIR man documentation [PREFIX/man] +_ACEOF + + cat <<\_ACEOF + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of funtools 1.4.6:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-shared build shared libraries + --enable-dl allow use of dynamic loading if available + --enable-fpu_double set FPU in double round mode + --enable-mainlib build funtools mainlib support + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-filter-cc=CC compiler + --with-filter-cflags=CFLAGS compiler flags + --with-altlib=LIB library name + --with-zlib=LIB library name + --with-wcslib=LIB library name + --with-tcl directory containing tcl configuration (tclConfig.sh) + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have + headers in a nonstandard directory + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to . +_ACEOF +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + ac_popdir=`pwd` + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d $ac_dir || continue + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + cd $ac_dir + # Check for guested configure; otherwise get Cygnus style configure. + if test -f $ac_srcdir/configure.gnu; then + echo + $SHELL $ac_srcdir/configure.gnu --help=recursive + elif test -f $ac_srcdir/configure; then + echo + $SHELL $ac_srcdir/configure --help=recursive + elif test -f $ac_srcdir/configure.ac || + test -f $ac_srcdir/configure.in; then + echo + $ac_configure --help + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi + cd $ac_popdir + done +fi + +test -n "$ac_init_help" && exit 0 +if $ac_init_version; then + cat <<\_ACEOF +funtools configure 1.4.6 +generated by GNU Autoconf 2.59 + +Copyright (C) 2003 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit 0 +fi +exec 5>config.log +cat >&5 <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by funtools $as_me 1.4.6, which was +generated by GNU Autoconf 2.59. Invocation command line was + + $ $0 $@ + +_ACEOF +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +hostinfo = `(hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + echo "PATH: $as_dir" +done + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_sep= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$ac_configure_args1 '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" + # Get rid of the leading space. + ac_sep=" " + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Be sure not to use single quotes in there, as some shells, +# such as our DU 5.0 friend, will then `close' the trap. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +{ + (set) 2>&1 | + case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in + *ac_space=\ *) + sed -n \ + "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" + ;; + *) + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------- ## +## Output files. ## +## ------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + sed "/^$/d" confdefs.h | sort + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core && + rm -rf conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status + ' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo >confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . $cache_file;; + *) . ./$cache_file;; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in `(set) 2>&1 | + sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val="\$ac_cv_env_${ac_var}_value" + eval ac_new_val="\$ac_env_${ac_var}_value" + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ac_config_headers="$ac_config_headers conf.h ./gnu/conf.h ./funtest/conf.h" + + +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f $ac_dir/shtool; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 +echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} + { (exit 1); exit 1; }; } +fi +ac_config_guess="$SHELL $ac_aux_dir/config.guess" +ac_config_sub="$SHELL $ac_aux_dir/config.sub" +ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. + +# Make sure we can run config.sub. +$ac_config_sub sun4 >/dev/null 2>&1 || + { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5 +echo "$as_me: error: cannot run $ac_config_sub" >&2;} + { (exit 1); exit 1; }; } + +echo "$as_me:$LINENO: checking build system type" >&5 +echo $ECHO_N "checking build system type... $ECHO_C" >&6 +if test "${ac_cv_build+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_build_alias=$build_alias +test -z "$ac_cv_build_alias" && + ac_cv_build_alias=`$ac_config_guess` +test -z "$ac_cv_build_alias" && + { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 +echo "$as_me: error: cannot guess build type; you must specify one" >&2;} + { (exit 1); exit 1; }; } +ac_cv_build=`$ac_config_sub $ac_cv_build_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_build" >&5 +echo "${ECHO_T}$ac_cv_build" >&6 +build=$ac_cv_build +build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + +echo "$as_me:$LINENO: checking host system type" >&5 +echo $ECHO_N "checking host system type... $ECHO_C" >&6 +if test "${ac_cv_host+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_host_alias=$host_alias +test -z "$ac_cv_host_alias" && + ac_cv_host_alias=$ac_cv_build_alias +ac_cv_host=`$ac_config_sub $ac_cv_host_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_host" >&5 +echo "${ECHO_T}$ac_cv_host" >&6 +host=$ac_cv_host +host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + + +# +# checks that we use in most projects +# +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$ac_ct_CC" && break +done + + CC=$ac_ct_CC +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO:" \ + "checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 + (eval $ac_compiler --version &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 + (eval $ac_compiler -v &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 + (eval $ac_compiler -V &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 +echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6 +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 + (eval $ac_link_default) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Find the output, starting from the most likely. This scheme is +# not robust to junk in `.', hence go to wildcards (a.*) only as a last +# resort. + +# Be careful to initialize this variable, since it used to be cached. +# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. +ac_cv_exeext= +# b.out is created by i960 compilers. +for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) + ;; + conftest.$ac_ext ) + # This is the source file. + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + # FIXME: I believe we export ac_cv_exeext for Libtool, + # but it would be cool to find out if it's true. Does anybody + # maintain Libtool? --akim. + export ac_cv_exeext + break;; + * ) + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables +See \`config.log' for more details." >&5 +echo "$as_me: error: C compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6 + +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +rm -f a.out a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 +echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6 + +echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + export ac_cv_exeext + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6 + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6 +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_compiler_gnu=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +CFLAGS="-g" +echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_prog_cc_g=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 +echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_stdc=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std1 is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std1. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +# Don't try gcc -ansi; that turns off useful extensions and +# breaks some systems' header files. +# AIX -qlanglvl=ansi +# Ultrix and OSF/1 -std1 +# HP-UX 10.20 and later -Ae +# HP-UX older versions -Aa -D_HPUX_SOURCE +# SVR4 -Xc -D__EXTENSIONS__ +for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_stdc=$ac_arg +break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext +done +rm -f conftest.$ac_ext conftest.$ac_objext +CC=$ac_save_CC + +fi + +case "x$ac_cv_prog_cc_stdc" in + x|xno) + echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6 ;; + *) + echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 + CC="$CC $ac_cv_prog_cc_stdc" ;; +esac + +# Some people use a C++ compiler to compile C. Since we use `exit', +# in C++ we need to declare it. In case someone uses the same compiler +# for both compiling C and C++ we need to have the C++ compiler decide +# the declaration of exit, since it's the most demanding environment. +cat >conftest.$ac_ext <<_ACEOF +#ifndef __cplusplus + choke me +#endif +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + for ac_declaration in \ + '' \ + 'extern "C" void std::exit (int) throw (); using std::exit;' \ + 'extern "C" void std::exit (int); using std::exit;' \ + 'extern "C" void exit (int) throw ();' \ + 'extern "C" void exit (int);' \ + 'void exit (int);' +do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +#include +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +continue +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +done +rm -f conftest* +if test -n "$ac_declaration"; then + echo '#ifdef __cplusplus' >>confdefs.h + echo $ac_declaration >>confdefs.h + echo '#endif' >>confdefs.h +fi + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +if test x"${EXEEXT}" = "xno"; then + EXEEXT="" +fi + + +echo "$as_me:$LINENO: checking for long long int" >&5 +echo $ECHO_N "checking for long long int... $ECHO_C" >&6 +if test "${ac_cv_c_long_long+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$GCC" = yes; then + ac_cv_c_long_long=yes + else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +long long int i; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_long_long=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_c_long_long=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + fi +fi +echo "$as_me:$LINENO: result: $ac_cv_c_long_long" >&5 +echo "${ECHO_T}$ac_cv_c_long_long" >&6 + if test $ac_cv_c_long_long = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_LONG_LONG 1 +_ACEOF + + fi + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + echo "$as_me:$LINENO: result: $RANLIB" >&5 +echo "${ECHO_T}$RANLIB" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":" +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 +echo "${ECHO_T}$ac_ct_RANLIB" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + RANLIB=$ac_ct_RANLIB +else + RANLIB="$ac_cv_prog_RANLIB" +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +echo "$as_me:$LINENO: result: $CPP" >&5 +echo "${ECHO_T}$CPP" >&6 +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&5 +echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +echo "$as_me:$LINENO: checking for egrep" >&5 +echo $ECHO_N "checking for egrep... $ECHO_C" >&6 +if test "${ac_cv_prog_egrep+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if echo a | (grep -E '(a|b)') >/dev/null 2>&1 + then ac_cv_prog_egrep='grep -E' + else ac_cv_prog_egrep='egrep' + fi +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 +echo "${ECHO_T}$ac_cv_prog_egrep" >&6 + EGREP=$ac_cv_prog_egrep + + +echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_header_stdc=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + exit(2); + exit (0); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6 +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. + + + + + + + + + +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_Header=no" +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + +for ac_header in malloc.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------ ## +## Report this to saord@cfa.harvard.edu ## +## ------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in getopt.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------ ## +## Report this to saord@cfa.harvard.edu ## +## ------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in values.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------ ## +## Report this to saord@cfa.harvard.edu ## +## ------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in dlfcn.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------ ## +## Report this to saord@cfa.harvard.edu ## +## ------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in sys/un.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------ ## +## Report this to saord@cfa.harvard.edu ## +## ------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in sys/ipc.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------ ## +## Report this to saord@cfa.harvard.edu ## +## ------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in sys/mman.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------ ## +## Report this to saord@cfa.harvard.edu ## +## ------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +case $host_os in + *cygwin*|*Cygwin* ) + ;; + * ) + +for ac_header in sys/shm.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------ ## +## Report this to saord@cfa.harvard.edu ## +## ------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + ;; +esac + +echo "$as_me:$LINENO: checking for socklen_t" >&5 +echo $ECHO_N "checking for socklen_t... $ECHO_C" >&6 +if test "${ac_cv_type_socklen_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +int +main () +{ +if ((socklen_t *) 0) + return 0; +if (sizeof (socklen_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_socklen_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_socklen_t=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_socklen_t" >&5 +echo "${ECHO_T}$ac_cv_type_socklen_t" >&6 +if test $ac_cv_type_socklen_t = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_SOCKLEN_T 1 +_ACEOF + + +fi + + +echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 +echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6 +if test "${ac_cv_c_const+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +/* FIXME: Include the comments suggested by Paul. */ +#ifndef __cplusplus + /* Ultrix mips cc rejects this. */ + typedef int charset[2]; + const charset x; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *ccp; + char **p; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + ccp = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++ccp; + p = (char**) ccp; + ccp = (char const *const *) p; + { /* SCO 3.2v4 cc rejects this. */ + char *t; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; }; + struct s *b; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + } +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_const=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_c_const=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 +echo "${ECHO_T}$ac_cv_c_const" >&6 +if test $ac_cv_c_const = no; then + +cat >>confdefs.h <<\_ACEOF +#define const +_ACEOF + +fi + + + + + +for ac_func in strchr memcpy snprintf +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +echo "$as_me:$LINENO: checking for connect" >&5 +echo $ECHO_N "checking for connect... $ECHO_C" >&6 +if test "${ac_cv_func_connect+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define connect to an innocuous variant, in case declares connect. + For example, HP-UX 11i declares gettimeofday. */ +#define connect innocuous_connect + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char connect (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef connect + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char connect (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_connect) || defined (__stub___connect) +choke me +#else +char (*f) () = connect; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != connect; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_connect=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_connect=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_connect" >&5 +echo "${ECHO_T}$ac_cv_func_connect" >&6 + +if test $ac_cv_func_connect = no; then + echo "$as_me:$LINENO: checking for connect in -lsocket" >&5 +echo $ECHO_N "checking for connect in -lsocket... $ECHO_C" >&6 +if test "${ac_cv_lib_socket_connect+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsocket $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char connect (); +int +main () +{ +connect (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_socket_connect=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_socket_connect=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_socket_connect" >&5 +echo "${ECHO_T}$ac_cv_lib_socket_connect" >&6 +if test $ac_cv_lib_socket_connect = yes; then + EXTRA_LIBS="$EXTRA_LIBS -lsocket" +fi + +fi +echo "$as_me:$LINENO: checking for gethostbyname" >&5 +echo $ECHO_N "checking for gethostbyname... $ECHO_C" >&6 +if test "${ac_cv_func_gethostbyname+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define gethostbyname to an innocuous variant, in case declares gethostbyname. + For example, HP-UX 11i declares gettimeofday. */ +#define gethostbyname innocuous_gethostbyname + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char gethostbyname (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef gethostbyname + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gethostbyname (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_gethostbyname) || defined (__stub___gethostbyname) +choke me +#else +char (*f) () = gethostbyname; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != gethostbyname; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_gethostbyname=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_gethostbyname=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_gethostbyname" >&5 +echo "${ECHO_T}$ac_cv_func_gethostbyname" >&6 + +if test $ac_cv_func_gethostbyname = no; then + echo "$as_me:$LINENO: checking for gethostbyname in -lnsl" >&5 +echo $ECHO_N "checking for gethostbyname in -lnsl... $ECHO_C" >&6 +if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lnsl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gethostbyname (); +int +main () +{ +gethostbyname (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_nsl_gethostbyname=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_nsl_gethostbyname=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_gethostbyname" >&5 +echo "${ECHO_T}$ac_cv_lib_nsl_gethostbyname" >&6 +if test $ac_cv_lib_nsl_gethostbyname = yes; then + EXTRA_LIBS="$EXTRA_LIBS -lnsl" +fi + +fi +# AC_CHECK_LIB(db, snprintf, EXTRA_LIBS="$EXTRA_LIBS -ldb") + +# +# checks specific to this project +# + +echo "$as_me:$LINENO: checking for filter cc" >&5 +echo $ECHO_N "checking for filter cc... $ECHO_C" >&6 + +# Check whether --with-filter-cc or --without-filter-cc was given. +if test "${with_filter_cc+set}" = set; then + withval="$with_filter_cc" + FILTER_CC=\\\"$withval\\\" +else + FILTER_CC=NULL +fi; +echo "$as_me:$LINENO: result: $FILTER_CC" >&5 +echo "${ECHO_T}$FILTER_CC" >&6 + + +echo "$as_me:$LINENO: checking for filter cflags" >&5 +echo $ECHO_N "checking for filter cflags... $ECHO_C" >&6 + +# Check whether --with-filter-cflags or --without-filter-cflags was given. +if test "${with_filter_cflags+set}" = set; then + withval="$with_filter_cflags" + FILTER_CFLAGS=\\\"$withval\\\" +else + FILTER_CFLAGS=NULL +fi; +echo "$as_me:$LINENO: result: $FILTER_CFLAGS" >&5 +echo "${ECHO_T}$FILTER_CFLAGS" >&6 + + +DEFLIB="libfuntools.a" +echo "$as_me:$LINENO: checking for alternate target library" >&5 +echo $ECHO_N "checking for alternate target library... $ECHO_C" >&6 + +# Check whether --with-altlib or --without-altlib was given. +if test "${with_altlib+set}" = set; then + withval="$with_altlib" + alt_lib=yes LIB=$withval +else + alt_lib=no LIB=$DEFLIB +fi; +echo "$as_me:$LINENO: result: $alt_lib ($LIB)" >&5 +echo "${ECHO_T}$alt_lib ($LIB)" >&6 + + + +echo "$as_me:$LINENO: checking for external zlib" >&5 +echo $ECHO_N "checking for external zlib... $ECHO_C" >&6 + +# Check whether --with-zlib or --without-zlib was given. +if test "${with_zlib+set}" = set; then + withval="$with_zlib" + zlib=yes EXTRA_LIBS="$EXTRA_LIBS $withval" +else + zlib=no +fi; +echo "$as_me:$LINENO: result: $zlib" >&5 +echo "${ECHO_T}$zlib" >&6 + +echo "$as_me:$LINENO: checking for external wcslib" >&5 +echo $ECHO_N "checking for external wcslib... $ECHO_C" >&6 + +# Check whether --with-wcslib or --without-wcslib was given. +if test "${with_wcslib+set}" = set; then + withval="$with_wcslib" + wcslib=yes EXTRA_LIBS="$EXTRA_LIBS $withval" +else + wcslib=no +fi; +echo "$as_me:$LINENO: result: $wcslib" >&5 +echo "${ECHO_T}$wcslib" >&6 + +echo "$as_me:$LINENO: checking for shared library build" >&5 +echo $ECHO_N "checking for shared library build... $ECHO_C" >&6 +# Check whether --enable-shared or --disable-shared was given. +if test "${enable_shared+set}" = set; then + enableval="$enable_shared" + fun_ok=$enableval +else + fun_ok=no +fi; +if test "$fun_ok" != "no"; then + fpic="yes" + DOSHARED=shlib + + if test "$fun_ok" = "link"; then + echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 +echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 +if test "${ac_cv_lib_dl_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen (); +int +main () +{ +dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dl_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_dl_dlopen=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 +echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 +if test $ac_cv_lib_dl_dlopen = yes; then + have_dl=yes +else + have_dl=no +fi + + if test "$have_dl" = yes; then + using_shlib="yes" + fpic="yes" + EXTRA_LIBS="$EXTRA_LIBS -ldl" + if test `$CC -v -rdynamic 2>&1 | grep -c unrecognized` = "0" ; then + LDFLAGS="$LDFLAGS -rdynamic" + fi + else + echo "$as_me:$LINENO: checking for dlopen in -lc" >&5 +echo $ECHO_N "checking for dlopen in -lc... $ECHO_C" >&6 +if test "${ac_cv_lib_c_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lc $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen (); +int +main () +{ +dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_c_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_c_dlopen=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_c_dlopen" >&5 +echo "${ECHO_T}$ac_cv_lib_c_dlopen" >&6 +if test $ac_cv_lib_c_dlopen = yes; then + have_dl=yes +else + have_dl=no +fi + + if test "$have_dl" = yes; then + using_shlib="yes" + fpic="yes" + if test `$CC -v -rdynamic 2>&1 | grep -c unrecognized` = "0" ; then + LDFLAGS="$LDFLAGS -rdynamic" + fi + else + using_shlib="no" + fi + fi + LLIB="-L. -l$PACKAGE_NAME" + else + LLIB='$(LIB)' + fi +else + LLIB='$(LIB)' +fi + +echo "$as_me:$LINENO: result: $fun_ok" >&5 +echo "${ECHO_T}$fun_ok" >&6 + +echo "$as_me:$LINENO: checking for dynamic loading of filters " >&5 +echo $ECHO_N "checking for dynamic loading of filters ... $ECHO_C" >&6 +# Check whether --enable-dl or --disable-dl was given. +if test "${enable_dl+set}" = set; then + enableval="$enable_dl" + fun_ok=$enableval +else + fun_ok=no +fi; +if test "$fun_ok" = "yes"; then +if test "$CC" = "gcc" -o `$CC -v 2>&1 | grep -c gcc` != "0" ; then + using_dl="yes" + if test x"$using_shlib" != xyes; then + echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 +echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 +if test "${ac_cv_lib_dl_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen (); +int +main () +{ +dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dl_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_dl_dlopen=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 +echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 +if test $ac_cv_lib_dl_dlopen = yes; then + have_dl=yes +else + have_dl=no +fi + + if test "$have_dl" = yes; then + USE_DL="-DUSE_DL=1" + fpic="yes" + EXTRA_LIBS="$EXTRA_LIBS -ldl" + if test `$CC -v -rdynamic 2>&1 | grep -c unrecognized` = "0" ; then + LDFLAGS="$LDFLAGS -rdynamic" + fi + else + echo "$as_me:$LINENO: checking for dlopen in -lc" >&5 +echo $ECHO_N "checking for dlopen in -lc... $ECHO_C" >&6 +if test "${ac_cv_lib_c_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lc $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen (); +int +main () +{ +dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_c_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_c_dlopen=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_c_dlopen" >&5 +echo "${ECHO_T}$ac_cv_lib_c_dlopen" >&6 +if test $ac_cv_lib_c_dlopen = yes; then + have_dl=yes +else + have_dl=no +fi + + if test "$have_dl" = yes; then + USE_DL="-DUSE_DL=1" + fpic="yes" + if test `$CC -v -rdynamic 2>&1 | grep -c unrecognized` = "0" ; then + LDFLAGS="$LDFLAGS -rdynamic" + fi + else + using_dl="no" + fi + fi + fi +else + using_dl="no" +fi +else +using_dl="no" +fi +echo "$as_me:$LINENO: result: $using_dl ($CC)" >&5 +echo "${ECHO_T}$using_dl ($CC)" >&6 + + +# Check whether --enable-fpu_double or --disable-fpu_double was given. +if test "${enable_fpu_double+set}" = set; then + enableval="$enable_fpu_double" + fun_ok=$enableval +else + fun_ok=no +fi; +if test "$fun_ok" = "yes"; then +echo "$as_me:$LINENO: checking for setting fpu in double rounding mode (with gcc) " >&5 +echo $ECHO_N "checking for setting fpu in double rounding mode (with gcc) ... $ECHO_C" >&6 +if test "$CC" = "gcc" -o `$CC -v 2>&1 | grep -c gcc` != "0" ; then + using_fpu_double="yes" + USE_FPU_DOUBLE="1" +else + using_fpu_double="no" + USE_FPU_DOUBLE="0" +fi +echo "$as_me:$LINENO: result: $using_fpu_double" >&5 +echo "${ECHO_T}$using_fpu_double" >&6 +else + USE_FPU_DOUBLE="0" +fi + + +echo "$as_me:$LINENO: checking for mainlib build" >&5 +echo $ECHO_N "checking for mainlib build... $ECHO_C" >&6 +DOMAINLIB="" +# Check whether --enable-mainlib or --disable-mainlib was given. +if test "${enable_mainlib+set}" = set; then + enableval="$enable_mainlib" + fun_ok=$enableval +else + fun_ok=no +fi; +if test "$fun_ok" = "yes"; then + DOMAINLIB=mainlib +elif test "$fun_ok" = "shared"; then + DOMAINLIB=shmainlib +fi + +echo "$as_me:$LINENO: result: $fun_ok" >&5 +echo "${ECHO_T}$fun_ok" >&6 + + + # + # Ok, lets find the tcl configuration + # First, look for one uninstalled. + # the alternative search directory is invoked by --with-tcl + # + + if test x"${no_tcl}" = x ; then + # we reset no_tcl in case something fails here + no_tcl=true + +# Check whether --with-tcl or --without-tcl was given. +if test "${with_tcl+set}" = set; then + withval="$with_tcl" + with_tclconfig=${withval} +fi; + echo "$as_me:$LINENO: checking for Tcl configuration" >&5 +echo $ECHO_N "checking for Tcl configuration... $ECHO_C" >&6 + if test x"${withval}" != xno ; then + if test "${ac_cv_c_tclconfig+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + + # First check to see if --with-tcl was specified. + if test x"${with_tclconfig}" != x ; then + if test -f "${with_tclconfig}/tclConfig.sh" ; then + ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)` + else + echo "$as_me:$LINENO: result: ${with_tclconfig} directory doesn't contain tclConfig.sh" >&5 +echo "${ECHO_T}${with_tclconfig} directory doesn't contain tclConfig.sh" >&6 + fi + fi + + # then check for a private Tcl installation + if test x"${ac_cv_c_tclconfig}" = x ; then + for i in \ + ../tcl \ + `ls -dr ../tcl[8-9].[0-9]* 2>/dev/null` \ + ../../tcl \ + `ls -dr ../../tcl[8-9].[0-9]* 2>/dev/null` \ + ../../../tcl \ + `ls -dr ../../../tcl[8-9].[0-9]* 2>/dev/null` ; do + if test -f "$i/unix/tclConfig.sh" ; then + ac_cv_c_tclconfig=`(cd $i/unix; pwd)` + break + fi + done + fi + + # check in a few common install locations + if test x"${ac_cv_c_tclconfig}" = x ; then + for i in `ls -d ${libdir} 2>/dev/null` \ + `ls -d /usr/local/lib 2>/dev/null` \ + `ls -d /usr/contrib/lib 2>/dev/null` \ + `ls -d /usr/lib 2>/dev/null` \ + ; do + if test -f "$i/tclConfig.sh" ; then + ac_cv_c_tclconfig=`(cd $i; pwd)` + break + fi + done + fi + + # check in a few other private locations + if test x"${ac_cv_c_tclconfig}" = x ; then + for i in \ + ${srcdir}/../tcl \ + `ls -dr ${srcdir}/../tcl[8-9].[0-9]* 2>/dev/null` ; do + if test -f "$i/unix/tclConfig.sh" ; then + ac_cv_c_tclconfig=`(cd $i/unix; pwd)` + break + fi + done + fi + +fi + + else + echo "$as_me:$LINENO: result: skipping Tcl configuration" >&5 +echo "${ECHO_T}skipping Tcl configuration" >&6 + ac_cv_c_tclconfig="none" + fi + + if test x"${ac_cv_c_tclconfig}" = x ; then + TCL_BIN_DIR="# no Tcl configs found" + echo "$as_me:$LINENO: result: can't find Tcl configuration definitions" >&5 +echo "${ECHO_T}can't find Tcl configuration definitions" >&6 +# no Tcl is OK egm 03/25/03 +# AC_MSG_WARN(Can't find Tcl configuration definitions) +# exit 0 + elif test x"${ac_cv_c_tclconfig}" = xnone ; then + TCL_BIN_DIR="" + else + no_tcl= + TCL_BIN_DIR=${ac_cv_c_tclconfig} + echo "$as_me:$LINENO: result: found $TCL_BIN_DIR/tclConfig.sh" >&5 +echo "${ECHO_T}found $TCL_BIN_DIR/tclConfig.sh" >&6 + fi + fi + +if test x"${no_tcl}" = x ; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_TCL 1 +_ACEOF + +fi + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_AWK+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + echo "$as_me:$LINENO: result: $AWK" >&5 +echo "${ECHO_T}$AWK" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$AWK" && break +done + + +# Extract the first word of "gzip", so it can be a program name with args. +set dummy gzip; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_gzip+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$gzip"; then + ac_cv_prog_gzip="$gzip" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_gzip="gzip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_gzip" && ac_cv_prog_gzip="none" +fi +fi +gzip=$ac_cv_prog_gzip +if test -n "$gzip"; then + echo "$as_me:$LINENO: result: $gzip" >&5 +echo "${ECHO_T}$gzip" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +if test "$gzip" = "none"; then + GUNZIP="cat" +else + GUNZIP="$gzip -dcf" +fi + +# Extract the first word of "gnuplot", so it can be a program name with args. +set dummy gnuplot; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_gnuplot+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$gnuplot"; then + ac_cv_prog_gnuplot="$gnuplot" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_gnuplot="gnuplot" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_gnuplot" && ac_cv_prog_gnuplot="none" +fi +fi +gnuplot=$ac_cv_prog_gnuplot +if test -n "$gnuplot"; then + echo "$as_me:$LINENO: result: $gnuplot" >&5 +echo "${ECHO_T}$gnuplot" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +if test "$gnuplot" = "none"; then + GNUPLOT="NONE" +else + GNUPLOT="$gnuplot" +fi + +echo "$as_me:$LINENO: checking $host_os configuration" >&5 +echo $ECHO_N "checking $host_os configuration... $ECHO_C" >&6 +PRE="" +POST="|\& cat" +case $host_os in + *cygwin*|*Cygwin* ) + CFLAGS="$CFLAGS -enable-auto-import" + +cat >>confdefs.h <<\_ACEOF +#define HAVE_CYGWIN +_ACEOF + + echo "$as_me:$LINENO: result: flagging Cygwin" >&5 +echo "${ECHO_T}flagging Cygwin" >&6 + PRE="sh -c {" + POST="}" + ;; + *mingw32*|*Mingw32*) + CFLAGS="$CFLAGS -mconsole -D_WSTRING_DEFINED=1" + EXTRA_LIBS="$EXTRA_LIBS -lwsock32" + +cat >>confdefs.h <<\_ACEOF +#define HAVE_MINGW32 +_ACEOF + + echo "$as_me:$LINENO: result: flagging MinGW" >&5 +echo "${ECHO_T}flagging MinGW" >&6 + ;; + *osf*|*Osf*) + echo "$as_me:$LINENO: checking for snprintf in -ldb" >&5 +echo $ECHO_N "checking for snprintf in -ldb... $ECHO_C" >&6 +if test "${ac_cv_lib_db_snprintf+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldb $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char snprintf (); +int +main () +{ +snprintf (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_db_snprintf=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_db_snprintf=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_db_snprintf" >&5 +echo "${ECHO_T}$ac_cv_lib_db_snprintf" >&6 +if test $ac_cv_lib_db_snprintf = yes; then + EXTRA_LIBS="$EXTRA_LIBS -ldb" +fi + + ;; + *darwin*|*Darwin*) + LDFLAGS="$LDFLAGS $CFLAGS" + G=`$CC -v 2>&1 | grep version | awk '{print $3}' | awk -F. '{print $1$2}'` + if test x"$G" != x -a "$G" -lt 42; then + CFLAGS="$CFLAGS -no-cpp-precomp" + fi + if test x"$fpic" = x"yes" ; then + CFLAGS="$CFLAGS -fPIC" + echo "$as_me:$LINENO: result: adding -fno-common, -fPIC to CFLAGS" >&5 +echo "${ECHO_T}adding -fno-common, -fPIC to CFLAGS" >&6 + else + echo "$as_me:$LINENO: result: adding -fno-common to CFLAGS" >&5 +echo "${ECHO_T}adding -fno-common to CFLAGS" >&6 + fi + ;; + * ) + if test x"$fpic" = x"yes" ; then + if test "$CC" = "gcc" -o `$CC -v 2>&1 | grep -c gcc` != "0" ; then + CFLAGS="$CFLAGS -fPIC" + echo "$as_me:$LINENO: result: adding -fPIC to gcc" >&5 +echo "${ECHO_T}adding -fPIC to gcc" >&6 + else + echo "$as_me:$LINENO: result: none" >&5 +echo "${ECHO_T}none" >&6 + fi + else + echo "$as_me:$LINENO: result: none" >&5 +echo "${ECHO_T}none" >&6 + fi + ;; +esac + + + + + + + + + + + ac_config_files="$ac_config_files Makefile ./gnu/Makefile ./funtest/Makefile ./faq/Makefile" + + +# generate pkg-config meta-data file + ac_config_files="$ac_config_files funtools.pc" + + +# for individual package that create libraries, we must run configure again, +# faking the subdirs into using the funtools library as their library +# this will run faster with --config-cache +ac_configure_args="--with-altlib=`pwd`/$LIB $ac_configure_args" +# AC_CONFIG_SUBDIRS(util fitsy filter wcs) + + +subdirs="$subdirs util" + + + +subdirs="$subdirs fitsy" + + + +subdirs="$subdirs filter" + + + +subdirs="$subdirs wcs" + + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +{ + (set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} | + sed ' + t clear + : clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + : end' >>confcache +if diff $cache_file confcache >/dev/null 2>&1; then :; else + if test -w $cache_file; then + test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" + cat confcache >$cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/; +s/:*\${srcdir}:*/:/; +s/:*@srcdir@:*/:/; +s/^\([^=]*=[ ]*\):*/\1/; +s/:*$//; +s/^[^=]*=[ ]*$//; +}' +fi + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_i=`echo "$ac_i" | + sed 's/\$U\././;s/\.o$//;s/\.obj$//'` + # 2. Add them. + ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi +DUALCASE=1; export DUALCASE # for MKS sh + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 +echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 +echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + +exec 6>&1 + +# Open the log real soon, to keep \$[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. Logging --version etc. is OK. +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX +} >&5 +cat >&5 <<_CSEOF + +This file was extended by funtools $as_me 1.4.6, which was +generated by GNU Autoconf 2.59. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +_CSEOF +echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 +echo >&5 +_ACEOF + +# Files that config.status was made for. +if test -n "$ac_config_files"; then + echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_headers"; then + echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_links"; then + echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_commands"; then + echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS +fi + +cat >>$CONFIG_STATUS <<\_ACEOF + +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Report bugs to ." +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +funtools config.status 1.4.6 +configured by $0, generated by GNU Autoconf 2.59, + with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2003 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." +srcdir=$srcdir +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "x$1" : 'x\([^=]*\)='` + ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` + ac_shift=: + ;; + -*) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + *) # This is not an option, so the user has probably given explicit + # arguments. + ac_option=$1 + ac_need_defaults=false;; + esac + + case $ac_option in + # Handling of the options. +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --vers* | -V ) + echo "$ac_cs_version"; exit 0 ;; + --he | --h) + # Conflict between --help and --header + { { echo "$as_me:$LINENO: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +if \$ac_cs_recheck; then + echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion +fi + +_ACEOF + + + + + +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_config_target in $ac_config_targets +do + case "$ac_config_target" in + # Handling of arguments. + "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "./gnu/Makefile" ) CONFIG_FILES="$CONFIG_FILES ./gnu/Makefile" ;; + "./funtest/Makefile" ) CONFIG_FILES="$CONFIG_FILES ./funtest/Makefile" ;; + "./faq/Makefile" ) CONFIG_FILES="$CONFIG_FILES ./faq/Makefile" ;; + "funtools.pc" ) CONFIG_FILES="$CONFIG_FILES funtools.pc" ;; + "conf.h" ) CONFIG_HEADERS="$CONFIG_HEADERS conf.h" ;; + "./gnu/conf.h" ) CONFIG_HEADERS="$CONFIG_HEADERS ./gnu/conf.h" ;; + "./funtest/conf.h" ) CONFIG_HEADERS="$CONFIG_HEADERS ./funtest/conf.h" ;; + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason to put it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Create a temporary directory, and hook for its removal unless debugging. +$debug || +{ + trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} + +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./confstat$$-$RANDOM + (umask 077 && mkdir $tmp) +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF + +# +# CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "\$CONFIG_FILES"; then + # Protect against being on the right side of a sed subst in config.status. + sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; + s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF +s,@SHELL@,$SHELL,;t t +s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t +s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t +s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t +s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t +s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t +s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t +s,@exec_prefix@,$exec_prefix,;t t +s,@prefix@,$prefix,;t t +s,@program_transform_name@,$program_transform_name,;t t +s,@bindir@,$bindir,;t t +s,@sbindir@,$sbindir,;t t +s,@libexecdir@,$libexecdir,;t t +s,@datadir@,$datadir,;t t +s,@sysconfdir@,$sysconfdir,;t t +s,@sharedstatedir@,$sharedstatedir,;t t +s,@localstatedir@,$localstatedir,;t t +s,@libdir@,$libdir,;t t +s,@includedir@,$includedir,;t t +s,@oldincludedir@,$oldincludedir,;t t +s,@infodir@,$infodir,;t t +s,@mandir@,$mandir,;t t +s,@build_alias@,$build_alias,;t t +s,@host_alias@,$host_alias,;t t +s,@target_alias@,$target_alias,;t t +s,@DEFS@,$DEFS,;t t +s,@ECHO_C@,$ECHO_C,;t t +s,@ECHO_N@,$ECHO_N,;t t +s,@ECHO_T@,$ECHO_T,;t t +s,@LIBS@,$LIBS,;t t +s,@build@,$build,;t t +s,@build_cpu@,$build_cpu,;t t +s,@build_vendor@,$build_vendor,;t t +s,@build_os@,$build_os,;t t +s,@host@,$host,;t t +s,@host_cpu@,$host_cpu,;t t +s,@host_vendor@,$host_vendor,;t t +s,@host_os@,$host_os,;t t +s,@CC@,$CC,;t t +s,@CFLAGS@,$CFLAGS,;t t +s,@LDFLAGS@,$LDFLAGS,;t t +s,@CPPFLAGS@,$CPPFLAGS,;t t +s,@ac_ct_CC@,$ac_ct_CC,;t t +s,@EXEEXT@,$EXEEXT,;t t +s,@OBJEXT@,$OBJEXT,;t t +s,@RANLIB@,$RANLIB,;t t +s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t +s,@CPP@,$CPP,;t t +s,@EGREP@,$EGREP,;t t +s,@FILTER_CC@,$FILTER_CC,;t t +s,@FILTER_CFLAGS@,$FILTER_CFLAGS,;t t +s,@LIB@,$LIB,;t t +s,@DEFLIB@,$DEFLIB,;t t +s,@DOSHARED@,$DOSHARED,;t t +s,@LLIB@,$LLIB,;t t +s,@USE_DL@,$USE_DL,;t t +s,@USE_FPU_DOUBLE@,$USE_FPU_DOUBLE,;t t +s,@DOMAINLIB@,$DOMAINLIB,;t t +s,@AWK@,$AWK,;t t +s,@gzip@,$gzip,;t t +s,@gnuplot@,$gnuplot,;t t +s,@EXTRA_LIBS@,$EXTRA_LIBS,;t t +s,@EXTRA_OBJS@,$EXTRA_OBJS,;t t +s,@PRE@,$PRE,;t t +s,@POST@,$POST,;t t +s,@GUNZIP@,$GUNZIP,;t t +s,@GNUPLOT@,$GNUPLOT,;t t +s,@PIPEGLUE@,$PIPEGLUE,;t t +s,@subdirs@,$subdirs,;t t +s,@LIBOBJS@,$LIBOBJS,;t t +s,@LTLIBOBJS@,$LTLIBOBJS,;t t +CEOF + +_ACEOF + + cat >>$CONFIG_STATUS <<\_ACEOF + # Split the substitutions into bite-sized pieces for seds with + # small command number limits, like on Digital OSF/1 and HP-UX. + ac_max_sed_lines=48 + ac_sed_frag=1 # Number of current file. + ac_beg=1 # First line for current file. + ac_end=$ac_max_sed_lines # Line after last line for current file. + ac_more_lines=: + ac_sed_cmds= + while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + else + sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + fi + if test ! -s $tmp/subs.frag; then + ac_more_lines=false + else + # The purpose of the label and of the branching condition is to + # speed up the sed processing (if there are no `@' at all, there + # is no need to browse any of the substitutions). + # These are the two extra sed commands mentioned above. + (echo ':t + /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" + else + ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" + fi + ac_sed_frag=`expr $ac_sed_frag + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_lines` + fi + done + if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat + fi +fi # test -n "$CONFIG_FILES" + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + + + if test x"$ac_file" != x-; then + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + rm -f "$ac_file" + fi + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + configure_input= + else + configure_input="$ac_file. " + fi + configure_input=$configure_input"Generated from `echo $ac_file_in | + sed 's,.*/,,'` by configure." + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo "$f";; + *) # Relative + if test -f "$f"; then + # Build tree + echo "$f" + elif test -f "$srcdir/$f"; then + # Source tree + echo "$srcdir/$f" + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s,@configure_input@,$configure_input,;t t +s,@srcdir@,$ac_srcdir,;t t +s,@abs_srcdir@,$ac_abs_srcdir,;t t +s,@top_srcdir@,$ac_top_srcdir,;t t +s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t +s,@builddir@,$ac_builddir,;t t +s,@abs_builddir@,$ac_abs_builddir,;t t +s,@top_builddir@,$ac_top_builddir,;t t +s,@abs_top_builddir@,$ac_abs_top_builddir,;t t +" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out + rm -f $tmp/stdin + if test x"$ac_file" != x-; then + mv $tmp/out $ac_file + else + cat $tmp/out + rm -f $tmp/out + fi + +done +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + +# +# CONFIG_HEADER section. +# + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='[ ].*$,\1#\2' +ac_dC=' ' +ac_dD=',;t' +# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='$,\1#\2define\3' +ac_uC=' ' +ac_uD=',;t' + +for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + # Do quote $f, to prevent DOS paths from being IFS'd. + echo "$f";; + *) # Relative + if test -f "$f"; then + # Build tree + echo "$f" + elif test -f "$srcdir/$f"; then + # Source tree + echo "$srcdir/$f" + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } + # Remove the trailing spaces. + sed 's/[ ]*$//' $ac_file_inputs >$tmp/in + +_ACEOF + +# Transform confdefs.h into two sed scripts, `conftest.defines' and +# `conftest.undefs', that substitutes the proper values into +# config.h.in to produce config.h. The first handles `#define' +# templates, and the second `#undef' templates. +# And first: Protect against being on the right side of a sed subst in +# config.status. Protect against being in an unquoted here document +# in config.status. +rm -f conftest.defines conftest.undefs +# Using a here document instead of a string reduces the quoting nightmare. +# Putting comments in sed scripts is not portable. +# +# `end' is used to avoid that the second main sed command (meant for +# 0-ary CPP macros) applies to n-ary macro definitions. +# See the Autoconf documentation for `clear'. +cat >confdef2sed.sed <<\_ACEOF +s/[\\&,]/\\&/g +s,[\\$`],\\&,g +t clear +: clear +s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp +t end +s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp +: end +_ACEOF +# If some macros were called several times there might be several times +# the same #defines, which is useless. Nevertheless, we may not want to +# sort them, since we want the *last* AC-DEFINE to be honored. +uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines +sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs +rm -f confdef2sed.sed + +# This sed command replaces #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +cat >>conftest.undefs <<\_ACEOF +s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */, +_ACEOF + +# Break up conftest.defines because some shells have a limit on the size +# of here documents, and old seds have small limits too (100 cmds). +echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS +echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS +echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS +echo ' :' >>$CONFIG_STATUS +rm -f conftest.tail +while grep . conftest.defines >/dev/null +do + # Write a limited-size here document to $tmp/defines.sed. + echo ' cat >$tmp/defines.sed <>$CONFIG_STATUS + # Speed up: don't consider the non `#define' lines. + echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS + # Work around the forget-to-reset-the-flag bug. + echo 't clr' >>$CONFIG_STATUS + echo ': clr' >>$CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS + echo 'CEOF + sed -f $tmp/defines.sed $tmp/in >$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in +' >>$CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail + rm -f conftest.defines + mv conftest.tail conftest.defines +done +rm -f conftest.defines +echo ' fi # grep' >>$CONFIG_STATUS +echo >>$CONFIG_STATUS + +# Break up conftest.undefs because some shells have a limit on the size +# of here documents, and old seds have small limits too (100 cmds). +echo ' # Handle all the #undef templates' >>$CONFIG_STATUS +rm -f conftest.tail +while grep . conftest.undefs >/dev/null +do + # Write a limited-size here document to $tmp/undefs.sed. + echo ' cat >$tmp/undefs.sed <>$CONFIG_STATUS + # Speed up: don't consider the non `#undef' + echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS + # Work around the forget-to-reset-the-flag bug. + echo 't clr' >>$CONFIG_STATUS + echo ': clr' >>$CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS + echo 'CEOF + sed -f $tmp/undefs.sed $tmp/in >$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in +' >>$CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail + rm -f conftest.undefs + mv conftest.tail conftest.undefs +done +rm -f conftest.undefs + +cat >>$CONFIG_STATUS <<\_ACEOF + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + echo "/* Generated by configure. */" >$tmp/config.h + else + echo "/* $ac_file. Generated by configure. */" >$tmp/config.h + fi + cat $tmp/in >>$tmp/config.h + rm -f $tmp/in + if test x"$ac_file" != x-; then + if diff $ac_file $tmp/config.h >/dev/null 2>&1; then + { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 +echo "$as_me: $ac_file is unchanged" >&6;} + else + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + rm -f $ac_file + mv $tmp/config.h $ac_file + fi + else + cat $tmp/config.h + rm -f $tmp/config.h + fi +done +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi + +# +# CONFIG_SUBDIRS section. +# +if test "$no_recursion" != yes; then + + # Remove --cache-file and --srcdir arguments so they do not pile up. + ac_sub_configure_args= + ac_prev= + for ac_arg in $ac_configure_args; do + if test -n "$ac_prev"; then + ac_prev= + continue + fi + case $ac_arg in + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* \ + | --c=*) + ;; + --config-cache | -C) + ;; + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + ;; + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + ;; + *) ac_sub_configure_args="$ac_sub_configure_args $ac_arg" ;; + esac + done + + # Always prepend --prefix to ensure using the same prefix + # in subdir configurations. + ac_sub_configure_args="--prefix=$prefix $ac_sub_configure_args" + + ac_popdir=`pwd` + for ac_dir in : $subdirs; do test "x$ac_dir" = x: && continue + + # Do not complain, so a configure script can configure whichever + # parts of a large source tree are present. + test -d $srcdir/$ac_dir || continue + + { echo "$as_me:$LINENO: configuring in $ac_dir" >&5 +echo "$as_me: configuring in $ac_dir" >&6;} + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + + cd $ac_dir + + # Check for guested configure; otherwise get Cygnus style configure. + if test -f $ac_srcdir/configure.gnu; then + ac_sub_configure="$SHELL '$ac_srcdir/configure.gnu'" + elif test -f $ac_srcdir/configure; then + ac_sub_configure="$SHELL '$ac_srcdir/configure'" + elif test -f $ac_srcdir/configure.in; then + ac_sub_configure=$ac_configure + else + { echo "$as_me:$LINENO: WARNING: no configuration information is in $ac_dir" >&5 +echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2;} + ac_sub_configure= + fi + + # The recursion is here. + if test -n "$ac_sub_configure"; then + # Make the cache file name correct relative to the subdirectory. + case $cache_file in + [\\/]* | ?:[\\/]* ) ac_sub_cache_file=$cache_file ;; + *) # Relative path. + ac_sub_cache_file=$ac_top_builddir$cache_file ;; + esac + + { echo "$as_me:$LINENO: running $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&5 +echo "$as_me: running $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&6;} + # The eval makes quoting arguments work. + eval $ac_sub_configure $ac_sub_configure_args \ + --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir || + { { echo "$as_me:$LINENO: error: $ac_sub_configure failed for $ac_dir" >&5 +echo "$as_me: error: $ac_sub_configure failed for $ac_dir" >&2;} + { (exit 1); exit 1; }; } + fi + + cd $ac_popdir + done +fi + diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..f0a0dfc --- /dev/null +++ b/configure.ac @@ -0,0 +1,286 @@ +# This file is an input file used by the GNU "autoconf" program to +# generate the file "configure", which is run during XPA installation +# to configure the system for the local environment. +AC_INIT(funtools, 1.4.7, saord@cfa.harvard.edu, funtools) + +AC_CONFIG_HEADERS([conf.h ./gnu/conf.h ./funtest/conf.h]) +AC_CONFIG_SRCDIR([./funtools.h]) +AC_CANONICAL_HOST + +# +# checks that we use in most projects +# +AC_PROG_CC + +AC_EXEEXT +if test x"${EXEEXT}" = "xno"; then + EXEEXT="" +fi + +AC_C_LONG_LONG + +AC_PROG_RANLIB + +AC_HEADER_STDC +AC_CHECK_HEADERS(malloc.h) +AC_CHECK_HEADERS(getopt.h) +AC_CHECK_HEADERS(values.h) +AC_CHECK_HEADERS(dlfcn.h) +AC_CHECK_HEADERS(sys/un.h) +AC_CHECK_HEADERS(sys/ipc.h) +AC_CHECK_HEADERS(sys/mman.h) +case $host_os in + *cygwin*|*Cygwin* ) + ;; + * ) + AC_CHECK_HEADERS(sys/shm.h) + ;; +esac + +AC_CHECK_TYPES([socklen_t], [], [], [#include ]) + +AC_C_CONST + +AC_CHECK_FUNCS(strchr memcpy snprintf) + +AC_CHECK_FUNC(connect) +if test $ac_cv_func_connect = no; then + AC_CHECK_LIB(socket, connect, EXTRA_LIBS="$EXTRA_LIBS -lsocket") +fi +AC_CHECK_FUNC(gethostbyname) +if test $ac_cv_func_gethostbyname = no; then + AC_CHECK_LIB(nsl, gethostbyname, EXTRA_LIBS="$EXTRA_LIBS -lnsl") +fi +# AC_CHECK_LIB(db, snprintf, EXTRA_LIBS="$EXTRA_LIBS -ldb") + +# +# checks specific to this project +# + +AC_MSG_CHECKING(for filter cc) +AC_ARG_WITH(filter-cc, [ --with-filter-cc=CC compiler], + FILTER_CC=\\\"$withval\\\", FILTER_CC=NULL) +AC_MSG_RESULT($FILTER_CC) +AC_SUBST(FILTER_CC) + +AC_MSG_CHECKING(for filter cflags) +AC_ARG_WITH(filter-cflags, [ --with-filter-cflags=CFLAGS compiler flags], + FILTER_CFLAGS=\\\"$withval\\\", FILTER_CFLAGS=NULL) +AC_MSG_RESULT($FILTER_CFLAGS) +AC_SUBST(FILTER_CFLAGS) + +DEFLIB="libfuntools.a" +AC_MSG_CHECKING(for alternate target library) +AC_ARG_WITH(altlib, [ --with-altlib=LIB library name], + alt_lib=yes LIB=$withval, alt_lib=no LIB=$DEFLIB) +AC_MSG_RESULT($alt_lib ($LIB)) +AC_SUBST(LIB) +AC_SUBST(DEFLIB) + +AC_MSG_CHECKING(for external zlib) +AC_ARG_WITH(zlib, [ --with-zlib=LIB library name], + zlib=yes EXTRA_LIBS="$EXTRA_LIBS $withval", zlib=no) +AC_MSG_RESULT($zlib) + +AC_MSG_CHECKING(for external wcslib) +AC_ARG_WITH(wcslib, [ --with-wcslib=LIB library name], + wcslib=yes EXTRA_LIBS="$EXTRA_LIBS $withval", wcslib=no) +AC_MSG_RESULT($wcslib) + +AC_MSG_CHECKING(for shared library build) +AC_ARG_ENABLE(shared, [ --enable-shared build shared libraries], + [fun_ok=$enableval], [fun_ok=no]) +if test "$fun_ok" != "no"; then + fpic="yes" + DOSHARED=shlib + AC_SUBST(DOSHARED) + if test "$fun_ok" = "link"; then + AC_CHECK_LIB(dl, dlopen, have_dl=yes, have_dl=no) + if test "$have_dl" = yes; then + using_shlib="yes" + fpic="yes" + EXTRA_LIBS="$EXTRA_LIBS -ldl" + if test `$CC -v -rdynamic 2>&1 | grep -c unrecognized` = "0" ; then + LDFLAGS="$LDFLAGS -rdynamic" + fi + else + AC_CHECK_LIB(c, dlopen, have_dl=yes, have_dl=no) + if test "$have_dl" = yes; then + using_shlib="yes" + fpic="yes" + if test `$CC -v -rdynamic 2>&1 | grep -c unrecognized` = "0" ; then + LDFLAGS="$LDFLAGS -rdynamic" + fi + else + using_shlib="no" + fi + fi + LLIB="-L. -l$PACKAGE_NAME" + else + LLIB='$(LIB)' + fi +else + LLIB='$(LIB)' +fi +AC_SUBST(LLIB) +AC_MSG_RESULT($fun_ok) + +AC_MSG_CHECKING([for dynamic loading of filters ]) +AC_ARG_ENABLE(dl, [ --enable-dl allow use of dynamic loading if available], + [fun_ok=$enableval], [fun_ok=no]) +if test "$fun_ok" = "yes"; then +if test "$CC" = "gcc" -o `$CC -v 2>&1 | grep -c gcc` != "0" ; then + using_dl="yes" + if test x"$using_shlib" != xyes; then + AC_CHECK_LIB(dl, dlopen, have_dl=yes, have_dl=no) + if test "$have_dl" = yes; then + USE_DL="-DUSE_DL=1" + fpic="yes" + EXTRA_LIBS="$EXTRA_LIBS -ldl" + if test `$CC -v -rdynamic 2>&1 | grep -c unrecognized` = "0" ; then + LDFLAGS="$LDFLAGS -rdynamic" + fi + else + AC_CHECK_LIB(c, dlopen, have_dl=yes, have_dl=no) + if test "$have_dl" = yes; then + USE_DL="-DUSE_DL=1" + fpic="yes" + if test `$CC -v -rdynamic 2>&1 | grep -c unrecognized` = "0" ; then + LDFLAGS="$LDFLAGS -rdynamic" + fi + else + using_dl="no" + fi + fi + fi +else + using_dl="no" +fi +else +using_dl="no" +fi +AC_MSG_RESULT([$using_dl ($CC)]) +AC_SUBST(USE_DL) + +AC_ARG_ENABLE(fpu_double, [ --enable-fpu_double set FPU in double round mode], + [fun_ok=$enableval], [fun_ok=no]) +if test "$fun_ok" = "yes"; then +AC_MSG_CHECKING([for setting fpu in double rounding mode (with gcc) ]) +if test "$CC" = "gcc" -o `$CC -v 2>&1 | grep -c gcc` != "0" ; then + using_fpu_double="yes" + USE_FPU_DOUBLE="1" +else + using_fpu_double="no" + USE_FPU_DOUBLE="0" +fi +AC_MSG_RESULT([$using_fpu_double]) +else + USE_FPU_DOUBLE="0" +fi +AC_SUBST(USE_FPU_DOUBLE) + +AC_MSG_CHECKING(for mainlib build) +DOMAINLIB="" +AC_ARG_ENABLE(mainlib, [ --enable-mainlib build funtools mainlib support], + [fun_ok=$enableval], [fun_ok=no]) +if test "$fun_ok" = "yes"; then + DOMAINLIB=mainlib +elif test "$fun_ok" = "shared"; then + DOMAINLIB=shmainlib +fi +AC_SUBST(DOMAINLIB) +AC_MSG_RESULT($fun_ok) + +SC_PATH_TCLCONFIG +if test x"${no_tcl}" = x ; then + AC_DEFINE([HAVE_TCL], [1], [Define if tcl is used.]) +fi + +AC_PROG_AWK + +AC_CHECK_PROG(gzip, gzip, gzip, none) +if test "$gzip" = "none"; then + GUNZIP="cat" +else + GUNZIP="$gzip -dcf" +fi + +AC_CHECK_PROG(gnuplot, gnuplot, gnuplot, none) +if test "$gnuplot" = "none"; then + GNUPLOT="NONE" +else + GNUPLOT="$gnuplot" +fi + +AC_MSG_CHECKING([$host_os configuration]) +PRE="" +POST="|\& cat" +case $host_os in + *cygwin*|*Cygwin* ) + CFLAGS="$CFLAGS -enable-auto-import" + AC_DEFINE([HAVE_CYGWIN]) + AC_MSG_RESULT(flagging Cygwin) + PRE="sh -c {" + POST="}" + ;; + *mingw32*|*Mingw32*) + CFLAGS="$CFLAGS -mconsole -D_WSTRING_DEFINED=1" + EXTRA_LIBS="$EXTRA_LIBS -lwsock32" + AC_DEFINE([HAVE_MINGW32]) + AC_MSG_RESULT(flagging MinGW) + ;; + *osf*|*Osf*) + AC_CHECK_LIB(db, snprintf, EXTRA_LIBS="$EXTRA_LIBS -ldb") + ;; + *darwin*|*Darwin*) + LDFLAGS="$LDFLAGS $CFLAGS" + G=`$CC -v 2>&1 | grep version | awk '{print $3}' | awk -F. '{print $1$2}'` + if test x"$G" != x -a "$G" -lt 42; then + CFLAGS="$CFLAGS -no-cpp-precomp" + fi + if test x"$fpic" = x"yes" ; then + CFLAGS="$CFLAGS -fPIC" + AC_MSG_RESULT([adding -fno-common, -fPIC to CFLAGS]) + else + AC_MSG_RESULT([adding -fno-common to CFLAGS]) + fi + ;; + * ) + if test x"$fpic" = x"yes" ; then + if test "$CC" = "gcc" -o `$CC -v 2>&1 | grep -c gcc` != "0" ; then + CFLAGS="$CFLAGS -fPIC" + AC_MSG_RESULT(adding -fPIC to gcc) + else + AC_MSG_RESULT(none) + fi + else + AC_MSG_RESULT(none) + fi + ;; +esac + +AC_SUBST(EXTRA_LIBS) +AC_SUBST(EXTRA_OBJS) +AC_SUBST(PRE) +AC_SUBST(POST) +AC_SUBST(AWK) +AC_SUBST(GUNZIP) +AC_SUBST(GNUPLOT) +AC_SUBST(PIPEGLUE) + +AC_CONFIG_FILES(Makefile ./gnu/Makefile ./funtest/Makefile ./faq/Makefile) + +# generate pkg-config meta-data file +AC_CONFIG_FILES(funtools.pc) + +# for individual package that create libraries, we must run configure again, +# faking the subdirs into using the funtools library as their library +# this will run faster with --config-cache +ac_configure_args="--with-altlib=`pwd`/$LIB $ac_configure_args" +# AC_CONFIG_SUBDIRS(util fitsy filter wcs) +AC_CONFIG_SUBDIRS(util) +AC_CONFIG_SUBDIRS(fitsy) +AC_CONFIG_SUBDIRS(filter) +AC_CONFIG_SUBDIRS(wcs) + +AC_OUTPUT diff --git a/copyright b/copyright new file mode 100644 index 0000000..dfd5e80 --- /dev/null +++ b/copyright @@ -0,0 +1,30 @@ +Unless otherwise indicated, all source is: + +Copyright (C) 1999-2007 +Smithsonian Astrophysical Observatory, Cambridge, MA, USA + +Funtools is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Correspondence concerning Funtools should be addressed as follows: + +Eric Mandel +Smithsonian Astrophysical Observatory +MS 3 +60 Garden St. +Cambridge, MA 02138 USA + +eric@cfa.harvard.edu + +http://hea-www.harvard.edu/saord/funtools/ diff --git a/doc/asc2fits.c b/doc/asc2fits.c new file mode 100644 index 0000000..5be9a9e --- /dev/null +++ b/doc/asc2fits.c @@ -0,0 +1,86 @@ +/* + * + * asc2fits foo.fits < foo.ascii + * + * This is an example of generating a binary table from specific ASCII input. + * The more general case is much harder. + * + */ +#include +#include +#include +#include + +#define SZ_LINE 1024 +#define MAXREC 30 + +typedef struct EvStruct{ + int x, y, pha; + double time; +} *Event, EventRec; + +int main(int argc, char **argv) +{ + int got, put; + char tbuf[SZ_LINE]; + Fun fun; + EventRec events[MAXREC]; + Event ev; + + /* exit on gio errors */ + setgerror(2); + + if( argc < 2 ){ + fprintf( stderr, "usage: %s oname\n", argv[0]); + exit(1); + } + + /* open output file */ + if( !(fun = FunOpen(argv[1],"w", NULL)) ) + gerror(stderr, "Could not open the output file: %s\n", argv[1]); + + /* set up the (hardwired) columns */ + FunColumnSelect( fun, sizeof(EventRec), NULL, + "x", "J", "w", FUN_OFFSET(Event, x), + "y", "J", "w", FUN_OFFSET(Event, y), + "pha", "J", "w", FUN_OFFSET(Event, pha), + "time", "D", "w", FUN_OFFSET(Event, time), + NULL); + + /* ignore first line, which is the header */ + fgets(tbuf, SZ_LINE, stdin); + + /* process data lines */ + got = 0; + /* get next line */ + while( fgets(tbuf, SZ_LINE, stdin) ){ + /* ignore comments */ + if( (*tbuf == '\n') || (*tbuf == '#') ) + continue; + /* point to next buffer to fill */ + ev = &events[got]; + /* parse data record */ + if(sscanf(tbuf, "%d %d %d %lf", &ev->x, &ev->y, &ev->pha, &ev->time) != 4) + break; + /* got another record */ + got++; + /* flush this batch of records if necessary */ + if( got == MAXREC ){ + if( (put=FunTableRowPut(fun, events, got, 0, NULL)) != got ){ + gerror(stderr, "expected to write %d rows; only wrote %d\n", + got, put); + } + /* reset record counter */ + got = 0; + } + } + /* final flush */ + if( got ){ + if( (put=FunTableRowPut(fun, events, got, 0, NULL)) != got ){ + gerror(stderr, "expected to write %d rows; only wrote %d\n", + got, put); + } + } + FunClose(fun); + return(0); +} diff --git a/doc/changelog.html b/doc/changelog.html new file mode 100644 index 0000000..a4049c8 --- /dev/null +++ b/doc/changelog.html @@ -0,0 +1,1182 @@ + + +Funtools ChangeLog + + +

Funtools ChangeLog

+ +

+This ChangeLog covers both the Funtools library and the suite of +applications. It will be updated as we continue to develop and improve +Funtools. The up-to-date version can be found +here. +[The changelog for the initial development of Funtools, covering the +beta releases, can be found +here.] + +

Patch Release 1.4.6 (internal ds9 release)

+
    +

    +

  • Upgrade wcssubs to version 3.8.7 +

    +

  • Port to mingw (Windows) +
+ +

Patch Release 1.4.5 (internal ds9 release)

+
    +

    +

  • Fixed bug in funim.c which broke vcol functionality. +

    +

  • Removed permission checking from Find() on cygwin systems. This was broken +by Windows 7. +

    +

  • Removed addition of -no-cpp-precomp flag from gcc 4.2 and beyond. +
+ +

Patch Release 1.4.4 (internal ds9 release)

+
    +

    +

  • Fixed -J funcone, which was not properly outputting all rows. +

    +

  • Filter: when an image is flipped, the rotation angle must be reversed. +

    +

  • Filter: add support for windows-based ipc communication when using tcc +compiler. +
+ +

Patch Release 1.4.3 (internal ds9 release)

+
    +

    +

  • Filter: improve checks for existence of compiler, even if CC is set. +

    +

  • Change launch.h to xlaunch.h to avoid conflict with OS X. +

    +

  • handle flipped images in filtering +
+ +

Patch Release 1.4.2 (internal ds9 release)

+
    +

    +

  • Port to gcc 4.2. +

    +

  • Fix 1-byte filters on intel machines (missing SW1 no-op). +

    +

  • Remove ambiguity from filt.l (and calc.l) using [A-z] in a +case-insensitive lexer. +

    +

  • In funsky, the default unit for RA was changed from hours to degrees. +

    +

  • Fixed bug in funtable in which TCRVL header values were output as strings. +

    +

  • Added support for running funtools filters in Rosetta (i.e. running PPC +executables on an Intel Mac) by sensing and handling data swap requirements. +Only works with FILTER_PTYPE set to 'c' (can't link against wrong architecture +libraries). +

    +

  • Fixed bug in FITS library to allow "-" in extension names. +

    +

  • Code and documentation now agree that the copy extension specifier ('+') +comes after the extension name. +
+ +

Patch Release 1.4.1 (internal ds9 release)

+
    +

    +

  • Modified internal Launch() routine to use posix_spawn(), if necessary. +This is required for OS X 10.5 (leopard), which frowns upon use of fork() +and exec(). Also modified zprocess routines to use Launch(). +
+ +

Public Release 1.4.0 (15 August 2007)

+ +
    +
  • Public release of production-quality code, incorporating changes +and improvements from previous beta releases, including: +
      +
    • Support for access to ASCII text column files. +
    • Support for fast indexed access of binary tables. +
    • Support for database views of tables, i.e. pre-set values for the filter + specification, the columns to activate, and display format. +
    • New programs include funcone (cone search), funindex (create index files), + and funcen (calculate centroids within regions). +
    + +
+ +

Release 1.3.0b[n] (mainly internal SAO beta releases)

+
    + +

    +

  • Added -F[c] switch to change the column delimiter to the +specified character. + +

    +

  • Extended fundisp's format switch (-f) so that it can now handle complex +formats such as 'x=sometext%3d- y=othertest%3d.ext'. + +

    +

  • Added support for creating and processing 1D FITS images. + +

    +

  • Added vcol=colname and vcol=/colname to filter specifications to +support use of a third value column when binning 2D images. + +

    +

  • Added switches to funcone to write out data rows are not within +any cone (-J, -X) and centers which have no close data rows (-L). + +

    +

  • In funjoin, added ability to specify a numeric tolerance for when joining +two files. + +

    +

  • shared memory support in gio now can create a shared segment if w+ is +specified as the open mode. + +

    +

  • Changed reggeometry man page so that examples correctly show angles +going counter-clockwise from the x-axis instead of from the y-axis. + +

    +

  • Added checks to funmerge to ensure that all files have the same columns. + +

    +

  • Fixed bug in text support that prevented header-less files from being +processed properly. + +

    +

  • Added support for 64-bit images (bitpix=64) and table columns (TFORM=K). + +

    +

  • Filter code was not applying bscale/bzero to columns. + +

    +

  • Fixed funimage bug that caused a .5/block error in WCS CRPIX values +generated from binary tables. + +

    +

  • Added feq(a,b) and div(a,b) macros to funcalc. + +

    +

  • Added support for single-line #define to funcalc. + +

    +

  • Updated wcs library to 3.6.6 + +

    +

  • Fix bug in funcen in which ra,dec was not being calculated correctly +if physical and image coords did not match up. + +

    +

  • The filter syntax "col1 = col2" now explicitly generates an error +(you really want to do "col1 == col2"). + +

    +

  • Added -o switch to include offset from the nominal target position. + +

    +

  • Fundisp now displays multi-dimensional vector columns properly. + +

    +

  • Documented support for lists of files processed as a single file +using "list: file1 ... filen" syntax. + +

    +

  • Fixed bugs in support for pipe file type (i.e. ability to pass +commands as a filename using "pipe: cmd arg1 ... argn" syntax). + +

    +

  • Fixed bug in funhist processing of image-based pixel histograms +(i.e using "xy" for columns) where a region was specified. All pixels +outside the region were erroneously being added to the bin containing +the 0 value. + +

    +

  • Disabled multi-file processing in funds9, which was breaking support +for pathnames containing spaces and is not used by ds9 anyway. + +

    +

  • Added support for Views of tables, i.e. pre-set values for the +filter specification, the columns to activate, and display format +(though the latter is for fundisp only). + +

    +

  • Added -l switch to funimage to read x, y, val columns from a list. + +

    +

  • Removed useless and meaningless section syntax foo'[*]' because it +breaks pointer de-referencing on string columns (i.e. foo'[*xxx=='a']'). +Use foo'[*,*]' instead, as documented. + +

    +

  • String variables were not always being terminated properly in the +filter code because FITS 'A' data is not necessarily null-terminated. + +

    +

  • Added funtools version number to all usage() displays. + +

    +

  • Added explanation of switch arguments to many usage() displays. + +

    +

  • The filter keyword row# now supports single row selection as well +as range selection, i.e., "row#=100" along with previous "row#=100:200". + +

    +

  • fundisp now outputs "0x" before hex values. + +

    +

  • Fixed bug in filter parser which processed rangelists incorrectly +if spaces were put into the rangelist (i.e. "pha= 1 : 3" instead of +pha=1:3). + +

    +

  • Fixed a bug in funindex which created a wrongly named index file +if more than one "." was in the input file name. + +

    +

  • Added support to funcone to take ra, dec, radius from a list +(i.e. columns in a FITS file or a text file). + +

    +

  • Fixed a bug in FunColumnActivate so that if some columns are +explicitly activated while others are de-activated, only the +explicitly activated columns are activated (code was activating all +columns in this case). + +

    +

  • Fixed a bug in funindex which prevented indexing tables containing +a column named N. + +

    +

  • fundisp now encloses ASCII column values in single quotes (unless +-T is specified to output RDB format). + +

    +

  • If a filter specification only involves indexed columns, then the +compiled filter is not used. + +

    +

  • Funmerge can now be given a list of files to merge using @list syntax. +Also removed the restriction on how many files can be merged (was limited to +the max number of open files). + +

    +

  • Added ability to edit (add, delete, modify) header parameters in funhead +by specifying an output file (editing acts as a filter) and an edit command +file (which can be stdin). + +

    +

  • Funtools now contains preliminary code to support (fast) indexed access +of binary tables. See idx.html or "man funidx" for more details. + +

    +

  • Funtools now contains preliminary code supporting access to ASCII +column files. See text.html or "man funtext" for more details. + +

    +

  • Fixed bug in funcalc in which columns used in an expression were +always being replaced by new columns, with all associated parameters +(e.g. WCS) were being deleted. Now this only happens if the column +explicitly changes its data type. + +

    +

  • Fixed bug in funcalc in which the raw data and user data became out +of sync for one row after every 8192 (FUN_MAXROW) rows. + +

    +

  • Fixed bug in gio in which gseek returned 0 instead of the current byte +offset for disk files. + +

    +

  • Added funcone program to perform cone search on RA, Dec columns in +a FITS binary table. + +

    +

  • Fixed bug in polygon, pie and rotated box region filtering for +tables (nearby rows exactly in line between two non-vertical or +non-horizontal vertices were being accepted incorrectly). + +

    +

  • Fixed pie and panda regions so that the angles now start from +positive x axis == 0 degrees and run counter-clockwise, as +documented. They were going from positive y. NB: a similar change +was made to ds9 release 4.0b3. You must be using ds9 4.0b3 or later +in order to have the correct behavior when generating regions in ds9 +and using them in funtools. + +

    +

  • Added -p [prog] switch to funcalc to save the generated program. +instead of executing (and deleting) it. + +

    +

  • Upgraded zlib to 1.2.3. + +
+ +

Patch Release 1.2.4 (internal SAO and beta release only)

+
    + +

    +

  • In funcalc, added support for user-specified arguments via the +-a [argstr] switch. These arguments are accessed in the compiled program +using the supplied ARGC and ARGV(n) macros. + +

    +

  • Added -n (no header display) to fundisp to skip outputting header. + +

    +

  • Added checks for various types of blank filters. + +

    +

  • Added macros NROW (current row number) and WRITE_ROW (write current +row to disk) to funcalc. + +

    +

  • funcalc no longer requires that at least one data column be +specified in the compiled expression. + +

    +

  • Added FUN_NROWS to FunInfoGet() to return the total number of rows in +an input table (i.e. value of NAXIS2). + +

    +

  • The compiled funcalc program now includes stdlib.h and unistd.h. + +

    +

  • The util/NaN.h header file is now modified at configure time to +contain endian status for the target architecture. References to +specific platforms have been removed. + +

    +

  • Added -m switch to funtable to output multiple files, one for +each input region (and a separate file for events that pass the +filters but are not in any region). + +

    +

  • Added ability to add new parameters (FunParamPutx) after writing +data if space is previously reserved in the form of a blank parameter +whose value is the name of the param to be updated. (Also requires the +append argument of FunParamPutx be set to 2). + +

    +

  • Added ability to build shared libraries. With --enable-shared=yes, +shared library is built but not used. With --enable-shared=link, +shared library is linked against (requires proper installation and/or +use of LD_LIBRARY_PATH). + +

    +

  • Added -v [column] support to funcnts so that counts in a table +can be accumulated using values from a specified column (instead of +the default case where an integral count is accumulated for each event +in a region). + +

    +

  • Added funcen program to calculate centroids within regions +(binary tables only). Also added support for a funcen-based centroid +tool to funtools.ds9. + +

    +

  • Fixed bug which prevented successful filtering of columns containing +arrays. + +

    +

  • Added filter check to ensure that a column is not incorrectly used +as an array. + +

    +

  • Fundisp now displays column arrays indexed from 0, not 1. + +

    +

  • Added -i [interval] support to funcnts so that multiple intervals +can be processed in a single pass through the data. For example, +specifying -i "pha=1:5;pha=6:10;pha=11:15" will generate results in +each of 3 pha bands. + +

    +

  • Fixed calculation of LTV quantities when binning floating point +column data (value was off by 0.5). + +

    +

  • Added support for 'D' in floating point header values. + +

    +

  • Added -a switch to funimage and funtable to append output image or +table to an existing FITS file (as an IMAGE or BINTABLE extension). + +

    +

  • Added support for column scaling (TSCAL and TZERO) on input columns. +Note that the default column type is changed to accommodate scaling (e.g. +a column of type 'I' is changed to 'J', 'J' is changed to 'D') so that +the scaled values can be handled properly by programs such as fundisp +(which utilize default types). + +

    +

  • Added support to FunColumnSelect() for handling structs of arrays +(i.e. where returned columns are contiguous) instead of the default array +of structs (returned row are contiguous). This is done by specifying +"org=structofarrays" in the plist and passing a single struct containing +the arrays. + +

    +

  • When writing an rdb/starbase file, fundisp now outputs the full +column name, regardless of the width of the column (which ordinarily +is truncated to match). + +

    +

  • Fixed support for large files by changing all file positions variables +from "long" declarations to "off_t. + +

    +

  • Fixed bug in funcalc incorrectly processed multiple array +references (e.g. cur->foo[0]=cur->x;cur->foo[1]=cur->y;) within a single +line of code. + +

    +

  • Added FILTER_CFLAGS environment variable for all filtering. Also added +--with-filter-cc and --with-filter-cflags options on configure to allow +specification of a default C compiler and associated CFLAGS for filtering. +All of this is necessary in order to support 64-bit libraries under Solaris. + +

    +

  • Added the funtbl script to extract a table from Funtools ASCII output. + +

    +

  • Added code to funimage to update IRAF DATASEC keyword. + +

    +

  • Added checks to ensure that image dimensions are positive. + +

    +

  • Fixed a bug in funimage where int data was being scaled using BSCALE and +BZERO but these keywords also were being retained in the output image header. +Now the data are not scaled unless the output data type is float (in which +case the scaling parameters are removed). + +

    +

  • Fixed a bug in funmerge which prevented merging of files unless one of +the -f, -w, or -x switches were used. + +

    +

  • Fixed a bug in funtable and fundisp which caused the special '$n' column +to be output incorrectly. + +

    +

  • Fixed sort option in funtable, which previously worked only if the +record size was an even divisor of 8192 (and returned garbage otherwise). + +

    +

  • Fixed bug in filters involving FITS data type 'X' (bitfield). + +

    +

  • Fixed bug in funcnts in which the output angles and radii were +being displayed incorrectly when multiple panda shapes were specified. + +

    +

  • Fixed bug in pandas and pies using n= syntax when first angle +specified was greater than second. The resulting mask was of +the correct shape but contained only a single region. + +

    +

  • Table row access routines will now decrease maxrows if memory cannot be +allocated for maxrows*sizeof(row), i.e. if the size of a row is so large that +space for maxrows cannot be allocated. + +

    +

  • The FUN_MAXBUFSIZE environment variable was added to limit the +max buffer size that will be allocated to hold table row data. The +default is 5Mb. + +

    +

  • Generated PostScript and PDF versions of the help pages. + +

    +

  • Moved OPTIONS section before (often-lengthy) DESCRIPTION section in +man pages. + +

    +

  • All memory allocation now does error checking on the result +(except wcs library, which is external code). + +

    +

  • Removed some compiler warnings that surfaced when using gcc -O2. + +

    +

  • Updated wcs library to 3.5.5. + +

    +

  • Upgraded zlib to 1.2.1. + +
+ +

Patch Release 1.2.3 (12 January 2004)

+
    + +

    +

  • Generated man pages from the html pages. These are installed +automatically at build time. + +

    +

  • Changed instances of sprintf() to snprintf() to protect +against buffer overflow. + +

    +

  • Fixed a number of compiler warnings in non-ANSI compilers. + +

    +

  • Increased SZ_LINE parameter value from 1024 to 4096. + +
+ +

Patch Release 1.2.3b1 (19 August 2003)

+
    + +

    +

  • The rule for using comma to separate a table filter expression +and a region expression has been changed. The rule now states: +
      +
    • if both expressions contain a region, the operator used is or. +
    • if one (or both) expression(s) does not contain a region, the operator +used is and. +
    +This rule handles the cases of pure regions and pure column filters properly. +It unambiguously assigns the boolean and to all mixed cases. Thus: +
    +  foo.fits[circle(10,10,3),pi=1:5]
    +
    +and +
    +  foo.fits[pi=1:5,circle(10,10,3)]
    +
    +both are equivalent to: +
    +  foo.fits[circle(10,10,3) && pi=1:5]
    +
    + +

    +

  • When include files are used in filters, they now have implied +parentheses surrounding them. Thus, if a region file foo.reg contains two +regions (e.g. circle 1 2 3 and circle 4 5 6), the syntax: +
    +    pha=4:5&&@foo.reg
    +
    +is equivalent to: +
    +    pha=4:5 && (circle 1 2 3 || cir 4 5 6)
    +
    +instead of: +
    +    pha=4:5 && circle 1 2 3 || cir 4 5 6
    +
    +and the pha filter is applied to both regions. + +

    +

  • Filters and comments now can be terminated with the string +literal "\n" as well as ";" and the new-line character. This means +that a region can have comments embedded in it: +
    +    funcnts foo.fits "circle 512 512 10 # color=red\n circle 512 512 20"
    +
    + +

    +

  • Added capability to update the value of an existing parameter +after writing the table or image (assuming the output image is a +disk file or is being redirected into a file). + +

    +

  • Improved handling of parentheses in filter expressions. + +

    +

  • Fixed a bug in image (not event) regions in which circles and +annuli with radius of 1 pixel were not being processed. No counts and +no area would be found in such regions. + +

    +

  • Fixed a bug in funcnts in which the radii column values for out of sync +if multiple annuli were specified (instead of a single varargs or accel +annulus). + +

    +

  • By default, fundisp will display integer image data as floats +if the BSCALE and BZERO header parameters are present. + +

    +

  • Added -L switch to funhead to output starbase list format. + +

    +

  • Changed the name of the routine _FunColumnSelect to +FunColumnSelectArr, in order to emphasize that it is not +a private routine. + +

    +

  • Funcalc now checks to ensure that a column was specified as part of +the expression. + +

    +

  • Funcalc local variables in the compiled program now use a "__" prefix +to avoid conflicts with user-defined variables. + +

    +

  • Unofficial unsigned short (bitpix=-16) image data now is scaled +correctly using BSCALE and BZERO header parameters. + +

    +

  • Ported to Intel icc and gcc 3.3 compilers. + +

    +

  • Updated wcs library to 3.5.1. + +

    +

  • Changed license from public domain to GNU GPL. + +
+ +

Patch Release 1.2.2 (18 May 2003)

+
    + +

    +

  • Fixed funcalc so that it now actually compiles an expression and +runs it, instead of getting a "filter compilation error". Oops! + +

    +

  • Fixed bug in FunOpen in which the bracket specification was being +removed from the filename if a disk file was opened for "w" or "a". + +

    +

  • Fixed bug in FunFlush which prevented two successive calls to +FunImagePut from writing the second extension header properly. + +

    +

  • All filter routines now use gerror(stderr, ...) call instead of +fprintf(stderr, ...) so that output to stderr can be turned off (via +setgerror(level) or GERROR environment variable). + +

    +

  • All standard Funtools programs check for GERROR environment +variable before setting gerror flag. + +

    +

  • Some error messages about invalid region arguments were not being +printed. + +

    +

  • FITS parameters/headers now conform more closely to FITS standard: +
      +
    • Blank keywords are treated in the same way as COMMENTS and HISTORY cards +
    • XTENSION keywords are now exactly 8 characters long +
    • 'E' is output instead of 'e' in floating point param values +
    • PCOUNT and GCOUNT are output correctly for image extensions +
    • EXTEND=T is output in primary header +
    • COMMENTS and HISTORY start in column 9 +
    + +
+ +

Patch Release 1.2.1 (24 April 2003)

+
    + +

    +

  • Varargs ellipse and box annular regions were being +processed incorrectly when the following conditions all were met: +
      +
    • the region was specified in physical or wcs coordinates +
    • the data file contained LTM/LTV keywords, i.e., it +was blocked with respect to the original data file +
    • the program being run was an image program (e.g. funcnts, funimage) +
    +Varargs ellipse and boxes are regions of the form: +
    +  ellipse x y a1 b1 a2 b2 ... an bn [angle]
    +  box x y l1 w1 l2 w2 ... ln wn [angle]
    +
    +where at least 2 sets of axis (length) values were specified to form +an annulus (i.e. simple ellipses and boxes worked properly). With all +of the above conditions met, a region in physical coordinates saw its +second length argument converted incorrectly from physical coordinates +to image coordinates. In simple terms, this means that funcnts did not +process elliptical or box regions in physical coords on blocked images +properly. Note that blocking on the command line (e.g. foo.fits[*,*,2]) +did work when no LTM/LTV keywords existed in the file. + +

    +

  • The fundisp -f switch now supports specification of +column-specific display formats as well as a more convenient way to +specify datatype-specific display formats. Both use keyword=value +specifiers. For columns, use: +
    +    fundisp -f "colname1=format1 colname2=format2 ..." ...
    +
    +e.g. +
    +    fundisp -f "time=%13.2f pha=%3d" ...
    +
    +You also can specify display formats for individual datatypes using the FITS +binary table TFORM variables as the keywords: +
    +    fundisp -f "D=double_format E=float_format J=int_format etc."
    +
    +e.g. +
    +    fundisp -f "D=%13.2f I=%3d" ...
    +
    +The old position-dependent syntax is deprecated. + +

    +

  • Fundisp will now print out a single 16-bit (or 32-bit) unsigned +int for a column whose data format is 16X (or 32X), instead of +printing 2 (or 4) unsigned chars. + +

    +

  • Fixed bug in which fundisp was not able to display bitfield data for +raw event lists. + +

    +

  • Previously, when binning columns used implicitly in a region +and explicitly in a filter could suffer from a case sensitivity problem. +This has been fixed. + +

    +

  • Fixed internal mask=all switch on fundisp. + +

    +

  • Filter include files now simply include text without changing the state +of the filter. They therefore can be used in expression. That is, if foo1 +contains "pi==1" and foo2 contains "pha==2" then the following expressions +are equivalent: +
    +    "[@foo1&&@foo2]" is equivalent to "[pi==1&&pha==2]"
    +    "[pha==1||@foo2]"  is equivalent to "[pi==1||pha==2]"
    +    "[@foo1,@foo2]" is equivalent to "[pi==1,pha==2]"
    +
    + +

    +

  • Fixed bug in filter specification which caused a SEGV if a varargs-style +region was enclosed in parens. + +

    +

  • Updated wcs library to 3.3.2. + +
+ +

Public Release 1.2.0 (24 March 2003)

+
    + +

    +

  • BSCALE and BZERO are now always applied to int pixel data, instead of +only being applied if the desired output is floating point. + +
+ +

Beta Release 1.2.b3 (4 February 2003)

+
    + +

    +

  • In FunColumnSelect, added the ability to specify an offset into +an array in the type specification, using the extended syntax: +
    + [@][n]<type>[[poff]][:[tlmin[:tlmax[:binsiz]]]]
    +
    +The [poff] string specifies the offset. For example, a type specification +such as "@I[2]" specifies the third (i.e., starting from 0) element in +the array pointed to by the pointer value. A value of "@2I[4]" specifies +the fifth and sixth values in the array. + +

    +

  • Added a non-varargs version of FunColumnSelect called _FunColumnSelect: +
    +int _FunColumnSelect(Fun fun, int size, char *plist, 
    +                     char **names, char **types, char **modes, int *offsets,
    +                     int nargs);
    +
    + +

    +

  • Added support for sorting binary tables by column name using: +funtable -s "col1 col2 ... coln" ... + +

    +

  • Added the FUN_RAW macro which, when applied to the "name" parameter +of FunParamGets(), returns the 80-character raw FITS card instead of +only the value. + +

    +

  • Added support for comparing column values with binary masks of the +form 0b[01]+, e.g.: +
    +  (status&0b111)==0b001
    +
    +Previously, such masks had to be specified in decimal, octal, or hex. + +

    +

  • Completed support for type 'L' (logical) in fundisp and in filtering of +binary tables. + +

    +

  • Fixed bug in funhist that was improperly setting the number of bins +when the data was of type float. + +

    +

  • Fixed bug in filter/Makefile where the filter OBJPATH #define was +being passed to the wrong module. + +
+ +

Beta Release 1.2.b2 (7 October 2002)

+
    + +

    +

  • Updated wcs library to 3.1.3. + +

    +

  • Added support for reading gzip'ed files via stdin. + +
+ +

Beta Release 1.2.b1 (24 September 2002)

+
    + +

    +

  • Added the following accelerators to region filtering: +
    +  shape:      arguments:
    +  -----       ---------
    +  BOX         xcenter ycenter xw1 yh1 xw2 yh2 ... xwn yhn (angle)
    +  BOX         xcenter ycenter xwlo yhin xwout yhhi n=[number] (angle)
    +  CIRCLE      xcenter ycenter r1 r2 ... rn              # same as annulus
    +  CIRCLE      xcenter ycenter rinner router n=[number]  # same as annulus
    +  ELLIPSE     xcenter ycenter xw1 yh1 xw2 yh2 ... xwn yhn (angle)
    +  ELLIPSE     xcenter ycenter xwlo yhin xwout yhhi n=[number] (angle)
    +
    + +

    +

  • Added the following new pandas (Pie AND Annulus) to region filtering: +
    +  shape:    arguments:
    +  -----     ---------
    +  CPANDA    xcen ycen ang1 ang2 nang irad orad nrad  # same as panda
    +  BPANDA    xcen ycen ang1 ang2 nang ixlo iylo ixhi iyhi nrad (ang) # box
    +  EPANDA    xcen ycen ang1 ang2 nang ixlo iylo ixhi iyhi nrad (ang) # ellipse
    +
    + +

    +

  • Added support for filtering images using simple FITS image masks, +i.e. 8-bit or 16-bit FITS images where the value of a pixel is the +region id number for that pixel (and therefore must be greater than +0). The image section being filtered must either be the same size as the +mask dimensions or else be an even multiple of the mask. This works with +image-style filtering, i.e., funcnts can utilize a mask on both +images and binary tables. + +

    +

  • Added '$n' to fundisp column specification to allow display of +ordinal value of each row passing the filter. + +

    +

  • Added code to support region filtering on image sections. + +

    +

  • Fixed bugs which prevented filtering more than one ASCII region file. + +

    +

  • Fixed bug occasionally causing filter slave processes to become zombies. + +

    +

  • Fixed bugs in event filtering: annulus with inner radius of 0 +(i.e., a circle) was rejecting events with coordinates xcen, ycen. +Also, pie with angles of 0 and 360 was rejecting some events. +Image filtering (e.g. funcnts) did not have these problems. + +

    +

  • Filters now accept global exclude regions without an include region. +In such a case, the field region is implied. That is, "-circle(x,y,r)" +is equivalent to "field; -circle(x,y,r)", etc. + +

    +

  • Fixed panda so that it can be used as a global exclude. + +

    +

  • Allow empty ds9 region file (comments and globals only) to be +a valid filter. Totally ignore zero length region or include file. + +

    +

  • Fixed funcnts bug that was displaying 0 value as inner radius of +a circle, instead of just one radius value. + +
+ +

Public Release 1.1.0 (22 April 2002)

+ +

+New features include: +

    +

    +

  • Funtools programs now accept gzip'ed files as valid input. + +

    +

  • Improved security via replacement of system() function. + +

    +

  • fundisp, funcnts, funhist can output starbase/rdb format (tabs between columns, form-feeds between tables). + +

    +

  • Improved support for Windows platform, as well as new support for Mac OSX. +
+ +

Pre-Release 1.1.0e (10 April 2002)

+
    + +

    +

  • Added enough support to skip over variable length arrays in BINTABLES. +We will add full support if this non-standard construct becomes more widely +used. + +

    +

  • Fixed bug in underlying fitsy _gread() routine that was returning +an arbitrary bytes-read value if the input fd was invalid. + +
+ +

Pre-Release 1.1.0e (19 March 2002)

+
    + +

    +

  • Added additional check for Windows/PC to filter/Nan.h. + +

    +

  • Upgraded zlib library to 1.1.4 (fix double free security hole). + +
+ + +

Pre-Release 1.1.0e (27 February 2002)

+
    + +

    +

  • Changed filter/process.[ch] to filter/zprocess.[ch] to avoid name +collision with Cygwin include file. + +

    +

  • Added -a switch to funhead to display all headers in a FITS file. + +
+ +

Pre-Release 1.1.0e (11 February 2002)

+
    + +

    +

  • Fixed filter parser so that it ignores ds9 "ruler" and "text" markers +only up to the first \n or ; (was ignoring to last \n). + +

    +

  • The NBLOCK parameter in fitsy/headdata.c was too large for Mac OS X +(max size of a declared char buf seems to be about .5 Mb). + +
+ +

Beta Release 1.0.1b5 (31 January 2002)

+
    + +

    +

  • Fixed bug introduced in calculated IRAF LTM values in 1.0.1b3. + +

    +

  • Fixed bug in filter parser giving wrong answers when two range +lists were combined with and explicit boolean operator: +
    +  $ fundisp $S"[x=512&&y=511,512]" 
    +
    +incorrectly acted like: +
    +  fundisp $S"[(x=512&&y=511)||(y=512)]" 
    +
    +instead of: +
    +  fundisp $S"[x=512&&(y=511||y=512)]"
    +
    +In general, we recommend use of explicit parentheses. + +

    +

  • Fixed filter/NaN.h to recognize Compaq Alpha again (broken by their last change to cc). + +

    +

  • Removed redundant varargs definitions that conflicted with Alpha compiler definitions. + +

    +

  • Added blank line to inc.sed to work around Apple Mac OS X bug in which the +"i" (insert) command was treating final \\ as continuation \ in the text. + +

    +

  • Added include of mkrtemp.h to mkrtemp.c to get conditional compilation +for Mac OSX. + +

    +

  • Added support for --with-zlib to fitsy so that ds9 could use its own +copy of zlib (and not build the copy in fitsy). + +

    +

  • Removed config.cache and Makefile files from distribution tar file. + +
+ +

Beta Release 1.0.1b4 (26 January 2002)

+
    + +

    +

  • Make explicit that column filters are not permitted in an image +expression (such as the funcnts region arguments). + +

    +

  • Fix bug in region parser in which a region (without parens), +followed immediately by an operator: +
    +  circle 512 512 .5&&pi==1
    +
    +was not processing the final argument of the region correctly. + +

    +

  • Ignore new "tile" directive in filters (used by ds9). + +
+ +

Beta Release 1.0.1b3 (4 January 2002)

+
    + +

    +

  • Made modifications to Makefile.in to make releases easier. + +

    +

  • Added instructions Makefile.in so that funtools.h will always +have correct #defines for FUN_VERSION, FUN_MAJOR_VERSION, +FUN_MINOR_VERSION, and FUN_PATCH_LEVEL. + +

    +

  • Allow #include statements in funcalc program files. + +

    +

  • funimage now updates all 4 CDX_Y values by the block factor. + +

    +

  • Minor changes to make funtools work under darwin (Mac OS X). + +
+ +

Beta Release 1.0.1b2 (14 November 2001)

+
    + +

    +

  • Fixed FunOpen() bug (introduced in b1) in which filenames without +extensions SEGV'ed on open. Yikes! + +

    +

  • Funmerge now extends the tlmin/tlmax values of the output +binning columns so that merged events from widely separated files are +valid in the output table. + +

    +

  • In funhist, added -w switch to specify bin width (lo:hi:width) +instead of number of bins (lo:hi:num). Added support for this new +width option in funtools.ds9. + +

    +

  • If a tdbin value was set using bincols=(name:tlmin:tlmax:tdbin, ...), +the WCS parameters were not being updated properly. + +

    +

  • Cleaned up build support for zlib. + +
+ +

Beta Release 1.0.1b1 (6 November 2001)

+
    + +

    +

  • Added support for gzip'ed files to the underlying fitsy/gio +library. This means that all funtools programs now accept gzip'ed +files as valid input: +
    +  funcnts foo.fits.gz "circle 504 512 10"
    +
    +It is no longer necessary to run gunzip and pipe the results to +stdin of a funtools program. + +

    +

  • Funtools tasks are now placed in a sub-menu in the DS9 Analysis +menu, instead of at the top level. + +

    +

  • Fixed a bug in funcnts in which the bottom-most pixel of a small +circle or annulus region could be missed when the region is only one +pixel wide for that value of y. + +

    +

  • Added -n switch to funhist so that table histograms could be +normalized by the width of the bin (val/(hi_edge-lo_edge)). + +

    +

  • Added -T switch to fundisp, funcnts, funhist to output in +starbase/rdb format (uses tabs instead of spaces between columns, +form-feeds between tables, etc.) + +

    +

  • Fixed a bug in which the field() region was not being properly +processed in combination with an image section. This could affect +funcnts processing of image data where an image section was specified +(though it usually resulted in a funcnts error). + +

    +

  • Fixed bug in display of binary table header for vector columns. + +

    +

  • Filters now recognize hex constants (starting with 0x) and long +constants (ending with L). + +

    +

  • Filenames containing a ':' are now only treated as sockets if they +actually are in the form of a valid ip:port. + +

    +

  • Replaced funtools.ds9 with a new version that calls a new funds9 +script, instead of calling funcnts or funhist directly. The new script +supports gzip'ed files and bracket specifications on filenames at the +same time, which the direct call could not. Also the new script has +better error reporting. + +

    +

  • Replaced system() call used to compile filter and funcalc +expression with a special launch() call, which performs execvp() +directly without going through sh. (launch() works under DOS and has +fewer security problems.) + +

    +

  • Fixed image filter code in which the field() region was being ignored +if it was combined with one or more exclude regions (and no other include +regions), resulting in no valid pixels. + +

    +

  • Changed use of getdtable() to FD_SETSIZE in calls to select(). + +

    +

  • Added code to guard against FITS binary tables without proper TFORMx +parameters. + +

    +

  • Added support to FunParamGets so that it returns the raw FITS card +if the specified input name is NULL and the input n value is positive. + +

    +

  • Fixed bug in underlying fitsy code that set the comment in a +header parameter. + +
+ + +

Public Release 1.0.0 (31 July 2001)

+
    +

    +

  • "a new day with no mistakes ... yet" +
+ +
+Index to the Funtools Help Pages +
Last updated: 22 April 2002
+ + diff --git a/doc/changelog_beta.html b/doc/changelog_beta.html new file mode 100644 index 0000000..4e3ccd3 --- /dev/null +++ b/doc/changelog_beta.html @@ -0,0 +1,953 @@ + + +Funtools ChangeLog + + +

Funtools ChangeLog

+ +

+This ChangeLog covers both the Funtools library and the suite of +applications. It will be updated as we continue to develop and improve +Funtools. The up-to-date version can be found here. + +

Beta release 1.0.b28 (06/26/01)

+
    + +

    +

  • In funcnts, removed extra new-lines from the primary table, +inadvertently added in cases where zero-area rows are skipped. + +

    +

  • Added code to support columns in binary tables that do not have names. + +

    +

  • Changed the ds9 radial plot so that the radius (x value) for each +plotted point is taken to be the middle of the annulus, (Rin+Rout)/2, +instead of just the inner annulus, Rin. + +
+ +

Beta release 1.0.b27 (06/21/01)

+
    + +

    +

  • Added missing new-lines in funcnts primary tables that did not +have -r switch. + +

    +

  • Filtering with dynamic shared objects (gcc only) now links the +region code into the shared object, instead of relying on finding the +region code in global space. + +

    +

  • A few minor changes to column headers in funcnts. +
+ +

Beta release 1.0.b26 (05/21/01)

+
    +

    +

  • Fixed funcnts to work properly when the background region +overlaps the source and therefore explicitly excludes the source. +It was simply ignoring the source regions in such a case. + +

    +Added a second DS9 init file, funcnts2.ds9, which contains funcnts +and radial profile routines that work from the image stored in DS9's +memory, rather than the original FITS file. This is useful in cases +where no original FITS file exists (e.g., a temp file was created +by a program and sent to DS9). + +

    +

  • Fixed funcnts so that region specified with a variable number of +arguments must come last (as is the case with panda and the n= +accelerator). Thus, a region specification such as "pie 504 512 10 20 +30 & circle 504 512 10" is now properly an error. Using "circle 504 512 10 +& pie 504 512 10 20 30" instead ensures that the circle is applied to +each pie. + +

    +

  • Fixed funcnts output of radii/angles when boolean expressions +such as "pie & annulus" are specified. + +

    +

  • Enhanced funcnts so that -r outputs valid radii for circular regions. + +
+ +

Beta release 1.0.b25 (4/19/01)

+
    + +

    +

  • Added support to funtable to generate a FITS binary table +from an image. By default, a 3-column table is generated, where the +columns are "X", "Y", and "VALUE". For each pixel in the image, a +single row (event) is generated with the "X" and "Y" columns assigned +the dim1 and dim2 values of the image pixel, respectively and the +"VALUE" column assigned the value of the pixel. If the -i +("individual" rows) switch is specified, then only the "X" and "Y" +columns are generated. However the number of rows (events) are written +out for each image pixel is equal to the value of that image pixel(or +1, whichever is larger). + +

    +

  • Added -z switch to funcnts to display shapes in primary table +that have no area. This is useful when automatic processing assumes +that there are a set number of rows. + +

    +

  • Reworked how the "$region" column is handled. A "$region" column +can now be added to a table already having a "region" column. If a +"region" column already exists, the new column will be "region1". If +that exists, we try "region2", etc. + +

    +

  • Added the header parameters EXTNAME="IMAGE" and EXTVER=1 when an +image extension of created automatically. + +

    +

  • When funcnts is run with -r, the rad1, rad2, ang1, and ang2 columns +are filled in with "NA" if the shape is not annulus, pie, or panda (instead +of being left blank). + +

    +

  • Changed funcnts to display arc-sec/pixel instead of degrees/pixel in the +output header. + +

    +

  • Fixed bug in FunColumnSelect() that prevented a new table from +being created that consists only of new columns. + +

    +

  • Fixed processing of blank values in FunImageRowGet() (was a SEGV). + +

    +

  • Fixed fundisp processing of images (SEGV upon completion, trying to +free space only used by tables). + +

    +

  • Fixed bug in funcalc which left executable in /tmp space if -n +(no execute) was specified. + +

    +

  • Fixed various bugs processing raw event files, especially on +little-endian machines and reading these files via stdin. + +

    +

  • Changed rad1, rad2 columns to radius1, radius2 in funcnts. + +

    +

  • Purified dynamically loaded filter code (since purify now can work +with gcc). + +
+ +

Beta release 1.0.b24 (03/26/01)

+
    + +

    +

  • First release of funcalc, the Funtools table calculator. +funcalc is a calculator program that allows arbitrary +expressions to be constructed, compiled, and executed on columns in a +Funtools table (FITS binary table or raw event file). It works by +integrating user-supplied expression(s) into a template C program, +then compiling and executing the program. funcalc expressions +are valid C statements, although some important simplifications (such +as automatic declaration of variables) are supported. + +Within a funcalc expression, reference is made to a +column of the current row using the C syntax +cur->[colname], e.g. cur->x, cur->pha, etc. Local scalar +variables can either be defined using C syntax at very the beginning +of the expression, or else they can be defined automatically by +funcalc (to be of type double). Thus, for example, a swap of +columns x and y in a table can be performed using either of the following +equivalent funcalc expressions: +
    +  double temp;
    +  temp = cur->x;
    +  cur->x = cur->y;
    +  cur->y = temp;
    +
    +or: +
    +  temp = cur->x;
    +  cur->x = cur->y;
    +  cur->y = temp;
    +
    +When this expression is executed using a command such as: +
    +  funcalc -f swap.expr itest.ev otest.ev
    +
    +the resulting file will have values of the x and y columns swapped. +Many other features are available in funcalc to make table +manipulation easy. See the Funtools program.html documentation. + +

    +

  • First release of the funtools.ds9 set-up file for adding +Funtools analysis programs to the DS9 Analysis menu. This set-up file +is installed in the same bin directory where Funtools programs are +installed and can be loaded into DS9 from the Load Analysis +Commands ... option of the Analysis menu. Alternatively, +you can tell DS9 to load this file each time it starts by adding the +file to the Edit->Preferences->Analysis +Menu->Analysis File menu option. + +

    +

  • Added support for non-integral binning of binary tables. The bincols +specifier on the command line now can take the form: +
    +  bincols=([xname[:tlmin[:tlmax:[binsiz]]]],[yname[:tlmin[:tlmax[:binsiz]]]])
    +
    +where the tlmin, tlmax, and binsiz specifiers determine the image binning +dimensions: +
    +  dim = (tlmax - tlmin)/binsiz     (floating point data)
    +  dim = (tlmax - tlmin)/binsiz + 1 (integer data)
    +
    +These tlmin, tlmax, and binsiz specifiers can be omitted if TLMIN, +TLMAX, and TDBIN header parameters (respectively) are present in the +FITS binary table header for the column in question. Note that if +only one parameter is specified, it is assumed to be tlmax, and tlmin +defaults to 1. If two parameters are specified, they are assumed to be +tlmin and tlmax. + +

    +

  • Added "mask=transparent" support to the plist argument in +FunTableRowGet(). If this string is passed in the call's plist +argument, then all events are passed back to the user. This is useful +when FunColumnSelect() specifies "$region" as a column in order to +return the regionid value for each event. In such a case, events +found in a region have regionid >0, events passing the filter but not +in a region have regionid == -1, events not passing the filter have +regionid ==0. + +

    +

  • Added FUN_WCS0 to the FUN_WCS option available to FunInfoGet(). +The original FUN_WCS option returns WCS Library handle (for use with +Doug Mink's wcssubs library) suitable for use with images, regardless +of whether the data are images or tables. For this structure, the WCS +reference point (CRPIX) has been converted to image coordinates if the +underlying file is a table (and therefore in physical coordinates). The +new FUN_WCS0 structure has not had its WCS reference point converted +to image coordinates. It therefore is useful when passing processing +physical coordinates from a table. + +

    +

  • Added -G switch to funcnts to print out floating point values +with maximum %.14g precision. + +

    +

  • Added -l switch to fundisp, which displays the pixels of an image as +a list with X, Y, VAL columns. + +

    +

  • Added support for images to funhist. The program will create +a histogram of the values found in each pixel, or it can perform +a projection over either axis. + +

    +

  • All Funtools programs now accept "-" to mean "stdin" or "stdout", +when the io mode is "r" or "w", respectively. + +

    +

  • Changed behavior of the prec (precision) argument in FunParamPutd() +(and the underlying fitsy routine ft_cardfmt()) so that if the double +value being put is less than 0.1 or greater than or equal to +10**(20-2-prec), then %20.[prec]e format is used, otherwise +%20.[prec]f format is used. + +

    +

  • Fixed behavior of "merge=replace" in FunColumnSelect() so that if +tlmin/tlmax values are not specified in the replacing column, but are +specified in the replaced column, then the original tlmin/tlmax values +are used in the replacing column. + +

    +

  • Improved funcnts error-handling when no valid region is specified. + +

    +

  • Fixed region parsing of '#' comment character so that comments +are terminated by new-lines, but not ';'. This is more intuitive behavior. + +

    +

  • Fixed region parser so that a region (without parens), followed by +a column expression (e.g., "circle 5 5 1,pha==4") is processed correctly. + +

    +

  • Fixed funcnts so that the timecorr parameter specified by -t +[timecorr] can be in lower case. + +

    +

  • Fixed panda region shapes when processing a blocked image. The +number of pies and number of annuli (args 5 and 8) were incorrectly +being divided by the block factor (i.e., they were being treated as +sizes). + +

    +

  • Fixed bug in funcnts that resulted in slightly smaller +integerized pixel boundaries being used when filtering events. This +does not affect ordinary event filtering(in fundisp, funtable, etc.). +In funcnts (which filters binary table events using image-style pixel +filtering), this bug could result in fewer photons being counted than +is the case when the equivalent image is used. + +

    +

  • Fixed funcnts to work with raw event files on little-endian machines. + +

    +

  • Fixed funhist so that it will read data from a pipe. + +

    +

  • Fixed region parser (and funcnts) so that an include file ending +with a comment stops the comment at the end of the include file. + +

    +

  • Clarified the meaning of the "," operator (should it be "or" or +"and") between a region and a non-region expression in a filter: if +the second operand in the expression contains a region, the operator +is "or", otherwise it is "and". + +

    +

  • Fixed bug in funmerge, which was not handling integerization of +negatively-valued physical pixels properly (not actually used in any +known application). + +
+ +

Beta release 1.0.b23 (02/16/01)

+
    +

    +

  • Fixed funcnts to report area correctly in arc-seconds. + +

    +

  • Fixed funcnts to report radii correctly when summing. + +

    +

  • Fixed bug in fundisp: a SEGV when trying to display an ASCII column +from a binary table. + +
+ +

Beta release 1.0.b22 (02/15/01)

+
    + +

    +

  • Funcnts now will automatically output appropriate columns from +the primary table in units of arc-seconds instead of pixels if WCS info +is present. Use -p to force the output to be in pixels. + +

    +

  • Added qualitative exposure correction to funcnts by means of the switch +"-e source_exp[;background_exp]". For each region, the average exposure is +calculated and net counts (and background) are divided by the average +exposure. See programs.html for more info. + +

    +

  • Added qualitative time correction to funcnts by means of the switch +"-t source_time[;background_time]". The net counts (and background) are +divided by this time. See programs.html for more info. + +

    +

  • Improved funcnts output. For example, column units are displayed +(since surf_bri units now can be cnts/pix**2, cnts/arcsec**2, etc.) + +

    +

  • Changed funcnts.gnuplot and funhist.gnuplot scripts to funcnts.plot +and funhist.plot, respectively. The new scripts take an argument +such as "gnuplot" or "ds9" and output data appropriate for each +target. Also enhanced funcnts.plot so that it senses the axis units +automatically. + +

    +

  • Fixed bug in funcnts when handling regions whose centers are out of the +image. Processing often resulted in BUS ERROR or zero counts, and it took +forever to reach those results + +

    +

  • Fixed bug in FunImagePut() when outputting float data on +little-endian machines (PCs/Dec Alpha) -- an erroneous error was +signaled trying to convert from native to IEEE before writing. + +

    +

  • Fixed bug in fundisp when displaying the mask of a double/float +image using the mask=all option. + +

    +

  • Fixed bug in fitsy/headimage/ft_imageloadhead(fits), in which the +default value for LTV[1,2] was incorrectly set to 1.0, not 0.0. This +means that region physical coordinates applied to FITS images and +arrays that did not have LTM/LTV keywords were 1 pixel off. + +

    +

  • Fixed obscure bug in region circle processing when a block factor +is specified in the section command but the circle has radius less +than the block. + +

    +

  • Fixed bug in FunImageGet which was returning the full image in +cases where a region was specified but no image pixels were in the +region. An empty image is now returned. +
+ +

Beta release 1.0.b21 (02/01/01)

+
    + +

    +

  • In funcnts, added ability to specify a separate background file. +When using a separate background file, the background area will be +normalized by the ration of the pixel sizes of the two files, if +requisite WCS info is available. + +

    +

  • In funcnts, added -r switch to output radii (and angle) +information. This is useful with annulus and panda shapes when +plotting radial profiles. An example plot script, funcnts.gnuplot, is +available for use with gnuplot (3.7 and higher): +
    +  funcnts ... | funcnts.gnuplot
    +
    + +

    +

  • First version of the funhist program, which creates a 1D +histogram by binning the specified column in a binary table. The +tabular output can be plotted using funhist.gnuplot: +
    +  funhist snr.ev x | funhist.gnuplot
    +
    + +

    +

  • Added additional error messages to funcnts when invalid binning +parameters are found for one or more binary table binning columns. + +

    +

  • Fixed bug in FunImagePut() which sometimes occurred when +dimensions were passed in the calling sequence. If, in addition, a +reference handle was passed in the FunOpen() call, then the output +dimensions are erroneously taken from the reference file, not the +passed dimensions. + +

    +

  • Fixed bug in filter lex code (filt.l) in which yyrestart was +being called incorrectly with the string to be parsed as the argument +(should be NULL). + +

    +

  • Fixed bug in filter code in which the Sun cc compiler was creating +a useless .o file in the working directory. + +

    +

  • Fixed bug in region parser which made it impossible to specify +angles with a 'd' or 'r' suffix unless WCS info was in the file. (The +use of 'd' or 'r' with angle is independent of WCS but the check was +there anyway.) + +
+ +

Beta release 1.0.b20 (11/29/00)

+
    + +

    +

  • Fixed a serious bug in which exclude regions were being ignored +when multiple annuli were specified. That is, in a region specification +such as: +
    +  annulus 512 512 0 100 n=4; -circle 510 510 20
    +
    +or +
    +  annulus 512 512 0 25 50 75 100; -circle 510 510 20
    +
    +the excluded region was not being sensed properly. Note that +single regions did work properly with exclude regions. + +

    +

  • Optimized funcnts so that the time for processing an event list +(binary table) is no longer proportional to the number of pixels in +the image. The unoptimized code was taking forever with Chandra ACIS +images (8192**2 pixels), even with relatively few events. + +

    +

  • Fixed bugs that gave incorrect answers when image regions were +combined with image sections. + +

    +

  • Fixed bug in parsing image section of the form: "foo.fits[*,6:9,2]", +i.e. the default ("*") x dimensions, followed by specified y dimensions. + +

    +

  • Added -g option to funcnts to change some output formats from +12.3f to 12.3g to accommodate display of very small numbers. +
+ +

Beta release 1.0.b19 (11/21/00)

+
    +

    +

  • Fixed bug in filter code that caused a SEGV on Solaris machines +when the first specified spatial region is an exclude region. Our +user-supplied qsort/compare algorithm was confusing the Solaris qsort() +routine, causing it to SEGV by trying to process a record prior to the +beginning of the passed array of records. +
+ +

Beta release 1.0.b18 (11/13/00)

+
    +

    +

  • Fixed bug in handling bitpix=-32 (single float) images. + +

    +

  • Fixed gio gskip routine to better handle skip of 0 bytes. +
+ +

Beta release 1.0.b17 (11/10/00)

+
    + +

    +

  • Fixed working of $REGION keyword in funtable. + +

    +

  • Removed FunFlush() from end of funtable (it was redundant). + +

    +

  • Fixed bug in gopen() handling of "pipe:". + +

    +

  • Fixed bug in gseek() where pipes, streams, and sockets were +not skipping bytes properly (that can do skips, but cannot do other +sorts of seek). + +
+ +

Beta release 1.0.b16 (10/23/00)

+
    + +

    +

  • Added -s switch to funcnts to support display of summed results +(as well as individual results for each region), i.e. each row in the +summed bkgd-subtracted table contains the sum of counts and areas from +previous rows. + +

    +

  • Added -f [format] switch to fundisp to allow control over the +display format for each data type. + +

    +

  • Fixed bug in which regions could be incorrectly re-ordered. This +was a problem with annular ellipses and rectangles created by ds9 and +then used in funcnts (the only program where the order of the regions is +important). +
+ +

Beta release 1.0.b15 (10/11/00)

+
    + +

    +

  • Changed the names of routines FunEventsGet() and FunEventsPut() +to FunTableRowGet() and FunTableRowPut(), respectively. The old names +are still valid (using #define in funtools.h), so no code change is +required. + +

    +

  • Changed funevents program name to funtable, in line with API changes. + +

    +

  • Renamed FunInfoGet/Put() parameter FUN_EVSIZE to FUN_ROWSIZE, in +order to reflect change from use of "events" to use of "row" in +funtools binary table support. The old name is still supported as +an alias. + +

    +

  • Completed first version of funmerge program to merge FITS binary tables. + +

    +

  • Fixed bug in line region shape that was causing a SEGV with event data. + +

    +

  • Fixed minor compiler warnings using "gcc-Wall". + +

    +

  • Added the ability for FunOpen() to open a list of event files and +read events from this list synchronously or asynchronously. This +facility is part of an experimental set of parallel processing +techniques that are being added to funtools. Documentation will be +forthcoming when we know which techniques have value! +
+ +

Beta release 1.0.b14 (9/22/00)

+
    + +

    +

  • Added first version of funmerge program to merge FITS binary tables. + +

    +

  • Changed the output format of funcnts so that the main results +(background-subtracted table) are displayed first. This means that the +result columns always start at line 4 in the file (after a 1-line +comment and a 2-line header) and end at the first blank line. The +fixed format makes it easier for programs such as sed to extract +results for further processing. For example: + +
    + csh> cat fun.sed
    + 1,/---- .*/d
    + /^$/,$d
    +
    + csh> funcnts snr.ev[pha==1] "annulus 512 512 0 200 n=8" | sed -f fun.sed
    +   1       49.000     7.000        0.000     0.000      1941    0.025    0.004
    +   2       91.000     9.539        0.000     0.000      5884    0.015    0.002
    +   3      129.000    11.358        0.000     0.000      9820    0.013    0.001
    +   4      159.000    12.610        0.000     0.000     13752    0.012    0.001
    +   5      176.000    13.266        0.000     0.000     17652    0.010    0.001
    +   6      183.000    13.528        0.000     0.000     21612    0.008    0.001
    +   7      137.000    11.705        0.000     0.000     25528    0.005    0.000
    +   8      198.000    14.071        0.000     0.000     29420    0.007    0.000
    +
    + +

    +

  • Fixed bug in row# processing in which all range was ignored if +lo range value was 1 (e.g., row#=1:7). + +

    +

  • Fixed bug in event header processing in which the multiple +instances of keywords HISTORY, COMMENT, and CONTINUE were not all +being copied from the old to the new header (e.g. in funevents). + +

    +

  • Fixed processing of ARRAY() and EVENTS() specifiers in FunOpen(). + +

    +

  • Fixed 'make clean' directive so that it also cleans funtools subdirs. +
+ +

Beta release 1.0.b12 (9/5/00)

+
    + +

    +

  • Improved the performance of panda regions so that the funcnts +"wall time" now is proportional to the size of the panda region, not +the size of the image. (The latter is the case with the pie shape; use +of panda is recommended over pie.) This means that it is possible to +run funcnts on an ACIS file at zoom 1 (8192x8192) in seconds rather +than (tens of) minutes. + +

    +

  • Added support for INET sockets to gio and hence, to funtools. +This means that you can read/write from/to sockets on other machines, +creating a distributed pipeline. For example: +
    +  on m1:  funevents foo.ev m2:1428
    +  on m2:  funevents :1428 m3:1428
    +  on m3:  funevents :1428 ...
    +
    +etc. Tests indicate that this is faster than pipes on a single +machine, once the CPU is saturated on that machine. (But note that it +is not faster until the CPU is saturated, due to the efficiency of +Unix pipes and the I/O wait time on non-saturated CPUs.) This new +facility implements the parallel processing technique called "process +decomposition" for pipelines, in which a pipeline process is run on +several machines at once, with different machines handling separate +parts of the pipeline process. +

    +NB: socket support requires that the libraries: +

    +  -lsocket  -lnsl
    +
    +be added to the Solaris link line. + +

    +

  • Added support for the row#=lo:hi keyword to process specific rows +in a FITS binary table. For example: +
    +  funevents "test.ev[row#=3:8]" stdout ...
    +or
    +  funevents "test.ev[row#=(3,8)]" stdout ...
    +
    +will only process rows 3 to 8 (inclusive) of the test.ev file. Along +with image section specification, use of the row#= keyword implements +the parallel processing technique called "data decomposition", in +which several copies of a single program operate on different parts of +a single data file. + +

    +

  • Added guard code to image region processing to catch illegal event +values. + +

    +

  • Fixed bug when writing FITS image extensions in which dim1, dim2, +and bitpix were being output as 0. + +

    +

  • reversed the y row order of displayed images in fundisp, so that pixel +(1,1) is in the lower left corner, as is the case for ds9 image display. +
+ +

Beta release 1.0.b11 (8/10/00)

+
    + +

    +

  • Fixed annulus accelerators and panda regions -- again. Old +problems (from the original implementation) were uncovered related to +the use of these shapes in boolean expressions. Documented an old +restriction that panda and accelerators must be put last in a boolean +expression and added code to signal an error if they are not placed last. + +

    +

  • The behavior of the point shape was changed so that multiple x,y +pairs in a single shape specifier now are assigned different region +ids. This makes the behavior of points and annuli consistent with one +another. +
+ +

Beta release 1.0.b10 (8/08/00)

+
    + +

    +

  • Fixed annulus accelerators and panda regions. These were +broken when dynamic loading was implemented. + +

    +

  • Fixed a bug in the event filter body code (i.e., the basis for +the slave filter program). Reading the data sometimes incorrectly +calculated the number of events being passed -- which only showed up +occasionally on the Alpha! +
+ +

Beta release 1.0.b9 (8/03/00)

+
    +

    +

  • Removed compilation of some extraneous routines from wcs library. +Also renamed wcssubs directory to wcs. + +

    +

  • Added calls to hlength() before wcsinit(). This is necessary in +ds9 (and is a safeguard in other programs) because once hlength() is +called before any invocation of wcsinit(), it must always be used. + +

    +

  • Fixed bug in filter code in which CTYPE1 and CTYPE2 param values +were not being passed to wcsinit() as valid FITS strings: the single +quotes were missing. + +

    +

  • Fixed a bug in fitsy in which the card buffer was not being +null-terminated properly when a "card insert" call reallocated space +for more cards. + +

    +

  • Added protective code so that one cannot set FILTER_PTYPE to +"dynamic" if dynamic filter objects are not available. + +

    +

  • Ported to Debian Linux, which (believe it or not) required +removal of extraneous strdup() and strstr() declarations in the code +(apparently these are macros in that version of Debian gcc, so you +cannot declare them). +
+ +

Beta release 1.0.b8 (8/01/00)

+
    + +

    +

  • Added new filter ptype ("contained"), which builds a separate +process by compiling both the main routine and the region code. This +is different from the "process" ptype, which compiles the main +routine, but links in pre-compiled region code (in order to make the +program build more quickly). It is needed by ds9 so that the latter +does not have to keep track of the compiled region code module. +
+ +

Beta release 1.0.b7 (7/25/00)

+
    + +

    +

  • Changed filter code so that, in simple cases, we can access the +contents of a file. This is needed so that funcnts can work properly in one +oft-used case, i.e., if the file foo contains: +
    +  circle 5 5 1
    +  circle 4 4 1
    +
    +then: +
    +  funcnts foo.fits @foo
    +
    +now will display the 2 regions in its output, instead of displaying the +near useless "@foo". This only works for simple cases where only a file +is input, not in odd combinations like: +
    +  funcnts foo.fits "@foo,circle 1 1 1"
    +
    + +

    +

  • Added programming tutorial and enhanced the programming +reference documentation. + +

    +

  • Ported to Windows via the Cygwin environment from +RedHat. We tested on an NT box, which has decent multi-tasking +support. Whether it works on Windows95 is unknown. + +

    +

  • Upgraded WCS libraries to 2.8.3. + +

    +

  • Ported to new and strict SGI C compiler, which uncovered +lots of unused variables, etc. + +

    +

  • Fixed FunParamPut status return. +
+ +

Beta release 1.0.b6 (7/15/00)

+
    + +

    +

  • Ran Purify with each high level program and each funtest +program. +

    +

  • Changed behavior of merge=update option of +FunColumnSelect() so that the update of the user column value only +takes place if the user mode has "w" in it. Previously, merge=update +overrode the mode flag and always updated the user value. Note that +all calls to FunColumnSelect with merge=update must change "r" to "rw" +in order to have that user column merged. (The merge=replace already +was checking the mode flag -- the fact that they were doing different +things is a bug.) +

    +

  • Added ability to FunOpen extensions by HDU name. (I +thought I had already done this!) +

    +

  • Fixed bug that was adding a NULL table at the end of +most binary table files (i.e., those that were not copying the rest of +the input file). +

    +

  • Re-ported to Alpha. The problem found most often was the +casting of pointers to ints when doing pointer calculations, i.e.: +
    +  char *s, *t;
    +  n = ((int)s - (int)t);
    +
    +which is invalid on the 64-bit Alpha. Instead use: +
    +  char *s, *t;
    +  n = (s - t);
    +
    +Also broadened the check for use of dlopen in configure to match Alpha's +library configurations (On Alpha, dlopen is in libc). + +

    +

  • Changed FunColumnActivate() so that funtools will +process columns in the sorted order specified by that routine. Thus: +
    +  fundisp foo.ev "time y x"
    +
    +will display columns in that order. + +

    +Sorting does not take place if the activate list contains only exclude +columns (since there is nothing to sort). Also, you can turn off +sorting altogether (mimicking the old behavior) by calling +FunColumnActivate() with a "sort=false" in the plist argument: +

    +  FunColumnActivate(fun, "y x", "sort=false");
    +
    +or by adding "sort=false" to the activate string itself: +
    +  # by default, its sorted
    +  fundisp $E "time y x"
    +               TIME       Y       X
    +   ---------------- ------- -------
    +             6.8500      -7      -7
    +             6.8600      -7      -7
    +
    +while: +
    +  # turn off sorting
    +  ./fundisp $E "time y x sort=false"
    +         X       Y             TIME
    +   ------- ------- ----------------
    +        -7      -7           6.8500
    +        -7      -7           6.8600
    +        -7      -7           6.8700
    +
    +
+ +

Beta release 1.0.b5 (7/8/00)

+
    + +

    +

  • Changed all FunParamSet calls to FunParamPut, to make the +naming consistent with FunImagePut, FunEventsPut, etc. + +

    +

  • Fixed bugs preventing tlmin/tlmax from being changed by the +user in binary tables. Also tlmin/tlmax are now written out using a +data type that matches the data type of the respective column. + +

    +

  • Extended filter syntax to allow "," as separator between +filename and filters (as well as brackets), i.e.: +
    +  foo.fits,events  # event extension
    +  foo.fits,pha==1  # filter on default extension
    +  foo.fits,1       # first extension
    +
    +Note that all but simple expressions will need to be quoted because +of the shell: +
    +  foo.fits,pha==1&&pi==2  # & tells shell to run in bkgd
    +  foo.fits,pha==1||pi==2  # similar problems with pipes
    +  foo.fits,circle(1,2,3)  # parens are grabbed by shell
    +
    + +

    +

  • Fixed configure so that --with-lib is no longer necessary +to generate a single funtools.a library. Removed this argument from +saoconfig. Note that: +
    +  ./configure
    +
    + +now works properly again, so saoconfig should not be used. + +

    +

  • Changed FunFlush() mode argument (single characters) to a +plist argument (keyword arguments). In particular, +
    +  FunFlush(fun, "C");
    +
    +is now: +
    +  FunFlush(fun, "copy=remaining");
    +(or FunFlush(fun, "copy=remainder"); )
    +
    + +This syntax extension allows FunFlush to support the copy of the +extension associated with the reference handle, which allows one to +copy any extension from an input file to an output file: +
    +  /* open a new input extension */
    +  ifun = FunOpen(...);
    +  /* make this new extension the output reference extension */
    +  FunInfoPut(ofun, FUN_IFUN, &ifun, 0);
    +  /* copy the current reference extension to output */
    +  FunFlush(ofun, "copy=reference");
    +
    + +

    +

  • Fixed bugs in region parser that caused pure floating +point positions (i.e., numbers w/o format characters) always to be +interpreted as pixels. Also fixed galactic and ecliptic conversions. +
+ +
+

+Index to the Funtools Help Pages + +


+Index to the Funtools Help Pages + +
Last updated: November 17, 2005
+ + + diff --git a/doc/combo.html b/doc/combo.html new file mode 100644 index 0000000..ab0bc28 --- /dev/null +++ b/doc/combo.html @@ -0,0 +1,117 @@ + + + +Combining Region and Table Filters + + + + +

FunCombine: Combining Region and Table Filters

+ + +

Summary

+

+This document discusses the conventions for combining region and table +filters, especially with regards to the comma operator. + + + +

Comma Conventions

+

+Filter specifications consist of a series of boolean expressions, +separated by commas. These expressions can be table filters, +spatial region filters, or combinations thereof. Unfortunately, +common usage requires that the comma operator must act differently +in different situations. Therefore, while its use is intuitive in +most cases, commas can be a source of confusion. + +

+According to long-standing usage in IRAF, when a comma separates two +table filters, it takes on the meaning of a boolean and. Thus: +

+  foo.fits[pha==1,pi==2]
+
+is equivalent to: +
+  foo.fits[pha==1 && pi==2]
+
+ +When a comma separates two spatial region filters, however, it has +traditionally taken on the meaning of a boolean or. Thus: +
+  foo.fits[circle(10,10,3),ellipse(20,20,8,5)]
+
+is equivalent to: +
+  foo.fits[circle(10,10,3) || ellipse(20,20,8,5)]
+
+(except that in the former case, each region is given a unique id +in programs such as funcnts). + +

+Region and table filters can be combined: +

+  foo.fits[circle(10,10,3),pi=1:5]
+
+or even: +
+  foo.fits[pha==1&&circle(10,10,3),pi==2&&ellipse(20,20,8,5)]
+
+In these cases, it is not obvious whether the command should utilize an +or or and operator. We therefore arbitrarily chose to +implement the following rule: +
    +
  • if both expressions contain a region, the operator used is or. +
  • if one (or both) expression(s) does not contain a region, the operator +used is and. +
+This rule handles the cases of pure regions and pure column filters properly. +It unambiguously assigns the boolean and to all mixed cases. Thus: +
+  foo.fits[circle(10,10,3),pi=1:5]
+
+and +
+  foo.fits[pi=1:5,circle(10,10,3)]
+
+both are equivalent to: +
+  foo.fits[circle(10,10,3) && pi=1:5]
+
+ +

+[NB: This arbitrary rule replaces the previous arbitrary rule +(pre-funtools 1.2.3) which stated: +

    +
  • if the 2nd expression contains a region, the operator used is or. +
  • if the 2nd expression does not contain a region, the operator +used is and. +
+In that scenario, the or operator was implied by: +
+  pha==4,circle 5 5 1
+
+while the and operator was implied by +
+  circle 5 5 1,pha==4
+
+Experience showed that this non-commutative treatment of the comma +operator was confusing and led to unexpected results.] + +

+The comma rule must be considered provisional: comments and complaints +are welcome to help clarify the matter. Better still, we recommend +that the comma operator be avoided in such cases in favor of an +explicit boolean operator. + + + + + +

+Go to Funtools Help Index + +

Last updated: November 16, 2005
+ + + diff --git a/doc/doc40.fits b/doc/doc40.fits new file mode 100644 index 0000000..8ac4dcc Binary files /dev/null and b/doc/doc40.fits differ diff --git a/doc/ds9.html b/doc/ds9.html new file mode 100644 index 0000000..eefdfb6 --- /dev/null +++ b/doc/ds9.html @@ -0,0 +1,105 @@ + + + +Funtools and DS9 Image Display + + + + +

FunDS9: Funtools and DS9 Image Display

+ + +

Summary

+Describes how funtools can be integrated into the ds9 Analysis menu. + + +

Description

+

+ +SAOImage/DS9 is an astronomical imaging and data visualization +application used by astronomers around the world. DS9 can display +standard astronomical FITS images and binary tables, but also has +support for displaying raw array files, shared memory files, and data +files automatically retrieved via FTP and HTTP. Standard functional +capabilities include multiple frame buffers, colormap and region +manipulation, and many data scaling algorithms. DS9's advanced +features include TrueColor visuals, deep frame buffers, true +PostScript printing, and display of image mosaics. The program's +support of image tiling, "blinking", arbitrary zoom, rotation, and pan +is unparalleled in astronomy. It also has innovative support for +automatic retrieval and display of standard image data such as the +Digital Sky Survey (using servers at SAO, StScI, or ESO). + +

+DS9 can communicate with external programs such as Funtools using the +XPA +messaging system. In addition, programs can be integrated directly +into the DS9 GUI by means of a configurable Analysis menu. By +default, the DS9 Analysis menu contains algorithms deemed essential to +the core functions of DS9, e.g., display cross-cuts of data, +iso-intensity contours, and WCS grids. However, new programs can be +added to DS9 by creating a set-up file which can be loaded into DS9 +to reconfigure the Analysis menu. + +

+The basic format of the analysis set-up file is:
+

+ # + # Analysis command descriptions: + # menu label/description + # file templates for this command + # "menu" (add to menu) |"bind" (bind to key) + # analysis command line +

+ +For example, the funcnts program can be specified in this way: +
+  Funcnts (counts in source/bkgd regions; options: none)
+  *
+  menu
+  funcnts $filename $regions(source,,) $regions(background,,) | $text
+
+As shown above, DS9 supports a macro facility to provide information +as well as task support to command lines. For example, the $regions +macro is expanded by DS9 to provide the current source and/or +background region to the analysis command. The $text macro is expanded +to generate a text window display. It also is possible to query for +parameters using a $param macro, plot data using a $plot macro, +etc. See the DS9 documentation for further details. + +

+A set-up file called funtools.ds9 will +load some useful Funtools applications (counts in regions, radial +profile, X-ray light curve and energy spectrum, 1D histogram) into the DS9 +Analysis menu (version 2.1 and above). The file resides in the bin +directory where Funtools programs are installed. It can be manually +loaded into DS9 from the Load Analysis Commands ... option of +the Analysis menu. Alternatively, you can tell DS9 to load +this file automatically at start-up time by adding the pathname to the +Edit->Preferences->Analysis Menu->Analysis +File menu option. (NB: make sure you select +Edit->Preferences->Save Preferences after setting +the pathname.) + +

+The tasks in this setup file generally process the original disk-based +FITS file. Funcnts-based results (radial profile, counts in regions) +are presented in WCS units, if present in the FITS header. For +situations where a disk file is not available (e.g., image data +generated and sent to DS9's 'fits' XPA access point), versions of the +radial profile and counts in regions tasks also are also offered +utilizing DS9's internal image data. Results are presented in pixels. +Aside from the units, the results should be identical to the file-based +results. + + + + + +

+Go to Funtools Help Index + +

Last updated: November 16, 2005
+ + + diff --git a/doc/env.html b/doc/env.html new file mode 100644 index 0000000..c060017 --- /dev/null +++ b/doc/env.html @@ -0,0 +1,222 @@ + + + +Funtools Environment Variables + + + + +

FunEnv: Funtools Environment Variables

+ + +

Summary

+Describes the environment variables which can be used to tailor the overall +Funtools environment. + + +

Description

+

+The following environment variables are supported by Funtools: +

+

+

FITS_EXTNAME +
The FITS_EXTNAME environment variable specifies the +default FITS extension name when FunOpen() is called on a file lacking +a primary image. Thus, +
+  setenv FITS_EXTNAME "NEWEV"
+
+will allow you to call FunOpen() on files without specifying NEWEV in +the +Funtools bracket specification. +If no FITS_EXTNAME variable is defined and the extension name also is +not passed in the bracket specification, then the default will be to +look for standard X-ray event table extension names "EVENTS" or +"STDEVT" (we are, after all, and X-ray astronomy group at heart!). + +

+

FITS_EXTNUM +
The FITS_EXTNUM environment variable specifies the +default FITS extension number when FunOpen() is called on a file lacking +a primary image. Thus, +
+  setenv FITS_EXTNUM 7
+
+will allow you to call FunOpen() on files to open the seventh +extension without specifying the number in the +Funtools bracket specification. + +

+

FITS_BINCOLS and EVENTS_BINCOLS +
These environment variable specifies the default binning key for +FITS binary tables and raw event files, respectively. They can be +over-ridden using the bincols=[naxis1,naxis2] keyword in a +Funtools bracket specification. +The value of each environment variable +is a pair of comma-delimited columns, enclosed in parentheses, to use +for binning. For example, if you want to bin on detx and dety by +default, then use: +
+  setenv FITS_BINCOLS "(detx,dety)"
+
+in preference to adding a bincols specification to each filename: +
+  foo.fits[bincols=(detx,dety)]
+
+ +

+

FITS_BITPIX and EVENTS_BITPIX +
These environment variable specifies the default bitpix value for +binning FITS binary tables and raw event files, respectively. They can +be over-ridden using the bitpix=[value] keyword in a +Funtools bracket specification. The value +of each environment variable is one of the standard FITS bitpix values +(8,16,32,-32,-64). For example, if you want binning routines to +create a floating array, then use: +
+  setenv FITS_BITPIX -32
+
+in preference to adding a bitpix specification to each filename: +
+  foo.fits[bitpix=-32]
+
+ +

+

ARRAY +
The ARRAY environment variable specifies the default +definition of an array file for Funtools. +It is used if there is no array specification passed in the +ARRAY() directive in a +Non-FITS Array specification. +The value of the environment variable is a valid array specification such as: +
+  setenv ARRAY "s100.150"
+  foo.arr[ARRAY()]
+
+This can be defined in preference to adding the specification to each filename: +
+  foo.arr[ARRAY(s100.150)]
+
+ +

+

EVENTS +
The EVENTS environment variable specifies the default +definition of an raw event file for Funtools. +It is used if there is no EVENTS specification passed in the +EVENTS() directive in a +Non-FITS EVENTS specification. +The value of the environment variable is a valid EVENTS specification such as: +
+  setenv EVENTS "x:J:1024,y:J:1024,pi:I,pha:I,time:D,dx:E:1024,dx:E:1024"
+  foo.ev[EVENTS()]
+
+This can be defined in preference to adding the specification to each filename: +
+  foo.ev[EVENTS(x:J:1024,y:J:1024,pi:I,pha:I,time:D,dx:E:1024,dx:E:1024)]
+
+
+ +The following filter-related environment variables are supported by Funtools: +
+ +

+

FILTER_PTYPE +
The FILTER_PTYPE environment variable specifies how to +build a filter. There are three possible methods: +
+
process or p +
The filter is compiled and linked against the funtools library (which +must therefore be accessible in the original install directory) to produce +a slave program. This program is fed events or image data and returns +filter results. + +
dynamic or d (gcc only) +
The filter is compiled and linked against the funtools library (which +must therefore be accessible in the original install directory) to produce +a dynamic shared object, which is loaded into the funtools program and +executed as a subroutine. (Extensive testing has shown that, contrary to +expectations, this method is no faster than using a slave process.) + +
contained or c +
The filter and all supporting region code is compiled and linked +without reference to the funtools library to produce a slave program +(which is fed events or image data and returns filter results). This method +is slower than the other two, because of the time it takes to compile the +region filtering code. It is used by stand-alone programs such as ds9, +which do not have access to the funtools library. +
+ +By default, dynamic is generally used for gcc compilers and +process for other compilers. However the filter building algorithm +will check for required external files and will use contained is +these are missing. + +

+

FUN_MAXROW +
The FUN_MAXROW environment variable is used by core +row-processing Funtools programs (funtable, fundisp, funcnts, funhist, +funmerge, and funcalc) to set the maximum number of rows read at once +(i.e. it sets the third argument to the FunTableRowGet() call). The +default is 8192. Note that this variable is a convention only: it will +not be a part of a non-core Funtools program unless code is explicitly +added, since each call to FunTableRowGet() specifies its own maximum +number of rows to read. NB: if you make this value very large, you +probably will need to increase FUN_MAXBUFSIZE (see below) as well. + +

+

FUN_MAXBUFSIZE +
The FUN_MAXBUFSIZE environment variable is used to limit the +max buffer size that will be allocated to hold table row data. This +buffer size is calculated to be the row size of the table multiplied +by the maximum number of rows read at once (see above). Since the +row size is unlimited (and we have examples of it being larger than 5 +Mb), it is possible that the total buffer size will exceed the machine +capabilities. We therefore set a default value of 5Mb for the max buffer +size, and adjust maxrow so that the total size calculated is less than +this max buffer size. (If the row size is greater than this max buffer +size, then maxrow is set to 1.) This environment variable will change +the max buffer size allowed. + +

+

FILTER_CC +
The FILTER_CC environment variable specifies the compiler to +use for compiling a filter specification. You also can use the CC +environment variable. If neither has been set, then gcc will be used +if available. Otherwise cc is used if available. + +

+

FILTER_EXTRA +
The FILTER_EXTRA environment variable specifies extra options +to add to a filter compile command line. In principle, you can add libraries, +include files, and compiler switches. This variable should be used with care. + +

+

FILTER_TMPDIR +
The FILTER_TMPDIR environment variable specifies the temporary +directory for filter compilation intermediate files. You also can use +the TMPDIR and TMP variables. By default, /tmp is used +as the temporary directory. + +

+

FILTER_KEEP +
The FILTER_KEEP environment variable specifies whether the +intermediate filter files (i.e. C source file and compile log file) +should be saved after a filter is built. The default is "false", so that +these intermediate files are deleted. This variable is useful for debugging, +but care should be taken to reset its value to false when debugging is +complete. + +
+ + + + + +

+Go to Funtools Help Index + +

Last updated: November 16, 2005
+ + + + diff --git a/doc/evcol.c b/doc/evcol.c new file mode 100644 index 0000000..1e40df9 --- /dev/null +++ b/doc/evcol.c @@ -0,0 +1,130 @@ +/* + * + * evcol.c -- example program for processing all extensions and adding a + * column to the binary tables + * + */ +#include +#include + +#define MAXROW 8192 + +typedef struct evstruct{ + char shape[17]; + int mycol; +} *Ev, EvRec; + +int main (int argc, char **argv) +{ + int i, got; + int idx; + int tlmax; + int ext=1; + int total=1; + int haveshape=0; + char *s[3]; + char tbuf[SZ_LINE]; + Fun fun, fun2; + Ev ebuf, ev; + + /* exit on gio errors */ + setgerror(2); + + /* make sure we have minimal arguments */ + if( argc < 3 ) + gerror(stderr, "usage: %s iname oname\n", argv[0]); + + /* open a new output FITS file */ + if( !(fun2 = FunOpen(argv[2], "w", NULL)) ) + gerror(stderr, "could not FunOpen output file: %s\n", argv[2]); + + /* process each input extension in turn */ + for(ext=0; ;ext++){ + /* get new extension name */ + sprintf(tbuf, "%s[%d]", argv[1], ext); + /* open it -- if we cannot open it, we are done */ + if( !(fun=FunOpen(tbuf, "r", NULL)) ) + break; + + /* make the new extension the reference handle for the output file */ + FunInfoPut(fun2, FUN_IFUN, &fun, 0); + + /* if its not a binary table, just write it out */ + for(i=0; i<=2; i++) s[i] = NULL; + if( !(s[0]=FunParamGets(fun, "XTENSION", 0, NULL, &got)) || + strcmp(s[0], "BINTABLE")){ + if( s[0] ) free(s[0]); + FunFlush(fun2, "copy=reference"); + FunClose(fun); + continue; + } + else{ + if( (s[1]=FunParamGets(fun, "EXTNAME", 0, NULL, &got)) ){ + fprintf(stdout, "processing %s", s[1]); + if( (s[2]=FunParamGets(fun, "HDUNAME", 0, NULL, &got)) ) + fprintf(stdout, " %s", s[2]); + fprintf(stdout, "\n"); + } + } + for(i=0; i<=2; i++) if( s[i] ) free(s[i]); + + /* select columns from this new extension for merging */ + /* we have some special code to test various bugs with bpix.fits */ + if( (idx = FunColumnLookup(fun, "SHAPE", 0, + NULL, NULL, NULL, NULL, NULL, NULL)) ){ + haveshape = 1; + FunColumnSelect(fun, sizeof(EvRec), "merge=update", + "SHAPE", "16A", "rw", FUN_OFFSET(Ev, shape), + "MYCOL", "J", "w", FUN_OFFSET(Ev, mycol), + NULL); + } + else{ + FunColumnSelect(fun, sizeof(EvRec), "merge=update", + "MYCOL", "J", "w", FUN_OFFSET(Ev, mycol), + NULL); + } + + /* we have some special code to test various bugs with bpix.fits */ + /* we need to increase tlmax value of the "component" column */ + if( (idx = FunColumnLookup(fun, "COMPONENT", 0, + NULL, NULL, NULL, NULL, NULL, NULL)) ){ + if( (tlmax=FunParamGeti(fun, "TLMAX", idx, -1, &got)) && got ) + FunParamPuti(fun2, "TLMAX", idx, tlmax+100, NULL, 0); + } + + /* get input rows (let routine allocate the row array) */ + while( (ebuf = (Ev)FunTableRowGet(fun, NULL, MAXROW, NULL, &got)) ){ + /* process all rows */ + for(i=0; ishape[17] = '\0'; + /* used with bpix.ev */ + if( haveshape ){ + cluc(ev->shape); + fprintf(stdout, "\tshape: %s\n", ev->shape); + } + ev->mycol = total++; + } + /* write out this batch of rows, along with the new column */ + FunTableRowPut(fun2, (char *)ebuf, got, 0, NULL); + /* write out one more record with special marker */ + ev = ebuf; + strcpy(ev->shape, "hexagon "); + ev->mycol = -1; + FunTableRowPut(fun2, (char *)ev, 1, 0, NULL); + /* free row data */ + if( ebuf ) free(ebuf); + } + + /* flush output extension (write padding, etc.) */ + FunFlush(fun2, NULL); + /* close the input extension */ + FunClose(fun); + } + + /* all done -- close output */ + FunClose(fun2); + return(0); +} diff --git a/doc/evmerge.c b/doc/evmerge.c new file mode 100644 index 0000000..6b7cebc --- /dev/null +++ b/doc/evmerge.c @@ -0,0 +1,77 @@ +/* + * + * evmerge.c -- example program for merging user values into a table file + * + */ +#include +#include + +#define MAXROW 8192 + +typedef struct evstruct{ + double time; + int time2; +} *Ev, EvRec; + +int main (int argc, char **argv) +{ + int i, got; + char tbuf[SZ_LINE]; + Fun fun, fun2; + Ev ebuf, ev; + + /* exit on gio errors */ + setgerror(2); + + /* make sure we have minimal arguments */ + if( argc < 4 ) + gerror(stderr, "usage: %s iname oname mergetype [columns]\n", argv[0]); + + /* open input file */ + if( !(fun = FunOpen(argv[1], "rc", NULL)) ) + gerror(stderr, "could not FunOpen input file: %s\n", argv[1]); + + /* open the output FITS image, inheriting params from input */ + if( !(fun2 = FunOpen(argv[2], "w", fun)) ) + gerror(stderr, "could not FunOpen output file: %s\n", argv[2]); + + /* "merge=[type]" merges original input columns with new ones, where type is: + * update -- add new columns, update value of existing ones (same data type) + * replace -- add new columns, replace data type and value of existing ones + * append -- only add new columns, do not "replace" or "update" existing ones + * If tbuf argument is NULL, no merging is performed -- only user-specified + * columns are output. + */ + if( isfalse(argv[3]) ) + *tbuf = '\0'; + else + sprintf(tbuf, "merge=%s", argv[3]); + FunColumnSelect(fun, sizeof(EvRec), tbuf, + "time", "D", "rw", FUN_OFFSET(Ev, time), + "time2", "J", "w", FUN_OFFSET(Ev, time2), + NULL); + + /* activate specified columns -- these will be written to the output file */ + if( argc >= 5 ) + FunColumnActivate(fun, argv[4], NULL); + + /* get rows -- let routine allocate the row array */ + while( (ebuf = (Ev)FunTableRowGet(fun, NULL, MAXROW, NULL, &got)) ){ + /* process all rows */ + for(i=0; itime2 = (int)(ev->time+.5); + ev->time = -(ev->time/10.0); + } + /* write out this batch of rows with the new column */ + FunTableRowPut(fun2, (char *)ebuf, got, 0, NULL); + /* free row data */ + if( ebuf ) free(ebuf); + } + + /* clean up -- close output before input to perform flush automatically */ + FunClose(fun2); + FunClose(fun); + return(0); +} diff --git a/doc/evnext.c b/doc/evnext.c new file mode 100644 index 0000000..4a7fa09 --- /dev/null +++ b/doc/evnext.c @@ -0,0 +1,116 @@ +/* + * + * evnext.c -- example program for changing the time of an row to have + * the value from the next row + * + */ + +#include + +#define MAXROW 100 + +typedef struct evstruct{ + double time; +} *Ev, EvRec; + +#ifdef ANSI_FUNC +int +main (int argc, char **argv) +#else +main(argc, argv) + int argc; + char **argv; +#endif +{ + int i; + int got, ogot; + char *oraw; + char *nraw; + char *null=NULL; + Ev ebuf, oebuf=NULL; + Ev ev, nev, oev; + Fun fun, fun2; + + /* exit on gio errors */ + setgerror(2); + + /* make sure we have minimal arguments */ + if( argc < 3 ) + gerror(stderr, "usage: %s iname oname [columns]\n", argv[0]); + + /* open file */ + if( !(fun = FunOpen(argv[1], "r", NULL)) ) + gerror(stderr, "could not FunOpen %s\n", argv[1]); + + /* open the output FITS image, inheriting params from input */ + if( !(fun2 = FunOpen(argv[2], "w", fun)) ) + gerror(stderr, "could not FunOpen output file: %s\n", argv[2]); + + /* specify columns we want */ + got = FunColumnSelect(fun, sizeof(EvRec), "merge=update", + "time", "1D", "rw", FUN_OFFSET(Ev, time), + NULL); + /* activate specified columns -- these will be written to the output file */ + if( argc >= 4 ) + FunColumnActivate(fun, argv[3], NULL); + + /* get rows */ + while( (ebuf = (Ev)FunTableRowGet(fun, NULL, MAXROW, NULL, &got)) ){ + /* process the last row from previous batch, if we have it */ + if( oebuf ){ + /* this is the old array of rows -- we point to the last one */ + oev = oebuf+(ogot-1); + /* this is the new array of rows -- we point to the first one */ + ev = ebuf; + /* change time value of old row to new row's value */ + oev->time = ev->time; + /* now we have to write out this last row */ + /* first, save pointer to the new raw data */ + FunInfoGet(fun, FUN_RAWBUF, &nraw); + /* put back old pointer so we merge it with last row */ + FunInfoPut(fun, FUN_RAWBUF, &oraw); + /* write out last row merging with its raw data */ + /* (its arg 4 that tells funtools to merge with the last raw row) */ + FunTableRowPut(fun2, oebuf, 1, ogot-1, NULL); + /* free up old raw data */ + if( oraw ) free(oraw); + /* free up old user data */ + if( oebuf ) free(oebuf); + /* finally, put back new raw data pointer, so we can process new batch */ + FunInfoPut(fun, FUN_RAWBUF, &nraw); + } + /* process the got-1 rows by replacing the time with time from + the succeeding row */ + for(i=0; i<(got-1); i++){ + /* point to the i'th row */ + ev = ebuf+i; + nev = ebuf+(i+1); + ev->time = nev->time; + } + /* if we processed at least one row this time ... */ + if( got > 1 ){ + /* write out got-1 rows with the raw columns */ + FunTableRowPut(fun2, (char *)ebuf, (got-1), 0, NULL); + } + /* if we have a "last" row to process next time ... */ + if( got ){ + /* save the user row for when we have the next batch */ + oebuf = ebuf; + /* save pointer to raw data */ + FunInfoGet(fun, FUN_RAWBUF, &oraw); + /* null out rawbuf pointer so Funtools does not free it automatically */ + FunInfoPut(fun, FUN_RAWBUF, &null); + /* save old value of got */ + ogot = got; + } + } + + /* clean up last saved batch */ + if( oraw ) free(oraw); + if( oebuf ) free(oebuf); + + /* close and return */ + FunClose(fun2); + FunClose(fun); + return(0); +} diff --git a/doc/evread.c b/doc/evread.c new file mode 100644 index 0000000..aad5a13 --- /dev/null +++ b/doc/evread.c @@ -0,0 +1,304 @@ +/* + * + * evread.c -- example program for reading rows in different ways + * + */ + +#include + +#define MAXROW 10000 + +extern char *optarg; +extern int optind; + +/* single event (used in array of structs) */ +typedef struct evstruct{ + short region; + double x, y; + int pi, pha; + double time; + double dx, dy; +} *Ev, EvRec; + +/* arrays of columns (used in struct of arrays) */ +typedef struct aevstruct{ + short region[MAXROW]; + double x[MAXROW], y[MAXROW]; + int pi[MAXROW], pha[MAXROW]; + double time[MAXROW]; + double dx[MAXROW], dy[MAXROW]; +} *AEv, AEvRec; + +/* pointers to arrays of columns (used in struct of arrays) */ +typedef struct pevstruct{ + short *region; + double *x, *y; + int *pi, *pha; + double *time; + double *dx, *dy; +} *PEv, PEvRec; + +#ifdef ANSI_FUNC +int +main (int argc, char **argv) +#else +main(argc, argv) + int argc; + char **argv; +#endif +{ + int i; + int c; + int got; + int put; + int args; + int doev=0; + int doualloc=0; + char *mode="r"; + char *iname; + char *oname=NULL; + char *params=NULL; + Fun fun=NULL; + Fun ofun=NULL; + void *buf=NULL; + Ev ev, ebuf=NULL; + AEv aev, abuf=NULL; + PEv pev, pbuf=NULL; + + /* process switch arguments */ + while ((c = getopt(argc, argv, "aepuw:")) != -1){ + switch(c){ + case 'a': + doev = 1; + params = "org=soa"; + break; + case 'e': + doev = 0; + params = "org=aos"; + break; + case 'f': + doev = 3; + params = "org=aos"; + break; + case 'p': + doev = 2; + params = "org=soa"; + break; + case 'u': + doualloc = 1; + break; + case 'w': + oname = optarg; + mode = "rw"; + break; + } + } + + /* check for required arguments */ + args = argc - optind; + if( args == 0 ) + iname = "test.ev[EVENTS]"; + else + iname = argv[optind]; + + /* open input file */ + if( !(fun = FunOpen(iname, "r", NULL)) ){ + gerror(stderr, "could not FunOpen %s\n", iname); + exit(1); + } + + /* open output file, if necessary */ + if( oname ){ + if( !(ofun = FunOpen(oname, "w", fun)) ){ + gerror(stderr, "could not FunOpen outout %s\n", oname); + exit(1); + } + } + + /* specify columns we want */ + switch(doev){ + /* array of structs */ + case 0: + got = FunColumnSelect(fun, sizeof(EvRec), params, + "$region", "I", mode, FUN_OFFSET(Ev, region), + "x", "D:10:10", mode, FUN_OFFSET(Ev, x), + "y", "D:10:10", mode, FUN_OFFSET(Ev, y), + "dx", "D:10:10", mode, FUN_OFFSET(Ev, dx), + "dy", "D:10:10", mode, FUN_OFFSET(Ev, dy), + "pi", "J", mode, FUN_OFFSET(Ev, pi), + "pha", "J", mode, FUN_OFFSET(Ev, pha), + "time", "1D", mode, FUN_OFFSET(Ev, time), + NULL); + if( doualloc ){ + ebuf = calloc(MAXROW, sizeof(EvRec)); + buf = ebuf; + } + break; + /* struct of arrays */ + case 1: + got = FunColumnSelect(fun, sizeof(AEvRec), params, + "$region", "I", mode, FUN_OFFSET(AEv, region), + "x", "D:10:10", mode, FUN_OFFSET(AEv, x), + "y", "D:10:10", mode, FUN_OFFSET(AEv, y), + "dx", "D:10:10", mode, FUN_OFFSET(AEv, dx), + "dy", "D:10:10", mode, FUN_OFFSET(AEv, dy), + "pi", "J", mode, FUN_OFFSET(AEv, pi), + "pha", "J", mode, FUN_OFFSET(AEv, pha), + "time", "1D", mode, FUN_OFFSET(AEv, time), + NULL); + if( doualloc ){ + abuf = calloc(1, sizeof(AEvRec)); + buf = abuf; + } + break; + /* struct of pointers */ + case 2: + got = FunColumnSelect(fun, sizeof(PEvRec), params, + "$region", "@I", mode, FUN_OFFSET(PEv, region), + "x", "@D:10:10", mode, FUN_OFFSET(PEv, x), + "y", "@D:10:10", mode, FUN_OFFSET(PEv, y), + "dx", "@D:10:10", mode, FUN_OFFSET(PEv, dx), + "dy", "@D:10:10", mode, FUN_OFFSET(PEv, dy), + "pi", "@J", mode, FUN_OFFSET(PEv, pi), + "pha", "@J", mode, FUN_OFFSET(PEv, pha), + "time", "@1D", mode, FUN_OFFSET(PEv, time), + NULL); + if( doualloc ){ + pbuf = calloc(1, sizeof(PEvRec)); + pbuf->region = calloc(MAXROW, sizeof(short)); + pbuf->x = calloc(MAXROW, sizeof(double)); + pbuf->y = calloc(MAXROW, sizeof(double)); + pbuf->pi = calloc(MAXROW, sizeof(int)); + pbuf->pha = calloc(MAXROW, sizeof(int)); + pbuf->time = calloc(MAXROW, sizeof(double)); + pbuf->dx = calloc(MAXROW, sizeof(double)); + pbuf->dy = calloc(MAXROW, sizeof(double)); + buf = pbuf; + } + break; + /* array of structs containing pointers */ + case 3: + got = FunColumnSelect(fun, sizeof(PEvRec), params, + "$region", "@I", mode, FUN_OFFSET(PEv, region), + "x", "@D:10:10", mode, FUN_OFFSET(PEv, x), + "y", "@D:10:10", mode, FUN_OFFSET(PEv, y), + "dx", "@D:10:10", mode, FUN_OFFSET(PEv, dx), + "dy", "@D:10:10", mode, FUN_OFFSET(PEv, dy), + "pi", "@J", mode, FUN_OFFSET(PEv, pi), + "pha", "@J", mode, FUN_OFFSET(PEv, pha), + "time", "@1D", mode, FUN_OFFSET(PEv, time), + NULL); + if( doualloc ){ + pbuf = calloc(1, sizeof(PEvRec)); + pbuf->region = calloc(1, sizeof(short)); + pbuf->x = calloc(1, sizeof(double)); + pbuf->y = calloc(1, sizeof(double)); + pbuf->pi = calloc(1, sizeof(int)); + pbuf->pha = calloc(1, sizeof(int)); + pbuf->time = calloc(1, sizeof(double)); + pbuf->dx = calloc(1, sizeof(double)); + pbuf->dy = calloc(1, sizeof(double)); + buf = pbuf; + } + break; + default: + gerror(stderr, "unknown params value: %d\n", doev); + break; + } + + /* get rows */ + while( (buf = (void *)FunTableRowGet(fun, buf, MAXROW, NULL, &got)) ){ + /* output if necessary */ + if( ofun ){ + if( (put=FunTableRowPut(ofun, buf, got, 0, NULL)) != got ){ + gerror(stderr, "expected to write %d rows; only wrote %d\n", + got, put); + } + } + /* and display */ + switch(doev){ + case 0: + for(i=0; iregion, + ev->x, ev->y, + ev->pi, ev->pha, + ev->dx, ev->dy, + ev->time); + fflush(stdout); + } + break; + case 1: + aev = (AEv)buf; + for(i=0; iregion[i], + aev->x[i], aev->y[i], + aev->pi[i], aev->pha[i], + aev->dx[i], aev->dy[i], + aev->time[i]); + fflush(stdout); + } + break; + case 2: + pev = (PEv)buf; + for(i=0; iregion[i], + pev->x[i], pev->y[i], + pev->pi[i], pev->pha[i], + pev->dx[i], pev->dy[i], + pev->time[i]); + fflush(stdout); + } + break; + case 3: + for(i=0; iregion[0], + pev->x[0], pev->y[0], + pev->pi[0], pev->pha[0], + pev->dx[0], pev->dy[0], + pev->time[0]); + fflush(stdout); + } + break; + default: + gerror(stderr, "unknown params value: %d\n", doev); + break; + } + /* if funtools did allocation, free it now */ + if( !doualloc ){ + if( buf ) xfree(buf); + buf = NULL; + } + } + + /* clean up */ + if( doualloc ){ + switch(doev){ + case 0: + if( ebuf ) xfree(ebuf); + break; + case 1: + if( abuf ) xfree(abuf); + break; + case 2: + if( pbuf->region ) xfree(pbuf->region); + if( pbuf->x ) xfree(pbuf->x); + if( pbuf->y ) xfree(pbuf->y); + if( pbuf->pi ) xfree(pbuf->pi); + if( pbuf->pha ) xfree(pbuf->pha); + if( pbuf->time ) xfree(pbuf->time); + if( pbuf->dx ) xfree(pbuf->dx); + if( pbuf->dy ) xfree(pbuf->dy); + if( pbuf ) xfree(pbuf); + break; + } + } + if( ofun ) FunClose(ofun); + FunClose(fun); + return(0); +} diff --git a/doc/files.html b/doc/files.html new file mode 100644 index 0000000..0d903a4 --- /dev/null +++ b/doc/files.html @@ -0,0 +1,627 @@ + + + +Funtools Data Files + + + + +

FunFiles: Funtools Data Files

+ + +

Summary

+This document describes the data file formats (FITS, array, raw +events) as well as the file types (gzip, socket, etc.) supported +by Funtools. + + +

Description

+

+Funtools supports FITS images and binary tables, and binary files +containing array (homogeneous) data or event (heterogeneous) data. +IRAF-style brackets are appended to the filename to specify various +kinds of information needed to characterize these data: +

+  file[ext|ind|ARRAY()|EVENTS(),section][filters]
+  or
+  file[ext|ind|ARRAY()|EVENTS(),section,filters]
+
+where: +
    +
  • file is the Funtools file name +
  • ext is the FITS extension name +
  • ind is the FITS extension number +
  • ARRAY() is an array specification +
  • EVENTS() is an event specification +
  • section is the image section specification +
  • filters are spatial region and table (row) filters +
+ +

Supported Data Formats

+

+Funtools programs (and the underlying libraries) support the +following data file formats: +

    +
  • FITS images (and image extensions) +
  • FITS binary tables +
  • binary files containing an array of homogeneous data +
  • binary files containing events, i.e. records of heterogeneous data +
  • column-based text files, which are documented here +
  • non-disk files and lists of files +
+Information needed to identify and characterize +the event or image data can be specified on the command line +using IRAF-style bracket notation appended to the filename: +
+  foo.fits                              # open FITS default extension
+  image.fits[3]                         # open FITS extension #3
+  events.fits[EVENTS]                   # open EVENTS extension
+  array.file[ARRAY(s1024)]              # open 1024x1024 short array
+  events.file[EVENTS(x:1024,y:1024...)] # open non-FITS event list
+
+Note that in many Unix shells (e.g., csh and tcsh), filenames must +be enclosed in quotes to protect the brackets from shell processing. + +

FITS Images and Binary Tables

+

+When FunOpen() opens a FITS file +without a bracket specifier, the default behavior is to look for a +valid image in the primary HDU. In the absence of a primary image, +Funtools will try to open an extension named either EVENTS or +STDEVT, if one of these exists. This default behavior supports +both FITS image processing and standard X-ray event list processing +(which, after all, is what we at SAO/HEAD do). + +

+In order to open a FITS binary table or image extension explicitly, it +is necessary to specify either the extension name or the extension +number in brackets: +

+  foo.fits[1]                      # open extension #1: the primary HDU
+  foo.fits[3]                      # open extension #3 of a FITS file
+  foo.fits[GTI]                    # open GTI extension of a FITS file
+
+The ext argument specifies the name of the FITS extension (i.e. the +value of the EXTENSION header parameter in a FITS extension), while +the index specifies the value of the FITS EXTVER header parameter. +Following FITS conventions, extension numbers start at 1. + +

+When a FITS data file is opened for reading using +FunOpen(), the specified extension +is automatically located and is used to initialize the Funtools internal +data structures. + +

Non-FITS Raw Event Files

+ +In addition to FITS tables, Funtools programs and libraries can operate +on non-FITS files containing heterogeneous event records. To specify +such an event file, use: + +
    +
  • file[EVENTS(event-spec)] +
  • file[EVENTS()] +
+where event-spec is a string that specified the names, data +types, and optional image dimensions for each element of the event +record: +
    +
  • [name]:[n][type]:[(lodim:)hidim] +
+ +

+Data types follow standard conventions for FITS binary tables, but include +two extra unsigned types ('U' and 'V'): +

    +
  • B -- unsigned 8-bit char +
  • I -- signed 16-bit int +
  • J -- signed 32-bit int +
  • K -- signed 64-bit int +
  • E -- 32-bit float +
  • D -- 64-bit float +
  • U -- unsigned 16-bit int +
  • V -- unsigned 32-bit int +
+An optional integer value n can be prefixed to the type to indicate +that the element is an array of n values. For example: +
+  foo.fits[EVENTS(x:I,y:I,status:4J)]
+
+defines x and y as 16-bit ints and status as an array of 4 32-bit ints. + +

+Furthermore, image dimensions can be attached to the event specification +in order to tell Funtools how to bin the events into an image. They +follow the conventions for the FITS TLMIN/TLMAX keywords. If the low +image dimension is not specified, it defaults to 1. Thus: + +

    +
  • RAWX:J:1:100 +
  • RAWX:J:100 +
+both specify that the dimension of this column runs from 1 to 100. + +

+NB: it is required that all padding be specified in the record +definition. Thus, when writing out whole C structs instead of +individual record elements, great care must be taken to include +the compiler-added padding in the event definition. + +

+For example, suppose a FITS binary table has the following set of column +definitions: +

+  TTYPE1  = 'X                 ' / Label for field
+  TFORM1  = '1I                ' / Data type for field
+  TLMIN1  =                    1 / Min. axis value
+  TLMAX1  =                   10 / Max. axis value
+  TTYPE2  = 'Y                 ' / Label for field
+  TFORM2  = '1I                ' / Data type for field
+  TLMIN2  =                    2 / Min. axis value
+  TLMAX2  =                   11 / Max. axis value
+  TTYPE3  = 'PHA               ' / Label for field
+  TFORM3  = '1I                ' / Data type for field
+  TTYPE4  = 'PI                ' / Label for field
+  TFORM4  = '1J                ' / Data type for field
+  TTYPE5  = 'TIME              ' / Label for field
+  TFORM5  = '1D                ' / Data type for field 
+  TTYPE6  = 'DX                ' / Label for field
+  TFORM6  = '1E                ' / Data type for field
+  TLMIN6  =                    1 / Min. axis value
+  TLMAX6  =                   10 / Max. axis value
+  TTYPE7  = 'DY                ' / Label for field
+  TFORM7  = '1E                ' / Data type for field
+  TLMIN7  =                    3 / Min. axis value
+  TLMAX7  =                   12 / Max. axis value
+
+ +An raw event file containing these same data would have the event +specification: +
+  EVENTS(X:I:10,Y:I:2:11,PHA:I,PI:J,TIME:D,DX:E:10,DY:E:3:12)
+
+ +

+If no event specification string is included within the EVENTS() operator, +then the event specification is taken from the EVENTS environment +variable: +

+  setenv EVENTS "X:I:10,Y:I:10,PHA:I,PI:J,TIME:D,DX:E:10,DY:E:10"
+
+ +

+In addition to knowing the data structure, it is necessary to know the +endian ordering of the data, i.e., whether or not the data is +in bigendian format, so that we can convert to the native +format for this platform. This issue does not arise for FITS Binary +Tables because all FITS files use big-endian ordering, regardless of +platform. But for non-FITS data, big-endian data produced on a Sun +workstation but read on a Linux PC needs to be byte-swapped, since PCs +use little-endian ordering. To specify an ordering, use the +bigendian= or endian= keywords on the command-line +or the EVENTS_BIGENDIAN or EVENTS_ENDIAN environment variables. The +value of the bigendian variables should be "true" or "false", +while the value of the endian variables should be "little" or +"big". + +

+For example, a PC can access data produced by a Sun using: +

+  hrc.nepr[EVENTS(),bigendian=true]
+or
+  hrc.nepr[EVENTS(),endian=big]
+or
+  setenv EVENTS_BIGENDIAN true
+or
+  setenv EVENTS_ENDIAN big
+
+If none of these are specified, the data are assumed to follow the +format for that platform and no byte-swapping is performed. + +

Non-FITS Array Files

+ +In addition to FITS images, Funtools programs and libraries can operate +on non-FITS files containing arrays of homogeneous data. To specify +an array file, use: +
    +
  • file[ARRAY(array-spec)] +
  • file[ARRAY()] +
+ +where array-spec is of the form: +
    +
  • [type][dim1][.dim2][:skip][endian] +
+ +and where [type] is: +
    +
  • b (8-bit unsigned char) +
  • s (16-bit short int) +
  • u (16-bit unsigned short int) +
  • i (32-bit int) +
  • r,f (32-bit float) +
  • d (64-bit float) +
+ +

+The dim1 specification is required, but dim2 is optional and defaults +to dim1. The skip specification is optional and defaults to 0. The +optional endian specification can be 'l' or 'b' and defaults to the +endian type for the current machine. + +

+If no array specification is included within the ARRAY() operator, +then the array specification is taken from the ARRAY environment +variable. For example: + +

+  foo.arr[ARRAY(r512)]          # bitpix=-32 dim1=512 dim2=512
+  foo.arr[ARRAY(r512.400)]      # bitpix=-32 dim1=512 dim2=400
+  foo.arr[ARRAY(r512.400])      # bitpix=-32 dim1=512 dim2=400
+  foo.arr[ARRAY(r512.400:2880)] # bitpix=-32 dim1=512 dim2=400 skip=2880
+  foo.arr[ARRAY(r512l)]         # bitpix=-32 dim1=512 dim2=512 endian=little
+  setenv ARRAY "r512.400:2880"
+  foo.arr[ARRAY()]              # bitpix=-32 dim1=512 dim2=400 skip=2880
+
+ +

Specifying Image Sections

+ +Once a data file (and possibly, a FITS extension) has been specified, +the next (optional) part of a bracket specification can be used to +select image section information, i.e., to specify the x,y +limits of an image section, as well as the blocking factor to apply to +that section. This information can be added to any file specification but +only is used by Funtools image processing routines. + +

+The format of the image section specification is one of the following: +

    +
  • file[xy0:xy1,block] +
  • file[x0:x1,y0:y1,block] +
  • file[x0:x1,*,block] +
  • file[*,y0:y1,block] +
  • file[*,block] +
+where the limit values can be ints or "*" for default. A single "*" +can be used instead of val:val, as shown. Note that blocking is +applied to the section after it is extracted. + +

+In addition to image sections specified by the lo and hi x,y limits, image +sections using center positions can be specified: +

    +
  • file[dim1@xcen,dim2@ycen] +
  • file[xdim2@xcen@ycen] +
  • file[dim1@xcen,dim2@ycen,block] +
  • file[dim@xcen@ycen,block] +
+Note that the (float) values for dim, dim1, dim2, xcen, ycen must be +specified or else the expression does not make sense! + +

+In all cases, block is optional and defaults to 1. An 's' or 'a' can +be appended to signify "sum" or "average" blocking (default is "sum"). +Section specifications are given in image coordinates by default. If you +wish to specify physical coordinates, add a 'p' as the last character +of the section specification, before the closing bracket. +For example: +

+
    +
  • file[-8:-7,-8:-7p] +
  • file[-8:-7,-8:-7,2p] +
+
+A section can be specified in any Funtools file name. If the operation +to be applied to that file is an imaging operation, then the +specification will be utilized. If the operation is purely a table +operation, then the section specification is ignored. + +

+Do not be confused by: +

+  foo.fits[2]
+  foo.fits[*,2]
+
+The former specifies opening the second extension of the FITS file. +The latter specifies application of block 2 to the image section. + +

+Note that the section specification must come after +any of FITS ext name or ind number, +but all sensible defaults are supported: +

    +
  • file[ext] +
  • file[ext,index] +
  • file[index] +
  • file[ext,section] +
  • file[ext,index,section] +
  • file[index,section] +
  • file[section] +
+ +

Binning FITS Binary Tables and Non-FITS Event Files

+ +If a FITS binary table or a non-FITS raw event file is to be binned +into a 2D image (e.g., using the +funimage +program), it is necessary to specify the two columns to be used for the +binning, as well as the dimensions of the image. Funtools first looks +for a specifier of the form: +
+ bincols=([xnam[:tlmin[:tlmax:[binsiz]]]],[ynam[:tlmin[:tlmax[:binsiz]]]])
+
+in bracket syntax, and uses the column names thus specified. The tlmin, tlmax, +and binsiz specifiers determine the image binning dimensions using: +
+  dim = (tlmax - tlmin)/binsiz     (floating point data)
+  dim = (tlmax - tlmin)/binsiz + 1 (integer data)
+
+These tlmin, tlmax, and binsiz specifiers can be omitted if TLMIN, +TLMAX, and TDBIN header parameters are present in the FITS binary +table header, respectively. If only one parameter is specified, it is +assumed to be tlmax, and tlmin defaults to 1. If two parameters are +specified, they are assumed to be tlmin and tlmax. + +For example, to bin an HRC event list columns "VPOS" and "UPOS", use: +
+  hrc.nepr[bincols=(VPOS,UPOS)]
+
+or +
+  hrc.nepr[bincols=(VPOS:49152,UPOS:4096)]
+
+Note that you can optionally specify the dimensions of these columns +to cover cases where neither TLMAX keywords are defined in +the header. If either dimension is specified, then both must be specified. + +

+You can set the FITS_BINCOLS or EVENTS_BINCOLS environment variable as +an alternative to adding the "bincols=" specifier to each file name +for FITS binary tables and raw event files, respectively. If no +binning keywords or environment variables are specified, or if the +specified columns are not in the binary table, the Chandra parameters +CPREF (or PREFX) are searched for in the FITS binary table header. +Failing this, columns named "X" and "Y" are sought. If these are not +found, the code looks for columns containing the characters "X" and +"Y". Thus, you can bin on "DETX" and "DETX" columns without +specifying them, if these are the only column names containing the "X" +and "Y" characters. + +

+Ordinarily, each event or row contributes one count to an image pixel +during the 2D binning process. Thus, if five events all have the same +(x,y) position, the image pixel value for that position will have a +value of five. It is possible to specify a variable contribution +for each event by using the vcol=[colname] filter spec: +

+ vcol=[colname]
+
+The vcol colname is a column containing a numeric value in each event row +that will be used as the contribution of the given event to its image +pixel. For example, consider an event file that has the following content: +
+  x:e:4    y:e:4    v:e
+  ------   ------   ----
+  1        1        1.0
+  2        2        2.0
+  3        3        3.0
+  4        4        0.0
+  1        1        1.0
+  2        2        2.0
+  3        3        3.0
+  4        4        4.0
+
+There are two events with x,y value of (1,1) so ordinarily a 2D image will +have a value of 2 in the (1,1) pixel. If the v column is specified as the +value column: +
+  foo.fits'[vcol=v]'
+
+then each pixel will contain the additive sum of the associated (x,y) +column values from the v column. For example, image pixel (1,1) will +contain 1. + 1. = 2, image pixel (2,2) will contain (2 + 2) = 4, etc. + +

+An important variation on the use of a value column to specify the +contribution an event makes to an image pixel is when the value column +contains the reciprocal of the event contribution. For this case, the +column name should be prefixed with a / (divide sign) thus: +

+  foo.fits'[vcol=/v]'
+
+Each image pixel value will then be the sum of the reciprocals of the value +column. A zero in the value column results in NaN (not a number). +Thus, in the above example, image pixel (1.1) will contain 1/1 + 1/1 = 2, +image pixel (2,2) will contain (1/2 + 1/2) = 1, etc. Image pixel (4,4) +will contain (1/0 + 1/4) = NaN. + +

+You can set the FITS_VCOL or EVENTS_VCOL environment variable as +an alternative to adding the "vcol=" specifier to each file name +for FITS binary tables and raw event files, respectively. + +

+Finally, when binning events, the data type of the resulting 2D image +must be specified. This can be done with the "bitpix=[n]" keyword in +the bracket specification. For example: +

+  events.fits[bincols=(VPOS,UPOS),bitpix=-32]
+
+will create a floating point image binned on columns VPOS and UPOS. +If no bitpix keyword is specified, bitpix=32 is assumed. As with +bincols values, you also can use the FITS_BITPIX and EVENTS_BITPIX +environment variables to set this value for FITS binary tables and +raw event files, respectively. + +

+The funimage program also allows you to create a 1D image projection +along any column of a table by using the bincols=[column] +filter specification and specifying a single column. +For example, the following command projects a 1D image along +the chipx column of a table: +

+  funimage ev.fits'[bincols=chipx]' im.fits
+
+See funimage for more +information about creating 1D and 2D images. + +

+Finally, please note that Funtools supports most FITS standards. +We will add missing support as required by the community. In general, +however, we do not support non-standard extensions. For example, we +sense the presence of the binary table 'variable length array' +proposed extension and we pass it along when copying and filtering +files, but we do not process it. We will add support for new standards +as they become official. + +

Table and Spatial Region Filters

+

+Note that, in addition extensions and image sections, Funtools bracket +notation can be used to specify table and spatial region filters. These +filters are always placed after the image section information. They +can be specified in the same bracket or in a separate bracket +immediately following: +

    +
  • file[ext|ind|ARRAY()|EVENTS(),section][filters] +
  • file[ext|ind|ARRAY()|EVENTS(),section,filters] +
+where: +
    +
  • file is the Funtools file name +
  • ARRAY() is an array specification +
  • EVENTS() is an event list specification +
  • ext is the FITS extension name +
  • ind is the FITS extension number +
  • section is the image section to extract +
  • filters are spatial region and table (row) filters to apply +
+ +The topics of table and region filtering are covered in detail in: +
+ +

Disk Files and Other Supported File Types

+

+The specified file usually is an ordinary disk file. In +addition, gzip'ed files are supported in Funtools: gzip'ed input files +are automatically uncompressed as they are read, and gzip'ed output +files are compressed as they are written. NB: if a FITS binary table +is written in gzip format, the number of rows in the table will be set +to -1. Such a file will work with Funtools programs but will not work +with other FITS programs such as ds9. + +

+The special keywords "stdin" and "stdout" designate Unix standard +input and standard output, respectively. The string "-" (hyphen) will +be taken to mean "stdin" if the file is opened for reading and +"stdout" if the file is opened for writing. + +

+A file also can be an INET socket on the same or another machine using +the syntax: +

+  machine:port
+
+Thus, for example: +
+  karapet:1428
+
+specifies that I/O should be performed to/from port 1428 on the +machine karapet. If no machine name is specified, the default is to +use the current machine: +
+  :1428
+
+This means to open port 1428 on the current machine. Socket support +allows you to generate a distributed pipe: +
+  on karapet:       funtask1 in.fits bynars:1428
+  on bynars:        funtask2 :1428 out.fits
+
+The socket mechanism thus supports simple parallel processing using +process decomposition. Note that parallel processing using +data decomposition is supported via the section specifier (see +below), and the row# specifier, which is part of +Table Filtering. + +

+A file also can be a pointer to shared memory using the syntax: +

+  shm:[id|@key][:size]
+
+A shared memory segment is specified with a shm: prefix, +followed by either the shared memory id or the shared memory key +(where the latter is prefixed by the '@' character). The size (in +bytes) of the shared memory segment can then be appended (preceded by +the ':' character). If the size specification is absent, the code will +attempt to determine the length automatically. + +If the open mode contains the string "w+", then the memory segment will be +created if it does not exist. (It also will be released and deleted when the +file is closed.) In the case where a memory segment is being created, the +length of the segment is required. + +

+A file also can be Unix piped command (i.e. a program to run) using the syntax: +

+  "pipe: command arg1 ... argn"
+
+The output from the command must be a valid FITS file. It is important +to use quotes to protect spaces so that command arguments are passed +correctly. A silly example is: +
+  fundisp "pipe: funtable 'foo.fits[cir 512 512 .1]' stdout"
+
+This seemed like a good idea at the time ... + +

Lists of Files

+ +

+Funtools also will process a list of files as a single file using the +syntax: +

+  "list: file1 file2 ... filen"
+
+The files in the list are separated by whitespace. Any of the +above file types can be used. For example, if two files, foo1.fits and +foo2.fits, are part of the same observation, they can be processed as +a single file (using their own filters): +
+  fundisp "list: foo1.fits[cir(512,512,10)] foo2.fits[cir(511,511,10)]"
+         X        Y      PHA       PI                  TIME       DX       DY
+  -------- -------- -------- -------- --------------------- -------- --------
+       512      512        6        7     79493997.45854475      578      574
+       512      512        8        9     79494575.58943175      579      573
+       512      512        5        6     79493631.03866175      578      575
+       512      512        5        5     79493290.86521725      578      575
+       512      512        8        9     79493432.00990875      579      573
+       511      511        5        5     79488631.09462625      580      575
+       511      511       10       11     79488780.60006675      580      573
+       511      511        4        4     79494562.35474326      580      575
+       511      511        6        6     79488203.01561825      580      575
+       511      511        6        6     79488017.99730176      580      575
+       511      511        4        4     79494332.45355175      580      575
+       511      511        9       10     79492685.94014275      581      574
+       511      511        5        5     79487708.71298325      580      575
+       511      511        8        9     79493719.00160225      581      573
+
+Again, note that it is important to avoid spaces in the filters +because the list separator also is whitespace. To protect whitespace +in a filter, enclose the file specification in quotes: +
+  fundisp "list: 'foo1.fits[cir 512 512 .1]' foo2.fits[cir(511,511,.1)]" 
+
+ + + + + +

+Go to Funtools Help Index + +

Last updated: February 15, 2006
+ + + diff --git a/doc/filters.html b/doc/filters.html new file mode 100644 index 0000000..bd78fea --- /dev/null +++ b/doc/filters.html @@ -0,0 +1,325 @@ + + + +Table Filtering + + + + +

Funfilters: Filtering Rows in a Table

+ + +

Summary

+

+This document contains a summary of the user interface for +filtering rows in binary tables. + + +

Description

+

+Table filtering allows a program to select rows from an table (e.g., +X-ray event list) by checking each row against one or more expressions +involving the columns in the table. When a table is filtered, only +valid rows satisfying these expressions are passed through for processing. + +

+A filter expression is specified using bracket notation appended to +the filename of the data being processed: +

+  foo.fits[pha==1&&pi==2]
+
+It is also possible to put region specification inside a file and +then pass the filename in bracket notation: +
+  foo.fits[@my.reg]
+
+Filters must be placed after the extension and image section +information, when such information is present. The correct order is: +
    +
  • file[fileinfo,sectioninfo][filters] +
  • file[fileinfo,sectioninfo,filters] +
+where: +
    +
  • file is the Funtools file name +
  • fileinfo is an ARRAY, EVENT, FITS extension, or FITS index +
  • sectioninfo is the image section to extract +
  • filters are spatial region and table (row) filters to apply +
+See Funtools Files for more information +on file and image section specifications. + +

Filter Expressions

+ +

+Table filtering can be performed on columns of data in a FITS +binary table or a raw event file. Table filtering is accomplished by +means of table filter specifications. An table filter +specification consists of one or more filter expressions Filter +specifications also can contain comments and local/global processing +directives. + +

+More specifically, a filter specification consist of one or more lines +containing: +

+  # comment until end of line
+  # include the following file in the table descriptor
+  @file
+  # each row expression can contain filters separated by operators
+  [filter_expression] BOOLOP [filter_expression2], ...
+  # each row expression can contain filters separated by the comma operator
+  [filter_expression1], [filter_expression2], ...
+  # the special row# keyword allows a range of rows to be processed
+  row#=m:n
+  # or a single row
+  row#=m
+  # regions are supported -- but are described elsewhere
+  [spatial_region_expression]
+
+ +

+A single filter expression consists of an arithmetic, logical, or +other operations involving one or more column values from a +table. Columns can be compared to other columns, to header values, +or to numeric constants. Standard math functions can be applied to +columns. Separate filter expressions can be combined using boolean operators. +Standard C semantics can be used when constructing expressions, with +the usual precedence and associativity rules holding sway: +

+  Operator                                Associativity
+  --------                                -------------
+  ()                                      left to right
+  !! (logical not)                        right to left
+  !  (bitwise not) - (unary minus)        right to left
+  *  /                                    left to right
+  +  -                                    left to right
+  < <= > >=                               left to right
+  == !=                                   left to right
+  &  (bitwise and)                        left to right
+  ^  (bitwise exclusive or)               left to right
+  |  (bitwise inclusive or)               left to right
+  && (logical and)                        left to right
+  || (logical or)                         left to right
+  =                                       right to left
+
+For example, if energy and pha are columns in a table, +then the following are valid expressions: +
+  pha>1
+  energy == pha
+  (pha>1) && (energy<=2)
+  max(pha,energy)>=2.5
+
+ +

+Comparison values can be integers or floats. Integer comparison values can be +specified in decimal, octal (using '0' as prefix), hex (using '0x' as prefix) +or binary (using '0b' as prefix). Thus, the following all specify the same +comparison test of a status mask: +

+  (status & 15) == 8           # decimal
+  (status & 017) == 010        # octal
+  (status & 0xf) == 0x8        # hex
+  (status & 0b1111) == 0b1000  # binary
+
+

+The special keyword row# allows you to process a range of rows. +When row# is specified, the filter code skips to the designated +row and only processes the specified number of rows. The +"*" character can be utilized as the high limit value to denote +processing of the remaining rows. Thus: +

+  row#=100:109
+
+processes 10 rows, starting with row 100 (counting from 1), +while: +
+  row#=100:*
+
+specifies that all but the first 99 rows are to be processed. + +

+Spatial region filtering allows a program to select regions of an +image or rows of a table (e.g., X-ray events) using simple geometric +shapes and boolean combinations of shapes. For a complete description +of regions, see Spatial Region Filtering. + +

Separators Also Are Operators

+

+As mentioned previously, multiple filter expressions can be specified +in a filter descriptor, separated by commas or new-lines. +When such a comma or new-line separator is used, the boolean AND operator +is automatically generated in its place. Thus and expression such as: +

+  pha==1,pi=2:4
+
+is equivalent to: +
+  (pha==1) && (pi>=2&&pi<=4)
+
+

+[Note that the behavior of separators is different for filter expressions +and spatial region expressions. The former uses AND as the operator, while +the latter user OR. See +Combining Region and Table Filters +for more information about these conventions and how they are treated +when combined.] + +

Range Lists

+

+Aside from the standard C syntax, filter expressions can make use of +IRAF-style range lists which specify a range of values. The +syntax requires that the column name be followed by an '=' sign, which +is followed by one or more comma-delimited range expressions of the form: +

+  col = vv              # col == vv in range
+  col = :vv             # col <= vv in range
+  col = vv:             # col >= vv in range
+  col = vv1:vv2         # vv1 <= col <= vv2 in range
+
+The vv's above must be numeric constants; the right hand side of a +range list cannot contain a column name or header value. +

+Note that, unlike an ordinary comma separator, the comma separator used +between two or more range expressions denotes OR. Thus, when two or +more range expressions are combined with a comma separator, the resulting +expression is a shortcut for more complicated boolean logic. For example: +

+  col = :3,6:8,10:
+
+is equivalent to: +
+  (col<=3) || (col>=6 && col <=8) || (col >=10)
+
+Note also that the single-valued rangelist: +
+  col = val
+
+is equivalent to the C-based filter expression: +
+  col == val
+
+assuming, of course, that val is a numeric constant. + +

Math Operations and Functions

+

+It is permissible to specify C math functions as part of the filter syntax. +When the filter parser recognizes a function call, it automatically +includes the math.h and links in the C math library. Thus, it is +possible to filter rows by expressions such as these: +

    +
  • (pi+pha)>(2+log(pi)-pha) +
  • min(pi,pha)*14>x +
  • max(pi,pha)==(pi+1) +
  • feq(pi,pha) +
  • div(pi,pha)>0 +
+The function feq(a,b) returns true (1) if the difference between a and b +(taken as double precision values) is less than approximately 10E-15. +The function div(a,b) divides a by b, but returns NaN (not a number) +if b is 0. It is a safe way to avoid floating point errors when +dividing one column by another. + +

Include Files

+

+The special @filename directive specifies an include file +containing filter expressions. This file is processed as part of +the overall filter descriptor: +

+  foo.fits[pha==1,@foo]
+
+ +

Header Parameters

+

+The filter syntax supports comparison between a column value and a +header parameter value of a FITS binary tables (raw event files have no +such header). The header parameters can be taken from the binary +table header or the primary header. For example, assuming there is a +header value MEAN_PHA in one of these headers, you can select photons +having exactly this value using: + +

    +
  • pha==MEAN_PHA +
+ +

Examples

+

+Table filtering is more easily described by means of examples. +Consider data containing the following table structure: +

    +
  • double TIME +
  • int X +
  • int Y +
  • short PI +
  • short PHA +
  • int DX +
  • int DY +
+ +

+Tables can be filtered on these columns using IRAF/QPOE range syntax or +any valid C syntax. The following examples illustrate the possibilities: +

+ +

+

pha=10 +
pha==10 +
select rows whose pha value is exactly 10 + +

+

pha=10:50 +
select rows whose pha value is in the range of 10 to 50 + +

+

pha=10:50,100 +
select rows whose pha value is in the range of 10 to 50 or is +equal to 100 + +

+

pha>=10 && pha<=50 +
select rows whose pha value is in the range of 10 to 50 + +

+

pi=1,2&&pha>3 +
select rows whose pha value is 1 or 2 and whose pi value is 3 + +

+

pi=1,2 || pha>3 +
select rows whose pha value is 1 or 2 or whose pi value is 3 + +

+

pha==pi+1 +
select rows whose pha value is 1 less than the pi value + +

+

(pha==pi+1) && (time>50000.0) +
select rows whose pha value is 1 less than the pi value +and whose time value is greater than 50000 + +

+

(pi+pha)>20 +
select rows in which the sum of the pi and pha values is greater +than 20 + +

+

pi%2==1 +
select rows in which the pi value is odd +
+ +

+Currently, integer range list limits cannot be specified in binary +notation (use decimal, hex, or octal instead). Please contact us if +this is a problem. + + + + + +

+Go to Funtools Help Index + +

Last updated: November 17, 2005
+ + + diff --git a/doc/funcalc.sed b/doc/funcalc.sed new file mode 100644 index 0000000..d865a5d --- /dev/null +++ b/doc/funcalc.sed @@ -0,0 +1,9 @@ +# cc 2>&1 | sed -n -f funauto.sed +# Linux gcc (and others) +s/.*`\([^)]*\)' undeclared (first use in this function).*/\1/p +# Solaris cc +s/.*undefined symbol: \([^)]*\)/\1/p +# Dec Alpha/OSF cc +s/.*In this statement, "\([^)]*\)" is not declared.*/\1/p +# SGI cc +s/.*The identifier "\([^)]*\)" is undefined.*/\1/p diff --git a/doc/funtools.ds9 b/doc/funtools.ds9 new file mode 100644 index 0000000..f445a36 --- /dev/null +++ b/doc/funtools.ds9 @@ -0,0 +1,83 @@ +# +# Analysis command descriptions: +# menu label/description +# file templates for this command (* for all files) +# "menu" (add to menu) |"bind" (bind to key) +# analysis command line +# + +hmenu Funtools + +# 1D histogram params for a table +param thist +column entry "Enter column name to histogram" pi "(histo)" +bins entry "Enter [min:max:]bins" 0 "('0' for default number of bins)" +norm checkbox "Normalize by binsize?" 0 +end + +# 1D histogram params for an image +param ihist +bins entry "Enter [min:max:]bins" 0 "('0' for default number of bins)" +end + +# Light Curve params +param ltc +bins entry "Enter [min:max:]bins" 0 "('0' for default number of bins)" +norm checkbox "Normalize by time?" 0 +end + +Funtools Overview +* +menu +echo "Funtools Tasks in DS9\r\rThe tasks in this section of the Analysis menu utilize the Funtools programs\r'funcnts' and 'funhist'. With the exceptions noted below, they all work off the \roriginal disk-based FITS file. The funcnts-based tasks (radial profile, counts\rin regions) present their results using WCS units, if the appropriate info is\rpresent in the FITS header. \r\rFor situations where a disk file is not available (e.g., image data generated\rby a program and sent to DS9's 'fits' XPA access point), alternate versions of\rthe radial profile and counts in regions tasks are offered that work from DS9's\rinternal image data. In these two cases, results are presented in pixels. Aside\rfrom the units, the results should be identical to the file-based results.\r\rFor more sophisticated analysis, please consider using the underlying Funtools\rtasks directly. These are documented at:\r\r http://hea-www.harvard.edu/RD/funtools/programs.html\r\r" | $text + +Radial Profile Plot (annulus regions; options: none) +* +menu +funds9 funcnts_plot "$xpa" "$filename" "$regions(source,,)" "$regions(background,,)" | $plot(stdin) + +Histogram Plot (any column; options: column name, number of bins) +* +menu +$param(thist); funds9 funhist_plot "$xpa" "$filename[$regions]" "$norm" "$column" "$bins" | $plot(stdin) + +Light Curve Plot ("time" column; options: number of bins) +* +menu +$param(ltc); funds9 funhist_plot "$xpa" "$filename[$regions]" "$norm" time "$bins" | $plot(stdin) + +Energy Spectrum Plot ("pi" column; options: none) +* +menu +funds9 funhist_plot "$xpa" "$filename[$regions]" "0" "pi" "$bins" | $plot(stdin) + +Counts in Regions (any regions; options: none) +* +menu +funds9 funcnts "$xpa" "$filename" "$regions(source,,)" "$regions(background,,)" | $text + +Column Histogram (any column; options: colname, bins) +* +menu +$param(thist); funds9 funhist "$xpa" "$filename[$regions]" "$norm" "$column" "$bins" | $text + +Image Histogram (options: bins) +* +menu +$param(ihist); $data | funhist "stdin[$regions]" xy "$bins" | $text + +--- + +Radial Profile Plot in Pixels using DS9's Internal Image Data (annulus regions) +* +menu +$data | funcnts -rpG stdin $regions(source,,) $regions(background,,) | funcnts.plot -file "$filename" ds9 | $plot(stdin) + +Counts in Regions in Pixels using DS9's Internal Image Data (any regions) +* +menu +$data | funcnts -rp stdin $regions(source,,) $regions(background,,) | $text + +--- + +end diff --git a/doc/funtools.pdf b/doc/funtools.pdf new file mode 100644 index 0000000..56575ac Binary files /dev/null and b/doc/funtools.pdf differ diff --git a/doc/funtools.ps b/doc/funtools.ps new file mode 100644 index 0000000..210149e --- /dev/null +++ b/doc/funtools.ps @@ -0,0 +1,11446 @@ +%!PS +%%Title: The Funtools Help Facility +%%Creator: html2ps version 1.0 beta5 +%%EndComments +save +2000 dict begin +/d {bind def} bind def +/D {def} d +/t true D +/f false D +/FL [/Times-Roman +/Times-Italic +/Times-Bold +/Times-BoldItalic +/Courier +/Courier-Oblique +/Courier-Bold +/Courier-BoldOblique +/Helvetica +/Helvetica-Oblique +/Helvetica-Bold +/Helvetica-BoldOblique] D +/WF t D +/WI 0 D +/F 1 D +/IW 471 F div D +/IL 621 F div D +/PS 791 D +/EF [0 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 2 2] D +/EZ [11 9 19 17 15 13 12 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 8 8] D +/Ey [0 0 2 2 2 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] D +/EG [-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1] D +/Tm [1 1 0.8 0.8 0.8 0.8 0.8 0.8 0 0 0 0 0 0 0.5 1 1 1 1 0 0 1.3 0 0] D +/Bm [1 1 0.5 0.5 0.5 0.5 0.5 0.5 0 0 0 0 0 0 0.5 1 1 1 1 0 0 1 0 0] D +/Lm [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 2 0 0 2 0 0 0] D +/Rm [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0] D +/EU [-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0 0] D +/NO t D +/YY [[{()}1][{()}0][{()}2]] D +/ZZ [[{()}1][{()}0][{()}2]] D +/Ts EZ 0 get D +/TU f D +/Xp t D +/AU t D +/SN 0 D +/Cf f D +/Tp f D +/Fe f D +/TI 1 Ts mul D +/Fm 14 D +/xL 71 D +/xR 71 D +/yL 706 D +/yR 706 D +/Wl 471 F div D +/Wr 471 F div D +/hL 621 F div D +/hR 621 F div D +/FE {newpath Fm neg Fm M CP BB IW Fm add Fm L IW Fm add IL Fm add neg L CP BB + Fm neg IL Fm add neg L closepath} D +/LA {PM 0 eq{/IW Wl D /IL hL D}{/IW Wr D /IL hR D}ie /W IW D /LL W D /LS W D + TU PM 0 eq and{IW 56 F div add SA{Sf div}if 0 translate} + {PM 0 eq{xL yL}{xR yR}ie translate F SA{Sf mul}if dup scale + CS CF FS Cf{CA CL get VC}if /Bb f D}ie 0 0 M + TF not Tc or {Cf{gsave SA{1 Sf div dup scale}if Cb VC FE fill grestore}if}if}D +/Pi 0 Ts mul D +/SG [0.8 1 1] D +/Ab 15 D +/J 0 D +/Tc t D +/NH 6 D +/Nf f D +/Pa f D +/LH 1.2 D +/XR f D +/Xr {/pN E D ( [p ) WB pN WB (] )WB} D +/Db [16#FF 16#FF 16#FF] D +/Dt [16#00 16#00 16#00] D +/eA f D +/Fi f D +/bT f D +/Lc t D +/Dl [16#00 16#00 16#00] D +/LX f D +/Br 0.25 D +/IA ([IMAGE]) D +/DS {/PF f D()WB NL NP()pop RC ZF} D +/Gb f D +/Mb t D +/Hc [16#00 16#00 16#00] D +/Bl 3 D +/MI -15.2 D +/DX (DRAFT) D +/Di 0 D +/Tt 113.385826771654 D +/Th {()2 Al()BR ( + ) 0 1 -1 H()4 FZ Ti ES()EH ( + ) 0 2 -1 H() ME 0 get join EH()Ea()BR()} D +/tH {()0 1 -1 H (Table of Contents) EH()} D +/FD 2 D +/Dy 2 D +/cD [16#F0 16#F0 16#F0] D +/FW 0.6 D +/FU [16#00 16#00 16#00] D +/ET {/RM f D /A0 0 D /PN SN D /OU t D /Ou t D /W IW D /LL W D D1 + Ms not TP and{Ip}if /TF f D} D +[{true statusdict/setduplexmode get exec} stopped cleartomark +%-- End of variable part -- +/MySymbol 10 dict dup begin + /FontType 3 D /FontMatrix [.001 0 0 .001 0 0 ] D /FontBBox [25 -10 600 600] D + /Encoding 256 array D 0 1 255{Encoding exch /.notdef put}for + Encoding (e) 0 get /euro put + /Metrics 2 dict D Metrics begin + /.notdef 0 D + /euro 651 D + end + /BBox 2 dict D BBox begin + /.notdef [0 0 0 0] D + /euro [25 -10 600 600] D + end + /CharacterDefs 2 dict D CharacterDefs begin + /.notdef {} D + /euro{newpath 114 600 moveto 631 600 lineto 464 200 lineto 573 200 lineto + 573 0 lineto -94 0 lineto 31 300 lineto -10 300 lineto closepath clip + 50 setlinewidth newpath 656 300 moveto 381 300 275 0 360 arc stroke + -19 350 moveto 600 0 rlineto -19 250 moveto 600 0 rlineto stroke}d + end + /BuildChar{0 begin + /char E D /fontdict E D /charname fontdict /Encoding get char get D + fontdict begin + Metrics charname get 0 BBox charname get aload pop setcachedevice + CharacterDefs charname get exec + end + end}D + /BuildChar load 0 3 dict put /UniqueID 1 D +end +definefont pop + +/Cd {aload length 2 idiv dup dict begin {D} repeat currentdict end} D +/EX {EC cvx exec} D +/DU {} d +/BB {pop pop}d +/ie {ifelse} d +/E {exch} d +/M {moveto} d +/R {rmoveto} d +/L {lineto} d +/RL {rlineto} d +/CP {currentpoint} d +/SW {stringwidth} d +/GI {getinterval} d +/PI {putinterval} d +/Sg {setgray} d +/LW {setlinewidth} d +/S {dup () ne OU and{0 Co R AT 3 eq LB and HF not and A1 0 ne A2 0 ne or and + {A2 0 32 A1 0 6 -1 roll awidthshow}{show}ie 0 Co neg R}{pop}ie + OU PH 3 eq or{/Ms t D}if} D +/U {OU{gsave CP currentfont /FontInfo get /UnderlinePosition get + 0 E currentfont /FontMatrix get dtransform E pop add newpath M dup SW pop + CJ 0 RL stroke grestore}if} D +/B {OU Br 0 gt and{CP Ts neg Ts .33 mul R gsave 0 Sg + CP newpath Ts Br mul 0 360 arc closepath UI 2 mod 0 eq{stroke}{fill}ie + grestore M CP E Ts Br 1 add mul sub E BB /Ms t D}if}D +/NP {Ms TP not or PA and OU and{TP{OR}if f1{mF k2 /mF E D /YC 0 D}if + TP TU not PM 0 eq or and{showpage}if DU Ip TE not{LA}if 0.6 LW + /CI 0 D /TP t D /Hs f D /hl 6 D /Hv 6 D /HI hi D /Ms f D}if Bs XO BO M} D +/Np {LE sub CP E pop gt PL 0 eq and{NP}if}D +/Ip {/PN PN 1 add D /Pn RM{1}{4}ie PN Ns D /PM PN SN sub 2 mod D} D +/GP {E dup 3 -1 roll get PN 1 add 2 mod get dup type /integertype eq + {get 0 get}{E pop}ie}d +/Fc {dup 2 GP exec SW pop /S1 E D dup 1 GP exec SW pop /S2 E D 0 GP exec SW + pop /S3 E D S1 0 gt{S2 2 mul S1 add S3 2 mul S1 add 2 copy lt{E}if pop}{0}ie + S2 S3 add 2 copy lt{E}if pop IW .9 mul div dup 1 gt{1 E div}{pop 1}ie}D +/OR {Df{Sd}if tp not{gsave SA{1 Sf div dup scale}if Fe{Cf{FU VC}if FW LW + 1 setlinejoin FE stroke}if /YO {60 F div dup 40 gt{pop 40}if}D /cs CS D + /cf CF D /CF 0 D /pf PF D /PF f D /Fn FN D /At AT D /AT 0 D /FN EF Hf 1 add + get D Fz Fs FS ZZ Fc Fz mul Fs FS EU Hf 1 add get dup type /arraytype eq + Cf and{VC}{pop 0 Sg}ie IW IL neg YO sub M ZZ 1 GP exec dup SW pop neg 0 R Sh + 0 IL neg YO sub M ZZ 0 GP exec Sh ZZ 2 GP exec dup SW pop IW E sub 2 div + IL neg YO sub M Sh Fz Fs FS NO{/AW IW Pn SW pop sub D AW 2 div IL neg YO sub + S1 0 gt S2 AW .45 mul gt or S3 AW .45 mul gt or{Fz 2 mul sub}if M Pn Sh}if + EU Hf get dup type /arraytype eq Cf and{VC}{pop 0 Sg}ie YY Fc /FN EF Hf get D + Hz mul HS FS IW YO M YY 1 GP exec dup SW pop neg 0 R Sh 0 YO M YY 0 GP exec Sh + YY 2 GP exec dup SW pop IW E sub 2 div YO M Sh /FN Fn D /AT At D t Pb XO SZ + SL get neg R /PF pf D grestore /CF 0 D cs cf FS}if}D +/Sh {dup () ne{CP Hz 4 div sub BB show CP CS add BB}{pop}ie}D +/Pb {/OU E D /Ou OU D /PB t D 0 0 M Ba{/Sa save D /BP t D /Fl t D RC /PL 0 D + /PH 0 D /W IW D /LE IL .7 mul D /EO 0 D SI ZF /YA 0 D /BO 0 D /C1 () D + BA 0 Ts neg R Bb{Xl Yl Xh Yh}if Bb CP Sa restore M + {/Yh E D /Xh E D /Yl E D /Xl E D}if /Fl t D}if + BL /OU t D /HM f D /Ou t D /PB f D} D +/Bs {/BP Ba not D}D +/reencodeISO { + dup dup findfont dup length dict begin{1 index /FID ne{D}{pop pop}ie}forall + /Encoding ISOLatin1Encoding D currentdict end definefont} D +/ISOLatin1Encoding [ +/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef +/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef +/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef +/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef +/space/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright +/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash +/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon +/less/equal/greater/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N +/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright +/asciicircum/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m +/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/asciitilde +/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef +/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef +/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef +/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef +/.notdef/space/exclamdown/cent/sterling/currency/yen/brokenbar +/section/dieresis/copyright/ordfeminine/guillemotleft/logicalnot +/hyphen/registered/macron/degree/plusminus/twosuperior/threesuperior +/acute/mu/paragraph/periodcentered/cedilla/onesuperior/ordmasculine +/guillemotright/onequarter/onehalf/threequarters/questiondown +/Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE/Ccedilla +/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex +/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis +/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute +/Thorn/germandbls/agrave/aacute/acircumflex/atilde/adieresis +/aring/ae/ccedilla/egrave/eacute/ecircumflex/edieresis/igrave +/iacute/icircumflex/idieresis/eth/ntilde/ograve/oacute/ocircumflex +/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex/udieresis +/yacute/thorn/ydieresis +] D +[128/backslash 129/parenleft 130/parenright 141/circumflex 142/tilde +143/perthousand 144/dagger 145/daggerdbl 146/Ydieresis 147/scaron 148/Scaron +149/oe 150/OE 151/guilsinglleft 152/guilsinglright 153/quotesinglbase +154/quotedblbase 155/quotedblleft 156/quotedblright 157/endash 158/emdash +159/trademark] +aload length 2 idiv 1 1 3 -1 roll{pop ISOLatin1Encoding 3 1 roll put}for +/colorimage where{pop}{ + /colorimage { + pop pop /Pr E D {/Cv Pr D /Gr Cv length 3 idiv string D 0 1 Gr length 1 sub + {Gr E dup /i E 3 mul D Cv i get 0.299 mul Cv i 1 add get 0.587 mul add + Cv i 2 add get 0.114 mul add cvi put}for Gr} image} D +}ie +/pdfmark where{pop}{userdict /pdfmark /cleartomark load put}ie +WF{FL{reencodeISO D}forall}{4 1 FL length 1 sub{FL E get reencodeISO D}for}ie +/Symbol dup dup findfont dup length dict begin + {1 index /FID ne{D}{pop pop}ie}forall /Encoding [Encoding aload pop] + dup 128 /therefore put D currentdict end definefont D + +/SF {/CS E D SZ SL CS put FO SL FN put /YI CS LH neg mul D dup ST cvs ( ) join + CS ST cvs join C1 E join ( NF ) join /C1 E D CS NF /Wf WF FN 0 gt or D + /BW Wf{( ) SW pop}{0}ie D}D +/NF {/cS E D /cF E D cF 0 ge{FL cF get}{cF -1 eq{/Symbol}{/MySymbol}ie}ie + findfont cS scalefont setfont} D +/FS {CF or /CF E D FR SL CF put CF CF 0 ge{FN 4 mul add}if E SF} D +/PC {SH /BP f D fin not GL not and{NL}if /HM t D /LL LS D} D +/BS {/TX E D Wf{/fin f D /CW 0 D /LK 0 D /SC 0 D + /RT TX D {RT ( ) search{/NW E D pop /RT E D /WH NW SW pop D CW WH add LL gt + {TX SC LK SC sub 1 sub NN GI GL{SH cF cS OC + 2 copy cS ne E cF ne or{NF}{pop pop}ie}{PC /CW WH BW add D}ie + /SC LK D} + {GL{JC}if + /CW CW WH add BW add D /HM t D}ie /GL f D /Ph f D + /LK LK NW length 1 add add D}{pop exit}ie}loop + /fin t D TX SC LK SC sub GI SH RT () ne{GL not{CC}if}if + /LC TX length D /WH RT SW pop D CW WH add Hy{HC SW pop add}if LL gt + {RT GL{SH cF cS OC 2 copy cS ne E cF ne or{NF}{pop pop}ie + Hy{/Ph t D}if /LL LS D}{NL /LL LS D SH}ie} + {RT PC Hy{CC}if /Ph Ph Hy or D}ie RT () ne{/GL t D /HM t D}if} + {TX SW pop LL le{TX SH}{/NW () D 0 2 TX length 1 sub + {/CW E D TX 0 CW GI dup SW pop LL gt{pop NW SH /HM t D NL/LL W XO sub MR sub D + /CW CW 2 sub NN D /TX TX CW TX length CW sub GI D TX BS exit} + {/NW E D}ie}for}ie}ie /HM t D}D +/CC {C0 length 0 gt{JC}if /C0 [C1 L1 YA YB Mf NS NB TB AF Bw] D + /C1 () D /L0 L1 D /YA 0 D /YB 0 D /Mf 0 D /NS 0 D /NB 0 D}D +/JC {C0 aload length 0 gt{pop pop pop NB add /NB E D NS add /NS E D + dup Mf gt{/Mf E D}{pop}ie dup YB gt{/YB E D}{pop}ie + dup YA gt{/YA E D}{pop}ie pop C1 join /C1 E D /C0 [] D}if}D +/OC {C0 length 0 gt{C1 L1 L0 sub YA YB Mf NS NB TB AF Bw GL C0 aload pop + /Bw E D /AF E D /TB E D /NB E D /NS E D /Mf E D /YB E D /YA E D /C0 [] D + /L1 E D /C1 E D Ph{HC SH}if NL /GL E D /Bw E D /AF E D /TB E D /NB E D /NS E D + /Mf E D /YB E D /YA E D /L1 E D /LL W L1 sub XO sub MR sub WH sub D /CW 0 D + C1 E join /C1 E D}if}D +/BT {/LB t D dup length string copy RS dup dup () ne E ( ) ne and + {/CI 0 D /LS LL D /LL W L1 sub XO sub MR sub D BS} + {dup ( ) eq{/GL f D}if dup () eq L1 0 eq or{pop}{SH /BP f D /Ph f D}ie}ie + /LB f D} D +/BL {CP E pop XO E M} D +/NL {JC /GL f D /SK W XO sub MR sub L1 sub TB{Bw add}if D + /YA LF{Mf HM Fl not and PF or{LH mul}if}{0 /LF t D}ie YA 2 copy lt{E}if pop D + C1 () ne{/FB YB Mf SA{Sf mul}if 4 div 2 copy lt{E}if pop D}if Fl{/Ya YA D}if + CP E pop YA sub YB sub LE neg lt Fl not and PB not and{NP}if NT TL BL + OU PF not and PB or{/RE L1 TB{Bw sub}if + W XO sub MR sub div YA YB add LE BO add div 2 copy lt{E}if pop D + RE 1 gt{BL 1 RE div dup scale}if}if + AT 2 le{SK AT mul 2 div YA neg R}if + AT 3 eq{0 YA neg R TB{/NB NB 1 sub D /NS NS 1 sub D}if /NB NB 1 sub NN D + /A3 NS 6 mul NB add D NS NB add 0 eq + {/A1 0 D /A2 0 D} + {NS 0 eq{/A1 SK NB div dup J gt{pop 0}if D /A2 0 D}{J A3 mul SK lt + {/A1 J D /A2 SK J NB mul sub NS div dup Ab gt{/A1 0 D pop 0}if D} + {/A1 SK A3 div D /A2 A1 6 mul D}ie}ie}ie /A1 A1 NN D /A2 A2 NN D}if + AT 4 eq{0 YA neg R PH 2 le{PD 0 lt{/PD L1 D}if PD M1 gt{/M1 PD D}if + L1 PD sub M2 gt{/M2 L1 PD sub D}if}{DV ID 1 sub get 0 ge{Lo 0 R}if}ie}if + F0 cF ne Cs cS ne or{F0 Cs NF}if + /ms Ms D /Ms f D CP FB sub + C1 cvx exec XO EO sub L1 add TB{BW sub}if dup LM gt{/LM E D}{pop}ie + PH 0 eq PH 4 eq or Ms and{HF not{/PO t D /AH t D}if + BB CP YA add E AT 3 eq LB and{A1 sub}if TB{BW sub}if E BB} + {pop pop}ie Ms HM PH 3 eq and or{/BP f D /Fl f D}if + /Lo 0 D /L1 0 D /F0 cF D /Cs cS D BP not{0 YB NN neg R}if + OU f1 and mF not and{k2 /f1 f D}if + OU PF not and PB or{RE 1 gt{RE dup scale}if}if /Ms ms Ms or D + /C1 AF{(Cp )}{()}ie D /YA 0 D /YB 0 D BL + AT 4 eq LB not and PH 3 ge and + {ID DV length lt{DV ID get dup 0 ge{DO E sub /Lo E D /L1 Lo D}{pop}ie + /ID ID 1 add D}if}if /T t D CD{/LN LN 1 add D PD}if + /PD -1 D /NS 0 D /NB 0 D /TB f D /Ph f D /Mf 0 D /HM f D} D +/RS {/TM E D /CN 0 D TM{10 eq{TM CN ( ) PI}if /CN CN 1 add D}forall + /CN 0 D /BK HM EN and{0}{1}ie D TM + {dup 32 ne{TM CN 3 2 roll put /CN CN 1 add D /BK 0 D} + {pop BK 0 eq{TM CN 32 put /CN CN 1 add D}if /BK 1 D}ie}forall + TM 0 CN GI dup dup () ne E ( ) ne and + {dup CN 1 sub get 32 eq{/EN f D}{/EN t D}ie}if} D +/join {2 copy length E length add string dup 4 2 roll 2 index 0 3 index + PI E length E PI}d +/WR {(\n) search{dup () ne BP not or + {Li 4 le CP E pop YI Li mul add LE add 0 lt and PL 0 eq and{NP}if + SH NL pop /Li Li 1 sub D WR}{pop pop WR}ie}{SH}ie /CI 0 D /BP f D} D +/SH {dup dup () ne E ( ) ne and PF or CS Mf gt and{/Mf CS D}if + T not Wf and{( ) E join /T t D}if dup BP{/MF CS D}if + AT 3 eq{2 copy length dup 0 gt{/NB E NB add D + {( ) search{/NS NS 1 add D pop pop}{pop exit}ie}loop}{pop pop}ie}if + CD PD 0 lt and{dup DC search{SW pop /PD E L1 add D pop pop}{pop}ie}if + 0 Np dup SW pop L1 add /L1 E D dup () ne + {C1 (\() join E join (\)) join AU AF and UF or Wf and{( U ) join}if + sF{( s ) join}if ( S ) join + /C1 E D dup length 1 sub get 32 eq /TB E D /Bw BW D}{pop pop}ie} D +/BG {AI LG BC add add 0 eq} D +/ON {OU{Ty AR AI NN get dup 1 add Ln Ns Ty 2 mod 0 eq{(. )}{(\) )}ie join + dup SW pop neg 0 R CP E 0 lt{0 E M}{pop}ie CP BB show /Ms t D}if} D +/Ln {AR AI 3 -1 roll put}D +/SP {dup CI lt BP not and{dup CI sub 0 E R /CI E D}{pop}ie} D +/BN {PF{WR /HM f D}{BT NL}ie} D +/NN {dup 0 lt{pop 0}if} D +/h {(h) HI ST cvs join cvx exec dup 1 get E Nf{0 get E join}{pop}ie} D +/H {/fn FN D /Hi E 1 add D 1 sub /HL E D /H2 HL 2 add D /GS EZ H2 get D + E Tm H2 get GS mul BE dup 0 gt{1 sub}{pop EG H2 get dup 0 lt{pop AT}if}ie NA + WW Np /SL SL 1 add D /FN EF H2 get D GS Ey H2 get FS + EU H2 get Sc Hs not HL Hl lt and Hs HL hl lt and or Hi 0 eq or + {/HI Hi D /Hs t D /hl HL D /Hv HL D}if HL Hl lt{/hi Hi D}if + Nf HI 0 gt and{(h) Hi ST cvs join cvx exec 0 get WB}if + /HF t D /AH f D /PO f D} D +/EH {Bm H2 get GS mul BE OA /SL SL 1 sub NN D /CF 0 D /FN fn D + SZ SL get FR SL get FS /HF f D /GS Ts D ()Ec} D +/P {E PF{WR}{PO{EP}{BN}ie Ts 4 mul Np AE not{Tm 0 get Ts mul neg SP}if + dup 0 ge AH and{Pi Pd}if}ie 1 sub dup 0 lt{pop AV AL get}if /AT E D /PO t D} D +/EP {PF{WR}{BN Ts 4 mul Np}ie AE not{Bm 0 get Ts mul neg SP}if + /AT AV AL get D /PO f D} D +/BE {E PO{EP}{BN}ie Ts 4 mul Np neg SP} D +/HR {/Aw W EO sub D /RW E dup 0 gt{Aw mul}{neg}ie dup Aw gt{pop Aw}if D /RZ E D + E BN Ts neg SP 1 sub 2 div Aw RW sub mul EO add CP E pop M PF{0 Ps neg R}if + 0 Np OU{gsave RZ LW Cf{Hc VC}{0 Sg}ie CP BB RW 0 RL CP BB stroke grestore}if + /CI 0 D /BP f D PF not{Ts neg SP}if /Ms t D} D +/AD {I NL EG 14 get dup 0 lt{pop AT}if NA /AE t D Tm 14 get Ts mul neg SP + Cf{EU 14 get dup -1 eq{pop CA CL get}if Sc}if} D +/DA {BN ()ES OA /AE f D ()Ec Bm 14 get Ts mul neg SP} D +/PR {/MW E D /Li E D Tm 1 get Ps mul BE 0 NA /FN Fp D /PF t D SI /SL SL 1 add D + /CF 0 D Ps CS mul Ts div MW WC mul CS mul Ts div dup LL gt PL 0 eq and + {LL div div}{pop}ie Ey 1 get FS CP E pop LE add YI neg div cvi dup Li lt + AH and{4 lt YI Li mul 5 mul LE add 0 gt or PL 0 eq and{NP}if}{pop}ie + EU 1 get Sc /GS Ps D}D +/RP {WR NL () /PF f D SI /FN 0 D ES Bm 1 get Ps mul neg SP OA /GS Ts D} D +/SI {/XO Lm 15 get BC NN mul Lm 16 get AI UI sub NN mul add + Lm 17 get UI NN mul add Lm 20 get LG NN mul add Ts mul + PF{Lm 1 get Ps mul add}if EO add D + /MR Rm 15 get BC NN mul Rm 16 get AI UI sub NN mul add + Rm 17 get UI NN mul add Rm 20 get LG NN mul add Ts mul + PF{Rm 1 get Ps mul add}if D /LL W XO sub MR sub D} D +/DT {/cC E D BN /LG LG 1 sub D SI /LG LG 1 add D WW 2 div Np BL} D +/DD {WB Cc 0 eq cC 0 eq and L1 0 eq or Lm 20 get Ts mul L1 sub TB{BW add}if + Ts 2 div lt or NL /LF E D SI BL /cC 0 D} D +/DL {Dc LG Cc put /Cc E D BG{Tm 18 get Ts mul BE}{BN}ie /LG LG 1 add D BL} D +/LD {BN LG 0 gt{/LG LG 1 sub D}if /Cc Dc LG get D SI + BG{()Bm 18 get Ts mul BE}if BL} D +/UL {BG{Tm 17 get Ts mul BE}{BN}ie NR AI NN 0 put /UI UI 1 add D + /AI AI 1 add D SI BL} D +/LU {BN /UI UI 1 sub D /AI AI 1 sub D SI BG{()Bm 17 get Ts mul BE}if BL} D +/OL {E BG{Tm 16 get Ts mul BE}{BN}ie TR AI NN Ty put /Ty E D NR AI NN 1 put + /AI AI 1 add D SI BL 1 Ln} D +/LO {BN /AI AI 1 sub D /Ty TR AI get D SI BG{()Bm 16 get Ts mul BE}if BL} D +/LI {E BN -1 SP /BP f D /CI 0 D 0 Np NR AI 1 sub NN get 1 eq + {dup dup 0 gt E 4 le and{/Ty E D}{pop}ie + /L1 L1 Ty AR AI NN get Ns SW pop XO sub dup 0 lt{pop 0}if add D ( ON )} + {pop ( B )}ie C1 E join /C1 E D CS Mf gt{/Mf CS D}if BL} D +/BQ {Tm 15 get Ts mul BE /BC BC 1 add D SI BL} D +/QB {Bm 15 get Ts mul BE /BC BC 1 sub D SI BL} D +/Al {E EP 1 sub dup 0 lt{pop AV AL get}if NA} D +/Ea {EP OA} D +/WB {PF{WR}{BT}ie} D +/F1 {WB /FN 0 D CS 0 FS} D +/F2 {WB /FN WI D CS 0 FS} D +/HY {/Hy t D WB /Hy f D} D +/YH {WB} D +/A {/LT E D LT 1 eq{/RN E D}if /Lh E D WB /C1 C1 ( Cp ) join D + Lc AF not and{Cl Sc}if /AF t D} D +/EA {Lc AF and{Ec}{WB}ie TL Pa AF and Lh 0 ne and + {( \() Lh join (\)) join /AF f D WB}if /AF f D} D +/TL {C1 ( Tl ) apa /C1 E D} d +/apa {AF OU and Lh 0 ne LT 1 eq or and{LT 1 eq{RN ( /) E ST cvs join} + {(\() Lh join (\)) join}ie E join join}{pop}ie} d +/Cp {/Xc CP /Yc E D D} D +/SS {Cf{dup 0 ge{EU E get dup -1 eq{pop CA CL get}if}{pop CA CL get}ie Sc} + {pop}ie SZ SL get /SL SL 1 add D} D +/I {WB 8 SS 1 FS} D +/EM {WB 8 SS /CF CF 1 xor D 0 FS} D +/BD {WB 9 SS 2 FS} D +/TT {WB 10 SS /FN Fp D 0 FS} D +/KB {WB 11 SS /FN Fp D 2 FS} D +/CT {WB 12 SS 1 FS} D +/SM {WB 13 SS /FN Fp D 0 FS} D +/Q {/QL QL 1 add D QO QL 2 mod get La get join WB} D +/EQ {QC QL 2 mod get La get join WB /QL QL 1 sub D} D +/RO {WB -1 SS /CF 0 D 0 FS} D +/SY {WB -1 SS -1 FS} D +/MY {WB -1 SS -2 FS} D +/ES {WB /SL SL 1 sub NN D /CF 0 D /FN FO SL get D SZ SL get FR SL get FS ()Ec}D +/FZ {3 sub 1.2 E exp GS mul E WB TL /C1 C1 ( Cp ) join D /SL SL 1 add D 0 FS} D +/Ef {WB TL ()ES /C1 C1 ( Cp ) join D} D +/BZ {dup /Bf E D FZ}D +/Sc {dup -1 ne Cf and{/CL CL 1 add D dup 0 eq{pop [0 0 0]}if + dup CA E CL E put VS ( VC ) join C1 E join /C1 E D}{pop}ie} D +/Ec {WB Cf{/CL CL 1 sub NN D CA CL get VS ( VC ) join C1 E join /C1 E D}if} D +/VS {dup type /arraytype eq{([) E {ST cvs join ( ) join}forall (]) join}if} D +/VC {{255 div}forall setrgbcolor} D +/Sl {dup type /integertype ne{Ds}if /La E D WB}d +/UN {WB /UF t D} D +/NU {WB /UF f D} D +/SE {WB /sF t D} D +/XE {WB /sF f D} D +/sM {/C1 C1 ( k1 ) join D}d +/eM {/C1 C1 ( k2 ) join D}d +/k1 {/YC CP E pop Ts add D /mF t D /f1 t D}d +/k2 {gsave 3 LW -9 CP E pop Ts 0.2 mul sub M -9 YC L stroke grestore /mF f D}d +/Ac {/AC E D WB}d +/Ca {eA{( \()join AC join(\) )join}if WB}d +/s {OU{gsave 0 CS .25 mul R dup SW pop CJ 0 RL stroke grestore}if}D +/CJ {AT 3 eq LB and{E dup dup length 1 sub A1 mul E + {( ) search{pop pop E A2 add E}{pop exit}ie}loop 3 -1 roll add + W CP pop sub 2 copy gt{E}if pop}if}D +/So {/Co E D} D +/SO {C1 Yo ST cvs join ( So ) join /C1 E D (j) SW pop 2 div Pd} D +/Se {E WB CS E div Pd}D +/Pd {dup type /stringtype eq{SW pop}if dup /L1 E L1 add D + ST cvs ( 0 R ) join C1 E join /C1 E D} D +/Sp {0.35 CO} D +/Sb {-0.2 CO} D +/CO {OV Io Yo put /Yo E CS mul Yo add D /Io Io 1 add D -1.5 Io mul 3 add FZ SO + CS Yo add dup YA gt{/YA E D}{pop}ie + Yo neg dup YB gt{/YB E D}{pop}ie} D +/Es {ES /Io Io 1 sub NN D /Yo OV Io get D SO} D +/SB {/N2 0 D 0 1 NI{/N E D{IX N2 get 0 lt{/N2 N2 1 add D}{exit}ie}loop + /K WS N get FC N get mul D /NY AY N2 get D /BV NY array D + 0 1 NY 1 sub{/TM K string D currentfile TM readhexstring pop pop BV E TM put} + for BM N BV put /N2 N2 1 add D}for} D +/IC [{/MA E D /MB 0 D}{2 div /MA E D /MB MA D}{/MB E CS sub D /MA CS D} + {pop /MA YS AB mul D /MB 1 AB sub YS mul D}{pop /MA 0 D /MB 0 D}] D +/IP {BV N get /N N 1 add D} D +/II {/K E D IX K get 0 lt{/EC E D}if /TY E D + TY 4 eq{/Y E D /X E D}if TY 3 eq{/AB E D}if + /XW AX K get D /YW AY K get D /IS SG IT K get get D /XS XW IS mul D + /YS YW IS mul D YS IC TY get exec /MA MA Fl not{3 add}if D} D +/IM {II /ty TY D /xs XS D /ys YS D /ya YA D /yb YB D /ma MA D /mb MB D /k K D + /ec EC D /BP f D /CI 0 D WB TL L1 xs add dup XO add MR add W gt + {pop /ma ma Fl{3 add}if D NL /YA ma D /YB mb D /YS ys D /L1 xs D} + {/L1 E D ma YA gt{/YA ma D}if mb YB gt{/YB mb D}if}ie /TB f D + OU{CP E pop YS sub LE neg lt Fl not and PB not and{NP /YA ma D /YB mb D}if + /BP f D ty ST cvs ( ) join IX k get 0 lt{(\() join ec join (\) ) join}if + k ST cvs join ty 3 eq{AB ST cvs ( ) join E join}if + ty 4 eq{X ST cvs ( ) join Y ST cvs join ( ) join E join}if C1 E join + ( DI ) join FP 2 eq FP 1 eq AF and or{( FM ) join}if + ( Il Cp ) apa /C1 E D /EN f D}if /HM t D /T f D} D +/DI {II /Xc CP /Yc E D D /YN YW neg D /HM t D /CI 0 D /K2 IX K get D gsave + TY 4 eq{OX X IS mul add OY FY add YS sub Y IS mul sub} + {/FY YS D CP MB sub 2 copy /OY E D /OX E D}ie + translate K2 0 ge{/DP AZ K2 get D /BV BM K2 get D XS YS scale /N 0 D XW YW DP + [XW 0 0 YN 0 YW] {IP} FC K2 get 1 eq{image}{f 3 colorimage}ie} + {EX}ie grestore XS 0 R /Ms t D} D +/FM {gsave 0 Sg CP MB sub translate XS neg 0 M 0 YS RL XS 0 RL 0 YS neg RL + XS neg 0 RL stroke grestore} D +/NA {/AT E D /AL AL 1 add D AV AL AT put} D +/OA {AL 0 gt{/AL AL 1 sub D /AT AV AL get D}if} D +/D1 {/BR {CP E pop E BN Mb{CP E pop eq{0 YI R}if}{pop}ie} D + /Sn {OU{C1 E ST cvs join ( Ld ) join /C1 E D}{pop}ie} D} D +/D1 {/BR {BN} D /Sn {OU {C1 E ST cvs join ( Ld ) join /C1 E D} {pop} ie} D} D +/TC {/TF t D /ML 0 D HN{SW pop dup ML gt{/ML E D}{pop}ie}forall NP /RM RM not D + RC /OU Tc D Ep /PN 0 D Ms not TP and{Ip}if /W IW ML sub Ts sub D + /A0 0 D TH{/BR {( ) join BT} D /Sn {pop} D /Au () D}if} D +/TN {0 eq{E EA PF HF or not XR and{HN E get Xr}{pop}ie} + {OU{Tn 0 ge{() BN}if /Tn E D}{pop}ie WB}ie} D +/NT {OU LB not and Tn 0 ge and{PL 0 eq{Ms not{CS CF FS}if CP dup + /y E YA sub D W 9 sub CS -1.8 mul XO L1 add 2 add{y M (.) show}for + HN Tn get dup SW pop IW E sub y M show CP BB M}if /Tn -1 D}if} D +/Ld {/DN E D HN DN Pn put [/View [/XYZ -4 Fl{PS}{CP YA add US E pop}ie null] + /Dest DN ST cvs cvn /DEST pdfmark} D +/C {ND 1 eq{1 sub}if TI mul /XO E D NL Nf not{pop()}if 0 3 -1 roll 1 A} D +/OP {BP not{NP}if PN 2 mod 0 eq{/Ms t D NP}if}D +/Ep {Xp PN 2 mod 0 eq and OU and{/Pn (-) D showpage /PM 1 D LA}if}D +/Dg [73 86 88 76 67 68 77] D +/Rd [0 [1 1 0][2 1 0][3 1 0][2 1 1][1 1 1][2 2 1][3 3 1][4 4 1][2 1 2]] D +/Ns {/m E D /c E 32 mul D /j m 1000 idiv D /p j 12 add string D + c 96 le m 0 gt and{c 32 le {/i 0 D /d 77 D /l 100 D /m m j 1000 mul sub D + j -1 1 {pop p i d c add put /i i 1 add D}for + 4 -2 0 {/j E D /n m l idiv D /m m n l mul sub D /d Dg j get D + n 0 gt {/x Rd n get D x 0 get -1 1 {pop p i d c add put /i i 1 add D}for + p i x 1 get sub Dg x 2 get j add get c add put}if /l l 10 idiv D + }for p 0 i GI} + {/i ST length 1 sub D m {1 sub dup 0 ge{dup 26 mod c add 1 add + ST i 3 -1 roll put 26 idiv dup 0 eq{pop exit}if}if /i i 1 sub D}loop + ST i ST length i sub GI}ie} + {m p cvs}ie} D +/US {matrix currentmatrix matrix defaultmatrix matrix invertmatrix + matrix concatmatrix transform} D +/GB {Gb{US}if}D +/Tl {/Rn E D Xc CP pop ne{ + [/Rect [Xc 1 sub Yc cS 0.25 mul sub GB CP E 1 add E cS 0.85 mul add GB] + /Subtype /Link /Border [0 0 Cf Lc and LX and AU or{0}{1}ie] Rn type + /nametype eq {/Dest Rn}{/Action [/Subtype /URI /URI Rn] Cd}ie + /ANN pdfmark}if} D +/Il {/Rn E D [/Rect [Xc Yc GB Xc XS add Yc YS add GB] /Subtype /Link + /Border [0 0 0] Rn type /nametype eq{/Dest Rn} + {/Action [/Subtype /URI /URI Rn] Cd}ie /ANN pdfmark} D +/XP {[{/Z Bz 2 div D Z 0 R Z Z RL Z neg Z RL Z neg Z neg RL Z Z neg RL + Fi cH 1 eq and{fill}if} {Bz 0 RL 0 Bz RL Bz neg 0 RL 0 Bz neg RL + Fi cH 1 eq and{fill}if} {0 -5 R Bz 0 RL 0 21 RL Bz neg 0 RL 0 -21 RL}]} D +/MS {/Sm E D WB}D +/O {BN()Sm BX} D +/O {BN()0 Sm BX} D +/BX {/Bt E D Bt 2 lt{/Ch E D CS 0.8 mul}{11 mul}ie W XO sub MR sub + 2 copy gt{E}if pop /HZ E D Bt 2 eq{Fi not{pop()}if ( )E join /Ft E D TT + /PF t D /MW 1 D /Li 1 D /Fw Ft SW pop D Fw HZ gt{/HZ Fw 8 add D}if + HZ ST cvs( )join}{WB Ch ST cvs( )join}ie L1 HZ add XO add MR add W gt{NL}if + Bt 2 eq{Ft ES Fw neg HM{CS sub}if Pd}if Bt ST cvs join( Bx )join + Bt 2 eq HM and{CS Pd}if C1 E join /C1 E D /L1 L1 HZ add D /T f D + ( ) Pd /PF f D Bt 2 lt{YA CS .8 mul lt{/YA CS .8 mul D}if} + {YB 5 lt{/YB 5 D}if YA 21 lt{/YA 21 D}if}ie /CI 0 D} D +/Bx {dup 2 eq{E /Bz E D}{E /cH E D /Bz CS .8 mul D}ie + OU {gsave 0 Sg XP E get exec stroke grestore}{pop}ie Bz 0 R /Ms t D}D +/SD {FD 4 mul Dy add DZ NF newpath 0 0 M DX t charpath pathbbox + 3 -1 roll sub /DY E D E dup /X1 E D sub WM mul WX DY mul add WM DG mul E div + /DF E D /DR WX DF mul DY mul WM div 2 div D} d +/Sd {gsave 0 IL Di mul neg translate IL IW atan Di 0 eq{neg}if rotate + FD 4 mul Dy add DZ NF DR X1 sub DY 2 div neg M cD VC DX show grestore} d +/Pt {/tp t D Tp{NP /Pn (TP) D 0 Tt neg R Th BN NP Ep ET RC ZF}if /tp f D} D +/RC {/AI 0 D /LG 0 D /BC 0 D /UI 0 D /PF f D /Cc 0 D /cC 0 D /Dc 10 array D + /NR [0 1 9{pop 0}for] D /La Ds D /AR 10 array D /TR 10 array D /AV 30 array D + SI /AL -1 D /AT A0 D AT NA /OV 9 array D /Yo 0 D /Co 0 D /Io 0 D /Hy f D + /Ph f D /CL -1 D Ct Sc}D +/ZF {/FR [0 1 30{pop 0}for] D /SZ [0 1 30{pop 0}for] D /FO [0 1 30{pop 0}for] D + /SL 0 D /CF 0 D /FN 0 D 0 Ts SF}D +/QO [[(\234)(\233)(\253\240)(\232)(\273)(\253)][(')(`)(\253\240)(\231)(\273)(\253)]] D +/QC [[(\234)(\234)(\240\273)(\233)(\253)(\273)][(')(')(\240\273)(`)(\253)(\273)]] D +/Hf EF length 2 sub D +/Hz EZ Hf get D +/HS Ey Hf get D +/Fz EZ Hf 1 add get D +/Fs Ey Hf 1 add get D +/LE IL D +/Ps EZ 1 get D +/Fp EF 1 get D +/XO 0 D +/YI 0 D +/CI 0 D +/FP 0 D +/WW Ts 7 mul D +/Mf 0 D +/YA 0 D +/YB 0 D +/Cs Ts D +/GS Ts D +/F0 0 D +/NS 0 D +/NB 0 D +/N 0 D +/C0 [] D +/C1 () D +/Lo 0 D +/L1 0 D +/LM 0 D +/PH 0 D +/EC 0 D +/Lh 0 D +/LT 0 D +/CH 1 string D +/ST 16 string D +/CA 9 array D +/HC (\255) D +/HM f D +/PF f D +/EN f D +/TB f D +/UF f D +/sF f D +/AE f D +/AF f D +/BP t D +/CD f D +/PA t D +/GL f D +/T t D +/HF f D +/AH f D +/SA f D +/PB f D +/f1 f D +/mF f D +/OX 0 D +/OY 0 D +/FY 0 D +/EO 0 D +/FB 0 D +/PL 0 D +/Bw 0 D +/PD -1 D +/TP f D +/tp f D +/TH f D +/Ty 4 D +/Tn -1 D +/Fl t D +/LB t D +/PM 1 D +/Ms f D +/Ba f D +/Bb f D +/Hl 3 D +/hl 6 D +/Hv 6 D +/Hs f D +/HI 0 D +/hi 0 D +/PO t D +/TE f D +/LF t D +/BO 0 D +/Sm 1 D +/Bf 3 D +/A1 0 D +/A2 0 D +/Ds 1 D +/QL -1 D +/Cb Db D +/Ct Dt D +/Cl Dl D +[/Creator (html2ps version 1.0 beta5) /Author () /Keywords () /Subject () + /Title (The Funtools Help Facility) /DOCINFO pdfmark +/ND 18 D +/HN [(1) (1) (1) (1) (8) (9) (19) (21) (28) (30) (33) (37) (38) (41) (42) (45) +(48) (51) (53) (??) (54) (56) (56) (87) (57) (58) (60) (62) (64) (65) (76) +(77) (66) (73) (75) (82) (85) (78) (80) (86) (87) (57) (91) (91) (92) (92) +(94) (102) (111) (95) (96) (100) (117) (123) (127) (136) (152) (157) (161) +(164) (165) (167) (171) (1) (1) (1) (3) (1) (1) (1) (8) (9) (19) (21) (28) +(30) (33) (37) (38) (41) (42) (45) (48) (50) (51) (51) (51) (51) (52) (53) +(53) (53) (53) (53) (54) (56) (56) (57) (57) (58) (60) (62) (64) (65) (66) +(73) (75) (76) (77) (80) (82) (85) (86) (87) (87) (87) (88) (90) (91) (98) +(91) (91) (91) (91) (92) (92) (94) (95) (96) (98) (99) (100) (101) (102) +(102) (102) (102) (102) (103) (104) (105) (105) (108) (109) (110) (111) +(111) (111) (111) (111) (111) (112) (113) (114) (114) (115) (116) (116) +(116) (117) (119) (119) (120) (120) (120) (117) (117) (117) (117) (119) +(119) (120) (120) (120) (121) (122) (123) (123) (123) (123) (126) (127) +(127) (127) (127) (127) (129) (129) (130) (131) (131) (132) (132) (133) +(135) (136) (136) (136) (136) (146) (151) (152) (152) (152) (152) (156) +(157) (157) (157) (157) (157) (158) (159) (160) (161) (161) (161) (161) +(161) (161) (162) (162) (163) (164) (164) (164) (164) (164) (165) (165) +(165) (165) (165) (166) (167) (167) (167) (167) (170) (171) (171) (171) +(171) (171) (172) (172) (172) (175) (178) (178) (179) (180) (181) (181) +(182) (182) (183) (183) (184) (184) (184) (184) (185) (185) (185) (186) +(187) (187)] D +/h0 [()(Table of Contents)] D +/h1 [(0.1\240\240)(Funtools: FITS Users Need Tools)] D +/h2 [(0.2\240\240)(Summary)] D +/h3 [(0.3\240\240)(Description)] D +/h4 [(0.3.0.0.1\240\240)(Last updated: January 6, 2006)] D +/h5 [(0.4\240\240)(Funtools Programs)] D +/h6 [(0.5\240\240)(Summary)] D +/h7 [(0.6\240\240)(funcalc - Funtools calculator \(for binary tables\))] D +/h8 [(0.7\240\240)(funcen - find centroid \(for binary tables\))] D +/h9 [(0.8\240\240)(funcnts - count photons in specified regions, with bkgd subtraction)] D +/h10 [(0.9\240\240)(funcone - cone search of a binary table containing RA, Dec columns)] D +/h11 [(0.10\240\240)(fundisp - display data in a Funtools data file)] D +/h12 [(0.11\240\240)(funhead - display a header in a Funtools file)] D +/h13 [(0.12\240\240)(funhist - create a 1D histogram of a column \(from a FITS binary table or raw event file\) or an image)] D +/h14 [(0.13\240\240)(funimage - create a FITS image from a Funtools data file)] D +/h15 [(0.14\240\240)(funindex - create an index for a column of a FITS binary table)] D +/h16 [(0.15\240\240)(funjoin - join two or more FITS binary tables on specified columns)] D +/h17 [(0.16\240\240)(funmerge - merge one or more Funtools table files)] D +/h18 [(0.17\240\240)(funsky - convert between image and sky coordinates)] D +/h19 [(0.18\240\240)(funtable - copy selected rows from a Funtools file to a FITS binary table)] D +/h20 [(0.19\240\240)(funtbl - extract a table from Funtools ASCII output)] D +/h21 [(0.19.0.0.1\240\240)(Last updated: April 1, 2007)] D +/h22 [(0.20\240\240)(FunDS9: Funtools and DS9 Image Display)] D +/h23 [(0.21\240\240)(Summary)] D +/h24 [(0.22\240\240)(Description)] D +/h25 [(0.22.0.0.1\240\240)(Last updated: November 16, 2005)] D +/h26 [(0.23\240\240)(FunLib: the Funtools Programming Interface)] D +/h27 [(0.24\240\240)(Summary)] D +/h28 [(0.25\240\240)(Introduction to the Funtools Programming Interface)] D +/h29 [(0.26\240\240)(Funtools Programming Tutorial)] D +/h30 [(0.27\240\240)(Compiling and Linking)] D +/h31 [(0.28\240\240)(A Short Digression on Subroutine Order)] D +/h32 [(0.29\240\240)(Funtools Programming Examples)] D +/h33 [(0.30\240\240)(The Funtools Programming Reference Manual)] D +/h34 [(0.31\240\240)(FunOpen - open a Funtools data file)] D +/h35 [(0.32\240\240)(FunImageGet - get an image or image section)] D +/h36 [(0.33\240\240)(FunImagePut - put an image to a Funtools file)] D +/h37 [(0.34\240\240)(FunImageRowGet - get row\(s\) of an image)] D +/h38 [(0.35\240\240)(FunImageRowPut - put row\(s\) of an image)] D +/h39 [(0.36\240\240)(FunColumnSelect - select Funtools columns)] D +/h40 [(0.37\240\240)(FunColumnActivate - activate Funtools columns)] D +/h41 [(0.38\240\240)(FunColumnLookup - lookup a Funtools column)] D +/h42 [(0.39\240\240)(FunTableRowGet - get Funtools rows)] D +/h43 [(0.40\240\240)(FunTableRowPut - put Funtools rows)] D +/h44 [(0.41\240\240)(FunParamPut - put a Funtools param value)] D +/h45 [(0.42\240\240)(FunInfoGet - get information from Funtools struct)] D +/h46 [(0.43\240\240)(FunInfoPut - put information into a Funtools struct)] D +/h47 [(0.44\240\240)(FunFlush - flush data to output file)] D +/h48 [(0.45\240\240)(FunClose - close a Funtools data file)] D +/h49 [(0.46\240\240)(FunRef: the Funtools Reference Handle)] D +/h50 [(0.47\240\240)(Summary)] D +/h51 [(0.48\240\240)(Description)] D +/h52 [(0.48.0.0.1\240\240)(Last updated: December 1, 2005)] D +/h53 [(0.49\240\240)(FunFiles: Funtools Data Files)] D +/h54 [(0.50\240\240)(Summary)] D +/h55 [(0.51\240\240)(Description)] D +/h56 [(0.52\240\240)(Supported Data Formats)] D +/h57 [(0.53\240\240)(FITS Images and Binary Tables)] D +/h58 [(0.54\240\240)(Non-FITS Raw Event Files)] D +/h59 [(0.55\240\240)(Non-FITS Array Files)] D +/h60 [(0.56\240\240)(Specifying Image Sections)] D +/h61 [(0.57\240\240)(Binning FITS Binary Tables and Non-FITS Event Files)] D +/h62 [(0.58\240\240)(Table and Spatial Region Filters)] D +/h63 [(0.59\240\240)(Disk Files and Other Supported File Types)] D +/h64 [(0.60\240\240)(Lists of Files)] D +/h65 [(0.60.0.0.1\240\240)(Last updated: February 15, 2006)] D +/h66 [(0.61\240\240)(Funtext: Support for Column-based Text Files)] D +/h67 [(0.62\240\240)(Summary)] D +/h68 [(0.63\240\240)(Description)] D +/h69 [(0.64\240\240)(Standard Text Files)] D +/h70 [(0.65\240\240)(Comments Convert to Header Params)] D +/h71 [(0.66\240\240)(Multiple Tables in a Single File)] D +/h72 [(0.67\240\240)(TEXT\(\) Specifier)] D +/h73 [(0.68\240\240)(Text\(\) Keyword Options)] D +/h74 [(0.69\240\240)(Environment Variables)] D +/h75 [(0.70\240\240)(Restrictions and Problems)] D +/h76 [(0.70.0.0.1\240\240)(Last updated: August 3, 2007)] D +/h77 [(0.71\240\240)(Funview: Database View Support for Tables)] D +/h78 [(0.72\240\240)(Summary)] D +/h79 [(0.73\240\240)(Description)] D +/h80 [(0.74\240\240)(Database Views)] D +/h81 [(0.75\240\240)(Funtools View Attributes)] D +/h82 [(0.76\240\240)(Invoking a Funtools View \(in Place of an Input File\))] D +/h83 [(0.77\240\240)(Basic View Matching Rules)] D +/h84 [(0.78\240\240)(More on View Matching Rules: Single vs. Multiple Matches)] D +/h85 [(0.79\240\240)(View Lists: Applying a View to Any File)] D +/h86 [(0.80\240\240)(Overriding Values Associated with a View)] D +/h87 [(0.81\240\240)(Environment Variables)] D +/h88 [(0.82\240\240)(Restrictions and Problems)] D +/h89 [(0.82.0.0.1\240\240)(Last updated: August 3, 2007)] D +/h90 [(0.83\240\240)(Funfilters: Filtering Rows in a Table)] D +/h91 [(0.84\240\240)(Summary)] D +/h92 [(0.85\240\240)(Description)] D +/h93 [(0.86\240\240)(Filter Expressions)] D +/h94 [(0.87\240\240)(Separators Also Are Operators)] D +/h95 [(0.88\240\240)(Range Lists)] D +/h96 [(0.89\240\240)(Math Operations and Functions)] D +/h97 [(0.90\240\240)(Include Files)] D +/h98 [(0.91\240\240)(Header Parameters)] D +/h99 [(0.92\240\240)(Examples)] D +/h100 [(0.92.0.0.1\240\240)(Last updated: November 17, 2005)] D +/h101 [(0.93\240\240)(Funidx: Using Indexes to Filter Rows in a Table)] D +/h102 [(0.94\240\240)(Summary)] D +/h103 [(0.95\240\240)(Description)] D +/h104 [(0.95.0.0.1\240\240)(Last updated: August 3, 2007)] D +/h105 [(0.96\240\240)(Regions: Spatial Region Filtering)] D +/h106 [(0.97\240\240)(Summary)] D +/h107 [(0.98\240\240)(Description)] D +/h108 [(0.99\240\240)(Region Expressions)] D +/h109 [(0.100\240\240)(Columns Used in Region Filtering)] D +/h110 [(0.101\240\240)(Region Algebra)] D +/h111 [(0.102\240\240)(Region Separators Also Are Operators)] D +/h112 [(0.103\240\240)(Region Exclusion)] D +/h113 [(0.104\240\240)(Include Files)] D +/h114 [(0.105\240\240)(Global and Local Properties of Regions)] D +/h115 [(0.106\240\240)(Coordinate Systems)] D +/h116 [(0.107\240\240)(Specifying Positions, Sizes, and Angles)] D +/h117 [(0.107.0.0.1\240\240)(Last updated: November 17, 2005)] D +/h118 [(0.108\240\240)(RegGeometry: Geometric Shapes in Spatial Region Filtering)] D +/h119 [(0.109\240\240)(Summary)] D +/h120 [(0.110\240\240)(Geometric shapes)] D +/h121 [(0.111\240\240)(Region accelerators)] D +/h122 [(0.111.0.0.1\240\240)(Last updated: March 12, 2007)] D +/h123 [(0.112\240\240)(RegAlgebra: Boolean Algebra on Spatial Regions)] D +/h124 [(0.113\240\240)(Summary)] D +/h125 [(0.114\240\240)(Description)] D +/h126 [(0.114.0.0.1\240\240)(Last updated: November 17, 2005)] D +/h127 [(0.115\240\240)(RegCoords: Spatial Region Coordinates)] D +/h128 [(0.116\240\240)(Summary)] D +/h129 [(0.117\240\240)(Pixel coordinate systems)] D +/h130 [(0.118\240\240)(World Coordinate Systems)] D +/h131 [(0.119\240\240)(WCS Positions and Sizes)] D +/h132 [(0.120\240\240)(NB: The Meaning of Pure Numbers Are Context Sensitive)] D +/h133 [(0.120.0.0.1\240\240)(Last updated: November 17, 2005)] D +/h134 [(0.121\240\240)(RegBounds: Region Boundaries)] D +/h135 [(0.122\240\240)(Summary)] D +/h136 [(0.123\240\240)(Description)] D +/h137 [(0.124\240\240)(Image boundaries : radially-symmetric shapes \(circle, annuli, ellipse\))] D +/h138 [(0.125\240\240)(Image Boundaries: non-radially symmetric shapes \(polygons, boxes\))] D +/h139 [(0.126\240\240)(Row Boundaries are Analytic)] D +/h140 [(0.127\240\240)(Image Boundaries vs. Row Boundaries: Practical Considerations)] D +/h141 [(0.127.0.0.1\240\240)(Last updated: November 16, 2005)] D +/h142 [(0.128\240\240)(RegDiff:Differences Between Funtools and IRAF Regions)] D +/h143 [(0.129\240\240)(Summary)] D +/h144 [(0.130\240\240)(Description)] D +/h145 [(0.130.0.0.1\240\240)(Last updated: November 16, 2005)] D +/h146 [(0.131\240\240)(FunCombine: Combining Region and Table Filters)] D +/h147 [(0.132\240\240)(Summary)] D +/h148 [(0.133\240\240)(Comma Conventions)] D +/h149 [(0.133.0.0.1\240\240)(Last updated: November 16, 2005)] D +/h150 [(0.134\240\240)(FunEnv: Funtools Environment Variables)] D +/h151 [(0.135\240\240)(Summary)] D +/h152 [(0.136\240\240)(Description)] D +/h153 [(0.136.0.0.1\240\240)(Last updated: November 16, 2005)] D +/h154 [(0.137\240\240)(Funtools ChangeLog)] D +/h155 [(0.138\240\240)(Patch Release 1.4.5 \(internal ds9 release\))] D +/h156 [(0.139\240\240)(Patch Release 1.4.4 \(internal ds9 release\))] D +/h157 [(0.140\240\240)(Patch Release 1.4.3 \(internal ds9 release\))] D +/h158 [(0.141\240\240)(Patch Release 1.4.2 \(internal ds9 release\))] D +/h159 [(0.142\240\240)(Patch Release 1.4.1 \(internal ds9 release\))] D +/h160 [(0.143\240\240)(Public Release 1.4.0 \(15 August 2007\))] D +/h161 [(0.144\240\240)(Release 1.3.0b[n] \(mainly internal SAO beta releases\))] D +/h162 [(0.145\240\240)(Patch Release 1.2.4 \(internal SAO and beta release only\))] D +/h163 [(0.146\240\240)(Patch Release 1.2.3 \(12 January 2004\))] D +/h164 [(0.147\240\240)(Patch Release 1.2.3b1 \(19 August 2003\))] D +/h165 [(0.148\240\240)(Patch Release 1.2.2 \(18 May 2003\))] D +/h166 [(0.149\240\240)(Patch Release 1.2.1 \(24 April 2003\))] D +/h167 [(0.150\240\240)(Public Release 1.2.0 \(24 March 2003\))] D +/h168 [(0.151\240\240)(Beta Release 1.2.b3 \(4 February 2003\))] D +/h169 [(0.152\240\240)(Beta Release 1.2.b2 \(7 October 2002\))] D +/h170 [(0.153\240\240)(Beta Release 1.2.b1 \(24 September 2002\))] D +/h171 [(0.154\240\240)(Public Release 1.1.0 \(22 April 2002\))] D +/h172 [(0.155\240\240)(Pre-Release 1.1.0e \(10 April 2002\))] D +/h173 [(0.156\240\240)(Pre-Release 1.1.0e \(19 March 2002\))] D +/h174 [(0.157\240\240)(Pre-Release 1.1.0e \(27 February 2002\))] D +/h175 [(0.158\240\240)(Pre-Release 1.1.0e \(11 February 2002\))] D +/h176 [(0.159\240\240)(Beta Release 1.0.1b5 \(31 January 2002\))] D +/h177 [(0.160\240\240)(Beta Release 1.0.1b4 \(26 January 2002\))] D +/h178 [(0.161\240\240)(Beta Release 1.0.1b3 \(4 January 2002\))] D +/h179 [(0.162\240\240)(Beta Release 1.0.1b2 \(14 November 2001\))] D +/h180 [(0.163\240\240)(Beta Release 1.0.1b1 \(6 November 2001\))] D +/h181 [(0.164\240\240)(Public Release 1.0.0 \(31 July 2001\))] D +/h182 [(0.164.0.0.1\240\240)(Last updated: 22 April 2002)] D +/Hr [-63 63 64 65 -66 -66 66 -67 67 68 69 70 71 72 73 74 75 76 77 78 79 +80 81 82 -83 -83 83 -85 85 86 87 -88 -88 88 -91 91 92 93 94 95 96 97 98 +99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 -117 +-117 117 -120 120 121 122 123 124 125 126 127 128 129 130 131 -132 -132 +132 -134 134 135 136 137 138 139 140 141 142 143 -144 -144 144 -146 146 +147 148 149 150 151 152 153 154 155 156 157 -158 -158 158 -165 165 166 167 +168 169 170 171 172 173 174 -175 -175 175 -177 177 178 179 -180 -180 180 +-182 182 183 184 185 186 187 188 189 190 191 192 193 -194 -194 194 -196 +196 197 198 199 -200 -200 200 -202 202 203 204 -205 -205 205 -207 207 208 +209 210 211 212 -213 -213 213 -215 215 216 217 218 219 220 221 -222 -222 +222 -224 224 225 226 -227 -227 227 -230 230 231 232 -233 -233 233 -235 235 +236 237 -238 -238 238 -239 239 240 241 242 243 244 245 246 247 248 249 250 +251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 -267 -267 +267]D +/HV [1 2 2 2 3 4 5 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 4 5 1 2 2 2 3 4 +5 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 4 5 1 2 2 2 2 +2 2 2 2 2 2 2 2 3 4 5 1 2 2 2 2 2 2 2 2 2 2 3 4 5 1 2 2 2 2 2 2 2 2 2 2 +2 2 3 4 5 1 2 2 2 2 2 2 2 2 2 2 3 4 5 1 2 2 2 3 4 5 1 2 2 2 2 2 2 2 2 2 +2 2 2 3 4 5 1 2 2 2 2 3 4 5 1 2 2 2 3 4 5 1 2 2 2 2 2 2 3 4 5 1 2 2 2 2 +2 2 2 3 4 5 1 2 2 2 3 4 5 1 2 2 2 3 4 5 1 2 2 2 3 4 5 1 2 2 2 2 2 2 2 2 +2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 4 5]D +/Cn [3 0 0 1 1 1 0 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 3 0 0 1 1 1 +0 26 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 12 0 0 0 +0 0 0 0 0 0 0 0 1 1 1 0 10 0 0 0 0 0 0 0 0 0 1 1 1 0 12 0 0 0 0 0 0 0 0 +0 0 0 1 1 1 0 10 0 0 0 0 0 0 0 0 0 1 1 1 0 3 0 0 1 1 1 0 12 0 0 0 0 0 0 +0 0 0 0 0 1 1 1 0 4 0 0 0 1 1 1 0 3 0 0 1 1 1 0 6 0 0 0 0 0 1 1 1 0 7 0 +0 0 0 0 0 1 1 1 0 3 0 0 1 1 1 0 3 0 0 1 1 1 0 3 0 0 1 1 1 0 28 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0]D +Hr length 0 gt{[/PageMode /UseOutlines /DOCVIEW pdfmark}if +/Hn 1 D +0 1 Hr length 1 sub{ + /Bn E D [Cn Bn get dup 0 gt{/Count E HV Bn get Bl ge{neg}if}{pop}ie + /Dest Hr Bn get dup abs ST cvs cvn E 0 ge{(h)Hn ST cvs join cvx exec + dup 1 get E Nf{0 get E join}{pop}ie /Hn Hn 1 add D}{()}ie + /Title E dup length 255 gt{0 255 getinterval}if /OUT pdfmark}for +ZF /FN Fp D Ps 0 FS /WC Wf{( )}{}ie SW pop D +ET RC ZF +/Df f D +/R1 (http://hea-www.harvard.edu/saord/ds9/index.html) D +/R2 (http://hea-www.harvard.edu/saord/xpa/index.html) D +/R3 (ftp://cfa-ftp.harvard.edu/pub/gsc/WCSTools/home.html) D +/R4 (http://tdc-www.harvard.edu/software/wcstools/) D +/R5 (http://hea-www.harvard.edu/RD/funtools/changelog.html) D +/R6 (http://hea-www.harvard.edu/RD/funtools/changelog_beta.html) D +/Ba f D /BO 0 D Bs +/UR (help.html) D +/Ti (The Funtools Help Facility) D +/Au () D +/Df f D +/ME [()] D + TC + +/Cb Db D /Ct [16#00 16#00 16#00] D /Cl [16#00 16#00 16#00] D /CL -1 D Ct Sc + +/Ba f D /BO 0 D Bs +/UR (help.html) D +/Ti (The Funtools Help Facility) D +/Au () D +/Df f D +/ME [()] D + TC + +NP RC ZF +()1 Sl()WB 0 Sn( + + +)0 2 0 H(Funtools:)WB 63 Sn()WB 1 Sn( FITS Users Need Tools)EA()EH( + + +)0 2 1 H(Summary)WB 64 Sn()EH( +This document is the Table of Contents for Funtools. + + +)0 2 2 H(Description)WB 65 Sn()EH( +Funtools, is a "minimal buy-in" FITS library and utility package developed +at the the High Energy Astrophysics Division of SAO. The Funtools +library provides simplified access to a wide array of file types: +standard astronomical FITS images and binary tables, raw arrays and +binary event lists, and even tables of ASCII column data. A +sophisticated region filtering library \201compatible with ds9\202 filters +images and tables using boolean operations between geometric shapes, +support world coordinates, etc. Funtools also supports advanced +capabilities such as optimized data searching using index files. + +The main goal of the Funtools project has been to develop a minimal buy-in +FITS library for researchers who are occasional \201but serious\202 coders. In +this case, "minimal buy-in" means "easy to learn, easy to use, and easy to +re-learn next month". We have tried to achieve this goal by emphasizing two +essential capabilities. The first is the ability to develop FITS programs +without knowing much about FITS, i.e., without having to deal with the +arcane rules for generating a properly formatted FITS file. The second is +to support the use of already-familiar C/Unix facilities, especially C +structs and Unix stdio. Taken together, these two capabilities should allow +researchers to leverage their existing programming expertise while +minimizing the need to learn new and complex coding rules. + + +)0 P(Choose from the following topics: + +)0 P()UL()-1 LI()0 2 1 A(Funtools User Programs)2 1 TN TL()Ec /AF f D( +)UL()-1 LI()0 3 1 A(funcalc: Funtools calculator \201for binary tables\202)3 1 TN TL()Ec /AF f D( + +)-1 LI()0 4 1 A(funcen: find centroid \201for binary tables\202)4 1 TN TL()Ec /AF f D( + +)-1 LI()0 5 1 A(funcnts: count photons in specified regions)5 1 TN TL()Ec /AF f D( + +)-1 LI()0 6 1 A(funcone: cone search on RA, Dec columns)6 1 TN TL()Ec /AF f D( + +)-1 LI()0 7 1 A(fundisp: display data in a Funtools data file)7 1 TN TL()Ec /AF f D( + +)-1 LI()0 8 1 A(funhead: display a header in a Funtools file)8 1 TN TL()Ec /AF f D( + +)-1 LI()0 9 1 A(funhist: create a 1D histogram of a column)9 1 TN TL()Ec /AF f D( + +)-1 LI()0 10 1 A(funimage: create a FITS image from a Funtools data file)10 1 TN TL()Ec /AF f D( + +)-1 LI()0 11 1 A(funindex: create an index on a column in a binary table)11 1 TN TL()Ec /AF f D( + +)-1 LI()0 12 1 A(funjoin: join two or more FITS binary tables on specified columns)12 1 TN TL()Ec /AF f D( + +)-1 LI()0 13 1 A(funmerge: merge one or more Funtools table files)13 1 TN TL()Ec /AF f D( + +)-1 LI()0 14 1 A(funsky: convert between image and sky coordinates, using WCS info from a FITS header)14 1 TN TL()Ec /AF f D( + +)-1 LI()0 15 1 A(funtable: copy selected rows from a Funtools file to a FITS binary table)15 1 TN TL()Ec /AF f D( + +)-1 LI()0 16 1 A(funtbl: extract a table from +Funtools ASCII output)16 1 TN TL()Ec /AF f D( + +)-1 LI()0 17 1 A(funtools and ds9 image display)17 1 TN TL()Ec /AF f D( +)LU( + +)-1 LI()0 18 1 A(Funtools Programming)18 1 TN TL()Ec /AF f D( +)UL()-1 LI()0 19 1 A(Funtools Programming Summary)19 1 TN TL()Ec /AF f D( + +)-1 LI()0 20 1 A(Funtools Programming Tutorial)20 1 TN TL()Ec /AF f D( + +)-1 LI()0 21 1 A(A Short Digression on Subroutine Order)21 1 TN TL()Ec /AF f D( + +)-1 LI()0 22 1 A(Compiling and Linking)22 1 TN TL()Ec /AF f D( + +)-1 LI()0 23 1 A(The Funtools Reference Handle)23 1 TN TL()Ec /AF f D( + +)-1 LI()0 24 1 A(The Funtools Programming Reference Manual)24 1 TN TL()Ec /AF f D( +)UL()-1 LI( )0 25 1 A(FunOpen: open a Funtools file)25 1 TN TL()Ec /AF f D( + +)-1 LI()0 26 1 A(FunImageGet: retrieve image data)26 1 TN TL()Ec /AF f D( + +)-1 LI()0 27 1 A(FunImagePut: output image data)27 1 TN TL()Ec /AF f D( + +)-1 LI()0 28 1 A(FunImageRowGet: retrieve image data by row)28 1 TN TL()Ec /AF f D( + +)-1 LI()0 29 1 A(FunImageRowPut: output image data by row)29 1 TN TL()Ec /AF f D( + +)-1 LI()0 30 1 A(FunTableRowGet: retrieve rows from a table)30 1 TN TL()Ec /AF f D( + +)-1 LI()0 31 1 A(FunTableRowPut: output rows to a table)31 1 TN TL()Ec /AF f D( + +)-1 LI()0 32 1 A(FunColumnSelect: select columns in a table for access)32 1 TN TL()Ec /AF f D( + +)-1 LI()0 33 1 A(FunColumnActivate: activate columns in a table for read/write)33 1 TN TL()Ec /AF f D( + +)-1 LI()0 34 1 A(FunColumnLookup: lookup info about the columns in a table)34 1 TN TL()Ec /AF f D( + +)-1 LI()0 35 1 A(FunInfoGet: get info about an image or table)35 1 TN TL()Ec /AF f D( + +)-1 LI()0 36 1 A(FunInfoPut: put info about an image or table)36 1 TN TL()Ec /AF f D( + +)-1 LI()0 37 1 A(FunParamGet: get header param)37 1 TN TL()Ec /AF f D( + +)-1 LI()0 38 1 A(FunParamPut: put header param)38 1 TN TL()Ec /AF f D( + +)-1 LI()0 39 1 A(FunFlush: flush I/O in a Funtools file)39 1 TN TL()Ec /AF f D( + +)-1 LI()0 40 1 A(FunClose: close a Funtools file)40 1 TN TL()Ec /AF f D( +)LU( + +)-1 LI()0 41 1 A(Funtools Programming Examples)41 1 TN TL()Ec /AF f D( + +)UL( +)-1 LI()0 2 A(evmerge: merge new columns with existing columns)EA( +)-1 LI()0 2 A(evcols: add column and rows to binary tables)EA( +)-1 LI()0 2 A(imblank: blank out image values below a threshold)EA()LU()LU( + +)-1 LI()0 42 1 A(Funtools Data Files)42 1 TN TL()Ec /AF f D( + +)UL( +)-1 LI()0 43 1 A(Supported Data Formats)43 1 TN TL()Ec /AF f D( +)UL()-1 LI()0 44 1 A(FITS File and Extensions)44 1 TN TL()Ec /AF f D( +)-1 LI()0 45 1 A(Non-FITS Raw Event Files)45 1 TN TL()Ec /AF f D( +)-1 LI()0 46 1 A(Non-FITS Array Files)46 1 TN TL()Ec /AF f D( +)-1 LI()0 47 1 A(Column-based Text \201ASCII\202 Files)47 1 TN TL()Ec /AF f D( +)-1 LI()0 48 1 A(Database Views of Tables)48 1 TN TL()Ec /AF f D()LU( +)-1 LI()0 49 1 A(Image Sections and Blocking)49 1 TN TL()Ec /AF f D( +)-1 LI()0 50 1 A(Binning FITS Binary Tables and Non-FITS Event Files)EH( +)-1 LI()0 51 1 A(Disk Files and Other Supported File Types)50 1 TN TL()Ec /AF f D()LU( + +)-1 LI(Funtools Data Filtering +)UL()-1 LI()0 52 1 A(Table Filtering)51 1 TN TL()Ec /AF f D( + +)-1 LI()0 53 1 A(Fast Table Filtering using Indexes)52 1 TN TL()Ec /AF f D( + +)-1 LI()0 54 1 A(Spatial Region Filtering)53 1 TN TL()Ec /AF f D( + +)UL()-1 LI()0 55 1 A(Region Geometry)54 1 TN TL()Ec /AF f D( + +)-1 LI()0 56 1 A(Region Algebra)55 1 TN TL()Ec /AF f D( + +)-1 LI()0 57 1 A(Region Coordinates)56 1 TN TL()Ec /AF f D( + +)-1 LI()0 58 1 A(Region Boundaries)57 1 TN TL()Ec /AF f D( + +)-1 LI()0 59 1 A(Differences Between Funtools and IRAF Regions)58 1 TN TL()Ec /AF f D( +)LU( +)-1 LI()0 60 1 A(Combining Table and Region Filters)59 1 TN TL()Ec /AF f D( +)LU( + +)-1 LI( Miscellaneous +)UL()-1 LI()0 61 1 A(Funtools Environment Variables)60 1 TN TL()Ec /AF f D( + +)-1 LI()0 62 1 A(Funtools ChangeLog)61 1 TN TL()Ec /AF f D()LU( +)LU( + + + +)0 5 3 H(Last)WB 66 Sn( updated: January 6, 2006)EH( + + +)WB NL NP Ep ET /Tc f D +/Cb Db D /Ct [16#00 16#00 16#00] D /Cl [16#00 16#00 16#00] D /CL -1 D Ct Sc +DS +/Ba f D /BO 0 D Bs +/UR (programs.html) D +/Ti (Funtools Programs) D +/Au () D +/Df f D +/ME [()] D + +0 BO R +()1 Sl()WB 2 Sn( +)0 2 4 H(Funtools)WB 67 Sn( Programs)EH( + +)0 2 5 H(Summary)WB 68 Sn()EH( + +)0 P() 27 129 PR()0 3 1 A(funcalc)3 0 TN TL()Ec /AF f D( [-n] [-a argstr] [-e expr] [-f file] [-l link] [-p prog] [-u] [oname [columns]] + +)0 4 1 A(funcen)4 0 TN TL()Ec /AF f D( [-i] [-n iter] [-t tol] [-v lev] + +)0 5 1 A(funcnts)5 0 TN TL()Ec /AF f D( [switches] [source_region] [bkgd_file] [bkgd_region|bkgd_cnts] + +)0 6 1 A(funcone)6 0 TN TL()Ec /AF f D( [-n] [-x|-X|-j|-J] [[-l|-L] list] [-r ra_col] [-d dec_col] [columns] + +)0 7 1 A(fundisp)7 0 TN TL()Ec /AF f D( [-f format] [-l] [-n] [-T] [columns|bitpix=n] + +)0 8 1 A(funhead)8 0 TN TL()Ec /AF f D( [-a] [-l] [-s] [-t] [-L] [oname ename] + +)0 9 1 A(funhist)9 0 TN TL()Ec /AF f D( [-n|-w|-T] [column] [[lo_edge:hi_edge:]bins] + +)0 10 1 A(funimage)10 0 TN TL()Ec /AF f D( [-a] [-l] [-p x|y] [bitpix=n] + +)0 11 1 A(funindex)11 0 TN TL()Ec /AF f D( [oname] + +)0 12 1 A(funjoin)12 0 TN TL()Ec /AF f D( [switches] ... + +)0 13 1 A(funmerge)13 0 TN TL()Ec /AF f D( ... + +)0 14 1 A(funsky)14 0 TN TL()Ec /AF f D( [switches] [ ] + +)0 15 1 A(funtable)15 0 TN TL()Ec /AF f D( [-a] [-i|-z] [-m] [-s cols] [columns] + +)0 16 1 A(funtbl)16 0 TN TL()Ec /AF f D( [-c cols] [-h] [-n table] [-p prog] [-s sep] [-T] )RP( + + + + +)0 2 6 H(funcalc)WB 69 Sn()WB 3 Sn( - Funtools calculator \201for binary tables\202)EA()EH( + +)BD() 1 90 PR(funcalc [-n] [-a argstr] [-e expr] [-f file] [-l link] [-p prog] [oname [columns]])RP()ES( + + +)0 P() 7 73 PR( -a argstr # user arguments to pass to the compiled program + -e expr # funcalc expression + -f file # file containing funcalc expression + -l libs # libs to add to link command + -n # output generated code instead of compiling and executing + -p prog # generate named program, no execution + -u # die if any variable is undeclared \201don't auto-declare\202)RP( + + +)0 P()BD(funcalc)ES( is a calculator program that allows arbitrary +expressions to be constructed, compiled, and executed on columns in a +Funtools table \201FITS binary table or raw event file\202. It works by +integrating user-supplied expression\201s\202 into a template C program, +then compiling and executing the program. )BD(funcalc)ES( expressions +are C statements, although some important simplifications \201such +as automatic declaration of variables\202 are supported. + +)0 P()BD(funcalc)ES( expressions can be specified in three ways: on the +command line using the )BD(-e [expression])ES( switch, in a file using +the )BD(-f [file])ES( switch, or from stdin \201if neither )BD(-e)ES( nor +)BD(-f)ES( is specified\202. Of course a file containing )BD(funcalc)ES( +expressions can be read from stdin. + +)0 P(Each invocation of )BD(funcalc)ES( requires an input Funtools table +file to be specified as the first command line argument. The output +Funtools table file is the second optional argument. It is needed only +if an output FITS file is being created \201i.e., in cases where the +)BD(funcalc)ES( expression only prints values, no output file is +needed\202. If input and output file are both specified, a third optional +argument can specify the list of columns to activate \201using +)0 33 1 A(FunColumnActivate\201\202)33 0 TN TL()Ec /AF f D(\202. Note +that )BD(funcalc)ES( determines whether or not to generate code for +writing an output file based on the presence or absence of an +output file argument. + +)0 P(A )BD(funcalc)ES( expression executes on each row of a table and +consists of one or more C statements that operate on the columns of +that row \201possibly using temporary variables\202. Within an expression, +reference is made to a column of the )BD(current)ES( row using the C +struct syntax )BD(cur->[colname])ES(, e.g. cur->x, cur->pha, etc. +Local scalar variables can be defined using C declarations at very the +beginning of the expression, or else they can be defined automatically +by )BD(funcalc)ES( \201to be of type double\202. Thus, for example, a swap of +columns x and y in a table can be performed using either of the +following equivalent )BD(funcalc)ES( expressions: + +) 4 18 PR( double temp; + temp = cur->x; + cur->x = cur->y; + cur->y = temp;)RP( + +or: + +) 3 18 PR( temp = cur->x; + cur->x = cur->y; + cur->y = temp;)RP( + +When this expression is executed using a command such as: +) 1 40 PR( funcalc -f swap.expr itest.ev otest.ev)RP( +the resulting file will have values of the x and y columns swapped. + +)0 P(By default, the data type of the variable for a column is the same as +the data type of the column as stored in the file. This can be changed +by appending ":[dtype]" to the first reference to that column. In the +example above, to force x and y to be output as doubles, specify the +type 'D' explicitly: +) 3 20 PR( temp = cur->x:D; + cur->x = cur->y:D; + cur->y = temp;)RP( + +Data type specifiers follow standard FITS table syntax for defining +columns using TFORM: +)UL()-1 LI(A: ASCII characters +)-1 LI(B: unsigned 8-bit char +)-1 LI(I: signed 16-bit int +)-1 LI(U: unsigned 16-bit int \201not standard FITS\202 +)-1 LI(J: signed 32-bit int +)-1 LI(V: unsigned 32-bit int \201not standard FITS\202 +)-1 LI(E: 32-bit float +)-1 LI(D: 64-bit float +)-1 LI(X: bits \201treated as an array of chars\202)LU( +Note that only the first reference to a column should contain the +explicit data type specifier. + +)0 P(Of course, it is important to handle the data type of the columns +correctly. One of the most frequent cause of error in )BD(funcalc)ES( +programming is the implicit use of the wrong data type for a column in +expression. For example, the calculation: +) 1 43 PR( dx = \201cur->x - cur->y\202/\201cur->x + cur->y\202;)RP( +usually needs to be performed using floating point arithmetic. In +cases where the x and y columns are integers, this can be done by +reading the columns as doubles using an explicit type specification: +) 1 47 PR( dx = \201cur->x:D - cur->y:D\202/\201cur->x + cur->y\202;)RP( + +Alternatively, it can be done using C type-casting in the expression: +) 1 75 PR( dx = \201\201double\202cur->x - \201double\202cur->y\202/\201\201double\202cur->x + \201double\202cur->y\202;)RP( + +)0 P(In addition to accessing columns in the current row, reference also +can be made to the )BD(previous)ES( row using )BD(prev->[colname])ES(, +and to the )BD(next)ES( row using )BD(next->[colname])ES(. Note that if +)BD(prev->[colname])ES( is specified in the )BD(funcalc)ES( +expression, the very first row is not processed. If +)BD(next->[colname])ES( is specified in the )BD(funcalc)ES( +expression, the very last row is not processed. In this way, +)BD(prev)ES( and )BD(next)ES( are guaranteed always to point to valid +rows. For example, to print out the values of the current x column +and the previous y column, use the C fprintf function in a +)BD(funcalc)ES( expression: +) 1 46 PR( fprintf\201stdout, "%d %d\200n", cur->x, prev->y\202;)RP( + +)0 P(New columns can be specified using the same )BD(cur->[colname])ES( +syntax by appending the column type \201and optional tlmin/tlmax/binsiz +specifiers\202, separated by colons. For example, cur->avg:D will define +a new column of type double. Type specifiers are the same those +used above to specify new data types for existing columns. + +)0 P(For example, to create and output a new column that is the average value of the +x and y columns, a new "avg" column can be defined: +) 1 36 PR( cur->avg:D = \201cur->x + cur->y\202/2.0)RP( +Note that the final ';' is not required for single-line expressions. + +)0 P(As with FITS TFORM data type specification, the column data type +specifier can be preceded by a numeric count to define an array, e.g., +"10I" means a vector of 10 short ints, "2E" means two single precision +floats, etc. A new column only needs to be defined once in a +)BD(funcalc)ES( expression, after which it can be used without +re-specifying the type. This includes reference to elements of a +column array: + +) 2 41 PR( cur->avg[0]:2D = \201cur->x + cur->y\202/2.0; + cur->avg[1] = \201cur->x - cur->y\202/2.0;)RP( + +)0 P(The 'X' \201bits\202 data type is treated as a char array of dimension +\201numeric_count/8\202, i.e., 16X is processed as a 2-byte char array. Each +8-bit array element is accessed separately: +) 2 24 PR( cur->stat[0]:16X = 1; + cur->stat[1] = 2;)RP( +Here, a 16-bit column is created with the MSB is set to 1 and the LSB set to 2. + +)0 P(By default, all processed rows are written to the specified output +file. If you want to skip writing certain rows, simply execute the C +"continue" statement at the end of the )BD(funcalc)ES( expression, +since the writing of the row is performed immediately after the +expression is executed. For example, to skip writing rows whose +average is the same as the current x value: + +) 4 41 PR( cur->avg[0]:2D = \201cur->x + cur->y\202/2.0; + cur->avg[1] = \201cur->x - cur->y\202/2.0; + if\201 cur->avg[0] == cur->x \202 + continue;)RP( + +)0 P(If no output file argument is specified on the )BD(funcalc)ES( command +line, no output file is opened and no rows are written. This is useful +in expressions that simply print output results instead of generating +a new file: +) 5 73 PR( fpv = \201cur->av3:D-cur->av1:D\202/\201cur->av1+cur->av2:D+cur->av3\202; + fbv = cur->av2/\201cur->av1+cur->av2+cur->av3\202; + fpu = \201\201double\202cur->au3-cur->au1\202/\201\201double\202cur->au1+cur->au2+cur->au3\202; + fbu = cur->au2/\201double\202\201cur->au1+cur->au2+cur->au3\202; + fprintf\201stdout, "%f\200t%f\200t%f\200t%f\200n", fpv, fbv, fpu, fbu\202;)RP( +In the above example, we use both explicit type specification +\201for "av" columns\202 and type casting \201for "au" columns\202 to ensure that +all operations are performed in double precision. + +)0 P(When an output file is specified, the selected input table is +processed and output rows are copied to the output file. Note that +the output file can be specified as "stdout" in order to write the +output rows to the standard output. If the output file argument is +passed, an optional third argument also can be passed to specify which +columns to process. + +)0 P(In a FITS binary table, it sometimes is desirable to copy all of the +other FITS extensions to the output file as well. This can be done by +appending a '+' sign to the name of the extension in the input file +name. See )BD(funtable)ES( for a related example. + +)0 P()BD(funcalc)ES( works by integrating the user-specified expression +into a template C program called )0 2 A(tabcalc.c)EA(. +The completed program then is compiled and executed. Variable +declarations that begin the )BD(funcalc)ES( expression are placed in +the local declaration section of the template main program. All other +lines are placed in the template main program's inner processing +loop. Other details of program generation are handled +automatically. For example, column specifiers are analyzed to build a +C struct for processing rows, which is passed to +)0 32 1 A(FunColumnSelect\201\202)32 0 TN TL()Ec /AF f D( and used +in )0 30 1 A(FunTableRowGet\201\202)30 0 TN TL()Ec /AF f D(. If +an unknown variable is used in the expression, resulting in a +compilation error, the program build is retried after defining the +unknown variable to be of type double. + +)0 P(Normally, )BD(funcalc)ES( expression code is added to +)BD(funcalc)ES( row processing loop. It is possible to add code +to other parts of the program by placing this code inside +special directives of the form: +) 3 26 PR( [directive name] + ... code goes here ... + end)RP( + +The directives are: +)UL()-1 LI()BD(global)ES( add code and declarations in global space, before the main routine. + +)-1 LI()BD(local)ES( add declarations \201and code\202 just after the local declarations in +main + +)-1 LI()BD(before)ES( add code just before entering the main row processing loop + +)-1 LI()BD(after)ES( add code just after exiting the main row processing loop)LU( + +Thus, the following )BD(funcalc)ES( expression will declare global +variables and make subroutine calls just before and just after the +main processing loop: +) 16 62 PR( global + double v1, v2; + double init\201void\202; + double finish\201double v\202; + end + before + v1 = init\201\202; + end + ... process rows, with calculations using v1 ... + after + v2 = finish\201v1\202; + if\201 v2 < 0.0 \202{ + fprintf\201stderr, "processing failed %g -> %g\200n", v1, v2\202; + exit\2011\202; + } + end)RP( +Routines such as init\201\202 and finish\201\202 above are passed to the generated +program for linking using the )BD(-l [link directives ...])ES( +switch. The string specified by this switch will be added to the link +line used to build the program \201before the funtools library\202. For +example, assuming that init\201\202 and finish\201\202 are in the library +libmysubs.a in the /opt/special/lib directory, use: +) 1 47 PR( funcalc -l "-L/opt/special/lib -lmysubs" ...)RP( + +)0 P(User arguments can be passed to a compiled funcalc program using a string +argument to the "-a" switch. The string should contain all of the +user arguments. For example, to pass the integers 1 and 2, use: +) 1 22 PR( funcalc -a "1 2" ...)RP( +The arguments are stored in an internal array and are accessed as +strings via the ARGV\201n\202 macro. For example, consider the following +expression: +) 11 60 PR( local + int pmin, pmax; + end + + before + pmin=atoi\201ARGV\2010\202\202; + pmax=atoi\201ARGV\2011\202\202; + end + + if\201 \201cur->pha >= pmin\202 && \201cur->pha <= pmax\202 \202 + fprintf\201stderr, "%d %d %d\200n", cur->x, cur->y, cur->pha\202;)RP( +This expression will print out x, y, and pha values for all rows in which +the pha value is between the two user-input values: +) 11 51 PR( funcalc -a '1 12' -f foo snr.ev'[cir 512 512 .1]' + 512 512 6 + 512 512 8 + 512 512 5 + 512 512 5 + 512 512 8 + + funcalc -a '5 6' -f foo snr.ev'[cir 512 512 .1]' + 512 512 6 + 512 512 5 + 512 512 5)RP( + +)0 P(Note that it is the user's responsibility to ensure that the correct +number of arguments are passed. The ARGV\201n\202 macro returns a NULL if a +requested argument is outside the limits of the actual number of args, +usually resulting in a SEGV if processed blindly. To check the +argument count, use the ARGC macro: +) 12 42 PR( local + long int seed=1; + double limit=0.8; + end + + before + if\201 ARGC >= 1 \202 seed = atol\201ARGV\2010\202\202; + if\201 ARGC >= 2 \202 limit = atof\201ARGV\2011\202\202; + srand48\201seed\202; + end + + if \201 drand48\201\202 > limit \202 continue;)RP( + +)0 P(The macro WRITE_ROW expands to the FunTableRowPut\201\202 call that writes +the current row. It can be used to write the row more than once. In +addition, the macro NROW expands to the row number currently being +processed. Use of these two macros is shown in the following example: +) 7 41 PR( if\201 cur->pha:I == cur->pi:I \202 continue; + a = cur->pha; + cur->pha = cur->pi; + cur->pi = a; + cur->AVG:E = \201cur->pha+cur->pi\202/2.0; + cur->NR:I = NROW; + if\201 NROW < 10 \202 WRITE_ROW;)RP( + +)0 P(If the )BD(-p [prog])ES( switch is specified, the expression is not +executed. Rather, the generated executable is saved with the specified +program name for later use. + +)0 P(If the )BD(-n)ES( switch is specified, the expression is not +executed. Rather, the generated code is written to stdout. This is +especially useful if you want to generate a skeleton file and add your +own code, or if you need to check compilation errors. Note that the +comment at the start of the output gives the compiler command needed +to build the program on that platform. \201The command can change from +platform to platform because of the use of different libraries, +compiler switches, etc.\202 + +)0 P(As mentioned previously, )BD(funcalc)ES( will declare a scalar +variable automatically \201as a double\202 if that variable has been used +but not declared. This facility is implemented using a sed script +named )0 2 A(funcalc.sed)EA(, which processes the +compiler output to sense an undeclared variable error. This script +has been seeded with the appropriate error information for gcc, and for +cc on Solaris, DecAlpha, and SGI platforms. If you find that automatic +declaration of scalars is not working on your platform, check this sed +script; it might be necessary to add to or edit some of the error +messages it senses. + +)0 P(In order to keep the lexical analysis of )BD(funcalc)ES( expressions +\201reasonably\202 simple, we chose to accept some limitations on how +accurately C comments, spaces, and new-lines are placed in the +generated program. In particular, comments associated with local +variables declared at the beginning of an expression \201i.e., not in a +)BD(local...end)ES( block\202 will usually end up in the inner loop, not +with the local declarations: +) 8 69 PR( /* this comment will end up in the wrong place \201i.e, inner loop\202 */ + double a; /* also in wrong place */ + /* this will be in the the right place \201inner loop\202 */ + if\201 cur->x:D == cur->y:D \202 continue; /* also in right place */ + a = cur->x; + cur->x = cur->y; + cur->y = a; + cur->avg:E = \201cur->x+cur->y\202/2.0;)RP( +Similarly, spaces and new-lines sometimes are omitted or added in a +seemingly arbitrary manner. Of course, none of these stylistic +blemishes affect the correctness of the generated code. + +)0 P(Because )BD(funcalc)ES( must analyze the user expression using the data +file\201s\202 passed on the command line, the input file\201s\202 must be opened +and read twice: once during program generation and once during +execution. As a result, it is not possible to use stdin for the +input file: )BD(funcalc)ES( cannot be used as a filter. We will +consider removing this restriction at a later time. + +)0 P(Along with C comments, )BD(funcalc)ES( expressions can have one-line +internal comments that are not passed on to the generated C +program. These internal comment start with the )BD(#)ES( character and +continue up to the new-line: +) 7 56 PR( double a; # this is not passed to the generated C file + # nor is this + a = cur->x; + cur->x = cur->y; + cur->y = a; + /* this comment is passed to the C file */ + cur->avg:E = \201cur->x+cur->y\202/2.0;)RP( + +)0 P(As previously mentioned, input columns normally are identified by +their being used within the inner event loop. There are rare cases +where you might want to read a column and process it outside the main +loop. For example, qsort might use a column in its sort comparison +routine that is not processed inside the inner loop \201and therefore not +implicitly specified as a column to be read\202. To ensure that such a +column is read by the event loop, use the )BD(explicit)ES( keyword. +The arguments to this keyword specify columns that should be read into +the input record structure even though they are not mentioned in the +inner loop. For example: + ) 1 17 PR( explicit pi pha)RP( +will ensure that the pi and pha columns are read for each row, +even if they are not processed in the inner event loop. The )BD(explicit)ES( +statement can be placed anywhere. + +)0 P(Finally, note that )BD(funcalc)ES( currently works on expressions +involving FITS binary tables and raw event files. We will consider +adding support for image expressions at a later point, if there is +demand for such support from the community. + + + + +)0 2 7 H(funcen)WB 70 Sn()WB 4 Sn( - find centroid \201for binary tables\202)EA()EH( + +)BD() 1 56 PR(funcen [-i] [-n iter] [-t tol] [-v lev] )RP()ES( + + +)0 P() 4 64 PR( -i # use image filtering \201default: event filtering\202 + -n iter # max number of iterations \201default: 0\202 + -t tol # pixel tolerance distance \201default: 1.0\202 + -v [0,1,2,3] # output verbosity level \201default: 0\202)RP( + + +)0 P()BD(funcen)ES( iteratively calculates the centroid position within one +or more regions of a Funtools table \201FITS binary table or raw event +file\202. Starting with an input table, an initial region specification, +and an iteration count, the program calculates the average x and y +position within the region and then uses this new position as the +region center for the next iteration. Iteration terminates when the +maximum number of iterations is reached or when the input tolerance +distance is met for that region. A count of events in the final region +is then output, along with the pixel position value \201and, where +available, WCS position\202. + +)0 P(The first argument to the program specifies the Funtools table file to +process. Since the file must be read repeatedly, a value of "stdin" +is not permitted when the number of iterations is non-zero. Use +)0 42 1 A(Funtools Bracket Notation)42 0 TN TL()Ec /AF f D( to specify FITS +extensions and filters. + +)0 P(The second required argument is the initial region descriptor. Multiple +regions are permitted. However, compound regions \201accelerators, +variable argument regions and regions connected via boolean algebra\202 +are not permitted. Points and polygons also are illegal. These +restrictions might be lifted in a future version, if warranted. + +)0 P(The )BD(-n)ES( \201iteration number\202 switch specifies the maximum number of +iterations to perform. The default is 0, which means that the program will +simply count and display the number of events in the initial region\201s\202. +Note that when iterations is 0, the data can be input via stdin. + +)0 P(The )BD(-t)ES( \201tolerance\202 switch specifies a floating point tolerance +value. If the distance between the current centroid position value and +the last position values is less than this value, iteration terminates. +The default value is 1 pixel. + +)0 P(The )BD(-v)ES( \201verbosity\202 switch specifies the verbosity level of the +output. The default is 0, which results in a single line of output for +each input region consisting of the following values: +) 1 30 PR( counts x y [ra dec coordsys])RP( +The last 3 WCS values are output if WCS information is available in the +data file header. Thus, for example: +) 5 47 PR( [sh] funcen -n 0 snr.ev "cir 505 508 5" + 915 505.00 508.00 345.284038 58.870920 j2000 + + [sh] funcen -n 3 snr.ev "cir 505 508 5" + 1120 504.43 509.65 345.286480 58.874587 j2000)RP( +The first example simply counts the number of events in the initial region. +The second example iterates the centroid calculation three times to determine +a final "best" position. + +)0 P( +Higher levels of verbosity obviously imply more verbose output. At +level 1, the output essentially contains the same information as level +0, but with keyword formatting: + + [sh] funcen -v 1 -n 3 snr.ev "cir 505 508 5" + event_file: snr.ev + initial_region: cir 505 508 5 + tolerance: 1.0000 + iterations: 1 + + events: 1120 + x,y\201physical\202: 504.43 509.65 + ra,dec\201j2000\202: 345.286480 58.874587 + final_region1: cir 504.43 509.65 5)RP( +Level 2 outputs results from intermediate calculations as well. + +)0 P(Ordinarily, region filtering is performed using analytic \201event\202 +filtering, i.e. that same style of filtering as is performed by +)BD(fundisp)ES( and )BD(funtable)ES(. Use the )BD(-i)ES( switch to specify image +filtering, i.e. the same style filtering as is performed by )BD(funcnts)ES(. +Thus, you can perform a quick calculation of counts in regions, using +either the analytic or image filtering method, by specifying the + )BD(-n 0)ES( and optional )BD(-i)ES( switches. These two method often +give different results because of how boundary events are processed: +) 5 46 PR( [sh] funcen snr.ev "cir 505 508 5" + 915 505.00 508.00 345.284038 58.870920 j2000 + + [sh] funcen -i snr.ev "cir 505 508 5" + 798 505.00 508.00 345.284038 58.870920 j2000)RP( +See )0 58 1 A(Region Boundaries)58 0 TN TL()Ec /AF f D( for more information +about how boundaries are calculated using these two methods. + + + + +)0 2 8 H(funcnts)WB 71 Sn()WB 5 Sn( - count photons in specified regions, with bkgd subtraction)EA()EH( + + +)BD() 1 86 PR(funcnts [switches] [source_region] [bkgd_file] [bkgd_region|bkgd_value])RP()ES( + + +)0 P() 16 79 PR( -e "source_exposure[;bkgd_exposure]" + # source \201bkgd\202 FITS exposure image using matching files + -w "source_exposure[;bkgd_exposure]" + # source \201bkgd\202 FITS exposure image using WCS transform + -t "source_timecorr[;bkgd_timecorr]" + # source \201bkgd\202 time correction value or header parameter name + -g # output using nice g format + -G # output using %.14g format \201maximum precision\202 + -i "[column;]int1;int2..." # column-based intervals + -m # match individual source and bkgd regions + -p # output in pixels, even if wcs is present + -r # output inner/outer radii \201and angles\202 for annuli \201and pandas\202 + -s # output summed values + -v "scol[;bcol]" # src and bkgd value columns for tables + -T # output in starbase/rdb format + -z # output regions with zero area)ES()RP( + + +)0 P()BD(funcnts)ES( counts photons in the specified source regions and +reports the results for each region. Regions are specified using the +)0 54 1 A(Spatial Region Filtering)54 0 TN TL()Ec /AF f D( mechanism. +Photons are also counted in the specified bkgd regions applied to the +same data file or a different data file. \201Alternatively, a constant +background value in counts/pixel**2 can be specified.\202 The bkgd regions +are either paired one-to-one with source regions or pooled and +normalized by area, and then subtracted from the source counts in each +region. Displayed results include the bkgd-subtracted counts in each +region, as well as the error on the counts, the area in +each region, and the surface brightness \201cnts/area**2\202 calculated for +each region. + +)0 P(The first argument to the program specifies the FITS input image, array, or +raw event file to process. If "stdin" is specified, data are read from +the standard input. Use )0 42 1 A(Funtools Bracket +Notation)42 0 TN TL()Ec /AF f D( to specify FITS extensions, image sections, and filters. + +)0 P(The optional second argument is the source region descriptor. If no +region is specified, the entire field is used. + +)0 P(The background arguments can take one of two forms, depending on +whether a separate background file is specified. If the source +file is to be used for background as well, the third argument can be +either the background region, or a constant value denoting background +cnts/pixel. Alternatively, the third argument can be a background +data file, in which case the fourth argument is the background region. +If no third argument is specified, a constant value of 0 is used +\201i.e., no background\202. + +)0 P(In summary, the following command arguments are valid: +) 5 77 PR( [sh] funcnts sfile # counts in source file + [sh] funcnts sfile sregion # counts in source region + [sh] funcnts sfile sregion bregion # bkgd reg. is from source file + [sh] funcnts sfile sregion bvalue # bkgd reg. is constant + [sh] funcnts sfile sregion bfile bregion # bkgd reg. is from separate file)RP( + +)0 P(NB: unlike other Funtools programs, source and background regions are +specified as separate arguments on the command line, rather than being +placed inside brackets as part of the source and background filenames. +This is because regions in funcnts are not simply used as data +filters, but also are used to calculate areas, exposure, etc. If you +put the source region inside the brackets \201i.e. use it simply as a +filter\202 rather than specifying it as argument two, the program still +will only count photons that pass the region filter. However, the area +calculation will be performed on the whole field, since field\201\202 is the +default source region. This rarely is the desired behavior. On the +other hand, with FITS binary tables, it often is useful to put a column +filter in the filename brackets, so that only events matching the +column filter are counted inside the region. + +)0 P(For example, to extract the counts within a radius of 22 pixels from the +center of the FITS binary table snr.ev and subtract the background determined +from the same image within an annulus of radii 50-100 pixels: +) 33 82 PR( [sh] funcnts snr.ev "circle\201502,512,22\202" "annulus\201502,512,50,100\202" + # source + # data file: snr.ev + # degrees/pix: 0.00222222 + # background + # data file: snr.ev + # column units + # area: arcsec**2 + # surf_bri: cnts/arcsec**2 + # surf_err: cnts/arcsec**2 + + # background-subtracted results + reg net_counts error background berror area surf_bri surf_err + ---- ------------ --------- ------------ --------- --------- --------- --------- + 1 3826.403 66.465 555.597 5.972 96831.98 0.040 0.001 + + + # the following source and background components were used: + source region\201s\202 + ---------------- + circle\201502,512,22\202 + + reg counts pixels + ---- ------------ --------- + 1 4382.000 1513 + + background region\201s\202 + -------------------- + annulus\201502,512,50,100\202 + + reg counts pixels)WR( + ---- ------------ --------- + all 8656.000 23572)RP( +The area units for the output columns labeled "area", "surf_bri" +\201surface brightness\202 and "surf_err" will be given either in +arc-seconds \201if appropriate WCS information is in the data file +header\201s\202\202 or in pixels. If the data file has WCS info, but you do not +want arc-second units, use the )BD(-p)ES( switch to force output in +pixels. Also, regions having zero area are not normally included in +the primary \201background-subtracted\202 table, but are included in the +secondary source and bkgd tables. If you want these regions to be +included in the primary table, use the )BD(-z)ES( switch. + +)0 P(Note that a simple sed command will extract the background-subtracted results +for further analysis: +) 6 79 PR( [sh] cat funcnts.sed + 1,/---- .*/d + /^$/,$d + + [sh] sed -f funcnts.sed funcnts.out + 1 3826.403 66.465 555.597 5.972 96831.98 0.040 0.001)RP( + +)0 P(If separate source and background files are specified, )BD(funcnts)ES( will +attempt to normalize the the background area so that the background +pixel size is the same as the source pixel size. This normalization +can only take place if the appropriate WCS information is contained in +both files \201e.g. degrees/pixel values in CDELT\202. If either +file does not contain the requisite size information, the normalization +is not performed. In this case, it is the user's responsibility to +ensure that the pixel sizes are the same for the two files. + +)0 P(Normally, if more than one background region is specified, )BD(funcnts)ES( +will combine them all into a single region and use this background +region to produce the background-subtracted results for each source +region. The )BD(-m)ES( \201match multiple backgrounds\202 switch tells +)BD(funcnts)ES( to make a one to one correspondence between background and +source regions, instead of using a single combined background region. +For example, the default case is to combine 2 background +regions into a single region and then apply that region to each of the +source regions: + +) 35 82 PR( [sh] funcnts snr.ev "annulus\201502,512,0,22,n=2\202" "annulus\201502,512,50,100,n=2\202" + # source + # data file: snr.ev + # degrees/pix: 0.00222222 + # background + # data file: snr.ev + # column units + # area: arcsec**2 + # surf_bri: cnts/arcsec**2 + # surf_err: cnts/arcsec**2 + + # background-subtracted results + reg net_counts error background berror area surf_bri surf_err + ---- ------------ --------- ------------ --------- --------- --------- --------- + 1 3101.029 56.922 136.971 1.472 23872.00 0.130 0.002 + 2 725.375 34.121 418.625 4.500 72959.99 0.010 0.000 + + + # the following source and background components were used: + source region\201s\202 + ---------------- + annulus\201502,512,0,22,n=2\202 + + reg counts pixels + ---- ------------ --------- + 1 3238.000 373 + 2 1144.000 1140 + + background region\201s\202 + -------------------- + annulus\201502,512,50,100,n=2\202)WR( + + reg counts pixels + ---- ------------ --------- + all 8656.000 23572)RP( +Note that the basic region filter rule "each photon is counted once +and no photon is counted more than once" still applies when using The +)BD(-m)ES( to match background regions. That is, if two background +regions overlap, the overlapping pixels will be counted in only one of +them. In a worst-case scenario, if two background regions are the same +region, the first will get all the counts and area and the second +will get none. + +)0 P(Using the )BD(-m)ES( switch causes )BD(funcnts)ES( to use each of the two +background regions independently with each of the two source regions: + +) 36 82 PR( [sh] funcnts -m snr.ev "annulus\201502,512,0,22,n=2\202" "ann\201502,512,50,100,n=2\202" + # source + # data file: snr.ev + # degrees/pix: 0.00222222 + # background + # data file: snr.ev + # column units + # area: arcsec**2 + # surf_bri: cnts/arcsec**2 + # surf_err: cnts/arcsec**2 + + # background-subtracted results + reg net_counts error background berror area surf_bri surf_err + ---- ------------ --------- ------------ --------- --------- --------- --------- + 1 3087.015 56.954 150.985 2.395 23872.00 0.129 0.002 + 2 755.959 34.295 388.041 5.672 72959.99 0.010 0.000 + + + # the following source and background components were used: + source region\201s\202 + ---------------- + annulus\201502,512,0,22,n=2\202 + + reg counts pixels + ---- ------------ --------- + 1 3238.000 373 + 2 1144.000 1140 + + background region\201s\202 + -------------------- + ann\201502,512,50,100,n=2\202)WR( + + reg counts pixels + ---- ------------ --------- + 1 3975.000 9820 + 2 4681.000 13752)RP( + +)0 P(Note that most floating point quantities are displayed using "f" +format. You can change this to "g" format using the )BD(-g)ES( +switch. This can be useful when the counts in each pixel is very +small or very large. If you want maximum precision and don't care +about the columns lining up nicely, use )BD(-G)ES(, which outputs +all floating values as %.14g. + +)0 P(When counting photons using the annulus and panda \201pie and annuli\202 +shapes, it often is useful to have access to the radii \201and panda +angles\202 for each separate region. The )BD(-r)ES( switch will add radii +and angle columns to the output table: + +) 37 122 PR( [sh] funcnts -r snr.ev "annulus\201502,512,0,22,n=2\202" "ann\201502,512,50,100,n=2\202" + # source + # data file: snr.ev + # degrees/pix: 0.00222222 + # background + # data file: snr.ev + # column units + # area: arcsec**2 + # surf_bri: cnts/arcsec**2 + # surf_err: cnts/arcsec**2 + # radii: arcsecs + # angles: degrees + + # background-subtracted results + reg net_counts error background berror area surf_bri surf_err radius1 radius2 angle1 angle2 + ---- ------------ --------- ------------ --------- --------- --------- --------- --------- --------- --------- --------- + 1 3101.029 56.922 136.971 1.472 23872.00 0.130 0.002 0.00 88.00 NA NA + 2 725.375 34.121 418.625 4.500 72959.99 0.010 0.000 88.00 176.00 NA NA + + + # the following source and background components were used: + source region\201s\202 + ---------------- + annulus\201502,512,0,22,n=2\202 + + reg counts pixels + ---- ------------ --------- + 1 3238.000 373 + 2 1144.000 1140 + + background region\201s\202)WR( + -------------------- + ann\201502,512,50,100,n=2\202 + + reg counts pixels + ---- ------------ --------- + all 8656.000 23572)RP( + +)0 P(Radii are given in units of pixels or arc-seconds \201depending on the +presence of WCS info\202, while the angle values \201when present\202 are in +degrees. These columns can be used to plot radial profiles. For +example, the script )BD(funcnts.plot)ES( in the funtools +distribution\202 will plot a radial profile using gnuplot \201version 3.7 or +above\202. A simplified version of this script is shown below: + +) 74 79 PR( #!/bin/sh + + if [ x"$1" = xgnuplot ]; then + if [ x`which gnuplot 2>/dev/null` = x ]; then + echo "ERROR: gnuplot not available" + exit 1 + fi + awk ' + BEGIN{HEADER=1; DATA=0; FILES=""; XLABEL="unknown"; YLABEL="unknown"} + HEADER==1{ + if\201 $1 == "#" && $2 == "data" && $3 == "file:" \202{ + if\201 FILES != "" \202 FILES = FILES "," + FILES = FILES $4 + } + else if\201 $1 == "#" && $2 == "radii:" \202{ + XLABEL = $3 + } + else if\201 $1 == "#" && $2 == "surf_bri:" \202{ + YLABEL = $3 + } + else if\201 $1 == "----" \202{ + printf "set nokey; set title \200"funcnts\201%s\202\200"\200n", FILES + printf "set xlabel \200" radius\201%s\202\200"\200n", XLABEL + printf "set ylabel \200"surf_bri\201%s\202\200"\200n", YLABEL + print "plot \200"-\200" using 3:4:6:7:8 with boxerrorbars" + HEADER = 0 + DATA = 1 + next + } + } + DATA==1{)WR( + if\201 NF == 12 \202{ + print $9, $10, \201$9+$10\202/2, $7, $8, $7-$8, $7+$8, $10-$9 + } + else{ + exit + } + } + ' | gnuplot -persist - 1>/dev/null 2>&1 + + elif [ x"$1" = xds9 ]; then + awk ' + BEGIN{HEADER=1; DATA=0; XLABEL="unknown"; YLABEL="unknown"} + HEADER==1{ + if\201 $1 == "#" && $2 == "data" && $3 == "file:" \202{ + if\201 FILES != "" \202 FILES = FILES "," + FILES = FILES $4 + } + else if\201 $1 == "#" && $2 == "radii:" \202{ + XLABEL = $3 + } + else if\201 $1 == "#" && $2 == "surf_bri:" \202{ + YLABEL = $3 + } + else if\201 $1 == "----" \202{ + printf "funcnts\201%s\202 radius\201%s\202 surf_bri\201%s\202 3\200n", FILES, XLABEL, YLABEL + HEADER = 0 + DATA = 1 + next + } + })WR( + DATA==1{ + if\201 NF == 12 \202{ + print $9, $7, $8 + } + else{ + exit + } + } + ' + else + echo "funcnts -r ... | funcnts.plot [ds9|gnuplot]" + exit 1 + fi)RP( + +Thus, to run )BD(funcnts)ES( and plot the results using gnuplot \201version 3.7 +or above\202, use: +) 1 75 PR( funcnts -r snr.ev "annulus\201502,512,0,50,n=5\202" ... | funcnts.plot gnuplot)RP( + +)0 P(The )BD(-s)ES( \201sum\202 switch causes )BD(funcnts)ES( to produce an +additional table of summed \201integrated\202 background subtracted values, +along with the default table of individual values: + +) 51 82 PR( [sh] funcnts -s snr.ev "annulus\201502,512,0,50,n=5\202" "annulus\201502,512,50,100\202" + # source + # data file: snr.ev + # degrees/pix: 0.00222222 + # background + # data file: snr.ev + # column units + # area: arcsec**2 + # surf_bri: cnts/arcsec**2 + # surf_err: cnts/arcsec**2 + + # summed background-subtracted results + upto net_counts error background berror area surf_bri surf_err + ---- ------------ --------- ------------ --------- --------- --------- --------- + 1 2880.999 54.722 112.001 1.204 19520.00 0.148 0.003 + 2 3776.817 65.254 457.183 4.914 79679.98 0.047 0.001 + 3 4025.492 71.972 1031.508 11.087 179775.96 0.022 0.000 + 4 4185.149 80.109 1840.851 19.786 320831.94 0.013 0.000 + 5 4415.540 90.790 2873.460 30.885 500799.90 0.009 0.000 + + + # background-subtracted results + reg counts error background berror area surf_bri surf_err + ---- ------------ --------- ------------ --------- --------- --------- --------- + 1 2880.999 54.722 112.001 1.204 19520.00 0.148 0.003 + 2 895.818 35.423 345.182 3.710 60159.99 0.015 0.001 + 3 248.675 29.345 574.325 6.173 100095.98 0.002 0.000 + 4 159.657 32.321 809.343 8.699 141055.97 0.001 0.000 + 5 230.390 37.231 1032.610 11.099 179967.96 0.001 0.000 + + )WR( + # the following source and background components were used: + source region\201s\202 + ---------------- + annulus\201502,512,0,50,n=5\202 + + reg counts pixels sumcnts sumpix + ---- ------------ --------- ------------ --------- + 1 2993.000 305 2993.000 305 + 2 1241.000 940 4234.000 1245 + 3 823.000 1564 5057.000 2809 + 4 969.000 2204 6026.000 5013 + 5 1263.000 2812 7289.000 7825 + + background region\201s\202 + -------------------- + annulus\201502,512,50,100\202 + + reg counts pixels + ---- ------------ --------- + all 8656.000 23572)RP( + +)0 P(The )BD(-t)ES( and )BD(-e)ES( switches can be used to apply timing and +exposure corrections, respectively, to the data. Please note that +these corrections are meant to be used qualitatively, since +application of more accurate correction factors is a complex and +mission-dependent effort. The algorithm for applying these simple +corrections is as follows: +) 9 63 PR( C = Raw Counts in Source Region + Ac= Area of Source Region + Tc= Exposure time for Source Data + Ec= Average exposure in Source Region, from exposure map + + B= Raw Counts in Background Region + Ab= Area of Background Region + Tb= \201Exposure\202 time for Background Data + Eb= Average exposure in Background Region, from exposure map)RP( +Then, Net Counts in Source region is +) 1 37 PR( Net= C - B * \201Ac*Tc*Ec\202/\201Ab*Tb*Eb\202)RP( +with the standard propagation of errors for the Error on Net. +The net rate would then be +) 1 27 PR( Net Rate = Net/\201Ac*Tc*Ec\202)RP( +The average exposure in each region is calculated by summing up the +pixel values in the exposure map for the given region and then +dividing by the number of pixels in that region. Exposure maps often +are generated at a block factor > 1 \201e.g., block 4 means that each +exposure pixel contains 4x4 pixels at full resolution\202 and +)BD(funcnts)ES( will deal with the blocking automatically. Using the +)BD(-e)ES( switch, you can supply both source and background exposure +files \201separated by ";"\202, if you have separate source and background +data files. If you do not supply a background exposure file to go with +a separate background data file, )BD(funcnts)ES( assumes that exposure +already has been applied to the background data file. In addition, it +assumes that the error on the pixels in the background data file is +zero. + +)0 P(NB: The )BD(-e)ES( switch assumes that the exposure map overlays the +image file )BD(exactly)ES(, except for the block factor. Each pixel in +the image is scaled by the block factor to access the corresponding +pixel in the exposure map. If your exposure map does not line up +exactly with the image, )BD(do not use)ES( the )BD(-e)ES( exposure +correction. In this case, it still is possible to perform exposure +correction )BD(if)ES( both the image and the exposure map have valid +WCS information: use the )BD(-w)ES( switch so that the transformation +from image pixel to exposure pixel uses the WCS information. That is, +each pixel in the image region will be transformed first from image +coordinates to sky coordinates, then from sky coordinates to exposure +coordinates. Please note that using )BD(-w)ES( can increase the time +required to process the exposure correction considerably. + +)0 P(A time correction can be applied to both source and +background data using the )BD(-t)ES( switch. The value for the correction can +either be a numeric constant or the name of a header parameter in +the source \201or background\202 file: +) 2 74 PR( [sh] funcnts -t 23.4 ... # number for source + [sh] funcnts -t "LIVETIME;23.4" ... # param for source, numeric for bkgd)RP( +When a time correction is specified, it is applied to the net counts +as well \201see algorithm above\202, so that the units of surface brightness +become cnts/area**2/sec. + +)0 P(The )BD(-i)ES( \201interval\202 switch is used to run )BD(funcnts)ES( on multiple +column-based intervals with only a single pass through the data. It is +equivalent to running )BD(funcnts)ES( several times with a different column +filter added to the source and background data each time. For each +interval, the full )BD(funcnts)ES( output is generated, with a linefeed +character \201^L\202 inserted between each run. In addition, the output for +each interval will contain the interval specification in its header. +Intervals are very useful for generating X-ray hardness ratios +efficiently. Of course, they are only supported when the input data +are contained in a table. + +)0 P(Two formats are supported for interval specification. The most general +format is semi-colon-delimited list of filters to be used as intervals: +) 1 73 PR( funcnts -i "pha=1:5;pha=6:10;pha=11:15" snr.ev "circle\201502,512,22\202" ...)RP( +Conceptually, this will be equivalent to running )BD(funcnts)ES( three times: +) 3 50 PR( funcnts snr.ev'[pha=1:5]' "circle\201502,512,22\202" + funcnts snr.ev'[pha=6:10]' "circle\201502,512,22\202" + funcnts snr.ev'[pha=11:15]' "circle\201502,512,22\202")RP( +However, using the )BD(-i)ES( switch will require only one pass through +the data. + +)0 P(Note that complex filters can be used to specify intervals: +) 1 64 PR( funcnts -i "pha=1:5&)SY(\160)ES(=4;pha=6:10&)SY(\160)ES(=5;pha=11:15&)SY(\160)ES(=6" snr.ev ...)RP( +The program simply runs the data through each filter in turn and generates +three )BD(funcnts)ES( outputs, separated by the line-feed character. + +)0 P(In fact, although the intent is to support intervals for hardness ratios, +the specified filters do not have to be intervals at all. Nor does one +"interval" filter have to be related to another. For example: +) 1 75 PR( funcnts -i "pha=1:5;pi=6:10;energy=11:15" snr.ev "circle\201502,512,22\202" ...)RP( +is equivalent to running )BD(funcnts)ES( three times with unrelated filter +specifications. + +)0 P(A second interval format is supported for the simple case in which a +single column is used to specify multiple homogeneous intervals for +that column. In this format, a column name is specified first, +followed by intervals: +) 1 65 PR( funcnts -i "pha;1:5;6:10;11:15" snr.ev "circle\201502,512,22\202" ...)RP( +This is equivalent to the first example, but requires less typing. The +)BD(funcnts)ES( program will simply prepend "pha=" before each of the specified +intervals. \201Note that this format does not contain the "=" character in +the column argument.\202 + +)0 P(Ordinarily, when )BD(funcnts)ES( is run on a FITS binary table \201or a +raw event table\202, one integral count is accumulated for each row +\201event\202 contained within a given region. The )BD(-v "scol[;bcol]")ES( +\201value column\202 switch will accumulate counts using the value from the +specified column for the given event. If only a single column is +specified, it is used for both the source and background regions. Two +separate columns, separated by a semi-colon, can be specified for source +and background. The special token '$none' can be used to specify that +a value column is to be used for one but not the other. For example, +'pha;$none' will use the pha column for the source but use integral +counts for the background, while '$none;pha' will do the converse. +If the value column is of type logical, then the value used will be 1 +for T and 0 for F. Value columns are used, for example, to integrate +probabilities instead of integral counts. + +)0 P(If the )BD(-T)ES( \201rdb table\202 switch is used, the output will conform +to starbase/rdb data base format: tabs will be inserted between +columns rather than spaces and line-feed will be inserted between +tables. + +)0 P(Finally, note that )BD(funcnts)ES( is an image program, even though it +can be run directly on FITS binary tables. This means that image +filtering is applied to the rows in order to ensure that the same +results are obtained regardless of whether a table or the equivalent +binned image is used. Because of this, however, the number of counts +found using )BD(funcnts)ES( can differ from the number of events found +using row-filter programs such as )BD(fundisp)ES( or )BD(funtable)ES( +For more information about these difference, see the discussion of +)0 58 1 A(Region Boundaries)58 0 TN TL()Ec /AF f D(. + + + + +)0 2 9 H(funcone)WB 72 Sn()WB 6 Sn( - cone search of a binary table containing RA, Dec columns)EA()EH( + + +)BD() 1 81 PR(funcone [columns])RP()ES( + + +)0 P() 9 84 PR( -d deccol:[hdr] # Dec column name, units \201def: DEC:d\202 + -j # join columns from list file + -J # join columns from list file, output all rows + -l listfile # read centers and radii from a list + -L listfile # read centers and radii from a list, output list rows + -n # don't use cone limits as a filter + -r racol:[hdr] # RA column name, units \201def: RA:h\202 + -x # append RA_CEN, DEC_CEN, RAD_CEN, CONE_KEY cols + -X # append RA_CEN, DEC_CEN, RAD_CEN, CONE_KEY cols, output all rows)RP( + + +)0 P(Funcone performs a cone search on the RA and Dec columns of a FITS +binary table. The distance from the center RA, Dec position to the RA, +Dec in each row in the table is calculated. Rows whose distance is +less than the specified radius are output. + +)0 P(The first argument to the program specifies the FITS file, raw event +file, or raw array file. If "stdin" is specified, data are read from +the standard input. Use )0 42 1 A(Funtools Bracket +Notation)42 0 TN TL()Ec /AF f D( to specify FITS extensions, and filters. The second +argument is the output FITS file. If "stdout" is specified, the FITS +binary table is written to the standard output. + +)0 P( +The third and fourth required arguments are the RA and Dec center +position. By default, RA is specified in hours while Dec is specified +in degrees. You can change the units of either of these by appending +the character "d" \201degrees\202, "h" \201hours\202 or "r" \201radians\202. Sexagesimal +notation is supported, with colons or spaces separating hms and dms. +\201When using spaces, please ensure that the entire string is quoted.\202 + +)0 P(The fifth required argument is the radius of the cone search. By default, +the radius value is given in degrees. The units can be changed by appending +the character "d" \201degrees\202, "r" \201radians\202, "'" \201arc minutes\202 or +'"' \201arc seconds\202. + +)0 P(By default, all +columns of the input file are copied to the output file. Selected +columns can be output using an optional sixth argument in the form: +) 1 31 PR( "column1 column1 ... columnN")RP( +A seventh argument allows you to output selected columns from the list +file when )BD(-j)ES( switch is used. Note that the RA and Dec columns +used in the cone calculation must not be de-selected. + +)0 P(Also by default, the RA and Dec column names are named "RA" and "Dec", +and are given in units of hours and degrees respectively. You can +change both the name and the units using the -r [RA] and/or -d [Dec] +switches. Once again, one of "h", "d", or "r" is appended to the +column name to specify units but in this case, there must be a colon ":" +between the name and the unit specification. + +)0 P(If the )BD(-l [listfile])ES( switch is used, then one or more of the +center RA, center Dec, and radius can be taken from a list file \201which +can be a FITS table or an ASCII column text file\202. In this case, the +third \201center RA\202, fourth \201center Dec\202, and fifth \201radius\202 command +line arguments can either be a column name in the list file \201if that +parameter varies\202 or else a numeric value \201if that parameter is +static\202. When a column name is specified for the RA, Dec, or radius, +you can append a colon followed by "h", "d", or "r" to specify units +\201also ' and " for radius\202. The cone search algorithm is run once for +each row in the list, taking RA, Dec, and radius values from the +specified columns or from static numeric values specified on the +command line. + +)0 P(When using a list, all valid rows from each iteration are written to a +single output file. Use the )BD(-x)ES( switch to help delineate which +line of the list file was used to produce the given output row\201s\202. +This switch causes the values for the center RA, Dec, radius, and row +number to be appended to the output file, in columns called RA_CEN, +DEC_CEN, RAD_CEN and CONE_KEY, respectively. Alternatively, the +)BD(-j)ES( \201join\202 switch will append all columns from the list row to +the output row \201essentially a join of the list row and input row\202, +along with the CONE_KEY row number. These two switches are mutually +exclusive. + +)0 P(The )BD(-X)ES( and )BD(-J)ES( switches write out the same data as their +lower case counterparts for each row satisfying a cone search. In +addition, these switches also write out rows from the event file that +do not satisfy any cone search. In such cases, that CONE_KEY column +will be given a value of -1 and the center and list position information +will be set to zero for the given row. Thus, all rows of the input +event file are guaranteed to be output, with rows satisfying at least +one cone search having additional search information. + +)0 P(The )BD(-L)ES( switch acts similarly to the )BD(-l)ES( switch in that it +takes centers from a list file. However, it also implicitly sets the +-j switch, so that output rows are the join of the input event row and +the center position row. In addition, this switch also writes out all +center position rows for which no event satisfies the cone search +criteria of that row. The CONE_KEY column will be given a value of -2 +for center rows that were not close to any data row and the event +columns will be zeroed out for such rows. In this way, all centers +rows are guaranteed to be output at least once. + +)0 P(If any of "all row" switches \201)BD(-X)ES(, )BD(-J)ES(, or )BD(-L)ES(\202 are +specified, then a new column named JSTAT is added to the output table. +The positive values in this column indicate the center position row number +\201starting from 1\202 in the list file that this data row successful matched +in a cone search. A value of -1 means that the data row did not match +any center position. A value of -2 means that the center position was +not matched by any data row. + +)0 P(Given a center position and radius, the cone search algorithm +calculates limit parameters for a box enclosing the specified cone, +and only tests rows whose positions values lie within those limits. +For small files, the overhead associated with this cone limit +filtering can cause the program to run more slowly than if all events +were tested. You can turn off cone limit filtering using the )BD(-n)ES( +switch to see if this speeds up the processing \201especially useful when +processing a large list of positions\202. + +)0 P(For example, the default cone search uses columns "RA" and "Dec" in hours +and degrees \201respectively\202 and RA position in hours, Dec and radius in degrees: +) 1 42 PR( funone in.fits out.fits 23.45 34.56 0.01)RP( +To specify the RA position in degrees: +) 1 44 PR( funcone in.fits out.fits 23.45d 34.56 0.01)RP( +To get RA and Dec from a list but use a static value for radius \201and +also write identifying info for each row in the list\202: +) 1 57 PR( funcone -x -l list.txt in.fits out.fits MYRA MYDec 0.01)RP( +User specified columns in degrees, RA position in hours \201sexagesimal +notation\202, Dec position in degrees \201sexagesimal notation\202 and radius +in arc minutes: +) 1 66 PR( funcone -r myRa:d -d myDec in.fits out.fits 12:30:15.5 30:12 15')RP( + + + + +)0 2 10 H(fundisp)WB 73 Sn()WB 7 Sn( - display data in a Funtools data file)EA()EH( + + +)BD() 1 62 PR(fundisp [-f format] [-l] [-n] [-T] [columns|bitpix=n])RP()ES( + + +)0 P() 5 68 PR( -f # format string for display + -l # display image as a list containing the columns X, Y, VAL + -n # don't output header + -F [c] # use specified character as column separator \201def: space\202 + -T # output in rdb/starbase format \201tab separators\202)RP( + + +)0 P()BD(fundisp)ES( displays the data in the specified +)0 42 1 A(FITS Extension)42 0 TN TL()Ec /AF f D( +and/or +)0 49 1 A(Image Section)49 0 TN TL()Ec /AF f D( +of a FITS file, or in a +)0 49 1 A(Section)49 0 TN TL()Ec /AF f D( +of a non-FITS array or raw event file. +)0 P(The first argument to the program specifies the FITS input image, array, or +raw event file to display. If "stdin" is specified, data are read from +the standard input. Use )0 42 1 A(Funtools Bracket +Notation)42 0 TN TL()Ec /AF f D( to specify FITS extensions, image sections, and filters. + +)0 P(If the data being displayed are columns \201either in a FITS binary table +or a raw event file\202, the individual rows are listed. Filters can be +added using bracket notation. Thus: +) 13 75 PR( [sh] fundisp "test.ev[time-\201int\202time>.15]" + X Y PHA PI TIME DX DY + ------- ------- ------- --------- ---------------- ---------- ---------- + 10 8 10 8 17.1600 8.50 10.50 + 9 9 9 9 17.1600 9.50 9.50 + 10 9 10 9 18.1600 9.50 10.50 + 10 9 10 9 18.1700 9.50 10.50 + 8 10 8 10 17.1600 10.50 8.50 + 9 10 9 10 18.1600 10.50 9.50 + 9 10 9 10 18.1700 10.50 9.50 + 10 10 10 10 19.1600 10.50 10.50 + 10 10 10 10 19.1700 10.50 10.50 + 10 10 10 10 19.1800 10.50 10.50)RP( +[NB: The FITS binary table test file test.ev, as well as the FITS +image test.fits, are contained in the funtools funtest directory.] + +)0 P(When a table is being displayed using )BD(fundisp)ES(, a second optional +argument can be used to specify the columns to display. For example: +) 12 56 PR( [sh] fundisp "test.ev[time-\201int\202time>=.99]" "x y time" + X Y TIME + -------- -------- --------------------- + 5 -6 40.99000000 + 4 -5 59.99000000 + -1 0 154.99000000 + -2 1 168.99000000 + -3 2 183.99000000 + -4 3 199.99000000 + -5 4 216.99000000 + -6 5 234.99000000 + -7 6 253.99000000)RP( + +)0 P(The special column )BD($REGION)ES( can be specified to display the +region id of each row: +) 12 89 PR( [sh $] fundisp "test.ev[time-\201int\202time>=.99&&annulus\2010 0 0 10 n=3\202]" 'x y time $REGION' + X Y TIME REGION + -------- -------- --------------------- ---------- + 5 -6 40.99000000 3 + 4 -5 59.99000000 2 + -1 0 154.99000000 1 + -2 1 168.99000000 1 + -3 2 183.99000000 2 + -4 3 199.99000000 2 + -5 4 216.99000000 2 + -6 5 234.99000000 3 + -7 6 253.99000000 3)RP( +)0 P(Here only rows with the proper fractional time and whose position also is +within one of the three annuli are displayed. +)0 P(Columns can be excluded from display using a minus sign before the +column: +) 12 64 PR( [sh $] fundisp "test.ev[time-\201int\202time>=.99]" "-time" + X Y PHA PI DX DY + -------- -------- -------- ---------- ----------- ----------- + 5 -6 5 -6 5.50 -6.50 + 4 -5 4 -5 4.50 -5.50 + -1 0 -1 0 -1.50 0.50 + -2 1 -2 1 -2.50 1.50 + -3 2 -3 2 -3.50 2.50 + -4 3 -4 3 -4.50 3.50 + -5 4 -5 4 -5.50 4.50 + -6 5 -6 5 -6.50 5.50 + -7 6 -7 6 -7.50 6.50)RP( +All columns except the time column are displayed. +)0 P(The special column )BD($N)ES( can be specified to display the +ordinal value of each row. Thus, continuing the previous example: +) 12 74 PR( fundisp "test.ev[time-\201int\202time>=.99]" '-time $n' + X Y PHA PI DX DY N + ------- -------- -------- ---------- ----------- ----------- ---------- + 5 -6 5 -6 5.50 -6.50 337 + 4 -5 4 -5 4.50 -5.50 356 + -1 0 -1 0 -1.50 0.50 451 + -2 1 -2 1 -2.50 1.50 465 + -3 2 -3 2 -3.50 2.50 480 + -4 3 -4 3 -4.50 3.50 496 + -5 4 -5 4 -5.50 4.50 513 + -6 5 -6 5 -6.50 5.50 531 + -7 6 -7 6 -7.50 6.50 550)RP( +Note that the column specification is enclosed in single quotes to protect +'$n' from begin expanded by the shell. + +)0 P(In general, the rules for activating and de-activating columns are: +)UL()-1 LI( If only exclude columns are specified, then all columns but +the exclude columns will be activated. +)-1 LI( If only include columns are specified, then only the specified columns +are activated. +)-1 LI( If a mixture of include and exclude columns are specified, then +all but the exclude columns will be active; this last case +is ambiguous and the rule is arbitrary.)LU( +In addition to specifying columns names explicitly, the special +symbols )BD(+)ES( and )BD(-)ES( can be used to activate and +de-activate )BD(all)ES( columns. This is useful if you want to +activate the $REGION column along with all other columns. According +to the rules, the syntax "$REGION" only activates the region column +and de-activates the rest. Use "+ $REGION" to activate all +columns as well as the region column. + +)0 P(If the data being displayed are image data \201either in a FITS primary +image, a FITS image extension, or an array file\202, an mxn pixel display +is produced, where m and n are the dimensions of the image. By +default, pixel values are displayed using the same data type as in the +file. However, for integer data where the BSCALE and BZERO header parameters +are present, the data is displayed as floats. In either case, the +display data type can be overridden using an optional second argument +of the form: +) 1 10 PR( bitpix=n)RP( +where n is 8,16,32,-32,-64, for unsigned char, short, int, float and double, +respectively. + +)0 P(Of course, running )BD(fundisp)ES( on anything but the smallest image +usually results in a display whose size makes it unreadable. +Therefore, one can uses bracket notation \201see below\202 +to apply section and/or blocking to the image before generating a +display. For example: +) 9 66 PR( [sh] fundisp "test.fits[2:6,2:7]" bitpix=-32 + 2 3 4 5 6 + ---------- ---------- ---------- ---------- ---------- + 2: 3.00 4.00 5.00 6.00 7.00 + 3: 4.00 5.00 6.00 7.00 8.00 + 4: 5.00 6.00 7.00 8.00 9.00 + 5: 6.00 7.00 8.00 9.00 10.00 + 6: 7.00 8.00 9.00 10.00 11.00 + 7: 8.00 9.00 10.00 11.00 12.00)RP( + +)0 P(Note that is is possible to display a FITS binary table as an image +simply by passing the table through )BD(funimage)ES( first: +) 9 68 PR( [sh] ./funimage test.ev stdout | fundisp "stdin[2:6,2:7]" bitpix=8 + 2 3 4 5 6 + ------- ------- ------- ------- ------- + 2: 3 4 5 6 7 + 3: 4 5 6 7 8 + 4: 5 6 7 8 9 + 5: 6 7 8 9 10 + 6: 7 8 9 10 11 + 7: 8 9 10 11 12)RP( + +If the )BD(-l)ES( \201list\202 switch is used, then an image is displayed as a +list containing the columns: X, Y, VAL. For example: +) 33 45 PR( fundisp -l "test1.fits[2:6,2:7]" bitpix=-32 + X Y VAL + ---------- ---------- ----------- + 2 2 6.00 + 3 2 1.00 + 4 2 1.00 + 5 2 1.00 + 6 2 1.00 + 2 3 1.00 + 3 3 5.00 + 4 3 1.00 + 5 3 1.00 + 6 3 1.00 + 2 4 1.00 + 3 4 1.00 + 4 4 4.00 + 5 4 1.00 + 6 4 1.00 + 2 5 1.00 + 3 5 1.00 + 4 5 1.00 + 5 5 3.00 + 6 5 1.00 + 2 6 1.00 + 3 6 1.00 + 4 6 1.00 + 5 6 1.00 + 6 6 2.00 + 2 7 1.00 + 3 7 1.00 + 4 7 1.00)WR( + 5 7 1.00 + 6 7 1.00)RP( + +)0 P(If the )BD(-n)ES( \201nohead\202 switch is used, then no header is output for +tables. This is useful, for example, when fundisp output is being +directed into gnuplot. + +)0 P(The )BD(fundisp)ES( program uses a default set of display formats: +) 10 33 PR( datatype TFORM format + -------- ----- -------- + double D "%21.8f" + float E "%11.2f" + int J "%10d" + short I "%8d" + byte B "%6d" + string A "%12.12s" + bits X "%8x" + logical L "%1x")RP( +Thus, the default display of 1 double and 2 shorts gives: +) 7 42 PR( [sh] fundisp snr.ev "time x y" + + TIME X Y + --------------------- -------- -------- + 79494546.56818075 546 201 + 79488769.94469175 548 201 + ...)RP( +You can change the display format for individual columns or for all +columns of a given data types by means of the -f switch. The format +string that accompanies -f is a space-delimited list of keyword=format +values. The keyword values can either be column names \201in which case +the associated format pertains only to that column\202 or FITS table +TFORM specifiers \201in which case the format pertains to all columns +having that data type\202. For example, you can change the double and +short formats for all columns like this: +) 7 53 PR( [sh] fundisp -f "D=%22.11f I=%3d" snr.ev "time x y" + + TIME X Y + ---------------------- --- --- + 79494546.56818075478 546 201 + 79488769.94469174743 548 201 + ...)RP( + +)0 P(Alternatively, you can change the format of the time and x columns like this: +) 7 56 PR( [sh] fundisp -f "time=%22.11f x=%3d" snr.ev "time x y" + + TIME X Y + ---------------------- --- -------- + 79494546.56818075478 546 201 + 79488769.94469174743 548 201 + ...)RP( +Note that there is a potential conflict if a column has the same name +as one of the TFORM specifiers. In the examples above, the the "X" +column in the table has the same name as the X \201bit\202 datatype. To +resolve this conflict, the format string is processed such that +TFORM datatype specifiers are checked for first, using a +case-sensitive comparison. If the specified format value is not an +upper case TFORM value, then a case-insensitive check is made on the +column name. This means that, in the examples above, "X=%3d" will refer +to the X \201bit\202 datatype, while "x=%3d" will refer to the X column: +) 15 38 PR( [sh] fundisp -f "X=%3d" snr.ev "x y" + + X Y + -------- -------- + 546 201 + 548 201 + ... + + [sh] fundisp -f "x=%3d" snr.ev "x y" + + X Y + --- -------- + 546 201 + 548 201 + ...)RP( +As a rule, therefore, it is best always to specify the column name in +lower case and TFORM data types in upper case. + +)0 P(The )BD(-f [format])ES( will change the format for a single execution +of fundisp. You also can use the )BD(FUN_FORMAT)ES( envronment variable +to change the format for all invocations of fundisp. The format of this +environment variable's value is identical to that used with +the )BD(-f)ES( switch. This global value can be overridden in +individual cases by use of the )BD(-f [format])ES( switch. + +)0 P(Caveats: Please also note that it is the user's responsibility to +match the format specifier to the column data type correctly. Also +note that, in order to maintain visual alignment between names and +columns, the column name will be truncated \201on the left\202 if the +format width is less than the length of the name. However, truncation +is not performed if the output is in RDB format \201using the -T switch\202. + +)0 P([An older-style format string is supported but deprecated. It +consists of space-delimited C format statements for all data types, +specified in the following order: +) 1 40 PR( double float int short byte string bit.)RP( +This order of the list is based on the assumption that people generally +will want to change the float formats. +)0 P(If "-" is entered instead of a format statement for a given data type, the +default format is used. Also, the format string can be terminated without +specifying all formats, and defaults will be used for the rest of the +list. Note that you must supply a minimum field width, i.e., "%6d" and +"%-6d" are legal, "%d" is not legal. + +By using -f [format], you can change the double and short formats like this: +) 7 51 PR( [sh] fundisp -f "22.11f - - 3d" snr.ev "time x y" + + TIME X Y + ---------------------- --- --- + 79494546.56818075478 546 201 + 79488769.94469174743 548 201 + ...)RP( +NB: This format is deprecated and will be removed in a future release.] + +)0 P(The )BD(-F[c])ES( switch can be used to specify a \201single-character\202 +column separator \201where the default is a space\202. Note that column +formatting will almost certainly also add spaces to pad individual +columns to the required width. These can be removed with a program +such as sed, at the cost of generating unaligned columns. For example: +) 26 117 PR(fundisp -F',' snr.ev'[cir 512 512 .1]' + X, Y, PHA, PI, TIME, DX, DY +--------,--------,--------,--------,---------------------,--------,-------- + 512, 512, 6, 7, 79493997.45854475, 578, 574 + 512, 512, 8, 9, 79494575.58943175, 579, 573 + 512, 512, 5, 6, 79493631.03866175, 578, 575 + 512, 512, 5, 5, 79493290.86521725, 578, 575 + 512, 512, 8, 9, 79493432.00990875, 579, 573 + +fundisp -F',' snr.ev'[cir 512 512 .1]' | sed 's/ *, */,/g' + X,Y,PHA,PI,TIME,DX,DY +--------,--------,--------,--------,---------------------,--------,-------- + 512,512,6,7,79493997.45854475,578,574 + 512,512,8,9,79494575.58943175,579,573 + 512,512,5,6,79493631.03866175,578,575 + 512,512,5,5,79493290.86521725,578,575 + 512,512,8,9,79493432.00990875,579,573 + +fundisp -f "x=%3d y=%3d pi=%1d pha=%1d time=%20.11f dx=%3d dy=%3d" -F',' snr.ev'[cir 512 512 .1]' | sed 's/ *, */,/g' + X,Y,A,I,TIME,DX,DY +---,---,-,-,--------------------,---,--- +512,512,6,7,79493997.45854474604,578,574 +512,512,8,9,79494575.58943174779,579,573 +512,512,5,6,79493631.03866174817,578,575 +512,512,5,5,79493290.86521725357,578,575 +512,512,8,9,79493432.00990875065,579,573)RP( + +)0 P(If the )BD(-T)ES( \201rdb table\202 switch is used, the output will conform +to starbase/rdb data base format: tabs will be inserted between +columns rather than spaces. This format is not available when +displaying image pixels \201except in conjunction with the )BD(-l)ES( +switch\202. + +)0 P(Finally, note that )BD(fundisp)ES( can be used to create column filters from +the auxiliary tables in a FITS file. For example, the following shell code +will generate a good-time interval \201GTI\202 filter for X-ray data files that +contain a standard GTI extension: +) 3 68 PR( #!/bin/sh + sed '1,/---- .*/d + /^$/,$d' | awk 'tot>0{printf "||"};{printf "time="$1":"$2; tot++}')RP( +If this script is placed in a file called "mkgti", it can be used in a +command such as: +) 1 46 PR( fundisp foo.fits"[GTI]" | mkgti > gti.filter)RP( +The resulting filter file can then be used in various funtools programs: +) 1 37 PR( funcnts foo.fits"[@gti.filter]" ...)RP( +to process only the events in the good-time intervals. + + + + +)0 2 11 H(funhead)WB 74 Sn()WB 8 Sn( - display a header in a Funtools file)EA()EH( + + +)BD() 1 50 PR(funhead [-a] [-s] [-t] [-L] [oname ename])RP()ES( + + +)0 P() 4 60 PR( -a # display all extension headers + -s # display 79 chars instead of 80 before the new-line + -t # prepend data type char to each line of output + -L # output in rdb/starbase list format)RP( + + +)0 P()BD(funhead)ES( displays the FITS header parameters in the specified +)0 42 1 A(FITS Extension)42 0 TN TL()Ec /AF f D(. +)0 P(The first argument to the program specifies the Funtools input file +to display. If "stdin" is specified, data are read from +the standard input. )0 42 1 A(Funtools Bracket +Notation)42 0 TN TL()Ec /AF f D( is used to specify particular FITS extension to process. +Normally, the full 80 characters of each header card is output, +followed by a new-line. + +)0 P(If the )BD(-a)ES( switch is specified, the header from each FITS +extensions in the file is displayed. Note, however, that the )BD(-a)ES( +switch does not work with FITS files input via stdin. We hope to +remove this restriction in a future release. + +)0 P(If the )BD(-s)ES( switch is specified, only 79 characters are output +before the new-line. This helps the display on 80 character terminals. + +)0 P(If the )BD(-t)ES( switch is specified, the data type of the parameter +is output as a one character prefix, followed by 77 characters of the +param. The parameter data types are defined as: FUN_PAR_UNKNOWN +\201'u'\202, FUN_PAR_COMMENT \201'c'\202, FUN_PAR_LOGICAL \201'l'\202, FUN_PAR_INTEGER +\201'i'\202, FUN_PAR_STRING \201's'\202, FUN_PAR_REAL \201'r'\202, FUN_PAR_COMPLEX \201'x'\202. + +)0 P(If the )BD(-L)ES( \201rdb table\202 switch is used, the output will conform +to starbase/rdb data base list format. + +)0 P(For example to display the EVENTS extension \201binary table\202: +) 17 65 PR( [sh] funhead "foo.fits[EVENTS]" + XTENSION= 'BINTABLE' / FITS 3D BINARY TABLE + BITPIX = 8 / Binary data + NAXIS = 2 / Table is a matrix + NAXIS1 = 20 / Width of table in bytes + NAXIS2 = 30760 / Number of entries in table + PCOUNT = 0 / Random parameter count + GCOUNT = 1 / Group count + TFIELDS = 7 / Number of fields in each row + EXTNAME = 'EVENTS ' / Table name + EXTVER = 1 / Version number of table + TFORM1 = '1I ' / Data type for field + TTYPE1 = 'X ' / Label for field + TUNIT1 = ' ' / Physical units for field + TFORM2 = '1I ' / Data type for field + etc. ... + END)RP( + +)0 P(To display the third header: +) 14 65 PR( [sh] funhead "foo.fits[3]" + XTENSION= 'BINTABLE' / FITS 3D BINARY TABLE + BITPIX = 8 / Binary data + NAXIS = 2 / Table is a matrix + NAXIS1 = 32 / Width of table in bytes + NAXIS2 = 40 / Number of entries in table + PCOUNT = 0 / Random parameter count + GCOUNT = 1 / Group count + TFIELDS = 7 / Number of fields in each row + EXTNAME = 'TGR ' / Table name + EXTVER = 1 / Version number of table + TFORM1 = '1D ' / Data type for field + etc. ... + END)RP( + +)0 P(To display the primary header \201i.e., extension 0\202: +) 8 59 PR( sh> funhead "coma.fits[0]" + SIMPLE = T /STANDARD FITS FORMAT + BITPIX = 16 /2-BYTE TWOS-COMPL INTEGER + NAXIS = 2 /NUMBER OF AXES + NAXIS1 = 800 / + NAXIS2 = 800 / + DATATYPE= 'INTEGER*2' /SHORT INTEGER + END)RP( + +)0 P(The funhead program also can edit \201i.e. add, delete, or modify\202 or +display individual headers parameters. Edit mode is signalled by the +presence of two additional command-line arguments: output file and +edit command file, in that order. Edit mode acts as a filter: the +output file will contain the entire input FITS file, including other +extensions. The edit command file can be "stdin", in which case edit +command are read from the standard input. + +)0 P(The edit command file contains parameter comments \201having '#' in the +first column\202 and delete and assignment\201modify or add\202 operations. A +delete operation is specified by preceding the parameter name with a +minus sign "-". A display operation \201very useful in interactive +sessions, i.e., where the edit commands are taken from stdin\202 is +specified by preceding the parameter name with a question mark "?". In +either case, a parameter value need not be specified. An assignment +operation is specified in the same two ways that a parameter is +specified in a text header \201but without the comment character that +precedes header params\202, i.e.: + +)UL()-1 LI( FITS-style comments have an equal sign "=" between the keyword and +value and an optional slash "/" to signify a comment. The strict FITS +rules on column positions are not enforced. + +)-1 LI( Free-form comments can have an optional colon separator between the +keyword and value. In the absence of quote, all tokens after the +keyword are part of the value, i.e. no comment is allowed.)LU( + +)0 P(For example, the following interactive session checks for the +existence of parameters, adds new parameters, modifies them, and +modifies and deletes existing parameters: +) 20 55 PR( sh$ ./funhead snr.ev foo.fits - + # look for FOO1 + ? FOO1 + WARNING: FOO1 not found + # add new foo1 + FOO1 = 100 + # add foo2 + FOO2 = 200 + # reset foo1 to a different value + FOO1 -1 + # delete foo2 + -FOO2 + # change existing value + EXTVER 2 + ? XS-SORT + XS-SORT = 'EOF ' / type of event sort + # delete existing value + -XS-SORT + # exit + ^D)RP( + +)0 P(See )0 47 1 A(Column-based Text Files)47 0 TN TL()Ec /AF f D( +for more information about header parameter format. + +)0 P( +)0 P( + + +)0 2 12 H(funhist)WB 75 Sn()WB 9 Sn( - create a 1D histogram of a column \201from a FITS binary table or raw event file\202 or an image)EA()EH( + + +)BD() 1 51 PR(funhist [-n|-w|-T] [column] [[lo:hi:]bins])RP()ES( + + +)0 P() 3 61 PR( -n # normalize bin value by the width of each bin + -w # specify bin width instead of number of bins in arg3 + -T # output in rdb/starbase format \201tab separators\202)RP( + + +)0 P()BD(funhist)ES( creates a one-dimensional histogram from the specified +columns of a )0 42 1 A(FITS Extension)42 0 TN TL()Ec /AF f D( +binary table of a FITS file \201or from a non-FITS raw event file\202, or +from a FITS image or array, and writes that histogram as an ASCII +table. Alternatively, the program can perform a 1D projection of one +of the image axes. + +)0 P(The first argument to the program is required, and specifies the +Funtools file: FITS table or image, raw event file, or array. If +"stdin" is specified, data are read from the standard input. Use +)0 42 1 A(Funtools Bracket Notation)42 0 TN TL()Ec /AF f D( to specify FITS +extensions, and filters. + +)0 P(For a table, the second argument also is required. It specifies the +column to use in generating the histogram. If the data file is of +type image \201or array\202, the column is optional: if "x" \201or "X"\202, "y" +\201or "Y"\202 is specified, then a projection is performed over the x +\201dim1\202 or y \201dim2\202 axes, respectively. \201That is, this projection will +give the same results as a histogram performed on a table containing +the equivalent x,y event rows.\202 If no column name is specified or +"xy" \201or "XY"\202 is specified for the image, then a histogram is +performed on the values contained in the image pixels. + +)0 P(The argument that follows is optional and specifies the number of bins +to use in creating the histogram and, if desired, the range of bin +values. For image and table histograms, the range should specify the +min and max data values. For image histograms on the x and y axes, +the range should specify the min and max image bin values. If this +argument is omitted, the number of output bins for a table is +calculated either from the TLMIN/TLMAX headers values \201if these exist +in the table FITS header for the specified column\202 or by going through +the data to calculate the min and max value. For an image, the number +of output bins is calculated either from the DATAMIN/DATAMAX header +values, or by going through the data to calculate min and max value. +\201Note that this latter calculation might fail if the image cannot be +fit in memory.\202 If the data are floating point \201table or image\202 and +the number of bins is not specified, an arbitrary default of 128 is +used. + +)0 P(For binary table processing, the )BD(-w)ES( \201bin width\202 switch can be used +to specify the width of each bin rather than the number of bins. Thus: +) 1 29 PR( funhist test.ev pha 1:100:5)RP( +means that 5 bins of width 20 are used in the histogram, while: +) 1 32 PR( funhist -w test.ev pha 1:100:5)RP( +means that 20 bins of width 5 are used in the histogram. + +)0 P(The data are divvied up into the specified number of bins and the +resulting 1D histogram \201or projection\202 is output in ASCII table +format. For a table, the output displays the low_edge \201inclusive\202 and +hi_edge \201exclusive\202 values for the data. For example, a 15-row table +containing a "pha" column whose values range from -7.5 to 7.5 +can be processed thus: + +) 47 62 PR( [sh] funhist test.ev pha + # data file: /home/eric/data/test.ev + # column: pha + # min,max,bins: -7.5 7.5 15 + + bin value lo_edge hi_edge + ------ --------- --------------------- --------------------- + 1 22 -7.50000000 -6.50000000 + 2 21 -6.50000000 -5.50000000 + 3 20 -5.50000000 -4.50000000 + 4 19 -4.50000000 -3.50000000 + 5 18 -3.50000000 -2.50000000 + 6 17 -2.50000000 -1.50000000 + 7 16 -1.50000000 -0.50000000 + 8 30 -0.50000000 0.50000000 + 9 16 0.50000000 1.50000000 + 10 17 1.50000000 2.50000000 + 11 18 2.50000000 3.50000000 + 12 19 3.50000000 4.50000000 + 13 20 4.50000000 5.50000000 + 14 21 5.50000000 6.50000000 + 15 22 6.50000000 7.50000000 + + [sh] funhist test.ev pha 1:6 + # data file: /home/eric/data/test.ev + # column: pha + # min,max,bins: 0.5 6.5 6 + + bin value lo_edge hi_edge + ------ --------- --------------------- --------------------- + 1 16 0.50000000 1.50000000)WR( + 2 17 1.50000000 2.50000000 + 3 18 2.50000000 3.50000000 + 4 19 3.50000000 4.50000000 + 5 20 4.50000000 5.50000000 + 6 21 5.50000000 6.50000000 + + [sh] funhist test.ev pha 1:6:3 + # data file: /home/eric/data/test.ev + # column: pha + # min,max,bins: 0.5 6.5 3 + + bin value lo_edge hi_edge + ------ --------- --------------------- --------------------- + 1 33 0.50000000 2.50000000 + 2 37 2.50000000 4.50000000 + 3 41 4.50000000 6.50000000)RP( + +)0 P(For a table histogram, the )BD(-n)ES(\201normalize\202 switch can be used to +normalize the bin value by the width of the bin \201i.e., hi_edge-lo_edge\202: +) 11 74 PR( [sh] funhist -n test.ev pha 1:6:3 + # data file: test.ev + # column: pha + # min,max,bins: 0.5 6.5 3 + # width normalization \201val/\201hi_edge-lo_edge\202\202 is applied + + bin value lo_edge hi_edge + ------ --------------------- --------------------- --------------------- + 1 16.50000000 0.50000000 2.50000000 + 2 6.16666667 2.50000000 4.50000000 + 3 4.10000000 4.50000000 6.50000000)RP( +This could used, for example, to produce a light curve with values +having units of counts/second instead of counts. + +)0 P(For an image histogram, the output displays the low and high image +values \201both inclusive\202 used to generate the histogram. For example, +in the following example, 184 pixels had a value of 1, 31 had a value +of 2, while only 2 had a value of 3,4,5,6, or 7: +) 13 74 PR( [sh] funhist test.fits + # data file: /home/eric/data/test.fits + # min,max,bins: 1 7 7 + + bin value lo_val hi_val + ------ --------------------- --------------------- --------------------- + 1 184.00000000 1.00000000 1.00000000 + 2 31.00000000 2.00000000 2.00000000 + 3 2.00000000 3.00000000 3.00000000 + 4 2.00000000 4.00000000 4.00000000 + 5 2.00000000 5.00000000 5.00000000 + 6 2.00000000 6.00000000 6.00000000 + 7 2.00000000 7.00000000 7.00000000)RP( + +)0 P(For the axis projection of an image, the output displays the low and +high image bins \201both inclusive\202 used to generate the projection. For +example, in the following example, 21 counts had their X bin value of +2, etc.: +) 23 74 PR( [sh] funhist test.fits x 2:7 + # data file: /home/eric/data/test.fits + # column: X + # min,max,bins: 2 7 6 + + bin value lo_bin hi_bin + ------ --------------------- --------------------- --------------------- + 1 21.00000000 2.00000000 2.00000000 + 2 20.00000000 3.00000000 3.00000000 + 3 19.00000000 4.00000000 4.00000000 + 4 18.00000000 5.00000000 5.00000000 + 5 17.00000000 6.00000000 6.00000000 + 6 16.00000000 7.00000000 7.00000000 + + [sh] funhist test.fits x 2:7:2 + # data file: /home/eric/data/test.fits + # column: X + # min,max,bins: 2 7 2 + + bin value lo_bin hi_bin + ------ --------------------- --------------------- --------------------- + 1 60.00000000 2.00000000 4.00000000 + 2 51.00000000 5.00000000 7.00000000)RP( + +)0 P(You can use gnuplot or other plotting programs to graph the +results, using a script such as: +) 7 119 PR( #!/bin/sh + sed -e '1,/---- .*/d + /^$/,$d' | \200 + awk '\200 + BEGIN{print "set nokey; set title \200"funhist\200"; set xlabel \200"bin\200"; set ylabel \200"counts\200"; plot \200"-\200" with boxes"} \200 + {print $3, $2, $4-$3}' | \200 + gnuplot -persist - 1>/dev/null 2>&1)RP( + +Similar plot commands are supplied in the script )BD(funhist.plot)ES(: +) 1 49 PR( funhist test.ev pha ... | funhist.plot gnuplot)RP( + + + + +)0 2 13 H(funimage)WB 76 Sn()WB 10 Sn( - create a FITS image from a Funtools data file)EA()EH( + + +)BD() 3 73 PR(funimage [-a] [bitpix=n] +funimage [-l] [bitpix=n] +funimage [-p x|y] [bitpix=n])RP()ES( + + +)0 P() 3 65 PR( -a # append to existing output file as an image extension + -l # input is a list file containing xcol, ycol, value + -p [x|y] # project along x or y axis to create a 1D image)RP( + + +)0 P()BD(funimage)ES( creates a primary FITS image from the specified +)0 42 1 A(FITS Extension)42 0 TN TL()Ec /AF f D( +and/or +)0 49 1 A(Image Section)49 0 TN TL()Ec /AF f D( +of a FITS file, or from an +)0 49 1 A(Image Section)49 0 TN TL()Ec /AF f D( +of a non-FITS array, or from a raw event file. +)0 P(The first argument to the program specifies the FITS input image, +array, or raw event file to process. If "stdin" is specified, data are +read from the standard input. Use )0 42 1 A(Funtools +Bracket Notation)42 0 TN TL()Ec /AF f D( to specify FITS extensions, image sections, and +filters. The second argument is the output FITS file. If "stdout" is +specified, the FITS image is written to the standard output. By +default, the output pixel values are of the same data type as those of the +input file \201or type "int" when binning a table\202, but this can be +overridden using an optional third argument of the form: +) 1 10 PR( bitpix=n)RP( +where n is 8,16,32,-32,-64, for unsigned char, short, int, float and double, +respectively. + +)0 P(If the input data are of type image, the appropriate section is +extracted and blocked \201based on how the +)0 49 1 A(Image Section)49 0 TN TL()Ec /AF f D( is specified\202, and +the result is written to the FITS primary image. When an integer +image containing the BSCALE and BZERO keywords is converted to float, +the pixel values are scaled and the scaling keywords are deleted from the +output header. When converting integer scaled data to integer +\201possibly of a different size\202, the pixels are not scaled and the +scaling keywords are retained. + +)0 P(If the input data is a binary table or raw event file, these are +binned into an image, from which a section is extracted and blocked, +and written to a primary FITS image. In this case, it is necessary to +specify the two columns that will be used in the 2D binning. This can +be done on the command line using the )BD(bincols=\201x,y\202)ES( keyword: +) 1 46 PR( funcnts "foo.ev[EVENTS,bincols=\201detx,dety\202]")RP( +The full form of the )BD(bincols=)ES( specifier is: +) 1 77 PR( bincols=\201[xname[:tlmin[:tlmax:[binsiz]]]],[yname[:tlmin[:tlmax[:binsiz]]]]\202)RP( +where the tlmin, tlmax, and binsiz specifiers determine the image binning +dimensions: +) 2 56 PR( dim = \201tlmax - tlmin\202/binsiz \201floating point data\202 + dim = \201tlmax - tlmin\202/binsiz + 1 \201integer data\202)RP( +Using this syntax, it is possible to bin any two columns of a binary +table at any bin size. Note that the tlmin, tlmax, and binsiz +specifiers can be omitted if TLMIN, TLMAX, and TDBIN header parameters +\201respectively\202 are present in the FITS binary table header for the +column in question. Note also that if only one parameter is specified, +it is assumed to be tlmax, and tlmin defaults to 1. If two parameters +are specified, they are assumed to be tlmin and tlmax. +See )0 50 1 A(Binning FITS Binary Tables and Non-FITS +Event Files)50 0 TN TL()Ec /AF f D( for more information about binning parameters. + +)0 P(By default, a new 2D FITS image file is created and the image is written +to the primary HDU. If the )BD(-a)ES( \201append\202 switch is specified, +the image is appended to an existing FITS file as an IMAGE extension. +\201If the output file does not exist, the switch is effectively ignored +and the image is written to the primary HDU.\202 This can be useful in a +shell programming environment when processing multiple FITS images +that you want to combine into a single final FITS file. + +)0 P()BD(funimage)ES( also can take input from a table containing columns of +x, y, and value \201e.g., the output from )BD(fundisp -l)ES( which +displays each image x and y and the number of counts at that +position.\202 When the )BD(-l)ES( \201list\202 switch is used, the input file is +taken to be a FITS or ASCII table containing \201at least\202 three columns +that specify the x and y image coordinates and the value of that +image pixel. In this case, )BD(funimage)ES( requires four extra +arguments: xcolumn:xdims, ycolumn:ydims, vcolumn and bitpix=n. The x +and y col:dim information takes the form: +) 3 55 PR( name:dim # values range from 1 to dim + name:min:max # values range from min to max + name:min:max:binsiz # dimensions scaled by binsize)RP( +In particular, the min value should be used whenever the +minimum coordinate value is something other than one. For example: +) 2 69 PR( + funimage -l foo.lst foo.fits xcol:0:512 ycol:0:512 value bitpix=-32)RP( + +)0 P(The list feature also can be used to read unnamed columns from standard +input: simply replace the column name with a null string. Note +that the dimension information is still required: +) 5 60 PR( funimage -l stdin foo.fits "":0:512 "":0:512 "" bitpix=-32 + 240 250 1 + 255 256 2 + ... + ^D)RP( + +)0 P(The list feature provides a simple way to generate a blank image. +If you pass a )0 47 1 A(Column-based Text File)47 0 TN TL()Ec /AF f D( +to funimage in which the text header contains the required image +information, then funimage will correctly make a blank image. For +example, consider the following text file \201called foo.txt\202: +) 3 20 PR( x:I:1:10 y:I:1:10 + ------ ------ + 0 0)RP( +This text file defines two columns, x and y, each of data type 32-bit int and +image dimension 10. The command: +) 1 36 PR( funimage foo.txt foo.fits bitpix=8)RP( +will create an empty FITS image called foo.fits containing a 10x10 +image of unsigned char: +) 13 75 PR( fundisp foo.fits + 1 2 3 4 5 6 7 8 9 10 + ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ + 10: 0 0 0 0 0 0 0 0 0 0 + 9: 0 0 0 0 0 0 0 0 0 0 + 8: 0 0 0 0 0 0 0 0 0 0 + 7: 0 0 0 0 0 0 0 0 0 0 + 6: 0 0 0 0 0 0 0 0 0 0 + 5: 0 0 0 0 0 0 0 0 0 0 + 4: 0 0 0 0 0 0 0 0 0 0 + 3: 0 0 0 0 0 0 0 0 0 0 + 2: 0 0 0 0 0 0 0 0 0 0 + 1: 1 0 0 0 0 0 0 0 0 0)RP( + +Note that the text file must contain at least +one row of data. However, in the present example, event position 0,0 is +outside the limits of the image and will be ignored. \201You can, of course, +use real x,y values to seed the image with data.\202 + +)0 P(Furthermore, you can use the TEXT filter specification to obviate the need for +an input text file altogether. The following command will create the same +10x10 char image without an actual input file: +) 3 69 PR( funimage stdin'[TEXT\201x:I:10,y:I:10\202]' foo.fits bitpix=8 < /dev/null +or + funimage /dev/null'[TEXT\201x:I:10,y:I:10\202]' foo.fits bitpix=8)RP( + +)0 P(You also can use either of these methods to generate a region mask simply +by appending a region inside the filter brackets and specfying )BD(mask=all)ES( +along with the bitpix. For example, the following command will generate a +10x10 char mask using 3 regions: +) 2 76 PR( funimage stdin'[TEXT\201x:I:10,y:I:10\202,cir\2015,5,4\202,point\20110,1\202,-cir\2015,5,2\202]' \200 + foo.fits bitpix=8,mask=all < /dev/null)RP( +The resulting mask looks like this: +) 13 75 PR( fundisp foo.fits + 1 2 3 4 5 6 7 8 9 10 + ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ + 10: 0 0 0 0 0 0 0 0 0 0 + 9: 0 0 0 0 0 0 0 0 0 0 + 8: 0 0 1 1 1 1 1 0 0 0 + 7: 0 1 1 1 1 1 1 1 0 0 + 6: 0 1 1 0 0 0 1 1 0 0 + 5: 0 1 1 0 0 0 1 1 0 0 + 4: 0 1 1 0 0 0 1 1 0 0 + 3: 0 1 1 1 1 1 1 1 0 0 + 2: 0 0 1 1 1 1 1 0 0 0 + 1: 0 0 0 0 0 0 0 0 0 2)RP( + +)0 P(You can use )BD(funimage)ES( to create 1D image projections along the x +or y axis using the )BD(-p [x|y])ES( switch. This capability works for +both images and tables. For example consider a FITS table named ev.fits +containing the following rows: +) 17 19 PR( X Y + -------- -------- + 1 1 + 1 2 + 1 3 + 1 4 + 1 5 + 2 2 + 2 3 + 2 4 + 2 5 + 3 3 + 3 4 + 3 5 + 4 4 + 4 5 + 5 5)RP( +A corresponding 5x5 image, called dim2.fits, would therefore contain: +) 7 59 PR( 1 2 3 4 5 + ---------- ---------- ---------- ---------- ---------- + 5: 1 1 1 1 1 + 4: 1 1 1 1 0 + 3: 1 1 1 0 0 + 2: 1 1 0 0 0 + 1: 1 0 0 0 0)RP( +A projection along the y axis can be performed on either the table or +the image: +) 9 59 PR( funimage -p y ev.fits stdout | fundisp stdin + 1 2 3 4 5 + ---------- ---------- ---------- ---------- ---------- + 1: 1 2 3 4 5 + + funimage -p y dim2.fits stdout | fundisp stdin + 1 2 3 4 5 + ---------- ---------- ---------- ---------- ---------- + 1: 1 2 3 4 5)RP( + +)0 P(Furthermore, you can create a 1D image projection along any column of +a table by using the )BD(bincols=[column])ES( filter specification and +specifying a single column. For example, the following command +projects the same 1D image along the y axis of a table as use of +the )BD(-p y)ES( switch: +) 4 59 PR( funimage ev.fits'[bincols=y]' stdout | fundisp stdin + 1 2 3 4 5 + ---------- ---------- ---------- ---------- ---------- + 1: 1 2 3 4 5)RP( + +)0 P(Examples: +)0 P(Create a FITS image from a FITS binary table: +) 1 33 PR( [sh] funimage test.ev test.fits)RP( + +)0 P(Display the FITS image generated from a blocked section of FITS binary table: +) 5 60 PR( [sh] funimage "test.ev[2:8,3:7,2]" stdout | fundisp stdin + 1 2 3 + --------- --------- --------- + 1: 20 28 36 + 2: 28 36 44)RP( + + + + +)0 2 14 H(funindex)WB 77 Sn()WB 11 Sn( - create an index for a column of a FITS binary table)EA()EH( + + +)BD() 1 42 PR(funindex [oname])RP()ES( + + +)0 P() 7 71 PR( NB: these options are not compatible with Funtools processing. Please + use the defaults instead. + -c # compress output using gzip" + -a # ASCII output, ignore -c \201default: FITS table\202" + -f # FITS table output \201default: FITS table\202" + -l # long output, i.e. with key value\201s\202 \201default: long\202" + -s # short output, i.e. no key value\201s\202 \201default: long\202")RP( + + +)0 P(The funindex script creates an index for the specified column \201key\202 by +running funtable -s \201sort\202 and then saving the column value and the +record number for each sorted row. This index will be used automatically + by funtools filtering of that column, provided the index file's modification +date is later than that of the data file. + +)0 P( +The first required argument is the name of the FITS binary table +to index. Please note that text files cannot be indexed at this time. +The second required argument is the column \201key\202 name to index. While +multiple keys can be specified in principle, the funtools index processing +assume a single key and will not recognize files containing multiple keys. + +)0 P(By default, the output index file name is [root]_[key].idx, where [root] +is the root of the input file. Funtools looks for this specific file name +when deciding whether to use an index for faster filtering. Therefore, the +optional third argument \201output file name\202 should not be used for funtools +processing. + +)0 P(For example, to create an index on column Y for a given FITS file, use: +) 1 21 PR( funindex foo.fits Y)RP( +This will generate an index named foo_y.idx, which will be used by funtools +for filters involving the Y column. + + + + +)0 2 15 H(funjoin)WB 78 Sn()WB 12 Sn( - join two or more FITS binary tables on specified columns)EA()EH( + + +)BD() 1 57 PR(funjoin [switches] ... )RP()ES( + + +)0 P() 11 74 PR( -a cols # columns to activate in all files + -a1 cols ... an cols # columns to activate in each file + -b 'c1:bvl,c2:bv2' # blank values for common columns in all files + -bn 'c1:bv1,c2:bv2' # blank values for columns in specific files + -j col # column to join in all files + -j1 col ... jn col # column to join in each file + -m min # min matches to output a row + -M max # max matches to output a row + -s # add 'jfiles' status column + -S col # add col as status column + -t tol # tolerance for joining numeric cols [2 files only])RP( + + +)BD(funjoin)ES( joins rows from two or more \201up to 32\202 +)0 42 1 A(FITS Binary Table files)42 0 TN TL()Ec /AF f D(, based on the values +of specified join columns in each file. NB: the join columns must have +an index file associated with it. These files are generated using the +)BD(funindex)ES( program. + +)0 P(The first argument to the program specifies the first input FITS table +or raw event file. If "stdin" is specified, data are read from the +standard input. Subsequent arguments specify additional event files +and tables to join. The last argument is the output FITS file. + +)0 P(NB: Do )BD(not)ES( use )0 42 1 A(Funtools Bracket +Notation)42 0 TN TL()Ec /AF f D( to specify FITS extensions and row filters when running +funjoin or you will get wrong results. Rows are accessed and joined +using the index files directly, and this bypasses all filtering. + +)0 P(The join columns are specified using the )BD(-j col)ES( switch \201which +specifies a column name to use for all files\202 or with )BD(-j1 col1)ES(, +)BD(-j2 col2)ES(, ... )BD(-jn coln)ES( switches \201which specify a column +name to use for each file\202. A join column must be specified for each file. +If both )BD(-j col)ES( and )BD(-jn coln)ES( are specified for a given +file, then the latter is used. Join columns must either be of type +string or type numeric; it is illegal to mix numeric and string +columns in a given join. For example, to join three files using the +same key column for each file, use: +) 1 52 PR( funjoin -j key in1.fits in2.fits in3.fits out.fits)RP( +A different key can be specified for the third file in this way: +) 1 65 PR( funjoin -j key -j3 otherkey in1.fits in2.fits in3.fits out.fits)RP( + +)0 P(The )BD(-a "cols")ES( switch \201and )BD(-a1 "col1")ES(, +)BD(-a2 "cols2")ES( counterparts\202 can be used to specify columns to +activate \201i.e. write to the output file\202 for each input file. By +default, all columns are output. + +)0 P(If two or more columns from separate files have the same name, the +second \201and subsequent\202 columns are renamed to have an underscore +and a numeric value appended. + +)0 P(The )BD(-m min)ES( and )BD(-M max)ES( switches specify the minimum +and maximum number of joins required to write out a row. The default +minimum is 0 joins \201i.e. all rows are written out\202 and the default maximum +is 63 \201the maximum number of possible joins with a limit of 32 input files\202. +For example, to write out only those rows in which exactly two files +have columns that match \201i.e. one join\202: +) 1 66 PR( funjoin -j key -m 1 -M 1 in1.fits in2.fits in3.fits ... out.fits)RP( + +)0 P(A given row can have the requisite number of joins without all of the +files being joined \201e.g. three files are being joined but only two +have a given join key value\202. In this case, all of the columns of the +non-joined file are written out, by default, using blanks \201zeros or NULLs\202. +The )BD(-b c1:bv1,c2:bv2)ES( and +)BD(-b1 'c1:bv1,c2:bv2' -b2 'c1:bv1,c2:bv2' ...)ES( +switches can be used to set the blank value for columns common to all +files and/or columns in a specified file, respectively. Each blank value +string contains a comma-separated list of column:blank_val specifiers. +For floating point values \201single or double\202, a case-insensitive string +value of "nan" means that the IEEE NaN \201not-a-number\202 should be +used. Thus, for example: +) 1 62 PR( funjoin -b "AKEY:???" -b1 "A:-1" -b3 "G:NaN,E:-1,F:-100" ...)RP( +means that a non-joined AKEY column in any file will contain the +string "???", the non-joined A column of file 1 will contain a value +of -1, the non-joined G column of file 3 will contain IEEE NaNs, while +the non-joined E and F columns of the same file will contain values -1 +and -100, respectively. Of course, where common and specific blank values +are specified for the same column, the specific blank value is used. + +)0 P(To distinguish which files are non-blank components of a given row, +the )BD(-s)ES( \201status\202 switch can be used to add a bitmask column named +"JFILES" to the output file. In this column, a bit is set for each +non-blank file composing the given row, with bit 0 corresponds to the +first file, bit 1 to the second file, and so on. The file names +themselves are stored in the FITS header as parameters named JFILE1, +JFILE2, etc. The )BD(-S col)ES( switch allows you to change the name +of the status column from the default "JFILES". + +)0 P(A join between rows is the Cartesian product of all rows in one file +having a given join column value with all rows in a second file having +the same value for its join column and so on. Thus, if file1 has 2 +rows with join column value 100, file2 has 3 rows with the same value, +and file3 has 4 rows, then the join results in 2*3*4=24 rows being output. + +)0 P(The join algorithm directly processes the index file associated with +the join column of each file. The smallest value of all the current +columns is selected as a base, and this value is used to join +equal-valued columns in the other files. In this way, the index files +are traversed exactly once. + +)0 P(The )BD(-t tol)ES( switch specifies a tolerance value for numeric +columns. At present, a tolerance value can join only two files at a +time. \201A completely different algorithm is required to join more than +two files using a tolerance, somethng we might consider implementing +in the future.\202 + +)0 P(The following example shows many of the features of funjoin. The input files +t1.fits, t2.fits, and t3.fits contain the following columns: +) 28 49 PR( [sh] fundisp t1.fits + AKEY KEY A B + ----------- ------ ------ ------ + aaa 0 0 1 + bbb 1 3 4 + ccc 2 6 7 + ddd 3 9 10 + eee 4 12 13 + fff 5 15 16 + ggg 6 18 19 + hhh 7 21 22 + +fundisp t2.fits + AKEY KEY C D + ----------- ------ ------ ------ + iii 8 24 25 + ggg 6 18 19 + eee 4 12 13 + ccc 2 6 7 + aaa 0 0 1 + +fundisp t3.fits + AKEY KEY E F G +------------ ------ -------- -------- ----------- + ggg 6 18 19 100.10 + jjj 9 27 28 200.20 + aaa 0 0 1 300.30 + ddd 3 9 10 400.40)RP( + +)0 P(Given these input files, the following funjoin command: +) 3 59 PR( funjoin -s -a1 "-B" -a2 "-D" -a3 "-E" -b \200 + "AKEY:???" -b1 "AKEY:XXX,A:255" -b3 "G:NaN,E:-1,F:-100" \200 + -j key t1.fits t2.fits t3.fits foo.fits)RP( +will join the files on the KEY column, outputting all columns except B +\201in t1.fits\202, D \201in t2.fits\202 and E \201in t3.fits\202, and setting blank +values for AKEY \201globally, but overridden for t1.fits\202 and A \201in file +1\202 and G, E, and F \201in file 3\202. A JFILES column will be output to +flag which files were used in each row: +) 12 105 PR( AKEY KEY A AKEY_2 KEY_2 C AKEY_3 KEY_3 F G JFILES + ------------ ------ ------ ------------ ------ ------ ------------ ------ -------- ----------- -------- + aaa 0 0 aaa 0 0 aaa 0 1 300.30 7 + bbb 1 3 ??? 0 0 ??? 0 -100 nan 1 + ccc 2 6 ccc 2 6 ??? 0 -100 nan 3 + ddd 3 9 ??? 0 0 ddd 3 10 400.40 5 + eee 4 12 eee 4 12 ??? 0 -100 nan 3 + fff 5 15 ??? 0 0 ??? 0 -100 nan 1 + ggg 6 18 ggg 6 18 ggg 6 19 100.10 7 + hhh 7 21 ??? 0 0 ??? 0 -100 nan 1 + XXX 0 255 iii 8 24 ??? 0 -100 nan 2 + XXX 0 255 ??? 0 0 jjj 9 28 200.20 4)RP( + + + +)0 2 16 H(funmerge)WB 79 Sn()WB 13 Sn( - merge one or more Funtools table files)EA()EH( + + +)BD() 1 61 PR(funmerge [-w|-x] -f [colname] ... )RP()ES( + + +)0 P() 3 68 PR( -f # output a column specifying file from which this event came + -w # adjust position values using WCS info + -x # adjust position values using WCS info and save old values)RP( + + +)0 P()BD(funmerge)ES( merges FITS data from one or more +)0 42 1 A(FITS Binary Table files)42 0 TN TL()Ec /AF f D( +or raw event files. +)0 P(The first argument to the program specifies the first input FITS table +or raw event file. If "stdin" is specified, data are read from the +standard input. Use )0 42 1 A(Funtools Bracket +Notation)42 0 TN TL()Ec /AF f D( to specify FITS extensions and row filters. Subsequent +arguments specify additional event files and tables to merge. \201NB: Stdin +cannot not be used for any of these additional input file arguments.\202 +The last argument is the output FITS file. The columns in each input table +must be identical. + +)0 P(If an input file begins with the '@' character, it is processed as an +include file, i.e., as a text file containing event file names \201as +well as blank lines and/or comment lines starting with the '#' sign\202. +If standard input is specified as an include file \201'@stdin'\202, then +file names are read from the standard input until EOF \201^D\202. Event +files and include files can be mixed on a command line. + +)0 P(Rows from each table are written sequentially to the output +file. If the switch )BD(-f [colname])ES( is specified on the command +line, an additional column is added to each row containing the number +of the file from which that row was taken \201starting from one\202. In +this case, the corresponding file names are stored in the header +parameters having the prefix )BD(FUNFIL)ES(, i.e., FUNFIL01, +FUNFIL02, etc. + +)0 P(Using the )BD(-w)ES( switch \201or )BD(-x)ES( switch as described +below\202, )BD(funmerge)ES( also can adjust the position column values +using the WCS information in each file. \201By position columns, we mean +the columns that the table is binned on, i.e., those columns defined +by the )BD(bincols=)ES( switch, or \201X,Y\202 by default.\202 To perform WCS +alignment, the WCS of the first file is taken as the base WCS. Each +position in subsequent files is adjusted by first converting it to the +sky coordinate in its own WCS coordinate system, then by converting +this sky position to the sky position of the base WCS, and finally +converting back to a pixel position in the base system. Note that in +order to perform WCS alignment, the appropriate WCS and TLMIN/TLMAX +keywords must already exist in each FITS file. +)0 P(When performing WCS alignment, you can save the original positions in +the output file by using the )BD(-x)ES( \201for "xtra"\202 switch instead +of the )BD(-w)ES( switch \201i.e., using this switch also implies using +)BD(-w)ES(\202 The old positions are saved in columns having the same +name as the original positional columns, with the added prefix "OLD_". +)0 P(Examples: + +)0 P(Merge two tables, and preserve the originating file number for +each row in the column called "FILE" \201along with the corresponding +file name in the header\202: +) 1 51 PR( [sh] funmerge -f "FILE" test.ev test2.ev merge.ev)RP( + +)0 P(Merge two tables with WCS alignment, saving the old position values in +2 additional columns: +) 1 44 PR( [sh] funmerge -x test.ev test2.ev merge.ev)RP( + +)0 P(This program only works on raw event files and binary tables. We have +not yet implemented image and array merging. + + + + +)0 2 17 H(funsky)WB 80 Sn()WB 14 Sn( - convert between image and sky coordinates)EA()EH( + + +)BD() 4 72 PR( funsky iname[ext] # RA,Dec \201deg\202 or image pix from stdin + funsky iname[ext] [lname] # RA, Dec \201deg\202 or image pix from list + funsky iname[ext] [col1] [col2] # named cols:units from stdin + funsky iname[ext] [lname] [col1] [col2] # named cols:units from list)RP()ES( + + +)0 P() 5 73 PR( -d # always use integer tlmin conversion \201as ds9 does\202 + -r # convert x,y to RA,Dec \201default: convert RA,Dec to x,y\202 + -o # include offset from the nominal target position \201in arcsec\202 + -v # display input values also \201default: display output only\202 + -T # output display in rdb format \201w/header,tab delimiters\202)RP( + + +)0 P(Funsky converts input sky coordinates \201RA, Dec\202 to image coordinates \201or vice +versa\202 using the WCS information contained in the specified FITS file. Several +calling sequences are supported in order to make it easy to specify +coordinate positions in different ways. + +)0 P(The first required argument is always the input FITS file \201or +extension\202 containing the WCS information in an extension header. Note +that the data from this file is not used. By default, the program +converts input RA and Dec values to X and Y using this WCS +information. If the WCS is associated with a FITS image, then the X,Y +values are image values. If the WCS is associated with a binary table, +then the X, Y values are physical values. To convert X,Y to RA and +Dec, use the )BD(-r)ES( \201reverse\202 switch. + +)0 P(If no other command arguments are supplied, then the input positions +are read from the standard input. Each line is assumed to contain a +single coordinate position consisting of an RA in degrees \201or X in +pixels\202 followed by a Dec in degrees \201or Y in pixels\202. The usual +delimiters are supported \201spaces, commas, tabs\202. For example: +) 9 52 PR( # read from stdin, default column names and units + [sh] funsky snr.ev + 22.982695 58.606523 # input RA \201hrs\202, Dec\201deg\202 + 510.00 510.00 + 22.982127 58.607634 # input + 512.00 510.50 + 22.981700 58.614301 # input + 513.50 513.50 + ^D # end of input)RP( + +)0 P(If a second argument is supplied, this argument is assumed to be +a file containing RA \201X\202 and Dec \201Y\202 positions. The file can either be +an ASCII table or a FITS binary table. The order of columns is +unimportant, if the table has a column header. In this case, the +names of the columns must be one of "RA", "DEC", or "X", "Y" for sky +to image and image to sky conversions, respectively. If the table has +no header, then once again, RA \201X\202 is assumed to first, followed +by DEC \201Y\202. +For example: +) 12 50 PR( # read from file, default column names and units + [sh] cat hd.in + RA DEC + --------- --------- + 22.982695 58.606523 + 22.982127 58.607634 + 22.981700 58.614301 + + [sh] funsky snr.ev hd.in + 510.00 510.00 + 512.00 510.50 + 513.50 513.50)RP( + +)0 P(If three arguments are supplied, then the input positions again are +read from the standard input. Each line is assumed to contain a single +coordinate position consisting of an RA \201or X in pixels\202 followed by a +Dec \201or Y in pixels\202, with the usual delimiters supported. However, +the second and third arguments now specify the column names and/or +sky units using a colon-delimited syntax: +) 1 19 PR( [colname]:[h|d|r])RP( +If the colname is omitted, the names default to "RA", "DEC", "X", "Y", +"COL1", or "COL2" as above. If the units are omitted, the default is degrees +for both RA and Dec. When the -r switch is used \201convert from image +to sky\202 the units are applied to the output instead of the input. The following +examples will serve to illustrate the options: +) 36 66 PR( # read from stdin, specifying column names \201def. units: degrees\202 + [sh] cat hd.in + MYRA MYDEC + --------- --------- + 22.982695 58.606523 + 22.982127 58.607634 + 22.981700 58.614301 + + [sh] funsky snr.ev MYRA MYDEC < hd.in + 510.00 510.00 + 512.00 510.50 + 513.50 513.50 + + # read from stdin, specifying column names and units + [sh] cat dd.in + MYRA MYDEC + --------- --------- + 344.740432 58.606523 + 344.731900 58.607634 + 344.725500 58.614301 + + [sh] funsky snr.ev MYRA:d MYDEC:d < dd.in + 510.00 510.00 + 512.00 510.50 + 513.50 513.50 + + # read stdin, convert image to sky, specifying output sky units + [sh] cat im.in + 510.00 510.00 + 512.00 510.50 + 513.50 513.50)WR( + + [sh] cat im.in | funsky -r snr.ev :d :d + 344.740432 58.606523 + 344.731900 58.607634 + 344.725500 58.614301)RP( + +)0 P(Finally, four command arguments specify both and input file and column names +and/or units: +) 22 64 PR( [sh] cat dd.in + MYRA MYDEC + --------- --------- + 344.740432 58.606523 + 344.731900 58.607634 + 344.725500 58.614301 + + [sh] funsky snr.ev dd.in MYRA:d MYDEC:d + 510.00 510.00 + 512.00 510.50 + 513.50 513.50 + + # read file, convert image to sky, specifying output sky units + [sh] cat im.in + 510.00 510.00 + 512.00 510.50 + 513.50 513.50 + + [sh] funsky -r snr.ev im.in :d :d + 344.740432 58.606523 + 344.731900 58.607634 + 344.725500 58.614301)RP( + +)0 P(By default, the output of funsky consists only of the converted coordinate +position\201s\202, one per output line. This makes parsing in shell scripts easy. +Use the )BD(-v)ES( \201verbose\202 switch to specify that the input +coordinates should be pre-pended to each line. For example: +) 16 53 PR( [sh] cat dd.in + MYRA MYDEC + --------- --------- + 344.740432 58.606523 + 344.731900 58.607634 + 344.725500 58.614301 + + [sh] funsky snr.ev dd.in MYRA:d MYDEC:d + 510.00 510.00 + 512.00 510.50 + 513.50 513.50 + + [sh] funsky -v snr.ev dd.in MYRA:d MYDEC:d + 344.740432 58.606523 510.00 510.00 + 344.731900 58.607634 512.00 510.50 + 344.725500 58.614301 513.50 513.50)RP( + +)0 P(In addition, a full starbase table can be output using the )BD(-T)ES( +\201table\202 switch. This switch can be used with or without the -v +switch. If the -T and -v are both specified, then a descriptive header +parameters are output before the table \201mainly to remind you of the +sky units\202: +) 23 62 PR( # output table in non-verbose mode + [sh] funsky -T snr.ev dd.in MYRA:d MYDEC:d + X Y + ------------ ------------ + 510.00 510.00 + 512.00 510.50 + 513.50 513.50 + + # output table in verbose mode + [sh] funsky -T -v snr.ev dd.in MYRA:d MYDEC:d + # IFILE = /Users/eric/data/snr.ev + # ICOL1 = MYRA + # ICOL2 = MYDEC + # IUNITS1 = d + # IUNITS2 = d + # OCOL1 = X + # OCOL2 = Y + + MYRA MYDEC X Y + ------------ ------------ ------------ ------------ + 344.740432 58.606523 510.00 510.00 + 344.731900 58.607634 512.00 510.50 + 344.725500 58.614301 513.50 513.50)RP( + +)0 P(Finally, the )BD(-d)ES( \201ds9\202 switch mimicks ds9's use of integer TLMIN +and TLMAX values for all coordinate transformations. FITS conventions +seem to call for use of floating point TLMIN and TLMAX when the data are +floats. This convention is followed by funsky but results in a +small discrepancy with ds9's converted values for floating point +data. We will remedy this conflict in the future, maybe. + + + + +)0 2 18 H(funtable)WB 81 Sn()WB 15 Sn( - copy selected rows from a Funtools file to a FITS binary table)EA()EH( + + +)BD() 1 62 PR(funtable [-a] [-i|-z] [-m] [-s cols] [columns])RP()ES( + + +)0 P() 5 61 PR( -a # append to existing output file as a table extension + -i # for image data, only generate X and Y columns + -m # for tables, write a separate file for each region + -s "col1 ..." # columns on which to sort + -z # for image data, output zero-valued pixels)RP( + + +)0 P()BD(funtable)ES( selects rows from the specified +)0 42 1 A(FITS Extension)42 0 TN TL()Ec /AF f D( +\201binary table only\202 of a FITS file, or from a non-FITS raw event +file, and writes those rows to a FITS binary table file. It also +will create a FITS binary table from an image or a raw array file. + +)0 P(The first argument to the program specifies the FITS file, raw event +file, or raw array file. If "stdin" is specified, data are read from +the standard input. Use )0 42 1 A(Funtools Bracket +Notation)42 0 TN TL()Ec /AF f D( to specify FITS extensions, and filters. The second +argument is the output FITS file. If "stdout" is specified, the FITS +binary table is written to the standard output. By default, all +columns of the input file are copied to the output file. Selected +columns can be output using an optional third argument in the form: +) 1 31 PR( "column1 column1 ... columnN")RP( + +)0 P(The )BD(funtable)ES( program generally is used to select rows from a +FITS binary table using +)0 52 1 A(Table Filters)52 0 TN TL()Ec /AF f D( +and/or +)0 54 1 A(Spatial Region Filters)54 0 TN TL()Ec /AF f D(. +For example, you can copy only selected rows \201and output only selected +columns\202 by executing in a command such as: +) 13 75 PR( [sh] funtable "test.ev[pha==1&)SY(\160)ES(==10]" stdout "x y pi pha" | fundisp stdin + X Y PHA PI + ------- ------- ------- --------- + 1 10 1 10 + 1 10 1 10 + 1 10 1 10 + 1 10 1 10 + 1 10 1 10 + 1 10 1 10 + 1 10 1 10 + 1 10 1 10 + 1 10 1 10 + 1 10 1 10)RP( +)0 P(The special column )BD($REGION)ES( can be specified to write the +region id of each row: +) 12 113 PR( [sh $] funtable "test.ev[time-\201int\202time>=.99&&annulus\2010 0 0 10 n=3\202]" stdout 'x y time $REGION' | fundisp stdin + X Y TIME REGION + -------- -------- --------------------- ---------- + 5 -6 40.99000000 3 + 4 -5 59.99000000 2 + -1 0 154.99000000 1 + -2 1 168.99000000 1 + -3 2 183.99000000 2 + -4 3 199.99000000 2 + -5 4 216.99000000 2 + -6 5 234.99000000 3 + -7 6 253.99000000 3)RP( +)0 P(Here only rows with the proper fractional time and whose position also is +within one of the three annuli are written. +)0 P(Columns can be excluded from display using a minus sign before the +column: +) 12 79 PR( [sh $] funtable "test.ev[time-\201int\202time>=.99]" stdout "-time" | fundisp stdin + X Y PHA PI DX DY + -------- -------- -------- ---------- ----------- ----------- + 5 -6 5 -6 5.50 -6.50 + 4 -5 4 -5 4.50 -5.50 + -1 0 -1 0 -1.50 0.50 + -2 1 -2 1 -2.50 1.50 + -3 2 -3 2 -3.50 2.50 + -4 3 -4 3 -4.50 3.50 + -5 4 -5 4 -5.50 4.50 + -6 5 -6 5 -6.50 5.50 + -7 6 -7 6 -7.50 6.50)RP( +All columns except the time column are written. +)0 P(In general, the rules for activating and de-activating columns are: +)UL()-1 LI( If only exclude columns are specified, then all columns but +the exclude columns will be activated. +)-1 LI( If only include columns are specified, then only the specified columns +are activated. +)-1 LI( If a mixture of include and exclude columns are specified, then +all but the exclude columns will be active; this last case +is ambiguous and the rule is arbitrary.)LU( +In addition to specifying columns names explicitly, the special +symbols )EM(+)ES( and )EM(-)ES( can be used to activate and +de-activate )EM(all)ES( columns. This is useful if you want to +activate the $REGION column along with all other columns. According +to the rules, the syntax "$REGION" only activates the region column +and de-activates the rest. Use "+ $REGION" to activate all +columns as well as the region column. + +)0 P(Ordinarily, only the selected table is copied to the output file. In +a FITS binary table, it sometimes is desirable to copy all of the +other FITS extensions to the output file as well. This can be done by +appending a '+' sign to the name of the extension in the input file +name. For example, the first command below copies only the EVENT table, +while the second command copies other extensions as well: +) 2 64 PR( [sh] funtable "/proj/rd/data/snr.ev[EVENTS]" events.ev + [sh] funtable "/proj/rd/data/snr.ev[EVENTS+]" eventsandmore.ev)RP( + +)0 P(If the input file is an image or a raw array file, then +)BD(funtable)ES( will generate a FITS binary table from the pixel +values in the image. Note that it is not possible to specify the +columns to output \201using command-line argument 3\202. Instead, there are +two ways to create such a binary table from an image. By default, a +3-column table is generated, where the columns are "X", "Y", and +"VALUE". For each pixel in the image, a single row \201event\202 is +generated with the "X" and "Y" columns assigned the dim1 and dim2 +values of the image pixel, respectively and the "VALUE" column +assigned the value of the pixel. With sort of table, running +)BD(funhist)ES( on the "VALUE" column will give the same results as +running )BD(funhist)ES( on the original image. + +)0 P(If the )BD(-i)ES( \201"individual" rows\202 switch is specified, then only +the "X" and "Y" columns are generated. In this case, each positive +pixel value in the image generates n rows \201events\202, where n is equal +to the integerized value of that pixel \201plus 0.5, for floating point +data\202. In effect, )BD(-i)ES( approximately recreates the rows of a +table that would have been binned into the input image. \201Of course, +this is only approximately correct, since the resulting x,y positions +are integerized.\202 + +)0 P(If the )BD(-s [col1 col2 ... coln])ES( \201"sort"\202 switch is specified, +the output rows of a binary table will be sorted using the +specified columns as sort keys. The sort keys must be scalar columns +and also must be part of the output file \201i.e. you cannot sort on a +column but not include it in the output\202. This facility uses the +)BD(_sort)ES( program \201included with funtools\202, which must be accessible +via your path. + +)0 P(For binary tables, the )BD(-m)ES( \201"multiple files"\202 switch will +generate a separate file for each region in the filter specification +i.e. each file contains only the rows from that region. Rows +which pass the filter but are not in any region also are put in a +separate file. + +)0 P(The separate output file names generated by the )BD(-m)ES( switch are +produced automatically from the root output file to contain the region id of +the associated region. \201Note that region ids start at 1, so that the +file name associated with id 0 contains rows that pass the filter but +are not in any given region.\202 Output file names are generated as follows: + +)UL()-1 LI( A $n specification can be used anywhere in the root file name \201suitably +quoted to protect it from the shell\202 and will be expanded to be the id +number of the associated region. For example: +) 1 78 PR( funtable -m input.fits'[cir\201512,512,1\202;cir\201520,520,1\202...]' 'foo.goo_$n.fits')RP( +will generate files named foo.goo_0.fits \201for rows not in any region but +still passing the filter\202, foo.goo_1.fits \201rows in region id #1, the first +region\202, foo.goo_2.fits \201rows in region id #2\202, etc. Note that single quotes +in the output root are required to protect the '$' from the shell. + +)-1 LI( If $n is not specified, then the region id will be placed before +the first dot \201.\202 in the filename. Thus: +) 1 73 PR( funtable -m input.fits'[cir\201512,512,1\202;cir\201520,520,1\202...]' foo.evt.fits)RP( +will generate files named foo0.evt.fits \201for rows not in any region but +still passing the filter\202, foo1.evt.fits \201rows in region id #1\202, +foo2.evt.fits \201rows in region id #2\202, etc. + +)-1 LI( If no dot is specified in the root output file name, then +the region id will be appended to the filename. Thus: +) 1 70 PR( funtable -m input.fits'[cir\201512,512,1\202;cir\201520,520,1\202...]' 'foo_evt')RP( +will generate files named foo_evt0 \201for rows not in any region but +still passing the filter\202, foo_evt1 \201rows in region id #1\202, +foo_evt2 \201rows in region id #2\202, etc.)LU( +The multiple file mechanism provide a simple way to generate +individual source data files with a single pass through the data. + +)0 P(By default, a new FITS file is created and the binary table is written +to the first extension. If the )BD(-a)ES( \201append\202 switch is specified, +the table is appended to an existing FITS file as a BINTABLE extension. +Note that the output FITS file must already exist. + +)0 P(If the )BD(-z)ES( \201"zero" pixel values\202 switch is specified and +)BD(-i)ES( is not specified, then pixels having a zero value will +be output with their "VALUE" column set to zero. Obviously, this +switch does not make sense when individual events are output. + + + + +)0 2 19 H(funtbl)WB 82 Sn()WB 16 Sn( - extract a table from Funtools ASCII output)EA()EH( + + +)BD() 1 61 PR(funtable [-c cols] [-h] [-n table] [-p prog] [-s sep] )RP()ES( + + +)0 P([NB: This program has been deprecated in favor of the ASCII text processing +support in funtools. You can now perform fundisp on funtools ASCII output +files \201specifying the table using bracket notation\202 to extract tables +and columns.] + +The )BD(funtbl)ES( script extracts a specified table \201without the +header and comments\202 from a funtools ASCII output file and writes the +result to the standard output. The first non-switch argument is the +ASCII input file name \201i.e. the saved output from funcnts, fundisp, +funhist, etc.\202. If no filename is specified, stdin is read. The +-n switch specifies which table \201starting from 1\202 to extract. The +default is to extract the first table. The -c switch is a +space-delimited list of column numbers to output, e.g. -c "1 3 5" +will extract the first three odd-numbered columns. The default is to +extract all columns. The -s switch specifies the separator string to +put between columns. The default is a single space. The -h switch +specifies that column names should be added in a header line before +the data is output. Without the switch, no header is prepended. The +-p program switch allows you to specify an awk-like program to run +instead of the default \201which is host-specific and is determined at +build time\202. The -T switch will output the data in rdb format \201i.e., +with a 2-row header of column names and dashes, and with data columns +separated by tabs\202. The -help switch will print out a message +describing program usage. + +)0 P(For example, consider the output from the following funcnts command: +) 37 82 PR( [sh] funcnts -sr snr.ev "ann 512 512 0 9 n=3" + # source + # data file: /proj/rd/data/snr.ev + # arcsec/pixel: 8 + # background + # constant value: 0.000000 + # column units + # area: arcsec**2 + # surf_bri: cnts/arcsec**2 + # surf_err: cnts/arcsec**2 + + # summed background-subtracted results + upto net_counts error background berror area surf_bri surf_err + ---- ------------ --------- ------------ --------- --------- --------- --------- + 1 147.000 12.124 0.000 0.000 1600.00 0.092 0.008 + 2 625.000 25.000 0.000 0.000 6976.00 0.090 0.004 + 3 1442.000 37.974 0.000 0.000 15936.00 0.090 0.002 + + + # background-subtracted results + reg net_counts error background berror area surf_bri surf_err + ---- ------------ --------- ------------ --------- --------- --------- --------- + 1 147.000 12.124 0.000 0.000 1600.00 0.092 0.008 + 2 478.000 21.863 0.000 0.000 5376.00 0.089 0.004 + 3 817.000 28.583 0.000 0.000 8960.00 0.091 0.003 + + + # the following source and background components were used: + source_region\201s\202 + ---------------- + ann 512 512 0 9 n=3)WR( + + reg counts pixels sumcnts sumpix + ---- ------------ --------- ------------ --------- + 1 147.000 25 147.000 25 + 2 478.000 84 625.000 109 + 3 817.000 140 1442.000 249)RP( +)0 P(There are four tables in this output. To extract the last one, you +can execute: +) 4 60 PR( [sh] funcnts -s snr.ev "ann 512 512 0 9 n=3" | funtbl -n 4 + 1 147.000 25 147.000 25 + 2 478.000 84 625.000 109 + 3 817.000 140 1442.000 249)RP( +Note that the output has been re-formatted so that only a single space +separates each column, with no extraneous header or comment information. + +)0 P(To extract only columns 1,2, and 4 from the last example \201but with a header +prepended and tabs between columns\202, you can execute: +) 5 82 PR( [sh] funcnts -s snr.ev "ann 512 512 0 9 n=3" | funtbl -c "1 2 4" -h -n 4 -s "\200t" + #reg counts sumcnts + 1 147.000 147.000 + 2 478.000 625.000 + 3 817.000 1442.000)RP( +)0 P(Of course, if the output has previously been saved in a file named +foo.out, the same result can be obtained by executing: +) 5 48 PR( [sh] funtbl -c "1 2 4" -h -n 4 -s "\200t" foo.out + #reg counts sumcnts + 1 147.000 147.000 + 2 478.000 625.000 + 3 817.000 1442.000)RP( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +)0 P()0 0 1 A(Go to Funtools Help Index)0 0 TN TL()Ec /AF f D( + +)0 5 20 H(Last)WB 83 Sn( updated: April 1, 2007)EH( + +)WB NL +/Cb Db D /Ct [16#00 16#00 16#00] D /Cl [16#00 16#00 16#00] D /CL -1 D Ct Sc +DS +/Ba f D /BO 0 D Bs +/UR (ds9.html) D +/Ti (Funtools and DS9 Image Display) D +/Au () D +/Df f D +/ME [()] D + +0 BO R +()1 Sl()WB 17 Sn( + + +)0 2 21 H(FunDS9:)WB 85 Sn()WB 84 Sn( Funtools and DS9 Image Display)EA()EH( + + +)0 2 22 H(Summary)WB 86 Sn()EH( +Describes how funtools can be integrated into the ds9 Analysis menu. + + +)0 2 23 H(Description)WB 87 Sn()EH( +)0 P()R1 2 A(SAOImage/DS9)EA( is an astronomical imaging and data visualization +application used by astronomers around the world. DS9 can display +standard astronomical FITS images and binary tables, but also has +support for displaying raw array files, shared memory files, and data +files automatically retrieved via FTP and HTTP. Standard functional +capabilities include multiple frame buffers, colormap and region +manipulation, and many data scaling algorithms. DS9's advanced +features include TrueColor visuals, deep frame buffers, true +PostScript printing, and display of image mosaics. The program's +support of image tiling, "blinking", arbitrary zoom, rotation, and pan +is unparalleled in astronomy. It also has innovative support for +automatic retrieval and display of standard image data such as the +Digital Sky Survey \201using servers at SAO, StScI, or ESO\202. + +)0 P(DS9 can communicate with external programs such as Funtools using the +)R2 2 A(XPA)EA( +messaging system. In addition, programs can be integrated directly +into the DS9 GUI by means of a configurable Analysis menu. By +default, the DS9 Analysis menu contains algorithms deemed essential to +the core functions of DS9, e.g., display cross-cuts of data, +iso-intensity contours, and WCS grids. However, new programs can be +added to DS9 by creating a set-up file which can be loaded into DS9 +to reconfigure the Analysis menu. + +) 7 48 PR(The basic format of the analysis set-up file is: +)0 P( # + # Analysis command descriptions: + # menu label/description + # file templates for this command + # "menu" \201add to menu\202 |"bind" \201bind to key\202 + # analysis command line)RP( + +For example, the funcnts program can be specified in this way: +) 4 69 PR( Funcnts \201counts in source/bkgd regions; options: none\202 + * + menu + funcnts $filename $regions\201source,,\202 $regions\201background,,\202 | $text)RP( +As shown above, DS9 supports a macro facility to provide information +as well as task support to command lines. For example, the $regions +macro is expanded by DS9 to provide the current source and/or +background region to the analysis command. The $text macro is expanded +to generate a text window display. It also is possible to query for +parameters using a $param macro, plot data using a $plot macro, +etc. See the DS9 documentation for further details. + +)0 P(A set-up file called )0 2 A(funtools.ds9)EA( will +load some useful Funtools applications \201counts in regions, radial +profile, X-ray light curve and energy spectrum, 1D histogram\202 into the DS9 +Analysis menu \201version 2.1 and above\202. The file resides in the bin +directory where Funtools programs are installed. It can be manually +loaded into DS9 from the )BD(Load Analysis Commands ...)ES( option of +the )BD(Analysis)ES( menu. Alternatively, you can tell DS9 to load +this file automatically at start-up time by adding the pathname to the +)BD(Edit)ES(->)BD(Preferences)ES(->)BD(Analysis Menu)ES(->)BD(Analysis +File)ES( menu option. \201NB: make sure you select +)BD(Edit)ES(->)BD(Preferences)ES(->)BD(Save Preferences)ES( after setting +the pathname.\202 + +)0 P(The tasks in this setup file generally process the original disk-based +FITS file. Funcnts-based results \201radial profile, counts in regions\202 +are presented in WCS units, if present in the FITS header. For +situations where a disk file is not available \201e.g., image data +generated and sent to DS9's 'fits' XPA access point\202, versions of the +radial profile and counts in regions tasks also are also offered +utilizing DS9's internal image data. Results are presented in pixels. +Aside from the units, the results should be identical to the file-based +results. + + + + + +)0 P()0 0 1 A(Go to Funtools Help Index)0 0 TN TL()Ec /AF f D( + +)0 5 24 H(Last)WB 88 Sn( updated: November 16, 2005)EH( + +)WB NL +/Cb Db D /Ct [16#00 16#00 16#00] D /Cl [16#00 16#00 16#00] D /CL -1 D Ct Sc +DS +/Ba f D /BO 0 D Bs +/UR (library.html) D +/Ti (Funtools Programming) D +/Au () D +/Df f D +/ME [()] D + +0 BO R +()1 Sl()WB 18 Sn( + + +)0 2 25 H(FunLib:)WB 91 Sn()WB 89 Sn( the Funtools Programming Interface)EA()EH( + + +)0 2 26 H(Summary)WB 92 Sn()EH( +A description of the Funtools library. + + +)0 2 27 H(Introduction)WB 93 Sn()WB 90 Sn( to the Funtools Programming Interface)EH()EA( +)0 P(To create a Funtools application, you need to include +the funtools.h definitions file in your code: +) 1 23 PR( #include )RP( + +You then call Funtools subroutines and functions to access Funtools data. +The most important routines are: +)UL( +)0 P()-1 LI( )0 25 1 A(FunOpen)25 0 TN TL()Ec /AF f D(: open a Funtools file +)-1 LI()0 35 1 A(FunInfoGet)35 0 TN TL()Ec /AF f D(: get info about an image or table +)-1 LI()0 26 1 A(FunImageGet)26 0 TN TL()Ec /AF f D(: retrieve image data +)-1 LI()0 28 1 A(FunImageRowGet)28 0 TN TL()Ec /AF f D(: retrieve image data by row +)-1 LI()0 27 1 A(FunImagePut)27 0 TN TL()Ec /AF f D(: output image data +)-1 LI()0 29 1 A(FunImageRowPut)29 0 TN TL()Ec /AF f D(: output image data by row +)-1 LI()0 32 1 A(FunColumnSelect)32 0 TN TL()Ec /AF f D(: select columns in a table for access +)-1 LI()0 30 1 A(FunTableRowGet)30 0 TN TL()Ec /AF f D(: retrieve rows from a table +)-1 LI()0 31 1 A(FunTableRowPut)31 0 TN TL()Ec /AF f D(: output rows to a table +)-1 LI( )0 40 1 A(FunClose)40 0 TN TL()Ec /AF f D(: close a Funtools file)LU( + +Your program must be linked against the libfuntools.a library, +along with the math library. The following libraries also might be required +on your system: +)UL()-1 LI( -lsocket -lnsl for socket support +)-1 LI( -ldl for dynamic loading)LU( +)0 P(For example, on a Solaris system using gcc, use the following link line: +) 1 53 PR( gcc -o foo foo.c -lfuntools -lsocket -lnsl -ldl -lm)RP( +On a Solaris system using Solaris cc, use the following link line: +) 1 48 PR( gcc -o foo foo.c -lfuntools -lsocket -lnsl -lm)RP( +On a Linux system using gcc, use the following link line: +) 1 38 PR( gcc -o foo foo.c -lfuntools -ldl -lm)RP( +Once configure has built a Makefile on your platform, the required +"extra" libraries \201aside from -lm, which always is required\202 are +specified in that file's EXTRA_LIBS variable. For example, under +Linux you will find: +) 3 26 PR( grep EXTRA_LIBS Makefile + EXTRA_LIBS = -ldl + ...)RP( + +)0 P(The Funtools library contains both the zlib library +\201http://www.gzip.org/zlib/\202 and Doug Mink's WCS library +\201http://tdc-www.harvard.edu/software/wcstools/\202. It is not necessary +to put these libraries on a Funtools link line. Include files +necessary for using these libraries are installed in the Funtools +include directory. + +)0 2 28 H(Funtools)WB 94 Sn()WB 20 Sn( Programming Tutorial)EA()EH( + +The +)0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D( +function is used to open a FITS file, an array, or a raw event file: +) 4 79 PR( /* open the input FITS file for reading */ + ifun = FunOpen\201iname, "r", NULL\202; + /* open the output FITS file for writing, and connect it to the input file */ + ofun = FunOpen\201iname, "w", ifun\202;)RP( +A new output file can inherit header parameters automatically from +existing input file by passing the input Funtools handle as the last +argument to the new file's +)0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D( +call as shown above. + +)0 P(For image data, you then can call +)0 26 1 A(FunImageGet\201\202)26 0 TN TL()Ec /AF f D( +to read an image into memory. +) 3 61 PR( float buf=NULL; + /* extract and bin the data section into an image buffer */ + buf = FunImageGet\201fun, NULL, "bitpix=-32"\202;)RP( +If the \201second\202 buf argument to this call is NULL, buffer space is allocated +automatically. The \201third\202 plist argument can be used to specify the +return data type of the array. If NULL is specified, the data type of +the input file is used. + +)0 P(To process an image buffer, you would generally make a call to +)0 35 1 A(FunInfoGet\201\202)35 0 TN TL()Ec /AF f D( to determine the +dimensions of the image \201which may have been changed from the original +file dimensions due to )0 49 1 A(Funtools image +sectioning)49 0 TN TL()Ec /AF f D( on the command line\202. In a FITS image, the index along +the dim1 axis varies most rapidly, followed by the dim2 axis, etc. +Thus, to access each pixel in an 2D image, use a double loop such as:)RP( + buf = FunImageGet\201fun, NULL, "bitpix=-32"\202; + FunInfoGet\201fun, FUN_SECT_DIM1, &dim1, FUN_SECT_DIM2, &dim2, 0\202; + for\201i=1; i<=dim2; i++\202{ + for\201j=1; j<=dim1; j++\202{ + ... process buf[\201\201i-1\202*dim1\202+\201j-1\202] ... + } + })RP( +or: +) 5 65 PR( buf = FunImageGet\201fun, NULL, "bitpix=-32"\202; + FunInfoGet\201fun, FUN_SECT_DIM1, &dim1, FUN_SECT_DIM2, &dim2, 0\202; + for\201i=0; i<\201dim1*dim2\202; i++\202{ + ... process buf[i] ... + })RP( +Finally, you can write the resulting image to disk using +)0 27 1 A(FunImagePut\201\202)27 0 TN TL()Ec /AF f D(: +) 1 48 PR( FunImagePut\201fun2, buf, dim1, dim2, -32, NULL\202;)RP( +Note that Funtools automatically takes care of book-keeping tasks such as +reading and writing FITS headers \201although you can, of course, write +your own header or add your own parameters to a header\202. + +)0 P(For binary tables and raw event files, a call to +)0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D( +will be followed by a call to the +)0 32 1 A(FunColumnSelect\201\202)32 0 TN TL()Ec /AF f D( +routine to select columns to be read from the input file and/or +written to the output file: + +) 8 69 PR( typedef struct evstruct{ + double time; + int time2; + } *Ev, EvRec; + FunColumnSelect\201fun, sizeof\201EvRec\202, NULL, + "time", "D", "rw", FUN_OFFSET\201Ev, time\202, + "time2", "J", "w", FUN_OFFSET\201Ev, time2\202, + NULL\202;)RP( +Columns whose \201third\202 mode argument contains an "r" are "readable", +i.e., columns will be read from the input file and converted into the +data type specified in the call's second argument. These columns +values then are stored in the specified offset of the user record +structure. Columns whose mode argument contains a "w" are +"writable", i.e., these values will be written to the output file. +The +)0 32 1 A(FunColumnSelect\201\202)32 0 TN TL()Ec /AF f D( +routine also offers the option of automatically merging user +columns with the original input columns when writing the output +rows. + +)0 P(Once a set of columns has been specified, you can retrieve rows using +)0 30 1 A(FunTableRowGet\201\202)30 0 TN TL()Ec /AF f D(, +and write the rows using +)0 31 1 A(FunTableRowPut\201\202)31 0 TN TL()Ec /AF f D(: +) 17 70 PR( Ev ebuf, ev; + /* get rows -- let routine allocate the array */ + while\201 \201ebuf = \201Ev\202FunTableRowGet\201fun, NULL, MAXROW, NULL, &got\202\202 \202{ + /* process all rows */ + for\201i=0; itime2 = \201int\202\201ev->time+.5\202; + /* change the input time as well */ + ev->time = -\201ev->time/10.0\202; + } + /* write out this batch of rows with the new column */ + FunTableRowPut\201fun2, \201char *\202ebuf, got, 0, NULL\202; + /* free row data */ + if\201 ebuf \202 free\201ebuf\202; + })RP( +The input rows are retrieved into an array of user structs, which +can be accessed serially as shown above. Once again, Funtools +automatically takes care of book-keeping tasks such as reading and writing +FITS headers \201although you can, of course, write your own header or +add your own parameters to a header\202. + +)0 P(When all processing is done, you can call +)0 40 1 A(FunClose\201\202)40 0 TN TL()Ec /AF f D( +to close the file\201s\202: +) 2 17 PR( FunClose\201fun2\202; + FunClose\201fun\202;)RP( + +)0 P(These are the basics of processing FITS files \201and arrays or raw event +data\202 using Funtools. The routines in these examples are described in +more detail below, along with a few other routines that support +parameter access, data flushing, etc. + +)0 2 29 H(Compiling)WB 95 Sn()WB 22 Sn( and Linking)EA()EH( +)0 P(To create a Funtools application, a software developer will include +the funtools.h definitions file in Funtools code: +) 1 23 PR( #include )RP( +The program is linked against the libfuntools.a library, along with the +math library \201and the dynamic load library, if the latter is available +on your system\202: +) 1 38 PR( gcc -o foo foo.c -lfuntools -ldl -lm)RP( +)0 P(If gcc is used, Funtools filtering can be performed using dynamically +loaded shared objects that are built at run-time. Otherwise, filtering +is performed using a slave process. +)0 P(Funtools has been built on the following systems: +)UL()-1 LI( Sun/Solaris 5.X +)-1 LI( Linux/RedHat Linux 5.X,6.X,7.X +)-1 LI( Dec Alpha/OSF1 V4.X +)-1 LI( WindowsNT/Cygwin 1.0 +)-1 LI( SGI/IRIX64 6.5)LU( + +)0 2 30 H(A)WB 96 Sn()WB 21 Sn( Short Digression on Subroutine Order)EA()EH( +)0 P(There is a natural order for all I/O access libraries. You would not +think of reading a file without first opening it, or writing a file +after closing it. A large part of the experiment in funtools is to use +the idea of "natural order" as a means of making programming +easier. We do this by maintaining the state of processing for a given +funtools file, so that we can do things like write headers and flush +extension padding at the right time, without you having to do it. + +)0 P(For example, if you open a new funtools file for writing using +)0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D(, +then generate an array of image data and call +)0 27 1 A(FunImagePut\201\202)27 0 TN TL()Ec /AF f D(, +funtools knows to write the image header automatically. +There is no need to think about writing a standard header. +Of course, you can add parameters to the file first by +calling one of the +)0 38 1 A(FunParamPut\201\202)38 0 TN TL()Ec /AF f D( +routines, and these parameters will automatically be added +to the header when it is written out. There still is no +need to write the header explicitly. + +)0 P(Maintaining state in this way means that there are certain rules of +order which should be maintained in any funtools program. In particular, +we strongly recommend the following ordering rules be adhered to: + +)UL()-1 LI( When specifying that input extensions be copied to an output file +via a reference handle, open the output file )BD(before)ES( reading the +input file. \201Otherwise the initial copy will not occur\202. + +)-1 LI( Always write parameters to an output file using one of the +)0 38 1 A(FunParamPut\201\202)38 0 TN TL()Ec /AF f D( calls +)BD(before)ES( writing any data. \201This is a good idea for all FITS +libraries, to avoid having to recopy data is the FITS header needs +to be extended by adding a single parameter.\202 + +)-1 LI( If you retrieve an image, and need to know the data +type, use the FUN_SECT_BITPIX option of +)0 35 1 A(FunInfoGet\201\202)35 0 TN TL()Ec /AF f D(, +)BD(after)ES( calling +)0 26 1 A(FunImageGet\201\202)26 0 TN TL()Ec /AF f D(, since +it is possible to change the value of BITPIX from the latter. + +)-1 LI( When specifying that input extensions be copied to an output file +via a reference handle, close the output file )BD(before)ES( closing +input file, or else use +)0 39 1 A(FunFlush\201\202)39 0 TN TL()Ec /AF f D( +explicitly on the output file +)BD(before)ES( closing the input file. \201Otherwise the final copy will +not occur\202.)LU( + +)0 P(We believe that these are the natural rules that are implied in most +FITS programming tasks. However, we recognize that making explicit use +of "natural order" to decide what automatic action to take on behalf +of the programmer is experimental. Therefore, if you find that your +needs are not compatible with our preferred order, please let us know +-- it will be most illuminating for us as we evaluate this experiment. + +)0 2 31 H(Funtools)WB 97 Sn()WB 41 Sn( Programming Examples)EA()EH( +)0 P(The following complete coding examples are provided to illustrate the +simplicity of Funtools applications. They can be found in the funtest +subdirectory of the Funtools distribution. In many cases, you should +be able to modify one of these programs to generate your own Funtools +program: +)UL()-1 LI()0 2 A(evread.c)EA(: read and write binary tables +)-1 LI()0 2 A(evcols.c)EA(: add column and rows to binary tables +)-1 LI()0 2 A(evmerge.c)EA(: merge new columns with existing columns +)-1 LI()0 2 A(evnext.c)EA(: manipulate raw data pointers +)-1 LI()0 2 A(imblank.c)EA(: blank out image values below a threshold +)-1 LI()0 2 A(asc2fits.c)EA(: convert a specific ASCII table to FITS binary table)LU( + +)0 2 32 H(The)WB 98 Sn()WB 24 Sn( Funtools Programming Reference Manual)EA()EH( +)0 P() 45 116 PR(#include + +Fun )0 25 1 A(FunOpen\201char *name, char *mode, Fun ref\202)25 0 TN TL()Ec /AF f D( + +void *)0 26 1 A(FunImageGet\201Fun fun, void *buf, char *plist\202)26 0 TN TL()Ec /AF f D( + +int )0 27 1 A(FunImagePut\201Fun fun, void *buf, int dim1, int dim2, int bitpix, char *plist\202)27 0 TN TL()Ec /AF f D( + +void * )0 28 1 A(FunImageRowGet\201Fun fun, void *buf, int rstart, int rstop, char *plist\202)28 0 TN TL()Ec /AF f D( + +void * )0 29 1 A(FunImageRowPut\201Fun fun, void *buf, int rstart, int rstop, int dim1, int dim2, int bitpix, char *plist\202)29 0 TN TL()Ec /AF f D( + +int )0 32 1 A(FunColumnSelect\201Fun fun, int size, char *plist, ...\202)32 0 TN TL()Ec /AF f D( + +void )0 33 1 A(FunColumnActivate\201Fun fun, char *s, char *plist\202)33 0 TN TL()Ec /AF f D( + +int )0 34 1 A(FunColumnLookup\201Fun fun, char *s, int which, char **name, int *type, int *mode, int *offset, int *n, int *width\202)34 0 TN TL()Ec /AF f D( + +void *)0 30 1 A(FunTableRowGet\201Fun fun, void *rows, int maxrow, char *plist, int *nrow\202)30 0 TN TL()Ec /AF f D( + +int )0 31 1 A(FunTableRowPut\201Fun fun, void *rows, int nev, int idx, char *plist\202)31 0 TN TL()Ec /AF f D( + +int )0 37 1 A(FunParamGetb\201Fun fun, char *name, int n, int defval, int *got\202)37 0 TN TL()Ec /AF f D( + +int )0 37 1 A(FunParamGeti\201Fun fun, char *name, int n, int defval, int *got\202)37 0 TN TL()Ec /AF f D( + +double )0 37 1 A(FunParamGetd\201Fun fun, char *name, int n, double defval, int *got\202)37 0 TN TL()Ec /AF f D( + +char *)0 37 1 A(FunParamGets\201Fun fun, char *name, int n, char *defval, int *got\202)37 0 TN TL()Ec /AF f D( + +int )0 38 1 A(FunParamPutb\201Fun fun, char *name, int n, int value, char *comm, int append\202)38 0 TN TL()Ec /AF f D()WR( + +int )0 38 1 A(FunParamPuti\201Fun fun, char *name, int n, int value, char *comm, int append\202)38 0 TN TL()Ec /AF f D( + +int )0 38 1 A(FunParamPutd\201Fun fun, char *name, int n, double value, int prec, char *comm, int append\202)38 0 TN TL()Ec /AF f D( + +int )0 38 1 A(FunParamPuts\201Fun fun, char *name, int n, char *value, char *comm, int append\202)38 0 TN TL()Ec /AF f D( + +int )0 35 1 A(FunInfoGet\201Fun fun, int type, ...\202)35 0 TN TL()Ec /AF f D( + +int )0 36 1 A(FunInfoPut\201Fun fun, int type, ...\202)36 0 TN TL()Ec /AF f D( + +void )0 39 1 A(FunFlush\201Fun fun, char *plist\202)39 0 TN TL()Ec /AF f D( + +void )0 40 1 A(FunClose\201Fun fun\202)40 0 TN TL()Ec /AF f D()RP( + + + + +)0 2 33 H(FunOpen)WB 99 Sn()WB 25 Sn( - open a Funtools data file)EA()EH( + + +)BD() 3 47 PR( #include + + Fun FunOpen\201char *name, char *mode, Fun ref\202;)RP()ES( + + +)0 P(The )BD(FunOpen\201\202)ES( routine opens a Funtools data file for reading or +appending, or creates a new FITS file for writing. The )BD(name)ES( +argument specifies the name of the Funtools data file to open. You can +use IRAF-style bracket notation to specify +)0 42 1 A(Funtools Files, Extensions, and Filters)42 0 TN TL()Ec /AF f D(. +A separate call should be made each time a different FITS extension is +accessed: +) 7 65 PR( Fun fun; + char *iname; + ... + if\201 !\201fun = FunOpen\201iname, "r", NULL\202\202 \202{ + fprintf\201stderr, "could not FunOpen input file: %s\200n", iname\202; + exit\2011\202; + })RP( +)0 P(If )BD(mode)ES( is "r", the file is opened for reading, and processing +is set up to begin at the specified extension. For reading, +)BD(name)ES( can be )BD(stdin)ES(, in which case the standard input is read. + +)0 P(If )BD(mode)ES( is "w", the file is created if it does not exist, or +opened and truncated for writing if it does exist. Processing starts +at the beginning of the file. The )BD(name)ES( can be )BD(stdout)ES(, +in which case the standard output is readied for processing. + +)0 P(If )BD(mode)ES( is "a", the file is created if it does not exist, or +opened if it does exist. Processing starts at the end of the file. +The )BD(name)ES( can be )BD(stdout)ES(, in which case the standard +output is readied for processing. + +)0 P(When a Funtools file is opened for writing or appending, a previously +opened )0 23 1 A(Funtools reference +handle)23 0 TN TL()Ec /AF f D( can be specified as the third argument. This handle +typically is associated with the input Funtools file that will be used +to generate the data for the output data. When a reference file is +specified in this way, the output file will inherit the \201extension\202 +header parameters from the input file: +) 8 67 PR( Fun fun, fun2; + ... + /* open input file */ + if\201 !\201fun = FunOpen\201argv[1], "r", NULL\202\202 \202 + gerror\201stderr, "could not FunOpen input file: %s\200n", argv[1]\202; + /* open the output FITS image, inheriting params from input */ + if\201 !\201fun2 = FunOpen\201argv[2], "w", fun\202\202 \202 + gerror\201stderr, "could not FunOpen output file: %s\200n", argv[2]\202;)RP( +Thus, in the above example, the output FITS binary table file will +inherit all of the parameters associated with the input binary table +extension. +)0 P(A file opened for writing with a +)0 23 1 A(Funtools reference handle)23 0 TN TL()Ec /AF f D( also +inherits the selected columns \201i.e. those columns chosen for +processing using the +)0 32 1 A(FunColumnSelect\201\202)32 0 TN TL()Ec /AF f D( routine\202 +from the reference file as its default columns. This makes it easy to +open an output file in such a way that the columns written to the +output file are the same as the columns read in the input file. Of +course, column selection can easily be tailored using the +)0 32 1 A(FunColumnSelect\201\202)32 0 TN TL()Ec /AF f D( routine. +In particular, it is easy to merge user-defined columns with the input +columns to generate a new file. See the +)0 2 A(evmerge)EA( for a complete example. + +)0 P(In addition, when a +)0 23 1 A(Funtools reference handle)23 0 TN TL()Ec /AF f D( +is supplied in a )0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D( call, +it is possible also to specify that all other extensions from the +reference file \201other than the input extension being processed\202 should +be copied from the reference file to the output file. This is useful, +for example, in a case where you are processing a FITS binary table +or image and you want to copy all of the other extensions to +the output file as well. Copy of other extensions is controlled by +adding a "C" or "c" to the mode string of the +)0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D( call )BD(of the input +reference file)ES(. If "C" is specified, then other extensions are +)BD(always)ES( copied \201i.e., copy is forced by the application\202. If +"c" is used, then other extensions are copied if the user requests +copying by adding a plus sign "+" to the extension name in the bracket +specification. For example, the )BD(funtable)ES( program utilizes +"c" mode, giving users the option of copying all other extensions: +) 6 67 PR( /* open input file -- allow user copy of other extensions */ + if\201 !\201fun = FunOpen\201argv[1], "rc", NULL\202\202 \202 + gerror\201stderr, "could not FunOpen input file: %s\200n", argv[1]\202; + /* open the output FITS image, inheriting params from input */ + if\201 !\201fun2 = FunOpen\201argv[2], "w", fun\202\202 \202 + gerror\201stderr, "could not FunOpen output file: %s\200n", argv[2]\202;)RP( + +Thus, )BD(funtable)ES( supports either of these command lines: +) 4 60 PR( # copy only the EVENTS extension + csh> funtable "test.ev[EVENTS,circle\201512,512,10\202]" foo.ev + # copy ALL extensions + csh> funtable "test.ev[EVENTS+,circle\201512,512,10\202]" foo.ev)RP( + +)0 P(Use of a )0 23 1 A(Funtools reference +handle)23 0 TN TL()Ec /AF f D( implies that the input file is opened before the output +file. However, it is important to note that if copy mode \201"c" or "C"\202 +is specified for the input file, the actual input file open is delayed +until just after the output file is opened, since the copy of prior +extensions to the output file takes place while Funtools is seeking to +the specified input extension. This implies that the output file +should be opened before any I/O is done on the input file or else the +copy will fail. Note also that the copy of subsequent extension will +be handled automatically by +)0 40 1 A(FunClose\201\202)40 0 TN TL()Ec /AF f D( +if the output file is +closed before the input file. Alternatively, it can be done explicitly +by )0 39 1 A(FunFlush\201\202)39 0 TN TL()Ec /AF f D(, but again, this +assumes that the input file still is open. + +)0 P(Upon success )0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D( returns a +Fun handle that is used in subsequent Funtools calls. On error, NULL +is returned. + + + + +)0 2 34 H(FunImageGet)WB 100 Sn()WB 26 Sn( - get an image or image section)EA()EH( + + +)BD() 3 52 PR( #include + + void *FunImageGet\201Fun fun, void *buf, char *plist\202)RP()ES( + + +)0 P(The )BD(FunImageGet\201\202)ES( routine returns an binned image array of the +specified section of a Funtools data file. If the input data are +already of type image, the array is generated by extracting the +specified image section and then binning it according to the specified +bin factor. If the input data are contained in a binary table or raw +event file, the rows are binned on the columns specified by the +)BD(bincols=)ES( keyword \201using appropriate default columns as +necessary\202, after which the image section and bin factors are +applied. In both cases, the data is automatically converted from FITS +to native format, if necessary. +)0 P(The first argument is the Funtools handle returned by +)0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D(. The second )BD(buf)ES( +argument is a pointer to a data buffer to fill. If NULL is specified, +FunImageGet will allocate a buffer of the appropriate size. Generally +speaking, you always want Funtools to allocate the buffer because +the image dimensions will be determined by +)0 49 1 A(Funtools image sectioning)49 0 TN TL()Ec /AF f D( +on the command line. +)0 P(The third )BD(plist)ES( \201i.e., parameter list\202 argument is a string +containing one or more comma-delimited )BD(keyword=value)ES( +parameters. It can be used to specify the return data type using the +)BD(bitpix=)ES( keyword. If no such keyword is specified in the plist +string, the data type of the returned image is the same as the data type +of the original input file, or is of type int for FITS binary tables. + +)0 P(If the )BD(bitpix=)ES( keyword is supplied in the plist string, the data +type of the returned image will be one of the supported FITS image +data types: +)UL()-1 LI( 8 unsigned char +)-1 LI( 16 short +)-1 LI( 32 int +)-1 LI( -32 float +)-1 LI( -64 double)LU( +For example: +) 4 57 PR( void *buf; + /* extract data section into an image buffer */ + if\201 !\201buf = FunImageGet\201fun, NULL, NULL\202\202 \202 + gerror\201stderr, "could not FunImageGet: %s\200n", iname\202;)RP( +will allocate buf and retrieve the image in the file data format. In +this case, you will have to determine the data type \201using the +FUN_SECT_BITPIX value in the +)0 35 1 A(FunInfoGet\201\202)35 0 TN TL()Ec /AF f D( +routine\202 +and then use a switch statement to process each data type: +) 17 65 PR( int bitpix; + void *buf; + unsigned char *cbuf; + short *sbuf; + int *ibuf; + ... + buf = FunImageGet\201fun, NULL, NULL\202; + FunInfoGet\201fun, FUN_SECT_BITPIX, &bitpix, 0\202; + /* set appropriate data type buffer to point to image buffer */ + switch\201bitpix\202{ + case 8: + cbuf = \201unsigned char *\202buf; break; + case 16: + sbuf = \201short *\202buf; break; + case 32: + ibuf = \201int *\202buf; break; + ...)RP( +See the +)0 2 A(imblank example code)EA( +for more details on how to process an image when the data type is not +specified beforehand. + +)0 P(It often is easier to specify the data type directly: +) 4 57 PR( double *buf; + /* extract data section into a double image buffer */ + if\201 !\201buf = FunImageGet\201fun, NULL, "bitpix=-64"\202\202 \202 + gerror\201stderr, "could not FunImageGet: %s\200n", iname\202;)RP( +will extract the image while converting to type double. + +)0 P(On success, a pointer to the image buffer is returned. \201This will be +the same as the second argument, if NULL is not passed to the latter.\202 +On error, NULL is returned. + +)0 P(In summary, to retrieve image or row data into a binned image, you simply +call FunOpen\201\202 followed by +)0 26 1 A(FunImageGet\201\202)26 0 TN TL()Ec /AF f D(. Generally, you +then will want to call +)0 35 1 A(FunInfoGet\201\202)35 0 TN TL()Ec /AF f D( +to retrieve the +axis dimensions \201and data type\202 of the section you are processing +\201so as to take account of sectioning and blocking of the original data\202: +) 20 73 PR( double *buf; + int i, j; + int dim1, dim2; + ... other declarations, etc. + + /* open the input FITS file */ + if\201 !\201fun = FunOpen\201argv[1], "rc", NULL\202\202 \202 + gerror\201stderr, "could not FunOpen input file: %s\200n", argv[1]\202; + + /* extract and bin the data section into a double float image buffer */ + if\201 !\201buf = FunImageGet\201fun, NULL, "bitpix=-64"\202\202 \202 + gerror\201stderr, "could not FunImageGet: %s\200n", argv[1]\202; + + /* get dimension information from funtools structure */ + FunInfoGet\201fun, FUN_SECT_DIM1, &dim1, FUN_SECT_DIM2, &dim2, 0\202; + + /* loop through pixels and reset values below limit to value */ + for\201i=0; i + + int FunImagePut\201Fun fun, void *buf, int dim1, int dim2, int bitpix, + char *plist\202)RP()ES( + + +The )BD(FunImagePut\201\202)ES( routine outputs an image array to a FITS +file. The image is written either as a primary header/data unit or as +an image extension, depending on whether other data have already been +written to the file. That is, if the current file position is at the +beginning of the file, a primary HDU is written. Otherwise, an +image extension is written. + +)0 P(The first argument is the Funtools handle returned by +)0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D(. The second )BD(buf)ES( +argument is a pointer to a data buffer to write. The )BD(dim1)ES(and +)BD(dim2)ES( arguments that follow specify the dimensions of the image, +where dim1 corresponds to naxis1 and dim2 corresponds to naxis2. The +)BD(bitpix)ES( argument specifies the data type of the image and can +have the following FITS-standard values: +)UL()-1 LI( 8 unsigned char +)-1 LI( 16 short +)-1 LI( 32 int +)-1 LI( -32 float +)-1 LI( -64 double)LU( + +)0 P(When )0 31 1 A(FunTableRowPut\201\202)31 0 TN TL()Ec /AF f D( is first +called for a given image, Funtools checks to see if the primary header +has already been written \201by having previously written an image or a +binary table.\202 If not, this image is written to the primary HDU. +Otherwise, it is written to an image extension. +)0 P(Thus, a simple program to generate a FITS image might look like this: +) 16 67 PR( int i; + int dim1=512, dim2=512; + double *dbuf; + Fun fun; + dbuf = malloc\201dim1*dim2*sizeof\201double\202\202; + /* open the output FITS image, preparing to copy input params */ + if\201 !\201fun = FunOpen\201argv[1], "w", NULL\202\202 \202 + gerror\201stderr, "could not FunOpen output file: %s\200n", argv[1]\202; + for\201i=0; i<\201dim1*dim2\202; i++\202{ + ... fill dbuf ... + } + /* put the image \201header will be generated automatically */ + if\201 !FunImagePut\201fun, buf, dim1, dim2, -64, NULL\202 \202 + gerror\201stderr, "could not FunImagePut: %s\200n", argv[1]\202; + FunClose\201fun\202; + free\201dbuf\202;)RP( + +)0 P(In addition, if a +)0 23 1 A(Funtools reference handle)23 0 TN TL()Ec /AF f D( +was specified when this table was opened, the +parameters from this +)0 23 1 A(Funtools reference handle)23 0 TN TL()Ec /AF f D( +are merged into the new image +header. Furthermore, if a reference image was specified during +)0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D(, the values of +)BD(dim1)ES(, )BD(dim2)ES(, and )BD(bitpix)ES( in the calling sequence +can all be set to 0. In this case, default values are taken from the +reference image section. This is useful if you are reading an image +section in its native data format, processing it, and then writing +that section to a new FITS file. See the +)0 2 A(imblank example code)EA(. + +)0 P(The data are assumed to be in the native machine format and will +automatically be swapped to FITS big-endian format if necessary. This +behavior can be over-ridden with the )BD(convert=[true|false])ES( +keyword in the )BD(plist)ES( param list string. + +)0 P(When you are finished writing the image, you should call +)0 39 1 A(FunFlush\201\202)39 0 TN TL()Ec /AF f D( to write out the FITS +image padding. However, this is not necessary if you subsequently call +FunClose\201\202 without doing any other I/O to the FITS file. + + + + +)0 2 36 H(FunImageRowGet)WB 102 Sn()WB 28 Sn( - get row\201s\202 of an image)EA()EH( + + +)BD() 4 65 PR( #include + + void *FunImageRowGet\201Fun fun, void *buf, int rstart, int rstop, + char *plist\202)RP()ES( + + +)0 P(The )BD(FunImageRowGet\201\202)ES( routine returns one or more image rows +from the specified section of a Funtools data file. If the input data +are of type image, the array is generated by extracting the specified +image rows and then binning them according to the specified bin +factor. If the input data are contained in a binary table or raw +event file, the rows are binned on the columns specified by the +)BD(bincols=)ES( keyword \201using appropriate default columns as needed\202, +after which the image section and bin factors are applied. + +)0 P(The first argument is the Funtools handle returned by +)0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D(. The second )BD(buf)ES( +argument is a pointer to a data buffer to fill. If NULL is specified, +FunImageGet\201\202 will allocate a buffer of the appropriate size. + +)0 P(The third and fourth arguments specify the first and last row to +retrieve. Rows are counted starting from 1, up to the value of +FUN_YMAX\201fun\202. The final )BD(plist)ES( \201i.e., parameter list\202 argument +is a string containing one or more comma-delimited +)BD(keyword=value)ES( parameters. It can be used to specify the return +data type using the )BD(bitpix=)ES( keyword. If no such keyword is +specified in the plist string, the data type of the image is the same +as the data type of the original input file, or is of type int for +FITS binary tables. + +)0 P(If the )BD(bitpix=)ES(value is supplied in the plist string, the data +type of the returned image will be one of the supported FITS image +data types: +)UL()-1 LI( 8 unsigned char +)-1 LI( 16 short +)-1 LI( 32 int +)-1 LI( -32 float +)-1 LI( -64 double)LU( + +)0 P(For example: +) 17 65 PR( double *drow; + Fun fun; + ... open files ... + /* get section dimensions */ + FunInfoGet\201fun, FUN_SECT_DIM1, &dim1, FUN_SECT_DIM2, &dim2, 0\202; + /* allocate one line's worth */ + drow = malloc\201dim1*sizeof\201double\202\202; + /* retrieve and process each input row \201starting at 1\202 */ + for\201i=1; i <= dim2; i++\202{ + if\201 !FunImageRowGet\201fun, drow, i, i, "bitpix=-64"\202 \202 + gerror\201stderr, "can't FunImageRowGet: %d %s\200n", i, iname\202; + /* reverse the line */ + for\201j=1; j<=dim1; j++\202{ + ... process drow[j-1] ... + } + } + ...)RP( + +)0 P(On success, a pointer to the image buffer is returned. \201This will be +the same as the second argument, if NULL is not passed to the latter.\202 +On error, NULL is returned. Note that the considerations described +above for specifying binning columns in +)0 26 1 A(FunImageGet\201\202)26 0 TN TL()Ec /AF f D( also apply to +)BD(FunImageRowGet\201\202)ES(. + + + + +)0 2 37 H(FunImageRowPut)WB 103 Sn()WB 29 Sn( - put row\201s\202 of an image)EA()EH( + + +)BD() 4 67 PR( #include + + void *FunImageRowPut\201Fun fun, void *buf, int rstart, int rstop, + int dim1, int dim2, int bitpix, char *plist\202)RP()ES( + + +)0 P(The )BD(FunImageRowPut\201\202)ES( routine writes one or more image rows to +the specified FITS image file. The first argument is the Funtools +handle returned by )0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D(. +The second )BD(buf)ES( argument is a pointer to the row data buffer, +while the third and fourth arguments specify the starting and ending +rows to write. Valid rows values range from 1 to dim2, i.e., row is +one-valued. + +)0 P(The )BD(dim1)ES(and )BD(dim2)ES( arguments that follow specify the +dimensions, where dim1 corresponds to naxis1 and dim2 corresponds to +naxis2. The )BD(bitpix)ES( argument data type of the image and can +have the following FITS-standard values: +)UL()-1 LI( 8 unsigned char +)-1 LI( 16 short +)-1 LI( 32 int +)-1 LI( -32 float +)-1 LI( -64 double)LU( + +For example: +) 16 65 PR( double *drow; + Fun fun, fun2; + ... open files ... + /* get section dimensions */ + FunInfoGet\201fun, FUN_SECT_DIM1, &dim1, FUN_SECT_DIM2, &dim2, 0\202; + /* allocate one line's worth */ + drow = malloc\201dim1*sizeof\201double\202\202; + /* retrieve and process each input row \201starting at 1\202 */ + for\201i=1; i <= dim2; i++\202{ + if\201 !FunImageRowGet\201fun, drow, i, i, "bitpix=-64"\202 \202 + gerror\201stderr, "can't FunImageRowGet: %d %s\200n", i, iname\202; + ... process drow ... + if\201 !FunImageRowPut\201fun2, drow, i, i, 64, NULL\202 \202 + gerror\201stderr, "can't FunImageRowPut: %d %s\200n", i, oname\202; + } + ...)RP( + +)0 P(The data are assumed to be in the native machine format and will +automatically be swapped to big-endian FITS format if necessary. This +behavior can be over-ridden with the )BD(convert=[true|false])ES( +keyword in the )BD(plist)ES( param list string. + +)0 P(When you are finished writing the image, you should call +)0 39 1 A(FunFlush\201\202)39 0 TN TL()Ec /AF f D( to write out the FITS +image padding. However, this is not necessary if you subsequently call +FunClose\201\202 without doing any other I/O to the FITS file. + + + + +)0 2 38 H(FunColumnSelect)WB 104 Sn()WB 32 Sn( - select Funtools columns)EA()EH( + +)BD() 11 73 PR( #include + + int FunColumnSelect\201Fun fun, int size, char *plist, + char *name1, char *type1, char *mode1, int offset1, + char *name2, char *type2, char *mode2, int offset2, + ..., + NULL\202 + + int FunColumnSelectArr\201Fun fun, int size, char *plist, + char **names, char **types, char **modes, + int *offsets, int nargs\202;)RP()ES( + + +The )BD(FunColumnSelect\201\202)ES( routine is used to select the columns +from a Funtools binary table extension or raw event file for +processing. This routine allows you to specify how columns in a file +are to be read into a user record structure or written from a user +record structure to an output FITS file. + +)0 P(The first argument is the Fun handle associated with this set of +columns. The second argument specifies the size of the user record +structure into which columns will be read. Typically, the sizeof\201\202 +macro is used to specify the size of a record structure. The third +argument allows you to specify keyword directives for the selection +and is described in more detail below. + +)0 P(Following the first three required arguments is a variable length list of +column specifications. Each column specification will consist of four +arguments: +)UL()-1 LI( )BD(name)ES(: the name of the column + +)-1 LI( )BD(type)ES(: the data type of the column as it will be stored in +the user record struct \201not the data type of the input file\202. The +following basic data types are recognized: +)UL()-1 LI(A: ASCII characters +)-1 LI(B: unsigned 8-bit char +)-1 LI(I: signed 16-bit int +)-1 LI(U: unsigned 16-bit int \201not standard FITS\202 +)-1 LI(J: signed 32-bit int +)-1 LI(V: unsigned 32-bit int \201not standard FITS\202 +)-1 LI(E: 32-bit float +)-1 LI(D: 64-bit float)LU( +The syntax used is similar to that which defines the TFORM parameter +in FITS binary tables. That is, a numeric repeat value can precede +the type character, so that "10I" means a vector of 10 short ints, "E" +means a single precision float, etc. Note that the column value from +the input file will be converted to the specified data type as the +data is read by +)0 30 1 A(FunTableRowGet\201\202)30 0 TN TL()Ec /AF f D(. + +)0 P([ A short digression regarding bit-fields: Special attention is +required when reading or writing the FITS bit-field type +\201"X"\202. Bit-fields almost always have a numeric repeat character +preceding the 'X' specification. Usually this value is a multiple of 8 +so that bit-fields fit into an integral number of bytes. For all +cases, the byte size of the bit-field B is \201N+7\202/8, where N is the +numeric repeat character. + +)0 P(A bit-field is most easily declared in the user struct as an array of +type char of size B as defined above. In this case, bytes are simply +moved from the file to the user space. If, instead, a short or int +scalar or array is used, then the algorithm for reading the bit-field +into the user space depends on the size of the data type used along +with the value of the repeat character. That is, if the user data +size is equal to the byte size of the bit-field, then the data is +simply moved \201possibly with endian-based byte-swapping\202 from one to +the other. If, on the other hand, the data storage is larger than the +bit-field size, then a data type cast conversion is performed to move +parts of the bit-field into elements of the array. Examples will help +make this clear: + +)UL()-1 LI( If the file contains a 16X bit-field and user space specifies a 2B +char array[2], then the bit-field is moved directly into the char array. + +)-1 LI( If the file contains a 16X bit-field and user space specifies a 1I +scalar short int, then the bit-field is moved directly into the short int. + +)-1 LI( If the file contains a 16X bit-field and user space specifies a 1J +scalar int, then the bit-field is type-cast to unsigned int before +being moved \201use of unsigned avoids possible sign extension\202. + +)-1 LI( If the file contains a 16X bit-field and user space specifies a 2J +int array[2], then the bit-field is handled as 2 chars, each of which +are type-cast to unsigned int before being moved \201use of unsigned +avoids possible sign extension\202. + +)-1 LI( If the file contains a 16X bit-field and user space specifies a 1B +char, then the bit-field is treated as a char, i.e., truncation will +occur. + +)-1 LI( If the file contains a 16X bit-field and user space specifies a 4J +int array[4], then the results are undetermined. +)LU( +For all user data types larger than char, the bit-field is byte-swapped +as necessary to convert to native format, so that bits in the +resulting data in user space can be tested, masked, etc. in the same +way regardless of platform.] + +)0 P(In addition to setting data type and size, the )BD(type)ES( +specification allows a few ancillary parameters to be set, using the +full syntax for )BD(type)ES(: +) 1 53 PR( [@][n][[['B']poff]][:[tlmin[:tlmax[:binsiz]]]])RP( + +)0 P(The special character "@" can be prepended to this specification to +indicated that the data element is a pointer in the user record, +rather than an array stored within the record. + +)0 P(The [n] value is an integer that specifies the +number of elements that are in this column \201default is 1\202. TLMIN, +TLMAX, and BINSIZ values also can be specified for this column after +the type, separated by colons. If only one such number is specified, +it is assumed to be TLMAX, and TLMIN and BINSIZ are set to 1. + +)0 P(The [poff] value can be used to specify the offset into an +array. By default, this offset value is set to zero and the data +specified starts at the beginning of the array. The offset usually +is specified in terms of the data type of the column. Thus an offset +specification of [5] means a 20-byte offset if the data type is a +32-bit integer, and a 40-byte offset for a double. If you want to +specify a byte offset instead of an offset tied to the column data type, +precede the offset value with 'B', e.g. [B6] means a 6-bye offset, +regardless of the column data type. + +The [poff] is especially useful in conjunction with the pointer @ +specification, since it allows the data element to anywhere stored +anywhere in the allocated array. For example, a specification such as +"@I[2]" specifies the third \201i.e., starting from 0\202 element in the +array pointed to by the pointer value. A value of "@2I[4]" specifies +the fifth and sixth values in the array. For example, consider the +following specification: ) 12 67 PR( typedef struct EvStruct{ + short x[4], *atp; + } *Event, EventRec; + /* set up the \201hardwired\202 columns */ + FunColumnSelect\201 fun, sizeof\201EventRec\202, NULL, + "2i", "2I ", "w", FUN_OFFSET\201Event, x\202, + "2i2", "2I[2]", "w", FUN_OFFSET\201Event, x\202, + "at2p", "@2I", "w", FUN_OFFSET\201Event, atp\202, + "at2p4", "@2I[4]", "w", FUN_OFFSET\201Event, atp\202, + "atp9", "@I[9]", "w", FUN_OFFSET\201Event, atp\202, + "atb20", "@I[B20]", "w", FUN_OFFSET\201Event, atb\202, + NULL\202;)RP( +Here we have specified the following columns: +)UL()-1 LI( 2i: two short ints in an array which is stored as part the +record +)-1 LI( 2i2: the 3rd and 4th elements of an array which is stored +as part of the record +)-1 LI( an array of at least 10 elements, not stored in the record but +allocated elsewhere, and used by three different columns: +)UL()-1 LI( at2p: 2 short ints which are the first 2 elements of the allocated array +)-1 LI( at2p4: 2 short ints which are the 5th and 6th elements of +the allocated array +)-1 LI( atp9: a short int which is the 10th element of the allocated array)LU( +)-1 LI( atb20: a short int which is at byte offset 20 of another allocated array)LU( +In this way, several columns can be specified, all of which are in a +single array. )BD(NB)ES(: it is the programmer's responsibility to +ensure that specification of a positive value for poff does not point +past the end of valid data. + +)-1 LI( )BD(read/write mode)ES(: "r" means that the column is read from an +input file into user space by +)0 30 1 A(FunTableRowGet\201\202)30 0 TN TL()Ec /AF f D(, "w" means that +the column is written to an output file. Both can specified at the same +time. + +)-1 LI( )BD(offset)ES(: the offset into the user data to store +this column. Typically, the macro FUN_OFFSET\201recname, colname\202 is used +to define the offset into a record structure.)LU( + +)0 P(When all column arguments have been specified, a final NULL argument +must added to signal the column selection list. + +)0 P(As an alternative to the varargs +)0 32 1 A(FunColumnSelect\201\202)32 0 TN TL()Ec /AF f D( +routine, a non-varargs routine called +)0 32 1 A(FunColumnSelectArr\201\202)32 0 TN TL()Ec /AF f D( +also is available. The first three arguments \201fun, size, plist\202 of this +routine are the same as in +)0 32 1 A(FunColumnSelect\201\202)32 0 TN TL()Ec /AF f D(. +Instead of a variable +argument list, however, +)0 32 1 A(FunColumnSelectArr\201\202)32 0 TN TL()Ec /AF f D( +takes 5 additional arguments. The first 4 arrays arguments contain the +names, types, modes, and offsets, respectively, of the columns being +selected. The final argument is the number of columns that are +contained in these arrays. It is the user's responsibility to free +string space allocated in these arrays. + +)0 P(Consider the following example: +) 12 54 PR( typedef struct evstruct{ + int status; + float pi, pha, *phas; + double energy; + } *Ev, EvRec; + + FunColumnSelect\201fun, sizeof\201EvRec\202, NULL, + "status", "J", "r", FUN_OFFSET\201Ev, status\202, + "pi", "E", "r", FUN_OFFSET\201Ev, pi\202, + "pha", "E", "r", FUN_OFFSET\201Ev, pha\202, + "phas", "@9E", "r", FUN_OFFSET\201Ev, phas\202, + NULL\202;)RP( +)0 P(Each time a row is read into the Ev struct, the "status" column is +converted to an int data type \201regardless of its data type in the +file\202 and stored in the status value of the struct. Similarly, "pi" +and "pha", and the phas vector are all stored as floats. Note that the +"@" sign indicates that the "phas" vector is a pointer to a 9 element +array, rather than an array allocated in the struct itself. The row +record can then be processed as required: +) 9 70 PR( /* get rows -- let routine allocate the row array */ + while\201 \201ebuf = \201Ev\202FunTableRowGet\201fun, NULL, MAXROW, NULL, &got\202\202 \202{ + /* process all rows */ + for\201i=0; ipi = \201ev->pi+.5\202; + ev->pha = \201ev->pi-.5\202; + })RP( + +)0 P()0 32 1 A(FunColumnSelect\201\202)32 0 TN TL()Ec /AF f D( +can also be called to define "writable" columns in order to generate a FITS +Binary Table, without reference to any input columns. For +example, the following will generate a 4-column FITS binary table when +)0 31 1 A(FunTableRowPut\201\202)31 0 TN TL()Ec /AF f D( is used to +write Ev records: + +) 12 56 PR( typedef struct evstruct{ + int status; + float pi, pha + double energy; + } *Ev, EvRec; + + FunColumnSelect\201fun, sizeof\201EvRec\202, NULL, + "status", "J", "w", FUN_OFFSET\201Ev, status\202, + "pi", "E", "w", FUN_OFFSET\201Ev, pi\202, + "pha", "E", "w", FUN_OFFSET\201Ev, pha\202, + "energy", "D", "w", FUN_OFFSET\201Ev, energy\202, + NULL\202;)RP( +All columns are declared to be write-only, so presumably the column +data is being generated or read from some other source. + +)0 P(In addition, +)0 32 1 A(FunColumnSelect\201\202)32 0 TN TL()Ec /AF f D( +can be called to define )BD(both)ES( "readable" and "writable" columns. +In this case, the "read" columns +are associated with an input file, while the "write" columns are +associated with the output file. Of course, columns can be specified as both +"readable" and "writable", in which case they are read from input +and \201possibly modified data values are\202 written to the output. +The +)0 32 1 A(FunColumnSelect\201\202)32 0 TN TL()Ec /AF f D( +call itself is made by passing the input Funtools handle, and it is +assumed that the output file has been opened using this input handle +as its +)0 23 1 A(Funtools reference handle)23 0 TN TL()Ec /AF f D(. + +)0 P(Consider the following example: +) 13 54 PR( typedef struct evstruct{ + int status; + float pi, pha, *phas; + double energy; + } *Ev, EvRec; + + FunColumnSelect\201fun, sizeof\201EvRec\202, NULL, + "status", "J", "r", FUN_OFFSET\201Ev, status\202, + "pi", "E", "rw", FUN_OFFSET\201Ev, pi\202, + "pha", "E", "rw", FUN_OFFSET\201Ev, pha\202, + "phas", "@9E", "rw", FUN_OFFSET\201Ev, phas\202, + "energy", "D", "w", FUN_OFFSET\201Ev, energy\202, + NULL\202;)RP( +As in the "read" example above, each time an row is read into the Ev +struct, the "status" column is converted to an int data type +\201regardless of its data type in the file\202 and stored in the status +value of the struct. Similarly, "pi" and "pha", and the phas vector +are all stored as floats. Since the "pi", "pha", and "phas" variables +are declared as "writable" as well as "readable", they also will be +written to the output file. Note, however, that the "status" variable +is declared as "readable" only, and hence it will not be written to +an output file. Finally, the "energy" column is declared as +"writable" only, meaning it will not be read from the input file. In +this case, it can be assumed that "energy" will be calculated in the +program before being output along with the other values. + +)0 P(In these simple cases, only the columns specified as "writable" will +be output using +)0 31 1 A(FunTableRowPut\201\202)31 0 TN TL()Ec /AF f D(. However, +it often is the case that you want to merge the user columns back in +with the input columns, even in cases where not all of the input +column names are explicitly read or even known. For this important +case, the )BD(merge=[type])ES( keyword is provided in the plist string. + +)0 P(The )BD(merge=[type])ES( keyword tells Funtools to merge the columns from +the input file with user columns on output. It is normally used when +an input and output file are opened and the input file provides the +)0 23 1 A(Funtools reference handle)23 0 TN TL()Ec /AF f D( +for the output file. In this case, each time +)0 30 1 A(FunTableRowGet\201\202)30 0 TN TL()Ec /AF f D( is called, the +raw input rows are saved in a special buffer. If +)0 31 1 A(FunTableRowPut\201\202)31 0 TN TL()Ec /AF f D( then is called +\201before another call to +)0 30 1 A(FunTableRowGet\201\202)30 0 TN TL()Ec /AF f D(\202, the contents +of the raw input rows are merged with the user rows according to the +value of )BD(type)ES( as follows: + +)UL()-1 LI( )BD(update)ES(: add new user columns, and update value of existing ones \201maintaining the input data type\202 + +)-1 LI( )BD(replace)ES(: add new user columns, and replace the data type +and value of existing ones. \201Note that if tlmin/tlmax values are not +specified in the replacing column, but are specified in the original +column being replaced, then the original tlmin/tlmax values are used +in the replacing column.\202 + +)-1 LI( )BD(append)ES(: only add new columns, do not "replace" or "update" existing ones)LU( + +)0 P(Consider the example above. If )BD(merge=update)ES( is specified in the +plist string, then "energy" will be added to the input columns, and +the values of "pi", "pha", and "phas" will be taken from the user +space \201i.e., the values will be updated from the original values, if +they were changed by the program\202. The data type for "pi", "pha", and +"phas" will be the same as in the original file. If +)BD(merge=replace)ES( is specified, both the data type and value of +these three input columns will be changed to the data type and value +in the user structure. If )BD(merge=append)ES( is specified, none of +these three columns will be updated, and only the "energy" column will +be added. Note that in all cases, "status" will be written from the +input data, not from the user record, since it was specified as read-only. + +)0 P(Standard applications will call +)0 32 1 A(FunColumnSelect\201\202)32 0 TN TL()Ec /AF f D( +to define user columns. However, if this routine is not called, the +default behavior is to transfer all input columns into user space. For +this purpose a default record structure is defined such that each data +element is properly aligned on a valid data type boundary. This +mechanism is used by programs such as fundisp and funtable to process +columns without needing to know the specific names of those columns. +It is not anticipated that users will need such capabilities \201contact +us if you do!\202 + +)0 P(By default, )0 32 1 A(FunColumnSelect\201\202)32 0 TN TL()Ec /AF f D( +reads/writes rows to/from an "array of structs", where each struct contains +the column values for a single row of the table. This means that the +returned values for a given column are not contiguous. You can +set up the IO to return a "struct of arrays" so that each of the +returned columns are contiguous by specifying )BD(org=structofarrays)ES( +\201abbreviation: )BD(org=soa)ES(\202 in the plist. +\201The default case is )BD(org=arrayofstructs)ES( or )BD(org=aos)ES(.\202 + +)0 P(For example, the default setup to retrieve rows from a table would be +to define a record structure for a single event and then call + )0 32 1 A(FunColumnSelect\201\202)32 0 TN TL()Ec /AF f D( +as follows: +) 14 73 PR( typedef struct evstruct{ + short region; + double x, y; + int pi, pha; + double time; + } *Ev, EvRec; + + got = FunColumnSelect\201fun, sizeof\201EvRec\202, NULL, + "x", "D:10:10", mode, FUN_OFFSET\201Ev, x\202, + "y", "D:10:10", mode, FUN_OFFSET\201Ev, y\202, + "pi", "J", mode, FUN_OFFSET\201Ev, pi\202, + "pha", "J", mode, FUN_OFFSET\201Ev, pha\202, + "time", "1D", mode, FUN_OFFSET\201Ev, time\202, + NULL\202;)RP( +Subsequently, each call to +FunTableRowGet\201\202)EA( +will return an array of structs, one for each returned row. If instead you +wanted to read columns into contiguous arrays, you specify )BD(org=soa)ES(: +) 14 72 PR( typedef struct aevstruct{ + short region[MAXROW]; + double x[MAXROW], y[MAXROW]; + int pi[MAXROW], pha[MAXROW]; + double time[MAXROW]; + } *AEv, AEvRec; + + got = FunColumnSelect\201fun, sizeof\201AEvRec\202, "org=soa", + "x", "D:10:10", mode, FUN_OFFSET\201AEv, x\202, + "y", "D:10:10", mode, FUN_OFFSET\201AEv, y\202, + "pi", "J", mode, FUN_OFFSET\201AEv, pi\202, + "pha", "J", mode, FUN_OFFSET\201AEv, pha\202, + "time", "1D", mode, FUN_OFFSET\201AEv, time\202, + NULL\202;)RP( +Note that the only modification to the call is in the plist string. + +)0 P(Of course, instead of using staticly allocated arrays, you also can specify +dynamically allocated pointers: +) 16 75 PR( /* pointers to arrays of columns \201used in struct of arrays\202 */ + typedef struct pevstruct{ + short *region; + double *x, *y; + int *pi, *pha; + double *time; + } *PEv, PEvRec; + + got = FunColumnSelect\201fun, sizeof\201PEvRec\202, "org=structofarrays", + "$region", "@I", mode, FUN_OFFSET\201PEv, region\202, + "x", "@D:10:10", mode, FUN_OFFSET\201PEv, x\202, + "y", "@D:10:10", mode, FUN_OFFSET\201PEv, y\202, + "pi", "@J", mode, FUN_OFFSET\201PEv, pi\202, + "pha", "@J", mode, FUN_OFFSET\201PEv, pha\202, + "time", "@1D", mode, FUN_OFFSET\201PEv, time\202, + NULL\202;)RP( +Here, the actual storage space is either allocated by the user or by the +)0 32 1 A(FunColumnSelect\201\202)32 0 TN TL()Ec /AF f D( call\202. + +)0 P(In all of the above cases, the same call is made to retrieve rows, e.g.: +) 1 64 PR( buf = \201void *\202FunTableRowGet\201fun, NULL, MAXROW, NULL, &got\202;)RP( +However, the individual data elements are accessed differently. +For the default case of an "array of structs", the +individual row records are accessed using: +) 5 69 PR( for\201i=0; ix, ev->y, ev->pi, ev->pha, ev->dx, ev->dy, ev->time\202; + })RP( +For a struct of arrays or a struct of array pointers, we have a single struct +through which we access individual columns and rows using: +) 6 63 PR( aev = \201AEv\202buf; + for\201i=0; ix[i], aev->y[i], aev->pi[i], aev->pha[i], + aev->dx[i], aev->dy[i], aev->time[i]\202; + })RP( +Support for struct of arrays in the +)0 31 1 A(FunTableRowPut\201\202)31 0 TN TL()Ec /AF f D( +call is handled analogously. + +)0 P(See the )0 2 A(evread example code)EA( +and +)0 2 A(evmerge example code)EA( +for working examples of how +)0 32 1 A(FunColumnSelect\201\202)32 0 TN TL()Ec /AF f D( is used. + + + + +)0 2 39 H(FunColumnActivate)WB 105 Sn()WB 33 Sn( - activate Funtools columns)EA()EH( + + +)BD() 3 55 PR( #include + + void FunColumnActivate\201Fun fun, char *s, char *plist\202)RP()ES( + + +)0 P(The )BD(FunColumnActivate\201\202)ES( routine determines which columns \201set up +by )0 32 1 A(FunColumnSelect\201\202)32 0 TN TL()Ec /AF f D(\202 +ultimately will be read and/or written. By default, all columns that +are selected using +)0 32 1 A(FunColumnSelect\201\202)32 0 TN TL()Ec /AF f D( +are activated. The +)0 33 1 A(FunColumnActivate\201\202)33 0 TN TL()Ec /AF f D( +routine can be used to turn off/off activation of specific columns. + +)0 P(The first argument is the Fun handle associated with this set of +columns. The second argument is a space-delimited list of columns to +activate or de-activate. Columns preceded by "+" are activated and +columns preceded by a "-" are de-activated. If a column is named +without "+" or "-", it is activated. The reserved strings "$region" +and '$n' are used to activate a special columns containing the filter +region value and row value, respectively, associated with +this row. For example, if a filter containing two circular regions is +specified as part of the Funtools file name, this column will contain +a value of 1 or 2, depending on which region that row was in. The +reserved strings "$x" and "$y" are used to activate the current +binning columns. Thus, if the columns DX and DY are specified as +binning columns: +) 1 42 PR( [sh $] fundisp foo.fits[bincols=\201DX,DY\202])RP( +then "$x" and "$y" will refer to these columns in a call to +)0 33 1 A(FunColumnActivate\201\202)33 0 TN TL()Ec /AF f D(. + +)0 P(In addition, if the activation string contains only columns to be +activated, then the routine will de-activate all other columns. +Similarly, if the activation string contains only +columns to de-activate, then the routine will activate all other columns +before activating the list. This makes it simple to change the +activation state of all columns without having to know all of the +column names. For example: +)UL()-1 LI( )BD("pi pha time")ES( # only these three columns will be active +)-1 LI( )BD("-pi -pha -time")ES( # all but these columns will be active +)-1 LI( )BD("pi -pha")ES( # only pi is active, pha is not, others are not +)-1 LI( )BD("+pi -pha")ES( # same as above +)-1 LI( )BD("pi -pha -time")ES( # only pi is active, all others are not +)-1 LI( )BD("pi pha")ES( # pha and pi are active, all others are not +)-1 LI( )BD("pi pha -x -y")ES( # pha and pi are active, all others are not)LU( + +)0 P(You can use the column activation list to reorder columns, since +columns are output in the order specified. For example: +) 19 77 PR( # default output order + fundisp snr.ev'[cir 512 512 .1]' + X Y PHA PI TIME DX DY + -------- -------- -------- -------- --------------------- -------- -------- + 512 512 6 7 79493997.45854475 578 574 + 512 512 8 9 79494575.58943175 579 573 + 512 512 5 6 79493631.03866175 578 575 + 512 512 5 5 79493290.86521725 578 575 + 512 512 8 9 79493432.00990875 579 573 + + # re-order the output by specifying explicit order + fundisp snr.ev'[cir 512 512 .1]' "time x y dy dx pi pha" + TIME X Y DY DX PI PHA + --------------------- -------- -------- -------- -------- -------- -------- + 79493997.45854475 512 512 574 578 7 6 + 79494575.58943175 512 512 573 579 9 8 + 79493631.03866175 512 512 575 578 6 5 + 79493290.86521725 512 512 575 578 5 5 + 79493432.00990875 512 512 573 579 9 8)RP( + +)0 P(A "+" sign by itself means to activate all columns, so that you can reorder +just a few columns without specifying all of them: +) 9 77 PR( # reorder 3 columns and then output the rest + fundisp snr.ev'[cir 512 512 .1]' "time pi pha +" + TIME PI PHA Y X DX DY + --------------------- -------- -------- -------- -------- -------- -------- + 79493997.45854475 7 6 512 512 578 574 + 79494575.58943175 9 8 512 512 579 573 + 79493631.03866175 6 5 512 512 578 575 + 79493290.86521725 5 5 512 512 578 575 + 79493432.00990875 9 8 512 512 579 573)RP( +The column activation/deactivation is performed in the order of the +specified column arguments. This means you can mix "+", "-" \201which +de-activates all columns\202 and specific column names to reorder and +select columns in one command. For example, consider the following: +) 9 59 PR( # reorder and de-activate + fundisp snr.ev'[cir 512 512 .1]' "time pi pha + -x -y" + TIME PI PHA DX DY + --------------------- -------- -------- -------- -------- + 79493997.45854475 7 6 578 574 + 79494575.58943175 9 8 579 573 + 79493631.03866175 6 5 578 575 + 79493290.86521725 5 5 578 575 + 79493432.00990875 9 8 579 573)RP( +We first activate "time", "pi", and "pha" so that they are output first. +We then activate all of the other columns, and then de-activate "x" and "y". +Note that this is different from: +) 9 77 PR( # probably not what you want ... + fundisp snr.ev'[cir 512 512 .1]' "time pi pha -x -y +" + TIME PI PHA Y X DX DY + --------------------- -------- -------- -------- -------- -------- -------- + 79493997.45854475 7 6 512 512 578 574 + 79494575.58943175 9 8 512 512 579 573 + 79493631.03866175 6 5 512 512 578 575 + 79493290.86521725 5 5 512 512 578 575 + 79493432.00990875 9 8 512 512 579 573)RP( +Here, "x" and "y" are de-activated, but then all columns including "x" and +"y" are again re-activated. + +)0 P(Typically, +)0 33 1 A(FunColumnActivate\201\202)33 0 TN TL()Ec /AF f D( uses a +list of columns that are passed into the program from the command line. For +example, the code for funtable contains the following: +) 9 66 PR( char *cols=NULL; + + /* open the input FITS file */ + if\201 !\201fun = FunOpen\201argv[1], "rc", NULL\202\202 \202 + gerror\201stderr, "could not FunOpen input file: %s\200n", argv[1]\202; + + /* set active flag for specified columns */ + if\201 argc >= 4 \202 cols = argv[3]; + FunColumnActivate\201fun, cols, NULL\202;)RP( + +The )0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D( call sets the +default columns to be all columns in the input file. The +)0 33 1 A(FunColumnActivate\201\202)33 0 TN TL()Ec /AF f D( call +then allows the user to control which columns ultimately will be +activated \201i.e., in this case, written to the new file\202. For example: +) 1 39 PR( funtable test.ev foo.ev "pi pha time")RP( +will process only the three columns mentioned, while: +) 1 33 PR( funtable test.ev foo.ev "-time")RP( +will process all columns except "time". + +)0 P(If )0 33 1 A(FunColumnActivate\201\202)33 0 TN TL()Ec /AF f D( +is called with a null string, then the environment variable +)BD(FUN_COLUMNS)ES( will be used to provide a global value, if present. +This is the reason why we call the routine even if no columns +are specified on the command line \201see example above\202, instead +of calling it this way: +) 4 45 PR( /* set active flag for specified columns */ + if\201 argc >= 4 \202{ + FunColumnActivate\201fun, argv[3], NULL\202; + })RP( + + + + +)0 2 40 H(FunColumnLookup)WB 106 Sn()WB 34 Sn( - lookup a Funtools column)EA()EH( + +)BD() 5 56 PR( #include + + int FunColumnLookup\201Fun fun, char *s, int which, + char **name, int *type, int *mode, + int *offset, int *n, int *width\202)RP()ES( + + +)0 P(The )BD(FunColumnLookup\201\202)ES( routine returns information about a named +\201or indexed\202 column. The first argument is the Fun handle associated +with this set of columns. The second argument is the name of the +column to look up. If the name argument is NULL, the argument that +follows is the zero-based index into the column array of the column +for which information should be returned. The next argument is a +pointer to a char *, which will contain the name of the column. The +arguments that follow are the addresses of int values into which +the following information will be returned: +)UL()-1 LI( )BD(type)ES(: data type of column: +)UL()-1 LI(A: ASCII characters +)-1 LI(B: unsigned 8-bit char +)-1 LI(I: signed 16-bit int +)-1 LI(U: unsigned 16-bit int \201not standard FITS\202 +)-1 LI(J: signed 32-bit int +)-1 LI(V: unsigned 32-bit int \201not standard FITS\202 +)-1 LI(E: 32-bit float +)-1 LI(D: 64-bit float)LU( +)-1 LI( )BD(mode)ES(: bit flag status of column, including: +)UL()-1 LI( COL_ACTIVE 1 is column activated? +)-1 LI( COL_IBUF 2 is column in the raw input data? +)-1 LI( COL_PTR 4 is column a pointer to an array? +)-1 LI( COL_READ 010 is read mode selected? +)-1 LI( COL_WRITE 020 is write mode selected? +)-1 LI( COL_REPLACEME 040 is this column being replaced by user data?)LU( +)-1 LI( )BD(offset)ES(: byte offset in struct +)-1 LI( )BD(n)ES(: number of elements \201i.e. size of vector\202 in this column +)-1 LI( )BD(width)ES(: size in bytes of this column)LU( +If the named column exists, the routine returns a positive integer, +otherwise zero is returned. \201The positive integer is the index+1 into +the column array where this column was located.\202 + +If NULL is passed as the return address of one \201or more\202 of these +values, no data is passed back for that information. For +example: +) 2 76 PR( if\201 !FunColumnLookup\201fun, "phas", 0, NULL NULL, NULL, NULL, &npha, NULL\202 \202 + gerror\201stderr, "can't find phas column\200n"\202;)RP( +only returns information about the size of the phas vector. + + + + +)0 2 41 H(FunTableRowGet)WB 107 Sn()WB 30 Sn( - get Funtools rows)EA()EH( + + +)BD() 4 68 PR( #include + + void *FunTableRowGet\201Fun fun, void *rows, int maxrow, char *plist, + int *nrow\202)RP()ES( + + +)0 P(The )BD(FunTableRowGet\201\202)ES( routine retrieves rows from a Funtools +binary table or raw event file, and places the values of columns +selected by )0 32 1 A(FunColumnSelect\201\202)32 0 TN TL()Ec /AF f D( +into an array of user structs. Selected column values are +automatically converted to the specified user data type \201and to native +data format\202 as necessary. + +)0 P(The first argument is the Fun handle associated with this row data. +The second )BD(rows)ES( argument is the array of user structs into +which the selected columns will be stored. If NULL is passed, the +routine will automatically allocate space for this array. \201This +includes proper allocation of pointers within each struct, if the "@" +pointer type is used in the selection of columns. Note that if you +pass NULL in the second argument, you should free this space using the +standard free\201\202 system call when you are finished with the array of +rows.\202 The third )BD(maxrow)ES( argument specifies the maximum number +of rows to be returned. Thus, if )BD(rows)ES( is allocated by the +user, it should be at least of size maxrow*sizeof\201evstruct\202. + +)0 P(The fourth )BD(plist)ES( argument is a param list string. Currently, +the keyword/value pair "mask=transparent" is supported in the plist +argument. If this string is passed in the call's plist argument, then +all rows are passed back to the user \201instead of just rows passing +the filter\202. This is only useful when +)0 32 1 A(FunColumnSelect\201\202)32 0 TN TL()Ec /AF f D( also is +used to specify "$region" as a column to return for each row. In +such a case, rows found within a region have a returned region value +greater than 0 \201corresponding to the region id of the region in which +they are located\202, rows passing the filter but not in a region have +region value of -1, and rows not passing any filter have region +value of 0. Thus, using "mask=transparent" and the returned region +value, a program can process all rows and decide on an action based +on whether a given row passed the filter or not. + +)0 P(The final argument is a pointer to an int variable that will return +the actual number of rows returned. The routine returns a pointer to +the array of stored rows, or NULL if there was an error. \201This pointer +will be the same as the second argument, if the latter is non-NULL\202. +) 16 69 PR( /* get rows -- let routine allocate the row array */ + while\201 \201buf = \201Ev\202FunTableRowGet\201fun, NULL, MAXROW, NULL, &got\202\202 \202{ + /* process all rows */ + for\201i=0; ienergy = \201ev->pi+ev->pha\202/2.0; + ev->pha = -ev->pha; + ev->pi = -ev->pi; + } + /* write out this batch of rows */ + FunTableRowPut\201fun2, buf, got, 0, NULL\202; + /* free row data */ + if\201 buf \202 free\201buf\202; + })RP( +As shown above, successive calls to +)0 30 1 A(FunTableRowGet\201\202)30 0 TN TL()Ec /AF f D( will return the +next set of rows from the input file until all rows have been read, +i.e., the routine behaves like sequential Unix I/O calls such as +fread\201\202. See )0 2 A(evmerge example code)EA( for a +more complete example. + +)0 P(Note that FunTableRowGet\201\202 also can be called as FunEventsGet\201\202, for +backward compatibility. + + + + +)0 2 42 H(FunTableRowPut)WB 108 Sn()WB 31 Sn( - put Funtools rows)EA()EH( + + +) 1 70 PR()BD(int FunTableRowPut\201Fun fun, void *rows, int nev, int idx, char *plist\202)ES()RP( + + +The )BD(FunTableRowPut\201\202)ES( routine writes rows to a FITS binary +table, taking its input from an array of user structs that contain +column values selected by a previous call to +)0 32 1 A(FunColumnSelect\201\202)32 0 TN TL()Ec /AF f D(. Selected +column values are automatically converted from native data format to +FITS data format as necessary. + +)0 P(The first argument is the Fun handle associated with this row data. +The second )BD(rows)ES( argument is the array of user structs to +output. The third )BD(nrow)ES( argument specifies the number number of +rows to write. The routine will write )BD(nrow)ES( records, starting +from the location specified by )BD(rows)ES(. + +)0 P(The fourth )BD(idx)ES( argument is the index of the first raw input +row to write, in the case where rows from the user buffer are +being merged with their raw input row counterparts \201see below\202. Note +that this )BD(idx)ES( value is has nothing to do with the +row buffer specified in argument 1. It merely matches the row +being written with its corresponding \201hidden\202 raw row. Thus, if you +read a number of rows, process them, and then write them out all at +once starting from the first user row, the value of )BD(idx)ES( +should be 0: +) 14 70 PR( Ev ebuf, ev; + /* get rows -- let routine allocate the row array */ + while\201 \201ebuf = \201Ev\202FunTableRowGet\201fun, NULL, MAXROW, NULL, &got\202\202 \202{ + /* process all rows */ + for\201i=0; i + + int FunParamGetb\201Fun fun, char *name, int n, int defval, int *got\202 + + int FunParamGeti\201Fun fun, char *name, int n, int defval, int *got\202 + + double FunParamGetd\201Fun fun, char *name, int n, double defval, int *got\202 + + char *FunParamGets\201Fun fun, char *name, int n, char *defval, int *got\202)RP()ES( + + +)0 P(The four routines )BD(FunParamGetb\201\202)ES(, )BD(FunParamGeti\201\202)ES(, +)BD(FunParamGetd\201\202)ES(, and )BD(FunParamGets\201\202)ES(, return the value of +a FITS header parameter as a boolean, int, double, and string, +respectively. The string returned by )BD(FunParamGets\201\202)ES( is a malloc'ed +copy of the header value and should be freed when no longer needed. + +)0 P(The first argument is the Fun handle associated with the FITS header +being accessed. Normally, the header is associated with the FITS +extension that you opened with )BD(FunOpen\201\202)ES(. However, you can use +FunInfoPut\201\202 to specify access of the primary header. In particular, +if you set the FUN_PRIMARYHEADER parameter to 1, then the primary +header is used for all parameter access until the value is reset to +0. For example: +) 9 75 PR( int val; + FunParamGeti\201fun, "NAXIS", 1, 0, &got\202; # current header + val=1; + FunInfoPut\201fun, FUN_PRIMARYHEADER, &val, 0\202; # switch to ... + FunParamGeti\201fun, "NAXIS", 1, 0, &got\202; # ... primary header + FunParamGeti\201fun, "NAXIS", 2, 0, &got\202; # ... primary header + val=0; + FunInfoPut\201fun, FUN_PRIMARYHEADER, &val, 0\202; # switch back to ... + FunParamGeti\201fun, "NAXIS", 2, 0, &got\202; # current header)RP( + +)0 P(Alternatively, you can use the FUN_PRIMARY macro to access parameters +from the primary header on a per-parameter basis: +) 2 72 PR( FunParamGeti\201fun, "NAXIS1", 0, 0, &got\202; # current header + FunParamGeti\201FUN_PRIMARY\201fun\202, "NAXIS1", 0, 0, &got\202; # primary header)RP( +)BD(NB: FUN_PRIMARY is deprecated.)ES( +It makes use of a global parameter and therefore will not not +appropriate for threaded applications, when we make funtools +thread-safe. We recommend use of FunInfoPut\201\202 to switch between the +extension header and the primary header. + +)0 P(For output data, access to the primary header is only possible until +the header is written out, which usually takes place when the first +data are written. + +)0 P(The second argument is the name of the parameter to access. The third +)BD(n)ES( argument, if non-zero, is an integer that will be added as a +suffix to the parameter name. This makes it easy to use a simple loop +to process parameters having the same root name. For example, to +gather up all values of TLMIN and TLMAX for each column in a binary +table, you can use: +) 4 74 PR( for\201i=0, got=1; got; i++\202{ + fun->cols[i]->tlmin = \201int\202FunParamGeti\201fun, "TLMIN", i+1, 0.0, &got\202; + fun->cols[i]->tlmax = \201int\202FunParamGeti\201fun, "TLMAX", i+1, 0.0, &got\202; + })RP( + +)0 P(The fourth )BD(defval)ES( argument is the default value to return if +the parameter does not exist. Note that the data type of this +parameter is different for each specific FunParamGet\201\202 call. The final +)BD(got)ES( argument will be 0 if no param was found. Otherwise the +data type of the parameter is returned as follows: FUN_PAR_UNKNOWN +\201'u'\202, FUN_PAR_COMMENT \201'c'\202, FUN_PAR_LOGICAL \201'l'\202, FUN_PAR_INTEGER +\201'i'\202, FUN_PAR_STRING \201's'\202, FUN_PAR_REAL \201'r'\202, FUN_PAR_COMPLEX \201'x'\202. + +)0 P(These routines return the value of the header parameter, or the +specified default value if the header parameter does not exist. The +returned value is a malloc'ed string and should be freed when no +longer needed. + +)0 P(By default, )BD(FunParamGets\201\202)ES( returns the string value of the +named parameter. However, you can use FunInfoPut\201\202 to retrieve the +raw 80-character FITS card instead. In particular, if you set the +FUN_RAWPARAM parameter to 1, then card images will be returned by +FunParamGets\201\202 until the value is reset to 0. + +)0 P(Alternatively, if the FUN_RAW macro is applied to the name, then the +80-character raw FITS card is returned instead. +)BD(NB: FUN_RAW is deprecated.)ES( +It makes use of a global parameter and therefore will not not +appropriate for threaded applications, when we make funtools +thread-safe. We recommend use of FunInfoPut\201\202 to switch between the +extension header and the primary header. + +)0 P(Note that in addition to the behaviors described above, the +routine )BD(FunParamGets\201\202)ES( will return the 80 raw characters of the +)BD(nth)ES( FITS card \201including the comment\202 if )BD(name)ES( is specified as +NULL and )BD(n)ES( is positive. For example, to loop through all FITS +header cards in a given extension and print out the raw card, use: +) 9 55 PR( for\201i=1; ;i++\202{ + if\201 \201s = FunParamGets\201fun, NULL, i, NULL, &got\202\202 \202{ + fprintf\201stdout, "%.80s\200n", s\202; + free\201s\202; + } + else{ + break; + } + })RP( + + + + +)0 2 43 H(FunParamPut)WB 109 Sn()WB 38 Sn( - put a Funtools param value)EA()EH( + + +)BD() 13 71 PR( #include + + int FunParamPutb\201Fun fun, char *name, int n, int value, char *comm, + int append\202 + + int FunParamPuti\201Fun fun, char *name, int n, int value, char *comm, + int append\202 + + int FunParamPutd\201Fun fun, char *name, int n, double value, int prec, + char *comm, int append\202 + + int FunParamPuts\201Fun fun, char *name, int n, char *value, char *comm, + int append\202)RP()ES( + + +)0 P(The four routines )BD(FunParamPutb\201\202)ES(, )BD(FunParamPuti\201\202)ES(, +)BD(FunParamPutd\201\202)ES(, and )BD(FunParamPuts\201\202)ES(, will set the value +of a FITS header parameter as a boolean, int, double, and string, +respectively. + +)0 P(The first argument is the Fun handle associated with the FITS header +being accessed. Normally, the header is associated with the FITS +extension that you opened with )BD(FunOpen\201\202)ES(. +However, you can use FunInfoPut\201\202 to specify that use of the primary +header. In particular, if you set the FUN_PRIMARYHEADER parameter to +1, then the primary header is used for all parameter access until the +value is reset to 0. For example: +) 5 69 PR( int val; + FunParamPuti\201fun, "NAXIS1", 0, 10, NULL, 1\202; # current header + val=1; + FunInfoPut\201fun, FUN_PRIMARYHEADER, &val, 0\202; # switch to ... + FunParamPuti\201fun, "NAXIS1", 0, 10, NULL, 1\202; # primary header)RP( +\201You also can use the deprecated FUN_PRIMARY macro, to access +parameters from the primary header.\202 + +)0 P(The second argument is the )BD(name)ES( of the parameter. \201 +In accordance with FITS standards, the special names )BD(COMMENT)ES( +and )BD(HISTORY)ES(, as well as blank names, are output without the "= " +value indicator in columns 9 and 10. + +)0 P(The third )BD(n)ES( argument, if non-zero, is an integer that will be +added as a suffix to the parameter name. This makes it easy to use a +simple loop to process parameters having the same root name. For +example, to set the values of TLMIN and TLMAX for each column in a +binary table, you can use: +) 4 70 PR( for\201i=0; i + + int FunInfoGet\201Fun fun, int type, char *addr, ...\202)RP()ES( + + +)0 P(The )BD(FunInfoGet\201\202)ES( routine returns information culled from the +Funtools structure. The first argument is the Fun handle from which +information is to be retrieved. This first required argument is followed +by a variable length list of pairs of arguments. Each pair consists +of an integer representing the type of information to retrieve and the +address where the information is to be stored. The list is terminated by a 0. +The routine returns the number of get actions performed. + +)0 P(The full list of available information is described below. Please note +that only a few of these will be useful to most application developers. +For imaging applications, the most important types are: +) 3 47 PR( FUN_SECT_DIM1 int /* dim1 for section */ + FUN_SECT_DIM2 int /* dim2 for section */ + FUN_SECT_BITPIX int /* bitpix for section */)RP( +These would be used to determine the dimensions and data type of image +data retrieved using the +)0 26 1 A(FunImageGet\201\202)26 0 TN TL()Ec /AF f D( routine. For +example: +) 17 68 PR( /* extract and bin the data section into an image buffer */ + buf = FunImageGet\201fun, NULL, NULL\202; + /* get required information from funtools structure. + this should come after the FunImageGet\201\202 call, in case the call + changed sect_bitpix */ + FunInfoGet\201fun, + FUN_SECT_BITPIX, &bitpix, + FUN_SECT_DIM1, &dim1, + FUN_SECT_DIM2, &dim2, + 0\202; + /* loop through pixels and reset values below limit to value */ + for\201i=0; i + void pix2wcs \201wcs,xpix,ypix,xpos,ypos\202 + struct WorldCoor *wcs; /* World coordinate system structure */ + double xpix,ypix; /* x and y coordinates in pixels */ + double *xpos,*ypos; /* RA and Dec in degrees \201returned\202 */)RP( + +which converts pixel coordinates to sky coordinates, and: + +) 5 67 PR( void wcs2pix \201wcs, xpos, ypos, xpix, ypix, offscl\202 + struct WorldCoor *wcs; /* World coordinate system structure */ + double xpos,ypos; /* World coordinates in degrees */ + double *xpix,*ypix; /* coordinates in pixels */ + int *offscl; /* 0 if within bounds, else off scale */)RP( +which converts sky coordinates to pixel coordinates. Again, please note +that the wcs structure returned by FUN_WCS assumes that image coordinates +are passed to the pix2wcs routine, while FUN_WCS0 assumes that physical +coordinates are passed. + +)0 P(Note that funtools.h file automatically includes wcs.h. An example +program that utilizes these WCS structure to call WCS Library routines +is )0 2 A(twcs.c)EA(. + +)0 P(The following is the complete list of information that can be returned: +) 52 79 PR( name type comment + --------- -------- --------------------------------------------- + FUN_FNAME char * /* file name */ + FUN_GIO GIO /* gio handle */ + FUN_HEADER FITSHead /* fitsy header struct */ + FUN_TYPE int /* TY_TABLE,TY_IMAGE,TY_EVENTS,TY_ARRAY */ + FUN_BITPIX int /* bits/pixel in file */ + FUN_MIN1 int /* tlmin of axis1 -- tables */ + FUN_MAX1 int /* tlmax of axis1 -- tables */ + FUN_MIN2 int /* tlmin of axis2 -- tables */ + FUN_MAX2 int /* tlmax of axis2 -- tables */ + FUN_DIM1 int /* dimension of axis1 */ + FUN_DIM2 int /* dimension of axis2 */ + FUN_ENDIAN int /* 0=little, 1=big endian */ + FUN_FILTER char * /* supplied filter */ + FUN_IFUN FITSHead /* pointer to reference header */ + FUN_IFUN0 FITSHead /* same as above, but no reset performed */ + /* image information */ + FUN_DTYPE int /* data type for images */ + FUN_DLEN int /* length of image in bytes */ + FUN_DPAD int /* padding to end of extension */ + FUN_DOBLANK int /* was blank keyword defined? */ + FUN_BLANK int /* value for blank */ + FUN_SCALED int /* was bscale/bzero defined? */ + FUN_BSCALE double /* bscale value */ + FUN_BZERO double /* bzero value */ + /* table information */ + FUN_NROWS int /* number of rows in file \201naxis2\202 */ + FUN_ROWSIZE int /* size of user row struct */ + FUN_BINCOLS char * /* specified binning columns */ + FUN_OVERFLOW int /* overflow detected during binning? */)WR( + /* array information */ + FUN_SKIP int /* bytes to skip in array header */ + /* section information */ + FUN_SECT_X0 int /* low dim1 value of section */ + FUN_SECT_X1 int /* hi dim1 value of section */ + FUN_SECT_Y0 int /* low dim2 value of section */ + FUN_SECT_Y1 int /* hi dim2 value of section */ + FUN_SECT_BLOCK int /* section block factor */ + FUN_SECT_BTYPE int /* 's' \201sum\202, 'a' \201average\202 for binning */ + FUN_SECT_DIM1 int /* dim1 for section */ + FUN_SECT_DIM2 int /* dim2 for section */ + FUN_SECT_BITPIX int /* bitpix for section */ + FUN_SECT_DTYPE int /* data type for section */ + FUN_RAWBUF char * /* pointer to raw row buffer */ + FUN_RAWSIZE int /* byte size of raw row records */ + /* column information */ + FUN_NCOL int /* number of row columns defined */ + FUN_COLS FunCol /* array of row columns */ + /* WCS information */ + FUN_WCS struct WorldCoor * /* wcs structure, converted for images*/ + FUN_WCS0 struct WorldCoor * /* wcs structure, not converted */)RP( + +)0 P(Row applications would not normally need any of this information. +An example of how these values can be used in more complex programs is +the )0 2 A(evnext example code)EA(. In this program, the +time value for each row is changed to be the value of the succeeding +row. The program thus reads the time values for a batch of rows, +changes the time values to be the value for the succeeding row, and +then merges these changed time values back with the other columns to +the output file. It then reads the next batch, etc. + +)0 P(This does not work for the last row read in each batch, since there +is no succeeding row until the next batch is read. Therefore, the +program saves that last row until it has read the next batch, then +processes the former before starting on the new batch. In order to +merge the last row successfully, the code uses FUN_RAWBUF to save +and restore the raw input data associated with each batch of +rows. Clearly, this requires some information about how funtools +works internally. We are happy to help you write such programs as the +need arises. + + + + +)0 2 45 H(FunInfoPut)WB 111 Sn()WB 36 Sn( - put information into a Funtools struct)EA()EH( + + +)BD() 3 52 PR( #include + + int FunInfoPut\201Fun fun, int type, char *addr, ...\202)RP()ES( + + +)0 P(The )BD(FunInfoPut\201\202)ES( routine puts information into a Funtools +structure. The first argument is the Fun handle from which +information is to be retrieved. After this first required argument +comes a variable length list of pairs of arguments. Each pair consists +of an integer representing the type of information to store and the +address of the new information to store in the struct. The variable +list is terminated by a 0. The routine returns the number of put +actions performed. + +)0 P(The full list of available information is described above with the +)0 36 1 A(FunInfoPut\201\202)36 0 TN TL()Ec /AF f D( routine. Although +use of this routine is expected to be uncommon, there is one +important situation in which it plays an essential part: writing +multiple extensions to a single output file. + +)0 P(For input, multiple extensions are handled by calling +)0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D( for each extension to be +processed. When opening multiple inputs, it sometimes is the case that +you will want to process them and then write them \201including their +header parameters\202 to a single output file. To accomplish this, you +open successive input extensions using +)0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D( and then call +)BD(FunInfoPut\201\202)ES( to set the +)0 23 1 A(Funtools reference handle)23 0 TN TL()Ec /AF f D( +of the output file to that of the newly opened input extension: +) 4 71 PR( /* open a new input extension */ + ifun=FunOpen\201tbuf, "r", NULL\202\202 \202 + /* make the new extension the reference handle for the output file */ + FunInfoPut\201ofun, FUN_IFUN, &ifun, 0\202;)RP( + +Resetting FUN_IFUN has same effect as when a funtools handle is passed +as the final argument to +)0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D(. The state of the output +file is reset so that a new extension is ready to be written. +Thus, the next I/O call on the output extension will output the +header, as expected. + +)0 P(For example, in a binary table, after resetting FUN_IFUN you can then +call )0 32 1 A(FunColumnSelect\201\202)32 0 TN TL()Ec /AF f D( to +select the columns for output. When you then call +)0 27 1 A(FunImagePut\201\202)27 0 TN TL()Ec /AF f D( or )0 31 1 A(FunTableRowPut\201\202)31 0 TN TL()Ec /AF f D(, a new +extension will be written that contains the header parameters from the +reference extension. Remember to call +)0 39 1 A(FunFlush\201\202)39 0 TN TL()Ec /AF f D( to complete output of a +given extension. + +)0 P(A complete example of this capability is given +in the )0 2 A(evcol example code)EA(. +The central algorithm is: +)UL()-1 LI( open the output file without a reference handle +)-1 LI( loop: open each input extension in turn +)UL()-1 LI( set the reference handle for output to the newly opened input extension +)-1 LI( read the input rows or image and perform processing +)-1 LI( write new rows or image to the output file +)-1 LI( flush the output +)-1 LI( close input extension)LU( +)-1 LI( close output file)LU( +Note that )0 39 1 A(FunFlush\201\202)39 0 TN TL()Ec /AF f D( is called +after processing each input extension in order to ensure that the +proper padding is written to the output file. A call to +)0 39 1 A(FunFlush\201\202)39 0 TN TL()Ec /AF f D( also ensures that the +extension header is written to the output file in the case where there +are no rows to output. + +)0 P(If you wish to output a new extension without using a +)0 23 1 A(Funtools reference handle)23 0 TN TL()Ec /AF f D(, you can +call FunInfoPut\201\202 to reset the FUN_OPS value directly. For a binary +table, you would then call FunColumnSelect\201\202 to set up the columns for +this new extension. +) 6 59 PR( /* reset the operations performed on this handle */ + int ops=0; + FunInfoPut\201ofun, FUN_OPS, &ops, 0\202; + FunColumnSelect\201fun, sizeof\201EvRec\202, NULL, + "MYCOL", "J", "w", FUN_OFFSET\201Ev, mycol\202, + NULL\202;)RP( +Once the FUN_OPS variable has been reset, the next I/O call on the +output extension will output the header, as expected. + + + + +)0 2 46 H(FunFlush)WB 112 Sn()WB 39 Sn( - flush data to output file)EA()EH( + + +)BD() 3 37 PR( #include + + void FunFlush\201Fun fun, char *plist\202)RP()ES( + + +)0 P(The )BD(FunFlush)ES( routine will flush data to a FITS output file. In +particular, it can be called after all rows have been written \201using +the )0 31 1 A(FunTableRowPut\201\202)31 0 TN TL()Ec /AF f D( routine\202 +in order to add the null padding that is required to complete a FITS +block. It also should be called after completely writing an image using +)0 27 1 A(FunImagePut\201\202)27 0 TN TL()Ec /AF f D( or after writing +the final row of an image using +)0 31 1 A(FunTableRowPut\201\202)31 0 TN TL()Ec /AF f D(. + +)0 P(The )BD(plist)ES( \201i.e., parameter list\202 argument is a string +containing one or more comma-delimited )BD(keyword=value)ES( +parameters. If the plist string contains the parameter +"copy=remainder" and the file was opened with a reference file, which, +in turn, was opened for extension copying \201i.e. the input +)0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D( mode also was "c" or "C"\202, +then FunFlush also will copy the remainder of the FITS extensions from +the input reference file to the output file. This normally would be +done only at the end of processing. + +)0 P(Note that )0 39 1 A(FunFlush\201\202)39 0 TN TL()Ec /AF f D( is called +with "copy=remainder" in the mode string by FunClose\201\202. This means +that if you close the output file before the reference input file, it +is not necessary to call +)0 39 1 A(FunFlush\201\202)39 0 TN TL()Ec /AF f D( explicitly, unless you +are writing more than one extension. See the +)0 2 A(evmerge example code)EA(. However, it is safe to +call )0 39 1 A(FunFlush\201\202)39 0 TN TL()Ec /AF f D( more than once +without fear of re-writing either the padding or the copied +extensions. + +)0 P(In addition, if )0 39 1 A(FunFlush\201\202)39 0 TN TL()Ec /AF f D( is +called on an output file with the plist set to "copy=reference" and if +the file was opened with a reference file, the reference extension is +written to the output file. This mechanism provides a simple way to +copy input extensions to an output file without processing the former. +For example, in the code fragment below, an input extension is set to +be the reference file for a newly opened output extension. If that +reference extension is not a binary table, it is written to the output +file: +) 22 73 PR( /* process each input extension in turn */ + for\201ext=0; ;ext++\202{ + /* get new extension name */ + sprintf\201tbuf, "%s[%d]", argv[1], ext\202; + /* open input extension -- if we cannot open it, we are done */ + if\201 !\201ifun=FunOpen\201tbuf, "r", NULL\202\202 \202 + break; + /* make the new extension the reference handle for the output file */ + FunInfoPut\201ofun, FUN_IFUN, &ifun, 0\202; + /* if its not a binary table, just write it out */ + if\201 !\201s=FunParamGets\201ifun, "XTENSION", 0, NULL, &got\202\202 || + strcmp\201s, "BINTABLE"\202\202{ + if\201 s \202 free\201s\202; + FunFlush\201ofun, "copy=reference"\202; + FunClose\201ifun\202; + continue; + } + else{ + /* process binary table */ + .... + } + })RP( + + + + +)0 2 47 H(FunClose)WB 113 Sn()WB 40 Sn( - close a Funtools data file)EA()EH( + + +)BD() 3 24 PR( #include + + void FunClose\201Fun fun\202)RP()ES( + + +)0 P(The )BD(FunClose\201\202)ES( routine closes a previously-opened Funtools data +file, freeing control structures. If a +)0 23 1 A(Funtools reference handle)23 0 TN TL()Ec /AF f D( +was passed to +the )0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D( call for this file, +and if copy mode also was specified for that file, then +)0 40 1 A(FunClose\201\202)40 0 TN TL()Ec /AF f D( also will copy the +remaining extensions from the input file to the output file \201if the +input file still is open\202. Thus, we recommend always closing the +output Funtools file )BD(before)ES( the input file. \201Alternatively, +you can call )0 39 1 A(FunFlush\201\202)39 0 TN TL()Ec /AF f D( +explicitly\202. + + + + +)0 2 48 H(FunRef:)WB 114 Sn()WB 23 Sn( the Funtools Reference Handle)EA()EH( + + +)0 2 49 H(Summary)WB 115 Sn()EH( +A description of how to use a Funtools reference handle to connect a +Funtools input file to an output file. + + +)0 2 50 H(Description)WB 116 Sn()EH( +)0 P(The Funtools reference handle connects a Funtools input file to a +Funtools output file so that parameters \201or even whole extensions\202 can +be copied from the one to the other. To make the connection, the Funtools +handle of the input file is passed to the +final argument of the +)0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D( call for the output file: +) 4 67 PR( if\201 !\201ifun = FunOpen\201argv[1], "r", NULL\202\202 \202 + gerror\201stderr, "could not FunOpen input file: %s\200n", argv[1]\202; + if\201 !\201ofun = FunOpen\201argv[2], "w", ifun\202\202 \202 + gerror\201stderr, "could not FunOpen output file: %s\200n", argv[2]\202;)RP( +It does not matter what type of input or output file \201or extension\202 is +opened, or whether they are the same type. When the output image or +binary table is written using +)0 27 1 A(FunImagePut\201\202)27 0 TN TL()Ec /AF f D( +or +)0 31 1 A(FunTableRowPut\201\202)31 0 TN TL()Ec /AF f D( +an appropriate header will be written first, with parameters copied +from the input extension. Of course, invalid parameters will be +removed first, e.g., if the input is a binary table and the output is +an image, then binary table parameters such as TFORM, TUNIT, +etc. parameters will not be copied to the output. + +)0 P(Use of a reference handle also allows default values to be passed +to +)0 27 1 A(FunImagePut\201\202)27 0 TN TL()Ec /AF f D( in order to +write out an output image with the same dimensions and data type +as the input image. To use the defaults from the input, a value +of 0 is entered for dim1, dim2, and bitpix. For example: +) 5 40 PR( fun = FunOpen\201argv[1], "r", NULL\202; + fun2 = FunOpen\201argv[2], "w", fun\202; + buf = FunImageGet\201fun, NULL, NULL\202; + ... process image data ... + FunImagePut\201fun2, buf, 0, 0, 0, NULL\202;)RP( +Of course, you often want to get information about the data type +and dimensions of the image for processing. The above code +is equivalent to the following: +) 7 61 PR( fun = FunOpen\201argv[1], "r", NULL\202; + fun2 = FunOpen\201argv[2], "w", fun\202; + buf = FunImageGet\201fun, NULL, NULL\202; + FunInfoGet\201fun, FUN_SECT_DIM1, &dim1, FUN_SECT_DIM2, &dim2, + FUN_SECT_BITPIX, &bitpix, 0\202; + ... process image data ... + FunImagePut\201fun2, buf, dim1, dim2, bitpix, NULL\202;)RP( + +)0 P(It is possible to change the reference handle for a given output Funtools +handle using the +)0 36 1 A(FunInfoPut\201\202)36 0 TN TL()Ec /AF f D( routine: +) 2 71 PR( /* make the new extension the reference handle for the output file */ + FunInfoPut\201fun2, FUN_IFUN, &fun, 0\202;)RP( +When this is done, Funtools specially resets the output file to start +a new output extension, which is connected to the new input reference +handle. You can use this mechanism to process multiple input extensions +into a single output file, by successively opening the former and +setting the reference handle for the latter. For example: +) 18 73 PR( /* open a new output FITS file */ + if\201 !\201fun2 = FunOpen\201argv[2], "w", NULL\202\202 \202 + gerror\201stderr, "could not FunOpen output file: %s\200n", argv[2]\202; + /* process each input extension in turn */ + for\201ext=0; ;ext++\202{ + /* get new extension name */ + sprintf\201tbuf, "%s[%d]", argv[1], ext\202; + /* open it -- if we cannot open it, we are done */ + if\201 !\201fun=FunOpen\201tbuf, "r", NULL\202\202 \202 + break; + /* make the new extension the reference handle for the output file */ + FunInfoPut\201fun2, FUN_IFUN, &fun, 0\202; + ... process ... + /* flush output extension \201write padding, etc.\202 */ + FunFlush\201fun2, NULL\202; + /* close the input extension */ + FunClose\201fun\202; + })RP( +In this example, the output file is opened first. Then each successive +input extension is opened, and the output reference handle is set to +the newly opened input handle. After data processing is performed, the +output extension is flushed and the input extension is closed, in +preparation for the next input extension. +)0 P(Finally, a reference handle can be used to copy other extensions from +the input file to the output file. Copy of other extensions is +controlled by adding a "C" or "c" to the mode string of the +)0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D( +call )BD(of the input reference file)ES(. If "C" is specified, then +other extensions are )BD(always)ES( copied \201i.e., copy is forced by the +application\202. If "c" is used, then other extensions are copied if the +user requests copying by adding a plus sign "+" to the extension name +in the bracket specification. For example, the )BD(funtable)ES( +program utilizes user-specified "c" mode so that the second example +below will copy all extensions: +) 4 60 PR( # copy only the EVENTS extension + csh> funtable "test.ev[EVENTS,circle\201512,512,10\202]" foo.ev + # copy ALL extensions + csh> funtable "test.ev[EVENTS+,circle\201512,512,10\202]" foo.ev)RP( +When extension copy is specified in the input file, the call to +)0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D( +on the input file delays the actual file open until the output file +also is opened \201or until I/O is performed on the input file, which +ever happens first\202. Then, when the output file is opened, the input +file is also opened and input extensions are copied to the output +file, up to the specific extension being opened. Processing of input +and output extensions then proceed. +)0 P(When extension processing is complete, the remaining extensions need to +be copied from input to output. This can be done explicitly, using the +)0 39 1 A(FunFlush\201\202)39 0 TN TL()Ec /AF f D( +call with the "copy=remaining" plist: +) 1 34 PR( FunFlush\201fun, "copy=remaining"\202;)RP( +Alternatively, this will happen automatically, if the output file +is closed )BD(before)ES( the input file: +) 5 77 PR( /* we could explicitly flush remaining extensions that need copying */ + /* FunFlush\201fun2, "copy=remaining"\202; */ + /* but if we close output before input, end flush is done automatically */ + FunClose\201fun2\202; + FunClose\201fun\202;)RP( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +)0 P()0 0 1 A(Go to Funtools Help Index)0 0 TN TL()Ec /AF f D( + +)0 5 51 H(Last)WB 117 Sn( updated: December 1, 2005)EH( + +)WB NL +/Cb Db D /Ct [16#00 16#00 16#00] D /Cl [16#00 16#00 16#00] D /CL -1 D Ct Sc +DS +/Ba f D /BO 0 D Bs +/UR (files.html) D +/Ti (Funtools Data Files) D +/Au () D +/Df f D +/ME [()] D + +0 BO R +()1 Sl()WB 42 Sn( + + +)0 2 52 H(FunFiles:)WB 120 Sn()WB 118 Sn( Funtools Data Files)EA()EH( + + +)0 2 53 H(Summary)WB 121 Sn()EH( +This document describes the data file formats \201FITS, array, raw +events\202 as well as the file types \201gzip, socket, etc.\202 supported +by Funtools. + + +)0 2 54 H(Description)WB 122 Sn()EH( +)0 P(Funtools supports FITS images and binary tables, and binary files +containing array \201homogeneous\202 data or event \201heterogeneous\202 data. +IRAF-style brackets are appended to the filename to specify various +kinds of information needed to characterize these data: +) 3 49 PR( file[ext|ind|ARRAY\201\202|EVENTS\201\202,section][filters] + or + file[ext|ind|ARRAY\201\202|EVENTS\201\202,section,filters])RP( +where: +)UL()-1 LI( )BD(file)ES( is the Funtools file name +)-1 LI( )BD(ext)ES( is the FITS extension name +)-1 LI( )BD(ind)ES( is the FITS extension number +)-1 LI( )BD(ARRAY\201\202)ES( is an array specification +)-1 LI( )BD(EVENTS\201\202)ES( is an event specification +)-1 LI( )BD(section)ES( is the image section specification +)-1 LI( )BD(filters)ES( are spatial region and table \201row\202 filters)LU( + +)0 2 55 H(Supported)WB 123 Sn()WB 43 Sn( Data Formats)EA()EH( +)0 P(Funtools programs \201and the underlying libraries\202 support the +following data file formats: +)UL()-1 LI( FITS images \201and image extensions\202 +)-1 LI( FITS binary tables +)-1 LI( binary files containing an array of homogeneous data +)-1 LI( binary files containing events, i.e. records of heterogeneous data +)-1 LI( column-based text files, which are documented )0 47 1 A(here)47 0 TN TL()Ec /AF f D( +)-1 LI( non-disk files and lists of files)LU( +Information needed to identify and characterize +the event or image data can be specified on the command line +using IRAF-style bracket notation appended to the filename: +) 5 69 PR( foo.fits # open FITS default extension + image.fits[3] # open FITS extension #3 + events.fits[EVENTS] # open EVENTS extension + array.file[ARRAY\201s1024\202] # open 1024x1024 short array + events.file[EVENTS\201x:1024,y:1024...\202] # open non-FITS event list)RP( +Note that in many Unix shells \201e.g., csh and tcsh\202, filenames must +be enclosed in quotes to protect the brackets from shell processing. + +)0 2 56 H(FITS)WB 124 Sn()WB 44 Sn( Images and Binary Tables)EA()EH( +)0 P(When )0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D( opens a FITS file +without a bracket specifier, the default behavior is to look for a +valid image in the primary HDU. In the absence of a primary image, +Funtools will try to open an extension named either )BD(EVENTS)ES( or +)BD(STDEVT)ES(, if one of these exists. This default behavior supports +both FITS image processing and standard X-ray event list processing +\201which, after all, is what we at SAO/HEAD do\202. + +)0 P(In order to open a FITS binary table or image extension explicitly, it +is necessary to specify either the extension name or the extension +number in brackets: +) 3 71 PR( foo.fits[1] # open extension #1: the primary HDU + foo.fits[3] # open extension #3 of a FITS file + foo.fits[GTI] # open GTI extension of a FITS file)RP( +The ext argument specifies the name of the FITS extension \201i.e. the +value of the EXTENSION header parameter in a FITS extension\202, while +the index specifies the value of the FITS EXTVER header parameter. +Following FITS conventions, extension numbers start at 1. + +)0 P(When a FITS data file is opened for reading using +)0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D(, the specified extension +is automatically located and is used to initialize the Funtools internal +data structures. + +)0 2 57 H(Non-FITS)WB 125 Sn()WB 45 Sn( Raw Event Files)EA()EH( + +In addition to FITS tables, Funtools programs and libraries can operate +on non-FITS files containing heterogeneous event records. To specify +such an event file, use: + +)UL()-1 LI( file[EVENTS\201event-spec\202] +)-1 LI( file[EVENTS\201\202])LU( +where )BD(event-spec)ES( is a string that specified the names, data +types, and optional image dimensions for each element of the event +record: +)UL()-1 LI( [name]:[n][type]:[\201lodim:\202hidim])LU( + +)0 P(Data types follow standard conventions for FITS binary tables, but include +two extra unsigned types \201'U' and 'V'\202: +)UL()-1 LI( )BD(B)ES( -- unsigned 8-bit char +)-1 LI( )BD(I)ES( -- signed 16-bit int +)-1 LI( )BD(J)ES( -- signed 32-bit int +)-1 LI( )BD(K)ES( -- signed 64-bit int +)-1 LI( )BD(E)ES( -- 32-bit float +)-1 LI( )BD(D)ES( -- 64-bit float +)-1 LI( )BD(U)ES( -- unsigned 16-bit int +)-1 LI( )BD(V)ES( -- unsigned 32-bit int)LU( +An optional integer value )BD(n)ES( can be prefixed to the type to indicate +that the element is an array of n values. For example: +) 1 37 PR( foo.fits[EVENTS\201x:I,y:I,status:4J\202])RP( +defines x and y as 16-bit ints and status as an array of 4 32-bit ints. + +)0 P(Furthermore, image dimensions can be attached to the event specification +in order to tell Funtools how to bin the events into an image. They +follow the conventions for the FITS TLMIN/TLMAX keywords. If the low +image dimension is not specified, it defaults to 1. Thus: + +)UL()-1 LI( RAWX:J:1:100 +)-1 LI( RAWX:J:100)LU( +both specify that the dimension of this column runs from 1 to 100. + +)0 P(NB: it is required that all padding be specified in the record +definition. Thus, when writing out whole C structs instead of +individual record elements, great care must be taken to include +the compiler-added padding in the event definition. + +)0 P(For example, suppose a FITS binary table has the following set of column +definitions: +) 22 54 PR( TTYPE1 = 'X ' / Label for field + TFORM1 = '1I ' / Data type for field + TLMIN1 = 1 / Min. axis value + TLMAX1 = 10 / Max. axis value + TTYPE2 = 'Y ' / Label for field + TFORM2 = '1I ' / Data type for field + TLMIN2 = 2 / Min. axis value + TLMAX2 = 11 / Max. axis value + TTYPE3 = 'PHA ' / Label for field + TFORM3 = '1I ' / Data type for field + TTYPE4 = 'PI ' / Label for field + TFORM4 = '1J ' / Data type for field + TTYPE5 = 'TIME ' / Label for field + TFORM5 = '1D ' / Data type for field + TTYPE6 = 'DX ' / Label for field + TFORM6 = '1E ' / Data type for field + TLMIN6 = 1 / Min. axis value + TLMAX6 = 10 / Max. axis value + TTYPE7 = 'DY ' / Label for field + TFORM7 = '1E ' / Data type for field + TLMIN7 = 3 / Min. axis value + TLMAX7 = 12 / Max. axis value)RP( + +An raw event file containing these same data would have the event +specification: +) 1 61 PR( EVENTS\201X:I:10,Y:I:2:11,PHA:I,PI:J,TIME:D,DX:E:10,DY:E:3:12\202)RP( + +)0 P(If no event specification string is included within the EVENTS\201\202 operator, +then the event specification is taken from the )BD(EVENTS)ES( environment +variable: +) 1 65 PR( setenv EVENTS "X:I:10,Y:I:10,PHA:I,PI:J,TIME:D,DX:E:10,DY:E:10")RP( + +)0 P(In addition to knowing the data structure, it is necessary to know the +)EM(endian)ES( ordering of the data, i.e., whether or not the data is +in )EM(bigendian)ES( format, so that we can convert to the native +format for this platform. This issue does not arise for FITS Binary +Tables because all FITS files use big-endian ordering, regardless of +platform. But for non-FITS data, big-endian data produced on a Sun +workstation but read on a Linux PC needs to be byte-swapped, since PCs +use little-endian ordering. To specify an ordering, use the +)EM(bigendian=)ES( or )EM(endian=)ES( keywords on the command-line +or the EVENTS_BIGENDIAN or EVENTS_ENDIAN environment variables. The +value of the )EM(bigendian)ES( variables should be "true" or "false", +while the value of the )EM(endian)ES( variables should be "little" or +"big". + +)0 P(For example, a PC can access data produced by a Sun using: +) 7 35 PR( hrc.nepr[EVENTS\201\202,bigendian=true] +or + hrc.nepr[EVENTS\201\202,endian=big] +or + setenv EVENTS_BIGENDIAN true +or + setenv EVENTS_ENDIAN big)RP( +If none of these are specified, the data are assumed to follow the +format for that platform and no byte-swapping is performed. + +)0 2 58 H(Non-FITS)WB 126 Sn()WB 46 Sn( Array Files)EA()EH( + +In addition to FITS images, Funtools programs and libraries can operate +on non-FITS files containing arrays of homogeneous data. To specify +an array file, use: +)UL()-1 LI( file[ARRAY\201array-spec\202] +)-1 LI( file[ARRAY\201\202])LU( + +where array-spec is of the form: +)UL()-1 LI( [type][dim1][.dim2][:skip][endian])LU( + +and where [type] is: +)UL()-1 LI( b \2018-bit unsigned char\202 +)-1 LI( s \20116-bit short int\202 +)-1 LI( u \20116-bit unsigned short int\202 +)-1 LI( i \20132-bit int\202 +)-1 LI( r,f \20132-bit float\202 +)-1 LI( d \20164-bit float\202)LU( + +)0 P(The dim1 specification is required, but dim2 is optional and defaults +to dim1. The skip specification is optional and defaults to 0. The +optional endian specification can be 'l' or 'b' and defaults to the +endian type for the current machine. + +)0 P(If no array specification is included within the ARRAY\201\202 operator, +then the array specification is taken from the )BD(ARRAY)ES( environment +variable. For example: + +) 7 76 PR( foo.arr[ARRAY\201r512\202] # bitpix=-32 dim1=512 dim2=512 + foo.arr[ARRAY\201r512.400\202] # bitpix=-32 dim1=512 dim2=400 + foo.arr[ARRAY\201r512.400]\202 # bitpix=-32 dim1=512 dim2=400 + foo.arr[ARRAY\201r512.400:2880\202] # bitpix=-32 dim1=512 dim2=400 skip=2880 + foo.arr[ARRAY\201r512l\202] # bitpix=-32 dim1=512 dim2=512 endian=little + setenv ARRAY "r512.400:2880" + foo.arr[ARRAY\201\202] # bitpix=-32 dim1=512 dim2=400 skip=2880)RP( + +)0 2 59 H(Specifying)WB 127 Sn()WB 49 Sn( Image Sections)EA()EH( + +Once a data file \201and possibly, a FITS extension\202 has been specified, +the next \201optional\202 part of a bracket specification can be used to +select image )BD(section)ES( information, i.e., to specify the x,y +limits of an image section, as well as the blocking factor to apply to +that section. This information can be added to any file specification but +only is used by Funtools image processing routines. + +)0 P(The format of the image section specification is one of the following: +)UL()-1 LI( file[xy0:xy1,block] +)-1 LI( file[x0:x1,y0:y1,block] +)-1 LI( file[x0:x1,*,block] +)-1 LI( file[*,y0:y1,block] +)-1 LI( file[*,block])LU( +where the limit values can be ints or "*" for default. A single "*" +can be used instead of val:val, as shown. Note that blocking is +applied to the section after it is extracted. + +)0 P(In addition to image sections specified by the lo and hi x,y limits, image +sections using center positions can be specified: +)UL()-1 LI( file[dim1@xcen,dim2@ycen] +)-1 LI( file[xdim2@xcen@ycen] +)-1 LI( file[dim1@xcen,dim2@ycen,block] +)-1 LI( file[dim@xcen@ycen,block])LU( +Note that the \201float\202 values for dim, dim1, dim2, xcen, ycen must be +specified or else the expression does not make sense! + +)0 P(In all cases, block is optional and defaults to 1. An 's' or 'a' can +be appended to signify "sum" or "average" blocking \201default is "sum"\202. +Section specifications are given in image coordinates by default. If you +wish to specify physical coordinates, add a 'p' as the last character +of the section specification, before the closing bracket. +For example: +) 2 21 PR()UL()-1 LI( file[-8:-7,-8:-7p] +)-1 LI( file[-8:-7,-8:-7,2p])LU()RP( +A section can be specified in any Funtools file name. If the operation +to be applied to that file is an imaging operation, then the +specification will be utilized. If the operation is purely a table +operation, then the section specification is ignored. + +)0 P(Do not be confused by: +) 2 15 PR( foo.fits[2] + foo.fits[*,2])RP( +The former specifies opening the second extension of the FITS file. +The latter specifies application of block 2 to the image section. + +)0 P(Note that the section specification must come after +any of FITS )BD(ext)ES( name or )BD(ind)ES( number, +but all sensible defaults are supported: +)UL()-1 LI( file[ext] +)-1 LI( file[ext,index] +)-1 LI( file[index] +)-1 LI( file[ext,section] +)-1 LI( file[ext,index,section] +)-1 LI( file[index,section] +)-1 LI( file[section])LU( + +)0 2 60 H(Binning)WB 128 Sn()WB 50 Sn( FITS Binary Tables and Non-FITS Event Files)EH( + +If a FITS binary table or a non-FITS raw event file is to be binned +into a 2D image \201e.g., using the +)0 10 1 A(funimage)10 0 TN TL()Ec /AF f D( +program\202, it is necessary to specify the two columns to be used for the +binning, as well as the dimensions of the image. Funtools first looks +for a specifier of the form: +) 1 74 PR( bincols=\201[xnam[:tlmin[:tlmax:[binsiz]]]],[ynam[:tlmin[:tlmax[:binsiz]]]]\202)RP( +in bracket syntax, and uses the column names thus specified. The tlmin, tlmax, +and binsiz specifiers determine the image binning dimensions using: +) 2 56 PR( dim = \201tlmax - tlmin\202/binsiz \201floating point data\202 + dim = \201tlmax - tlmin\202/binsiz + 1 \201integer data\202)RP( +These tlmin, tlmax, and binsiz specifiers can be omitted if TLMIN, +TLMAX, and TDBIN header parameters are present in the FITS binary +table header, respectively. If only one parameter is specified, it is +assumed to be tlmax, and tlmin defaults to 1. If two parameters are +specified, they are assumed to be tlmin and tlmax. + +For example, to bin an HRC event list columns "VPOS" and "UPOS", use: +) 1 31 PR( hrc.nepr[bincols=\201VPOS,UPOS\202])RP( +or +) 1 42 PR( hrc.nepr[bincols=\201VPOS:49152,UPOS:4096\202])RP( +Note that you can optionally specify the dimensions of these columns +to cover cases where neither TLMAX keywords are defined in +the header. If either dimension is specified, then both must be specified. + +)0 P(You can set the FITS_BINCOLS or EVENTS_BINCOLS environment variable as +an alternative to adding the "bincols=" specifier to each file name +for FITS binary tables and raw event files, respectively. If no +binning keywords or environment variables are specified, or if the +specified columns are not in the binary table, the Chandra parameters +CPREF \201or PREFX\202 are searched for in the FITS binary table header. +Failing this, columns named "X" and "Y" are sought. If these are not +found, the code looks for columns containing the characters "X" and +"Y". Thus, you can bin on "DETX" and "DETX" columns without +specifying them, if these are the only column names containing the "X" +and "Y" characters. + +)0 P(Ordinarily, each event or row contributes one count to an image pixel +during the 2D binning process. Thus, if five events all have the same +\201x,y\202 position, the image pixel value for that position will have a +value of five. It is possible to specify a variable contribution +for each event by using the vcol=[colname] filter spec: +) 1 15 PR( vcol=[colname])RP( +The vcol colname is a column containing a numeric value in each event row +that will be used as the contribution of the given event to its image +pixel. For example, consider an event file that has the following content: +) 10 24 PR( x:e:4 y:e:4 v:e + ------ ------ ---- + 1 1 1.0 + 2 2 2.0 + 3 3 3.0 + 4 4 0.0 + 1 1 1.0 + 2 2 2.0 + 3 3 3.0 + 4 4 4.0)RP( +There are two events with x,y value of \2011,1\202 so ordinarily a 2D image will +have a value of 2 in the \2011,1\202 pixel. If the v column is specified as the +value column: +) 1 20 PR( foo.fits'[vcol=v]')RP( +then each pixel will contain the additive sum of the associated \201x,y\202 +column values from the v column. For example, image pixel \2011,1\202 will +contain 1. + 1. = 2, image pixel \2012,2\202 will contain \2012 + 2\202 = 4, etc. + +)0 P(An important variation on the use of a value column to specify the +contribution an event makes to an image pixel is when the value column +contains the reciprocal of the event contribution. For this case, the +column name should be prefixed with a / \201divide sign\202 thus: +) 1 21 PR( foo.fits'[vcol=/v]')RP( +Each image pixel value will then be the sum of the reciprocals of the value +column. A zero in the value column results in NaN \201not a number\202. +Thus, in the above example, image pixel \2011.1\202 will contain 1/1 + 1/1 = 2, +image pixel \2012,2\202 will contain \2011/2 + 1/2\202 = 1, etc. Image pixel \2014,4\202 +will contain \2011/0 + 1/4\202 = NaN. + +)0 P(You can set the FITS_VCOL or EVENTS_VCOL environment variable as +an alternative to adding the "vcol=" specifier to each file name +for FITS binary tables and raw event files, respectively. + +)0 P(Finally, when binning events, the data type of the resulting 2D image +must be specified. This can be done with the "bitpix=[n]" keyword in +the bracket specification. For example: +) 1 45 PR( events.fits[bincols=\201VPOS,UPOS\202,bitpix=-32])RP( +will create a floating point image binned on columns VPOS and UPOS. +If no bitpix keyword is specified, bitpix=32 is assumed. As with +bincols values, you also can use the FITS_BITPIX and EVENTS_BITPIX +environment variables to set this value for FITS binary tables and +raw event files, respectively. + +)0 P(The )BD(funimage)ES( program also allows you to create a 1D image projection +along any column of a table by using the )BD(bincols=[column])ES( +filter specification and specifying a single column. +For example, the following command projects a 1D image along +the chipx column of a table: +) 1 43 PR( funimage ev.fits'[bincols=chipx]' im.fits)RP( +See )0 10 1 A(funimage)10 0 TN TL()Ec /AF f D( for more +information about creating 1D and 2D images. + +)0 P(Finally, please note that Funtools supports most FITS standards. +We will add missing support as required by the community. In general, +however, we do not support non-standard extensions. For example, we +sense the presence of the binary table 'variable length array' +proposed extension and we pass it along when copying and filtering +files, but we do not process it. We will add support for new standards +as they become official. + +)0 2 61 H(Table)WB 129 Sn()WB 119 Sn( and Spatial Region Filters)EH( +)0 P(Note that, in addition extensions and image sections, Funtools bracket +notation can be used to specify table and spatial region filters. These +filters are always placed after the image section information. They +can be specified in the same bracket or in a separate bracket +immediately following: +)UL()-1 LI( file[ext|ind|ARRAY\201\202|EVENTS\201\202,section][filters] +)-1 LI( file[ext|ind|ARRAY\201\202|EVENTS\201\202,section,filters])LU( +where: +)UL()-1 LI( )BD(file)ES( is the Funtools file name +)-1 LI( )BD(ARRAY\201\202)ES( is an array specification +)-1 LI( )BD(EVENTS\201\202)ES( is an event list specification +)-1 LI( )BD(ext)ES( is the FITS extension name +)-1 LI( )BD(ind)ES( is the FITS extension number +)-1 LI( )BD(section)ES( is the image section to extract +)-1 LI( )BD(filters)ES( are spatial region and table \201row\202 filters to apply)LU( + +The topics of table and region filtering are covered in detail in: +)UL()-1 LI()0 52 1 A(Table Filtering)52 0 TN TL()Ec /AF f D( +)-1 LI()0 54 1 A(Spatial Region Filtering)54 0 TN TL()Ec /AF f D()LU( + +)0 2 62 H(Disk)WB 130 Sn()WB 51 Sn( Files and Other Supported File Types)EA()EH( +)0 P(The specified )BD(file)ES( usually is an ordinary disk file. In +addition, gzip'ed files are supported in Funtools: gzip'ed input files +are automatically uncompressed as they are read, and gzip'ed output +files are compressed as they are written. NB: if a FITS binary table +is written in gzip format, the number of rows in the table will be set +to -1. Such a file will work with Funtools programs but will not work +with other FITS programs such as ds9. + +)0 P(The special keywords "stdin" and "stdout" designate Unix standard +input and standard output, respectively. The string "-" \201hyphen\202 will +be taken to mean "stdin" if the file is opened for reading and +"stdout" if the file is opened for writing. + +)0 P(A file also can be an INET socket on the same or another machine using +the syntax: +) 1 14 PR( machine:port)RP( +Thus, for example: +) 1 14 PR( karapet:1428)RP( +specifies that I/O should be performed to/from port 1428 on the +machine karapet. If no machine name is specified, the default is to +use the current machine: +) 1 7 PR( :1428)RP( +This means to open port 1428 on the current machine. Socket support +allows you to generate a distributed pipe: +) 2 48 PR( on karapet: funtask1 in.fits bynars:1428 + on bynars: funtask2 :1428 out.fits)RP( +The socket mechanism thus supports simple parallel processing using +)BD(process decomposition)ES(. Note that parallel processing using +)BD(data decomposition)ES( is supported via the )BD(section)ES( specifier \201see +below\202, and the )BD(row#)ES( specifier, which is part of +)0 52 1 A(Table Filtering)52 0 TN TL()Ec /AF f D(. + +)0 P(A file also can be a pointer to shared memory using the syntax: +) 1 22 PR( shm:[id|@key][:size])RP( +A shared memory segment is specified with a )BD(shm:)ES( prefix, +followed by either the shared memory id or the shared memory key +\201where the latter is prefixed by the '@' character\202. The size \201in +bytes\202 of the shared memory segment can then be appended \201preceded by +the ':' character\202. If the size specification is absent, the code will +attempt to determine the length automatically. + +If the open mode contains the string "w+", then the memory segment will be +created if it does not exist. \201It also will be released and deleted when the +file is closed.\202 In the case where a memory segment is being created, the +length of the segment is required. + +)0 P(A file also can be Unix piped command \201i.e. a program to run\202 using the syntax: +) 1 31 PR( "pipe: command arg1 ... argn")RP( +The output from the command must be a valid FITS file. It is important +to use quotes to protect spaces so that command arguments are passed +correctly. A silly example is: +) 1 60 PR( fundisp "pipe: funtable 'foo.fits[cir 512 512 .1]' stdout")RP( +This seemed like a good idea at the time ... + +)0 2 63 H(Lists)WB 131 Sn()WB 51 Sn( of Files)EA()EH( + +)0 P(Funtools also will process a list of files as a single file using the +syntax: +) 1 31 PR( "list: file1 file2 ... filen")RP( +The files in the list are separated by whitespace. Any of the +above file types can be used. For example, if two files, foo1.fits and +foo2.fits, are part of the same observation, they can be processed as +a single file \201using their own filters\202: +) 17 77 PR( fundisp "list: foo1.fits[cir\201512,512,10\202] foo2.fits[cir\201511,511,10\202]" + X Y PHA PI TIME DX DY + -------- -------- -------- -------- --------------------- -------- -------- + 512 512 6 7 79493997.45854475 578 574 + 512 512 8 9 79494575.58943175 579 573 + 512 512 5 6 79493631.03866175 578 575 + 512 512 5 5 79493290.86521725 578 575 + 512 512 8 9 79493432.00990875 579 573 + 511 511 5 5 79488631.09462625 580 575 + 511 511 10 11 79488780.60006675 580 573 + 511 511 4 4 79494562.35474326 580 575 + 511 511 6 6 79488203.01561825 580 575 + 511 511 6 6 79488017.99730176 580 575 + 511 511 4 4 79494332.45355175 580 575 + 511 511 9 10 79492685.94014275 581 574 + 511 511 5 5 79487708.71298325 580 575 + 511 511 8 9 79493719.00160225 581 573)RP( +Again, note that it is important to avoid spaces in the filters +because the list separator also is whitespace. To protect whitespace +in a filter, enclose the file specification in quotes: +) 1 72 PR( fundisp "list: 'foo1.fits[cir 512 512 .1]' foo2.fits[cir\201511,511,.1\202]")RP( + + + + + +)0 P()0 0 1 A(Go to Funtools Help Index)0 0 TN TL()Ec /AF f D( + +)0 5 64 H(Last)WB 132 Sn( updated: February 15, 2006)EH( + +)WB NL +/Cb Db D /Ct [16#00 16#00 16#00] D /Cl [16#00 16#00 16#00] D /CL -1 D Ct Sc +DS +/Ba f D /BO 0 D Bs +/UR (text.html) D +/Ti (Column-based Text Files) D +/Au () D +/Df f D +/ME [()] D + +0 BO R +()1 Sl()WB 47 Sn( + + +)0 2 65 H(Funtext:)WB 134 Sn()WB 133 Sn( Support for Column-based Text Files)EA()EH( + + +)0 2 66 H(Summary)WB 135 Sn()EH( +)0 P(This document contains a summary of the options for processing column-based +text files. + + +)0 2 67 H(Description)WB 136 Sn()EH( + +)0 P(Funtools will automatically sense and process "standard" +column-based text files as if they were FITS binary tables without any +change in Funtools syntax. In particular, you can filter text files +using the same syntax as FITS binary tables: +) 3 54 PR( fundisp foo.txt'[cir 512 512 .1]' + fundisp -T foo.txt > foo.rdb + funtable foo.txt'[pha=1:10,cir 512 512 10]' foo.fits)RP( + +)0 P(The first example displays a filtered selection of a text file. The +second example converts a text file to an RDB file. The third example +converts a filtered selection of a text file to a FITS binary table. + +)0 P(Text files can also be used in Funtools image programs. In this case, +you must provide binning parameters \201as with raw event files\202, using +the bincols keyword specifier: + +) 1 75 PR( bincols=\201[xname[:tlmin[:tlmax:[binsiz]]]],[yname[:tlmin[:tlmax[:binsiz]]])RP( + +For example: +) 1 64 PR( funcnts foo'[bincols=\201x:1024,y:1024\202]' "ann 512 512 0 10 n=10")RP( + +)0 2 68 H(Standard)WB 137 Sn( Text Files)EH( + +)0 P(Standard text files have the following characteristics: + +)UL()-1 LI( Optional comment lines start with # +)-1 LI( Optional blank lines are considered comments +)-1 LI( An optional table header consists of the following \201in order\202: +)UL( )-1 LI( a single line of alpha-numeric column names + )-1 LI( an optional line of unit strings containing the same number of cols + )-1 LI( an optional line of dashes containing the same number of cols)LU( +)-1 LI( Data lines follow the optional header and \201for the present\202 consist of + the same number of columns as the header. +)-1 LI( Standard delimiters such as space, tab, comma, semi-colon, and bar.)LU( + +)0 P(Examples: + +) 26 46 PR( # rdb file + foo1 foo2 foo3 foos + ---- ---- ---- ---- + 1 2.2 3 xxxx + 10 20.2 30 yyyy + + # multiple consecutive whitespace and dashes + foo1 foo2 foo3 foos + --- ---- ---- ---- + 1 2.2 3 xxxx + 10 20.2 30 yyyy + + # comma delims and blank lines + foo1,foo2,foo3,foos + + 1,2.2,3,xxxx + 10,20.2,30,yyyy + + # bar delims with null values + foo1|foo2|foo3|foos + 1||3|xxxx + 10|20.2||yyyy + + # header-less data + 1 2.2 3 xxxx + 10 20.2 30 yyyy)RP( + +)0 P(The default set of token delimiters consists of spaces, tabs, commas, +semi-colons, and vertical bars. Several parsers are used +simultaneously to analyze a line of text in different ways. One way +of analyzing a line is to allow a combination of spaces, tabs, and +commas to be squashed into a single delimiter \201no null values between +consecutive delimiters\202. Another way is to allow tab, semi-colon, and +vertical bar delimiters to support null values, i.e. two consecutive +delimiters implies a null value \201e.g. RDB file\202. A successful parser +is one which returns a consistent number of columns for all rows, with +each column having a consistent data type. More than one parser can +be successful. For now, it is assumed that successful parsers all +return the same tokens for a given line. \201Theoretically, there are +pathological cases, which will be taken care of as needed\202. Bad parsers +are discarded on the fly. + +)0 P(If the header does not exist, then names "col1", "col2", etc. are +assigned to the columns to allow filtering. Furthermore, data types +for each column are determined by the data types found in the columns +of the first data line, and can be one of the following: string, int, +and double. Thus, all of the above examples return the following +display: +) 4 58 PR( fundisp foo'[foo1>5]' + FOO1 FOO2 FOO3 FOOS + ---------- --------------------- ---------- ------------ + 10 20.20000000 30 yyyy)RP( + +)0 2 69 H(Comments)WB 138 Sn( Convert to Header Params)EH( + +)0 P(Comments which precede data rows are converted into header parameters and +will be written out as such using funimage or funhead. Two styles of comments +are recognized: + +)0 P(1. FITS-style comments have an equal sign "=" between the keyword and +value and an optional slash "/" to signify a comment. The strict FITS +rules on column positions are not enforced. In addition, strings only +need to be quoted if they contain whitespace. For example, the following +are valid FITS-style comments: + +) 5 55 PR( # fits0 = 100 + # fits1 = /usr/local/bin + # fits2 = "/usr/local/bin /opt/local/bin" + # fits3c = /usr/local/bin /opt/local/bin /usr/bin + # fits4c = "/usr/local/bin /opt/local/bin" / path dir)RP( + +Note that the fits3c comment is not quoted and therefore its value is the +single token "/usr/local/bin" and the comment is "opt/local/bin /usr/bin". +This is different from the quoted comment in fits4c. + +)0 P(2. Free-form comments can have an optional colon separator between the +keyword and value. In the absence of quote, all tokens after the +keyword are part of the value, i.e. no comment is allowed. If a string +is quoted, then slash "/" after the string will signify a comment. +For example: + +) 9 54 PR( # com1 /usr/local/bin + # com2 "/usr/local/bin /opt/local/bin" + # com3 /usr/local/bin /opt/local/bin /usr/bin + # com4c "/usr/local/bin /opt/local/bin" / path dir + + # com11: /usr/local/bin + # com12: "/usr/local/bin /opt/local/bin" + # com13: /usr/local/bin /opt/local/bin /usr/bin + # com14c: "/usr/local/bin /opt/local/bin" / path dir)RP( + +)0 P(Note that com3 and com13 are not quoted, so the whole string is part of +the value, while comz4c and com14c are quoted and have comments following +the values. + +)0 P(Some text files have column name and data type information in the header. +You can specify the format of column information contained in the +header using the "hcolfmt=" specification. See below for a detailed +description. + +)0 2 70 H(Multiple)WB 139 Sn( Tables in a Single File)EH( + +)0 P( +Multiple tables are supported in a single file. If an RDB-style file +is sensed, then a ^L \201vertical tab\202 will signify end of +table. Otherwise, an end of table is sensed when a new header \201i.e., +all alphanumeric columns\202 is found. \201Note that this heuristic does not +work for single column tables where the column type is ASCII and the +table that follows also has only one column.\202 You also can specify +characters that signal an end of table condition using the )BD(eot=)ES( +keyword. See below for details. + +)0 P(You can access the nth table \201starting from 1\202 in a multi-table file +by enclosing the table number in brackets, as with a FITS extension: + +) 1 18 PR( fundisp foo'[2]')RP( +The above example will display the second table in the file. +\201Index values start at 1 in oder to maintain logical compatibility +with FITS files, where extension numbers also start at 1\202. + + +)0 2 71 H(TEXT\201\202)WB 140 Sn( Specifier)EH( + +)0 P(As with ARRAY\201\202 and EVENTS\201\202 specifiers for raw image arrays and raw +event lists respectively, you can use TEXT\201\202 on text files to pass +key=value options to the parsers. An empty set of keywords is +equivalent to not having TEXT\201\202 at all, that is: + +) 2 23 PR( fundisp foo + fundisp foo'[TEXT\201\202]')RP( + +are equivalent. A multi-table index number is placed before the TEXT\201\202 +specifier as the first token, when indexing into a multi-table: + + fundisp foo'[2,TEXT\201...\202]' + +)0 P(The filter specification is placed after the TEXT\201\202 specifier, separated +by a comma, or in an entirely separate bracket: + +) 2 47 PR( fundisp foo'[TEXT\201...\202,circle 512 512 .1]' + fundisp foo'[2,TEXT\201...\202][circle 512 512 .1]')RP( + +)0 2 72 H(Text\201\202)WB 141 Sn( Keyword Options)EH( + +)0 P( +The following is a list of keywords that can be used within the TEXT\201\202 +specifier \201the first three are the most important\202: + +)0 DL( +)0 P()0 DT( delims="[delims]" +)DD(Specify token delimiters for this file. Only a single parser having these +delimiters will be used to process the file. +) 2 40 PR( fundisp foo.fits'[TEXT\201delims="!"\202]' + fundisp foo.fits'[TEXT\201delims="\200t%"\202]')RP( + +)0 P()0 DT( comchars="[comchars]" +)DD( Specify comment characters. You must include "\200n" to allow blank lines. +These comment characters will be used for all standard parsers \201unless delims +are also specified\202. +) 1 42 PR( fundisp foo.fits'[TEXT\201comchars="!\200n"\202]')RP( + +)0 P()0 DT( cols="[name1:type1 ...]" +)DD( Specify names and data type of columns. This overrides header +names and/or data types in the first data row or default names and +data types for header-less tables. +) 1 70 PR( fundisp foo.fits'[TEXT\201cols="x:I,y:I,pha:I,pi:I,time:D,dx:E,dy:e"\202]')RP( +)0 P(If the column specifier is the only keyword, then the cols= is not +required \201in analogy with EVENTS\201\202\202: +) 1 63 PR( fundisp foo.fits'[TEXT\201x:I,y:I,pha:I,pi:I,time:D,dx:E,dy:e\202]')RP( +Of course, an index is allowed in this case: +) 1 65 PR( fundisp foo.fits'[2,TEXT\201x:I,y:I,pha:I,pi:I,time:D,dx:E,dy:e\202]')RP( + +)0 P()0 DT( eot="[eot delim]" +)DD( Specify end of table string specifier for multi-table files. RDB +files support ^L. The end of table specifier is a string and the whole +string must be found alone on a line to signify EOT. For example: +) 1 37 PR( fundisp foo.fits'[TEXT\201eot="END"\202]')RP( +will end the table when a line contains "END" is found. Multiple lines +are supported, so that: +) 1 43 PR( fundisp foo.fits'[TEXT\201eot="END\200nGAME"\202]')RP( +will end the table when a line contains "END" followed by a line +containing "GAME". +)0 P(In the absence of an EOT delimiter, a new table will be sensed when a new +header \201all alphanumeric columns\202 is found. + +)0 P()0 DT( null1="[datatype]" +)DD( Specify data type of a single null value in row 1. +Since column data types are determined by the first row, a null value +in that row will result in an error and a request to specify names and +data types using cols=. If you only have a one null in row 1, you don't +need to specify all names and columns. Instead, use null1="type" to +specify its data type. + +)0 P()0 DT( alen=[n] +)DD(Specify size in bytes for ASCII type columns. +FITS binary tables only support fixed length ASCII columns, so a +size value must be specified. The default is 16 bytes. + +)0 P()0 DT( nullvalues=["true"|"false"] +)DD(Specify whether to expect null values. +Give the parsers a hint as to whether null values should be allowed. The +default is to try to determine this from the data. + +)0 P()0 DT( whitespace=["true"|"false"] +)DD( Specify whether surrounding white space should be kept as part of +string tokens. By default surrounding white space is removed from +tokens. + +)0 P()0 DT( header=["true"|"false"] +)DD(Specify whether to require a header. This is needed by tables +containing all string columns \201and with no row containing dashes\202, in +order to be able to tell whether the first row is a header or part of +the data. The default is false, meaning that the first row will be +data. If a row dashes are present, the previous row is considered the +column name row. + +)0 P()0 DT( units=["true"|"false"] +)DD(Specify whether to require a units line. +Give the parsers a hint as to whether a row specifying units should be +allowed. The default is to try to determine this from the data. + +)0 P()0 DT( i2f=["true"|"false"] +)DD(Specify whether to allow int to float conversions. +If a column in row 1 contains an integer value, the data type for that +column will be set to int. If a subsequent row contains a float in +that same column, an error will be signaled. This flag specifies that, +instead of an error, the float should be silently truncated to +int. Usually, you will want an error to be signaled, so that you can +specify the data type using cols= \201or by changing the value of +the column in row 1\202. + +)0 P()0 DT( comeot=["true"|"false"|0|1|2] +)DD(Specify whether comment signifies end of table. +If comeot is 0 or false, then comments do not signify end of table and +can be interspersed with data rows. If the value is true or 1 \201the +default for standard parsers\202, then non-blank lines \201e.g. lines +beginning with '#'\202 signify end of table but blanks are allowed +between rows. If the value is 2, then all comments, including blank +lines, signify end of table. + +)0 P()0 DT( lazyeot=["true"|"false"] +)DD(Specify whether "lazy" end of table should be permitted \201default is +true for standard formats, except rdb format where explicit ^L is required +between tables\202. A lazy EOT can occur when a new table starts directly +after an old one, with no special EOT delimiter. A check for this EOT +condition is begun when a given row contains all string tokens. If, in +addition, there is a mismatch between the number of tokens in the +previous row and this row, or a mismatch between the number of string +tokens in the prev row and this row, a new table is assumed to have +been started. For example: +) 9 20 PR( ival1 sval3 + ----- ----- + 1 two + 3 four + + jval1 jval2 tval3 + ----- ----- ------ + 10 20 thirty + 40 50 sixty)RP( +Here the line "jval1 ..." contains all string tokens. In addition, +the number of tokens in this line \2013\202 differs from the number of +tokens in the previous line \2012\202. Therefore a new table is assumed +to have started. Similarly: +) 9 20 PR( ival1 ival2 sval3 + ----- ----- ----- + 1 2 three + 4 5 six + + jval1 jval2 tval3 + ----- ----- ------ + 10 20 thirty + 40 50 sixty)RP( +Again, the line "jval1 ..." contains all string tokens. The number of +string tokens in the previous row \2011\202 differs from the number of +tokens in the current row\2013\202. We therefore assume a new table as been +started. This lazy EOT test is not performed if lazyeot is explicitly +set to false. + +)0 P()0 DT( hcolfmt=[header column format] +)DD( Some text files have column name and data type information in the header. +For example, VizieR catalogs have headers containing both column names +and data types: +) 3 95 PR( #Column e_Kmag \201F6.3\202 ?\201k_msigcom\202 K total magnitude uncertainty \2014\202 [ucd=ERROR] + #Column Rflg \201A3\202 \201rd_flg\202 Source of JHK default mag \2016\202 [ucd=REFER_CODE] + #Column Xflg \201I1\202 [0,2] \201gal_contam\202 Extended source contamination \20110\202 [ucd=CODE_MISC])RP( + +while Sextractor files have headers containing column names alone: + +) 4 79 PR( # 1 X_IMAGE Object position along x [pixel] + # 2 Y_IMAGE Object position along y [pixel] + # 3 ALPHA_J2000 Right ascension of barycenter \201J2000\202 [deg] + # 4 DELTA_J2000 Declination of barycenter \201J2000\202 [deg])RP( +The hcolfmt specification allows you to describe which header lines +contain column name and data type information. It consists of a string +defining the format of the column line, using "$col" \201or "$name"\202 to +specify placement of the column name, "$fmt" to specify placement of the +data format, and "$skip" to specify tokens to ignore. You also can +specify tokens explicitly \201or, for those users familiar with how +sscanf works, you can specify scanf skip specifiers using "%*"\202. +For example, the VizieR hcolfmt above might be specified in several ways: +) 3 67 PR( Column $col \201$fmt\202 # explicit specification of "Column" string + $skip $col \201$fmt\202 # skip one token + %*s $col \201$fmt\202 # skip one string \201using scanf format\202)RP( +while the Sextractor format might be specified using: +) 2 59 PR( $skip $col # skip one token + %*d $col # skip one int \201using scanf format\202)RP( +You must ensure that the hcolfmt statement only senses actual column +definitions, with no false positives or negatives. For example, the +first Sextractor specification, "$skip $col", will consider any header +line containing two tokens to be a column name specifier, while the +second one, "%*d $col", requires an integer to be the first token. In +general, it is preferable to specify formats as explicitly as +possible. + +)0 P(Note that the VizieR-style header info is sensed automatically by the +funtools standard VizieR-like parser, using the hcolfmt "Column $col +\201$fmt\202". There is no need for explicit use of hcolfmt in this case. + +)0 P()0 DT( debug=["true"|"false"] +)DD(Display debugging information during parsing. +)LD( + +)0 2 73 H(Environment)WB 142 Sn( Variables)EH( + +)0 P( +Environment variables are defined to allow many of these TEXT\201\202 values to be +set without having to include them in TEXT\201\202 every time a file is processed: + +) 10 36 PR( keyword environment variable + ------- -------------------- + delims TEXT_DELIMS + comchars TEXT_COMCHARS + cols TEXT_COLUMNS + eot TEXT_EOT + null1 TEXT_NULL1 + alen TEXT_ALEN + bincols TEXT_BINCOLS + hcolfmt TEXT_HCOLFMT)RP( + +)0 2 74 H(Restrictions)WB 143 Sn( and Problems)EH( + +)0 P( +As with raw event files, the '+' \201copy extensions\202 specifier is not +supported for programs such as funtable. + +)0 P(String to int and int to string data conversions are allowed by the +text parsers. This is done more by force of circumstance than by +conviction: these transitions often happens with VizieR catalogs, +which we want to support fully. One consequence of allowing these +transitions is that the text parsers can get confused by columns which +contain a valid integer in the first row and then switch to a +string. Consider the following table: +) 4 20 PR( xxx yyy zzz + ---- ---- ---- + 111 aaa bbb + ccc 222 ddd)RP( +The xxx column has an integer value in row one a string in row two, +while the yyy column has the reverse. The parser will erroneously +treat the first column as having data type int: +) 5 38 PR( fundisp foo.tab + XXX YYY ZZZ + ---------- ------------ ------------ + 111 'aaa' 'bbb' + 1667457792 '222' 'ddd')RP( +while the second column is processed correctly. This situation can be avoided +in any number of ways, all of which force the data type of the first column +to be a string. For example, you can edit the file and explicitly quote the +first row of the column: +) 10 40 PR( xxx yyy zzz + ---- ---- ---- + "111" aaa bbb + ccc 222 ddd + + [sh] fundisp foo.tab + XXX YYY ZZZ + ------------ ------------ ------------ + '111' 'aaa' 'bbb' + 'ccc' '222' 'ddd')RP( +You can edit the file and explicitly set the data type of the first column: +) 10 40 PR( xxx:3A yyy zzz + ------ ---- ---- + 111 aaa bbb + ccc 222 ddd + + [sh] fundisp foo.tab + XXX YYY ZZZ + ------------ ------------ ------------ + '111' 'aaa' 'bbb' + 'ccc' '222' 'ddd')RP( +You also can explicitly set the column names and data types of all columns, +without editing the file: +) 5 52 PR( [sh] fundisp foo.tab'[TEXT\201xxx:3A,yyy:3A,zzz:3a\202]' + XXX YYY ZZZ + ------------ ------------ ------------ + '111' 'aaa' 'bbb' + 'ccc' '222' 'ddd')RP( +The issue of data type transitions \201which to allow and which to disallow\202 +is still under discussion. + + + + + +)0 P()0 0 1 A(Go to Funtools Help Index)0 0 TN TL()Ec /AF f D( + +)0 5 75 H(Last)WB 144 Sn( updated: August 3, 2007)EH( + +)WB NL +/Cb Db D /Ct [16#00 16#00 16#00] D /Cl [16#00 16#00 16#00] D /CL -1 D Ct Sc +DS +/Ba f D /BO 0 D Bs +/UR (view.html) D +/Ti (Database View Support for Tables) D +/Au () D +/Df f D +/ME [()] D + +0 BO R +()1 Sl()WB 48 Sn( + + +)0 2 76 H(Funview:)WB 146 Sn()WB 145 Sn( Database View Support for Tables)EA()EH( + + +)0 2 77 H(Summary)WB 147 Sn()EH( +)0 P(This document contains a summary of the options for utilizing +database-inspired Views of tables. + + +)0 2 78 H(Description)WB 148 Sn()EH( + +)0 2 79 H(Database)WB 149 Sn( Views)EH( +)0 P(In database parlance, a )BD(View)ES( defines a "virtual table", i.e., +a description of row and/or column selection filters \201but with no +permanent storage space allocated\202. When used in place of a table, a +View selects the specified rows and/or columns from one or more real +tables. Views enable you to see complicated data tables in a more +convenient format. They also can be used as a security mechanism, by +restricting user access to specific columns and/or rows. [See: +) 1 72 PR(http://www.cs.unibo.it/~ciaccia/COURSES/RESOURCES/SQLTutorial/sqlch5.htm)RP( +for a good discussion of SQL Views.] + +)0 P(Funtools supports an expanded notion of Views for all tabular data +\201FITS tables, raw binary tables, and ASCII column files\202. Funtools +Views allow you to pre-set values for the filter specification, the +columns to activate, and display format \201though the latter is for +fundisp only\202. Setting the filter and column activation values +provides functionality equivalent to that of a classical database +View, while the ability to set the format is similar to classical +report writing capabilities. + +)0 2 80 H(Funtools)WB 150 Sn( View Attributes)EH( +)0 P(A Funtools View is a text file containing one or more of the following +columns: +) 7 46 PR( column description + ------ ----------------------------- + view name of view + file data file name or template + filter filter specification + columns columns to activate + format fundisp format specification)RP( +All of the attribute columns are optional, including +the )BD(view)ES( name itself. This means that a View can be named or +unnamed. Unnamed Views can refer to a specific file or a template of +files \201obviously if neither the view or the file column is specified, +the input View specification will never be used\202. You can specify any +combination of filter, column, and format parameters. \201It also is +possible to apply file-specific View to other files; see the discussion +on )BD(View Lists)ES( below\202. Each column has a size limit of 1024 characters. + +)0 P(For example, consider the following View file: +) 13 70 PR( view file format columns filter + ---- ---------------------- ------ ------------ ------- + x3 ${HOME}/data/snr.ev I=%4d x y pi pha cir 512 512 .1 + x2 ${HOME}/data/snr.ev x y pi pha cir 512 512 .1 + x1 ${HOME}/data/snr.ev cir 512 512 .1 + x1a ${HOME}/data/snr.ev x y pi pha + x0 ${HOME}/data/snr.ev + xf I=%4d + xc x y pi pha + xr cir 512 512 .1 + *.ev x y pi pha + *.fit x y dx dy cir 400 400 3 + *.fits I=%3d x y dx dy cir 400 400 3)RP( +This database example is in rdb format, i.e. using tab delimiters and +permitting null values. Any valid ASCII table format is acceptable, +but if you use a format that does not permit null values, it will be +necessary to quote the null strings. + +)0 P(The first five entries \201x3, x2, x1, x1a, x0\202 are named entries defining +default values specifically for the snr.ev data file. Typically, you +would use these Views by specifying View name, and the corresponding +file, filter, column, and format values would be used. Note that the x0 +View is essentially an alias for the pathname of this file. + +)0 P(The next three entries define defaults that can be applied to any +file. You typically would use these View names in conjunction with +a specific file name \201see )BD(View Lists)ES( below\202 so that the associated +parameter\201s\202 were applied to that file. + +)0 P(The last three entry in the database define unnamed Views that +pertains to all files ending with the specified templates. In these +cases, any View that specifies a file name matching the file template +would be processed with the associated parameter attributes. + +)0 2 81 H(Invoking)WB 151 Sn( a Funtools View \201in Place of an Input File\202)EH( +)0 P(To use a Funtools View, you simply pre-pend the "v:" prefix to a View name or +a file name where an input file name usually is specified. For example: +) 1 14 PR( fundisp v:x3)RP( +specifies that the View named x3 \201with its file name and associated +parameters\202 is processed as the input file to fundisp. Using the +example database, above, this is equivalent to: +) 1 73 PR( fundisp -f "I=%4d" ${HOME}/data/snr.ev'[cir 512 512 .1]' "x y pi pha")RP( +That is, the format is used with fundisp's -f \201format\202 switch, while the +filename and extension are composed of the x3 View's filename and +region filter. + +)0 P(Similarly, executing a command such as: +) 1 19 PR( fundisp v:foo.fit)RP( +will match the unnamed View associated with the template "*.fit". +This is equivalent to executing: +) 1 46 PR( fundisp foo.fit'[cir 400 400 3]' "x y dx dy")RP( +Of course, if you omit the "v:" prefix, then no View processing takes place: +) 2 66 PR( fundisp foo.fit # process foo.fit without any View parameters + fundisp x3 # error \201assuming there is no file named x3\202)RP( + +)0 2 82 H(Basic)WB 152 Sn( View Matching Rules)EH( + +)0 P(When a "v:" prefix is recognized, Funtools searches for a View database +file in the following order: +) 5 59 PR( location description + ------------ ------------------------------------ + FUN_VIEWFILE environment variable \201any file name\202 + ./.funtools.vu hidden file, default name + $HOME/.funtools.vu hidden file, default name)RP( +The first View database file located is used to construct a new +filename, as well as an activation column specification and a format +specification. The following rules are used: + +)0 P(1. An attempt is made to match the input name \201i.e., the part of the +input View after the "v:" prefix\202 against the )BD(view)ES( column value +\201if present\202 of each row in the database. If a match is found, the +values of all non-blank columns are saved for later use. Also note +that the first match terminates the search: i.e., )BD(the order of the +database rows matters)ES(. + +)0 P(2. If no )BD(view)ES( match is made, an attempt is made to match the input +name against the )BD(file)ES( column value \201if present\202. Matching is +performed on the full pathname of both the input name and the +database file name, and on the non-directory \201root\202 part of these +files. This means that the root specification: +) 1 18 PR( fundisp v:snr.ev)RP( +will match a row in the database that has a full pathname in the file, +allowing you to use a )BD(file)ES(-matched View without having to +specify the full pathname. In this example, the "v:snr.ev" View +specification will match the first row \201v:x3\202 in the database: +) 1 67 PR( x3 ${HOME}/data/snr.ev I=%4d x y pi pha cir 512 512 .1)RP( +even though the row contains a fully qualified pathname as the file +value. Once again, values of all non-blank columns are saved, and the +first match terminates the search. + +)0 P(3. If neither a )BD(view)ES( or a )BD(view)ES( match has been found, +then a simple template match is attempted against the )BD(view)ES( +values. Template matching supports a simplified version of file +globbing \201not a regular expression\202, with support for a single "*" +\201all characters\202, "?" \201single character\202, or "[...]" \201range\202 specification. + +)0 P(4. If no template match was found on the )BD(view)ES( column, then a +simple template match is attempted against the )BD(file)ES( columns. + +)0 P(5. If no match is found, then the filename \201minus the "v:" prefix\202 is +returned. + +)0 2 83 H(More)WB 153 Sn( on View Matching Rules: Single vs. Multiple Matches )EH( + +The matching rules described above stop after the first match, +regardless of whether that match provides values for all three +parameters \201filter, columns, and format\202. In cases where a )BD(view)ES( +or )BD(file)ES( match does not provide all three values, it is possible +that a template match might do so. With regard to the example View +database above, the x1 View provides only a filter, while omitting +both the format and columns values. But note that the final rows in +the database could provide the values via a template match on the +filename. This sort of multiple matching is especially valuable in +order to provide "global" values to several Views. + +)0 P(Obviously, multiple matching might not be wanted in every +case. Therefore, we support both multiple matching and single matching +according to the value of the FUN_VIEWMATCH environment variable. If +the FUN_VIEWMATCH environment variable exists and if its value begins +with "s", then a single match is used and missing parameters are not +filled in with subsequent template matches on the file name. That is, +matching rules above are followed exactly as explained above. If the +value of this environment variable begins with "m" \201or does not exist\202, +then multiple matches are used to try to fill in missing parameters. +In this case, template matching always takes place and missing values are +taken from these template matches. + +)0 P(Thus, in the example above, the View specification: +) 1 14 PR( fundisp v:x1)RP( +will take the file name and filter value from the x1 View: +) 1 70 PR( x1 ${HOME}/data/snr.ev cir 512 512 .1)RP( +The column value then will be taken from the "*.ev" file template match +against the x1 file name: +) 1 52 PR( *.ev x y pi pha)RP( +Note once again that order is important: missing values are taken in the +order in which the template matches are processed. + +)0 2 84 H(View)WB 154 Sn( Lists: Applying a View to Any File)EH( + +)0 P(It is possible to apply a named View, or even several Views, to any +data file by appending a )BD(viewlist)ES( immediately after the standard "v:" +prefix. A viewlist takes the form: +) 1 15 PR( :v1,v2,...vn:)RP( +where v1, v2, etc. are named Views. The two ":" colon characters surrounding +the list are required. Thus, the syntax for applying a viewlist to a file is: +) 1 34 PR( v::view1,view2,...viewn:filename)RP( +Note that the name after the last ":" is assumed to be a file; it is +not permissible \201or sensible\202 to use a View name. + +)0 P(For example, the View specification: +) 1 19 PR( fundisp v::x2:foo)RP( +applies the x2 View to the file foo \201even if there is a View named foo\202 +and \201in using our example database\202 is equivalent to: +) 1 45 PR( ./fundisp foo'[cir 512 512 .1] "x y pi pha")RP( +The same command can be effected using a list of Views: +) 1 23 PR( fundisp v::x1,x1a:foo)RP( + +)0 P(What happens if a viewlist is used and the file also matches a +template? Consider, for example, this View specification: +) 1 23 PR( fundisp v::x2:foo.fit)RP( +Here, the x2 View will supply filter and column values, while the +template *.fit can also supply \201different\202 filter and column +values. In this case, the explicitly specified Views of the viewlist +trump the matched view values. + +)0 P(On the other hand, if a file template match can supply a View value +that is not supplied by the viewlist, then that value will be taken +from the file template match. For example: +) 1 24 PR( fundisp v::x2:foo.fits)RP( +does not explicitly supply a format value, but the file match on *.fits +can and does. You can avoid supplying missing values using file template +matching by replacing the first ":" with a "-" in a viewlist +specification: +) 1 24 PR( fundisp v:-x2:foo.fits)RP( +The use of ":+" to explicitly allow file template matching is also +supported, but is the same as the default case. Note that the nuances +of viewlist support are subject to change as our experience and +understanding grow. + +)0 2 85 H(Overriding)WB 155 Sn( Values Associated with a View)EH( + +)0 P(To override values associated with a View, simply supply the override +values in the correct place on the command line. Thus, given +the example database described above, the command: +) 1 14 PR( fundisp v:x3)RP( +specifies that the View named x3, along with its file name and +associated parameters, be processed as the input file to fundisp in +this way: +) 1 73 PR( fundisp -f "I=%4d" ${HOME}/data/snr.ev'[cir 512 512 .1]' "x y pi pha")RP( +To override one or more of these values, simply specify a new value +for the format, filter, or columns. For example, if your input View file +contains a filter, then the View will use that filter as an override +of the View filter: +) 1 31 PR( fundisp v:x3'[cir 400 400 3]')RP( +will use the columns and format of the x3 View but not the x3 filter. Further +examples are: +) 2 67 PR( fundisp v:x3 "x y dx dy" # activate a different set of columns + fundisp -f "I=%3d" v:x3 # use a different format statement)RP( + +)0 P(Note that extension names, extension index values, and other +non-filter specifications )BD(do not)ES( override the View +filter. Thus: +) 1 22 PR( fundisp v:foo.fit[3])RP( +will still use the filter associated with the .fit template \201see above\202, since +the "3" is an extension index, not a filter. + +)0 2 86 H(Environment)WB 156 Sn( Variables)EH( + +The following environment variables are used by Funtools Views: +)0 DL()0 DT()BD(FUN_VIEWNAME)ES( +)DD( The )BD(FUN_VIEWNAME)ES( environment variable specifies the +name and location of the View database file. If not present, the +files ./.funtools.vu and $HOME/.funtools.vu are searched for, in +that order. + +)0 DT()BD(FUN_VIEWMATCH)ES( +)DD( The )BD(FUN_VIEWMATCH)ES( environment variable specifies whether a +single match or multiple match algorithm is used to locate parameter +values. If the value of this environment variable begins with "s", +then a single match is used and missing parameters are not filled in +with subsequent template matches on the file name. If the value begins +with "m", then multiple matches are used to try to fill in missing +parameters. The default is to use multiple matches.)LD( + +)0 2 87 H(Restrictions)WB 157 Sn( and Problems)EH( + +Support for overriding a filter \201while not overriding extension names, +extension indexes, etc.\202 requires that we can sense the presence of a +filter in a bracket specification. It is unclear yet whether our +algorithm is perfect. + +)0 P()0 0 1 A(Go to Funtools Help Index)0 0 TN TL()Ec /AF f D( + +)0 5 88 H(Last)WB 158 Sn( updated: August 3, 2007)EH( + +)WB NL +/Cb Db D /Ct [16#00 16#00 16#00] D /Cl [16#00 16#00 16#00] D /CL -1 D Ct Sc +DS +/Ba f D /BO 0 D Bs +/UR (filters.html) D +/Ti (Table Filtering) D +/Au () D +/Df f D +/ME [()] D + +0 BO R +()1 Sl()WB 52 Sn( + + +)0 2 89 H(Funfilters:)WB 165 Sn()WB 159 Sn( Filtering Rows in a Table)EA()EH( + + +)0 2 90 H(Summary)WB 166 Sn()EH( +)0 P(This document contains a summary of the user interface for +filtering rows in binary tables. + + +)0 2 91 H(Description)WB 167 Sn()EH( +)0 P(Table filtering allows a program to select rows from an table \201e.g., +X-ray event list\202 by checking each row against one or more expressions +involving the columns in the table. When a table is filtered, only +valid rows satisfying these expressions are passed through for processing. + +)0 P(A filter expression is specified using bracket notation appended to +the filename of the data being processed: +) 1 23 PR( foo.fits[pha==1&)SY(\160)ES(==2])RP( +It is also possible to put region specification inside a file and +then pass the filename in bracket notation: +) 1 19 PR( foo.fits[@my.reg])RP( +Filters must be placed after the extension and image section +information, when such information is present. The correct order is: +)UL()-1 LI( file[fileinfo,sectioninfo][filters] +)-1 LI( file[fileinfo,sectioninfo,filters])LU( +where: +)UL()-1 LI( )BD(file)ES( is the Funtools file name +)-1 LI( )BD(fileinfo)ES( is an ARRAY, EVENT, FITS extension, or FITS index +)-1 LI( )BD(sectioninfo)ES( is the image section to extract +)-1 LI( )BD(filters)ES( are spatial region and table \201row\202 filters to apply)LU( +See )0 42 1 A(Funtools Files)42 0 TN TL()Ec /AF f D( for more information +on file and image section specifications. + +)0 2 92 H(Filter)WB 168 Sn( Expressions)EH( + +)0 P(Table filtering can be performed on columns of data in a FITS +binary table or a raw event file. Table filtering is accomplished by +means of )BD(table filter specifications)ES(. An table filter +specification consists of one or more )BD(filter expressions)ES( Filter +specifications also can contain comments and local/global processing +directives. + +)0 P(More specifically, a filter specification consist of one or more lines +containing: +) 13 75 PR( # comment until end of line + # include the following file in the table descriptor + @file + # each row expression can contain filters separated by operators + [filter_expression] BOOLOP [filter_expression2], ... + # each row expression can contain filters separated by the comma operator + [filter_expression1], [filter_expression2], ... + # the special row# keyword allows a range of rows to be processed + row#=m:n + # or a single row + row#=m + # regions are supported -- but are described elsewhere + [spatial_region_expression])RP( + +)0 P(A single filter expression consists of an arithmetic, logical, or +other operations involving one or more column values from a +table. Columns can be compared to other columns, to header values, +or to numeric constants. Standard math functions can be applied to +columns. Separate filter expressions can be combined using boolean operators. +Standard C semantics can be used when constructing expressions, with +the usual precedence and associativity rules holding sway: +) 15 55 PR( Operator Associativity + -------- ------------- + \201\202 left to right + !! \201logical not\202 right to left + ! \201bitwise not\202 - \201unary minus\202 right to left + * / left to right + + - left to right + < <= > >= left to right + == != left to right + & \201bitwise and\202 left to right + ^ \201bitwise exclusive or\202 left to right + | \201bitwise inclusive or\202 left to right + && \201logical and\202 left to right + || \201logical or\202 left to right + = right to left)RP( +For example, if energy and pha are columns in a table, +then the following are valid expressions: +) 4 24 PR( pha>1 + energy == pha + \201pha>1\202 && \201energy<=2\202 + max\201pha,energy\202>=2.5)RP( + +)0 P(Comparison values can be integers or floats. Integer comparison values can be +specified in decimal, octal \201using '0' as prefix\202, hex \201using '0x' as prefix\202 +or binary \201using '0b' as prefix\202. Thus, the following all specify the same +comparison test of a status mask: +) 4 40 PR( \201status & 15\202 == 8 # decimal + \201status & 017\202 == 010 # octal + \201status & 0xf\202 == 0x8 # hex + \201status & 0b1111\202 == 0b1000 # binary)RP( +)0 P(The special keyword row# allows you to process a range of rows. +When row# is specified, the filter code skips to the designated +row and only processes the specified number of rows. The +"*" character can be utilized as the high limit value to denote +processing of the remaining rows. Thus: +) 1 14 PR( row#=100:109)RP( +processes 10 rows, starting with row 100 \201counting from 1\202, +while: +) 1 12 PR( row#=100:*)RP( +specifies that all but the first 99 rows are to be processed. + +)0 P(Spatial region filtering allows a program to select regions of an +image or rows of a table \201e.g., X-ray events\202 using simple geometric +shapes and boolean combinations of shapes. For a complete description +of regions, see )0 54 1 A(Spatial Region Filtering)54 0 TN TL()Ec /AF f D(. + +)0 2 93 H(Separators)WB 169 Sn()WB 160 Sn( Also Are Operators)EA()EH( +)0 P(As mentioned previously, multiple filter expressions can be specified +in a filter descriptor, separated by commas or new-lines. +When such a comma or new-line separator is used, the boolean AND operator +is automatically generated in its place. Thus and expression such as: +) 1 15 PR( pha==1,pi=2:4)RP( +is equivalent to: +) 1 26 PR( \201pha==1\202 && \201pi>=2&)SY(\160)ES(<=4\202)RP( +)0 P([Note that the behavior of separators is different for filter expressions +and spatial region expressions. The former uses AND as the operator, while +the latter user OR. See +)0 60 1 A(Combining Region and Table Filters)60 0 TN TL()Ec /AF f D( +for more information about these conventions and how they are treated +when combined.] + +)0 2 94 H(Range)WB 170 Sn()WB 161 Sn( Lists)EA()EH()0 P( +)0 P(Aside from the standard C syntax, filter expressions can make use of +IRAF-style )BD(range lists)ES( which specify a range of values. The +syntax requires that the column name be followed by an '=' sign, which +is followed by one or more comma-delimited range expressions of the form: +) 4 52 PR( col = vv # col == vv in range + col = :vv # col <= vv in range + col = vv: # col >= vv in range + col = vv1:vv2 # vv1 <= col <= vv2 in range)RP( +The vv's above must be numeric constants; the right hand side of a +range list cannot contain a column name or header value. +)0 P(Note that, unlike an ordinary comma separator, the comma separator used +between two or more range expressions denotes OR. Thus, when two or +more range expressions are combined with a comma separator, the resulting +expression is a shortcut for more complicated boolean logic. For example: +) 1 18 PR( col = :3,6:8,10:)RP( +is equivalent to: +) 1 47 PR( \201col<=3\202 || \201col>=6 && col <=8\202 || \201col >=10\202)RP( +Note also that the single-valued rangelist: +) 1 11 PR( col = val)RP( +is equivalent to the C-based filter expression: +) 1 12 PR( col == val)RP( +assuming, of course, that val is a numeric constant. + +)0 2 95 H(Math)WB 171 Sn()WB 162 Sn( Operations and Functions)EA()EH()0 P( +)0 P(It is permissible to specify C math functions as part of the filter syntax. +When the filter parser recognizes a function call, it automatically +includes the math.h and links in the C math library. Thus, it is +possible to filter rows by expressions such as these: +)UL()-1 LI(\201pi+pha\202>\2012+log\201pi\202-pha\202 +)-1 LI( min\201pi,pha\202*14>x +)-1 LI( max\201pi,pha\202==\201pi+1\202 +)-1 LI( feq\201pi,pha\202 +)-1 LI( div\201pi,pha\202>0)LU( +The function feq\201a,b\202 returns true \2011\202 if the difference between a and b +\201taken as double precision values\202 is less than approximately 10E-15. +The function div\201a,b\202 divides a by b, but returns NaN \201not a number\202 +if b is 0. It is a safe way to avoid floating point errors when +dividing one column by another. + +)0 2 96 H(Include)WB 172 Sn()WB 163 Sn( Files)EA()EH()0 P( +)0 P(The special )BD(@filename)ES( directive specifies an include file +containing filter expressions. This file is processed as part of +the overall filter descriptor: +) 1 23 PR( foo.fits[pha==1,@foo])RP( + +)0 2 97 H(Header)WB 173 Sn()WB 164 Sn( Parameters)EA()EH()0 P( +)0 P(The filter syntax supports comparison between a column value and a +header parameter value of a FITS binary tables \201raw event files have no +such header\202. The header parameters can be taken from the binary +table header or the primary header. For example, assuming there is a +header value MEAN_PHA in one of these headers, you can select photons +having exactly this value using: + +)UL()-1 LI( pha==MEAN_PHA)LU( + +)0 2 98 H(Examples)WB 174 Sn()EH( +)0 P(Table filtering is more easily described by means of examples. +Consider data containing the following table structure: +)UL()-1 LI( double TIME +)-1 LI( int X +)-1 LI( int Y +)-1 LI( short PI +)-1 LI( short PHA +)-1 LI( int DX +)-1 LI( int DY)LU( + +)0 P(Tables can be filtered on these columns using IRAF/QPOE range syntax or +any valid C syntax. The following examples illustrate the possibilities: +)0 DL( +)0 P()0 DT( pha=10 +)0 DT( pha==10 +)DD( select rows whose pha value is exactly 10 + +)0 P()0 DT( pha=10:50 +)DD( select rows whose pha value is in the range of 10 to 50 + +)0 P()0 DT( pha=10:50,100 +)DD( select rows whose pha value is in the range of 10 to 50 or is +equal to 100 + +)0 P()0 DT( pha>=10 && pha<=50 +)DD( select rows whose pha value is in the range of 10 to 50 + +)0 P()0 DT( pi=1,2&&pha>3 +)DD( select rows whose pha value is 1 or 2 and whose pi value is 3 + +)0 P()0 DT( pi=1,2 || pha>3 +)DD( select rows whose pha value is 1 or 2 or whose pi value is 3 + +)0 P()0 DT( pha==pi+1 +)DD( select rows whose pha value is 1 less than the pi value + +)0 P()0 DT( \201pha==pi+1\202 && \201time>50000.0\202 +)DD( select rows whose pha value is 1 less than the pi value +and whose time value is greater than 50000 + +)0 P()0 DT(\201pi+pha\202>20 +)DD( select rows in which the sum of the pi and pha values is greater +than 20 + +)0 P()0 DT( pi%2==1 +)DD( select rows in which the pi value is odd)LD( + +)0 P(Currently, integer range list limits cannot be specified in binary +notation \201use decimal, hex, or octal instead\202. Please contact us if +this is a problem. + + + + + +)0 P()0 0 1 A(Go to Funtools Help Index)0 0 TN TL()Ec /AF f D( + +)0 5 99 H(Last)WB 175 Sn( updated: November 17, 2005)EH( + +)WB NL +/Cb Db D /Ct [16#00 16#00 16#00] D /Cl [16#00 16#00 16#00] D /CL -1 D Ct Sc +DS +/Ba f D /BO 0 D Bs +/UR (idx.html) D +/Ti (Table Filtering with Indexes) D +/Au () D +/Df f D +/ME [()] D + +0 BO R +()1 Sl()WB 53 Sn( + + +)0 2 100 H(Funidx:)WB 177 Sn()WB 176 Sn( Using Indexes to Filter Rows in a Table)EA()EH( + + +)0 2 101 H(Summary)WB 178 Sn()EH( +)0 P(This document contains a summary of the user interface for +filtering rows in binary tables with indexes. + + +)0 2 102 H(Description)WB 179 Sn()EH( +)0 P(Funtools )0 52 1 A(Table Filtering)52 0 TN TL()Ec /AF f D( allows rows in a +table to be selected based on the values of one or more columns in the +row. Because the actual filter code is compiled on the fly, it is very +efficient. However, for very large files \201hundreds of Mb or larger\202, +evaluating the filter expression on each row can take a long time. Therefore, +funtools supports index files for columns, which are used automatically during +filtering to reduce dramatically the number of row evaluations performed. +The speed increase for indexed filtering can be an order of magnitude or +more, depending on the size of the file. + +)0 P(The )0 11 1 A(funindex)11 0 TN TL()Ec /AF f D( program creates an +index on one or more columns in a binary table. For example, to create an index +for the column pi in the file huge.fits, use: +) 1 23 PR( funindex huge.fits pi)RP( +This will create an index named huge_pi.idx. + +)0 P(When a filter expression is initialized for row evaluation, funtools +looks for an index file for each column in the filter expression. If +found, and if the file modification date of the index file is later +than that of the data file, then the index will be used to reduce the +number of rows that are evaluated in the filter. When +)0 54 1 A(Spatial Region Filtering)54 0 TN TL()Ec /AF f D( is part of the +expression, the columns associated with the region are checked for index +files. + +)0 P(If an index file is not available for a given column, then in general, +all rows must be checked when that column is part of a filter +expression. This is not true, however, when a non-indexed column is +part of an AND expression. In this case, only the rows that pass the +other part of the AND expression need to be checked. Thus, in some cases, +filtering speed can increase significantly even if all columns are not +indexed. + +)0 P(Also note that certain types of filter expression syntax cannot make +use of indices. For example, calling functions with column names as +arguments implies that all rows must be checked against the function +value. Once again, however, if this function is part of an AND +expression, then a significant improvement in speed still is possible +if the other part of the AND expression is indexed. + +)0 P(For example, note below the dramatic speedup in searching a 1 Gb +file using an AND filter, even when one of the columns \201pha\202 has no +index: + +) 49 69 PR( time fundisp \200 + huge.fits'[idx_activate=0,idx_debug=1,pha=2348&&cir 4000 4000 1]' \200 + "x y pha" + x y pha + ---------- ----------- ---------- + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 42.36u 13.07s 6:42.89 13.7% + + time fundisp \200 + huge.fits'[idx_activate=1,idx_debug=1,pha=2348&&cir 4000 4000 1]' \200 + "x y pha" + x y pha + ---------- ----------- ---------- + idxeq: [INDEF] + idxand sort: x[ROW 8037025:8070128] y[ROW 5757665:5792352] + idxand\2011\202: INDEF [IDX_OR_SORT] )WR( + idxall\2011\202: [IDX_OR_SORT] + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 1.55u 0.37s 1:19.80 2.4%)RP( + +When all columns are indexed, the increase in speed can be even more dramatic: +) 50 67 PR( time fundisp \200 + huge.fits'[idx_activate=0,idx_debug=1,pi=770&&cir 4000 4000 1]' \200 + "x y pi" + x y pi + ---------- ----------- ---------- + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 42.60u 12.63s 7:28.63 12.3% + + time fundisp \200 + huge.fits'[idx_activate=1,idx_debug=1,pi=770&&cir 4000 4000 1]' \200 + "x y pi" + x y pi + ---------- ----------- ---------- + idxeq: pi start=9473025,stop=9492240 => pi[ROW 9473025:9492240] + idxand sort: x[ROW 8037025:8070128] y[ROW 5757665:5792352] + idxor sort/merge: pi[ROW 9473025:9492240] [IDX_OR_SORT] )WR( + idxmerge\2015\202: [IDX_OR_SORT] pi[ROW] + idxall\2011\202: [IDX_OR_SORT] + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 1.67u 0.30s 0:24.76 7.9%)RP( + +)0 P(The miracle of indexed filtering \201and indeed, of any indexing\202 is the +speed of the binary search on the index, which is of order log2\201n\202 +instead of n. \201The funtools binary search method is taken from +http://www.tbray.org/ongoing/When/200x/2003/03/22/Binary, to whom +grateful acknowledgement is made.\202 This means that the larger the +file, the better the performance. Conversely, it also means that for +small files, using an index \201and the overhead involved\202 can slow +filtering down somewhat. Our tests indicate that on a file containing +a few tens of thousands of rows, indexed filtering can be 10 to 20 +percent slower than non-indexed filtering. Of course, your mileage +will vary with conditions \201disk access speed, amount of available +memory, process load, etc.\202 + +)0 P(Any problem encountered during index processing will result in +indexing being turned off, and replaced by filtering all rows. You can turn +filtering off manually by setting the idx_activate variable to 0 \201in a filter +expression\202 or the FILTER_IDX_ACTIVATE environment variable to 0 \201in the global +environment\202. Debugging output showing how the indexes are being processed can +be displayed to stderr by setting the idx_debug variable to 1 \201in a filter +expression\202 or the FILTER_IDX_DEBUG environment variable to 1 \201in the global +environment\202. + +)0 P(Currently, indexed filtering only works with FITS binary tables and raw +event files. It does not work with text files. This restriction might be +removed in a future release. + + + + + +)0 P()0 0 1 A(Go to Funtools Help Index)0 0 TN TL()Ec /AF f D( + +)0 5 103 H(Last)WB 180 Sn( updated: August 3, 2007)EH( + +)WB NL +/Cb Db D /Ct [16#00 16#00 16#00] D /Cl [16#00 16#00 16#00] D /CL -1 D Ct Sc +DS +/Ba f D /BO 0 D Bs +/UR (regions.html) D +/Ti (Spatial Region Filtering) D +/Au () D +/Df f D +/ME [()] D + +0 BO R +()1 Sl()WB 54 Sn( + + +)0 2 104 H(Regions:)WB 182 Sn()WB 181 Sn( Spatial Region Filtering)EA()EH( + + +)0 2 105 H(Summary)WB 183 Sn()EH( +)0 P(This document contains a summary of the user interface for spatial +region filtering images and tables. + + +)0 2 106 H(Description)WB 184 Sn()EH( +)0 P(Spatial region filtering allows a program to select regions of an +image or rows of a table \201e.g., X-ray events\202 to process using +simple geometric shapes and boolean combinations of shapes. When an +image is filtered, only pixels found within these shapes are +processed. When a table is filtered, only rows found within these +shapes are processed. + +)0 P(Spatial region filtering for images and tables is accomplished by +means of )BD(region specifications)ES(. A region specification +consists of one or more )BD(region expressions)ES(, which are geometric +shapes,combined according to the rules of boolean algebra. Region +specifications also can contain comments and local/global processing +directives. + +)0 P(Typically, region specifications are specified using bracket notation +appended to the filename of the data being processed: +) 1 31 PR( foo.fits[circle\201512,512,100\202])RP( +It is also possible to put region specification inside a file and +then pass the filename in bracket notation: +) 1 19 PR( foo.fits[@my.reg])RP( + +)0 P(When region filters are passed in bracket notation in this manner, the +filtering is set up automatically when the file is opened and all +processing occurs through the filter. Programs also can use the filter +library API to open filters explicitly. + +)0 2 107 H(Region)WB 185 Sn( Expressions)EH( + +More specifically, region specifications consist of one or more lines +containing: +) 9 68 PR( # comment until end of line + global keyword=value keyword=value ... # set global value\201s\202 + # include the following file in the region descriptor + @file + # use the FITS image as a mask \201cannot be used with other regions\202 + @fitsimage + # each region expression contains shapes separated by operators + [region_expression1], [region_expression2], ... + [region_expression], [region_expression], ...)RP( + +)0 P(A single region expression consists of: +) 8 72 PR( # parens and commas are optional, as is the + sign + [+-]shape\201num , num , ...\202 OP1 shape num num num OP2 shape ... + +e.g.: + + \201[+-]shape\201num , num , ...\202 && shape num num || shape\201num, num\202 + # a comment can come after a region -- reserved for local properties + [+-]shape\201num , num , ...\202 # local properties go here, e.g. color=red)RP( + +)0 P(Thus, a region descriptor consists of one or more )BD(region +expressions)ES( or )BD(regions)ES(, separated by comas, new-lines, or +semi-colons. Each )BD(region)ES( consists of one or more )BD(geometric +shapes)ES( combined using standard boolean operation. Several types +of shapes are supported, including: + +) 11 57 PR( shape: arguments: + ----- ---------------------------------------- + ANNULUS xcenter ycenter inner_radius outer_radius + BOX xcenter ycenter xwidth yheight \201angle\202 + CIRCLE xcenter ycenter radius + ELLIPSE xcenter ycenter xwidth yheight \201angle\202 + FIELD none + LINE x1 y1 x2 y2 + PIE xcenter ycenter angle1 angle2 + POINT x1 y1 + POLYGON x1 y1 x2 y2 ... xn yn)RP( + +)0 P(In addition, the following regions accept )BD(accelerator)ES( syntax: + +) 13 73 PR( shape arguments + ----- ------------------------------------------ + ANNULUS xcenter ycenter radius1 radius2 ... radiusn + ANNULUS xcenter ycenter inner_radius outer_radius n=[number] + BOX xcenter ycenter xw1 yh1 xw2 yh2 ... xwn yhn \201angle\202 + BOX xcenter ycenter xwlo yhlo xwhi yhhi n=[number] \201angle\202 + CIRCLE xcenter ycenter r1 r2 ... rn # same as annulus + CIRCLE xcenter ycenter rinner router n=[number] # same as annulus + ELLIPSE xcenter ycenter xw1 yh1 xw2 yh2 ... xwn yhn \201angle\202 + ELLIPSE xcenter ycenter xwlo yhlo xwhi yhhi n=[number] \201angle\202 + PIE xcenter ycenter angle1 angle2 \201angle3\202 \201angle4\202 \201angle5\202 ... + PIE xcenter ycenter angle1 angle2 \201n=[number]\202 + POINT x1 y1 x2 y2 ... xn yn)RP( +Note that the circle accelerators are simply aliases for the annulus +accelerators. See )0 55 1 A(region geometry)55 0 TN TL()Ec /AF f D( +for more information about accelerators. + +)0 P(Finally, the following are combinations of pie with different shapes +\201called "panda" for "Pie AND Annulus"\202 allow for easy specification of +radial sections: + +) 6 75 PR( shape: arguments: + ----- --------- + PANDA xcen ycen ang1 ang2 nang irad orad nrad # circular + CPANDA xcen ycen ang1 ang2 nang irad orad nrad # circular + BPANDA xcen ycen ang1 ang2 nang xwlo yhlo xwhi yhhi nrad \201ang\202 # box + EPANDA xcen ycen ang1 ang2 nang xwlo yhlo xwhi yhhi nrad \201ang\202 # ellipse)RP( + +The panda and cpanda specify combinations of annulus and circle with pie, +respectively and give identical results. The bpanda combines box and pie, +while epanda combines ellipse and pie. +See )0 55 1 A(region geometry)55 0 TN TL()Ec /AF f D( +for more information about pandas. + +)0 P(The following "shapes" are ignored by funtools \201generated by ds9\202: +) 8 62 PR( shape: arguments: + ----- --------- + PROJECTION x1 y1 x2 y2 width # NB: ignored by funtools + RULER x1 y1 x2 y2 # NB: ignored by funtools + TEXT x y # NB: ignored by funtools + GRID # NB: ignored by funtools + TILE # NB: ignored by funtools + COMPASS # NB: ignored by funtools)RP( + +)0 P(All arguments to regions are real values; integer values are +automatically converted to real where necessary. All angles are in +degrees and run from the positive image x-axis to the positive image +y-axis. If a rotation angle is part of the associated WCS header, that +angle is added implicitly as well. + +)0 P(Note that 3-letter abbreviations are supported for all shapes, so that +you can specify "circle" or "cir". + +)0 P()0 2 108 H(Columns)WB 186 Sn( Used in Region Filtering)EH( +)0 P(By default, the x,y values in a region expression refer to the two +"image binning" columns, i.e. the columns that would be used to +bin the data into an image. For images, these are just the 2 dimensions +of the image. For tables, these usually default to x and y but +can be changed as required. For example, in Funtools, new binning +columns are specified using a bincols=\201col1,col2\202 statement within +the bracket string on the command line. +)0 P(Alternate columns for region filtering can be specified by the syntax: +) 1 25 PR( \201col1,col2\202=region\201...\202)RP( +e.g.: +) 3 34 PR( \201X,Y\202=annulus\201x,y,ri,ro\202 + \201PHA,PI\202=circle\201x,y,r\202 + \201DX,DY\202=ellipse\201x,y,a,b[,angle]\202)RP( + +)0 P()0 2 109 H(Region)WB 187 Sn( Algebra)EH( + +\201See also )0 56 1 A(Region Algebra)56 0 TN TL()Ec /AF f D( for more complete +information.\202 + +)0 P(Region shapes can be combined together using Boolean operators: +) 6 72 PR( Symbol Operation Use + -------- --------- ----------------------------------- + ! not Exclude this shape from this region + & or && and Include only the overlap of these shapes + | or || inclusive or Include all of both shapes + ^ exclusive or Include both shapes except their overlap)RP( +Note that the !region syntax must be combined with another region in order +that we be able to assign a region id properly. That is, +) 1 21 PR( !circle\201512,512,10\202)RP( +is not a legal region because there is no valid region id to work with. +To get the full field without a circle, combine the above with field\201\202, +as in: +) 1 32 PR( field\201\202 && !circle\201512,512,10\202)RP( + +)0 2 110 H()WB 188 Sn( Region Separators Also Are Operators)EH( + +)0 P(As mentioned previously, multiple region expressions can be specified +in a region descriptor, separated by commas, new-lines, or +semi-colons. When such a separator is used, the boolean OR operator +is automatically generated in its place but, unlike explicit use of +the OR operator, the region ID is incremented \201starting from 1\202. + +)0 P(For example, the two shapes specified in this example are given the +same region value: +) 1 50 PR( foo.fits[circle\201512,512,10\202||circle\201400,400,20\202])RP( +On the other hand, the two shapes defined in the following example are +given different region values: +) 1 49 PR( foo.fits[circle\201512,512,10\202,circle\201400,400,20\202])RP( + +)0 P(Of course these two examples will both mask the same table rows or +pixels. However, in programs that distinguish region id's \201such as +)0 5 1 A(funcnts)5 0 TN TL()Ec /AF f D( \202, they will act +differently. The explicit OR operator will result in one region +expression consisting of two shapes having the same region id and +funcnts will report a single region. The comma operator will cause +funcnts to report two region expressions, each with one shape, in +its output. + +)0 P(In general, commas are used to separate region expressions entered +in bracket notation on the command line: +) 2 57 PR( # regions are added to the filename in bracket notation + foo.fits[circle\201512,512,100\202,circle\201400,400,20\202])RP( +New-lines are used to separate region +expressions in a file: +) 4 58 PR( # regions usually are separated by new-lines in a file + # use @filename to include this file on the command line + circle\201512,512,100\202 + circle\201400,400,20\202)RP( +Semi-colons are provided for backward compatibility with the original +IRAF/PROS implementation and can be used in either case. + +)0 P(If a pixel is covered by two different regions expressions, it is +given the mask value of the )BD(first)ES( region that contains that +pixel. That is, successive regions )BD(do not)ES( overwrite previous +regions in the mask, as was the case with the original PROS regions. +In this way, an individual pixel is covered by one and only one +region. This means that one must sometimes be careful about the order +in which regions are defined. If region N is fully contained within +region M, then N should be defined )BD(before)ES( M, or else it will be +"covered up" by the latter. + +)0 2 111 H(Region)WB 189 Sn( Exclusion)EH( +)0 P(Shapes also can be globally excluded from all the region specifiers in +a region descriptor by using a minus sign before a region: + +) 4 73 PR( operator arguments: + -------- ----------- + - Globally exclude the region expression following '-' sign + from ALL regions specified in this file)RP( +The global exclude region can be used by itself; in such a case, field\201\202 is +implied. + +)0 P(A global exclude differs from the local exclude \201i.e. a shape prefixed +by the logical not "!" symbol\202 in that global excludes are logically +performed last, so that no region will contain pixels from a globally +excluded shape. A local exclude is used in a boolean expression with +an include shape, and only excludes pixels from that include shape. +Global excludes cannot be used in boolean expressions. + +)0 2 112 H(Include)WB 190 Sn( Files)EH( + +)0 P(The )BD(@filename)ES( directive specifies an include file +containing region expressions. This file is processed as part of +the overall region descriptor: +) 1 35 PR( foo.fits[circle\201512,512,10\202,@foo])RP( +A filter include file simply includes text without changing the state +of the filter. It therefore can be used in expression. That is, if the +file foo1 contains "pi==1" and foo2 contains "pha==2" then +the following expressions are equivalent: +) 3 57 PR( "[@foo1&&@foo2]" is equivalent to "[pi==1&&pha==2]" + "[pha==1||@foo2]" is equivalent to "[pi==1||pha==2]" + "[@foo1,@foo2]" is equivalent to "[pi==1,pha==2]")RP( +Be careful that you specify evaluation order properly using +parenthesis, especially if the include file contains multiple +filter statements. For example, consider a file containing two +regions such as: +) 2 19 PR( circle 512 512 10 + circle 520 520 10)RP( +If you want to include only events \201or pixels\202 that are in these regions +and have a pi value of 4, then the correct syntax is: +) 1 17 PR( pi==4&&\201@foo\202)RP( +since this is equivalent to: +) 1 53 PR( pi==4 && \201circle 512 512 10 || circle 520 520 10\202)RP( +If you leave out the parenthesis, you are filtering this statement: +) 1 52 PR( pi==4 && circle 512 512 10 || circle 520 520 10\202)RP( +which is equivalent to: +) 1 54 PR( \201pi==4 && circle 512 512 10\202 || circle 520 520 10\202)RP( +The latter syntax only applies the pi test to the first region. + +)0 P(For image-style filtering, the )BD(@filename)ES( can specify an 8-bit +or 16-bit FITS image. In this case, the pixel values in the mask image +are used as the region mask. The valid pixels in the mask must have +positive values. Zero values are excluded from the mask and negative +values are not allowed. Moreover, the region id value is taken as +the image pixel value and the total number of regions is taken to be +the highest pixel value. The dimensions of the image mask must be less +than or equal to the image dimensions of the data. The mask will be +replicated as needed to match the size of the image. \201Thus, best +results are obtained when the data dimensions are an even multiple of +the mask dimensions.\202 + +)0 P(An image mask can be used in any image filtering operation, regardless +of whether the data is of type image or table. For example, the +)0 5 1 A(funcnts)5 0 TN TL()Ec /AF f D( \202 +program performs image filtering on images or tables, and so +FITS image masks are valid input for either type of data in this +program.. An image mask cannot be used in a program such as +)0 7 1 A(fundisp)7 0 TN TL()Ec /AF f D( \202 +when the input data is a table, because fundisp displays +rows of a table and processes these rows using event-style filtering. + +)0 2 113 H(Global)WB 191 Sn( and Local Properties of Regions)EH( + +)0 P(The ds9 image display program describes a host of properties such as +color, font, fix/free state, etc. Such properties can be specified +globally \201for all regions\202 or locally \201for an individual region\202. +The )BD(global)ES( keyword specifies properties and qualifiers for all +regions, while local properties are specified in comments on the same +line as the region: +) 4 30 PR( global color=red + circle\20110,10,2\202 + circle\20120,20,3\202 # color=blue + circle\20130,30,4\202)RP( +The first and third circles will be red, which the second circle will +be blue. Note that funtools currently ignores region properties, as +they are used in display only. + +)0 2 114 H()WB 192 Sn( Coordinate Systems)EH( + +For each region, it is important to specify the coordinate system +used to interpret the region, i.e., to set the context in which position and +size values are interpreted. For this purpose, the following keywords +are recognized: + +) 12 68 PR( name description + ---- ------------------------------------------ + PHYSICAL pixel coords of original file using LTM/LTV + IMAGE pixel coords of current file + FK4, B1950 sky coordinate systems + FK5, J2000 sky coordinate systems + GALACTIC sky coordinate systems + ECLIPTIC sky coordinate systems + ICRS currently same as J2000 + LINEAR linear wcs as defined in file + AMPLIFIER mosaic coords of original file using ATM/ATV + DETECTOR mosaic coords of original file using DTM/DTV)RP( + +)0 P()0 2 115 H(Specifying)WB 193 Sn( Positions, Sizes, and Angles)EH( + +The arguments to region shapes can be floats or integers describing +positions and sizes. They can be specified as pure numbers or using +explicit formatting directives: + +) 21 57 PR( position arguments description + ------------------ ------------------------------ + [num] context-dependent \201see below\202 + [num]d degrees + [num]r radians + [num]p physical pixels + [num]i image pixels + [num]:[num]:[num] hms for 'odd' position arguments + [num]:[num]:[num] dms for 'even' position arguments + [num]h[num]m[num]s explicit hms + [num]d[num]m[num]s explicit dms + + size arguments description + -------------- ----------- + [num] context-dependent \201see below\202 + [num]" arc seconds + [num]' arc minutes + [num]d degrees + [num]r radians + [num]p physical pixels + [num]i image pixels)RP( + + +When a "pure number" \201i.e. one without a format directive such as 'd' +for 'degrees'\202 is specified, its interpretation depends on the context +defined by the 'coordsys' keyword. In general, the rule is: + +)0 P()BD(All pure numbers have implied units corresponding to the current +coordinate system.)ES( + +)0 P(If no such system is explicitly specified, the default system is +implicitly assumed to be PHYSICAL. + +)0 P(In practice this means that for IMAGE and PHYSICAL systems, pure +numbers are pixels. Otherwise, for all systems other than linear, +pure numbers are degrees. For LINEAR systems, pure numbers are in the +units of the linear system. This rule covers both positions and +sizes. + +)0 P(The input values to each shape can be specified in several coordinate +systems including: + +) 12 68 PR( name description + ---- ---------------------------- + IMAGE pixel coords of current file + LINEAR linear wcs as defined in file + FK4, B1950 various sky coordinate systems + FK5, J2000 + GALACTIC + ECLIPTIC + ICRS + PHYSICAL pixel coords of original file using LTM/LTV + AMPLIFIER mosaic coords of original file using ATM/ATV + DETECTOR mosaic coords of original file using DTM/DTV)RP( + +)0 P(If no coordinate system is specified, PHYSICAL is assumed. PHYSICAL or +a World Coordinate System such as J2000 is preferred and most general. +The coordinate system specifier should appear at the beginning of the +region description, on a separate line \201in a file\202, or followed by a +new-line or semicolon; e.g., + +) 2 26 PR( global coordsys physical + circle 6500 9320 200)RP( + +The use of celestial input units automatically implies WORLD +coordinates of the reference image. Thus, if the world coordinate +system of the reference image is J2000, then + +) 1 27 PR( circle 10:10:0 20:22:0 3')RP( + +is equivalent to: + +) 1 35 PR( circle 10:10:0 20:22:0 3' # j2000)RP()RP( +Note that by using units as described above, you may mix coordinate +systems within a region specifier; e.g., + +) 1 32 PR( circle 6500 9320 3' # physical)RP( + +)0 P(Note that, for regions which accept a rotation angle: + +) 2 29 PR(ellipse \201x, y, r1, r2, angle\202 +box\201x, y, w, h, angle\202)RP( + +the angle is relative to the specified coordinate system. In +particular, if the region is specified in WCS coordinates, the angle +is related to the WCS system, not x/y image coordinate axis. For WCS +systems with no rotation, this obviously is not an issue. However, +some images do define an implicit rotation \201e.g., by using a non-zero +CROTA value in the WCS parameters\202 and for these images, the angle +will be relative to the WCS axes. In such case, a region specification +such as: + +) 1 54 PR(fk4;ellipse\20122:59:43.985, +58:45:26.92,320", 160", 30\202)RP( + +will not, in general, be the same region specified as: + +) 1 38 PR(physical;ellipse\201465, 578, 40, 20, 30\202)RP( + +even when positions and sizes match. The angle is relative to WCS axes +in the first case, and relative to physical x,y axes in the second. + + +)0 P(More detailed descriptions are available for: +)0 55 1 A(Region Geometry)55 0 TN TL()Ec /AF f D(, +)0 56 1 A(Region Algebra)56 0 TN TL()Ec /AF f D(, +)0 57 1 A(Region Coordinates)57 0 TN TL()Ec /AF f D(, and +)0 58 1 A(Region Boundaries)58 0 TN TL()Ec /AF f D(. + + + + + +)0 P()0 0 1 A(Go to Funtools Help Index)0 0 TN TL()Ec /AF f D( + +)0 5 116 H(Last)WB 194 Sn( updated: November 17, 2005)EH( + +)WB NL +/Cb Db D /Ct [16#00 16#00 16#00] D /Cl [16#00 16#00 16#00] D /CL -1 D Ct Sc +DS +/Ba f D /BO 0 D Bs +/UR (reggeometry.html) D +/Ti (Region Geometry) D +/Au () D +/Df f D +/ME [()] D + +0 BO R +()1 Sl()WB 55 Sn( + + +)0 2 117 H(RegGeometry:)WB 196 Sn()WB 195 Sn( Geometric Shapes in Spatial Region Filtering)EA()EH( + + +)0 2 118 H(Summary)WB 197 Sn()EH( +)0 P(This document describes the geometry of regions available for spatial +filtering in IRAF/PROS analysis. + + +)0 2 119 H(Geometric)WB 198 Sn( shapes)EH( +)0 P(Several geometric shapes are used to describe regions. The valid +shapes are: + +) 11 57 PR( shape: arguments: + ----- ---------------------------------------- + ANNULUS xcenter ycenter inner_radius outer_radius + BOX xcenter ycenter xwidth yheight \201angle\202 + CIRCLE xcenter ycenter radius + ELLIPSE xcenter ycenter xwidth yheight \201angle\202 + FIELD none + LINE x1 y1 x2 y2 + PIE xcenter ycenter angle1 angle2 + POINT x1 y1 + POLYGON x1 y1 x2 y2 ... xn yn)RP( + + +All arguments are real values; integer values are automatically +converted to real where necessary. All angles are in degrees and +specify angles that run counter-clockwise from the positive y-axis. + +)0 P(Shapes can be specified using "command" syntax: +) 1 23 PR( [shape] arg1 arg2 ...)RP( +or using "routine" syntax: +) 1 26 PR( [shape]\201arg1, arg2, ...\202)RP( +or by any combination of the these. \201Of course, the parentheses must +balance and there cannot be more commas than necessary.\202 The shape +keywords are case-insensitive. Furthermore, any shape can be +specified by a three-character unique abbreviation. For example, one +can specify three circular regions as: + +) 1 64 PR( "foo.fits[CIRCLE 512 512 50;CIR\201128 128, 10\202;cir\201650,650,20\202]")RP( + +\201Quotes generally are required to protect the region descriptor +from being processed by the Unix shell.\202 + +)2 1 1 HR( +)0 P(The )BD(annulus)ES( shape specifies annuli, centered at xcenter, +ycenter, with inner and outer radii \201r1, r2\202. For example, +) 1 20 PR( ANNULUS 25 25 5 10)RP( +specifies an annulus centered at 25.0 25.0 with an inner radius of 5.0 and +an outer radius of 10. Assuming \201as will be done for all examples in this +document, unless otherwise noted\202 this shape is used in a mask of size 40x40, +it will look like this: +) 42 51 PR( 1234567890123456789012345678901234567890 + ---------------------------------------- + 40:........................................ + 39:........................................ + 38:........................................ + 37:........................................ + 36:........................................ + 35:........................................ + 34:....................111111111........... + 33:...................11111111111.......... + 32:.................111111111111111........ + 31:.................111111111111111........ + 30:................11111111111111111....... + 29:...............1111111.....1111111...... + 28:...............111111.......111111...... + 27:...............11111.........11111...... + 26:...............11111.........11111...... + 25:...............11111.........11111...... + 24:...............11111.........11111...... + 23:...............11111.........11111...... + 22:...............111111.......111111...... + 21:...............1111111.....1111111...... + 20:................11111111111111111....... + 19:.................111111111111111........ + 18:.................111111111111111........ + 17:...................11111111111.......... + 16:....................111111111........... + 15:........................................ + 14:........................................ + 13:........................................ + 12:........................................)WR( + 11:........................................ + 10:........................................ + 9:........................................ + 8:........................................ + 7:........................................ + 6:........................................ + 5:........................................ + 4:........................................ + 3:........................................ + 2:........................................ + 1:........................................)RP( + +)2 1 1 HR( +)0 P(The )BD(box)ES( shape specifies an orthogonally oriented box, +centered at xcenter, ycenter, of size xwidth, yheight. It requires four +arguments and accepts an optional fifth argument to specify a rotation angle. +When the rotation angle is specified \201in degrees\202, the box is rotated by +an angle that runs counter-clockwise from the positive y-axis. + +)0 P(The )BD(box)ES( shape specifies a rotated box, centered at +xcenter, ycenter, of size xwidth, yheight. The box is rotated by an angle +specified in degrees that runs counter-clockwise from the positive y-axis. +If the angle argument is omitted, it defaults to 0. + +)2 1 1 HR( +)0 P(The )BD(circle)ES( shape specifies a circle, centered at xcenter, +ycenter, of radius r. It requires three arguments. + +)2 1 1 HR( +)0 P(The )BD(ellipse)ES( shape specifies an ellipse, centered at +xcenter, ycenter, with y-axis width a and the y-axis length b defined such +that: +) 1 27 PR( x**2/a**2 + y**2/b**2 = 1)RP( +Note that a can be less than, equal to, or greater than b. The ellipse +is rotated the specified number of degrees. The rotation is done according +to astronomical convention, counter-clockwise from the positive y-axis. +An ellipse defined by: +) 1 23 PR( ELLIPSE 20 20 5 10 45)RP( +will look like this: +) 42 49 PR( 1234567890123456789012345678901234567890 + ---------------------------------------- + 40:........................................ + 39:........................................ + 38:........................................ + 37:........................................ + 36:........................................ + 35:........................................ + 34:........................................ + 33:........................................ + 32:........................................ + 31:........................................ + 30:........................................ + 29:........................................ + 28:........................................ + 27:............111111...................... + 26:............11111111.................... + 25:............111111111................... + 24:............11111111111................. + 23:............111111111111................ + 22:............111111111111................ + 21:.............111111111111............... + 20:.............1111111111111.............. + 19:..............111111111111.............. + 18:...............111111111111............. + 17:...............111111111111............. + 16:................11111111111............. + 15:..................111111111............. + 14:...................11111111............. + 13:.....................111111............. + 12:........................................)WR( + 11:........................................ + 10:........................................ + 9:........................................ + 8:........................................ + 7:........................................ + 6:........................................ + 5:........................................ + 4:........................................ + 3:........................................ + 2:........................................ + 1:........................................)RP( + + +)2 1 1 HR( +)0 P(The )BD(field)ES( shape specifies the entire field as a +region. It is not usually specified explicitly, but is used implicitly in the +case where no regions are specified, that is, in cases where either a null +string or some abbreviation of the string "none" is input. +)BD(Field)ES( takes no arguments. + +)2 1 1 HR( +)0 P(The )BD(pie)ES( shape specifies an angular wedge of the entire field, +centered at xcenter, ycenter. The wedge runs between the two specified angles. +The angles are given in degrees, running counter-clockwise from the positive +x-axis. For example, +) 1 18 PR( PIE 20 20 90 180)RP( +defines a region from 90 degrees to 180 degrees, i.e., quadrant 2 of the +Cartesian plane. The display of such a region looks like this: + +) 42 51 PR( 1234567890123456789012345678901234567890 + ---------------------------------------- + 40:11111111111111111111.................... + 39:11111111111111111111.................... + 38:11111111111111111111.................... + 37:11111111111111111111.................... + 36:11111111111111111111.................... + 35:11111111111111111111.................... + 34:11111111111111111111.................... + 33:11111111111111111111.................... + 32:11111111111111111111.................... + 31:11111111111111111111.................... + 30:11111111111111111111.................... + 29:11111111111111111111.................... + 28:11111111111111111111.................... + 27:11111111111111111111.................... + 26:11111111111111111111.................... + 25:11111111111111111111.................... + 24:11111111111111111111.................... + 23:11111111111111111111.................... + 22:11111111111111111111.................... + 21:11111111111111111111.................... + 20:........................................ + 19:........................................ + 18:........................................ + 17:........................................ + 16:........................................ + 15:........................................ + 14:........................................ + 13:........................................ + 12:........................................)WR( + 11:........................................ + 10:........................................ + 9:........................................ + 8:........................................ + 7:........................................ + 6:........................................ + 5:........................................ + 4:........................................ + 3:........................................ + 2:........................................ + 1:........................................)RP( +The pie slice specified is always a counter-clockwise sweep between +the angles, starting at the first angle and ending at the second. Thus: +) 1 17 PR( PIE 10 15 30 60)RP( +describes a 30 degree sweep from 2 o'clock to 1 o'clock, while: +) 1 17 PR( PIE 10 15 60 30)RP( +describes a 330 degree counter-clockwise sweep from 1 o'clock to 2 o'clock +passing through 12 o'clock \2010 degrees\202. Note in both of these examples that +the center of the slice can be anywhere on the plane. The second mask looks +like this: + +) 42 51 PR( 1234567890123456789012345678901234567890 + ---------------------------------------- + 40:111111111111111111111111................ + 39:11111111111111111111111................. + 38:11111111111111111111111................. + 37:1111111111111111111111.................. + 36:1111111111111111111111.................. + 35:111111111111111111111................... + 34:11111111111111111111.................... + 33:11111111111111111111.................... + 32:1111111111111111111....................1 + 31:1111111111111111111..................111 + 30:111111111111111111.................11111 + 29:111111111111111111................111111 + 28:11111111111111111...............11111111 + 27:1111111111111111..............1111111111 + 26:1111111111111111.............11111111111 + 25:111111111111111............1111111111111 + 24:111111111111111..........111111111111111 + 23:11111111111111.........11111111111111111 + 22:11111111111111........111111111111111111 + 21:1111111111111.......11111111111111111111 + 20:111111111111......1111111111111111111111 + 19:111111111111....111111111111111111111111 + 18:11111111111....1111111111111111111111111 + 17:11111111111..111111111111111111111111111 + 16:1111111111.11111111111111111111111111111 + 15:1111111111111111111111111111111111111111 + 14:1111111111111111111111111111111111111111 + 13:1111111111111111111111111111111111111111 + 12:1111111111111111111111111111111111111111)WR( + 11:1111111111111111111111111111111111111111 + 10:1111111111111111111111111111111111111111 + 9:1111111111111111111111111111111111111111 + 8:1111111111111111111111111111111111111111 + 7:1111111111111111111111111111111111111111 + 6:1111111111111111111111111111111111111111 + 5:1111111111111111111111111111111111111111 + 4:1111111111111111111111111111111111111111 + 3:1111111111111111111111111111111111111111 + 2:1111111111111111111111111111111111111111 + 1:1111111111111111111111111111111111111111)RP( +The pie slice goes to the edge of the field. To limit its scope, pie +usually is is combined with other shapes, such as circles and annuli, +using boolean operations. \201See below and in "help regalgebra"\202. + +)0 P(Pie Performance Notes: +)0 P(Pie region processing time is proportional to the size of the image, +and not the size of the region. This is because the pie shape is the +only infinite length shape, and we essentially must check all y rows +for inclusion \201unlike other regions, where the y limits can be +calculated beforehand\202. Thus, pie can run very slowly on large images. +In particular, it will run MUCH more slowly than the panda shape in +image-based region operations \201such as funcnts\202. We recommend use of +panda over pie where ever possible. + +)0 P(If you must use pie, always try to put it last in a boolean && +expression. The reason for this is that the filter code is optimized +to exit as soon as the result is know. Since pie is the slowest +region, it is better to avoid executing it if another region can decide +the result. Consider, for example, the difference in time required to +process a Chandra ACIS file when a pie and circle are combined in +two different orders: + +) 5 74 PR( time ./funcnts nacis.fits "circle 4096 4096 100 && pie 4096 4096 10 78" +2.87u 0.38s 0:35.08 9.2% + + time ./funcnts nacis.fits "pie 4096 4096 10 78 && circle 4096 4096 100 " +89.73u 0.36s 1:03.50 141.8%)RP( + +)0 P(Black-magic performance note: + +)0 P(Panda region processing uses a )BD(quick test)ES( pie region instead of +the normal pie region when combining its annulus and pie shapes. This +)BD(qtpie)ES( shape differs from the normal pie in that it utilizes the +y limits from the previous region with which it is combined. In a +panda shape, which is a series of annuli combined with pies, the +processing time is thus reduced to that of the annuli. + +)0 P(You can use the qtpie shape instead of pie in cases where you are +combining pie with another shape using the && operator. This will +cause the pie limits to be set using limits from the other shape, and +will speed up the processing considerably. For example, the above +execution of funcnts can be improved considerably using this technique: + +) 2 75 PR( time ./funcnts nacis.fits "circle 4096 4096 100 && qtpie 4096 4096 10 78" +4.66u 0.33s 0:05.87 85.0%)RP( + +)0 P(We emphasize that this is a quasi-documented feature and might change in +the future. The qtpie shape is not recognized by ds9 or other programs. + +)2 1 1 HR( +)0 P(The )BD(line)ES( shape allows single pixels in a line between \201x1,y1\202 and +\201x2,y2\202 to be included or excluded. For example: +) 44 49 PR( LINE \2015,6, 24,25\202 +) 43 49 PR(displays as: +) 42 49 PR( 1234567890123456789012345678901234567890 + ---------------------------------------- + 40:........................................ + 39:........................................ + 38:........................................ + 37:........................................ + 36:........................................ + 35:........................................ + 34:........................................ + 33:........................................ + 32:........................................ + 31:........................................ + 30:........................................ + 29:........................................ + 28:........................................ + 27:........................................ + 26:........................................ + 25:.......................1................ + 24:......................1................. + 23:.....................1.................. + 22:....................1................... + 21:...................1.................... + 20:..................1..................... + 19:.................1...................... + 18:................1....................... + 17:...............1........................ + 16:..............1......................... + 15:.............1.......................... + 14:............1...........................)WR( + 13:...........1............................)WR( + 12:..........1.............................)WR( + 11:.........1.............................. + 10:........1............................... + 9:.......1................................ + 8:......1................................. + 7:.....1.................................. + 6:....1................................... + 5:........................................ + 4:........................................ + 3:........................................ + 2:........................................ + 1:........................................)RP( + +)2 1 1 HR( +)0 P(The )BD(point)ES( shape allows single pixels to be included or +excluded. Although the \201x,y\202 values are real numbers, they are truncated +to integer and the corresponding pixel is included or excluded, as specified. + +)0 P(Several points can be put in one region declaration; unlike the +original IRAF implementation, each now is given a different region mask value. +This makes it easier, for example, for funcnts to determine the number of +photons in the individual pixels. For example, +) 1 37 PR( POINT \2015,6, 10,11, 20,20, 35,30\202)RP( +will give the different region mask values to all four points, as shown below: + +) 42 49 PR( 1234567890123456789012345678901234567890 + ---------------------------------------- + 40:........................................ + 39:........................................ + 38:........................................ + 37:........................................ + 36:........................................ + 35:........................................ + 34:........................................ + 33:........................................ + 32:........................................ + 31:........................................ + 30:..................................4..... + 29:........................................ + 28:........................................ + 27:........................................ + 26:........................................ + 25:........................................ + 24:........................................ + 23:........................................ + 22:........................................ + 21:........................................ + 20:...................3.................... + 19:........................................ + 18:........................................ + 17:........................................ + 16:........................................ + 15:........................................ + 14:........................................ + 13:........................................ + 12:........................................)WR( + 11:.........2.............................. + 10:........................................ + 9:........................................ + 8:........................................ + 7:........................................ + 6:....1................................... + 5:........................................ + 4:........................................ + 3:........................................ + 2:........................................ + 1:........................................)RP( + +)2 1 1 HR( +)0 P(The )BD(polygon)ES( shape specifies a polygon with vertices +\201x1, y1\202 ... \201xn, yn\202. The polygon is closed automatically: one should +not specify the last vertex to be the same as the first. Any number of +vertices are allowed. For example, the following polygon defines a +right triangle as shown below: +) 1 33 PR( POLYGON \20110,10, 10,30, 30,30\202)RP( + +looks like this: + +) 42 49 PR( 1234567890123456789012345678901234567890 + ---------------------------------------- + 40:........................................ + 39:........................................ + 38:........................................ + 37:........................................ + 36:........................................ + 35:........................................ + 34:........................................ + 33:........................................ + 32:........................................ + 31:........................................ + 30:..........11111111111111111111.......... + 29:..........1111111111111111111........... + 28:..........111111111111111111............ + 27:..........11111111111111111............. + 26:..........1111111111111111.............. + 25:..........111111111111111............... + 24:..........11111111111111................ + 23:..........1111111111111................. + 22:..........111111111111.................. + 21:..........11111111111................... + 20:..........1111111111.................... + 19:..........111111111..................... + 18:..........11111111...................... + 17:..........1111111....................... + 16:..........111111........................ + 15:..........11111......................... + 14:..........1111.......................... + 13:..........111........................... + 12:..........11............................)WR( + 11:..........1............................. + 10:........................................ + 9:........................................ + 8:........................................ + 7:........................................ + 6:........................................ + 5:........................................ + 4:........................................ + 3:........................................ + 2:........................................ + 1:........................................)RP( +Note that polygons can get twisted upon themselves if edge lines +cross. Thus: +) 1 37 PR( POL \20110,10, 20,20, 20,10, 10,20\202)RP( +will produce an area which is two triangles, like butterfly wings, as shown +below: + +) 42 49 PR( 1234567890123456789012345678901234567890 + ---------------------------------------- + 40:........................................ + 39:........................................ + 38:........................................ + 37:........................................ + 36:........................................ + 35:........................................ + 34:........................................ + 33:........................................ + 32:........................................ + 31:........................................ + 30:........................................ + 29:........................................ + 28:........................................ + 27:........................................ + 26:........................................ + 25:........................................ + 24:........................................ + 23:........................................ + 22:........................................ + 21:........................................ + 20:........................................ + 19:..........1........1.................... + 18:..........11......11.................... + 17:..........111....111.................... + 16:..........1111..1111.................... + 15:..........1111111111.................... + 14:..........1111..1111.................... + 13:..........111....111.................... + 12:..........11......11....................)WR( + 11:..........1........1.................... + 10:........................................ + 9:........................................ + 8:........................................ + 7:........................................ + 6:........................................ + 5:........................................ + 4:........................................ + 3:........................................ + 2:........................................ + 1:........................................)RP( + +)2 1 1 HR( +)0 P(The following are combinations of pie with different shapes +\201called "panda" for "Pie AND Annulus"\202 allow for easy specification of +radial sections: +) 6 76 PR( shape: arguments: + ----- --------- + PANDA xcen ycen ang1 ang2 nang irad orad nrad # circular + CPANDA xcen ycen ang1 ang2 nang irad orad nrad # circular + BPANDA xcen ycen ang1 ang2 nang xwlo yhlo xwhi yhhi nrad \201ang\202 # box + EPANDA xcen ycen ang1 ang2 nang xwlo yhlo xwhi yhhi nrad \201ang\202 # ellipse)RP( + +The )BD(panda)ES( \201)BD(P)ES(ies )BD(AND)ES( )BD(A)ES(nnuli\202 shape can be +used to create combinations of pie and annuli markers. It is analogous +to a Cartesian product on those shapes, i.e., the result is several +shapes generated by performing a boolean AND between pies and +annuli. Thus, the panda and cpanda specify combinations of annulus and +circle with pie, respectively and give identical results. The bpanda +combines box and pie, while epanda combines ellipse and pie. + +)0 P(Consider the example shown below: +) 1 31 PR( PANDA\20120,20, 0,360,3, 0,15,4\202)RP( +Here, 3 pie slices centered at 20, 20 are combined with 4 annuli, also +centered at 20, 20. The result is a mask with 12 regions \201displayed in +base 16 to save characters\202: +) 42 51 PR( 1234567890123456789012345678901234567890 + ---------------------------------------- + 40:........................................ + 39:........................................ + 38:........................................ + 37:........................................ + 36:........................................ + 35:........................................ + 34:..............44444444444............... + 33:............444444444444444............. + 32:...........88444444444444444............ + 31:.........888844443333344444444.......... + 30:........88888833333333333444444......... + 29:........88888733333333333344444......... + 28:.......8888877733333333333344444........ + 27:......888887777332222233333344444....... + 26:......888877777622222222333334444....... + 25:.....88887777766622222222333334444...... + 24:.....88887777666622222222233334444...... + 23:.....88887777666651111222233334444...... + 22:.....88877776666551111122223333444...... + 21:.....88877776666555111122223333444...... + 20:.....888777766665559999aaaabbbbccc...... + 19:.....888777766665559999aaaabbbbccc...... + 18:.....888777766665599999aaaabbbbccc...... + 17:.....88887777666659999aaaabbbbcccc...... + 16:.....888877776666aaaaaaaaabbbbcccc...... + 15:.....888877777666aaaaaaaabbbbbcccc...... + 14:......8888777776aaaaaaaabbbbbcccc....... + 13:......888887777bbaaaaabbbbbbccccc....... + 12:.......88888777bbbbbbbbbbbbccccc........)WR( + 11:........888887bbbbbbbbbbbbccccc......... + 10:........888888bbbbbbbbbbbcccccc......... + 9:.........8888ccccbbbbbcccccccc.......... + 8:...........88ccccccccccccccc............ + 7:............ccccccccccccccc............. + 6:..............ccccccccccc............... + 5:........................................ + 4:........................................ + 3:........................................ + 2:........................................ + 1:........................................)RP( + +)2 1 1 HR( +)0 P(Several regions with different mask values can be combined in the +same mask. This supports comparing data from the different regions. +\201For information on how to combine different shapes into a single +region, see "help regalgebra".\202 For example, consider the following +set of regions: +) 3 24 PR( ANNULUS 25 25 5 10 + ELLIPSE 20 20 5 10 315 + BOX 15 15 5 10)RP( +The resulting mask will look as follows: + +) 42 49 PR( 1234567890123456789012345678901234567890 + ---------------------------------------- + 40:........................................ + 39:........................................ + 38:........................................ + 37:........................................ + 36:........................................ + 35:........................................ + 34:....................111111111........... + 33:...................11111111111.......... + 32:.................111111111111111........ + 31:.................111111111111111........ + 30:................11111111111111111....... + 29:...............1111111.....1111111...... + 28:...............111111.......111111...... + 27:...............11111.222222..11111...... + 26:...............111112222222..11111...... + 25:...............111112222222..11111...... + 24:...............111112222222..11111...... + 23:...............111112222222..11111...... + 22:...............111111222222.111111...... + 21:..............211111112222.1111111...... + 20:............322211111111111111111....... + 19:............32222111111111111111........ + 18:............22222111111111111111........ + 17:............222222211111111111.......... + 16:............22222222111111111........... + 15:............222222222................... + 14:............22222222.................... + 13:............222222...................... + 12:............33333.......................)WR( + 11:............33333....................... + 10:........................................ + 9:........................................ + 8:........................................ + 7:........................................ + 6:........................................ + 5:........................................ + 4:........................................ + 3:........................................ + 2:........................................ + 1:........................................)RP( +Note that when a pixel is in 2 or more regions, it is arbitrarily +assigned to a one of the regions in question \201often based on how a +give C compiler optimizes boolean expressions\202. + +)0 P()0 2 120 H(Region)WB 199 Sn( accelerators)EH( + +)0 P(Two types of \200fBaccelerators)ES(, to simplify region specification, +are provided as natural extensions to the ways shapes are described. +These are: extended lists of parameters, specifying multiple regions, +valid for annulus, box, circle, ellipse, pie, and points; and +)BD(n=)ES(, valid for annulus, box, circle, ellipse, and pie \201not +point\202. In both cases, one specification is used to define several +different regions, that is, to define shapes with different mask +values in the region mask. + +)0 P(The following regions accept )BD(accelerator)ES( syntax: +) 13 73 PR( shape arguments + ----- ------------------------------------------ + ANNULUS xcenter ycenter radius1 radius2 ... radiusn + ANNULUS xcenter ycenter inner_radius outer_radius n=[number] + BOX xcenter ycenter xw1 yh1 xw2 yh2 ... xwn yhn \201angle\202 + BOX xcenter ycenter xwlo yhlo xwhi yhhi n=[number] \201angle\202 + CIRCLE xcenter ycenter r1 r2 ... rn # same as annulus + CIRCLE xcenter ycenter rinner router n=[number] # same as annulus + ELLIPSE xcenter ycenter xw1 yh1 xw2 yh2 ... xwn yhn \201angle\202 + ELLIPSE xcenter ycenter xwlo yhlo xwhi yhhi n=[number] \201angle\202 + PIE xcenter ycenter angle1 angle2 \201angle3\202 \201angle4\202 \201angle5\202 ... + PIE xcenter ycenter angle1 angle2 \201n=[number]\202 + POINT x1 y1 x2 y2 ... xn yn)RP( +Note that the circle accelerators are simply aliases for the annulus +accelerators. + +)0 P(For example, several annuli at the same center can be specified in one +region expression by specifying more than two radii. If )BD(N)ES( +radii are specified, then )BD(N)ES(-1 annuli result, with the outer +radius of each preceding annulus being the inner radius of the +succeeding annulus. Each annulus is considered a separate region, and +is given a separate mask value. For example, +) 1 30 PR( ANNULUS 20 20 0 2 5 10 15 20)RP( +specifies five different annuli centered at 20 20, and is equivalent to: +) 5 25 PR( ANNULUS 20.0 20.0 0 2 + ANNULUS 20.0 20.0 2 5 + ANNULUS 20.0 20.0 5 10 + ANNULUS 20.0 20.0 10 15 + ANNULUS 20.0 20.0 15 20)RP( +The mask is shown below: + +) 42 49 PR( 1234567890123456789012345678901234567890 + ---------------------------------------- + 40:........................................ + 39:.............5555555555555.............. + 38:...........55555555555555555............ + 37:.........555555555555555555555.......... + 36:........55555555555555555555555......... + 35:......555555555555555555555555555....... + 34:.....55555555544444444444555555555...... + 33:....5555555544444444444444455555555..... + 32:....5555555444444444444444445555555..... + 31:...555555444444444444444444444555555.... + 30:..55555544444444444444444444444555555... + 29:..55555544444443333333334444444555555... + 28:.5555554444444333333333334444444555555.. + 27:.5555544444433333333333333344444455555.. + 26:555555444444333333333333333444444555555. + 25:555554444443333333333333333344444455555. + 24:555554444433333332222233333334444455555. + 23:555554444433333322222223333334444455555. + 22:555554444433333222222222333334444455555. + 21:555554444433333222111222333334444455555. + 20:555554444433333222111222333334444455555. + 19:555554444433333222111222333334444455555. + 18:555554444433333222222222333334444455555. + 17:555554444433333322222223333334444455555. + 16:555554444433333332222233333334444455555. + 15:555554444443333333333333333344444455555. + 14:555555444444333333333333333444444555555. + 13:.5555544444433333333333333344444455555.. + 12:.5555554444444333333333334444444555555..)WR( + 11:..55555544444443333333334444444555555... + 10:..55555544444444444444444444444555555... + 9:...555555444444444444444444444555555.... + 8:....5555555444444444444444445555555..... + 7:....5555555544444444444444455555555..... + 6:.....55555555544444444444555555555...... + 5:......555555555555555555555555555....... + 4:........55555555555555555555555......... + 3:.........555555555555555555555.......... + 2:...........55555555555555555............ + 1:.............5555555555555..............)RP( + +)0 P(For boxes and ellipses, if an odd number of arguments is specified, +then the last argument is assumed to be an angle. Otherwise, the +angle is assumed to be zero. For example: +) 1 38 PR( ellipse 20 20 3 5 6 10 9 15 12 20 45)RP( +specifies an 3 ellipses at a 45 degree angle: +) 42 51 PR( 1234567890123456789012345678901234567890 + ---------------------------------------- + 40:........................................ + 39:........................................ + 38:........................................ + 37:........................................ + 36:........33333333........................ + 35:......333333333333...................... + 34:.....3333333333333333................... + 33:....333333333333333333.................. + 32:....33333332222233333333................ + 31:...3333332222222222333333............... + 30:...33333222222222222233333.............. + 29:...333332222222222222223333............. + 28:...3333222222211112222223333............ + 27:...33332222211111111222223333........... + 26:...333322222111111111122223333.......... + 25:...3333222211111111111122223333......... + 24:....3332222111111..1111122223333........ + 23:....333322211111.....11112222333........ + 22:....33332222111.......11112223333....... + 21:.....33322221111.......11122223333...... + 20:.....33332221111.......11112223333...... + 19:.....33332222111.......11112222333...... + 18:......33332221111.......11122223333..... + 17:.......33322221111.....111112223333..... + 16:.......3333222211111..1111112222333..... + 15:........3333222211111111111122223333.... + 14:.........333322221111111111222223333.... + 13:..........33332222211111111222223333.... + 12:...........3333222222111122222223333....)WR( + 11:............333322222222222222233333.... + 10:.............33333222222222222233333.... + 9:..............3333332222222222333333.... + 8:...............33333333222223333333..... + 7:.................333333333333333333..... + 6:..................3333333333333333...... + 5:.....................333333333333....... + 4:.......................33333333......... + 3:........................................ + 2:........................................ + 1:........................................)RP( +Note in the above example that the lower limit is not part of the +region for boxes, circles, and ellipses. This makes circles and annuli +equivalent, i.e.: +) 2 26 PR( circle 20 20 5 10 15 20 + annulus 20 20 5 10 15 20)RP( +both give the following region mask: +) 42 51 PR( 1234567890123456789012345678901234567890 + ---------------------------------------- + 40:........................................ + 39:.............3333333333333.............. + 38:...........33333333333333333............ + 37:.........333333333333333333333.......... + 36:........33333333333333333333333......... + 35:......333333333333333333333333333....... + 34:.....33333333322222222222333333333...... + 33:....3333333322222222222222233333333..... + 32:....3333333222222222222222223333333..... + 31:...333333222222222222222222222333333.... + 30:..33333322222222222222222222222333333... + 29:..33333322222221111111112222222333333... + 28:.3333332222222111111111112222222333333.. + 27:.3333322222211111111111111122222233333.. + 26:333333222222111111111111111222222333333. + 25:333332222221111111111111111122222233333. + 24:33333222221111111.....11111112222233333. + 23:3333322222111111.......1111112222233333. + 22:333332222211111.........111112222233333. + 21:333332222211111.........111112222233333. + 20:333332222211111.........111112222233333. + 19:333332222211111.........111112222233333. + 18:333332222211111.........111112222233333. + 17:3333322222111111.......1111112222233333. + 16:33333222221111111.....11111112222233333. + 15:333332222221111111111111111122222233333. + 14:333333222222111111111111111222222333333. + 13:.3333322222211111111111111122222233333.. + 12:.3333332222222111111111112222222333333..)WR( + 11:..33333322222221111111112222222333333... + 10:..33333322222222222222222222222333333... + 9:...333333222222222222222222222333333.... + 8:....3333333222222222222222223333333..... + 7:....3333333322222222222222233333333..... + 6:.....33333333322222222222333333333...... + 5:......333333333333333333333333333....... + 4:........33333333333333333333333......... + 3:.........333333333333333333333.......... + 2:...........33333333333333333............ + 1:.............3333333333333..............)RP( + +)0 P(As a final example, specifying several angles in one pie slice +expression is equivalent to specifying several separate slices with +the same center. As with the annulus, if )BD(N)ES( angles are +specified, then )BD(N)ES(-1 slices result, with the ending angle of +each preceding slice being the starting angle of the succeeding slice. +Each slice is considered a separate region, and is given a separate +mask value. For example, +) 1 26 PR( PIE 12 12 315 45 115 270)RP( +specifies three regions as shown below: +) 42 51 PR( 1234567890123456789012345678901234567890 + ---------------------------------------- + 40:2222222222222222222222222222222222222222 + 39:2222222222222222222222222222222222222221 + 38:2222222222222222222222222222222222222211 + 37:2222222222222222222222222222222222222111 + 36:2222222222222222222222222222222222221111 + 35:3222222222222222222222222222222222211111 + 34:3222222222222222222222222222222222111111 + 33:3322222222222222222222222222222221111111 + 32:3322222222222222222222222222222211111111 + 31:3332222222222222222222222222222111111111 + 30:3332222222222222222222222222221111111111 + 29:3333222222222222222222222222211111111111 + 28:3333222222222222222222222222111111111111 + 27:3333322222222222222222222221111111111111 + 26:3333322222222222222222222211111111111111 + 25:3333322222222222222222222111111111111111 + 24:3333332222222222222222221111111111111111 + 23:3333332222222222222222211111111111111111 + 22:3333333222222222222222111111111111111111 + 21:3333333222222222222221111111111111111111 + 20:3333333322222222222211111111111111111111 + 19:3333333322222222222111111111111111111111 + 18:3333333332222222221111111111111111111111 + 17:3333333332222222211111111111111111111111 + 16:3333333333222222111111111111111111111111 + 15:3333333333222221111111111111111111111111 + 14:3333333333322211111111111111111111111111 + 13:3333333333322111111111111111111111111111 + 12:33333333333.1111111111111111111111111111)WR( + 11:3333333333331111111111111111111111111111 + 10:333333333333.111111111111111111111111111 + 9:333333333333..11111111111111111111111111 + 8:333333333333...1111111111111111111111111 + 7:333333333333....111111111111111111111111 + 6:333333333333.....11111111111111111111111 + 5:333333333333......1111111111111111111111 + 4:333333333333.......111111111111111111111 + 3:333333333333........11111111111111111111 + 2:333333333333.........1111111111111111111 + 1:333333333333..........111111111111111111)RP( + +)0 P(The annulus, box, circle, ellipse, and pie shapes also accept an +)BD(n=[int])ES( syntax for specifying multiple regions. The +)BD(n=[int])ES(syntax interprets the previous \201shape-dependent\202 +arguments as lower and upper limits for the region and creates n +shapes with evenly spaced boundaries. For example, if )BD(n=[int])ES( +is specified in an annulus, the two immediately preceding radii +\201)BD(rn)ES( and )BD(rm)ES(\202 are divided into )BD(int)ES( annuli, such +that the inner radius of the first is )BD(rn)ES( and the outer radius +of the last is )BD(rm)ES(. For example, +) 1 24 PR( ANNULUS 20 20 5 20 n=3)RP( +is equivalent to: +) 1 26 PR( ANNULUS 20 20 5 10 15 20)RP( +If this syntax is used with an ellipse or box, then the two preceding +pairs of values are taken to be lower and upper limits for a set of +ellipses or boxes. A circle uses the two preceding arguments for upper +and lower radii. For pie, the two preceding angles are divided into n +wedges such that the starting angle of the first is the lower bound +and the ending angle of the last is the upper bound. In all cases, +the )BD(n=[int])ES( syntax allows any single alphabetic character +before the "=", i.e, i=3, z=3, etc. are all equivalent. + +)0 P(Also note that for boxes and ellipses, the optional angle argument is +always specified after the )BD(n=[int])ES( syntax. For example: +) 45 57 PR( ellipse 20 20 4 6 16 24 n=3 45 +) 44 57 PR(specifies 3 elliptical regions at an angle of 45 degrees: + +) 42 45 PR( 1234567890123456789012345678901234567890 + ---------------------------------------- + 40:........33333333........................ + 39:.....33333333333333..................... + 38:....33333333333333333................... + 37:...33333333333333333333................. + 36:..33333333333333333333333............... + 35:.3333333333222223333333333.............. + 34:3333333322222222222233333333............ + 33:33333332222222222222223333333........... + 32:333333222222222222222222333333.......... + 31:3333322222222222222222222333333......... + 30:33333222222222111122222222333333........ + 29:333332222222111111112222222333333....... + 28:3333222222211111111111222222333333...... + 27:3333222222111111111111112222233333...... + 26:33332222221111111111111112222233333..... + 25:33332222211111111.111111112222233333.... + 24:333322222111111......111111222223333.... + 23:333322222111111.......111112222233333... + 22:33333222221111.........11111222223333... + 21:333332222211111.........11112222233333.. + 20:.33332222211111.........11111222223333.. + 19:.33333222221111.........111112222233333. + 18:..33332222211111.........11112222233333. + 17:..333332222211111.......111111222233333. + 16:...333322222111111......111111222223333. + 15:...333332222211111111.111111112222233333)WR( + 14:....333332222211111111111111122222233333)WR( + 13:.....33333222221111111111111122222233333 + 12:.....33333322222211111111111222222233333)WR( + 11:......3333332222222111111112222222333333 + 10:.......333333222222221111222222222333333 + 9:........33333322222222222222222222333333 + 8:.........333333222222222222222222333333. + 7:..........33333332222222222222223333333. + 6:...........3333333322222222222233333333. + 5:.............3333333333222223333333333.. + 4:..............33333333333333333333333... + 3:................33333333333333333333.... + 2:..................33333333333333333..... + 1:....................33333333333333......)RP( + +)0 P(Both the variable argument syntax and the )BD(n=[int])ES( syntax must +occur alone in a region descriptor \201aside from the optional angle for +boxes and ellipses\202. They cannot be combined. Thus, it is not valid +to precede or follow an )BD(n=[int])ES( accelerator with more angles or +radii, as in this example: +) 3 49 PR( # INVALID -- one too many angles before a=5 ... + # and no angles are allowed after a=5 + PIE 12 12 10 25 50 a=5 85 135)RP( +Instead, use three separate specifications, such as: +) 3 21 PR( PIE 12 12 10 25 + PIE 12 12 25 50 a=5 + PIE 12 12 85 135)RP( +The original \201IRAF\202 implementation of region filtering permitted this +looser syntax, but we found it caused more confusion than it was worth +and therefore removed it. + +)0 P(NB: Accelerators may be combined with other shapes in a boolean +expression in any order. \201This is a change starting with funtools +v1.1.1. Prior to this release, the accelerator shape had to be +specified last\202. The actual region mask id values returned depend on the +order in which the shapes are specified, although the total number of +pixels or rows that pass the filter will be consistent. For this +reason, use of accelerators in boolean expressions is discouraged in +programs such as funcnts, where region mask id values are used +to count events or image pixels. + +)0 P([All region masks displayed in this document were generated using the +)BD(fundisp)ES( routine and the undocumented "mask=all" argument \201with +spaced removed using sed \202: +) 2 72 PR( fundisp "funtools/funtest/test40.fits[ANNULUS 25 25 5 10]" mask=all |\200 + sed 's/ //g')RP( +Note that you must supply an image of the appropriate size -- in this case, +a FITS image of dimension 40x40 is used.] + + + + + +)0 P()0 0 1 A(Go to Funtools Help Index)0 0 TN TL()Ec /AF f D( + +)0 5 121 H(Last)WB 200 Sn( updated: March 12, 2007)EH( + +)WB NL +/Cb Db D /Ct [16#00 16#00 16#00] D /Cl [16#00 16#00 16#00] D /CL -1 D Ct Sc +DS +/Ba f D /BO 0 D Bs +/UR (regalgebra.html) D +/Ti (Region Algebra) D +/Au () D +/Df f D +/ME [()] D + +0 BO R +()1 Sl()WB 56 Sn( + + +)0 2 122 H(RegAlgebra:)WB 202 Sn()WB 201 Sn( Boolean Algebra on Spatial Regions)EA()EH( + + +)0 2 123 H(Summary)WB 203 Sn()EH( +)0 P(This document describes the boolean arithmetic defined for +region expressions. + + +)0 2 124 H(Description)WB 204 Sn()EH( +)0 P(When defining a region, several shapes can be combined using boolean +operations. The boolean operators are \201in order of precedence\202: +) 6 53 PR( Symbol Operator Associativity + ------ -------- ------------- + ! not right to left + & and left to right + ^ exclusive or left to right + | inclusive or left to right)RP( +For example, to create a mask consisting of a large circle with a +smaller box removed, one can use the )BD(and)ES( and )BD(not)ES( +operators: +) 1 36 PR( CIRCLE\20111,11,15\202 & !BOX\20111,11,3,6\202)RP( + +and the resulting mask is: +) 42 49 PR( 1234567890123456789012345678901234567890 + ---------------------------------------- + 1:1111111111111111111111.................. + 2:1111111111111111111111.................. + 3:11111111111111111111111................. + 4:111111111111111111111111................ + 5:111111111111111111111111................ + 6:1111111111111111111111111............... + 7:1111111111111111111111111............... + 8:1111111111111111111111111............... + 9:111111111...1111111111111............... + 10:111111111...1111111111111............... + 11:111111111...1111111111111............... + 12:111111111...1111111111111............... + 13:111111111...1111111111111............... + 14:111111111...1111111111111............... + 15:1111111111111111111111111............... + 16:1111111111111111111111111............... + 17:111111111111111111111111................ + 18:111111111111111111111111................ + 19:11111111111111111111111................. + 20:1111111111111111111111.................. + 21:1111111111111111111111.................. + 22:111111111111111111111................... + 23:..11111111111111111..................... + 24:...111111111111111...................... + 25:.....11111111111........................ + 26:........................................ + 27:........................................ + 28:........................................ + 29:........................................)WR( + 30:........................................ + 31:........................................ + 32:........................................ + 33:........................................ + 34:........................................ + 35:........................................ + 36:........................................ + 37:........................................ + 38:........................................ + 39:........................................ + 40:........................................)RP( +A three-quarter circle can be defined as: +) 1 40 PR( CIRCLE\20120,20,10\202 & !PIE\20120,20,270,360\202)RP( + +and looks as follows: +) 42 49 PR( 1234567890123456789012345678901234567890 + ---------------------------------------- + 1:........................................ + 2:........................................ + 3:........................................ + 4:........................................ + 5:........................................ + 6:........................................ + 7:........................................ + 8:........................................ + 9:........................................ + 10:........................................ + 11:...............111111111................ + 12:..............11111111111............... + 13:............111111111111111............. + 14:............111111111111111............. + 15:...........11111111111111111............ + 16:..........1111111111111111111........... + 17:..........1111111111111111111........... + 18:..........1111111111111111111........... + 19:..........1111111111111111111........... + 20:..........1111111111111111111........... + 21:..........1111111111.................... + 22:..........1111111111.................... + 23:..........1111111111.................... + 24:..........1111111111.................... + 25:...........111111111.................... + 26:............11111111.................... + 27:............11111111.................... + 28:..............111111.................... + 29:...............11111....................)WR( + 30:........................................ + 31:........................................ + 32:........................................ + 33:........................................ + 34:........................................ + 35:........................................ + 36:........................................ + 37:........................................ + 38:........................................ + 39:........................................ + 40:........................................)RP( +Two non-intersecting ellipses can be made into the same region: +) 1 40 PR( ELL\20120,20,10,20,90\202 | ELL\2011,1,20,10,0\202)RP( + +and looks as follows: +) 42 49 PR( 1234567890123456789012345678901234567890 + ---------------------------------------- + 1:11111111111111111111.................... + 2:11111111111111111111.................... + 3:11111111111111111111.................... + 4:11111111111111111111.................... + 5:1111111111111111111..................... + 6:111111111111111111...................... + 7:1111111111111111........................ + 8:111111111111111......................... + 9:111111111111............................ + 10:111111111............................... + 11:...........11111111111111111............ + 12:........111111111111111111111111........ + 13:.....11111111111111111111111111111...... + 14:....11111111111111111111111111111111.... + 15:..11111111111111111111111111111111111... + 16:.1111111111111111111111111111111111111.. + 17:111111111111111111111111111111111111111. + 18:111111111111111111111111111111111111111. + 19:111111111111111111111111111111111111111. + 20:111111111111111111111111111111111111111. + 21:111111111111111111111111111111111111111. + 22:111111111111111111111111111111111111111. + 23:111111111111111111111111111111111111111. + 24:.1111111111111111111111111111111111111.. + 25:..11111111111111111111111111111111111... + 26:...11111111111111111111111111111111..... + 27:.....11111111111111111111111111111...... + 28:.......111111111111111111111111......... + 29:...........11111111111111111............)WR( + 30:........................................ + 31:........................................ + 32:........................................ + 33:........................................ + 34:........................................ + 35:........................................ + 36:........................................ + 37:........................................ + 38:........................................ + 39:........................................ + 40:........................................)RP( +You can use several boolean operations in a single region expression, +to create arbitrarily complex regions. With the important exception +below, you can apply the operators in any order, using parentheses if +necessary to override the natural precedences of the operators. + +)0 P(NB: Using a panda shape is always much more efficient than explicitly +specifying "pie & annulus", due to the ability of panda to place a +limit on the number of pixels checked in the pie shape. If you are +going to specify the intersection of pie and annulus, use panda +instead. + +)0 P(As described in "help regreometry", the )BD(PIE)ES( slice goes to the +edge of the field. To limit its scope, )BD(PIE)ES( usually is is +combined with other shapes, such as circles and annuli, using boolean +operations. In this context, it is worth noting that that there is a +difference between )BD(-PIE)ES( and )BD(&!PIE)ES(. The former is a +global exclude of all pixels in the )BD(PIE)ES( slice, while the latter +is a local excludes of pixels affecting only the region\201s\202 with which +the )BD(PIE)ES( is combined. For example, the following region uses +)BD(&!PIE)ES( as a local exclude of a single circle. Two other circles +are also defined and are unaffected by the local exclude: +) 21 56 PR( CIRCLE\2011,8,1\202 + CIRCLE\2018,8,7\202&!PIE\2018,8,60,120\202&!PIE\2018,8,240,300\202 + CIRCLE\20115,8,2\202 + + 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + - - - - - - - - - - - - - - - + 15: . . . . . . . . . . . . . . . + 14: . . . . 2 2 2 2 2 2 2 . . . . + 13: . . . 2 2 2 2 2 2 2 2 2 . . . + 12: . . 2 2 2 2 2 2 2 2 2 2 2 . . + 11: . . 2 2 2 2 2 2 2 2 2 2 2 . . + 10: . . . . 2 2 2 2 2 2 2 . . . . + 9: . . . . . . 2 2 2 . . . . 3 3 + 8: 1 . . . . . . . . . . . . 3 3 + 7: . . . . . . 2 2 2 . . . . 3 3 + 6: . . . . 2 2 2 2 2 2 2 . . . . + 5: . . 2 2 2 2 2 2 2 2 2 2 2 . . + 4: . . 2 2 2 2 2 2 2 2 2 2 2 . . + 3: . . . 2 2 2 2 2 2 2 2 2 . . . + 2: . . . . 2 2 2 2 2 2 2 . . . . + 1: . . . . . . . . . . . . . . .)RP( +Note that the two other regions are not affected by the )BD(&!PIE)ES(, +which only affects the circle with which it is combined. + +)0 P(On the other hand, a )BD(-PIE)ES( is an global exclude that does +affect other regions with which it overlaps: +) 23 39 PR( CIRCLE\2011,8,1\202 + CIRCLE\2018,8,7\202 + -PIE\2018,8,60,120\202 + -PIE\2018,8,240,300\202 + CIRCLE\20115,8,2\202 + + 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + - - - - - - - - - - - - - - - + 15: . . . . . . . . . . . . . . . + 14: . . . . 2 2 2 2 2 2 2 . . . . + 13: . . . 2 2 2 2 2 2 2 2 2 . . . + 12: . . 2 2 2 2 2 2 2 2 2 2 2 . . + 11: . . 2 2 2 2 2 2 2 2 2 2 2 . . + 10: . . . . 2 2 2 2 2 2 2 . . . . + 9: . . . . . . 2 2 2 . . . . . . + 8: . . . . . . . . . . . . . . . + 7: . . . . . . 2 2 2 . . . . . . + 6: . . . . 2 2 2 2 2 2 2 . . . . + 5: . . 2 2 2 2 2 2 2 2 2 2 2 . . + 4: . . 2 2 2 2 2 2 2 2 2 2 2 . . + 3: . . . 2 2 2 2 2 2 2 2 2 . . . + 2: . . . . 2 2 2 2 2 2 2 . . . . + 1: . . . . . . . . . . . . . . .)RP( +The two smaller circles are entirely contained within the two exclude +)BD(PIE)ES( slices and therefore are excluded from the region. + + + + + +)0 P()0 0 1 A(Go to Funtools Help Index)0 0 TN TL()Ec /AF f D( + +)0 5 125 H(Last)WB 205 Sn( updated: November 17, 2005)EH( + +)WB NL +/Cb Db D /Ct [16#00 16#00 16#00] D /Cl [16#00 16#00 16#00] D /CL -1 D Ct Sc +DS +/Ba f D /BO 0 D Bs +/UR (regcoords.html) D +/Ti (Spatial Region Coordinates) D +/Au () D +/Df f D +/ME [()] D + +0 BO R +()1 Sl()WB 57 Sn( + + +)0 2 126 H(RegCoords:)WB 207 Sn()WB 206 Sn( Spatial Region Coordinates)EA()EH( + + +)0 2 127 H(Summary)WB 208 Sn()EH( +)0 P(This document describes the specification of coordinate systems, and the +interpretation of coordinate values, for spatial region filtering. + + +)0 2 128 H(Pixel)WB 209 Sn( coordinate systems)EH( +)0 P(The default coordinate system for regions is PHYSICAL, which means +that region position and size values are taken from the original +data. \201Note that this is a change from the original IRAF/PROS +implementation, in which the IMAGE coordinate system was the default.\202 +PHYSICAL coordinates always refer to pixel positions on the original +image \201using IRAF LTM and LTV keywords\202. With PHYSICAL coordinates, +if a set of coordinates specifies the position of an object in an +original FITS file, the same coordinates will specify the same object +in any FITS derived from the original. Physical coordinates are +invariant with blocking of FITS files or taking sections of images, +even when a blocked section is written to a new file. + +)0 P(Thus, although a value in pixels refers, by default, to the PHYSICAL +coordinate system, you may specify that position values refer to the +image coordinate system using the )BD(global)ES( or )BD(local)ES( +properties commands: + +) 2 23 PR( global coordsys image + circle 512 512 100)RP( + +The )BD(global)ES( command changes the coordinate system for all +regions that follow, while the )BD(local)ES( command changes the +coordinate system only for the region immediately following: +) 3 22 PR( local coordsys image + circle 512 512 100 + circle 1024 1024 200)RP( +This changes the coordinate system only for the region that follows. +In the above example, the second region uses the global coordinate +system \201PHYSICAL by default\202. + +)0 P()0 2 129 H(World)WB 210 Sn( Coordinate Systems)EH( + +If World Coordinate System information is contained in the data file +being filtered, it also is possible to define regions using a sky +coordinate system. Supported systems include: + +) 10 67 PR( name description + ---- ----------- + PHYSICAL pixel coords of original file using LTM/LTV + IMAGE pixel coords of current file + FK4, B1950 sky coordinate systems + FK5, J2000 sky coordinate systems + GALACTIC sky coordinate systems + ECLIPTIC sky coordinate systems + ICRS currently same as J2000 + LINEAR linear wcs as defined in file)RP( + +In addition, two mosaic coordinate systems have been defined that +utilize the \201evolving\202 IRAF mosaic keywords: + +) 4 68 PR( name description + ---- ----------- + AMPLIFIER mosaic coords of original file using ATM/ATV + DETECTOR mosaic coords of original file using DTM/DTV)RP( +Again, to use one of these coordinate systems, the )BD(global)ES( or +)BD(local)ES( properties commands are used: + +) 1 26 PR( global coordsys galactic)RP( + +)0 2 130 H(WCS)WB 211 Sn( Positions and Sizes)EH( + +In addition to pixels, positional values in a WCS-enabled region can +be specified using sexagesimal or degrees format: + +) 11 57 PR( position arguments description + ------------------ ----------- + [num] context-dependent \201see below\202 + [num]d degrees + [num]r radians + [num]p physical pixels + [num]i image pixels + [num]:[num]:[num] hms for 'odd' position arguments + [num]:[num]:[num] dms for 'even' position arguments + [num]h[num]m[num]s explicit hms + [num]d[num]m[num]s explicit dms)RP( + +If ':' is used as sexagesimal separator, the value is considered to be +specifying hours/minutes/seconds if it is the first argument of a +positional pair, and degrees/minutes/seconds for the second argument +of a pair \201except for galactic coordinates, which always use degrees\202: + +) 7 78 PR( argument description + ----------- ----------- + 10:20:30.0 10 hours, 20 minutes, 30 seconds for 1st positional argument + 10 degrees, 20 minutes, 30 seconds for 2nd positional argument + 10h20m30.0 10 hours, 20 minutes, 30 seconds + 10d20m30.0 10 degrees, 20 minutes, 30 seconds + 10.20d 10.2 degrees)RP( + +Similarly, the units of size values are defined by the formating +character\201s\202 attached to a number: + +) 9 53 PR( size arguments description + -------------- ----------- + [num] context-dependent \201see below\202 + [num]" arc seconds + [num]' arc minutes + [num]d degrees + [num]r radians + [num]p physical pixels + [num]i image pixels)RP( + +For example: +) 8 34 PR( argument description + ----------- ----------- + 10 ten pixels + 10' ten minutes of arc + 10" ten seconds of arc + 10d ten degrees + 10p ten pixels + 0.5r half of a radian)RP( + +)0 P(An example of using sky coordinate systems follows: + +) 4 65 PR( global coordsys B1950 + -box 175.54d 20.01156d 10' 10' + local coordsys J2000 + pie 179.57d 22.4d 0 360 n=4 && annulus 179.57d 22.4d 3' 24' n=5)RP( + +At the FK4 1950 coordinates 175.54d RA, 20.01156d DEC exclude a 10 +minute by 10 minute box. Then at the FK5 2000 coordinates 179.57d RA +22.4d DEC draw a radial profile regions pattern with 4 quadrants and 5 +annuli ranging from 3 minutes to 24 minutes in diameter. In this +example, the default coordinate system is overridden by the commands +in the regions spec. + +)0 2 131 H(NB:)WB 212 Sn( The Meaning of Pure Numbers Are Context Sensitive)EH( + +)0 P(When a "pure number" \201i.e. one without a format directive such as 'd' +for 'degrees'\202 is specified as a position or size, its interpretation +depends on the context defined by the 'coordsys' keyword. In general, +the rule is: + +)0 P()BD(All pure numbers have implied units corresponding to the current +coordinate system.)ES( + +)0 P(If no coordinate system is explicitly specified, the default system is +implicitly assumed to be PHYSICAL. In practice this means that for +IMAGE and PHYSICAL systems, pure numbers are pixels. Otherwise, +for all systems other than LINEAR, pure numbers are degrees. For +LINEAR systems, pure numbers are in the units of the linear system. +This rule covers both positions and sizes. + +)0 P(As a corollary, when a sky-formatted number is used with the IMAGE +or PHYSICAL coordinate system \201which includes the default case of no +coordsys being specified\202, the formatted number is assumed to be in +the units of the WCS contained in the current file. If no sky WCS is +specified, an error results. + +)0 P(Examples: + +) 2 43 PR( circle\201512,512,10\202 + ellipse 202.44382d 47.181656d 0.01d 0.02d)RP( + +)0 P(In the absence of a specified coordinate system, the circle uses the +default PHYSICAL units of pixels, while the ellipse explicitly uses degrees, +presumably to go with the WCS in the current file. + +) 5 43 PR( global coordsys=fk5 + global color=green font="system 10 normal" + circle 202.44382 47.181656 0.01 + circle 202.44382 47.181656 10p + ellipse\201512p,512p,10p,15p,20\202)RP( + + +)0 P(Here, the circles use the FK5 units of degrees \201except for the +explicit use of pixels in the second radius\202, while the ellipse +explicitly specifies pixels. The ellipse angle is in degrees. + +)0 P(Note that Chandra data format appears to use "coordsys=physical" +implicitly. Therefore, for most Chandra applications, valid regions +can be generated safely by asking ds9 to save/display regions in +pixels using the PHYSICAL coordsys. + + + + + +)0 P()0 0 1 A(Go to Funtools Help Index)0 0 TN TL()Ec /AF f D( + +)0 5 132 H(Last)WB 213 Sn( updated: November 17, 2005)EH( + +)WB NL +/Cb Db D /Ct [16#00 16#00 16#00] D /Cl [16#00 16#00 16#00] D /CL -1 D Ct Sc +DS +/Ba f D /BO 0 D Bs +/UR (regbounds.html) D +/Ti (Spatial Region Boundaries) D +/Au () D +/Df f D +/ME [()] D + +0 BO R +()1 Sl()WB 58 Sn( + + +)0 2 133 H(RegBounds:)WB 215 Sn()WB 214 Sn( Region Boundaries)EA()EH( + + +)0 2 134 H(Summary)WB 216 Sn()EH( +Describes how spatial region boundaries are handled. + + +)0 2 135 H(Description)WB 217 Sn()EH( +)0 P(The golden rule for spatial region filtering was first enunciated by +Leon VanSpeybroeck in 1986: + +)0 P()BD(Each photon will be counted once, and no photon will be counted +more than once)ES(. + +)0 P(This means that we must be careful about boundary +conditions. For example, if a circle is contained in an annulus such +that the inner radius of the annulus is the same as the radius of the +circle, then photons on that boundary must always be assigned to one +or the other region. That is, the number of photons in both regions +must equal the sum of the number of photons in each region taken +separately. + +With this in mind, the rules for determining whether a boundary image +pixel or table row are assigned to a region are defined below. + +)0 2 136 H(Image)WB 218 Sn( boundaries : radially-symmetric shapes \201circle, annuli, ellipse\202)EH( + +For image filtering, pixels whose center is inside the boundary are +included. This also applies non-radially-symmetric shapes. When a +pixel center is exactly on the boundary, the pixel assignment rule is: + +)UL()-1 LI( the outer boundary of a symmetric shape does not include such pixels +)-1 LI( the inner boundary of a symmetric shape \201annulus\202 includes such pixels)LU( + +In this way, an annulus with radius from 0 to 1, centered exactly on a +pixel, includes the pixel on which it is centered, but none of its +neighbors. + +These rules ensure that when defining concentric shapes, no pixels are +omitted between concentric regions and no pixels are claimed by two +regions. When applied to small symmetric shapes, the shape is less +likely to be skewed, as would happen with non-radially-symmetric +rules. These rules differ from the rules for box-like shapes, which +are more likely to be positioned adjacent to one another. + +)0 2 137 H(Image)WB 219 Sn( Boundaries: non-radially symmetric shapes \201polygons, boxes\202)EH( + +For image filtering, pixels whose center is inside the boundary are +included. This also applies radially-symmetric shapes. When a pixel +center is exactly on the boundary of a non-radially symmetric region, +the pixel is included in the right or upper region, but not the left +or lower region. This ensures that geometrically adjoining regions +touch but don't overlap. + +)0 2 138 H(Row)WB 220 Sn( Boundaries are Analytic)EH( + +When filtering table rows, the boundary rules are the same as for +images, except that the calculation is not done on the center of a +pixel, \201since table rows, especially X-ray events rows, often have +discrete, floating point positions\202 but are calculated exactly. That +is, an row is inside the boundary without regard to its integerized +pixel value. For rows that are exactly on a region boundary, the +above rules are applied to ensure that all rows are counted once and +no row is counted more than once. + +)0 P(Because row boundaries are calculated differently from image boundaries, +certain programs will give different results when filtering the same +region file. In particular, fundisp/funtable \201which utilize analytic +row filtering\202 perform differently from funcnts \201which performs image +filtering, even on tables\202. + +)0 2 139 H(Image)WB 221 Sn( Boundaries vs. Row Boundaries: Practical Considerations)EH( + +)0 P(You will sometimes notice a discrepancy between running funcnts on an +binary table file and running fundisp on the same file with the same filter. +For example, consider the following: +) 2 49 PR( fundisp test1.fits"[box\2014219,3887,6,6,0\202]" | wc + 8893 320148 3752846)RP( +Since fundisp has a 2-line header, there are actually 8891 photons +that pass the filter. But then run funtable and select only the +rows that pass this filter, placing them in a new file: +) 1 58 PR( ./funtable test1.fits"[box\2014219,3887,6,6,0\202]" test2.fits)RP( +Now run funcnts using the original filter on the derived file: +) 12 61 PR( ./funcnts test2.fits "physical; box\2014219,3887,6,6,0\202" + + [... lot of processed output ...] + + # the following source and background components were used: + source region\201s\202 + ---------------- + physical; box\2014219,3887,6,6,0\202 + + reg counts pixels + ---- ------------ --------- + 1 7847.000 36)RP( +There are 1044 rows \201events\202 that pass the row filter in fundisp \201or +funtable\202 but fail to make it through funcnts. Why? + +)0 P(The reason can be traced to how analytic row filtering \201fundisp, funtable\202 +differs from integerized pixel filtering\201funcnts, funimage\202. Consider the +region: +) 1 22 PR( box\2014219,3887,6,6,0\202)RP( +Analytically \201i.e., using row filtering\202, positions will pass this +filter successfully if: +) 2 19 PR( 4216 <= x <= 4222 + 3884 <= y <= 3890)RP( +For example, photons with position values of x=4216.4 or y=3884.08 will pass. + +)0 P(Integerized image filtering is different in that the pixels that will +pass this filter have centers at: +) 2 40 PR( x = 4217, 4218, 4219, 4220, 4221, 4222 + y = 3885, 3886, 3887, 3888, 3889, 3890)RP( +Note that there are 6 pixels in each direction, as specified by the region. +That means that positions will pass the filter successfully if: +) 2 24 PR( 4217 <= \201int\202x <= 4222 + 3885 <= \201int\202y <= 3890)RP( +Photons with position values of x=4216.4 or y=3884.08 will NOT pass. + +)0 P(Note that the position values are integerized, in effect, binned into +image values. This means that x=4222.4 will pass this filter, but not +the analytic filter above. We do this to maintain the design goal that +either all counts in a pixel are included in an integerized filter, or +else none are included. + +)0 P([It could be argued that the correct photon limits for floating point +row data really should be: +) 2 23 PR( 4216.5 <= x <= 4222.5 + 3884.5 <= y <= 3890.5)RP( +since each pixel extends for .5 on either side of the center. We chose +to the maintain integerized algorithm for all image-style filtering so +that funcnts would give the exact same results regardless of whether +a table or a derived non-blocked binned image is used.] + + + + + +)0 P()0 0 1 A(Go to Funtools Help Index)0 0 TN TL()Ec /AF f D( + +)0 5 140 H(Last)WB 222 Sn( updated: November 16, 2005)EH( + +)WB NL +/Cb Db D /Ct [16#00 16#00 16#00] D /Cl [16#00 16#00 16#00] D /CL -1 D Ct Sc +DS +/Ba f D /BO 0 D Bs +/UR (regdiff.html) D +/Ti (Differences Between Funtools and IRAF Regions) D +/Au () D +/Df f D +/ME [()] D + +0 BO R +()1 Sl()WB 59 Sn( + + +)0 2 141 H(RegDiff:Differences)WB 224 Sn()WB 223 Sn( Between Funtools and IRAF Regions)EA()EH( + + +)0 2 142 H(Summary)WB 225 Sn()EH( +Describes the differences between Funtools/ds9 regions and the old IRAF/PROS +regions. + + +)0 2 143 H(Description)WB 226 Sn()EH( +)0 P(We have tried to make Funtools regions compatible with their +predecessor, IRAF/PROS regions. For simple regions and simple boolean +algebra between regions, there should be no difference between the two +implementations. The following is a list of differences and +incompatibilities between the two: + +)UL( +)0 P()-1 LI(If a pixel is covered by two different regions expressions, +Funtools assigns the mask value of the )BD(first)ES( region that +contains that pixel. That is, successive regions )BD(do not)ES( +overwrite previous regions in the mask, as was the case with the +original PROS regions. This means that one must define overlapping +regions in the reverse order in which they were defined in PROS. If +region N is fully contained within region M, then N should be defined +)BD(before)ES( M, or else it will be "covered up" by the latter. This +change is necessitated by the use of optimized filter compilation, i.e., +Funtools only tests individual regions until a proper match is made. + +)0 P()-1 LI( The )BD(PANDA)ES( region has replaced the old PROS syntax in which +a )BD(PIE)ES( accelerator was combined with an )BD(ANNULUS)ES( accelerator +using )BD(AND)ES(. That is, +) 1 48 PR( ANNULUS\20120,20,0,15,n=4\202 & PIE\20120,20,0,360,n=3\202)RP( +has been replaced by: +) 1 29 PR( PANDA\20120,20,0,360,3,0,15,4\202)RP( +The PROS syntax was inconsistent with the meaning of the )BD(AND)ES( operator. + +)0 P()-1 LI( The meaning of pure numbers \201i.e., without format specifiers\202 in +regions has been clarified, as has the syntax for specifying coordinate +systems. See the general discussion on +)0 54 1 A(Spatial Region Filtering)54 0 TN TL()Ec /AF f D( +for more information. +)LU( + + + + + +)0 P()0 0 1 A(Go to Funtools Help Index)0 0 TN TL()Ec /AF f D( + +)0 5 144 H(Last)WB 227 Sn( updated: November 16, 2005)EH( + +)WB NL +/Cb Db D /Ct [16#00 16#00 16#00] D /Cl [16#00 16#00 16#00] D /CL -1 D Ct Sc +DS +/Ba f D /BO 0 D Bs +/UR (combo.html) D +/Ti (Combining Region and Table Filters) D +/Au () D +/Df f D +/ME [()] D + +0 BO R +()1 Sl()WB 60 Sn( + + +)0 2 145 H(FunCombine:)WB 230 Sn()WB 228 Sn( Combining Region and Table Filters)EA()EH( + + +)0 2 146 H(Summary)WB 231 Sn()EH( +)0 P(This document discusses the conventions for combining region and table +filters, especially with regards to the comma operator. + + + +)0 2 147 H(Comma)WB 232 Sn()WB 229 Sn( Conventions)EA()EH( +)0 P(Filter specifications consist of a series of boolean expressions, +separated by commas. These expressions can be table filters, +spatial region filters, or combinations thereof. Unfortunately, +common usage requires that the comma operator must act differently +in different situations. Therefore, while its use is intuitive in +most cases, commas can be a source of confusion. + +)0 P(According to long-standing usage in IRAF, when a comma separates two +table filters, it takes on the meaning of a boolean )BD(and)ES(. Thus: +) 1 24 PR( foo.fits[pha==1,pi==2])RP( +is equivalent to: +) 1 27 PR( foo.fits[pha==1 && pi==2])RP( + +When a comma separates two spatial region filters, however, it has +traditionally taken on the meaning of a boolean )BD(or)ES(. Thus: +) 1 46 PR( foo.fits[circle\20110,10,3\202,ellipse\20120,20,8,5\202])RP( +is equivalent to: +) 1 49 PR( foo.fits[circle\20110,10,3\202 || ellipse\20120,20,8,5\202])RP( +\201except that in the former case, each region is given a unique id +in programs such as funcnts\202. + +)0 P(Region and table filters can be combined: +) 1 34 PR( foo.fits[circle\20110,10,3\202,pi=1:5])RP( +or even: +) 1 61 PR( foo.fits[pha==1&&circle\20110,10,3\202,pi==2&&ellipse\20120,20,8,5\202])RP( +In these cases, it is not obvious whether the command should utilize an +)BD(or)ES( or )BD(and)ES( operator. We therefore arbitrarily chose to +implement the following rule: +)UL()-1 LI( if both expressions contain a region, the operator used is )BD(or)ES(. +)-1 LI( if one \201or both\202 expression\201s\202 does not contain a region, the operator +used is )BD(and)ES(.)LU( +This rule handles the cases of pure regions and pure column filters properly. +It unambiguously assigns the boolean )BD(and)ES( to all mixed cases. Thus: +) 1 34 PR( foo.fits[circle\20110,10,3\202,pi=1:5])RP( +and +) 1 34 PR( foo.fits[pi=1:5,circle\20110,10,3\202])RP( +both are equivalent to: +) 1 37 PR( foo.fits[circle\20110,10,3\202 && pi=1:5])RP( + +)0 P([NB: This arbitrary rule )BD(replaces the previous arbitrary rule)ES( +\201pre-funtools 1.2.3\202 which stated: +)UL()-1 LI( if the 2nd expression contains a region, the operator used is )BD(or)ES(. +)-1 LI( if the 2nd expression does not contain a region, the operator +used is )BD(and)ES(.)LU( +In that scenario, the )BD(or)ES( operator was implied by: +) 1 21 PR( pha==4,circle 5 5 1)RP( +while the )BD(and)ES( operator was implied by +) 1 21 PR( circle 5 5 1,pha==4)RP( +Experience showed that this non-commutative treatment of the comma +operator was confusing and led to unexpected results.] + +)0 P(The comma rule must be considered provisional: comments and complaints +are welcome to help clarify the matter. Better still, we recommend +that the comma operator be avoided in such cases in favor of an +explicit boolean operator. + + + + + +)0 P()0 0 1 A(Go to Funtools Help Index)0 0 TN TL()Ec /AF f D( + +)0 5 148 H(Last)WB 233 Sn( updated: November 16, 2005)EH( + +)WB NL +/Cb Db D /Ct [16#00 16#00 16#00] D /Cl [16#00 16#00 16#00] D /CL -1 D Ct Sc +DS +/Ba f D /BO 0 D Bs +/UR (env.html) D +/Ti (Funtools Environment Variables) D +/Au () D +/Df f D +/ME [()] D + +0 BO R +()1 Sl()WB 61 Sn( + + +)0 2 149 H(FunEnv:)WB 235 Sn()WB 234 Sn( Funtools Environment Variables)EA()EH( + + +)0 2 150 H(Summary)WB 236 Sn()EH( +Describes the environment variables which can be used to tailor the overall +Funtools environment. + + +)0 2 151 H(Description)WB 237 Sn()EH( +)0 P(The following environment variables are supported by Funtools: +)0 DL()0 P()0 DT()BD(FITS_EXTNAME)ES( +)DD( The )BD(FITS_EXTNAME)ES( environment variable specifies the +default FITS extension name when )0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D( is called on a file lacking +a primary image. Thus, +) 1 29 PR( setenv FITS_EXTNAME "NEWEV")RP( +will allow you to call )0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D( on files without specifying NEWEV in +the +)0 42 1 A(Funtools bracket specification)42 0 TN TL()Ec /AF f D(. +If no FITS_EXTNAME variable is defined and the extension name also is +not passed in the bracket specification, then the default will be to +look for standard X-ray event table extension names "EVENTS" or +"STDEVT" \201we are, after all, and X-ray astronomy group at heart!\202. + +)0 P()0 DT()BD(FITS_EXTNUM)ES( +)DD( The )BD(FITS_EXTNUM)ES( environment variable specifies the +default FITS extension number when )0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D( is called on a file lacking +a primary image. Thus, +) 1 22 PR( setenv FITS_EXTNUM 7)RP( +will allow you to call )0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D( on files to open the seventh +extension without specifying the number in the +)0 42 1 A(Funtools bracket specification)42 0 TN TL()Ec /AF f D(. + +)0 P()0 DT()BD(FITS_BINCOLS)ES( and )BD(EVENTS_BINCOLS)ES( +)DD( These environment variable specifies the default binning key for +FITS binary tables and raw event files, respectively. They can be +over-ridden using the )BD(bincols=[naxis1,naxis2])ES( keyword in a +)0 42 1 A(Funtools bracket specification)42 0 TN TL()Ec /AF f D(. +The value of each environment variable +is a pair of comma-delimited columns, enclosed in parentheses, to use +for binning. For example, if you want to bin on detx and dety by +default, then use: +) 1 35 PR( setenv FITS_BINCOLS "\201detx,dety\202")RP( +in preference to adding a bincols specification to each filename: +) 1 31 PR( foo.fits[bincols=\201detx,dety\202])RP( + +)0 P()0 DT()BD(FITS_BITPIX)ES( and )BD(EVENTS_BITPIX)ES( +)DD( These environment variable specifies the default bitpix value for +binning FITS binary tables and raw event files, respectively. They can +be over-ridden using the )BD(bitpix=[value])ES( keyword in a +)0 42 1 A(Funtools bracket specification)42 0 TN TL()Ec /AF f D(. The value +of each environment variable is one of the standard FITS bitpix values +\2018,16,32,-32,-64\202. For example, if you want binning routines to +create a floating array, then use: +) 1 24 PR( setenv FITS_BITPIX -32)RP( +in preference to adding a bitpix specification to each filename: +) 1 22 PR( foo.fits[bitpix=-32])RP( + +)0 P()0 DT()BD(ARRAY)ES( +)DD( The )BD(ARRAY)ES( environment variable specifies the default +definition of an array file for Funtools. +It is used if there is no array specification passed in the +)BD(ARRAY\201\202)ES( directive in a +)0 46 1 A(Non-FITS Array specification)46 0 TN TL()Ec /AF f D(. +The value of the environment variable is a valid array specification such as: +) 2 25 PR( setenv ARRAY "s100.150" + foo.arr[ARRAY\201\202])RP( +This can be defined in preference to adding the specification to each filename: +) 1 26 PR( foo.arr[ARRAY\201s100.150\202])RP( + +)0 P()0 DT()BD(EVENTS)ES( +)DD( The )BD(EVENTS)ES( environment variable specifies the default +definition of an raw event file for Funtools. +It is used if there is no EVENTS specification passed in the +)BD(EVENTS\201\202)ES( directive in a +)0 45 1 A(Non-FITS EVENTS specification)45 0 TN TL()Ec /AF f D(. +The value of the environment variable is a valid EVENTS specification such as: +) 2 73 PR( setenv EVENTS "x:J:1024,y:J:1024,pi:I,pha:I,time:D,dx:E:1024,dx:E:1024" + foo.ev[EVENTS\201\202])RP( +This can be defined in preference to adding the specification to each filename: +) 1 73 PR( foo.ev[EVENTS\201x:J:1024,y:J:1024,pi:I,pha:I,time:D,dx:E:1024,dx:E:1024\202])RP()LD( + +The following filter-related environment variables are supported by Funtools: +)0 DL( +)0 P()0 DT()BD(FILTER_PTYPE)ES( +)DD( The )BD(FILTER_PTYPE)ES( environment variable specifies how to +build a filter. There are three possible methods: +)0 DL()0 DT(process or p +)DD(The filter is compiled and linked against the funtools library \201which +must therefore be accessible in the original install directory\202 to produce +a slave program. This program is fed events or image data and returns +filter results. + +)0 DT(dynamic or d \201gcc only\202 +)DD(The filter is compiled and linked against the funtools library \201which +must therefore be accessible in the original install directory\202 to produce +a dynamic shared object, which is loaded into the funtools program and +executed as a subroutine. \201Extensive testing has shown that, contrary to +expectations, this method is no faster than using a slave process.\202 + +)0 DT(contained or c +)DD(The filter and all supporting region code is compiled and linked +without reference to the funtools library to produce a slave program +\201which is fed events or image data and returns filter results\202. This method +is slower than the other two, because of the time it takes to compile the +region filtering code. It is used by stand-alone programs such as ds9, +which do not have access to the funtools library.)LD( + +By default, )BD(dynamic)ES( is generally used for gcc compilers and +)BD(process)ES( for other compilers. However the filter building algorithm +will check for required external files and will use )BD(contained)ES( is +these are missing. + +)0 P()0 DT()BD(FUN_MAXROW)ES( +)DD( The )BD(FUN_MAXROW)ES( environment variable is used by core +row-processing Funtools programs \201funtable, fundisp, funcnts, funhist, +funmerge, and funcalc\202 to set the maximum number of rows read at once +\201i.e. it sets the third argument to the FunTableRowGet\201\202 call\202. The +default is 8192. Note that this variable is a convention only: it will +not be a part of a non-core Funtools program unless code is explicitly +added, since each call to FunTableRowGet\201\202 specifies its own maximum +number of rows to read. NB: if you make this value very large, you +probably will need to increase )BD(FUN_MAXBUFSIZE)ES( \201see below\202 as well. + +)0 P()0 DT()BD(FUN_MAXBUFSIZE)ES( +)DD( The )BD(FUN_MAXBUFSIZE)ES( environment variable is used to limit the +max buffer size that will be allocated to hold table row data. This +buffer size is calculated to be the row size of the table multiplied +by the maximum number of rows read at once \201see above\202. Since the +row size is unlimited \201and we have examples of it being larger than 5 +Mb\202, it is possible that the total buffer size will exceed the machine +capabilities. We therefore set a default value of 5Mb for the max buffer +size, and adjust maxrow so that the total size calculated is less than +this max buffer size. \201If the row size is greater than this max buffer +size, then maxrow is set to 1.\202 This environment variable will change +the max buffer size allowed. + +)0 P()0 DT()BD(FILTER_CC)ES( +)DD( The )BD(FILTER_CC)ES( environment variable specifies the compiler to +use for compiling a filter specification. You also can use the )BD(CC)ES( +environment variable. If neither has been set, then gcc will be used +if available. Otherwise cc is used if available. + +)0 P()0 DT()BD(FILTER_EXTRA)ES( +)DD( The )BD(FILTER_EXTRA)ES( environment variable specifies extra options +to add to a filter compile command line. In principle, you can add libraries, +include files, and compiler switches. This variable should be used with care. + +)0 P()0 DT()BD(FILTER_TMPDIR)ES( +)DD( The )BD(FILTER_TMPDIR)ES( environment variable specifies the temporary +directory for filter compilation intermediate files. You also can use +the )BD(TMPDIR)ES( and )BD(TMP)ES( variables. By default, /tmp is used +as the temporary directory. + +)0 P()0 DT()BD(FILTER_KEEP)ES( +)DD( The )BD(FILTER_KEEP)ES( environment variable specifies whether the +intermediate filter files \201i.e. C source file and compile log file\202 +should be saved after a filter is built. The default is "false", so that +these intermediate files are deleted. This variable is useful for debugging, +but care should be taken to reset its value to false when debugging is +complete. +)LD( + + + + + +)0 P()0 0 1 A(Go to Funtools Help Index)0 0 TN TL()Ec /AF f D( + +)0 5 152 H(Last)WB 238 Sn( updated: November 16, 2005)EH( + + +)WB NL +/Cb Db D /Ct [16#00 16#00 16#00] D /Cl [16#00 16#00 16#00] D /CL -1 D Ct Sc +DS +/Ba f D /BO 0 D Bs +/UR (changelog.html) D +/Ti (Funtools ChangeLog) D +/Au () D +/Df f D +/ME [()] D + +0 BO R +()1 Sl()WB 62 Sn( +)0 2 153 H(Funtools)WB 239 Sn( ChangeLog)EH( + +)0 P(This ChangeLog covers both the Funtools library and the suite of +applications. It will be updated as we continue to develop and improve +Funtools. The up-to-date version can be found +)R5 2 A(here)EA(. +[The changelog for the initial development of Funtools, covering the +beta releases, can be found +)R6 2 A(here)EA(.] + +)0 2 154 H()WB 240 Sn( Patch Release 1.4.5 \201internal ds9 release\202)EH( +)UL()0 P()-1 LI( Removed permission checking from Find\201\202 on cygwin systems. This was broken +by Windows 7. +)0 P()-1 LI( Removed addition of -no-cpp-precomp flag from gcc 4.2 and beyond.)LU( + +)0 2 155 H()WB 241 Sn( Patch Release 1.4.4 \201internal ds9 release\202)EH( +)UL()0 P()-1 LI( Fixed -J funcone, which was not properly outputting all rows. +)0 P()-1 LI( Filter: when an image is flipped, the rotation angle must be reversed. +)0 P()-1 LI( Filter: add support for windows-based ipc communication when using tcc +compiler.)LU( + +)0 2 156 H()WB 242 Sn( Patch Release 1.4.3 \201internal ds9 release\202)EH( +)UL()0 P()-1 LI( Filter: improve checks for existence of compiler, even if CC is set. +)0 P()-1 LI( Change launch.h to xlaunch.h to avoid conflict with OS X. +)0 P()-1 LI( handle flipped images in filtering)LU( + +)0 2 157 H()WB 243 Sn( Patch Release 1.4.2 \201internal ds9 release\202)EH( +)UL()0 P( +)-1 LI( Port to gcc 4.2. +)0 P()-1 LI( Fix 1-byte filters on intel machines \201missing SW1 no-op\202. +)0 P()-1 LI( Remove ambiguity from filt.l \201and calc.l\202 using [A-z] in a +case-insensitive lexer. +)0 P()-1 LI( In funsky, the default unit for RA was changed from hours to degrees. +)0 P()-1 LI( Fixed bug in funtable in which TCRVL header values were output as strings. +)0 P()-1 LI( Added support for running funtools filters in Rosetta \201i.e. running PPC +executables on an Intel Mac\202 by sensing and handling data swap requirements. +Only works with FILTER_PTYPE set to 'c' \201can't link against wrong architecture +libraries\202. +)0 P()-1 LI( Fixed bug in FITS library to allow "-" in extension names. +)0 P()-1 LI( Code and documentation now agree that the copy extension specifier \201'+'\202 +comes after the extension name.)LU( + +)0 2 158 H()WB 244 Sn( Patch Release 1.4.1 \201internal ds9 release\202)EH( +)UL()0 P()-1 LI( Modified internal Launch\201\202 routine to use posix_spawn\201\202, if necessary. +This is required for OS X 10.5 \201leopard\202, which frowns upon use of fork\201\202 +and exec\201\202. Also modified zprocess routines to use Launch\201\202.)LU( + +)0 2 159 H()WB 245 Sn( Public Release 1.4.0 \20115 August 2007\202)EH( + +)UL()-1 LI( Public release of production-quality code, incorporating changes +and improvements from previous beta releases, including: +)UL()-1 LI( Support for access to ASCII text column files. +)-1 LI( Support for fast indexed access of binary tables. +)-1 LI( Support for database views of tables, i.e. pre-set values for the filter + specification, the columns to activate, and display format. +)-1 LI( New programs include funcone \201cone search\202, funindex \201create index files\202, + and funcen \201calculate centroids within regions\202.)LU( +)LU( + +)0 2 160 H()WB 246 Sn( Release 1.3.0b[n] \201mainly internal SAO beta releases\202)EH( +)UL( +)0 P()-1 LI( Added -F[c] switch to change the column delimiter to the +specified character. + +)0 P()-1 LI( Extended fundisp's format switch \201-f\202 so that it can now handle complex +formats such as 'x=sometext%3d- y=othertest%3d.ext'. + +)0 P()-1 LI( Added support for creating and processing 1D FITS images. + +)0 P()-1 LI( Added vcol=colname and vcol=/colname to filter specifications to +support use of a third value column when binning 2D images. + +)0 P()-1 LI( Added switches to funcone to write out data rows are not within +any cone \201-J, -X\202 and centers which have no close data rows \201-L\202. + +)0 P()-1 LI( In funjoin, added ability to specify a numeric tolerance for when joining +two files. + +)0 P()-1 LI( shared memory support in gio now can create a shared segment if w+ is +specified as the open mode. + +)0 P()-1 LI( Changed reggeometry man page so that examples correctly show angles +going counter-clockwise from the x-axis instead of from the y-axis. + +)0 P()-1 LI( Added checks to funmerge to ensure that all files have the same columns. + +)0 P()-1 LI( Fixed bug in text support that prevented header-less files from being +processed properly. + +)0 P()-1 LI( Added support for 64-bit images \201bitpix=64\202 and table columns \201TFORM=K\202. + +)0 P()-1 LI( Filter code was not applying bscale/bzero to columns. + +)0 P( +)-1 LI( Fixed funimage bug that caused a .5/block error in WCS CRPIX values +generated from binary tables. + +)0 P()-1 LI( Added feq\201a,b\202 and div\201a,b\202 macros to funcalc. + +)0 P()-1 LI( Added support for single-line #define to funcalc. + +)0 P()-1 LI( Updated wcs library to 3.6.6 + +)0 P()-1 LI( Fix bug in funcen in which ra,dec was not being calculated correctly +if physical and image coords did not match up. + +)0 P()-1 LI( The filter syntax "col1 = col2" now explicitly generates an error +\201you really want to do "col1 == col2"\202. + +)0 P()-1 LI( Added -o switch to include offset from the nominal target position. + +)0 P()-1 LI( Fundisp now displays multi-dimensional vector columns properly. + +)0 P()-1 LI( Documented support for lists of files processed as a single file +using "list: file1 ... filen" syntax. + +)0 P()-1 LI( Fixed bugs in support for pipe file type \201i.e. ability to pass +commands as a filename using "pipe: cmd arg1 ... argn" syntax\202. + +)0 P()-1 LI( Fixed bug in funhist processing of image-based pixel histograms +\201i.e using "xy" for columns\202 where a region was specified. All pixels +outside the region were erroneously being added to the bin containing +the 0 value. + +)0 P()-1 LI( Disabled multi-file processing in funds9, which was breaking support +for pathnames containing spaces and is not used by ds9 anyway. + +)0 P()-1 LI( Added support for Views of tables, i.e. pre-set values for the +filter specification, the columns to activate, and display format +\201though the latter is for fundisp only\202. + +)0 P()-1 LI( Added -l switch to funimage to read x, y, val columns from a list. + +)0 P()-1 LI( Removed useless and meaningless section syntax foo'[*]' because it +breaks pointer de-referencing on string columns \201i.e. foo'[*xxx=='a']'\202. +Use foo'[*,*]' instead, as documented. + +)0 P()-1 LI( String variables were not always being terminated properly in the +filter code because FITS 'A' data is not necessarily null-terminated. + +)0 P()-1 LI( Added funtools version number to all usage\201\202 displays. + +)0 P()-1 LI( Added explanation of switch arguments to many usage\201\202 displays. + +)0 P()-1 LI( The filter keyword row# now supports single row selection as well +as range selection, i.e., "row#=100" along with previous "row#=100:200". + +)0 P()-1 LI( fundisp now outputs "0x" before hex values. + +)0 P()-1 LI( Fixed bug in filter parser which processed rangelists incorrectly +if spaces were put into the rangelist \201i.e. "pha= 1 : 3" instead of +pha=1:3\202. + +)0 P()-1 LI( Fixed a bug in funindex which created a wrongly named index file +if more than one "." was in the input file name. + +)0 P()-1 LI( Added support to funcone to take ra, dec, radius from a list +\201i.e. columns in a FITS file or a text file\202. + +)0 P()-1 LI( Fixed a bug in FunColumnActivate so that if some columns are +explicitly activated while others are de-activated, only the +explicitly activated columns are activated \201code was activating all +columns in this case\202. + +)0 P()-1 LI( Fixed a bug in funindex which prevented indexing tables containing +a column named N. + +)0 P()-1 LI( fundisp now encloses ASCII column values in single quotes \201unless +-T is specified to output RDB format\202. + +)0 P()-1 LI( If a filter specification only involves indexed columns, then the +compiled filter is not used. + +)0 P()-1 LI( Funmerge can now be given a list of files to merge using @list syntax. +Also removed the restriction on how many files can be merged \201was limited to +the max number of open files\202. + +)0 P()-1 LI( Added ability to edit \201add, delete, modify\202 header parameters in funhead +by specifying an output file \201editing acts as a filter\202 and an edit command +file \201which can be stdin\202. + +)0 P()-1 LI( Funtools now contains preliminary code to support \201fast\202 indexed access +of binary tables. See idx.html or "man funidx" for more details. + +)0 P()-1 LI( Funtools now contains preliminary code supporting access to ASCII +column files. See text.html or "man funtext" for more details. + +)0 P()-1 LI( Fixed bug in funcalc in which columns used in an expression were +always being replaced by new columns, with all associated parameters +\201e.g. WCS\202 were being deleted. Now this only happens if the column +explicitly changes its data type. + +)0 P()-1 LI( Fixed bug in funcalc in which the raw data and user data became out +of sync for one row after every 8192 \201FUN_MAXROW\202 rows. + +)0 P()-1 LI( Fixed bug in gio in which gseek returned 0 instead of the current byte +offset for disk files. + +)0 P()-1 LI( Added funcone program to perform cone search on RA, Dec columns in +a FITS binary table. + +)0 P()-1 LI( Fixed bug in polygon, pie and rotated box region filtering for +tables \201nearby rows exactly in line between two non-vertical or +non-horizontal vertices were being accepted incorrectly\202. + +)0 P()-1 LI( Fixed pie and panda regions so that the angles now start from +positive x axis == 0 degrees and run counter-clockwise, as +documented. They were going from positive y. NB: a similar change +was made to ds9 release 4.0b3. You must be using ds9 4.0b3 or later +in order to have the correct behavior when generating regions in ds9 +and using them in funtools. + +)0 P()-1 LI( Added -p [prog] switch to funcalc to save the generated program. +instead of executing \201and deleting\202 it. + +)0 P()-1 LI( Upgraded zlib to 1.2.3. +)LU( + +)0 2 161 H()WB 247 Sn( Patch Release 1.2.4 \201internal SAO and beta release only\202)EH( +)UL( +)0 P()-1 LI( In funcalc, added support for user-specified arguments via the +-a [argstr] switch. These arguments are accessed in the compiled program +using the supplied ARGC and ARGV\201n\202 macros. + +)0 P()-1 LI( Added -n \201no header display\202 to fundisp to skip outputting header. + +)0 P()-1 LI( Added checks for various types of blank filters. + +)0 P( +)-1 LI( Added macros NROW \201current row number\202 and WRITE_ROW \201write current +row to disk\202 to funcalc. + +)0 P()-1 LI( funcalc no longer requires that at least one data column be +specified in the compiled expression. + +)0 P()-1 LI( Added FUN_NROWS to FunInfoGet\201\202 to return the total number of rows in +an input table \201i.e. value of NAXIS2\202. + +)0 P( +)-1 LI( The compiled funcalc program now includes stdlib.h and unistd.h. + +)0 P()-1 LI( The util/NaN.h header file is now modified at configure time to +contain endian status for the target architecture. References to +specific platforms have been removed. + +)0 P()-1 LI( Added -m switch to funtable to output multiple files, one for +each input region \201and a separate file for events that pass the +filters but are not in any region\202. + +)0 P()-1 LI( Added ability to add new parameters \201FunParamPutx\202 after writing +data if space is previously reserved in the form of a blank parameter +whose value is the name of the param to be updated. \201Also requires the +append argument of FunParamPutx be set to 2\202. + +)0 P( +)-1 LI( Added ability to build shared libraries. With --enable-shared=yes, +shared library is built but not used. With --enable-shared=link, +shared library is linked against \201requires proper installation and/or +use of LD_LIBRARY_PATH\202. + +)0 P()-1 LI( Added -v [column] support to funcnts so that counts in a table +can be accumulated using values from a specified column \201instead of +the default case where an integral count is accumulated for each event +in a region\202. + +)0 P()-1 LI( Added funcen program to calculate centroids within regions +\201binary tables only\202. Also added support for a funcen-based centroid +tool to funtools.ds9. + +)0 P()-1 LI( Fixed bug which prevented successful filtering of columns containing +arrays. + +)0 P()-1 LI( Added filter check to ensure that a column is not incorrectly used +as an array. + +)0 P()-1 LI( Fundisp now displays column arrays indexed from 0, not 1. + +)0 P()-1 LI( Added -i [interval] support to funcnts so that multiple intervals +can be processed in a single pass through the data. For example, +specifying -i "pha=1:5;pha=6:10;pha=11:15" will generate results in +each of 3 pha bands. + +)0 P()-1 LI( Fixed calculation of LTV quantities when binning floating point +column data \201value was off by 0.5\202. + +)0 P()-1 LI( Added support for 'D' in floating point header values. + +)0 P()-1 LI( Added -a switch to funimage and funtable to append output image or +table to an existing FITS file \201as an IMAGE or BINTABLE extension\202. + +)0 P()-1 LI( Added support for column scaling \201TSCAL and TZERO\202 on input columns. +Note that the default column type is changed to accommodate scaling \201e.g. +a column of type 'I' is changed to 'J', 'J' is changed to 'D'\202 so that +the scaled values can be handled properly by programs such as fundisp +\201which utilize default types\202. + +)0 P( +)-1 LI( Added support to FunColumnSelect\201\202 for handling structs of arrays +\201i.e. where returned columns are contiguous\202 instead of the default array +of structs \201returned row are contiguous\202. This is done by specifying +"org=structofarrays" in the plist and passing a single struct containing +the arrays. + +)0 P()-1 LI( When writing an rdb/starbase file, fundisp now outputs the full +column name, regardless of the width of the column \201which ordinarily +is truncated to match\202. + +)0 P()-1 LI( Fixed support for large files by changing all file positions variables +from "long" declarations to "off_t. + +)0 P()-1 LI( Fixed bug in funcalc incorrectly processed multiple array +references \201e.g. cur->foo[0]=cur->x;cur->foo[1]=cur->y;\202 within a single +line of code. + +)0 P()-1 LI( Added FILTER_CFLAGS environment variable for all filtering. Also added +--with-filter-cc and --with-filter-cflags options on configure to allow +specification of a default C compiler and associated CFLAGS for filtering. +All of this is necessary in order to support 64-bit libraries under Solaris. + +)0 P()-1 LI( Added the funtbl script to extract a table from Funtools ASCII output. + +)0 P()-1 LI( Added code to funimage to update IRAF DATASEC keyword. + +)0 P()-1 LI( Added checks to ensure that image dimensions are positive. + +)0 P()-1 LI( Fixed a bug in funimage where int data was being scaled using BSCALE and +BZERO but these keywords also were being retained in the output image header. +Now the data are not scaled unless the output data type is float \201in which +case the scaling parameters are removed\202. + +)0 P()-1 LI( Fixed a bug in funmerge which prevented merging of files unless one of +the -f, -w, or -x switches were used. + +)0 P()-1 LI( Fixed a bug in funtable and fundisp which caused the special '$n' column +to be output incorrectly. + +)0 P()-1 LI( Fixed sort option in funtable, which previously worked only if the +record size was an even divisor of 8192 \201and returned garbage otherwise\202. + +)0 P()-1 LI( Fixed bug in filters involving FITS data type 'X' \201bitfield\202. + +)0 P()-1 LI( Fixed bug in funcnts in which the output angles and radii were +being displayed incorrectly when multiple panda shapes were specified. + +)0 P()-1 LI( Fixed bug in pandas and pies using n= syntax when first angle +specified was greater than second. The resulting mask was of +the correct shape but contained only a single region. + +)0 P()-1 LI( Table row access routines will now decrease maxrows if memory cannot be +allocated for maxrows*sizeof\201row\202, i.e. if the size of a row is so large that +space for maxrows cannot be allocated. + +)0 P()-1 LI( The FUN_MAXBUFSIZE environment variable was added to limit the +max buffer size that will be allocated to hold table row data. The +default is 5Mb. + +)0 P()-1 LI( Generated PostScript and PDF versions of the help pages. + +)0 P()-1 LI( Moved OPTIONS section before \201often-lengthy\202 DESCRIPTION section in +man pages. + +)0 P()-1 LI( All memory allocation now does error checking on the result +\201except wcs library, which is external code\202. + +)0 P()-1 LI( Removed some compiler warnings that surfaced when using gcc -O2. + +)0 P()-1 LI( Updated wcs library to 3.5.5. + +)0 P()-1 LI( Upgraded zlib to 1.2.1. +)LU( + +)0 2 162 H()WB 248 Sn( Patch Release 1.2.3 \20112 January 2004\202)EH( +)UL( +)0 P()-1 LI( Generated man pages from the html pages. These are installed +automatically at build time. + +)0 P()-1 LI( Changed instances of sprintf\201\202 to snprintf\201\202 to protect +against buffer overflow. + +)0 P()-1 LI( Fixed a number of compiler warnings in non-ANSI compilers. + +)0 P()-1 LI( Increased SZ_LINE parameter value from 1024 to 4096. +)LU( + +)0 2 163 H()WB 249 Sn( Patch Release 1.2.3b1 \20119 August 2003\202)EH( +)UL( +)0 P()-1 LI( The rule for using comma to separate a table filter expression +and a region expression has been changed. The rule now states: +)UL()-1 LI( if both expressions contain a region, the operator used is )BD(or)ES(. +)-1 LI( if one \201or both\202 expression\201s\202 does not contain a region, the operator +used is )BD(and)ES(.)LU( +This rule handles the cases of pure regions and pure column filters properly. +It unambiguously assigns the boolean )BD(and)ES( to all mixed cases. Thus: +) 1 34 PR( foo.fits[circle\20110,10,3\202,pi=1:5])RP( +and +) 1 34 PR( foo.fits[pi=1:5,circle\20110,10,3\202])RP( +both are equivalent to: +) 1 37 PR( foo.fits[circle\20110,10,3\202 && pi=1:5])RP( + +)0 P()-1 LI( When include files are used in filters, they now have implied +parentheses surrounding them. Thus, if a region file foo.reg contains two +regions \201e.g. circle 1 2 3 and circle 4 5 6\202, the syntax: +) 1 21 PR( pha=4:5&&@foo.reg)RP( +is equivalent to: +) 1 42 PR( pha=4:5 && \201circle 1 2 3 || cir 4 5 6\202)RP( +instead of: +) 1 40 PR( pha=4:5 && circle 1 2 3 || cir 4 5 6)RP( +and the pha filter is applied to both regions. + +)0 P()-1 LI( Filters and comments now can be terminated with the string +literal "\200n" as well as ";" and the new-line character. This means +that a region can have comments embedded in it: +) 1 72 PR( funcnts foo.fits "circle 512 512 10 # color=red\200n circle 512 512 20")RP( + +)0 P()-1 LI( Added capability to update the value of an existing parameter +after writing the table or image \201assuming the output image is a +disk file or is being redirected into a file\202. + +)0 P()-1 LI( Improved handling of parentheses in filter expressions. + +)0 P( +)-1 LI( Fixed a bug in image \201not event\202 regions in which circles and +annuli with radius of 1 pixel were not being processed. No counts and +no area would be found in such regions. + +)0 P()-1 LI( Fixed a bug in funcnts in which the radii column values for out of sync +if multiple annuli were specified \201instead of a single varargs or accel +annulus\202. + +)0 P()-1 LI( By default, fundisp will display integer image data as floats +if the BSCALE and BZERO header parameters are present. + +)0 P()-1 LI( Added -L switch to funhead to output starbase list format. + +)0 P()-1 LI( Changed the name of the routine _FunColumnSelect to +FunColumnSelectArr, in order to emphasize that it is not +a private routine. + +)0 P()-1 LI( Funcalc now checks to ensure that a column was specified as part of +the expression. + +)0 P()-1 LI( Funcalc local variables in the compiled program now use a "__" prefix +to avoid conflicts with user-defined variables. + +)0 P()-1 LI( Unofficial unsigned short \201bitpix=-16\202 image data now is scaled +correctly using BSCALE and BZERO header parameters. + +)0 P()-1 LI( Ported to Intel icc and gcc 3.3 compilers. + +)0 P()-1 LI( Updated wcs library to 3.5.1. + +)0 P()-1 LI( Changed license from public domain to GNU GPL. +)LU( + +)0 2 164 H()WB 250 Sn( Patch Release 1.2.2 \20118 May 2003\202)EH( +)UL( +)0 P( +)-1 LI( Fixed funcalc so that it now actually compiles an expression and +runs it, instead of getting a "filter compilation error". Oops! + +)0 P()-1 LI( Fixed bug in FunOpen in which the bracket specification was being +removed from the filename if a disk file was opened for "w" or "a". + +)0 P()-1 LI( Fixed bug in FunFlush which prevented two successive calls to +FunImagePut from writing the second extension header properly. + +)0 P()-1 LI( All filter routines now use gerror\201stderr, ...\202 call instead of +fprintf\201stderr, ...\202 so that output to stderr can be turned off \201via +setgerror\201level\202 or GERROR environment variable\202. + +)0 P()-1 LI( All standard Funtools programs check for GERROR environment +variable before setting gerror flag. + +)0 P()-1 LI( Some error messages about invalid region arguments were not being +printed. + +)0 P()-1 LI( FITS parameters/headers now conform more closely to FITS standard: +)UL()-1 LI( Blank keywords are treated in the same way as COMMENTS and HISTORY cards +)-1 LI( XTENSION keywords are now exactly 8 characters long +)-1 LI( 'E' is output instead of 'e' in floating point param values +)-1 LI( PCOUNT and GCOUNT are output correctly for image extensions +)-1 LI( EXTEND=T is output in primary header +)-1 LI( COMMENTS and HISTORY start in column 9)LU( +)LU( + +)0 2 165 H()WB 251 Sn( Patch Release 1.2.1 \20124 April 2003\202)EH( +)UL( +)0 P()-1 LI( Varargs ellipse and box annular regions were being +processed incorrectly when the following conditions all were met: +)UL()-1 LI( the region was specified in physical or wcs coordinates +)-1 LI( the data file contained LTM/LTV keywords, i.e., it +was blocked with respect to the original data file +)-1 LI( the program being run was an image program \201e.g. funcnts, funimage\202)LU( +Varargs ellipse and boxes are regions of the form: +) 2 43 PR( ellipse x y a1 b1 a2 b2 ... an bn [angle] + box x y l1 w1 l2 w2 ... ln wn [angle])RP( +where at least 2 sets of axis \201length\202 values were specified to form +an annulus \201i.e. simple ellipses and boxes worked properly\202. With all +of the above conditions met, a region in physical coordinates saw its +second length argument converted incorrectly from physical coordinates +to image coordinates. In simple terms, this means that funcnts did not +process elliptical or box regions in physical coords on blocked images +properly. Note that blocking on the command line \201e.g. foo.fits[*,*,2]\202 +did work when no LTM/LTV keywords existed in the file. + +)0 P()-1 LI( The fundisp -f switch now supports specification of +column-specific display formats as well as a more convenient way to +specify datatype-specific display formats. Both use keyword=value +specifiers. For columns, use: +) 1 58 PR( fundisp -f "colname1=format1 colname2=format2 ..." ...)RP( +e.g. +) 1 40 PR( fundisp -f "time=%13.2f pha=%3d" ...)RP( +You also can specify display formats for individual datatypes using the FITS +binary table TFORM variables as the keywords: +) 1 65 PR( fundisp -f "D=double_format E=float_format J=int_format etc.")RP( +e.g. +) 1 35 PR( fundisp -f "D=%13.2f I=%3d" ...)RP( +The old position-dependent syntax is deprecated. + +)0 P()-1 LI( Fundisp will now print out a single 16-bit \201or 32-bit\202 unsigned +int for a column whose data format is 16X \201or 32X\202, instead of +printing 2 \201or 4\202 unsigned chars. + +)0 P()-1 LI( Fixed bug in which fundisp was not able to display bitfield data for +raw event lists. + +)0 P()-1 LI( Previously, when binning columns used implicitly in a region +and explicitly in a filter could suffer from a case sensitivity problem. +This has been fixed. + +)0 P()-1 LI( Fixed internal mask=all switch on fundisp. + +)0 P()-1 LI( Filter include files now simply include text without changing the state +of the filter. They therefore can be used in expression. That is, if foo1 +contains "pi==1" and foo2 contains "pha==2" then the following expressions +are equivalent: +) 3 57 PR( "[@foo1&&@foo2]" is equivalent to "[pi==1&&pha==2]" + "[pha==1||@foo2]" is equivalent to "[pi==1||pha==2]" + "[@foo1,@foo2]" is equivalent to "[pi==1,pha==2]")RP( + +)0 P()-1 LI( Fixed bug in filter specification which caused a SEGV if a varargs-style +region was enclosed in parens. + +)0 P()-1 LI( Updated wcs library to 3.3.2. +)LU( + +)0 2 166 H()WB 252 Sn( Public Release 1.2.0 \20124 March 2003\202)EH( +)UL( +)0 P()-1 LI( BSCALE and BZERO are now always applied to int pixel data, instead of +only being applied if the desired output is floating point. +)LU( + +)0 2 167 H()WB 253 Sn( Beta Release 1.2.b3 \2014 February 2003\202)EH( +)UL( +)0 P()-1 LI( In FunColumnSelect, added the ability to specify an offset into +an array in the type specification, using the extended syntax: +) 1 48 PR( [@][n][[poff]][:[tlmin[:tlmax[:binsiz]]]])RP( +The [poff] string specifies the offset. For example, a type specification +such as "@I[2]" specifies the third \201i.e., starting from 0\202 element in +the array pointed to by the pointer value. A value of "@2I[4]" specifies +the fifth and sixth values in the array. + +)0 P()-1 LI( Added a non-varargs version of FunColumnSelect called _FunColumnSelect: +) 3 76 PR(int _FunColumnSelect\201Fun fun, int size, char *plist, + char **names, char **types, char **modes, int *offsets, + int nargs\202;)RP( + +)0 P()-1 LI( Added support for sorting binary tables by column name using: +funtable -s "col1 col2 ... coln" ... + +)0 P()-1 LI( Added the FUN_RAW macro which, when applied to the "name" parameter +of FunParamGets\201\202, returns the 80-character raw FITS card instead of +only the value. + +)0 P()-1 LI( Added support for comparing column values with binary masks of the +form 0b[01]+, e.g.: +) 1 23 PR( \201status&0b111\202==0b001)RP( +Previously, such masks had to be specified in decimal, octal, or hex. + +)0 P()-1 LI( Completed support for type 'L' \201logical\202 in fundisp and in filtering of +binary tables. + +)0 P()-1 LI( Fixed bug in funhist that was improperly setting the number of bins +when the data was of type float. + +)0 P()-1 LI( Fixed bug in filter/Makefile where the filter OBJPATH #define was +being passed to the wrong module. +)LU( + +)0 2 168 H()WB 254 Sn( Beta Release 1.2.b2 \2017 October 2002\202)EH( +)UL( +)0 P()-1 LI( Updated wcs library to 3.1.3. + +)0 P()-1 LI( Added support for reading gzip'ed files via stdin. +)LU( + +)0 2 169 H()WB 255 Sn( Beta Release 1.2.b1 \20124 September 2002\202)EH( +)UL( +)0 P()-1 LI( Added the following accelerators to region filtering: +) 8 73 PR( shape: arguments: + ----- --------- + BOX xcenter ycenter xw1 yh1 xw2 yh2 ... xwn yhn \201angle\202 + BOX xcenter ycenter xwlo yhin xwout yhhi n=[number] \201angle\202 + CIRCLE xcenter ycenter r1 r2 ... rn # same as annulus + CIRCLE xcenter ycenter rinner router n=[number] # same as annulus + ELLIPSE xcenter ycenter xw1 yh1 xw2 yh2 ... xwn yhn \201angle\202 + ELLIPSE xcenter ycenter xwlo yhin xwout yhhi n=[number] \201angle\202)RP( + +)0 P()-1 LI( Added the following new pandas \201Pie AND Annulus\202 to region filtering: +) 5 77 PR( shape: arguments: + ----- --------- + CPANDA xcen ycen ang1 ang2 nang irad orad nrad # same as panda + BPANDA xcen ycen ang1 ang2 nang ixlo iylo ixhi iyhi nrad \201ang\202 # box + EPANDA xcen ycen ang1 ang2 nang ixlo iylo ixhi iyhi nrad \201ang\202 # ellipse)RP( + +)0 P()-1 LI( Added support for filtering images using simple FITS image masks, +i.e. 8-bit or 16-bit FITS images where the value of a pixel is the +region id number for that pixel \201and therefore must be greater than +0\202. The image section being filtered must either be the same size as the +mask dimensions or else be an even multiple of the mask. This works with +image-style filtering, i.e., funcnts can utilize a mask on both +images and binary tables. + +)0 P()-1 LI( Added '$n' to fundisp column specification to allow display of +ordinal value of each row passing the filter. + +)0 P()-1 LI( Added code to support region filtering on image sections. + +)0 P()-1 LI( Fixed bugs which prevented filtering more than one ASCII region file. + +)0 P()-1 LI( Fixed bug occasionally causing filter slave processes to become zombies. + +)0 P()-1 LI( Fixed bugs in event filtering: annulus with inner radius of 0 +\201i.e., a circle\202 was rejecting events with coordinates xcen, ycen. +Also, pie with angles of 0 and 360 was rejecting some events. +Image filtering \201e.g. funcnts\202 did not have these problems. + +)0 P()-1 LI( Filters now accept global exclude regions without an include region. +In such a case, the field region is implied. That is, "-circle\201x,y,r\202" +is equivalent to "field; -circle\201x,y,r\202", etc. + +)0 P()-1 LI( Fixed panda so that it can be used as a global exclude. + +)0 P()-1 LI( Allow empty ds9 region file \201comments and globals only\202 to be +a valid filter. Totally ignore zero length region or include file. + +)0 P( +)-1 LI( Fixed funcnts bug that was displaying 0 value as inner radius of +a circle, instead of just one radius value. +)LU( + +)0 2 170 H()WB 256 Sn( Public Release 1.1.0 \20122 April 2002\202)EH( + +)0 P(New features include: +)UL()0 P()-1 LI( Funtools programs now accept gzip'ed files as valid input. + +)0 P()-1 LI( Improved security via replacement of system\201\202 function. + +)0 P()-1 LI( fundisp, funcnts, funhist can output starbase/rdb format \201tabs between columns, form-feeds between tables\202. + +)0 P()-1 LI( Improved support for Windows platform, as well as new support for Mac OSX.)LU( + +)0 2 171 H()WB 257 Sn( Pre-Release 1.1.0e \20110 April 2002\202)EH( +)UL( + +)0 P()-1 LI( Added enough support to skip over variable length arrays in BINTABLES. +We will add full support if this non-standard construct becomes more widely +used. + +)0 P()-1 LI( Fixed bug in underlying fitsy _gread\201\202 routine that was returning +an arbitrary bytes-read value if the input fd was invalid. +)LU( + +)0 2 172 H()WB 258 Sn( Pre-Release 1.1.0e \20119 March 2002\202)EH( +)UL( + +)0 P()-1 LI( Added additional check for Windows/PC to filter/Nan.h. + +)0 P()-1 LI( Upgraded zlib library to 1.1.4 \201fix double free security hole\202. +)LU( + + +)0 2 173 H()WB 259 Sn( Pre-Release 1.1.0e \20127 February 2002\202)EH( +)UL( + +)0 P()-1 LI( Changed filter/process.[ch] to filter/zprocess.[ch] to avoid name +collision with Cygwin include file. + +)0 P()-1 LI( Added -a switch to funhead to display all headers in a FITS file. +)LU( + +)0 2 174 H()WB 260 Sn( Pre-Release 1.1.0e \20111 February 2002\202)EH( +)UL( + +)0 P()-1 LI( Fixed filter parser so that it ignores ds9 "ruler" and "text" markers +only up to the first \200n or ; \201was ignoring to last \200n\202. + +)0 P()-1 LI( The NBLOCK parameter in fitsy/headdata.c was too large for Mac OS X +\201max size of a declared char buf seems to be about .5 Mb\202. +)LU( + +)0 2 175 H()WB 261 Sn( Beta Release 1.0.1b5 \20131 January 2002\202)EH( +)UL( + +)0 P()-1 LI( Fixed bug introduced in calculated IRAF LTM values in 1.0.1b3. + +)0 P()-1 LI( Fixed bug in filter parser giving wrong answers when two range +lists were combined with and explicit boolean operator: +) 1 34 PR( $ fundisp $S"[x=512&&y=511,512]")RP( +incorrectly acted like: +) 1 39 PR( fundisp $S"[\201x=512&&y=511\202||\201y=512\202]")RP( +instead of: +) 1 37 PR( fundisp $S"[x=512&&\201y=511||y=512\202]")RP( +In general, we recommend use of explicit parentheses. + +)0 P()-1 LI( Fixed filter/NaN.h to recognize Compaq Alpha again \201broken by their last change to cc\202. + +)0 P()-1 LI( Removed redundant varargs definitions that conflicted with Alpha compiler definitions. + +)0 P()-1 LI( Added blank line to inc.sed to work around Apple Mac OS X bug in which the +"i" \201insert\202 command was treating final \200\200 as continuation \200 in the text. + +)0 P( +)-1 LI( Added include of mkrtemp.h to mkrtemp.c to get conditional compilation +for Mac OSX. + +)0 P()-1 LI( Added support for --with-zlib to fitsy so that ds9 could use its own +copy of zlib \201and not build the copy in fitsy\202. + +)0 P()-1 LI( Removed config.cache and Makefile files from distribution tar file. +)LU( + +)0 2 176 H()WB 262 Sn( Beta Release 1.0.1b4 \20126 January 2002\202)EH( +)UL( + +)0 P()-1 LI( Make explicit that column filters are not permitted in an image +expression \201such as the funcnts region arguments\202. + +)0 P()-1 LI( Fix bug in region parser in which a region \201without parens\202, +followed immediately by an operator: +) 1 24 PR( circle 512 512 .5&)SY(\160)ES(==1)RP( +was not processing the final argument of the region correctly. + +)0 P()-1 LI( Ignore new "tile" directive in filters \201used by ds9\202. +)LU( + +)0 2 177 H()WB 263 Sn( Beta Release 1.0.1b3 \2014 January 2002\202)EH( +)UL( + +)0 P()-1 LI( Made modifications to Makefile.in to make releases easier. + +)0 P()-1 LI( Added instructions Makefile.in so that funtools.h will always +have correct #defines for FUN_VERSION, FUN_MAJOR_VERSION, +FUN_MINOR_VERSION, and FUN_PATCH_LEVEL. + +)0 P()-1 LI( Allow #include statements in funcalc program files. + +)0 P()-1 LI( funimage now updates all 4 CDX_Y values by the block factor. + +)0 P()-1 LI( Minor changes to make funtools work under darwin \201Mac OS X\202. +)LU( + +)0 2 178 H()WB 264 Sn( Beta Release 1.0.1b2 \20114 November 2001\202)EH( +)UL( + +)0 P()-1 LI( Fixed FunOpen\201\202 bug \201introduced in b1\202 in which filenames without +extensions SEGV'ed on open. Yikes! + +)0 P()-1 LI( Funmerge now extends the tlmin/tlmax values of the output +binning columns so that merged events from widely separated files are +valid in the output table. + +)0 P()-1 LI( In funhist, added -w switch to specify bin width \201lo:hi:width\202 +instead of number of bins \201lo:hi:num\202. Added support for this new +width option in funtools.ds9. + +)0 P()-1 LI( If a tdbin value was set using bincols=\201name:tlmin:tlmax:tdbin, ...\202, +the WCS parameters were not being updated properly. + +)0 P()-1 LI( Cleaned up build support for zlib. +)LU( + +)0 2 179 H()WB 265 Sn( Beta Release 1.0.1b1 \2016 November 2001\202)EH( +)UL( + +)0 P()-1 LI( Added support for gzip'ed files to the underlying fitsy/gio +library. This means that all funtools programs now accept gzip'ed +files as valid input: +) 1 41 PR( funcnts foo.fits.gz "circle 504 512 10")RP( +It is no longer necessary to run gunzip and pipe the results to +stdin of a funtools program. + +)0 P()-1 LI( Funtools tasks are now placed in a sub-menu in the DS9 Analysis +menu, instead of at the top level. + +)0 P()-1 LI( Fixed a bug in funcnts in which the bottom-most pixel of a small +circle or annulus region could be missed when the region is only one +pixel wide for that value of y. + +)0 P()-1 LI( Added -n switch to funhist so that table histograms could be +normalized by the width of the bin \201val/\201hi_edge-lo_edge\202\202. + +)0 P()-1 LI( Added -T switch to fundisp, funcnts, funhist to output in +starbase/rdb format \201uses tabs instead of spaces between columns, +form-feeds between tables, etc.\202 + +)0 P()-1 LI( Fixed a bug in which the field\201\202 region was not being properly +processed in combination with an image section. This could affect +funcnts processing of image data where an image section was specified +\201though it usually resulted in a funcnts error\202. + +)0 P()-1 LI( Fixed bug in display of binary table header for vector columns. + +)0 P()-1 LI( Filters now recognize hex constants \201starting with 0x\202 and long +constants \201ending with L\202. + +)0 P()-1 LI(Filenames containing a ':' are now only treated as sockets if they +actually are in the form of a valid ip:port. + +)0 P()-1 LI(Replaced funtools.ds9 with a new version that calls a new funds9 +script, instead of calling funcnts or funhist directly. The new script +supports gzip'ed files and bracket specifications on filenames at the +same time, which the direct call could not. Also the new script has +better error reporting. + +)0 P()-1 LI( Replaced system\201\202 call used to compile filter and funcalc +expression with a special launch\201\202 call, which performs execvp\201\202 +directly without going through sh. \201launch\201\202 works under DOS and has +fewer security problems.\202 + +)0 P()-1 LI( Fixed image filter code in which the field\201\202 region was being ignored +if it was combined with one or more exclude regions \201and no other include +regions\202, resulting in no valid pixels. + +)0 P()-1 LI( Changed use of getdtable\201\202 to FD_SETSIZE in calls to select\201\202. + +)0 P()-1 LI( Added code to guard against FITS binary tables without proper TFORMx +parameters. + +)0 P()-1 LI( Added support to FunParamGets so that it returns the raw FITS card +if the specified input name is NULL and the input n value is positive. + +)0 P()-1 LI( Fixed bug in underlying fitsy code that set the comment in a +header parameter. +)LU( + + +)0 2 180 H()WB 266 Sn( Public Release 1.0.0 \20131 July 2001\202)EH( +)UL( +)0 P()-1 LI( "a new day with no mistakes ... yet")LU( + +)2 1 1 HR()0 0 1 A(Index to the Funtools Help Pages)0 0 TN TL()Ec /AF f D( +)0 5 181 H(Last)WB 267 Sn( updated: 22 April 2002)EH( +)WB NL +/TE t D NP TU PM 0 eq and{/Pn () D showpage}if end restore diff --git a/doc/help.html b/doc/help.html new file mode 100644 index 0000000..e32f9bf --- /dev/null +++ b/doc/help.html @@ -0,0 +1,192 @@ + + + +The Funtools Help Facility + + + + +

Funtools: FITS Users Need Tools

+ + +

Summary

+This document is the Table of Contents for Funtools. + + +

Description

+Funtools, is a "minimal buy-in" FITS library and utility package developed +at the the High Energy Astrophysics Division of SAO. The Funtools +library provides simplified access to a wide array of file types: +standard astronomical FITS images and binary tables, raw arrays and +binary event lists, and even tables of ASCII column data. A +sophisticated region filtering library (compatible with ds9) filters +images and tables using boolean operations between geometric shapes, +support world coordinates, etc. Funtools also supports advanced +capabilities such as optimized data searching using index files. + +The main goal of the Funtools project has been to develop a minimal buy-in +FITS library for researchers who are occasional (but serious) coders. In +this case, "minimal buy-in" means "easy to learn, easy to use, and easy to +re-learn next month". We have tried to achieve this goal by emphasizing two +essential capabilities. The first is the ability to develop FITS programs +without knowing much about FITS, i.e., without having to deal with the +arcane rules for generating a properly formatted FITS file. The second is +to support the use of already-familiar C/Unix facilities, especially C +structs and Unix stdio. Taken together, these two capabilities should allow +researchers to leverage their existing programming expertise while +minimizing the need to learn new and complex coding rules. + + +

+Choose from the following topics: + +

+

+ + + +
Last updated: January 6, 2006
+ + + + diff --git a/doc/html2man b/doc/html2man new file mode 100755 index 0000000..4e60799 --- /dev/null +++ b/doc/html2man @@ -0,0 +1,258 @@ +#!/usr/bin/perl +# +# See COPYRIGHT +# +# Script to generate a pod file from an html source (the same one as for text files too) +# and later this pod file it passed through pod2man +# +# Use: +# html2man [ [] ] is the directory where the man pages will be created +# (current directory by default). If a file name is given instead of +# directory then the directory of that file is used. +# is the directory containing the ttf2pt1 files version.h +# and CHANGES.html which are used to generate the release name and date +# for the man page (by default looks in current directory and then in up to +# 5 ancestor directories). +# If the version files can not be found then the release defaults to +# "current" and the date defaults to today. +# +# Special formatting in the html file is: +# All controls are hidden within HTML comments that must occupy a whole separate line +# Such a line looks like: +# +# +# Any sort of directive must be followed by a space. The pod directives are +# automatically surrounded by empty lines in the output file. +# The html2man directives are: +# +# +# Define a man page. Multiple man pages can be defined in the same HTML +# file. is a short name by which this man page will be referred in the +# other directives. is the name of the man page, and
is the +# section of the manual (do not confuse with sections within a man page). +# +# +# All the text following this directive is copied (with translation) +# into the specified section of the specified man page. The sections +# may appear in arbitrary order, they will be rearranged to the standard +# order before output. Only standard section names are permitted (see @stdsect +# below). The pod directives which occur outside of man sections are ignored, +# just like the common text. The translation of HTML tags is: +# +#
- to paragraph break +# - to B<> +# - to I<> +# - to C<> +# - to F<> +#
    ,
  • ,
- to =over 2, =item *, =back +#  , &, <, > - to their symbols, appropriately encoded +# +# The rest of HTML tags is removed +# +# If the same section is started more than once, the text from the +# second appearance will be added to the first, etc. +# +# +# Stop copying text to the man page. +# +# +# Continue copying text to the man page, same section as before. +# +# +# Insert this into the man page (works only when copying is enabled). +# Characters <, >, & are converted as usual. + +@mons = qw(January February March April May June July August September October November December); + +$dir = $ARGV[0]; +$maindir = $ARGV[1]; + +if($dir eq "") { + $dir = "."; +} elsif( ! -d $dir ) { + if( ! ($dir =~ s|\/[^/]*$||) ) { + $dir = "."; + } +} +if($maindir eq "") { + $maindir = "."; + for($i=0; $i<5; $i++) { + if(-f "$maindir/version.h") { + last; + } + $maindir = "../$maindir"; + } +} + +if( open(VERFILE, "<$maindir/version.h") ) { + while() { + if( /^\s*\#define\s+TTF2PT1_VERSION\s+\"(.*)\"/ ) { + $release = "version $1"; + } + } + close(VERFILE); + if( $release =~ /SNAP-([0-9][0-9])([0-9][0-9])([0-9][0-9])/ ) { + $date = sprintf("%s %d, 20%02d", $mons[$2-1], $3, $1); + } elsif( open(CFILE, "<$maindir/CHANGES.html") ) { + while() { + if( /\/) { + last; + } + } + $_ = ; + chomp; + if( $_ =~ s/^.*?-- // ) { + $date = $_; + } + close(CFILE); + } +} + +if($release eq "") { + if( open(VERFILE, "<../Makefile") ) { + while() { + if( /^VERSION\s+=\s+(.*)/ ) { + $release = "version $1"; + } + } + close(VERFILE); + } +} + +if($release eq "") { + $release = "current"; +} +if($date eq "") { + @lt = localtime(time); + $date = sprintf("%s %d, %d", $mons[$lt[4]], $lt[3], 1900+$lt[5]); +} + +#printf(STDERR "date=%s release=%s\n", $date, $release); + +$writemode = 0; + +while() { + if( s/^\<\!\-\- \=(\S+)\s+//) { + $cmd = $1; + s/\s*\-\-\>\s*$//; + #printf(STDERR "cmd=%s args=%s\n", $cmd, $_); + if($cmd =~ /^=/) { + if($writemode) { + $text{$tosect} .= "\n\n$cmd $_\n\n"; + } + } elsif($cmd eq "defdoc") { + @sl = split; + push(@allids, $sl[0]); + $file{$sl[0]} = $sl[1]; + $mansect{$sl[0]} = $sl[2]; + } elsif($cmd eq "section") { + # tosect includes the file id + $tosect = $_; + $text{$tosect} .= "\n\n"; + $writemode = 1; + } elsif($cmd eq "stop") { + $writemode = 0; + $text{$tosect} .= "\n"; + } elsif($cmd eq "cont") { + $writemode = 1; + } elsif($cmd eq "text") { + if($writemode) { + s/\<\;//gi; + s/\&\;/\&/gi; + $text{$tosect} .= "$_\n"; + } + } + } elsif($writemode) { +# s/^\s+//; + + s/\{/\&lbr;/g; + s/\}/\&rbr;/g; + + s/\/\n\n/gi; + #s/\/\n\n=over 4\n\n/gi; + #s/\<\/blockquote\>/\n\n=back\n\n/gi; + s/\/\n\n=over 4\n\n/gi; + s/\<\/ul\>/\n\n=back\n\n/gi; + s/\\s*/\n\n=item \*\n\n/gi; + + s/\/\n\n=over 4\n\n/gi; + s/\<\/dl\>/\n\n=back\n\n/gi; + s/\\s*/\n\n=item \*\n\n/gi; + s/\\s*/\n\n/gi; + + s/\(.*?)\<\/i\>/I\{\1\}/gi; + s/\(.*?)\<\/em\>/I\{\1\}/gi; + s/\(.*?)\<\/b\>/B\{\1\}/gi; + s/\(.*?)\<\/tt\>/C\{\1\}/gi; + s/\
(.*?)\<\/a\>/F\{\1\}/gi; + s/\summary\<\/h2\>//gi; + s/\description\<\/h2\>//gi; + s/\examples\<\/h2\>//gi; + s/\options\<\/h2\>//gi; + s/\(.*?)\<\/h2\>/B\{\1\}/gi; + s/\<.*?\>//g; + s/\{/\/g; + + s/\ \;/S< >/gi; + s/\&\;/\&/gi; +# s/\<\;/E/gi; +# s/\>\;/E/gi; + s/\<\;/\/gi; + #s/\|/E/g; + #s/\//E/g; + s/\&lbr\;/\{/g; + s/\&rbr\;/\}/g; + + #printf(STDERR "section=%s add=%s", $tosect, $_); + $text{$tosect} .= $_; + } +} + +@stdsect = ( + "NAME", + "SYNOPSIS", + "OPTIONS", + "DESCRIPTION", + "RETURN VALUE", + "ERRORS", + "EXAMPLES", + "ENVIRONMENT", + "FILES", + "SEE ALSO", + "NOTES", + "CAVEATS", + "DIAGNOSTICS", + "BUGS", + "RESTRICTIONS", + "AUTHOR", + "HISTORY" ); + +#printf(STDERR "allids= @allids\n"); +for $id (@allids) { + print(STDERR "creating man page $id $file{$id} $mansect{$id}\n\n"); + die "Unable to create pod file $dir/$file{$id}.pod" + unless open(PODF, ">./pod/$file{$id}.pod"); + print(PODF "=pod\n\n"); + for $sect (@stdsect) { + $sid = "$id $sect"; + #printf(STDERR "trying %s\n", $sid); + if(defined $text{$sid}) { + #printf(STDERR " section %s\n", $sid); + print(PODF "=head1 $sect\n\n$text{$sid}\n\n"); + } + } + print(PODF "=cut\n"); + close(PODF); + die "Unable to generate the man page $dir/$file{$id}.1" + if system("pod2man --section=\"$mansect{$id}\" --release=\"$release\" " + . "--center=\"SAORD Documentation\" --date=\"$date\" " + . "--name=\"$file{$id}\" " + . "./pod/$file{$id}.pod > $dir/man$mansect{$id}/$file{$id}.$mansect{$id}"); + + unlink("$dir/$file{$id}.pod"); +} diff --git a/doc/idx.html b/doc/idx.html new file mode 100644 index 0000000..a08b10b --- /dev/null +++ b/doc/idx.html @@ -0,0 +1,216 @@ + + + +Table Filtering with Indexes + + + + +

Funidx: Using Indexes to Filter Rows in a Table

+ + +

Summary

+

+This document contains a summary of the user interface for +filtering rows in binary tables with indexes. + + +

Description

+

+Funtools Table Filtering allows rows in a +table to be selected based on the values of one or more columns in the +row. Because the actual filter code is compiled on the fly, it is very +efficient. However, for very large files (hundreds of Mb or larger), +evaluating the filter expression on each row can take a long time. Therefore, +funtools supports index files for columns, which are used automatically during +filtering to reduce dramatically the number of row evaluations performed. +The speed increase for indexed filtering can be an order of magnitude or +more, depending on the size of the file. + +

+The funindex program creates an +index on one or more columns in a binary table. For example, to create an index +for the column pi in the file huge.fits, use: +

+  funindex huge.fits pi
+
+This will create an index named huge_pi.idx. + +

+When a filter expression is initialized for row evaluation, funtools +looks for an index file for each column in the filter expression. If +found, and if the file modification date of the index file is later +than that of the data file, then the index will be used to reduce the +number of rows that are evaluated in the filter. When +Spatial Region Filtering is part of the +expression, the columns associated with the region are checked for index +files. + +

+If an index file is not available for a given column, then in general, +all rows must be checked when that column is part of a filter +expression. This is not true, however, when a non-indexed column is +part of an AND expression. In this case, only the rows that pass the +other part of the AND expression need to be checked. Thus, in some cases, +filtering speed can increase significantly even if all columns are not +indexed. + +

+Also note that certain types of filter expression syntax cannot make +use of indices. For example, calling functions with column names as +arguments implies that all rows must be checked against the function +value. Once again, however, if this function is part of an AND +expression, then a significant improvement in speed still is possible +if the other part of the AND expression is indexed. + +

+For example, note below the dramatic speedup in searching a 1 Gb +file using an AND filter, even when one of the columns (pha) has no +index: + +

+  time fundisp \
+  huge.fits'[idx_activate=0,idx_debug=1,pha=2348&&cir 4000 4000 1]' \
+  "x y pha"
+          x           y        pha                                   
+ ---------- ----------- ----------                                    
+    3999.48     4000.47       2348
+    3999.48     4000.47       2348
+    3999.48     4000.47       2348
+    3999.48     4000.47       2348
+    3999.48     4000.47       2348
+    3999.48     4000.47       2348
+    3999.48     4000.47       2348
+    3999.48     4000.47       2348
+    3999.48     4000.47       2348
+    3999.48     4000.47       2348
+    3999.48     4000.47       2348
+    3999.48     4000.47       2348
+    3999.48     4000.47       2348
+    3999.48     4000.47       2348
+    3999.48     4000.47       2348
+    3999.48     4000.47       2348
+    42.36u 13.07s 6:42.89 13.7%
+
+  time fundisp \
+  huge.fits'[idx_activate=1,idx_debug=1,pha=2348&&cir 4000 4000 1]' \
+  "x y pha"
+          x           y        pha                                    
+ ---------- ----------- ----------                                    
+ idxeq: [INDEF]                                   
+ idxand sort: x[ROW 8037025:8070128] y[ROW 5757665:5792352]             
+ idxand(1): INDEF [IDX_OR_SORT]                                   
+ idxall(1): [IDX_OR_SORT]                                   
+    3999.48     4000.47       2348
+    3999.48     4000.47       2348
+    3999.48     4000.47       2348
+    3999.48     4000.47       2348
+    3999.48     4000.47       2348
+    3999.48     4000.47       2348
+    3999.48     4000.47       2348
+    3999.48     4000.47       2348
+    3999.48     4000.47       2348
+    3999.48     4000.47       2348
+    3999.48     4000.47       2348
+    3999.48     4000.47       2348
+    3999.48     4000.47       2348
+    3999.48     4000.47       2348
+    3999.48     4000.47       2348
+    3999.48     4000.47       2348
+    1.55u 0.37s 1:19.80 2.4%
+
+ +When all columns are indexed, the increase in speed can be even more dramatic: +
+  time fundisp \
+  huge.fits'[idx_activate=0,idx_debug=1,pi=770&&cir 4000 4000 1]' \
+  "x y pi"
+          x           y         pi                                    
+ ---------- ----------- ----------                                    
+    3999.48     4000.47        770
+    3999.48     4000.47        770
+    3999.48     4000.47        770
+    3999.48     4000.47        770
+    3999.48     4000.47        770
+    3999.48     4000.47        770
+    3999.48     4000.47        770
+    3999.48     4000.47        770
+    3999.48     4000.47        770
+    3999.48     4000.47        770
+    3999.48     4000.47        770
+    3999.48     4000.47        770
+    3999.48     4000.47        770
+    3999.48     4000.47        770
+    3999.48     4000.47        770
+    3999.48     4000.47        770
+    42.60u 12.63s 7:28.63 12.3%
+
+  time fundisp \
+  huge.fits'[idx_activate=1,idx_debug=1,pi=770&&cir 4000 4000 1]' \
+  "x y pi"
+          x           y         pi                                    
+ ---------- ----------- ----------                                    
+ idxeq: pi start=9473025,stop=9492240 => pi[ROW 9473025:9492240]          
+ idxand sort: x[ROW 8037025:8070128] y[ROW 5757665:5792352]               
+ idxor sort/merge: pi[ROW 9473025:9492240] [IDX_OR_SORT]                   
+ idxmerge(5): [IDX_OR_SORT] pi[ROW]                                   
+ idxall(1): [IDX_OR_SORT]                                   
+    3999.48     4000.47        770
+    3999.48     4000.47        770
+    3999.48     4000.47        770
+    3999.48     4000.47        770
+    3999.48     4000.47        770
+    3999.48     4000.47        770
+    3999.48     4000.47        770
+    3999.48     4000.47        770
+    3999.48     4000.47        770
+    3999.48     4000.47        770
+    3999.48     4000.47        770
+    3999.48     4000.47        770
+    3999.48     4000.47        770
+    3999.48     4000.47        770
+    3999.48     4000.47        770
+    3999.48     4000.47        770
+    1.67u 0.30s 0:24.76 7.9%
+
+ +

+The miracle of indexed filtering (and indeed, of any indexing) is the +speed of the binary search on the index, which is of order log2(n) +instead of n. (The funtools binary search method is taken from +http://www.tbray.org/ongoing/When/200x/2003/03/22/Binary, to whom +grateful acknowledgement is made.) This means that the larger the +file, the better the performance. Conversely, it also means that for +small files, using an index (and the overhead involved) can slow +filtering down somewhat. Our tests indicate that on a file containing +a few tens of thousands of rows, indexed filtering can be 10 to 20 +percent slower than non-indexed filtering. Of course, your mileage +will vary with conditions (disk access speed, amount of available +memory, process load, etc.) + +

+Any problem encountered during index processing will result in +indexing being turned off, and replaced by filtering all rows. You can turn +filtering off manually by setting the idx_activate variable to 0 (in a filter +expression) or the FILTER_IDX_ACTIVATE environment variable to 0 (in the global +environment). Debugging output showing how the indexes are being processed can +be displayed to stderr by setting the idx_debug variable to 1 (in a filter +expression) or the FILTER_IDX_DEBUG environment variable to 1 (in the global +environment). + +

+Currently, indexed filtering only works with FITS binary tables and raw +event files. It does not work with text files. This restriction might be +removed in a future release. + + + + + +

+Go to Funtools Help Index + +

Last updated: August 3, 2007
+ + + diff --git a/doc/imblank.c b/doc/imblank.c new file mode 100644 index 0000000..bdd736e --- /dev/null +++ b/doc/imblank.c @@ -0,0 +1,106 @@ +#include +#include + +#ifdef ANSI_FUNC +int +main (int argc, char **argv) +#else +main(argc, argv) + int argc; + char **argv; +#endif +{ + int i; + int bitpix, dim1, dim2; + int total; + double blimit, bvalue; + char *buf; + unsigned char *cbuf; + short *sbuf; + int *ibuf; + float *fbuf; + double *dbuf; + Fun fun, fun2; + + if( argc < 4 ){ + fprintf(stderr, "usage: %s iname oname blimit bvalue\n", argv[0]); + exit(1); + } + + /* get blank limit and optional blank value */ + blimit = atof(argv[3]); + bvalue = 0; + if( argc >= 5 ) + bvalue = atof(argv[4]); + + /* exit on gio errors */ + setgerror(2); + + /* open the input FITS file */ + if( !(fun = FunOpen(argv[1], "rc", NULL)) ) + gerror(stderr, "could not FunOpen input file: %s\n", argv[1]); + + /* open the output FITS image, preparing to copy input params */ + if( !(fun2 = FunOpen(argv[2], "w", fun)) ) + gerror(stderr, "could not FunOpen output file: %s\n", argv[2]); + + /* extract and bin the data section into an image buffer */ + if( !(buf = FunImageGet(fun, NULL, NULL)) ) + gerror(stderr, "could not FunImageGet: %s\n", argv[1]); + + /* get required information from funtools structure. + this should come after the ImageGet call, in case that call + changed fun_sect_bitpix value */ + FunInfoGet(fun, + FUN_SECT_BITPIX, &bitpix, + FUN_SECT_DIM1, &dim1, + FUN_SECT_DIM2, &dim2, + 0); + + /* set appropriate data type buffer to point to image buffer */ + switch(bitpix){ + case 8: + cbuf = (unsigned char *)buf; break; + case 16: + sbuf = (short *)buf; break; + case 32: + ibuf = (int *)buf; break; + case -32: + fbuf = (float *)buf; break; + case -64: + dbuf = (double *)buf; break; + } + + /* loop through pixels and reset values below limit to value */ + total = dim1*dim2; + for(i=0; i + + +Funtools Programming + + + + +

FunLib: the Funtools Programming Interface

+ + +

Summary

+A description of the Funtools library. + + +

Introduction to the Funtools Programming Interface

+

+To create a Funtools application, you need to include +the funtools.h definitions file in your code: +

+  #include <funtools.h>
+
+ +You then call Funtools subroutines and functions to access Funtools data. +The most important routines are: + + +Your program must be linked against the libfuntools.a library, +along with the math library. The following libraries also might be required +on your system: +
    +
  • -lsocket -lnsl for socket support +
  • -ldl for dynamic loading +
+

+For example, on a Solaris system using gcc, use the following link line: +

+  gcc -o foo foo.c -lfuntools -lsocket -lnsl -ldl -lm
+
+On a Solaris system using Solaris cc, use the following link line: +
+  gcc -o foo foo.c -lfuntools -lsocket -lnsl -lm
+
+On a Linux system using gcc, use the following link line: +
+  gcc -o foo foo.c -lfuntools -ldl -lm
+
+Once configure has built a Makefile on your platform, the required +"extra" libraries (aside from -lm, which always is required) are +specified in that file's EXTRA_LIBS variable. For example, under +Linux you will find: +
+  grep EXTRA_LIBS Makefile
+  EXTRA_LIBS      =  -ldl
+  ...
+
+ +

+The Funtools library contains both the zlib library +(http://www.gzip.org/zlib/) and Doug Mink's WCS library +(http://tdc-www.harvard.edu/software/wcstools/). It is not necessary +to put these libraries on a Funtools link line. Include files +necessary for using these libraries are installed in the Funtools +include directory. + +

Funtools Programming Tutorial

+ +The +FunOpen() +function is used to open a FITS file, an array, or a raw event file: +
+  /* open the input FITS file for reading */
+  ifun = FunOpen(iname, "r", NULL);
+  /* open the output FITS file for writing, and connect it to the input file */
+  ofun = FunOpen(iname, "w", ifun);
+
+A new output file can inherit header parameters automatically from +existing input file by passing the input Funtools handle as the last +argument to the new file's +FunOpen() +call as shown above. + +

+For image data, you then can call +FunImageGet() +to read an image into memory. +

+  float buf=NULL;
+  /* extract and bin the data section into an image buffer */
+  buf = FunImageGet(fun, NULL, "bitpix=-32");
+
+If the (second) buf argument to this call is NULL, buffer space is allocated +automatically. The (third) plist argument can be used to specify the +return data type of the array. If NULL is specified, the data type of +the input file is used. + +

+To process an image buffer, you would generally make a call to +FunInfoGet() to determine the +dimensions of the image (which may have been changed from the original +file dimensions due to Funtools image +sectioning on the command line). In a FITS image, the index along +the dim1 axis varies most rapidly, followed by the dim2 axis, etc. +Thus, to access each pixel in an 2D image, use a double loop such as: + + buf = FunImageGet(fun, NULL, "bitpix=-32"); + FunInfoGet(fun, FUN_SECT_DIM1, &dim1, FUN_SECT_DIM2, &dim2, 0); + for(i=1; i<=dim2; i++){ + for(j=1; j<=dim1; j++){ + ... process buf[((i-1)*dim1)+(j-1)] ... + } + } + +or: +

+  buf = FunImageGet(fun, NULL, "bitpix=-32");
+  FunInfoGet(fun, FUN_SECT_DIM1, &dim1, FUN_SECT_DIM2, &dim2, 0);
+  for(i=0; i<(dim1*dim2); i++){
+    ... process buf[i] ...
+  }
+
+Finally, you can write the resulting image to disk using +FunImagePut(): +
+  FunImagePut(fun2, buf, dim1, dim2, -32, NULL);
+
+Note that Funtools automatically takes care of book-keeping tasks such as +reading and writing FITS headers (although you can, of course, write +your own header or add your own parameters to a header). + +

+For binary tables and raw event files, a call to +FunOpen() +will be followed by a call to the +FunColumnSelect() +routine to select columns to be read from the input file and/or +written to the output file: + +

+  typedef struct evstruct{
+    double time;
+    int time2;
+  } *Ev, EvRec;
+  FunColumnSelect(fun, sizeof(EvRec), NULL,
+                  "time",      "D",     "rw",  FUN_OFFSET(Ev, time),
+                  "time2",     "J",     "w",   FUN_OFFSET(Ev, time2),
+                  NULL);
+
+Columns whose (third) mode argument contains an "r" are "readable", +i.e., columns will be read from the input file and converted into the +data type specified in the call's second argument. These columns +values then are stored in the specified offset of the user record +structure. Columns whose mode argument contains a "w" are +"writable", i.e., these values will be written to the output file. +The +FunColumnSelect() +routine also offers the option of automatically merging user +columns with the original input columns when writing the output +rows. + +

+Once a set of columns has been specified, you can retrieve rows using +FunTableRowGet(), +and write the rows using +FunTableRowPut(): +

+  Ev ebuf, ev;
+  /* get rows -- let routine allocate the array */
+  while( (ebuf = (Ev)FunTableRowGet(fun, NULL, MAXROW, NULL, &got)) ){
+    /* process all rows */
+    for(i=0; i<got; i++){
+      /* point to the i'th row */
+      ev = ebuf+i;
+      /* time2 is generated here */
+      ev->time2 = (int)(ev->time+.5);
+      /* change the input time as well */
+      ev->time = -(ev->time/10.0);
+    }
+    /* write out this batch of rows with the new column */
+    FunTableRowPut(fun2, (char *)ebuf, got, 0, NULL);
+    /* free row data */
+    if( ebuf ) free(ebuf);
+  }
+
+The input rows are retrieved into an array of user structs, which +can be accessed serially as shown above. Once again, Funtools +automatically takes care of book-keeping tasks such as reading and writing +FITS headers (although you can, of course, write your own header or +add your own parameters to a header). + +

+When all processing is done, you can call +FunClose() +to close the file(s): +

+  FunClose(fun2);
+  FunClose(fun);
+
+ +

+These are the basics of processing FITS files (and arrays or raw event +data) using Funtools. The routines in these examples are described in +more detail below, along with a few other routines that support +parameter access, data flushing, etc. + +

Compiling and Linking

+

+To create a Funtools application, a software developer will include +the funtools.h definitions file in Funtools code: +

+  #include <funtools.h>
+
+The program is linked against the libfuntools.a library, along with the +math library (and the dynamic load library, if the latter is available +on your system): +
+  gcc -o foo foo.c -lfuntools -ldl -lm
+
+

+If gcc is used, Funtools filtering can be performed using dynamically +loaded shared objects that are built at run-time. Otherwise, filtering +is performed using a slave process. +

+Funtools has been built on the following systems: +

    +
  • Sun/Solaris 5.X +
  • Linux/RedHat Linux 5.X,6.X,7.X +
  • Dec Alpha/OSF1 V4.X +
  • WindowsNT/Cygwin 1.0 +
  • SGI/IRIX64 6.5 +
+ +

A Short Digression on Subroutine Order

+

+There is a natural order for all I/O access libraries. You would not +think of reading a file without first opening it, or writing a file +after closing it. A large part of the experiment in funtools is to use +the idea of "natural order" as a means of making programming +easier. We do this by maintaining the state of processing for a given +funtools file, so that we can do things like write headers and flush +extension padding at the right time, without you having to do it. + +

+For example, if you open a new funtools file for writing using +FunOpen(), +then generate an array of image data and call +FunImagePut(), +funtools knows to write the image header automatically. +There is no need to think about writing a standard header. +Of course, you can add parameters to the file first by +calling one of the +FunParamPut() +routines, and these parameters will automatically be added +to the header when it is written out. There still is no +need to write the header explicitly. + +

+Maintaining state in this way means that there are certain rules of +order which should be maintained in any funtools program. In particular, +we strongly recommend the following ordering rules be adhered to: + +

    +
  • When specifying that input extensions be copied to an output file +via a reference handle, open the output file before reading the +input file. (Otherwise the initial copy will not occur). + +
  • Always write parameters to an output file using one of the +FunParamPut() calls +before writing any data. (This is a good idea for all FITS +libraries, to avoid having to recopy data is the FITS header needs +to be extended by adding a single parameter.) + +
  • If you retrieve an image, and need to know the data +type, use the FUN_SECT_BITPIX option of +FunInfoGet(), +after calling +FunImageGet(), since +it is possible to change the value of BITPIX from the latter. + +
  • When specifying that input extensions be copied to an output file +via a reference handle, close the output file before closing +input file, or else use +FunFlush() +explicitly on the output file +before closing the input file. (Otherwise the final copy will +not occur). +
+ +

+We believe that these are the natural rules that are implied in most +FITS programming tasks. However, we recognize that making explicit use +of "natural order" to decide what automatic action to take on behalf +of the programmer is experimental. Therefore, if you find that your +needs are not compatible with our preferred order, please let us know +-- it will be most illuminating for us as we evaluate this experiment. + +

Funtools Programming Examples

+

+The following complete coding examples are provided to illustrate the +simplicity of Funtools applications. They can be found in the funtest +subdirectory of the Funtools distribution. In many cases, you should +be able to modify one of these programs to generate your own Funtools +program: +

    +
  • evread.c: read and write binary tables +
  • evcols.c: add column and rows to binary tables +
  • evmerge.c: merge new columns with existing columns +
  • evnext.c: manipulate raw data pointers +
  • imblank.c: blank out image values below a threshold +
  • asc2fits.c: convert a specific ASCII table to FITS binary table +
+ +

The Funtools Programming Reference Manual

+

+

+#include <funtools.h>
+
+Fun FunOpen(char *name, char *mode, Fun ref)
+
+void *FunImageGet(Fun fun, void *buf, char *plist)
+
+int FunImagePut(Fun fun, void *buf, int dim1, int dim2, int bitpix, char *plist)
+
+void * FunImageRowGet(Fun fun, void *buf, int rstart, int rstop, char *plist)
+
+void * FunImageRowPut(Fun fun, void *buf, int rstart, int rstop, int dim1, int dim2, int bitpix, char *plist)
+
+int FunColumnSelect(Fun fun, int size, char *plist, ...)
+
+void FunColumnActivate(Fun fun, char *s, char *plist)
+
+int FunColumnLookup(Fun fun, char *s, int which, char **name, int *type, int *mode, int *offset, int *n, int *width)
+
+void *FunTableRowGet(Fun fun, void *rows, int maxrow, char *plist, int *nrow)
+
+int FunTableRowPut(Fun fun, void *rows, int nev, int idx, char *plist)
+
+int FunParamGetb(Fun fun, char *name, int n, int defval, int *got)
+
+int FunParamGeti(Fun fun, char *name, int n, int defval, int *got)
+
+double FunParamGetd(Fun fun, char *name, int n, double defval, int *got)
+
+char *FunParamGets(Fun fun, char *name, int n, char *defval, int *got)
+
+int FunParamPutb(Fun fun, char *name, int n, int value, char *comm, int append)
+
+int FunParamPuti(Fun fun, char *name, int n, int value, char *comm, int append)
+
+int FunParamPutd(Fun fun, char *name, int n, double value, int prec, char *comm, int append)
+
+int FunParamPuts(Fun fun, char *name, int n, char *value, char *comm, int append)
+
+int FunInfoGet(Fun fun, int type, ...)
+
+int FunInfoPut(Fun fun, int type, ...)
+
+void FunFlush(Fun fun, char *plist)
+
+void FunClose(Fun fun)
+
+ + + + +

FunOpen - open a Funtools data file

+ + + +
+  #include <funtools.h>
+
+  Fun FunOpen(char *name, char *mode, Fun ref);
+
+
+ + +

+The FunOpen() routine opens a Funtools data file for reading or +appending, or creates a new FITS file for writing. The name +argument specifies the name of the Funtools data file to open. You can +use IRAF-style bracket notation to specify +Funtools Files, Extensions, and Filters. +A separate call should be made each time a different FITS extension is +accessed: +

+  Fun fun;
+  char *iname;
+  ...
+  if( !(fun = FunOpen(iname, "r", NULL)) ){
+    fprintf(stderr, "could not FunOpen input file: %s\n", iname);
+    exit(1);
+  }
+
+

+If mode is "r", the file is opened for reading, and processing +is set up to begin at the specified extension. For reading, +name can be stdin, in which case the standard input is read. + +

+If mode is "w", the file is created if it does not exist, or +opened and truncated for writing if it does exist. Processing starts +at the beginning of the file. The name can be stdout, +in which case the standard output is readied for processing. + +

+If mode is "a", the file is created if it does not exist, or +opened if it does exist. Processing starts at the end of the file. +The name can be stdout, in which case the standard +output is readied for processing. + +

+When a Funtools file is opened for writing or appending, a previously +opened Funtools reference +handle can be specified as the third argument. This handle +typically is associated with the input Funtools file that will be used +to generate the data for the output data. When a reference file is +specified in this way, the output file will inherit the (extension) +header parameters from the input file: +

+  Fun fun, fun2;
+  ...
+  /* open input file */
+  if( !(fun = FunOpen(argv[1], "r", NULL)) )
+    gerror(stderr, "could not FunOpen input file: %s\n", argv[1]);
+  /* open the output FITS image, inheriting params from input */
+  if( !(fun2 = FunOpen(argv[2], "w", fun)) )
+    gerror(stderr, "could not FunOpen output file: %s\n", argv[2]);
+
+Thus, in the above example, the output FITS binary table file will +inherit all of the parameters associated with the input binary table +extension. +

+A file opened for writing with a +Funtools reference handle also +inherits the selected columns (i.e. those columns chosen for +processing using the +FunColumnSelect() routine) +from the reference file as its default columns. This makes it easy to +open an output file in such a way that the columns written to the +output file are the same as the columns read in the input file. Of +course, column selection can easily be tailored using the +FunColumnSelect() routine. +In particular, it is easy to merge user-defined columns with the input +columns to generate a new file. See the +evmerge for a complete example. + +

+In addition, when a +Funtools reference handle +is supplied in a FunOpen() call, +it is possible also to specify that all other extensions from the +reference file (other than the input extension being processed) should +be copied from the reference file to the output file. This is useful, +for example, in a case where you are processing a FITS binary table +or image and you want to copy all of the other extensions to +the output file as well. Copy of other extensions is controlled by +adding a "C" or "c" to the mode string of the +FunOpen() call of the input +reference file. If "C" is specified, then other extensions are +always copied (i.e., copy is forced by the application). If +"c" is used, then other extensions are copied if the user requests +copying by adding a plus sign "+" to the extension name in the bracket +specification. For example, the funtable program utilizes +"c" mode, giving users the option of copying all other extensions: +

+  /* open input file -- allow user copy of other extensions */
+  if( !(fun = FunOpen(argv[1], "rc", NULL)) )
+    gerror(stderr, "could not FunOpen input file: %s\n", argv[1]);
+  /* open the output FITS image, inheriting params from input */
+  if( !(fun2 = FunOpen(argv[2], "w", fun)) )
+    gerror(stderr, "could not FunOpen output file: %s\n", argv[2]);
+
+ +Thus, funtable supports either of these command lines: +
+  # copy only the EVENTS extension
+  csh> funtable "test.ev[EVENTS,circle(512,512,10)]" foo.ev
+  # copy ALL extensions
+  csh> funtable "test.ev[EVENTS+,circle(512,512,10)]" foo.ev
+
+ +

+Use of a Funtools reference +handle implies that the input file is opened before the output +file. However, it is important to note that if copy mode ("c" or "C") +is specified for the input file, the actual input file open is delayed +until just after the output file is opened, since the copy of prior +extensions to the output file takes place while Funtools is seeking to +the specified input extension. This implies that the output file +should be opened before any I/O is done on the input file or else the +copy will fail. Note also that the copy of subsequent extension will +be handled automatically by +FunClose() +if the output file is +closed before the input file. Alternatively, it can be done explicitly +by FunFlush(), but again, this +assumes that the input file still is open. + +

+Upon success FunOpen() returns a +Fun handle that is used in subsequent Funtools calls. On error, NULL +is returned. + + + + +

FunImageGet - get an image or image section

+ + + +
+  #include <funtools.h>
+
+  void *FunImageGet(Fun fun, void *buf, char *plist)
+
+
+ + +

+The FunImageGet() routine returns an binned image array of the +specified section of a Funtools data file. If the input data are +already of type image, the array is generated by extracting the +specified image section and then binning it according to the specified +bin factor. If the input data are contained in a binary table or raw +event file, the rows are binned on the columns specified by the +bincols= keyword (using appropriate default columns as +necessary), after which the image section and bin factors are +applied. In both cases, the data is automatically converted from FITS +to native format, if necessary. +

+The first argument is the Funtools handle returned by +FunOpen(). The second buf +argument is a pointer to a data buffer to fill. If NULL is specified, +FunImageGet will allocate a buffer of the appropriate size. Generally +speaking, you always want Funtools to allocate the buffer because +the image dimensions will be determined by +Funtools image sectioning +on the command line. +

+The third plist (i.e., parameter list) argument is a string +containing one or more comma-delimited keyword=value +parameters. It can be used to specify the return data type using the +bitpix= keyword. If no such keyword is specified in the plist +string, the data type of the returned image is the same as the data type +of the original input file, or is of type int for FITS binary tables. + +

+If the bitpix= keyword is supplied in the plist string, the data +type of the returned image will be one of the supported FITS image +data types: +

    +
  • 8 unsigned char +
  • 16 short +
  • 32 int +
  • -32 float +
  • -64 double +
+For example: +
+  void *buf;
+  /* extract data section into an image buffer */
+  if( !(buf = FunImageGet(fun, NULL, NULL)) )
+    gerror(stderr, "could not FunImageGet: %s\n", iname);
+
+will allocate buf and retrieve the image in the file data format. In +this case, you will have to determine the data type (using the +FUN_SECT_BITPIX value in the +FunInfoGet() +routine) +and then use a switch statement to process each data type: +
+  int bitpix;
+  void *buf;
+  unsigned char *cbuf;
+  short *sbuf;
+  int *ibuf;
+  ...
+  buf = FunImageGet(fun, NULL, NULL);
+  FunInfoGet(fun, FUN_SECT_BITPIX,  &bitpix, 0);
+  /* set appropriate data type buffer to point to image buffer */
+  switch(bitpix){
+  case 8:
+    cbuf = (unsigned char *)buf; break;
+  case 16:
+    sbuf = (short *)buf; break;
+  case 32:
+    ibuf = (int *)buf; break;
+ ...
+
+See the +imblank example code +for more details on how to process an image when the data type is not +specified beforehand. + +

+It often is easier to specify the data type directly: +

+  double *buf;
+  /* extract data section into a double image buffer */
+  if( !(buf = FunImageGet(fun, NULL, "bitpix=-64")) )
+    gerror(stderr, "could not FunImageGet: %s\n", iname);
+
+will extract the image while converting to type double. + +

+On success, a pointer to the image buffer is returned. (This will be +the same as the second argument, if NULL is not passed to the latter.) +On error, NULL is returned. + +

+In summary, to retrieve image or row data into a binned image, you simply +call FunOpen() followed by +FunImageGet(). Generally, you +then will want to call +FunInfoGet() +to retrieve the +axis dimensions (and data type) of the section you are processing +(so as to take account of sectioning and blocking of the original data): +

+  double *buf;
+  int i, j;
+  int dim1, dim2;
+  ... other declarations, etc.
+
+  /* open the input FITS file */
+  if( !(fun = FunOpen(argv[1], "rc", NULL)) )
+    gerror(stderr, "could not FunOpen input file: %s\n", argv[1]);
+
+  /* extract and bin the data section into a double float image buffer */
+  if( !(buf = FunImageGet(fun, NULL, "bitpix=-64")) )
+    gerror(stderr, "could not FunImageGet: %s\n", argv[1]);
+
+  /* get dimension information from funtools structure */
+  FunInfoGet(fun, FUN_SECT_DIM1, &dim1, FUN_SECT_DIM2, &dim2, 0);
+
+  /* loop through pixels and reset values below limit to value */
+  for(i=0; i<dim1*dim2; i++){
+    if( buf[i] <= blimit ) buf[i] = bvalue;
+  }
+
+ +

+Another useful plist string value is "mask=all", which returns an +image populated with regions id values. Image pixels within a region +will contain the associated region id (region values start at 1), and +otherwise will contain a 0 value. Thus, the returned image is a +region mask which can be used to process the image data (which +presumably is retrieved by a separate call to FunImageGet) pixel by +pixel. + +

+If a FITS binary table or a non-FITS raw event file is being binned +into an image, it is necessary to specify the two columns that will be +used in the 2D binning. This usually is done on the command line +using the bincols=(x,y) keyword: +

+  funcnts "foo.ev[EVENTS,bincols=(detx,dety)]"
+
+ +

+The full form of the bincols= specifier is: +

+  bincols=([xname[:tlmin[:tlmax:[binsiz]]]],[yname[:tlmin[:tlmax[:binsiz]]]])
+
+where the tlmin, tlmax, and binsiz specifiers determine the image binning +dimensions: +
+  dim = (tlmax - tlmin)/binsiz     (floating point data)
+  dim = (tlmax - tlmin)/binsiz + 1 (integer data)
+
+These tlmin, tlmax, and binsiz specifiers can be omitted if TLMIN, +TLMAX, and TDBIN header parameters (respectively) are present in the +FITS binary table header for the column in question. Note that if +only one parameter is specified, it is assumed to be tlmax, and tlmin +defaults to 1. If two parameters are specified, they are assumed to be +tlmin and tlmax. + +

+If bincols is not specified on the command line, Funtools tries +to use appropriate defaults: it looks for the environment variable +FITS_BINCOLS (or FITS_BINKEY). Then it looks for the Chandra +parameters CPREF (or PREFX) in the FITS binary table header. Failing +this, it looks for columns named "X" and "Y" and if these are not +found, it looks for columns containing the characters "X" and "Y". +

+See Binning FITS Binary Tables and +Non-FITS Event Files for more information. + + + + +

FunImagePut - put an image to a Funtools file

+ + +
+  #include <funtools.h>
+
+  int FunImagePut(Fun fun, void *buf, int dim1, int dim2, int bitpix,
+                  char *plist)
+
+
+ + +The FunImagePut() routine outputs an image array to a FITS +file. The image is written either as a primary header/data unit or as +an image extension, depending on whether other data have already been +written to the file. That is, if the current file position is at the +beginning of the file, a primary HDU is written. Otherwise, an +image extension is written. + +

+The first argument is the Funtools handle returned by +FunOpen(). The second buf +argument is a pointer to a data buffer to write. The dim1and +dim2 arguments that follow specify the dimensions of the image, +where dim1 corresponds to naxis1 and dim2 corresponds to naxis2. The +bitpix argument specifies the data type of the image and can +have the following FITS-standard values: +

    +
  • 8 unsigned char +
  • 16 short +
  • 32 int +
  • -32 float +
  • -64 double +
+ +

+When FunTableRowPut() is first +called for a given image, Funtools checks to see if the primary header +has already been written (by having previously written an image or a +binary table.) If not, this image is written to the primary HDU. +Otherwise, it is written to an image extension. +

+Thus, a simple program to generate a FITS image might look like this: +

+  int i;
+  int dim1=512, dim2=512;
+  double *dbuf;
+  Fun fun;
+  dbuf = malloc(dim1*dim2*sizeof(double));
+  /* open the output FITS image, preparing to copy input params */
+  if( !(fun = FunOpen(argv[1], "w", NULL)) )
+    gerror(stderr, "could not FunOpen output file: %s\n", argv[1]);
+  for(i=0; i<(dim1*dim2); i++){
+    ... fill dbuf ...
+  }
+  /* put the image (header will be generated automatically */
+  if( !FunImagePut(fun, buf, dim1, dim2, -64, NULL) )
+    gerror(stderr, "could not FunImagePut: %s\n", argv[1]);
+  FunClose(fun);
+  free(dbuf);
+
+ +

+In addition, if a +Funtools reference handle +was specified when this table was opened, the +parameters from this +Funtools reference handle +are merged into the new image +header. Furthermore, if a reference image was specified during +FunOpen(), the values of +dim1, dim2, and bitpix in the calling sequence +can all be set to 0. In this case, default values are taken from the +reference image section. This is useful if you are reading an image +section in its native data format, processing it, and then writing +that section to a new FITS file. See the +imblank example code. + +

+The data are assumed to be in the native machine format and will +automatically be swapped to FITS big-endian format if necessary. This +behavior can be over-ridden with the convert=[true|false] +keyword in the plist param list string. + +

+When you are finished writing the image, you should call +FunFlush() to write out the FITS +image padding. However, this is not necessary if you subsequently call +FunClose() without doing any other I/O to the FITS file. + + + + +

FunImageRowGet - get row(s) of an image

+ + + +
+  #include <funtools.h>
+
+  void *FunImageRowGet(Fun fun, void *buf, int rstart, int rstop,
+                       char *plist)
+
+
+ + +

+The FunImageRowGet() routine returns one or more image rows +from the specified section of a Funtools data file. If the input data +are of type image, the array is generated by extracting the specified +image rows and then binning them according to the specified bin +factor. If the input data are contained in a binary table or raw +event file, the rows are binned on the columns specified by the +bincols= keyword (using appropriate default columns as needed), +after which the image section and bin factors are applied. + +

+The first argument is the Funtools handle returned by +FunOpen(). The second buf +argument is a pointer to a data buffer to fill. If NULL is specified, +FunImageGet() will allocate a buffer of the appropriate size. + +

+The third and fourth arguments specify the first and last row to +retrieve. Rows are counted starting from 1, up to the value of +FUN_YMAX(fun). The final plist (i.e., parameter list) argument +is a string containing one or more comma-delimited +keyword=value parameters. It can be used to specify the return +data type using the bitpix= keyword. If no such keyword is +specified in the plist string, the data type of the image is the same +as the data type of the original input file, or is of type int for +FITS binary tables. + +

+If the bitpix=value is supplied in the plist string, the data +type of the returned image will be one of the supported FITS image +data types: +

    +
  • 8 unsigned char +
  • 16 short +
  • 32 int +
  • -32 float +
  • -64 double +
+ +

+For example: +

+  double *drow;
+  Fun fun;
+  ... open files ...
+  /* get section dimensions */
+  FunInfoGet(fun, FUN_SECT_DIM1, &dim1, FUN_SECT_DIM2, &dim2, 0);
+  /* allocate one line's worth */
+  drow = malloc(dim1*sizeof(double));
+  /* retrieve and process each input row (starting at 1) */
+  for(i=1; i <= dim2; i++){
+    if( !FunImageRowGet(fun, drow, i, i, "bitpix=-64") )
+      gerror(stderr, "can't FunImageRowGet: %d %s\n", i, iname);
+      /* reverse the line */
+      for(j=1; j<=dim1; j++){
+        ... process drow[j-1] ...
+      }
+  }
+  ...
+
+ +

+On success, a pointer to the image buffer is returned. (This will be +the same as the second argument, if NULL is not passed to the latter.) +On error, NULL is returned. Note that the considerations described +above for specifying binning columns in +FunImageGet() also apply to +FunImageRowGet(). + + + + +

FunImageRowPut - put row(s) of an image

+ + + +
+  #include <funtools.h>
+
+  void *FunImageRowPut(Fun fun, void *buf, int rstart, int rstop,
+                       int dim1, int dim2, int bitpix, char *plist)
+
+
+ + +

+The FunImageRowPut() routine writes one or more image rows to +the specified FITS image file. The first argument is the Funtools +handle returned by FunOpen(). +The second buf argument is a pointer to the row data buffer, +while the third and fourth arguments specify the starting and ending +rows to write. Valid rows values range from 1 to dim2, i.e., row is +one-valued. + +

+The dim1and dim2 arguments that follow specify the +dimensions, where dim1 corresponds to naxis1 and dim2 corresponds to +naxis2. The bitpix argument data type of the image and can +have the following FITS-standard values: +

    +
  • 8 unsigned char +
  • 16 short +
  • 32 int +
  • -32 float +
  • -64 double +
+ +For example: +
+  double *drow;
+  Fun fun, fun2;
+  ... open files ...
+  /* get section dimensions */
+  FunInfoGet(fun, FUN_SECT_DIM1, &dim1, FUN_SECT_DIM2, &dim2, 0);
+  /* allocate one line's worth */
+  drow = malloc(dim1*sizeof(double));
+  /* retrieve and process each input row (starting at 1) */
+  for(i=1; i <= dim2; i++){
+    if( !FunImageRowGet(fun, drow, i, i, "bitpix=-64") )
+      gerror(stderr, "can't FunImageRowGet: %d %s\n", i, iname);
+    ... process drow ...
+    if( !FunImageRowPut(fun2, drow, i, i, 64, NULL) )
+      gerror(stderr, "can't FunImageRowPut: %d %s\n", i, oname);
+  }
+  ...
+
+ +

+The data are assumed to be in the native machine format and will +automatically be swapped to big-endian FITS format if necessary. This +behavior can be over-ridden with the convert=[true|false] +keyword in the plist param list string. + +

+When you are finished writing the image, you should call +FunFlush() to write out the FITS +image padding. However, this is not necessary if you subsequently call +FunClose() without doing any other I/O to the FITS file. + + + + +

FunColumnSelect - select Funtools columns

+ + +
+  #include <funtools.h>
+
+  int FunColumnSelect(Fun fun, int size, char *plist, 
+                      char *name1, char *type1, char *mode1, int offset1,
+                      char *name2, char *type2, char *mode2, int offset2,
+                      ...,
+                      NULL)
+
+  int FunColumnSelectArr(Fun fun, int size, char *plist, 
+                         char **names, char **types, char **modes,
+                         int *offsets, int nargs);
+
+
+ + +The FunColumnSelect() routine is used to select the columns +from a Funtools binary table extension or raw event file for +processing. This routine allows you to specify how columns in a file +are to be read into a user record structure or written from a user +record structure to an output FITS file. + +

+The first argument is the Fun handle associated with this set of +columns. The second argument specifies the size of the user record +structure into which columns will be read. Typically, the sizeof() +macro is used to specify the size of a record structure. The third +argument allows you to specify keyword directives for the selection +and is described in more detail below. + +

+Following the first three required arguments is a variable length list of +column specifications. Each column specification will consist of four +arguments: +

    +
  • name: the name of the column + +
  • type: the data type of the column as it will be stored in +the user record struct (not the data type of the input file). The +following basic data types are recognized: +
      +
    • A: ASCII characters +
    • B: unsigned 8-bit char +
    • I: signed 16-bit int +
    • U: unsigned 16-bit int (not standard FITS) +
    • J: signed 32-bit int +
    • V: unsigned 32-bit int (not standard FITS) +
    • E: 32-bit float +
    • D: 64-bit float +
    +The syntax used is similar to that which defines the TFORM parameter +in FITS binary tables. That is, a numeric repeat value can precede +the type character, so that "10I" means a vector of 10 short ints, "E" +means a single precision float, etc. Note that the column value from +the input file will be converted to the specified data type as the +data is read by +FunTableRowGet(). + +

    +[ A short digression regarding bit-fields: Special attention is +required when reading or writing the FITS bit-field type +("X"). Bit-fields almost always have a numeric repeat character +preceding the 'X' specification. Usually this value is a multiple of 8 +so that bit-fields fit into an integral number of bytes. For all +cases, the byte size of the bit-field B is (N+7)/8, where N is the +numeric repeat character. + +

    +A bit-field is most easily declared in the user struct as an array of +type char of size B as defined above. In this case, bytes are simply +moved from the file to the user space. If, instead, a short or int +scalar or array is used, then the algorithm for reading the bit-field +into the user space depends on the size of the data type used along +with the value of the repeat character. That is, if the user data +size is equal to the byte size of the bit-field, then the data is +simply moved (possibly with endian-based byte-swapping) from one to +the other. If, on the other hand, the data storage is larger than the +bit-field size, then a data type cast conversion is performed to move +parts of the bit-field into elements of the array. Examples will help +make this clear: + +

      +
    • If the file contains a 16X bit-field and user space specifies a 2B +char array[2], then the bit-field is moved directly into the char array. + +
    • If the file contains a 16X bit-field and user space specifies a 1I +scalar short int, then the bit-field is moved directly into the short int. + +
    • If the file contains a 16X bit-field and user space specifies a 1J +scalar int, then the bit-field is type-cast to unsigned int before +being moved (use of unsigned avoids possible sign extension). + +
    • If the file contains a 16X bit-field and user space specifies a 2J +int array[2], then the bit-field is handled as 2 chars, each of which +are type-cast to unsigned int before being moved (use of unsigned +avoids possible sign extension). + +
    • If the file contains a 16X bit-field and user space specifies a 1B +char, then the bit-field is treated as a char, i.e., truncation will +occur. + +
    • If the file contains a 16X bit-field and user space specifies a 4J +int array[4], then the results are undetermined. + +
    +For all user data types larger than char, the bit-field is byte-swapped +as necessary to convert to native format, so that bits in the +resulting data in user space can be tested, masked, etc. in the same +way regardless of platform.] + +

    +In addition to setting data type and size, the type +specification allows a few ancillary parameters to be set, using the +full syntax for type: +

    + [@][n]<type>[[['B']poff]][:[tlmin[:tlmax[:binsiz]]]]
    +
    + +

    +The special character "@" can be prepended to this specification to +indicated that the data element is a pointer in the user record, +rather than an array stored within the record. + +

    +The [n] value is an integer that specifies the +number of elements that are in this column (default is 1). TLMIN, +TLMAX, and BINSIZ values also can be specified for this column after +the type, separated by colons. If only one such number is specified, +it is assumed to be TLMAX, and TLMIN and BINSIZ are set to 1. + +

    +The [poff] value can be used to specify the offset into an +array. By default, this offset value is set to zero and the data +specified starts at the beginning of the array. The offset usually +is specified in terms of the data type of the column. Thus an offset +specification of [5] means a 20-byte offset if the data type is a +32-bit integer, and a 40-byte offset for a double. If you want to +specify a byte offset instead of an offset tied to the column data type, +precede the offset value with 'B', e.g. [B6] means a 6-bye offset, +regardless of the column data type. + +The [poff] is especially useful in conjunction with the pointer @ +specification, since it allows the data element to anywhere stored +anywhere in the allocated array. For example, a specification such as +"@I[2]" specifies the third (i.e., starting from 0) element in the +array pointed to by the pointer value. A value of "@2I[4]" specifies +the fifth and sixth values in the array. For example, consider the +following specification:

    +
    +  typedef struct EvStruct{
    +    short x[4], *atp;
    +  } *Event, EventRec;
    +  /* set up the (hardwired) columns */
    +  FunColumnSelect( fun, sizeof(EventRec), NULL,
    +                   "2i",    "2I  ",    "w", FUN_OFFSET(Event, x),
    +                   "2i2",   "2I[2]",   "w", FUN_OFFSET(Event, x),
    +                   "at2p",  "@2I",     "w", FUN_OFFSET(Event, atp),
    +                   "at2p4", "@2I[4]",  "w", FUN_OFFSET(Event, atp),
    +                   "atp9",  "@I[9]",   "w", FUN_OFFSET(Event, atp),
    +                   "atb20", "@I[B20]", "w", FUN_OFFSET(Event, atb),
    +                   NULL);
    +
    +Here we have specified the following columns: +
      +
    • 2i: two short ints in an array which is stored as part the +record +
    • 2i2: the 3rd and 4th elements of an array which is stored +as part of the record +
    • an array of at least 10 elements, not stored in the record but +allocated elsewhere, and used by three different columns: +
        +
      • at2p: 2 short ints which are the first 2 elements of the allocated array +
      • at2p4: 2 short ints which are the 5th and 6th elements of +the allocated array +
      • atp9: a short int which is the 10th element of the allocated array +
      +
    • atb20: a short int which is at byte offset 20 of another allocated array +
    +In this way, several columns can be specified, all of which are in a +single array. NB: it is the programmer's responsibility to +ensure that specification of a positive value for poff does not point +past the end of valid data. + +
  • read/write mode: "r" means that the column is read from an +input file into user space by +FunTableRowGet(), "w" means that +the column is written to an output file. Both can specified at the same +time. + +
  • offset: the offset into the user data to store +this column. Typically, the macro FUN_OFFSET(recname, colname) is used +to define the offset into a record structure. +
+ +

+When all column arguments have been specified, a final NULL argument +must added to signal the column selection list. + +

+As an alternative to the varargs +FunColumnSelect() +routine, a non-varargs routine called +FunColumnSelectArr() +also is available. The first three arguments (fun, size, plist) of this +routine are the same as in +FunColumnSelect(). +Instead of a variable +argument list, however, +FunColumnSelectArr() +takes 5 additional arguments. The first 4 arrays arguments contain the +names, types, modes, and offsets, respectively, of the columns being +selected. The final argument is the number of columns that are +contained in these arrays. It is the user's responsibility to free +string space allocated in these arrays. + +

+Consider the following example: +

+  typedef struct evstruct{
+    int status;
+    float pi, pha, *phas;
+    double energy;
+  } *Ev, EvRec;
+
+  FunColumnSelect(fun, sizeof(EvRec), NULL,
+    "status",  "J",     "r",   FUN_OFFSET(Ev, status),
+    "pi",      "E",     "r",  FUN_OFFSET(Ev, pi),
+    "pha",     "E",     "r",  FUN_OFFSET(Ev, pha),
+    "phas",    "@9E",   "r",  FUN_OFFSET(Ev, phas),
+    NULL);
+
+

+Each time a row is read into the Ev struct, the "status" column is +converted to an int data type (regardless of its data type in the +file) and stored in the status value of the struct. Similarly, "pi" +and "pha", and the phas vector are all stored as floats. Note that the +"@" sign indicates that the "phas" vector is a pointer to a 9 element +array, rather than an array allocated in the struct itself. The row +record can then be processed as required: +

+  /* get rows -- let routine allocate the row array */
+  while( (ebuf = (Ev)FunTableRowGet(fun, NULL, MAXROW, NULL, &got)) ){
+    /* process all rows */
+    for(i=0; i<got; i++){
+      /* point to the i'th row */
+      ev = ebuf+i;
+      ev->pi = (ev->pi+.5);
+      ev->pha = (ev->pi-.5);
+    }
+
+ +

+FunColumnSelect() +can also be called to define "writable" columns in order to generate a FITS +Binary Table, without reference to any input columns. For +example, the following will generate a 4-column FITS binary table when +FunTableRowPut() is used to +write Ev records: + +

+  typedef struct evstruct{
+    int status;
+    float pi, pha
+    double energy;
+  } *Ev, EvRec;
+
+  FunColumnSelect(fun, sizeof(EvRec), NULL,
+    "status",  "J",     "w",   FUN_OFFSET(Ev, status),
+    "pi",      "E",     "w",   FUN_OFFSET(Ev, pi),
+    "pha",     "E",     "w",   FUN_OFFSET(Ev, pha),
+    "energy",  "D",       "w",   FUN_OFFSET(Ev, energy),
+    NULL);
+
+All columns are declared to be write-only, so presumably the column +data is being generated or read from some other source. + +

+In addition, +FunColumnSelect() +can be called to define both "readable" and "writable" columns. +In this case, the "read" columns +are associated with an input file, while the "write" columns are +associated with the output file. Of course, columns can be specified as both +"readable" and "writable", in which case they are read from input +and (possibly modified data values are) written to the output. +The +FunColumnSelect() +call itself is made by passing the input Funtools handle, and it is +assumed that the output file has been opened using this input handle +as its +Funtools reference handle. + +

+Consider the following example: +

+  typedef struct evstruct{
+    int status;
+    float pi, pha, *phas;
+    double energy;
+  } *Ev, EvRec;
+
+  FunColumnSelect(fun, sizeof(EvRec), NULL,
+    "status",  "J",     "r",   FUN_OFFSET(Ev, status),
+    "pi",      "E",     "rw",  FUN_OFFSET(Ev, pi),
+    "pha",     "E",     "rw",  FUN_OFFSET(Ev, pha),
+    "phas",    "@9E",   "rw",  FUN_OFFSET(Ev, phas),
+    "energy",  "D",     "w",   FUN_OFFSET(Ev, energy),
+    NULL);
+
+As in the "read" example above, each time an row is read into the Ev +struct, the "status" column is converted to an int data type +(regardless of its data type in the file) and stored in the status +value of the struct. Similarly, "pi" and "pha", and the phas vector +are all stored as floats. Since the "pi", "pha", and "phas" variables +are declared as "writable" as well as "readable", they also will be +written to the output file. Note, however, that the "status" variable +is declared as "readable" only, and hence it will not be written to +an output file. Finally, the "energy" column is declared as +"writable" only, meaning it will not be read from the input file. In +this case, it can be assumed that "energy" will be calculated in the +program before being output along with the other values. + +

+In these simple cases, only the columns specified as "writable" will +be output using +FunTableRowPut(). However, +it often is the case that you want to merge the user columns back in +with the input columns, even in cases where not all of the input +column names are explicitly read or even known. For this important +case, the merge=[type] keyword is provided in the plist string. + +

+The merge=[type] keyword tells Funtools to merge the columns from +the input file with user columns on output. It is normally used when +an input and output file are opened and the input file provides the +Funtools reference handle +for the output file. In this case, each time +FunTableRowGet() is called, the +raw input rows are saved in a special buffer. If +FunTableRowPut() then is called +(before another call to +FunTableRowGet()), the contents +of the raw input rows are merged with the user rows according to the +value of type as follows: + +

    +
  • update: add new user columns, and update value of existing ones (maintaining the input data type) + +
  • replace: add new user columns, and replace the data type +and value of existing ones. (Note that if tlmin/tlmax values are not +specified in the replacing column, but are specified in the original +column being replaced, then the original tlmin/tlmax values are used +in the replacing column.) + +
  • append: only add new columns, do not "replace" or "update" existing ones +
+ +

+Consider the example above. If merge=update is specified in the +plist string, then "energy" will be added to the input columns, and +the values of "pi", "pha", and "phas" will be taken from the user +space (i.e., the values will be updated from the original values, if +they were changed by the program). The data type for "pi", "pha", and +"phas" will be the same as in the original file. If +merge=replace is specified, both the data type and value of +these three input columns will be changed to the data type and value +in the user structure. If merge=append is specified, none of +these three columns will be updated, and only the "energy" column will +be added. Note that in all cases, "status" will be written from the +input data, not from the user record, since it was specified as read-only. + +

+Standard applications will call +FunColumnSelect() +to define user columns. However, if this routine is not called, the +default behavior is to transfer all input columns into user space. For +this purpose a default record structure is defined such that each data +element is properly aligned on a valid data type boundary. This +mechanism is used by programs such as fundisp and funtable to process +columns without needing to know the specific names of those columns. +It is not anticipated that users will need such capabilities (contact +us if you do!) + +

+By default, FunColumnSelect() +reads/writes rows to/from an "array of structs", where each struct contains +the column values for a single row of the table. This means that the +returned values for a given column are not contiguous. You can +set up the IO to return a "struct of arrays" so that each of the +returned columns are contiguous by specifying org=structofarrays +(abbreviation: org=soa) in the plist. +(The default case is org=arrayofstructs or org=aos.) + +

+For example, the default setup to retrieve rows from a table would be +to define a record structure for a single event and then call + FunColumnSelect() +as follows: +

+  typedef struct evstruct{
+    short region;
+    double x, y;
+    int pi, pha;
+    double time;
+  } *Ev, EvRec;
+
+  got = FunColumnSelect(fun, sizeof(EvRec), NULL,
+                        "x",       "D:10:10", mode, FUN_OFFSET(Ev, x),
+                        "y",       "D:10:10", mode, FUN_OFFSET(Ev, y),
+                        "pi",      "J",       mode, FUN_OFFSET(Ev, pi),
+                        "pha",     "J",       mode, FUN_OFFSET(Ev, pha),
+                        "time",    "1D",      mode, FUN_OFFSET(Ev, time),
+                        NULL);
+
+Subsequently, each call to +FunTableRowGet() +will return an array of structs, one for each returned row. If instead you +wanted to read columns into contiguous arrays, you specify org=soa: +
+  typedef struct aevstruct{
+    short region[MAXROW];
+    double x[MAXROW], y[MAXROW];
+    int pi[MAXROW], pha[MAXROW];
+    double time[MAXROW];
+  } *AEv, AEvRec;
+
+  got = FunColumnSelect(fun, sizeof(AEvRec), "org=soa",
+                      "x",       "D:10:10", mode, FUN_OFFSET(AEv, x),
+                      "y",       "D:10:10", mode, FUN_OFFSET(AEv, y),
+                      "pi",      "J",       mode, FUN_OFFSET(AEv, pi),
+                      "pha",     "J",       mode, FUN_OFFSET(AEv, pha),
+                      "time",    "1D",      mode, FUN_OFFSET(AEv, time),
+                      NULL);
+
+Note that the only modification to the call is in the plist string. + +

+Of course, instead of using staticly allocated arrays, you also can specify +dynamically allocated pointers: +

+  /* pointers to arrays of columns (used in struct of arrays) */
+  typedef struct pevstruct{
+    short *region;
+    double *x, *y;
+    int *pi, *pha;
+    double *time;
+  } *PEv, PEvRec;
+
+  got = FunColumnSelect(fun, sizeof(PEvRec), "org=structofarrays",
+                      "$region", "@I",       mode, FUN_OFFSET(PEv, region),
+                      "x",       "@D:10:10", mode, FUN_OFFSET(PEv, x),
+                      "y",       "@D:10:10", mode, FUN_OFFSET(PEv, y),
+                      "pi",      "@J",       mode, FUN_OFFSET(PEv, pi),
+                      "pha",     "@J",       mode, FUN_OFFSET(PEv, pha),
+                      "time",    "@1D",      mode, FUN_OFFSET(PEv, time),
+                      NULL);
+
+Here, the actual storage space is either allocated by the user or by the +FunColumnSelect() call). + +

+In all of the above cases, the same call is made to retrieve rows, e.g.: +

+    buf = (void *)FunTableRowGet(fun, NULL, MAXROW, NULL, &got);
+
+However, the individual data elements are accessed differently. +For the default case of an "array of structs", the +individual row records are accessed using: +
+  for(i=0; i<got; i++){
+    ev = (Ev)buf+i;
+    fprintf(stdout, "%.2f\t%.2f\t%d\t%d\t%.4f\t%.4f\t%21.8f\n",
+            ev->x, ev->y, ev->pi, ev->pha, ev->dx, ev->dy, ev->time);
+  }
+
+For a struct of arrays or a struct of array pointers, we have a single struct +through which we access individual columns and rows using: +
+  aev = (AEv)buf;
+  for(i=0; i<got; i++){
+    fprintf(stdout, "%.2f\t%.2f\t%d\t%d\t%.4f\t%.4f\t%21.8f\n",
+            aev->x[i], aev->y[i], aev->pi[i], aev->pha[i], 
+            aev->dx[i], aev->dy[i], aev->time[i]);
+  }
+
+Support for struct of arrays in the +FunTableRowPut() +call is handled analogously. + +

+See the evread example code +and +evmerge example code +for working examples of how +FunColumnSelect() is used. + + + + +

FunColumnActivate - activate Funtools columns

+ + + +
+  #include <funtools.h>
+
+  void FunColumnActivate(Fun fun, char *s, char *plist)
+
+
+ + +

+The FunColumnActivate() routine determines which columns (set up +by FunColumnSelect()) +ultimately will be read and/or written. By default, all columns that +are selected using +FunColumnSelect() +are activated. The +FunColumnActivate() +routine can be used to turn off/off activation of specific columns. + +

+The first argument is the Fun handle associated with this set of +columns. The second argument is a space-delimited list of columns to +activate or de-activate. Columns preceded by "+" are activated and +columns preceded by a "-" are de-activated. If a column is named +without "+" or "-", it is activated. The reserved strings "$region" +and '$n' are used to activate a special columns containing the filter +region value and row value, respectively, associated with +this row. For example, if a filter containing two circular regions is +specified as part of the Funtools file name, this column will contain +a value of 1 or 2, depending on which region that row was in. The +reserved strings "$x" and "$y" are used to activate the current +binning columns. Thus, if the columns DX and DY are specified as +binning columns: +

+  [sh $] fundisp foo.fits[bincols=(DX,DY)]
+
+then "$x" and "$y" will refer to these columns in a call to +FunColumnActivate(). + +

+In addition, if the activation string contains only columns to be +activated, then the routine will de-activate all other columns. +Similarly, if the activation string contains only +columns to de-activate, then the routine will activate all other columns +before activating the list. This makes it simple to change the +activation state of all columns without having to know all of the +column names. For example: +

    +
  • "pi pha time" # only these three columns will be active +
  • "-pi -pha -time" # all but these columns will be active +
  • "pi -pha" # only pi is active, pha is not, others are not +
  • "+pi -pha" # same as above +
  • "pi -pha -time" # only pi is active, all others are not +
  • "pi pha" # pha and pi are active, all others are not +
  • "pi pha -x -y" # pha and pi are active, all others are not +
+ +

+You can use the column activation list to reorder columns, since +columns are output in the order specified. For example: +

+  # default output order
+  fundisp snr.ev'[cir 512 512 .1]' 
+         X        Y      PHA       PI                  TIME       DX       DY
+  -------- -------- -------- -------- --------------------- -------- --------
+       512      512        6        7     79493997.45854475      578      574
+       512      512        8        9     79494575.58943175      579      573
+       512      512        5        6     79493631.03866175      578      575
+       512      512        5        5     79493290.86521725      578      575
+       512      512        8        9     79493432.00990875      579      573
+
+  # re-order the output by specifying explicit order
+  fundisp snr.ev'[cir 512 512 .1]' "time x y dy dx pi pha"
+                   TIME        X        Y       DY       DX       PI      PHA
+  --------------------- -------- -------- -------- -------- -------- --------
+      79493997.45854475      512      512      574      578        7        6
+      79494575.58943175      512      512      573      579        9        8
+      79493631.03866175      512      512      575      578        6        5
+      79493290.86521725      512      512      575      578        5        5
+      79493432.00990875      512      512      573      579        9        8
+
+ +

+A "+" sign by itself means to activate all columns, so that you can reorder +just a few columns without specifying all of them: +

+  # reorder 3 columns and then output the rest
+  fundisp snr.ev'[cir 512 512 .1]' "time pi pha +"
+                   TIME       PI      PHA        Y        X       DX       DY
+  --------------------- -------- -------- -------- -------- -------- --------
+      79493997.45854475        7        6      512      512      578      574
+      79494575.58943175        9        8      512      512      579      573
+      79493631.03866175        6        5      512      512      578      575
+      79493290.86521725        5        5      512      512      578      575
+      79493432.00990875        9        8      512      512      579      573
+
+The column activation/deactivation is performed in the order of the +specified column arguments. This means you can mix "+", "-" (which +de-activates all columns) and specific column names to reorder and +select columns in one command. For example, consider the following: +
+  # reorder and de-activate
+  fundisp snr.ev'[cir 512 512 .1]' "time pi pha + -x -y"
+                   TIME       PI      PHA       DX       DY
+  --------------------- -------- -------- -------- --------
+      79493997.45854475        7        6      578      574
+      79494575.58943175        9        8      579      573
+      79493631.03866175        6        5      578      575
+      79493290.86521725        5        5      578      575
+      79493432.00990875        9        8      579      573
+
+We first activate "time", "pi", and "pha" so that they are output first. +We then activate all of the other columns, and then de-activate "x" and "y". +Note that this is different from: +
+  # probably not what you want ...
+  fundisp snr.ev'[cir 512 512 .1]' "time pi pha -x -y +"
+                   TIME       PI      PHA        Y        X       DX       DY
+  --------------------- -------- -------- -------- -------- -------- --------
+      79493997.45854475        7        6      512      512      578      574
+      79494575.58943175        9        8      512      512      579      573
+      79493631.03866175        6        5      512      512      578      575
+      79493290.86521725        5        5      512      512      578      575
+      79493432.00990875        9        8      512      512      579      573
+
+Here, "x" and "y" are de-activated, but then all columns including "x" and +"y" are again re-activated. + +

+Typically, +FunColumnActivate() uses a +list of columns that are passed into the program from the command line. For +example, the code for funtable contains the following: +

+  char *cols=NULL;
+
+  /* open the input FITS file */
+  if( !(fun = FunOpen(argv[1], "rc", NULL)) )
+    gerror(stderr, "could not FunOpen input file: %s\n", argv[1]);
+
+  /* set active flag for specified columns */
+  if( argc >= 4 ) cols = argv[3];
+  FunColumnActivate(fun, cols, NULL);
+
+ +The FunOpen() call sets the +default columns to be all columns in the input file. The +FunColumnActivate() call +then allows the user to control which columns ultimately will be +activated (i.e., in this case, written to the new file). For example: +
+  funtable test.ev foo.ev "pi pha time"
+
+will process only the three columns mentioned, while: +
+  funtable test.ev foo.ev "-time"
+
+will process all columns except "time". + +

+If FunColumnActivate() +is called with a null string, then the environment variable +FUN_COLUMNS will be used to provide a global value, if present. +This is the reason why we call the routine even if no columns +are specified on the command line (see example above), instead +of calling it this way: +

+  /* set active flag for specified columns */
+  if( argc >= 4 ){
+    FunColumnActivate(fun, argv[3], NULL);
+  }
+
+ + + + +

FunColumnLookup - lookup a Funtools column

+ + +
+  #include <funtools.h>
+
+  int FunColumnLookup(Fun fun, char *s, int which,
+                      char **name, int *type, int *mode,
+                      int *offset, int *n, int *width)
+
+
+ + +

+The FunColumnLookup() routine returns information about a named +(or indexed) column. The first argument is the Fun handle associated +with this set of columns. The second argument is the name of the +column to look up. If the name argument is NULL, the argument that +follows is the zero-based index into the column array of the column +for which information should be returned. The next argument is a +pointer to a char *, which will contain the name of the column. The +arguments that follow are the addresses of int values into which +the following information will be returned: +

    +
  • type: data type of column: +
      +
    • A: ASCII characters +
    • B: unsigned 8-bit char +
    • I: signed 16-bit int +
    • U: unsigned 16-bit int (not standard FITS) +
    • J: signed 32-bit int +
    • V: unsigned 32-bit int (not standard FITS) +
    • E: 32-bit float +
    • D: 64-bit float +
    +
  • mode: bit flag status of column, including: +
      +
    • COL_ACTIVE 1 is column activated? +
    • COL_IBUF 2 is column in the raw input data? +
    • COL_PTR 4 is column a pointer to an array? +
    • COL_READ 010 is read mode selected? +
    • COL_WRITE 020 is write mode selected? +
    • COL_REPLACEME 040 is this column being replaced by user data? +
    +
  • offset: byte offset in struct +
  • n: number of elements (i.e. size of vector) in this column +
  • width: size in bytes of this column +
+If the named column exists, the routine returns a positive integer, +otherwise zero is returned. (The positive integer is the index+1 into +the column array where this column was located.) + +If NULL is passed as the return address of one (or more) of these +values, no data is passed back for that information. For +example: +
+  if( !FunColumnLookup(fun, "phas", 0, NULL NULL, NULL, NULL, &npha, NULL) )
+    gerror(stderr, "can't find phas column\n");
+
+only returns information about the size of the phas vector. + + + + +

FunTableRowGet - get Funtools rows

+ + + +
+  #include <funtools.h>
+
+  void *FunTableRowGet(Fun fun, void *rows, int maxrow, char *plist,
+                       int *nrow)
+
+
+ + +

+The FunTableRowGet() routine retrieves rows from a Funtools +binary table or raw event file, and places the values of columns +selected by FunColumnSelect() +into an array of user structs. Selected column values are +automatically converted to the specified user data type (and to native +data format) as necessary. + +

+The first argument is the Fun handle associated with this row data. +The second rows argument is the array of user structs into +which the selected columns will be stored. If NULL is passed, the +routine will automatically allocate space for this array. (This +includes proper allocation of pointers within each struct, if the "@" +pointer type is used in the selection of columns. Note that if you +pass NULL in the second argument, you should free this space using the +standard free() system call when you are finished with the array of +rows.) The third maxrow argument specifies the maximum number +of rows to be returned. Thus, if rows is allocated by the +user, it should be at least of size maxrow*sizeof(evstruct). + +

+The fourth plist argument is a param list string. Currently, +the keyword/value pair "mask=transparent" is supported in the plist +argument. If this string is passed in the call's plist argument, then +all rows are passed back to the user (instead of just rows passing +the filter). This is only useful when +FunColumnSelect() also is +used to specify "$region" as a column to return for each row. In +such a case, rows found within a region have a returned region value +greater than 0 (corresponding to the region id of the region in which +they are located), rows passing the filter but not in a region have +region value of -1, and rows not passing any filter have region +value of 0. Thus, using "mask=transparent" and the returned region +value, a program can process all rows and decide on an action based +on whether a given row passed the filter or not. + +

+The final argument is a pointer to an int variable that will return +the actual number of rows returned. The routine returns a pointer to +the array of stored rows, or NULL if there was an error. (This pointer +will be the same as the second argument, if the latter is non-NULL). +

+  /* get rows -- let routine allocate the row array */
+  while( (buf = (Ev)FunTableRowGet(fun, NULL, MAXROW, NULL, &got)) ){
+    /* process all rows */
+    for(i=0; i<got; i++){
+      /* point to the i'th row */
+      ev = buf+i;
+      /* rearrange some values. etc. */
+      ev->energy = (ev->pi+ev->pha)/2.0;
+      ev->pha = -ev->pha;
+      ev->pi = -ev->pi;
+    }
+    /* write out this batch of rows */
+    FunTableRowPut(fun2, buf, got, 0, NULL);
+    /* free row data */
+    if( buf ) free(buf);
+  }
+
+As shown above, successive calls to +FunTableRowGet() will return the +next set of rows from the input file until all rows have been read, +i.e., the routine behaves like sequential Unix I/O calls such as +fread(). See evmerge example code for a +more complete example. + +

+Note that FunTableRowGet() also can be called as FunEventsGet(), for +backward compatibility. + + + + +

FunTableRowPut - put Funtools rows

+ + +
+
+int FunTableRowPut(Fun fun, void *rows, int nev, int idx, char *plist)
+
+
+ + +The FunTableRowPut() routine writes rows to a FITS binary +table, taking its input from an array of user structs that contain +column values selected by a previous call to +FunColumnSelect(). Selected +column values are automatically converted from native data format to +FITS data format as necessary. + +

+The first argument is the Fun handle associated with this row data. +The second rows argument is the array of user structs to +output. The third nrow argument specifies the number number of +rows to write. The routine will write nrow records, starting +from the location specified by rows. + +

+The fourth idx argument is the index of the first raw input +row to write, in the case where rows from the user buffer are +being merged with their raw input row counterparts (see below). Note +that this idx value is has nothing to do with the +row buffer specified in argument 1. It merely matches the row +being written with its corresponding (hidden) raw row. Thus, if you +read a number of rows, process them, and then write them out all at +once starting from the first user row, the value of idx +should be 0: +

+  Ev ebuf, ev;
+  /* get rows -- let routine allocate the row array */
+  while( (ebuf = (Ev)FunTableRowGet(fun, NULL, MAXROW, NULL, &got)) ){
+    /* process all rows */
+    for(i=0; i<got; i++){
+      /* point to the i'th row */
+      ev = ebuf+i;
+      ...
+    }
+    /* write out this batch of rows, starting with the first */
+    FunTableRowPut(fun2, (char *)ebuf, got, 0, NULL);
+    /* free row data */
+    if( ebuf ) free(ebuf);
+  }
+
+ +

+On the other hand, if you write out the rows one at a time (possibly +skipping rows), then, when writing the i'th row from the input +array of rows, set idx to the value of i: +

+  Ev ebuf, ev;
+  /* get rows -- let routine allocate the row array */
+  while( (ebuf = (Ev)FunTableRowGet(fun, NULL, MAXROW, NULL, &got)) ){
+    /* process all rows */
+    for(i=0; i<got; i++){
+      /* point to the i'th row */
+      ev = ebuf+i;
+      ...
+      /* write out the current (i.e., i'th) row */
+      FunTableRowPut(fun2, (char *)ev, 1, i, NULL);
+    }
+    /* free row data */
+    if( ebuf ) free(ebuf);
+  }
+
+ +

+The final argument is a param list string that is not currently used. +The routine returns the number of rows output. This should be equal +to the value passed in the third nrow +When FunTableRowPut() is first +called for a given binary table, Funtools checks to see of the primary +header has already been written (either by writing a previous row +table or by writing an image.) If not, a dummy primary header is +written to the file specifying that an extension should be expected. +After this, a binary table header is automatically written containing +information about the columns that will populate this table. In +addition, if a +Funtools reference handle +was specified when this table was opened, the parameters from this +Funtools reference handle +are merged into the new binary table header. + +

+In a typical Funtools row loop, you read rows using +FunTableRowGet()() and write +rows using FunTableRowPut(). The columns written by +FunTableRowPut()() are those defined as writable by a previous call to +FunColumnSelect(). If +that call to FunColumnSelect also specified +merge=[update|replace|append], then the entire corresponding +raw input row record will be merged with the output row according +to the merge specification (see +FunColumnSelect() above). + +

+A call to write rows can either be done once, after all rows in +the input batch have been processed, or it can be done (slightly less +efficiently) one row at a time (or anything in between). We do +recommend that you write all rows associated with a given batch of +input rows before reading new rows. This is required if +you are merging the output rows with the raw input rows (since +the raw rows are destroyed with each successive call to get new rows). + +For example: +

+  Ev buf, ev;
+  ...
+  /* get rows -- let routine allocate the row array */
+  while( (buf = (Ev)FunTableRowGet(fun, NULL, MAXROW, NULL, &got)) ){
+    /* point to the i'th row */
+    ev = buf + i;
+    .... process
+  }
+  /* write out this batch of rows */
+  FunTableRowPut(fun2, buf, got, 0, NULL);
+  /* free row data */
+  if( buf ) free(buf);
+  }
+
+ +or + +
+  Ev buf, ev;
+  ...
+  /* get rows -- let routine allocate the row array */
+  while( (buf = (Ev)FunTableRowGet(fun, NULL, MAXROW, NULL, &got)) ){
+    /* process all rows */
+    for(i=0; i<got; i++){
+      /* point to the i'th row */
+      ev = buf + i;
+      ... process
+      /* write out this batch of rows with the new column */
+      if( dowrite )
+        FunTableRowPut(fun2, buf, 1, i, NULL);
+    }
+    /* free row data */
+    if( buf ) free(buf);
+  }
+
+ +

+Note that the difference between these calls is that the first one +outputs got rows all at once and therefore passes +idx=0 in argument four, so that merging starts at the first raw +input row. In the second case, a check it made on each row to see +if it needs to be output. If so, the value of idx is passed as +the value of the i variable which points to the current row +being processed in the batch of input rows. + +

+As shown above, successive calls to +FunTableRowPut() will write +rows sequentially. When you are finished writing all rows in a +table, you should call +FunFlush() to write out the FITS +binary table padding. However, this is not necessary if you +subsequently call FunClose() without doing any other I/O to the FITS +file. + +

+Note that FunTableRowPut() also can be called as FunEventsPut(), for +backward compatibility. + + + + +

FunParamGet - get a Funtools param value

+ + + +
+  #include <funtools.h>
+
+  int FunParamGetb(Fun fun, char *name, int n, int defval, int *got)
+
+  int FunParamGeti(Fun fun, char *name, int n, int defval, int *got)
+
+  double FunParamGetd(Fun fun, char *name, int n, double defval, int *got)
+
+  char *FunParamGets(Fun fun, char *name, int n, char *defval, int *got)
+
+
+ + +

+The four routines FunParamGetb(), FunParamGeti(), +FunParamGetd(), and FunParamGets(), return the value of +a FITS header parameter as a boolean, int, double, and string, +respectively. The string returned by FunParamGets() is a malloc'ed +copy of the header value and should be freed when no longer needed. + +

+The first argument is the Fun handle associated with the FITS header +being accessed. Normally, the header is associated with the FITS +extension that you opened with FunOpen(). However, you can use +FunInfoPut() to specify access of the primary header. In particular, +if you set the FUN_PRIMARYHEADER parameter to 1, then the primary +header is used for all parameter access until the value is reset to +0. For example: +

+  int val;
+  FunParamGeti(fun, "NAXIS", 1, 0, &got);              # current header
+  val=1;
+  FunInfoPut(fun, FUN_PRIMARYHEADER, &val, 0);         # switch to ...
+  FunParamGeti(fun, "NAXIS", 1, 0, &got);              # ... primary header
+  FunParamGeti(fun, "NAXIS", 2, 0, &got);              # ... primary header
+  val=0;
+  FunInfoPut(fun, FUN_PRIMARYHEADER, &val, 0);         # switch back to ...
+  FunParamGeti(fun, "NAXIS", 2, 0, &got);              # current header
+
+ +

+Alternatively, you can use the FUN_PRIMARY macro to access parameters +from the primary header on a per-parameter basis: +

+  FunParamGeti(fun, "NAXIS1", 0, 0, &got);              # current header
+  FunParamGeti(FUN_PRIMARY(fun), "NAXIS1", 0, 0, &got); # primary header
+
+NB: FUN_PRIMARY is deprecated. +It makes use of a global parameter and therefore will not not +appropriate for threaded applications, when we make funtools +thread-safe. We recommend use of FunInfoPut() to switch between the +extension header and the primary header. + +

+For output data, access to the primary header is only possible until +the header is written out, which usually takes place when the first +data are written. + +

+The second argument is the name of the parameter to access. The third +n argument, if non-zero, is an integer that will be added as a +suffix to the parameter name. This makes it easy to use a simple loop +to process parameters having the same root name. For example, to +gather up all values of TLMIN and TLMAX for each column in a binary +table, you can use: +

+  for(i=0, got=1; got; i++){
+    fun->cols[i]->tlmin = (int)FunParamGeti(fun, "TLMIN", i+1, 0.0, &got);
+    fun->cols[i]->tlmax = (int)FunParamGeti(fun, "TLMAX", i+1, 0.0, &got);
+  }
+
+ +

+The fourth defval argument is the default value to return if +the parameter does not exist. Note that the data type of this +parameter is different for each specific FunParamGet() call. The final +got argument will be 0 if no param was found. Otherwise the +data type of the parameter is returned as follows: FUN_PAR_UNKNOWN +('u'), FUN_PAR_COMMENT ('c'), FUN_PAR_LOGICAL ('l'), FUN_PAR_INTEGER +('i'), FUN_PAR_STRING ('s'), FUN_PAR_REAL ('r'), FUN_PAR_COMPLEX ('x'). + +

+These routines return the value of the header parameter, or the +specified default value if the header parameter does not exist. The +returned value is a malloc'ed string and should be freed when no +longer needed. + +

+By default, FunParamGets() returns the string value of the +named parameter. However, you can use FunInfoPut() to retrieve the +raw 80-character FITS card instead. In particular, if you set the +FUN_RAWPARAM parameter to 1, then card images will be returned by +FunParamGets() until the value is reset to 0. + +

+Alternatively, if the FUN_RAW macro is applied to the name, then the +80-character raw FITS card is returned instead. +NB: FUN_RAW is deprecated. +It makes use of a global parameter and therefore will not not +appropriate for threaded applications, when we make funtools +thread-safe. We recommend use of FunInfoPut() to switch between the +extension header and the primary header. + +

+Note that in addition to the behaviors described above, the +routine FunParamGets() will return the 80 raw characters of the +nth FITS card (including the comment) if name is specified as +NULL and n is positive. For example, to loop through all FITS +header cards in a given extension and print out the raw card, use: +

+  for(i=1; ;i++){
+    if( (s = FunParamGets(fun, NULL, i, NULL, &got)) ){
+      fprintf(stdout, "%.80s\n", s);
+      free(s);
+    }
+    else{
+      break;
+    }
+  }
+
+ + + + +

FunParamPut - put a Funtools param value

+ + + +
+  #include <funtools.h>
+
+  int FunParamPutb(Fun fun, char *name, int n, int value, char *comm,
+                   int append)
+
+  int FunParamPuti(Fun fun, char *name, int n, int value, char *comm,
+                   int append)
+
+  int FunParamPutd(Fun fun, char *name, int n, double value, int prec,
+                   char *comm, int append)
+
+  int FunParamPuts(Fun fun, char *name, int n, char *value, char *comm,
+                   int append)
+
+
+ + +

+The four routines FunParamPutb(), FunParamPuti(), +FunParamPutd(), and FunParamPuts(), will set the value +of a FITS header parameter as a boolean, int, double, and string, +respectively. + +

+The first argument is the Fun handle associated with the FITS header +being accessed. Normally, the header is associated with the FITS +extension that you opened with FunOpen(). +However, you can use FunInfoPut() to specify that use of the primary +header. In particular, if you set the FUN_PRIMARYHEADER parameter to +1, then the primary header is used for all parameter access until the +value is reset to 0. For example: +

+  int val;
+  FunParamPuti(fun, "NAXIS1", 0, 10, NULL, 1);       # current header
+  val=1;
+  FunInfoPut(fun, FUN_PRIMARYHEADER, &val, 0);       # switch to ...
+  FunParamPuti(fun, "NAXIS1", 0, 10, NULL, 1);       # primary header
+
+(You also can use the deprecated FUN_PRIMARY macro, to access +parameters from the primary header.) + +

+The second argument is the name of the parameter. ( +In accordance with FITS standards, the special names COMMENT +and HISTORY, as well as blank names, are output without the "= " +value indicator in columns 9 and 10. + +

+The third n argument, if non-zero, is an integer that will be +added as a suffix to the parameter name. This makes it easy to use a +simple loop to process parameters having the same root name. For +example, to set the values of TLMIN and TLMAX for each column in a +binary table, you can use: +

+  for(i=0; i<got; i++){
+    FunParamPutd(fun, "TLMIN", i+1, tlmin[i], 7, "min column val", 1);
+    FunParamPutd(fun, "TLMAX", i+1, tlmax[i], 7, "max column val", 1);
+  }
+
+ +

+The fourth defval argument is the value to set. Note that the +data type of this argument is different for each specific +FunParamPut() call. The comm argument is the comment +string to add to this header parameter. Its value can be NULL. The +final append argument determines whether the parameter is added +to the header if it does not exist. If set to a non-zero value, the +header parameter will be appended to the header if it does not exist. +If set to 0, the value will only be used to change an existing parameter. + +

+Note that the double precision routine FunParamPutd() supports an +extra prec argument after the value argument, in order +to specify the precision when converting the double value to ASCII. In +general a 20.[prec] format is used (since 20 characters are alloted to +a floating point number in FITS) as follows: if the double value being +put to the header is less than 0.1 or greater than or equal to +10**(20-2-[prec]), then %20.[prec]e format is used (i.e., scientific +notation); otherwise %20.[prec]f format is used (i.e., numeric +notation). + +

+As a rule, parameters should be set before writing the table or image. +It is, however, possible to update the value of an existing +parameter after writing an image or table (but not to add a new +one). Such updating only works if the parameter already exists and if +the output file is seekable, i.e. if it is a disk file or is stdout +being redirected to a disk file. + +

+It is possible to add a new parameter to a header after the data has +been written, but only if space has previously been reserved. To reserve +space, add a blank parameter whose value is the name of the parameter you +eventually will update. Then, when writing the new parameter, specify a +value of 2 for the append flag. The parameter writing routine will +first look to update an existing parameter, as usual. If an existing +parameter is not found, an appropriately-valued blank parameter will be +searched for and replaced. For example: +

+  /* add blank card to be used as a place holder for IPAR1 update */
+  FunParamPuts(fun, NULL, 0, "IPAR1", "INTEGER Param", 0);
+  ...
+  /* write header and data */
+  FunTableRowPut(fun, events, got, 0, NULL);
+  ...
+  /* update param in file after writing data -- note append = 2 here */
+  FunParamPuti(fun, "IPAR", 1, 400, "INTEGER Param", 2);
+
+ +

+The parameter routines return a 1 if the routine was successful and a 0 on +failure. In general, the major reason for failure is that you did not +set the append argument to a non-zero value and the parameter did not +already exist in the file. + + + + +

FunInfoGet - get information from Funtools struct

+ + + +
+  #include <funtools.h>
+
+  int FunInfoGet(Fun fun, int type, char *addr, ...)
+
+
+ + +

+The FunInfoGet() routine returns information culled from the +Funtools structure. The first argument is the Fun handle from which +information is to be retrieved. This first required argument is followed +by a variable length list of pairs of arguments. Each pair consists +of an integer representing the type of information to retrieve and the +address where the information is to be stored. The list is terminated by a 0. +The routine returns the number of get actions performed. + +

+The full list of available information is described below. Please note +that only a few of these will be useful to most application developers. +For imaging applications, the most important types are: +

+  FUN_SECT_DIM1   int  /* dim1 for section */
+  FUN_SECT_DIM2   int  /* dim2 for section */
+  FUN_SECT_BITPIX int  /* bitpix for section */
+
+These would be used to determine the dimensions and data type of image +data retrieved using the +FunImageGet() routine. For +example: +
+  /* extract and bin the data section into an image buffer */
+  buf = FunImageGet(fun, NULL, NULL);
+  /* get required information from funtools structure.
+     this should come after the FunImageGet() call, in case the call
+     changed sect_bitpix */
+  FunInfoGet(fun,
+             FUN_SECT_BITPIX,  &bitpix,
+             FUN_SECT_DIM1,    &dim1,
+             FUN_SECT_DIM2,    &dim2,
+             0);
+  /* loop through pixels and reset values below limit to value */
+  for(i=0; i<dim1*dim2; i++){
+    switch(bitpix){
+    case 8:
+      if( cbuf[i] <= blimit ) cbuf[i] = bvalue;
+    ...
+  }
+
+It is important to bear in mind that the call to +FunImageGet() +can change the value of FUN_SECT_BITPIX (e.g. if "bitpix=n" is passed +in the param list). Therefore, a call to +FunInfoGet() +should be made after the call to +FunImageGet(), +in order to retrieve the updated bitpix value. +See the imblank example code for more +details. + +

+It also can be useful to retrieve the World Coordinate System +information from the Funtools structure. Funtools uses the the WCS +Library developed by Doug Mink at SAO, which is available +here. +(More information about the WCSTools project in general can be found +here.) +The FunOpen() routine initializes +two WCS structures that can be used with this WCS Library. +Applications can retrieve either of these two WCS structures using +FunInfoGet(): +

+  FUN_WCS  struct WorldCoor * /* wcs structure, for image coordinates*/
+  FUN_WCS0 struct WorldCoor * /* wcs structure, for physical coordinates */
+
+The structure retrieved by FUN_WCS is a WCS library handle containing +parameters suitable for use with image coordinates, regardless of whether the +data are images or tables. For this structure, the WCS reference point +(CRPIX) has been converted to image coordinates if the underlying file +is a table (and therefore in physical coordinates). You therefore must +ensure that the positions being passed to a routine like pix2wcs are in +image coordinates. The FUN_WCS0 structure has not had its WCS +reference point converted to image coordinates. It therefore is useful +when passing processing physical coordinates from a table. + +

+Once a WCS structure has been retrieved, it can be used as the first +argument to the WCS library routines. (If the structure is NULL, no +WCS information was contained in the file.) The two important WCS routines +that Funtools uses are: +

+  #include <wcs.h>
+  void pix2wcs (wcs,xpix,ypix,xpos,ypos)
+    struct WorldCoor *wcs; /* World coordinate system structure */
+    double xpix,ypix;      /* x and y coordinates in pixels */
+    double *xpos,*ypos;    /* RA and Dec in degrees (returned) */
+
+ +which converts pixel coordinates to sky coordinates, and: + +
+  void wcs2pix (wcs, xpos, ypos, xpix, ypix, offscl)
+    struct WorldCoor *wcs; /* World coordinate system structure */
+    double xpos,ypos;      /* World coordinates in degrees */
+    double *xpix,*ypix;    /* coordinates in pixels */
+    int *offscl;           /* 0 if within bounds, else off scale */
+
+which converts sky coordinates to pixel coordinates. Again, please note +that the wcs structure returned by FUN_WCS assumes that image coordinates +are passed to the pix2wcs routine, while FUN_WCS0 assumes that physical +coordinates are passed. + +

+Note that funtools.h file automatically includes wcs.h. An example +program that utilizes these WCS structure to call WCS Library routines +is twcs.c. + +

+The following is the complete list of information that can be returned: +

+  name            type            comment
+  ---------       --------        ---------------------------------------------
+  FUN_FNAME     char *            /* file name */
+  FUN_GIO       GIO               /* gio handle */
+  FUN_HEADER    FITSHead          /* fitsy header struct */
+  FUN_TYPE      int               /* TY_TABLE,TY_IMAGE,TY_EVENTS,TY_ARRAY */
+  FUN_BITPIX    int               /* bits/pixel in file */
+  FUN_MIN1      int               /* tlmin of axis1 -- tables */
+  FUN_MAX1      int               /* tlmax of axis1 -- tables */
+  FUN_MIN2      int               /* tlmin of axis2 -- tables */
+  FUN_MAX2      int               /* tlmax of axis2 -- tables */
+  FUN_DIM1      int               /* dimension of axis1 */
+  FUN_DIM2      int               /* dimension of axis2 */
+  FUN_ENDIAN    int               /* 0=little, 1=big endian */
+  FUN_FILTER    char *            /* supplied filter */
+  FUN_IFUN      FITSHead          /* pointer to reference header */
+  FUN_IFUN0     FITSHead          /* same as above, but no reset performed */
+  /* image information */
+  FUN_DTYPE     int               /* data type for images */
+  FUN_DLEN      int               /* length of image in bytes */
+  FUN_DPAD      int               /* padding to end of extension */
+  FUN_DOBLANK   int               /* was blank keyword defined? */
+  FUN_BLANK     int               /* value for blank */
+  FUN_SCALED    int               /* was bscale/bzero defined? */
+  FUN_BSCALE    double            /* bscale value */
+  FUN_BZERO     double            /* bzero value */
+  /* table information */
+  FUN_NROWS     int               /* number of rows in file (naxis2) */
+  FUN_ROWSIZE   int               /* size of user row struct */
+  FUN_BINCOLS   char *            /* specified binning columns */
+  FUN_OVERFLOW  int               /* overflow detected during binning? */
+  /* array information */
+  FUN_SKIP      int               /* bytes to skip in array header */
+  /* section information */
+  FUN_SECT_X0   int               /* low dim1 value of section */
+  FUN_SECT_X1   int               /* hi dim1 value of section */
+  FUN_SECT_Y0   int               /* low dim2 value of section */
+  FUN_SECT_Y1   int               /* hi dim2 value of section */
+  FUN_SECT_BLOCK int              /* section block factor */
+  FUN_SECT_BTYPE int              /* 's' (sum), 'a' (average) for binning */
+  FUN_SECT_DIM1 int               /* dim1 for section */
+  FUN_SECT_DIM2 int               /* dim2 for section */
+  FUN_SECT_BITPIX int             /* bitpix for section */
+  FUN_SECT_DTYPE int              /* data type for section */
+  FUN_RAWBUF    char *            /* pointer to raw row buffer */
+  FUN_RAWSIZE   int               /* byte size of raw row records */
+  /* column  information */
+  FUN_NCOL      int               /* number of row columns defined */
+  FUN_COLS      FunCol            /* array of row columns */
+  /* WCS information */
+  FUN_WCS       struct WorldCoor * /* wcs structure, converted for images*/
+  FUN_WCS0      struct WorldCoor * /* wcs structure, not converted */
+
+ +

+Row applications would not normally need any of this information. +An example of how these values can be used in more complex programs is +the evnext example code. In this program, the +time value for each row is changed to be the value of the succeeding +row. The program thus reads the time values for a batch of rows, +changes the time values to be the value for the succeeding row, and +then merges these changed time values back with the other columns to +the output file. It then reads the next batch, etc. + +

+This does not work for the last row read in each batch, since there +is no succeeding row until the next batch is read. Therefore, the +program saves that last row until it has read the next batch, then +processes the former before starting on the new batch. In order to +merge the last row successfully, the code uses FUN_RAWBUF to save +and restore the raw input data associated with each batch of +rows. Clearly, this requires some information about how funtools +works internally. We are happy to help you write such programs as the +need arises. + + + + +

FunInfoPut - put information into a Funtools struct

+ + + +
+  #include <funtools.h>
+
+  int FunInfoPut(Fun fun, int type, char *addr, ...)
+
+
+ + +

+The FunInfoPut() routine puts information into a Funtools +structure. The first argument is the Fun handle from which +information is to be retrieved. After this first required argument +comes a variable length list of pairs of arguments. Each pair consists +of an integer representing the type of information to store and the +address of the new information to store in the struct. The variable +list is terminated by a 0. The routine returns the number of put +actions performed. + +

+The full list of available information is described above with the +FunInfoPut() routine. Although +use of this routine is expected to be uncommon, there is one +important situation in which it plays an essential part: writing +multiple extensions to a single output file. + +

+For input, multiple extensions are handled by calling +FunOpen() for each extension to be +processed. When opening multiple inputs, it sometimes is the case that +you will want to process them and then write them (including their +header parameters) to a single output file. To accomplish this, you +open successive input extensions using +FunOpen() and then call +FunInfoPut() to set the +Funtools reference handle +of the output file to that of the newly opened input extension: +

+  /* open a new input extension */
+  ifun=FunOpen(tbuf, "r", NULL)) )
+  /* make the new extension the reference handle for the output file */
+  FunInfoPut(ofun, FUN_IFUN, &ifun, 0);
+
+ +Resetting FUN_IFUN has same effect as when a funtools handle is passed +as the final argument to +FunOpen(). The state of the output +file is reset so that a new extension is ready to be written. +Thus, the next I/O call on the output extension will output the +header, as expected. + +

+For example, in a binary table, after resetting FUN_IFUN you can then +call FunColumnSelect() to +select the columns for output. When you then call +FunImagePut() or FunTableRowPut(), a new +extension will be written that contains the header parameters from the +reference extension. Remember to call +FunFlush() to complete output of a +given extension. + +

+A complete example of this capability is given +in the evcol example code. +The central algorithm is: +

    +
  • open the output file without a reference handle +
  • loop: open each input extension in turn +
      +
    • set the reference handle for output to the newly opened input extension +
    • read the input rows or image and perform processing +
    • write new rows or image to the output file +
    • flush the output +
    • close input extension +
    +
  • close output file +
+Note that FunFlush() is called +after processing each input extension in order to ensure that the +proper padding is written to the output file. A call to +FunFlush() also ensures that the +extension header is written to the output file in the case where there +are no rows to output. + +

+If you wish to output a new extension without using a +Funtools reference handle, you can +call FunInfoPut() to reset the FUN_OPS value directly. For a binary +table, you would then call FunColumnSelect() to set up the columns for +this new extension. +

+  /* reset the operations performed on this handle */
+  int ops=0;
+  FunInfoPut(ofun, FUN_OPS, &ops, 0);
+  FunColumnSelect(fun, sizeof(EvRec), NULL,
+                  "MYCOL", "J", "w", FUN_OFFSET(Ev, mycol),
+                  NULL);
+
+Once the FUN_OPS variable has been reset, the next I/O call on the +output extension will output the header, as expected. + + + + +

FunFlush - flush data to output file

+ + + +
+  #include <funtools.h>
+
+  void FunFlush(Fun fun, char *plist)
+
+
+ + +

+The FunFlush routine will flush data to a FITS output file. In +particular, it can be called after all rows have been written (using +the FunTableRowPut() routine) +in order to add the null padding that is required to complete a FITS +block. It also should be called after completely writing an image using +FunImagePut() or after writing +the final row of an image using +FunTableRowPut(). + +

+The plist (i.e., parameter list) argument is a string +containing one or more comma-delimited keyword=value +parameters. If the plist string contains the parameter +"copy=remainder" and the file was opened with a reference file, which, +in turn, was opened for extension copying (i.e. the input +FunOpen() mode also was "c" or "C"), +then FunFlush also will copy the remainder of the FITS extensions from +the input reference file to the output file. This normally would be +done only at the end of processing. + +

+Note that FunFlush() is called +with "copy=remainder" in the mode string by FunClose(). This means +that if you close the output file before the reference input file, it +is not necessary to call +FunFlush() explicitly, unless you +are writing more than one extension. See the +evmerge example code. However, it is safe to +call FunFlush() more than once +without fear of re-writing either the padding or the copied +extensions. + +

+In addition, if FunFlush() is +called on an output file with the plist set to "copy=reference" and if +the file was opened with a reference file, the reference extension is +written to the output file. This mechanism provides a simple way to +copy input extensions to an output file without processing the former. +For example, in the code fragment below, an input extension is set to +be the reference file for a newly opened output extension. If that +reference extension is not a binary table, it is written to the output +file: +

+  /* process each input extension in turn */
+  for(ext=0; ;ext++){
+    /* get new extension name */
+    sprintf(tbuf, "%s[%d]", argv[1], ext);
+    /* open input extension -- if we cannot open it, we are done */
+    if( !(ifun=FunOpen(tbuf, "r", NULL)) )
+      break;
+    /* make the new extension the reference handle for the output file */
+    FunInfoPut(ofun, FUN_IFUN, &ifun, 0);
+    /* if its not a binary table, just write it out */
+    if( !(s=FunParamGets(ifun, "XTENSION", 0, NULL, &got)) || 
+      strcmp(s, "BINTABLE")){
+      if( s ) free(s);
+      FunFlush(ofun, "copy=reference");
+      FunClose(ifun);
+      continue;
+    }
+    else{
+      /* process binary table */
+      ....
+    }
+  }
+
+ + + + +

FunClose - close a Funtools data file

+ + + +
+  #include <funtools.h>
+
+  void FunClose(Fun fun)
+
+
+ + +

+The FunClose() routine closes a previously-opened Funtools data +file, freeing control structures. If a +Funtools reference handle +was passed to +the FunOpen() call for this file, +and if copy mode also was specified for that file, then +FunClose() also will copy the +remaining extensions from the input file to the output file (if the +input file still is open). Thus, we recommend always closing the +output Funtools file before the input file. (Alternatively, +you can call FunFlush() +explicitly). + + + + +

FunRef: the Funtools Reference Handle

+ + +

Summary

+A description of how to use a Funtools reference handle to connect a +Funtools input file to an output file. + + +

Description

+

+The Funtools reference handle connects a Funtools input file to a +Funtools output file so that parameters (or even whole extensions) can +be copied from the one to the other. To make the connection, the Funtools +handle of the input file is passed to the +final argument of the +FunOpen() call for the output file: +

+  if( !(ifun = FunOpen(argv[1], "r", NULL)) )
+    gerror(stderr, "could not FunOpen input file: %s\n", argv[1]);
+  if( !(ofun = FunOpen(argv[2], "w", ifun)) )
+    gerror(stderr, "could not FunOpen output file: %s\n", argv[2]);
+
+It does not matter what type of input or output file (or extension) is +opened, or whether they are the same type. When the output image or +binary table is written using +FunImagePut() +or +FunTableRowPut() +an appropriate header will be written first, with parameters copied +from the input extension. Of course, invalid parameters will be +removed first, e.g., if the input is a binary table and the output is +an image, then binary table parameters such as TFORM, TUNIT, +etc. parameters will not be copied to the output. + +

+Use of a reference handle also allows default values to be passed +to +FunImagePut() in order to +write out an output image with the same dimensions and data type +as the input image. To use the defaults from the input, a value +of 0 is entered for dim1, dim2, and bitpix. For example: +

+  fun = FunOpen(argv[1], "r", NULL);
+  fun2 = FunOpen(argv[2], "w", fun);
+  buf = FunImageGet(fun, NULL, NULL);
+  ... process image data ...
+  FunImagePut(fun2, buf, 0, 0, 0, NULL);
+
+Of course, you often want to get information about the data type +and dimensions of the image for processing. The above code +is equivalent to the following: +
+  fun = FunOpen(argv[1], "r", NULL);
+  fun2 = FunOpen(argv[2], "w", fun);
+  buf = FunImageGet(fun, NULL, NULL);
+  FunInfoGet(fun, FUN_SECT_DIM1, &dim1, FUN_SECT_DIM2, &dim2, 
+             FUN_SECT_BITPIX, &bitpix, 0);
+  ... process image data ...
+  FunImagePut(fun2, buf, dim1, dim2, bitpix, NULL);
+
+ +

+It is possible to change the reference handle for a given output Funtools +handle using the +FunInfoPut() routine: +

+  /* make the new extension the reference handle for the output file */
+  FunInfoPut(fun2, FUN_IFUN, &fun, 0);
+
+When this is done, Funtools specially resets the output file to start +a new output extension, which is connected to the new input reference +handle. You can use this mechanism to process multiple input extensions +into a single output file, by successively opening the former and +setting the reference handle for the latter. For example: +
+  /* open a new output FITS file */
+  if( !(fun2 = FunOpen(argv[2], "w", NULL)) )
+    gerror(stderr, "could not FunOpen output file: %s\n", argv[2]);
+  /* process each input extension in turn */
+  for(ext=0; ;ext++){
+    /* get new extension name */
+    sprintf(tbuf, "%s[%d]", argv[1], ext);
+    /* open it -- if we cannot open it, we are done */
+    if( !(fun=FunOpen(tbuf, "r", NULL)) )
+      break;
+    /* make the new extension the reference handle for the output file */
+    FunInfoPut(fun2, FUN_IFUN, &fun, 0);
+    ... process ...
+    /* flush output extension (write padding, etc.) */
+    FunFlush(fun2, NULL);
+    /* close the input extension */
+    FunClose(fun);
+  }
+
+In this example, the output file is opened first. Then each successive +input extension is opened, and the output reference handle is set to +the newly opened input handle. After data processing is performed, the +output extension is flushed and the input extension is closed, in +preparation for the next input extension. +

+Finally, a reference handle can be used to copy other extensions from +the input file to the output file. Copy of other extensions is +controlled by adding a "C" or "c" to the mode string of the +FunOpen() +call of the input reference file. If "C" is specified, then +other extensions are always copied (i.e., copy is forced by the +application). If "c" is used, then other extensions are copied if the +user requests copying by adding a plus sign "+" to the extension name +in the bracket specification. For example, the funtable +program utilizes user-specified "c" mode so that the second example +below will copy all extensions: +

+  # copy only the EVENTS extension
+  csh> funtable "test.ev[EVENTS,circle(512,512,10)]" foo.ev
+  # copy ALL extensions
+  csh> funtable "test.ev[EVENTS+,circle(512,512,10)]" foo.ev
+
+When extension copy is specified in the input file, the call to +FunOpen() +on the input file delays the actual file open until the output file +also is opened (or until I/O is performed on the input file, which +ever happens first). Then, when the output file is opened, the input +file is also opened and input extensions are copied to the output +file, up to the specific extension being opened. Processing of input +and output extensions then proceed. +

+When extension processing is complete, the remaining extensions need to +be copied from input to output. This can be done explicitly, using the +FunFlush() +call with the "copy=remaining" plist: +

+  FunFlush(fun, "copy=remaining");
+
+Alternatively, this will happen automatically, if the output file +is closed before the input file: +
+  /* we could explicitly flush remaining extensions that need copying */
+  /* FunFlush(fun2, "copy=remaining"); */
+  /* but if we close output before input, end flush is done automatically  */
+  FunClose(fun2);
+  FunClose(fun);
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Go to Funtools Help Index + +

Last updated: December 1, 2005
+ + + diff --git a/doc/pod/funcalc.pod b/doc/pod/funcalc.pod new file mode 100644 index 0000000..f63cfc8 --- /dev/null +++ b/doc/pod/funcalc.pod @@ -0,0 +1,572 @@ +=pod + +=head1 NAME + + + +B + + +=head1 SYNOPSIS + + + + + +funcalc [-n] [-a argstr] [-e expr] [-f file] [-l link] [-p prog] [oname [columns]] + + + + + +=head1 OPTIONS + + + + + + -a argstr # user arguments to pass to the compiled program + -e expr # funcalc expression + -f file # file containing funcalc expression + -l libs # libs to add to link command + -n # output generated code instead of compiling and executing + -p prog # generate named program, no execution + -u # die if any variable is undeclared (don't auto-declare) + + + + +=head1 DESCRIPTION + + + + +B is a calculator program that allows arbitrary +expressions to be constructed, compiled, and executed on columns in a +Funtools table (FITS binary table or raw event file). It works by +integrating user-supplied expression(s) into a template C program, +then compiling and executing the program. B expressions +are C statements, although some important simplifications (such +as automatic declaration of variables) are supported. + + +B expressions can be specified in three ways: on the +command line using the B<-e [expression]> switch, in a file using +the B<-f [file]> switch, or from stdin (if neither B<-e> nor +B<-f> is specified). Of course a file containing B +expressions can be read from stdin. + + +Each invocation of B requires an input Funtools table +file to be specified as the first command line argument. The output +Funtools table file is the second optional argument. It is needed only +if an output FITS file is being created (i.e., in cases where the +B expression only prints values, no output file is +needed). If input and output file are both specified, a third optional +argument can specify the list of columns to activate (using +FunColumnActivate()). Note +that B determines whether or not to generate code for +writing an output file based on the presence or absence of an +output file argument. + + +A B expression executes on each row of a table and +consists of one or more C statements that operate on the columns of +that row (possibly using temporary variables). Within an expression, +reference is made to a column of the B row using the C +struct syntax B[colname]>, e.g. cur->x, cur->pha, etc. +Local scalar variables can be defined using C declarations at very the +beginning of the expression, or else they can be defined automatically +by B (to be of type double). Thus, for example, a swap of +columns x and y in a table can be performed using either of the +following equivalent B expressions: + + + double temp; + temp = cur->x; + cur->x = cur->y; + cur->y = temp; + + +or: + + + temp = cur->x; + cur->x = cur->y; + cur->y = temp; + + +When this expression is executed using a command such as: + + funcalc -f swap.expr itest.ev otest.ev + +the resulting file will have values of the x and y columns swapped. + + +By default, the data type of the variable for a column is the same as +the data type of the column as stored in the file. This can be changed +by appending ":[dtype]" to the first reference to that column. In the +example above, to force x and y to be output as doubles, specify the +type 'D' explicitly: + + temp = cur->x:D; + cur->x = cur->y:D; + cur->y = temp; + + +Data type specifiers follow standard FITS table syntax for defining +columns using TFORM: + + +=over 4 + + + + +=item * + +A: ASCII characters + + +=item * + +B: unsigned 8-bit char + + +=item * + +I: signed 16-bit int + + +=item * + +U: unsigned 16-bit int (not standard FITS) + + +=item * + +J: signed 32-bit int + + +=item * + +V: unsigned 32-bit int (not standard FITS) + + +=item * + +E: 32-bit float + + +=item * + +D: 64-bit float + + +=item * + +X: bits (treated as an array of chars) + + +=back + + +Note that only the first reference to a column should contain the +explicit data type specifier. + + +Of course, it is important to handle the data type of the columns +correctly. One of the most frequent cause of error in B +programming is the implicit use of the wrong data type for a column in +expression. For example, the calculation: + + dx = (cur->x - cur->y)/(cur->x + cur->y); + +usually needs to be performed using floating point arithmetic. In +cases where the x and y columns are integers, this can be done by +reading the columns as doubles using an explicit type specification: + + dx = (cur->x:D - cur->y:D)/(cur->x + cur->y); + + +Alternatively, it can be done using C type-casting in the expression: + + dx = ((double)cur->x - (double)cur->y)/((double)cur->x + (double)cur->y); + + + +In addition to accessing columns in the current row, reference also +can be made to the B row using B[colname]>, +and to the B row using B[colname]>. Note that if +B[colname]> is specified in the B +expression, the very first row is not processed. If +B[colname]> is specified in the B +expression, the very last row is not processed. In this way, +B and B are guaranteed always to point to valid +rows. For example, to print out the values of the current x column +and the previous y column, use the C fprintf function in a +B expression: + + fprintf(stdout, "%d %d\n", cur->x, prev->y); + + + +New columns can be specified using the same B[colname]> +syntax by appending the column type (and optional tlmin/tlmax/binsiz +specifiers), separated by colons. For example, cur->avg:D will define +a new column of type double. Type specifiers are the same those +used above to specify new data types for existing columns. + + +For example, to create and output a new column that is the average value of the +x and y columns, a new "avg" column can be defined: + + cur->avg:D = (cur->x + cur->y)/2.0 + +Note that the final ';' is not required for single-line expressions. + + +As with FITS TFORM data type specification, the column data type +specifier can be preceded by a numeric count to define an array, e.g., +"10I" means a vector of 10 short ints, "2E" means two single precision +floats, etc. A new column only needs to be defined once in a +B expression, after which it can be used without +re-specifying the type. This includes reference to elements of a +column array: + + + cur->avg[0]:2D = (cur->x + cur->y)/2.0; + cur->avg[1] = (cur->x - cur->y)/2.0; + + + +The 'X' (bits) data type is treated as a char array of dimension +(numeric_count/8), i.e., 16X is processed as a 2-byte char array. Each +8-bit array element is accessed separately: + + cur->stat[0]:16X = 1; + cur->stat[1] = 2; + +Here, a 16-bit column is created with the MSB is set to 1 and the LSB set to 2. + + +By default, all processed rows are written to the specified output +file. If you want to skip writing certain rows, simply execute the C +"continue" statement at the end of the B expression, +since the writing of the row is performed immediately after the +expression is executed. For example, to skip writing rows whose +average is the same as the current x value: + + + cur->avg[0]:2D = (cur->x + cur->y)/2.0; + cur->avg[1] = (cur->x - cur->y)/2.0; + if( cur->avg[0] == cur->x ) + continue; + + + +If no output file argument is specified on the B command +line, no output file is opened and no rows are written. This is useful +in expressions that simply print output results instead of generating +a new file: + + fpv = (cur->av3:D-cur->av1:D)/(cur->av1+cur->av2:D+cur->av3); + fbv = cur->av2/(cur->av1+cur->av2+cur->av3); + fpu = ((double)cur->au3-cur->au1)/((double)cur->au1+cur->au2+cur->au3); + fbu = cur->au2/(double)(cur->au1+cur->au2+cur->au3); + fprintf(stdout, "%f\t%f\t%f\t%f\n", fpv, fbv, fpu, fbu); + +In the above example, we use both explicit type specification +(for "av" columns) and type casting (for "au" columns) to ensure that +all operations are performed in double precision. + + +When an output file is specified, the selected input table is +processed and output rows are copied to the output file. Note that +the output file can be specified as "stdout" in order to write the +output rows to the standard output. If the output file argument is +passed, an optional third argument also can be passed to specify which +columns to process. + + +In a FITS binary table, it sometimes is desirable to copy all of the +other FITS extensions to the output file as well. This can be done by +appending a '+' sign to the name of the extension in the input file +name. See B for a related example. + + +B works by integrating the user-specified expression +into a template C program called tabcalc.c. +The completed program then is compiled and executed. Variable +declarations that begin the B expression are placed in +the local declaration section of the template main program. All other +lines are placed in the template main program's inner processing +loop. Other details of program generation are handled +automatically. For example, column specifiers are analyzed to build a +C struct for processing rows, which is passed to +FunColumnSelect() and used +in FunTableRowGet(). If +an unknown variable is used in the expression, resulting in a +compilation error, the program build is retried after defining the +unknown variable to be of type double. + + +Normally, B expression code is added to +B row processing loop. It is possible to add code +to other parts of the program by placing this code inside +special directives of the form: + + [directive name] + ... code goes here ... + end + + +The directives are: + + +=over 4 + + + + +=item * + +B add code and declarations in global space, before the main routine. + + + +=item * + +B add declarations (and code) just after the local declarations in +main + + + +=item * + +B add code just before entering the main row processing loop + + + +=item * + +B add code just after exiting the main row processing loop + + +=back + + + +Thus, the following B expression will declare global +variables and make subroutine calls just before and just after the +main processing loop: + + global + double v1, v2; + double init(void); + double finish(double v); + end + before + v1 = init(); + end + ... process rows, with calculations using v1 ... + after + v2 = finish(v1); + if( v2 < 0.0 ){ + fprintf(stderr, "processing failed %g -> %g\n", v1, v2); + exit(1); + } + end + +Routines such as init() and finish() above are passed to the generated +program for linking using the B<-l [link directives ...]> +switch. The string specified by this switch will be added to the link +line used to build the program (before the funtools library). For +example, assuming that init() and finish() are in the library +libmysubs.a in the /opt/special/lib directory, use: + + funcalc -l "-L/opt/special/lib -lmysubs" ... + + + +User arguments can be passed to a compiled funcalc program using a string +argument to the "-a" switch. The string should contain all of the +user arguments. For example, to pass the integers 1 and 2, use: + + funcalc -a "1 2" ... + +The arguments are stored in an internal array and are accessed as +strings via the ARGV(n) macro. For example, consider the following +expression: + + local + int pmin, pmax; + end + + before + pmin=atoi(ARGV(0)); + pmax=atoi(ARGV(1)); + end + + if( (cur->pha >= pmin) && (cur->pha <= pmax) ) + fprintf(stderr, "%d %d %d\n", cur->x, cur->y, cur->pha); + +This expression will print out x, y, and pha values for all rows in which +the pha value is between the two user-input values: + + funcalc -a '1 12' -f foo snr.ev'[cir 512 512 .1]' + 512 512 6 + 512 512 8 + 512 512 5 + 512 512 5 + 512 512 8 + + funcalc -a '5 6' -f foo snr.ev'[cir 512 512 .1]' + 512 512 6 + 512 512 5 + 512 512 5 + + + +Note that it is the user's responsibility to ensure that the correct +number of arguments are passed. The ARGV(n) macro returns a NULL if a +requested argument is outside the limits of the actual number of args, +usually resulting in a SEGV if processed blindly. To check the +argument count, use the ARGC macro: + + local + long int seed=1; + double limit=0.8; + end + + before + if( ARGC >= 1 ) seed = atol(ARGV(0)); + if( ARGC >= 2 ) limit = atof(ARGV(1)); + srand48(seed); + end + + if ( drand48() > limit ) continue; + + + +The macro WRITE_ROW expands to the FunTableRowPut() call that writes +the current row. It can be used to write the row more than once. In +addition, the macro NROW expands to the row number currently being +processed. Use of these two macros is shown in the following example: + + if( cur->pha:I == cur->pi:I ) continue; + a = cur->pha; + cur->pha = cur->pi; + cur->pi = a; + cur->AVG:E = (cur->pha+cur->pi)/2.0; + cur->NR:I = NROW; + if( NROW < 10 ) WRITE_ROW; + + + +If the B<-p [prog]> switch is specified, the expression is not +executed. Rather, the generated executable is saved with the specified +program name for later use. + + +If the B<-n> switch is specified, the expression is not +executed. Rather, the generated code is written to stdout. This is +especially useful if you want to generate a skeleton file and add your +own code, or if you need to check compilation errors. Note that the +comment at the start of the output gives the compiler command needed +to build the program on that platform. (The command can change from +platform to platform because of the use of different libraries, +compiler switches, etc.) + + +As mentioned previously, B will declare a scalar +variable automatically (as a double) if that variable has been used +but not declared. This facility is implemented using a sed script +named funcalc.sed, which processes the +compiler output to sense an undeclared variable error. This script +has been seeded with the appropriate error information for gcc, and for +cc on Solaris, DecAlpha, and SGI platforms. If you find that automatic +declaration of scalars is not working on your platform, check this sed +script; it might be necessary to add to or edit some of the error +messages it senses. + + +In order to keep the lexical analysis of B expressions +(reasonably) simple, we chose to accept some limitations on how +accurately C comments, spaces, and new-lines are placed in the +generated program. In particular, comments associated with local +variables declared at the beginning of an expression (i.e., not in a +B block) will usually end up in the inner loop, not +with the local declarations: + + /* this comment will end up in the wrong place (i.e, inner loop) */ + double a; /* also in wrong place */ + /* this will be in the the right place (inner loop) */ + if( cur->x:D == cur->y:D ) continue; /* also in right place */ + a = cur->x; + cur->x = cur->y; + cur->y = a; + cur->avg:E = (cur->x+cur->y)/2.0; + +Similarly, spaces and new-lines sometimes are omitted or added in a +seemingly arbitrary manner. Of course, none of these stylistic +blemishes affect the correctness of the generated code. + + +Because B must analyze the user expression using the data +file(s) passed on the command line, the input file(s) must be opened +and read twice: once during program generation and once during +execution. As a result, it is not possible to use stdin for the +input file: B cannot be used as a filter. We will +consider removing this restriction at a later time. + + +Along with C comments, B expressions can have one-line +internal comments that are not passed on to the generated C +program. These internal comment start with the B<#> character and +continue up to the new-line: + + double a; # this is not passed to the generated C file + # nor is this + a = cur->x; + cur->x = cur->y; + cur->y = a; + /* this comment is passed to the C file */ + cur->avg:E = (cur->x+cur->y)/2.0; + + + +As previously mentioned, input columns normally are identified by +their being used within the inner event loop. There are rare cases +where you might want to read a column and process it outside the main +loop. For example, qsort might use a column in its sort comparison +routine that is not processed inside the inner loop (and therefore not +implicitly specified as a column to be read). To ensure that such a +column is read by the event loop, use the B keyword. +The arguments to this keyword specify columns that should be read into +the input record structure even though they are not mentioned in the +inner loop. For example: + + explicit pi pha + +will ensure that the pi and pha columns are read for each row, +even if they are not processed in the inner event loop. The B +statement can be placed anywhere. + + +Finally, note that B currently works on expressions +involving FITS binary tables and raw event files. We will consider +adding support for image expressions at a later point, if there is +demand for such support from the community. + + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + +=cut diff --git a/doc/pod/funcen.pod b/doc/pod/funcen.pod new file mode 100644 index 0000000..3f10795 --- /dev/null +++ b/doc/pod/funcen.pod @@ -0,0 +1,145 @@ +=pod + +=head1 NAME + + + +B + + +=head1 SYNOPSIS + + + + + +funcen [-i] [-n iter] [-t tol] [-v lev] + + + + + +=head1 OPTIONS + + + + + + -i # use image filtering (default: event filtering) + -n iter # max number of iterations (default: 0) + -t tol # pixel tolerance distance (default: 1.0) + -v [0,1,2,3] # output verbosity level (default: 0) + + + + +=head1 DESCRIPTION + + + + +B iteratively calculates the centroid position within one +or more regions of a Funtools table (FITS binary table or raw event +file). Starting with an input table, an initial region specification, +and an iteration count, the program calculates the average x and y +position within the region and then uses this new position as the +region center for the next iteration. Iteration terminates when the +maximum number of iterations is reached or when the input tolerance +distance is met for that region. A count of events in the final region +is then output, along with the pixel position value (and, where +available, WCS position). + + +The first argument to the program specifies the Funtools table file to +process. Since the file must be read repeatedly, a value of "stdin" +is not permitted when the number of iterations is non-zero. Use +Funtools Bracket Notation to specify FITS +extensions and filters. + + +The second required argument is the initial region descriptor. Multiple +regions are permitted. However, compound regions (accelerators, +variable argument regions and regions connected via boolean algebra) +are not permitted. Points and polygons also are illegal. These +restrictions might be lifted in a future version, if warranted. + + +The B<-n> (iteration number) switch specifies the maximum number of +iterations to perform. The default is 0, which means that the program will +simply count and display the number of events in the initial region(s). +Note that when iterations is 0, the data can be input via stdin. + + +The B<-t> (tolerance) switch specifies a floating point tolerance +value. If the distance between the current centroid position value and +the last position values is less than this value, iteration terminates. +The default value is 1 pixel. + + +The B<-v> (verbosity) switch specifies the verbosity level of the +output. The default is 0, which results in a single line of output for +each input region consisting of the following values: + + counts x y [ra dec coordsys] + +The last 3 WCS values are output if WCS information is available in the +data file header. Thus, for example: + + [sh] funcen -n 0 snr.ev "cir 505 508 5" + 915 505.00 508.00 345.284038 58.870920 j2000 + + [sh] funcen -n 3 snr.ev "cir 505 508 5" + 1120 504.43 509.65 345.286480 58.874587 j2000 + +The first example simply counts the number of events in the initial region. +The second example iterates the centroid calculation three times to determine +a final "best" position. + + +Higher levels of verbosity obviously imply more verbose output. At +level 1, the output essentially contains the same information as level +0, but with keyword formatting: + + [sh] funcen -v 1 -n 3 snr.ev "cir 505 508 5" + event_file: snr.ev + initial_region: cir 505 508 5 + tolerance: 1.0000 + iterations: 1 + + events: 1120 + x,y(physical): 504.43 509.65 + ra,dec(j2000): 345.286480 58.874587 + final_region1: cir 504.43 509.65 5 + +Level 2 outputs results from intermediate calculations as well. + + +Ordinarily, region filtering is performed using analytic (event) +filtering, i.e. that same style of filtering as is performed by +B and B. Use the B<-i> switch to specify image +filtering, i.e. the same style filtering as is performed by B. +Thus, you can perform a quick calculation of counts in regions, using +either the analytic or image filtering method, by specifying the + B<-n 0> and optional B<-i> switches. These two method often +give different results because of how boundary events are processed: + + [sh] funcen snr.ev "cir 505 508 5" + 915 505.00 508.00 345.284038 58.870920 j2000 + + [sh] funcen -i snr.ev "cir 505 508 5" + 798 505.00 508.00 345.284038 58.870920 j2000 + +See Region Boundaries for more information +about how boundaries are calculated using these two methods. + + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + +=cut diff --git a/doc/pod/funclose.pod b/doc/pod/funclose.pod new file mode 100644 index 0000000..48357a3 --- /dev/null +++ b/doc/pod/funclose.pod @@ -0,0 +1,53 @@ +=pod + +=head1 NAME + + + +B + + + +=head1 SYNOPSIS + + + + + + #include + + void FunClose(Fun fun) + + + + + +=head1 DESCRIPTION + + + + +The B routine closes a previously-opened Funtools data +file, freeing control structures. If a +Funtools reference handle +was passed to +the FunOpen() call for this file, +and if copy mode also was specified for that file, then +FunClose() also will copy the +remaining extensions from the input file to the output file (if the +input file still is open). Thus, we recommend always closing the +output Funtools file B the input file. (Alternatively, +you can call FunFlush() +explicitly). + + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + +=cut diff --git a/doc/pod/funcnts.pod b/doc/pod/funcnts.pod new file mode 100644 index 0000000..7d5dfe5 --- /dev/null +++ b/doc/pod/funcnts.pod @@ -0,0 +1,657 @@ +=pod + +=head1 NAME + + + +B + + + +=head1 SYNOPSIS + + + + + +funcnts [switches] [source_region] [bkgd_file] [bkgd_region|bkgd_value] + + + + + +=head1 OPTIONS + + + + + + -e "source_exposure[;bkgd_exposure]" + # source (bkgd) FITS exposure image using matching files + -w "source_exposure[;bkgd_exposure]" + # source (bkgd) FITS exposure image using WCS transform + -t "source_timecorr[;bkgd_timecorr]" + # source (bkgd) time correction value or header parameter name + -g # output using nice g format + -G # output using %.14g format (maximum precision) + -i "[column;]int1;int2..." # column-based intervals + -m # match individual source and bkgd regions + -p # output in pixels, even if wcs is present + -r # output inner/outer radii (and angles) for annuli (and pandas) + -s # output summed values + -v "scol[;bcol]" # src and bkgd value columns for tables + -T # output in starbase/rdb format + -z # output regions with zero area + + + + + +=head1 DESCRIPTION + + + + +B counts photons in the specified source regions and +reports the results for each region. Regions are specified using the +Spatial Region Filtering mechanism. +Photons are also counted in the specified bkgd regions applied to the +same data file or a different data file. (Alternatively, a constant +background value in counts/pixel**2 can be specified.) The bkgd regions +are either paired one-to-one with source regions or pooled and +normalized by area, and then subtracted from the source counts in each +region. Displayed results include the bkgd-subtracted counts in each +region, as well as the error on the counts, the area in +each region, and the surface brightness (cnts/area**2) calculated for +each region. + + +The first argument to the program specifies the FITS input image, array, or +raw event file to process. If "stdin" is specified, data are read from +the standard input. Use Funtools Bracket +Notation to specify FITS extensions, image sections, and filters. + + +The optional second argument is the source region descriptor. If no +region is specified, the entire field is used. + + +The background arguments can take one of two forms, depending on +whether a separate background file is specified. If the source +file is to be used for background as well, the third argument can be +either the background region, or a constant value denoting background +cnts/pixel. Alternatively, the third argument can be a background +data file, in which case the fourth argument is the background region. +If no third argument is specified, a constant value of 0 is used +(i.e., no background). + + +In summary, the following command arguments are valid: + + [sh] funcnts sfile # counts in source file + [sh] funcnts sfile sregion # counts in source region + [sh] funcnts sfile sregion bregion # bkgd reg. is from source file + [sh] funcnts sfile sregion bvalue # bkgd reg. is constant + [sh] funcnts sfile sregion bfile bregion # bkgd reg. is from separate file + + + +NB: unlike other Funtools programs, source and background regions are +specified as separate arguments on the command line, rather than being +placed inside brackets as part of the source and background filenames. +This is because regions in funcnts are not simply used as data +filters, but also are used to calculate areas, exposure, etc. If you +put the source region inside the brackets (i.e. use it simply as a +filter) rather than specifying it as argument two, the program still +will only count photons that pass the region filter. However, the area +calculation will be performed on the whole field, since field() is the +default source region. This rarely is the desired behavior. On the +other hand, with FITS binary tables, it often is useful to put a column +filter in the filename brackets, so that only events matching the +column filter are counted inside the region. + + +For example, to extract the counts within a radius of 22 pixels from the +center of the FITS binary table snr.ev and subtract the background determined +from the same image within an annulus of radii 50-100 pixels: + + [sh] funcnts snr.ev "circle(502,512,22)" "annulus(502,512,50,100)" + # source + # data file: snr.ev + # degrees/pix: 0.00222222 + # background + # data file: snr.ev + # column units + # area: arcsec**2 + # surf_bri: cnts/arcsec**2 + # surf_err: cnts/arcsec**2 + + # background-subtracted results + reg net_counts error background berror area surf_bri surf_err + ---- ------------ --------- ------------ --------- --------- --------- --------- + 1 3826.403 66.465 555.597 5.972 96831.98 0.040 0.001 + + + # the following source and background components were used: + source region(s) + ---------------- + circle(502,512,22) + + reg counts pixels + ---- ------------ --------- + 1 4382.000 1513 + + background region(s) + -------------------- + annulus(502,512,50,100) + + reg counts pixels + ---- ------------ --------- + all 8656.000 23572 + +The area units for the output columns labeled "area", "surf_bri" +(surface brightness) and "surf_err" will be given either in +arc-seconds (if appropriate WCS information is in the data file +header(s)) or in pixels. If the data file has WCS info, but you do not +want arc-second units, use the B<-p> switch to force output in +pixels. Also, regions having zero area are not normally included in +the primary (background-subtracted) table, but are included in the +secondary source and bkgd tables. If you want these regions to be +included in the primary table, use the B<-z> switch. + + +Note that a simple sed command will extract the background-subtracted results +for further analysis: + + [sh] cat funcnts.sed + 1,/---- .*/d + /^$/,$d + + [sh] sed -f funcnts.sed funcnts.out + 1 3826.403 66.465 555.597 5.972 96831.98 0.040 0.001 + + + +If separate source and background files are specified, B will +attempt to normalize the the background area so that the background +pixel size is the same as the source pixel size. This normalization +can only take place if the appropriate WCS information is contained in +both files (e.g. degrees/pixel values in CDELT). If either +file does not contain the requisite size information, the normalization +is not performed. In this case, it is the user's responsibility to +ensure that the pixel sizes are the same for the two files. + + +Normally, if more than one background region is specified, B +will combine them all into a single region and use this background +region to produce the background-subtracted results for each source +region. The B<-m> (match multiple backgrounds) switch tells +B to make a one to one correspondence between background and +source regions, instead of using a single combined background region. +For example, the default case is to combine 2 background +regions into a single region and then apply that region to each of the +source regions: + + + [sh] funcnts snr.ev "annulus(502,512,0,22,n=2)" "annulus(502,512,50,100,n=2)" + # source + # data file: snr.ev + # degrees/pix: 0.00222222 + # background + # data file: snr.ev + # column units + # area: arcsec**2 + # surf_bri: cnts/arcsec**2 + # surf_err: cnts/arcsec**2 + + # background-subtracted results + reg net_counts error background berror area surf_bri surf_err + ---- ------------ --------- ------------ --------- --------- --------- --------- + 1 3101.029 56.922 136.971 1.472 23872.00 0.130 0.002 + 2 725.375 34.121 418.625 4.500 72959.99 0.010 0.000 + + + # the following source and background components were used: + source region(s) + ---------------- + annulus(502,512,0,22,n=2) + + reg counts pixels + ---- ------------ --------- + 1 3238.000 373 + 2 1144.000 1140 + + background region(s) + -------------------- + annulus(502,512,50,100,n=2) + + reg counts pixels + ---- ------------ --------- + all 8656.000 23572 + +Note that the basic region filter rule "each photon is counted once +and no photon is counted more than once" still applies when using The +B<-m> to match background regions. That is, if two background +regions overlap, the overlapping pixels will be counted in only one of +them. In a worst-case scenario, if two background regions are the same +region, the first will get all the counts and area and the second +will get none. + + +Using the B<-m> switch causes B to use each of the two +background regions independently with each of the two source regions: + + + [sh] funcnts -m snr.ev "annulus(502,512,0,22,n=2)" "ann(502,512,50,100,n=2)" + # source + # data file: snr.ev + # degrees/pix: 0.00222222 + # background + # data file: snr.ev + # column units + # area: arcsec**2 + # surf_bri: cnts/arcsec**2 + # surf_err: cnts/arcsec**2 + + # background-subtracted results + reg net_counts error background berror area surf_bri surf_err + ---- ------------ --------- ------------ --------- --------- --------- --------- + 1 3087.015 56.954 150.985 2.395 23872.00 0.129 0.002 + 2 755.959 34.295 388.041 5.672 72959.99 0.010 0.000 + + + # the following source and background components were used: + source region(s) + ---------------- + annulus(502,512,0,22,n=2) + + reg counts pixels + ---- ------------ --------- + 1 3238.000 373 + 2 1144.000 1140 + + background region(s) + -------------------- + ann(502,512,50,100,n=2) + + reg counts pixels + ---- ------------ --------- + 1 3975.000 9820 + 2 4681.000 13752 + + + +Note that most floating point quantities are displayed using "f" +format. You can change this to "g" format using the B<-g> +switch. This can be useful when the counts in each pixel is very +small or very large. If you want maximum precision and don't care +about the columns lining up nicely, use B<-G>, which outputs +all floating values as %.14g. + + +When counting photons using the annulus and panda (pie and annuli) +shapes, it often is useful to have access to the radii (and panda +angles) for each separate region. The B<-r> switch will add radii +and angle columns to the output table: + + + [sh] funcnts -r snr.ev "annulus(502,512,0,22,n=2)" "ann(502,512,50,100,n=2)" + # source + # data file: snr.ev + # degrees/pix: 0.00222222 + # background + # data file: snr.ev + # column units + # area: arcsec**2 + # surf_bri: cnts/arcsec**2 + # surf_err: cnts/arcsec**2 + # radii: arcsecs + # angles: degrees + + # background-subtracted results + reg net_counts error background berror area surf_bri surf_err radius1 radius2 angle1 angle2 + ---- ------------ --------- ------------ --------- --------- --------- --------- --------- --------- --------- --------- + 1 3101.029 56.922 136.971 1.472 23872.00 0.130 0.002 0.00 88.00 NA NA + 2 725.375 34.121 418.625 4.500 72959.99 0.010 0.000 88.00 176.00 NA NA + + + # the following source and background components were used: + source region(s) + ---------------- + annulus(502,512,0,22,n=2) + + reg counts pixels + ---- ------------ --------- + 1 3238.000 373 + 2 1144.000 1140 + + background region(s) + -------------------- + ann(502,512,50,100,n=2) + + reg counts pixels + ---- ------------ --------- + all 8656.000 23572 + + + +Radii are given in units of pixels or arc-seconds (depending on the +presence of WCS info), while the angle values (when present) are in +degrees. These columns can be used to plot radial profiles. For +example, the script B in the funtools +distribution) will plot a radial profile using gnuplot (version 3.7 or +above). A simplified version of this script is shown below: + + + #!/bin/sh + + if [ x"$1" = xgnuplot ]; then + if [ x`which gnuplot 2>/dev/null` = x ]; then + echo "ERROR: gnuplot not available" + exit 1 + fi + awk ' + BEGIN{HEADER=1; DATA=0; FILES=""; XLABEL="unknown"; YLABEL="unknown"} + HEADER==1{ + if( $1 == "#" && $2 == "data" && $3 == "file:" ){ + if( FILES != "" ) FILES = FILES "," + FILES = FILES $4 + } + else if( $1 == "#" && $2 == "radii:" ){ + XLABEL = $3 + } + else if( $1 == "#" && $2 == "surf_bri:" ){ + YLABEL = $3 + } + else if( $1 == "----" ){ + printf "set nokey; set title \"funcnts(%s)\"\n", FILES + printf "set xlabel \" radius(%s)\"\n", XLABEL + printf "set ylabel \"surf_bri(%s)\"\n", YLABEL + print "plot \"-\" using 3:4:6:7:8 with boxerrorbars" + HEADER = 0 + DATA = 1 + next + } + } + DATA==1{ + if( NF == 12 ){ + print $9, $10, ($9+$10)/2, $7, $8, $7-$8, $7+$8, $10-$9 + } + else{ + exit + } + } + ' | gnuplot -persist - 1>/dev/null 2>&1 + + elif [ x"$1" = xds9 ]; then + awk ' + BEGIN{HEADER=1; DATA=0; XLABEL="unknown"; YLABEL="unknown"} + HEADER==1{ + if( $1 == "#" && $2 == "data" && $3 == "file:" ){ + if( FILES != "" ) FILES = FILES "," + FILES = FILES $4 + } + else if( $1 == "#" && $2 == "radii:" ){ + XLABEL = $3 + } + else if( $1 == "#" && $2 == "surf_bri:" ){ + YLABEL = $3 + } + else if( $1 == "----" ){ + printf "funcnts(%s) radius(%s) surf_bri(%s) 3\n", FILES, XLABEL, YLABEL + HEADER = 0 + DATA = 1 + next + } + } + DATA==1{ + if( NF == 12 ){ + print $9, $7, $8 + } + else{ + exit + } + } + ' + else + echo "funcnts -r ... | funcnts.plot [ds9|gnuplot]" + exit 1 + fi + + +Thus, to run B and plot the results using gnuplot (version 3.7 +or above), use: + + funcnts -r snr.ev "annulus(502,512,0,50,n=5)" ... | funcnts.plot gnuplot + + + +The B<-s> (sum) switch causes B to produce an +additional table of summed (integrated) background subtracted values, +along with the default table of individual values: + + + [sh] funcnts -s snr.ev "annulus(502,512,0,50,n=5)" "annulus(502,512,50,100)" + # source + # data file: snr.ev + # degrees/pix: 0.00222222 + # background + # data file: snr.ev + # column units + # area: arcsec**2 + # surf_bri: cnts/arcsec**2 + # surf_err: cnts/arcsec**2 + + # summed background-subtracted results + upto net_counts error background berror area surf_bri surf_err + ---- ------------ --------- ------------ --------- --------- --------- --------- + 1 2880.999 54.722 112.001 1.204 19520.00 0.148 0.003 + 2 3776.817 65.254 457.183 4.914 79679.98 0.047 0.001 + 3 4025.492 71.972 1031.508 11.087 179775.96 0.022 0.000 + 4 4185.149 80.109 1840.851 19.786 320831.94 0.013 0.000 + 5 4415.540 90.790 2873.460 30.885 500799.90 0.009 0.000 + + + # background-subtracted results + reg counts error background berror area surf_bri surf_err + ---- ------------ --------- ------------ --------- --------- --------- --------- + 1 2880.999 54.722 112.001 1.204 19520.00 0.148 0.003 + 2 895.818 35.423 345.182 3.710 60159.99 0.015 0.001 + 3 248.675 29.345 574.325 6.173 100095.98 0.002 0.000 + 4 159.657 32.321 809.343 8.699 141055.97 0.001 0.000 + 5 230.390 37.231 1032.610 11.099 179967.96 0.001 0.000 + + + # the following source and background components were used: + source region(s) + ---------------- + annulus(502,512,0,50,n=5) + + reg counts pixels sumcnts sumpix + ---- ------------ --------- ------------ --------- + 1 2993.000 305 2993.000 305 + 2 1241.000 940 4234.000 1245 + 3 823.000 1564 5057.000 2809 + 4 969.000 2204 6026.000 5013 + 5 1263.000 2812 7289.000 7825 + + background region(s) + -------------------- + annulus(502,512,50,100) + + reg counts pixels + ---- ------------ --------- + all 8656.000 23572 + + + +The B<-t> and B<-e> switches can be used to apply timing and +exposure corrections, respectively, to the data. Please note that +these corrections are meant to be used qualitatively, since +application of more accurate correction factors is a complex and +mission-dependent effort. The algorithm for applying these simple +corrections is as follows: + + C = Raw Counts in Source Region + Ac= Area of Source Region + Tc= Exposure time for Source Data + Ec= Average exposure in Source Region, from exposure map + + B= Raw Counts in Background Region + Ab= Area of Background Region + Tb= (Exposure) time for Background Data + Eb= Average exposure in Background Region, from exposure map + +Then, Net Counts in Source region is + + Net= C - B * (Ac*Tc*Ec)/(Ab*Tb*Eb) + +with the standard propagation of errors for the Error on Net. +The net rate would then be + + Net Rate = Net/(Ac*Tc*Ec) + +The average exposure in each region is calculated by summing up the +pixel values in the exposure map for the given region and then +dividing by the number of pixels in that region. Exposure maps often +are generated at a block factor > 1 (e.g., block 4 means that each +exposure pixel contains 4x4 pixels at full resolution) and +B will deal with the blocking automatically. Using the +B<-e> switch, you can supply both source and background exposure +files (separated by ";"), if you have separate source and background +data files. If you do not supply a background exposure file to go with +a separate background data file, B assumes that exposure +already has been applied to the background data file. In addition, it +assumes that the error on the pixels in the background data file is +zero. + + +NB: The B<-e> switch assumes that the exposure map overlays the +image file B, except for the block factor. Each pixel in +the image is scaled by the block factor to access the corresponding +pixel in the exposure map. If your exposure map does not line up +exactly with the image, B the B<-e> exposure +correction. In this case, it still is possible to perform exposure +correction B both the image and the exposure map have valid +WCS information: use the B<-w> switch so that the transformation +from image pixel to exposure pixel uses the WCS information. That is, +each pixel in the image region will be transformed first from image +coordinates to sky coordinates, then from sky coordinates to exposure +coordinates. Please note that using B<-w> can increase the time +required to process the exposure correction considerably. + + +A time correction can be applied to both source and +background data using the B<-t> switch. The value for the correction can +either be a numeric constant or the name of a header parameter in +the source (or background) file: + + [sh] funcnts -t 23.4 ... # number for source + [sh] funcnts -t "LIVETIME;23.4" ... # param for source, numeric for bkgd + +When a time correction is specified, it is applied to the net counts +as well (see algorithm above), so that the units of surface brightness +become cnts/area**2/sec. + + +The B<-i> (interval) switch is used to run B on multiple +column-based intervals with only a single pass through the data. It is +equivalent to running B several times with a different column +filter added to the source and background data each time. For each +interval, the full B output is generated, with a linefeed +character (^L) inserted between each run. In addition, the output for +each interval will contain the interval specification in its header. +Intervals are very useful for generating X-ray hardness ratios +efficiently. Of course, they are only supported when the input data +are contained in a table. + + +Two formats are supported for interval specification. The most general +format is semi-colon-delimited list of filters to be used as intervals: + + funcnts -i "pha=1:5;pha=6:10;pha=11:15" snr.ev "circle(502,512,22)" ... + +Conceptually, this will be equivalent to running B three times: + + funcnts snr.ev'[pha=1:5]' "circle(502,512,22)" + funcnts snr.ev'[pha=6:10]' "circle(502,512,22)" + funcnts snr.ev'[pha=11:15]' "circle(502,512,22)" + +However, using the B<-i> switch will require only one pass through +the data. + + +Note that complex filters can be used to specify intervals: + + funcnts -i "pha=1:5&&pi=4;pha=6:10&&pi=5;pha=11:15&&pi=6" snr.ev ... + +The program simply runs the data through each filter in turn and generates +three B outputs, separated by the line-feed character. + + +In fact, although the intent is to support intervals for hardness ratios, +the specified filters do not have to be intervals at all. Nor does one +"interval" filter have to be related to another. For example: + + funcnts -i "pha=1:5;pi=6:10;energy=11:15" snr.ev "circle(502,512,22)" ... + +is equivalent to running B three times with unrelated filter +specifications. + + +A second interval format is supported for the simple case in which a +single column is used to specify multiple homogeneous intervals for +that column. In this format, a column name is specified first, +followed by intervals: + + funcnts -i "pha;1:5;6:10;11:15" snr.ev "circle(502,512,22)" ... + +This is equivalent to the first example, but requires less typing. The +B program will simply prepend "pha=" before each of the specified +intervals. (Note that this format does not contain the "=" character in +the column argument.) + + +Ordinarily, when B is run on a FITS binary table (or a +raw event table), one integral count is accumulated for each row +(event) contained within a given region. The B<-v "scol[;bcol]"> +(value column) switch will accumulate counts using the value from the +specified column for the given event. If only a single column is +specified, it is used for both the source and background regions. Two +separate columns, separated by a semi-colon, can be specified for source +and background. The special token '$none' can be used to specify that +a value column is to be used for one but not the other. For example, +'pha;$none' will use the pha column for the source but use integral +counts for the background, while '$none;pha' will do the converse. +If the value column is of type logical, then the value used will be 1 +for T and 0 for F. Value columns are used, for example, to integrate +probabilities instead of integral counts. + + +If the B<-T> (rdb table) switch is used, the output will conform +to starbase/rdb data base format: tabs will be inserted between +columns rather than spaces and line-feed will be inserted between +tables. + + +Finally, note that B is an image program, even though it +can be run directly on FITS binary tables. This means that image +filtering is applied to the rows in order to ensure that the same +results are obtained regardless of whether a table or the equivalent +binned image is used. Because of this, however, the number of counts +found using B can differ from the number of events found +using row-filter programs such as B or B +For more information about these difference, see the discussion of +Region Boundaries. + + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + +=cut diff --git a/doc/pod/funcolumnactivate.pod b/doc/pod/funcolumnactivate.pod new file mode 100644 index 0000000..d5f6e3a --- /dev/null +++ b/doc/pod/funcolumnactivate.pod @@ -0,0 +1,239 @@ +=pod + +=head1 NAME + + + +B + + + +=head1 SYNOPSIS + + + + + + #include + + void FunColumnActivate(Fun fun, char *s, char *plist) + + + + + +=head1 DESCRIPTION + + + + +The B routine determines which columns (set up +by FunColumnSelect()) +ultimately will be read and/or written. By default, all columns that +are selected using +FunColumnSelect() +are activated. The +FunColumnActivate() +routine can be used to turn off/off activation of specific columns. + + +The first argument is the Fun handle associated with this set of +columns. The second argument is a space-delimited list of columns to +activate or de-activate. Columns preceded by "+" are activated and +columns preceded by a "-" are de-activated. If a column is named +without "+" or "-", it is activated. The reserved strings "$region" +and '$n' are used to activate a special columns containing the filter +region value and row value, respectively, associated with +this row. For example, if a filter containing two circular regions is +specified as part of the Funtools file name, this column will contain +a value of 1 or 2, depending on which region that row was in. The +reserved strings "$x" and "$y" are used to activate the current +binning columns. Thus, if the columns DX and DY are specified as +binning columns: + + [sh $] fundisp foo.fits[bincols=(DX,DY)] + +then "$x" and "$y" will refer to these columns in a call to +FunColumnActivate(). + + +In addition, if the activation string contains only columns to be +activated, then the routine will de-activate all other columns. +Similarly, if the activation string contains only +columns to de-activate, then the routine will activate all other columns +before activating the list. This makes it simple to change the +activation state of all columns without having to know all of the +column names. For example: + + +=over 4 + + + + +=item * + +B<"pi pha time"> # only these three columns will be active + + +=item * + +B<"-pi -pha -time"> # all but these columns will be active + + +=item * + +B<"pi -pha"> # only pi is active, pha is not, others are not + + +=item * + +B<"+pi -pha"> # same as above + + +=item * + +B<"pi -pha -time"> # only pi is active, all others are not + + +=item * + +B<"pi pha"> # pha and pi are active, all others are not + + +=item * + +B<"pi pha -x -y"> # pha and pi are active, all others are not + + +=back + + + + +You can use the column activation list to reorder columns, since +columns are output in the order specified. For example: + + # default output order + fundisp snr.ev'[cir 512 512 .1]' + X Y PHA PI TIME DX DY + -------- -------- -------- -------- --------------------- -------- -------- + 512 512 6 7 79493997.45854475 578 574 + 512 512 8 9 79494575.58943175 579 573 + 512 512 5 6 79493631.03866175 578 575 + 512 512 5 5 79493290.86521725 578 575 + 512 512 8 9 79493432.00990875 579 573 + + # re-order the output by specifying explicit order + fundisp snr.ev'[cir 512 512 .1]' "time x y dy dx pi pha" + TIME X Y DY DX PI PHA + --------------------- -------- -------- -------- -------- -------- -------- + 79493997.45854475 512 512 574 578 7 6 + 79494575.58943175 512 512 573 579 9 8 + 79493631.03866175 512 512 575 578 6 5 + 79493290.86521725 512 512 575 578 5 5 + 79493432.00990875 512 512 573 579 9 8 + + + +A "+" sign by itself means to activate all columns, so that you can reorder +just a few columns without specifying all of them: + + # reorder 3 columns and then output the rest + fundisp snr.ev'[cir 512 512 .1]' "time pi pha +" + TIME PI PHA Y X DX DY + --------------------- -------- -------- -------- -------- -------- -------- + 79493997.45854475 7 6 512 512 578 574 + 79494575.58943175 9 8 512 512 579 573 + 79493631.03866175 6 5 512 512 578 575 + 79493290.86521725 5 5 512 512 578 575 + 79493432.00990875 9 8 512 512 579 573 + +The column activation/deactivation is performed in the order of the +specified column arguments. This means you can mix "+", "-" (which +de-activates all columns) and specific column names to reorder and +select columns in one command. For example, consider the following: + + # reorder and de-activate + fundisp snr.ev'[cir 512 512 .1]' "time pi pha + -x -y" + TIME PI PHA DX DY + --------------------- -------- -------- -------- -------- + 79493997.45854475 7 6 578 574 + 79494575.58943175 9 8 579 573 + 79493631.03866175 6 5 578 575 + 79493290.86521725 5 5 578 575 + 79493432.00990875 9 8 579 573 + +We first activate "time", "pi", and "pha" so that they are output first. +We then activate all of the other columns, and then de-activate "x" and "y". +Note that this is different from: + + # probably not what you want ... + fundisp snr.ev'[cir 512 512 .1]' "time pi pha -x -y +" + TIME PI PHA Y X DX DY + --------------------- -------- -------- -------- -------- -------- -------- + 79493997.45854475 7 6 512 512 578 574 + 79494575.58943175 9 8 512 512 579 573 + 79493631.03866175 6 5 512 512 578 575 + 79493290.86521725 5 5 512 512 578 575 + 79493432.00990875 9 8 512 512 579 573 + +Here, "x" and "y" are de-activated, but then all columns including "x" and +"y" are again re-activated. + + +Typically, +FunColumnActivate() uses a +list of columns that are passed into the program from the command line. For +example, the code for funtable contains the following: + + char *cols=NULL; + + /* open the input FITS file */ + if( !(fun = FunOpen(argv[1], "rc", NULL)) ) + gerror(stderr, "could not FunOpen input file: %s\n", argv[1]); + + /* set active flag for specified columns */ + if( argc >= 4 ) cols = argv[3]; + FunColumnActivate(fun, cols, NULL); + + +The FunOpen() call sets the +default columns to be all columns in the input file. The +FunColumnActivate() call +then allows the user to control which columns ultimately will be +activated (i.e., in this case, written to the new file). For example: + + funtable test.ev foo.ev "pi pha time" + +will process only the three columns mentioned, while: + + funtable test.ev foo.ev "-time" + +will process all columns except "time". + + +If FunColumnActivate() +is called with a null string, then the environment variable +B will be used to provide a global value, if present. +This is the reason why we call the routine even if no columns +are specified on the command line (see example above), instead +of calling it this way: + + /* set active flag for specified columns */ + if( argc >= 4 ){ + FunColumnActivate(fun, argv[3], NULL); + } + + + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + +=cut diff --git a/doc/pod/funcolumnlookup.pod b/doc/pod/funcolumnlookup.pod new file mode 100644 index 0000000..bfdf5c0 --- /dev/null +++ b/doc/pod/funcolumnlookup.pod @@ -0,0 +1,188 @@ +=pod + +=head1 NAME + + + +B + + +=head1 SYNOPSIS + + + + + + #include + + int FunColumnLookup(Fun fun, char *s, int which, + char **name, int *type, int *mode, + int *offset, int *n, int *width) + + + + + +=head1 DESCRIPTION + + + + +The B routine returns information about a named +(or indexed) column. The first argument is the Fun handle associated +with this set of columns. The second argument is the name of the +column to look up. If the name argument is NULL, the argument that +follows is the zero-based index into the column array of the column +for which information should be returned. The next argument is a +pointer to a char *, which will contain the name of the column. The +arguments that follow are the addresses of int values into which +the following information will be returned: + + +=over 4 + + + + +=item * + +B: data type of column: + + +=over 4 + + + + +=item * + +A: ASCII characters + + +=item * + +B: unsigned 8-bit char + + +=item * + +I: signed 16-bit int + + +=item * + +U: unsigned 16-bit int (not standard FITS) + + +=item * + +J: signed 32-bit int + + +=item * + +V: unsigned 32-bit int (not standard FITS) + + +=item * + +E: 32-bit float + + +=item * + +D: 64-bit float + + +=back + + + + +=item * + +B: bit flag status of column, including: + + +=over 4 + + + + +=item * + +COL_ACTIVE 1 is column activated? + + +=item * + +COL_IBUF 2 is column in the raw input data? + + +=item * + +COL_PTR 4 is column a pointer to an array? + + +=item * + +COL_READ 010 is read mode selected? + + +=item * + +COL_WRITE 020 is write mode selected? + + +=item * + +COL_REPLACEME 040 is this column being replaced by user data? + + +=back + + + + +=item * + +B: byte offset in struct + + +=item * + +B: number of elements (i.e. size of vector) in this column + + +=item * + +B: size in bytes of this column + + +=back + + +If the named column exists, the routine returns a positive integer, +otherwise zero is returned. (The positive integer is the index+1 into +the column array where this column was located.) + +If NULL is passed as the return address of one (or more) of these +values, no data is passed back for that information. For +example: + + if( !FunColumnLookup(fun, "phas", 0, NULL NULL, NULL, NULL, &npha, NULL) ) + gerror(stderr, "can't find phas column\n"); + +only returns information about the size of the phas vector. + + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + +=cut diff --git a/doc/pod/funcolumnselect.pod b/doc/pod/funcolumnselect.pod new file mode 100644 index 0000000..ce65d38 --- /dev/null +++ b/doc/pod/funcolumnselect.pod @@ -0,0 +1,686 @@ +=pod + +=head1 NAME + + + +B + + +=head1 SYNOPSIS + + + + + + #include + + int FunColumnSelect(Fun fun, int size, char *plist, + char *name1, char *type1, char *mode1, int offset1, + char *name2, char *type2, char *mode2, int offset2, + ..., + NULL) + + int FunColumnSelectArr(Fun fun, int size, char *plist, + char **names, char **types, char **modes, + int *offsets, int nargs); + + + + + +=head1 DESCRIPTION + + + +The B routine is used to select the columns +from a Funtools binary table extension or raw event file for +processing. This routine allows you to specify how columns in a file +are to be read into a user record structure or written from a user +record structure to an output FITS file. + + +The first argument is the Fun handle associated with this set of +columns. The second argument specifies the size of the user record +structure into which columns will be read. Typically, the sizeof() +macro is used to specify the size of a record structure. The third +argument allows you to specify keyword directives for the selection +and is described in more detail below. + + +Following the first three required arguments is a variable length list of +column specifications. Each column specification will consist of four +arguments: + + +=over 4 + + + + +=item * + +B: the name of the column + + + +=item * + +B: the data type of the column as it will be stored in +the user record struct (not the data type of the input file). The +following basic data types are recognized: + + +=over 4 + + + + +=item * + +A: ASCII characters + + +=item * + +B: unsigned 8-bit char + + +=item * + +I: signed 16-bit int + + +=item * + +U: unsigned 16-bit int (not standard FITS) + + +=item * + +J: signed 32-bit int + + +=item * + +V: unsigned 32-bit int (not standard FITS) + + +=item * + +E: 32-bit float + + +=item * + +D: 64-bit float + + +=back + + +The syntax used is similar to that which defines the TFORM parameter +in FITS binary tables. That is, a numeric repeat value can precede +the type character, so that "10I" means a vector of 10 short ints, "E" +means a single precision float, etc. Note that the column value from +the input file will be converted to the specified data type as the +data is read by +FunTableRowGet(). + + +[ A short digression regarding bit-fields: Special attention is +required when reading or writing the FITS bit-field type +("X"). Bit-fields almost always have a numeric repeat character +preceding the 'X' specification. Usually this value is a multiple of 8 +so that bit-fields fit into an integral number of bytes. For all +cases, the byte size of the bit-field B is (N+7)/8, where N is the +numeric repeat character. + + +A bit-field is most easily declared in the user struct as an array of +type char of size B as defined above. In this case, bytes are simply +moved from the file to the user space. If, instead, a short or int +scalar or array is used, then the algorithm for reading the bit-field +into the user space depends on the size of the data type used along +with the value of the repeat character. That is, if the user data +size is equal to the byte size of the bit-field, then the data is +simply moved (possibly with endian-based byte-swapping) from one to +the other. If, on the other hand, the data storage is larger than the +bit-field size, then a data type cast conversion is performed to move +parts of the bit-field into elements of the array. Examples will help +make this clear: + + + +=over 4 + + + + +=item * + +If the file contains a 16X bit-field and user space specifies a 2B +char array[2], then the bit-field is moved directly into the char array. + + + +=item * + +If the file contains a 16X bit-field and user space specifies a 1I +scalar short int, then the bit-field is moved directly into the short int. + + + +=item * + +If the file contains a 16X bit-field and user space specifies a 1J +scalar int, then the bit-field is type-cast to unsigned int before +being moved (use of unsigned avoids possible sign extension). + + + +=item * + +If the file contains a 16X bit-field and user space specifies a 2J +int array[2], then the bit-field is handled as 2 chars, each of which +are type-cast to unsigned int before being moved (use of unsigned +avoids possible sign extension). + + + +=item * + +If the file contains a 16X bit-field and user space specifies a 1B +char, then the bit-field is treated as a char, i.e., truncation will +occur. + + + +=item * + +If the file contains a 16X bit-field and user space specifies a 4J +int array[4], then the results are undetermined. + + + +=back + + +For all user data types larger than char, the bit-field is byte-swapped +as necessary to convert to native format, so that bits in the +resulting data in user space can be tested, masked, etc. in the same +way regardless of platform.] + + +In addition to setting data type and size, the B +specification allows a few ancillary parameters to be set, using the +full syntax for B: + + [@][n][[['B']poff]][:[tlmin[:tlmax[:binsiz]]]] + + + +The special character "@" can be prepended to this specification to +indicated that the data element is a pointer in the user record, +rather than an array stored within the record. + + +The [n] value is an integer that specifies the +number of elements that are in this column (default is 1). TLMIN, +TLMAX, and BINSIZ values also can be specified for this column after +the type, separated by colons. If only one such number is specified, +it is assumed to be TLMAX, and TLMIN and BINSIZ are set to 1. + + +The [poff] value can be used to specify the offset into an +array. By default, this offset value is set to zero and the data +specified starts at the beginning of the array. The offset usually +is specified in terms of the data type of the column. Thus an offset +specification of [5] means a 20-byte offset if the data type is a +32-bit integer, and a 40-byte offset for a double. If you want to +specify a byte offset instead of an offset tied to the column data type, +precede the offset value with 'B', e.g. [B6] means a 6-bye offset, +regardless of the column data type. + +The [poff] is especially useful in conjunction with the pointer @ +specification, since it allows the data element to anywhere stored +anywhere in the allocated array. For example, a specification such as +"@I[2]" specifies the third (i.e., starting from 0) element in the +array pointed to by the pointer value. A value of "@2I[4]" specifies +the fifth and sixth values in the array. For example, consider the +following specification: + + typedef struct EvStruct{ + short x[4], *atp; + } *Event, EventRec; + /* set up the (hardwired) columns */ + FunColumnSelect( fun, sizeof(EventRec), NULL, + "2i", "2I ", "w", FUN_OFFSET(Event, x), + "2i2", "2I[2]", "w", FUN_OFFSET(Event, x), + "at2p", "@2I", "w", FUN_OFFSET(Event, atp), + "at2p4", "@2I[4]", "w", FUN_OFFSET(Event, atp), + "atp9", "@I[9]", "w", FUN_OFFSET(Event, atp), + "atb20", "@I[B20]", "w", FUN_OFFSET(Event, atb), + NULL); + +Here we have specified the following columns: + + +=over 4 + + + + +=item * + +2i: two short ints in an array which is stored as part the +record + + +=item * + +2i2: the 3rd and 4th elements of an array which is stored +as part of the record + + +=item * + +an array of at least 10 elements, not stored in the record but +allocated elsewhere, and used by three different columns: + + +=over 4 + + + + +=item * + +at2p: 2 short ints which are the first 2 elements of the allocated array + + +=item * + +at2p4: 2 short ints which are the 5th and 6th elements of +the allocated array + + +=item * + +atp9: a short int which is the 10th element of the allocated array + + +=back + + + + +=item * + +atb20: a short int which is at byte offset 20 of another allocated array + + +=back + + +In this way, several columns can be specified, all of which are in a +single array. B: it is the programmer's responsibility to +ensure that specification of a positive value for poff does not point +past the end of valid data. + + + +=item * + +B: "r" means that the column is read from an +input file into user space by +FunTableRowGet(), "w" means that +the column is written to an output file. Both can specified at the same +time. + + + +=item * + +B: the offset into the user data to store +this column. Typically, the macro FUN_OFFSET(recname, colname) is used +to define the offset into a record structure. + + +=back + + + + +When all column arguments have been specified, a final NULL argument +must added to signal the column selection list. + + +As an alternative to the varargs +FunColumnSelect() +routine, a non-varargs routine called +FunColumnSelectArr() +also is available. The first three arguments (fun, size, plist) of this +routine are the same as in +FunColumnSelect(). +Instead of a variable +argument list, however, +FunColumnSelectArr() +takes 5 additional arguments. The first 4 arrays arguments contain the +names, types, modes, and offsets, respectively, of the columns being +selected. The final argument is the number of columns that are +contained in these arrays. It is the user's responsibility to free +string space allocated in these arrays. + + +Consider the following example: + + typedef struct evstruct{ + int status; + float pi, pha, *phas; + double energy; + } *Ev, EvRec; + + FunColumnSelect(fun, sizeof(EvRec), NULL, + "status", "J", "r", FUN_OFFSET(Ev, status), + "pi", "E", "r", FUN_OFFSET(Ev, pi), + "pha", "E", "r", FUN_OFFSET(Ev, pha), + "phas", "@9E", "r", FUN_OFFSET(Ev, phas), + NULL); + + +Each time a row is read into the Ev struct, the "status" column is +converted to an int data type (regardless of its data type in the +file) and stored in the status value of the struct. Similarly, "pi" +and "pha", and the phas vector are all stored as floats. Note that the +"@" sign indicates that the "phas" vector is a pointer to a 9 element +array, rather than an array allocated in the struct itself. The row +record can then be processed as required: + + /* get rows -- let routine allocate the row array */ + while( (ebuf = (Ev)FunTableRowGet(fun, NULL, MAXROW, NULL, &got)) ){ + /* process all rows */ + for(i=0; ipi = (ev->pi+.5); + ev->pha = (ev->pi-.5); + } + + + +FunColumnSelect() +can also be called to define "writable" columns in order to generate a FITS +Binary Table, without reference to any input columns. For +example, the following will generate a 4-column FITS binary table when +FunTableRowPut() is used to +write Ev records: + + + typedef struct evstruct{ + int status; + float pi, pha + double energy; + } *Ev, EvRec; + + FunColumnSelect(fun, sizeof(EvRec), NULL, + "status", "J", "w", FUN_OFFSET(Ev, status), + "pi", "E", "w", FUN_OFFSET(Ev, pi), + "pha", "E", "w", FUN_OFFSET(Ev, pha), + "energy", "D", "w", FUN_OFFSET(Ev, energy), + NULL); + +All columns are declared to be write-only, so presumably the column +data is being generated or read from some other source. + + +In addition, +FunColumnSelect() +can be called to define B "readable" and "writable" columns. +In this case, the "read" columns +are associated with an input file, while the "write" columns are +associated with the output file. Of course, columns can be specified as both +"readable" and "writable", in which case they are read from input +and (possibly modified data values are) written to the output. +The +FunColumnSelect() +call itself is made by passing the input Funtools handle, and it is +assumed that the output file has been opened using this input handle +as its +Funtools reference handle. + + +Consider the following example: + + typedef struct evstruct{ + int status; + float pi, pha, *phas; + double energy; + } *Ev, EvRec; + + FunColumnSelect(fun, sizeof(EvRec), NULL, + "status", "J", "r", FUN_OFFSET(Ev, status), + "pi", "E", "rw", FUN_OFFSET(Ev, pi), + "pha", "E", "rw", FUN_OFFSET(Ev, pha), + "phas", "@9E", "rw", FUN_OFFSET(Ev, phas), + "energy", "D", "w", FUN_OFFSET(Ev, energy), + NULL); + +As in the "read" example above, each time an row is read into the Ev +struct, the "status" column is converted to an int data type +(regardless of its data type in the file) and stored in the status +value of the struct. Similarly, "pi" and "pha", and the phas vector +are all stored as floats. Since the "pi", "pha", and "phas" variables +are declared as "writable" as well as "readable", they also will be +written to the output file. Note, however, that the "status" variable +is declared as "readable" only, and hence it will not be written to +an output file. Finally, the "energy" column is declared as +"writable" only, meaning it will not be read from the input file. In +this case, it can be assumed that "energy" will be calculated in the +program before being output along with the other values. + + +In these simple cases, only the columns specified as "writable" will +be output using +FunTableRowPut(). However, +it often is the case that you want to merge the user columns back in +with the input columns, even in cases where not all of the input +column names are explicitly read or even known. For this important +case, the B keyword is provided in the plist string. + + +The B keyword tells Funtools to merge the columns from +the input file with user columns on output. It is normally used when +an input and output file are opened and the input file provides the +Funtools reference handle +for the output file. In this case, each time +FunTableRowGet() is called, the +raw input rows are saved in a special buffer. If +FunTableRowPut() then is called +(before another call to +FunTableRowGet()), the contents +of the raw input rows are merged with the user rows according to the +value of B as follows: + + + +=over 4 + + + + +=item * + +B: add new user columns, and update value of existing ones (maintaining the input data type) + + + +=item * + +B: add new user columns, and replace the data type +and value of existing ones. (Note that if tlmin/tlmax values are not +specified in the replacing column, but are specified in the original +column being replaced, then the original tlmin/tlmax values are used +in the replacing column.) + + + +=item * + +B: only add new columns, do not "replace" or "update" existing ones + + +=back + + + + +Consider the example above. If B is specified in the +plist string, then "energy" will be added to the input columns, and +the values of "pi", "pha", and "phas" will be taken from the user +space (i.e., the values will be updated from the original values, if +they were changed by the program). The data type for "pi", "pha", and +"phas" will be the same as in the original file. If +B is specified, both the data type and value of +these three input columns will be changed to the data type and value +in the user structure. If B is specified, none of +these three columns will be updated, and only the "energy" column will +be added. Note that in all cases, "status" will be written from the +input data, not from the user record, since it was specified as read-only. + + +Standard applications will call +FunColumnSelect() +to define user columns. However, if this routine is not called, the +default behavior is to transfer all input columns into user space. For +this purpose a default record structure is defined such that each data +element is properly aligned on a valid data type boundary. This +mechanism is used by programs such as fundisp and funtable to process +columns without needing to know the specific names of those columns. +It is not anticipated that users will need such capabilities (contact +us if you do!) + + +By default, FunColumnSelect() +reads/writes rows to/from an "array of structs", where each struct contains +the column values for a single row of the table. This means that the +returned values for a given column are not contiguous. You can +set up the IO to return a "struct of arrays" so that each of the +returned columns are contiguous by specifying B +(abbreviation: B) in the plist. +(The default case is B or B.) + + +For example, the default setup to retrieve rows from a table would be +to define a record structure for a single event and then call + FunColumnSelect() +as follows: + + typedef struct evstruct{ + short region; + double x, y; + int pi, pha; + double time; + } *Ev, EvRec; + + got = FunColumnSelect(fun, sizeof(EvRec), NULL, + "x", "D:10:10", mode, FUN_OFFSET(Ev, x), + "y", "D:10:10", mode, FUN_OFFSET(Ev, y), + "pi", "J", mode, FUN_OFFSET(Ev, pi), + "pha", "J", mode, FUN_OFFSET(Ev, pha), + "time", "1D", mode, FUN_OFFSET(Ev, time), + NULL); + +Subsequently, each call to +FunTableRowGet() +will return an array of structs, one for each returned row. If instead you +wanted to read columns into contiguous arrays, you specify B: + + typedef struct aevstruct{ + short region[MAXROW]; + double x[MAXROW], y[MAXROW]; + int pi[MAXROW], pha[MAXROW]; + double time[MAXROW]; + } *AEv, AEvRec; + + got = FunColumnSelect(fun, sizeof(AEvRec), "org=soa", + "x", "D:10:10", mode, FUN_OFFSET(AEv, x), + "y", "D:10:10", mode, FUN_OFFSET(AEv, y), + "pi", "J", mode, FUN_OFFSET(AEv, pi), + "pha", "J", mode, FUN_OFFSET(AEv, pha), + "time", "1D", mode, FUN_OFFSET(AEv, time), + NULL); + +Note that the only modification to the call is in the plist string. + + +Of course, instead of using staticly allocated arrays, you also can specify +dynamically allocated pointers: + + /* pointers to arrays of columns (used in struct of arrays) */ + typedef struct pevstruct{ + short *region; + double *x, *y; + int *pi, *pha; + double *time; + } *PEv, PEvRec; + + got = FunColumnSelect(fun, sizeof(PEvRec), "org=structofarrays", + "$region", "@I", mode, FUN_OFFSET(PEv, region), + "x", "@D:10:10", mode, FUN_OFFSET(PEv, x), + "y", "@D:10:10", mode, FUN_OFFSET(PEv, y), + "pi", "@J", mode, FUN_OFFSET(PEv, pi), + "pha", "@J", mode, FUN_OFFSET(PEv, pha), + "time", "@1D", mode, FUN_OFFSET(PEv, time), + NULL); + +Here, the actual storage space is either allocated by the user or by the +FunColumnSelect() call). + + +In all of the above cases, the same call is made to retrieve rows, e.g.: + + buf = (void *)FunTableRowGet(fun, NULL, MAXROW, NULL, &got); + +However, the individual data elements are accessed differently. +For the default case of an "array of structs", the +individual row records are accessed using: + + for(i=0; ix, ev->y, ev->pi, ev->pha, ev->dx, ev->dy, ev->time); + } + +For a struct of arrays or a struct of array pointers, we have a single struct +through which we access individual columns and rows using: + + aev = (AEv)buf; + for(i=0; ix[i], aev->y[i], aev->pi[i], aev->pha[i], + aev->dx[i], aev->dy[i], aev->time[i]); + } + +Support for struct of arrays in the +FunTableRowPut() +call is handled analogously. + + +See the evread example code +and +evmerge example code +for working examples of how +FunColumnSelect() is used. + + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + +=cut diff --git a/doc/pod/funcombine.pod b/doc/pod/funcombine.pod new file mode 100644 index 0000000..946d304 --- /dev/null +++ b/doc/pod/funcombine.pod @@ -0,0 +1,157 @@ +=pod + +=head1 NAME + + + +B + + + +=head1 SYNOPSIS + + + + + +This document discusses the conventions for combining region and table +filters, especially with regards to the comma operator. + + + + +=head1 DESCRIPTION + + + +B + +Filter specifications consist of a series of boolean expressions, +separated by commas. These expressions can be table filters, +spatial region filters, or combinations thereof. Unfortunately, +common usage requires that the comma operator must act differently +in different situations. Therefore, while its use is intuitive in +most cases, commas can be a source of confusion. + + +According to long-standing usage in IRAF, when a comma separates two +table filters, it takes on the meaning of a boolean B. Thus: + + foo.fits[pha==1,pi==2] + +is equivalent to: + + foo.fits[pha==1 && pi==2] + + +When a comma separates two spatial region filters, however, it has +traditionally taken on the meaning of a boolean B. Thus: + + foo.fits[circle(10,10,3),ellipse(20,20,8,5)] + +is equivalent to: + + foo.fits[circle(10,10,3) || ellipse(20,20,8,5)] + +(except that in the former case, each region is given a unique id +in programs such as funcnts). + + +Region and table filters can be combined: + + foo.fits[circle(10,10,3),pi=1:5] + +or even: + + foo.fits[pha==1&&circle(10,10,3),pi==2&&ellipse(20,20,8,5)] + +In these cases, it is not obvious whether the command should utilize an +B or B operator. We therefore arbitrarily chose to +implement the following rule: + + +=over 4 + + + + +=item * + +if both expressions contain a region, the operator used is B. + + +=item * + +if one (or both) expression(s) does not contain a region, the operator +used is B. + + +=back + + +This rule handles the cases of pure regions and pure column filters properly. +It unambiguously assigns the boolean B to all mixed cases. Thus: + + foo.fits[circle(10,10,3),pi=1:5] + +and + + foo.fits[pi=1:5,circle(10,10,3)] + +both are equivalent to: + + foo.fits[circle(10,10,3) && pi=1:5] + + + +[NB: This arbitrary rule B +(pre-funtools 1.2.3) which stated: + + +=over 4 + + + + +=item * + +if the 2nd expression contains a region, the operator used is B. + + +=item * + +if the 2nd expression does not contain a region, the operator +used is B. + + +=back + + +In that scenario, the B operator was implied by: + + pha==4,circle 5 5 1 + +while the B operator was implied by + + circle 5 5 1,pha==4 + +Experience showed that this non-commutative treatment of the comma +operator was confusing and led to unexpected results.] + + +The comma rule must be considered provisional: comments and complaints +are welcome to help clarify the matter. Better still, we recommend +that the comma operator be avoided in such cases in favor of an +explicit boolean operator. + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + + +=cut diff --git a/doc/pod/funcone.pod b/doc/pod/funcone.pod new file mode 100644 index 0000000..a766ca6 --- /dev/null +++ b/doc/pod/funcone.pod @@ -0,0 +1,191 @@ +=pod + +=head1 NAME + + + +B + + + +=head1 SYNOPSIS + + + + + +funcone [columns] + + + + + +=head1 OPTIONS + + + + + + -d deccol:[hdr] # Dec column name, units (def: DEC:d) + -j # join columns from list file + -J # join columns from list file, output all rows + -l listfile # read centers and radii from a list + -L listfile # read centers and radii from a list, output list rows + -n # don't use cone limits as a filter + -r racol:[hdr] # RA column name, units (def: RA:h) + -x # append RA_CEN, DEC_CEN, RAD_CEN, CONE_KEY cols + -X # append RA_CEN, DEC_CEN, RAD_CEN, CONE_KEY cols, output all rows + + + + +=head1 DESCRIPTION + + + + +Funcone performs a cone search on the RA and Dec columns of a FITS +binary table. The distance from the center RA, Dec position to the RA, +Dec in each row in the table is calculated. Rows whose distance is +less than the specified radius are output. + + +The first argument to the program specifies the FITS file, raw event +file, or raw array file. If "stdin" is specified, data are read from +the standard input. Use Funtools Bracket +Notation to specify FITS extensions, and filters. The second +argument is the output FITS file. If "stdout" is specified, the FITS +binary table is written to the standard output. + + +The third and fourth required arguments are the RA and Dec center +position. By default, RA is specified in hours while Dec is specified +in degrees. You can change the units of either of these by appending +the character "d" (degrees), "h" (hours) or "r" (radians). Sexagesimal +notation is supported, with colons or spaces separating hms and dms. +(When using spaces, please ensure that the entire string is quoted.) + + +The fifth required argument is the radius of the cone search. By default, +the radius value is given in degrees. The units can be changed by appending +the character "d" (degrees), "r" (radians), "'" (arc minutes) or +'"' (arc seconds). + + +By default, all +columns of the input file are copied to the output file. Selected +columns can be output using an optional sixth argument in the form: + + "column1 column1 ... columnN" + +A seventh argument allows you to output selected columns from the list +file when B<-j> switch is used. Note that the RA and Dec columns +used in the cone calculation must not be de-selected. + + +Also by default, the RA and Dec column names are named "RA" and "Dec", +and are given in units of hours and degrees respectively. You can +change both the name and the units using the -r [RA] and/or -d [Dec] +switches. Once again, one of "h", "d", or "r" is appended to the +column name to specify units but in this case, there must be a colon ":" +between the name and the unit specification. + + +If the B<-l [listfile]> switch is used, then one or more of the +center RA, center Dec, and radius can be taken from a list file (which +can be a FITS table or an ASCII column text file). In this case, the +third (center RA), fourth (center Dec), and fifth (radius) command +line arguments can either be a column name in the list file (if that +parameter varies) or else a numeric value (if that parameter is +static). When a column name is specified for the RA, Dec, or radius, +you can append a colon followed by "h", "d", or "r" to specify units +(also ' and " for radius). The cone search algorithm is run once for +each row in the list, taking RA, Dec, and radius values from the +specified columns or from static numeric values specified on the +command line. + + +When using a list, all valid rows from each iteration are written to a +single output file. Use the B<-x> switch to help delineate which +line of the list file was used to produce the given output row(s). +This switch causes the values for the center RA, Dec, radius, and row +number to be appended to the output file, in columns called RA_CEN, +DEC_CEN, RAD_CEN and CONE_KEY, respectively. Alternatively, the +B<-j> (join) switch will append all columns from the list row to +the output row (essentially a join of the list row and input row), +along with the CONE_KEY row number. These two switches are mutually +exclusive. + + +The B<-X> and B<-J> switches write out the same data as their +lower case counterparts for each row satisfying a cone search. In +addition, these switches also write out rows from the event file that +do not satisfy any cone search. In such cases, that CONE_KEY column +will be given a value of -1 and the center and list position information +will be set to zero for the given row. Thus, all rows of the input +event file are guaranteed to be output, with rows satisfying at least +one cone search having additional search information. + + +The B<-L> switch acts similarly to the B<-l> switch in that it +takes centers from a list file. However, it also implicitly sets the +-j switch, so that output rows are the join of the input event row and +the center position row. In addition, this switch also writes out all +center position rows for which no event satisfies the cone search +criteria of that row. The CONE_KEY column will be given a value of -2 +for center rows that were not close to any data row and the event +columns will be zeroed out for such rows. In this way, all centers +rows are guaranteed to be output at least once. + + +If any of "all row" switches (B<-X>, B<-J>, or B<-L>) are +specified, then a new column named JSTAT is added to the output table. +The positive values in this column indicate the center position row number +(starting from 1) in the list file that this data row successful matched +in a cone search. A value of -1 means that the data row did not match +any center position. A value of -2 means that the center position was +not matched by any data row. + + +Given a center position and radius, the cone search algorithm +calculates limit parameters for a box enclosing the specified cone, +and only tests rows whose positions values lie within those limits. +For small files, the overhead associated with this cone limit +filtering can cause the program to run more slowly than if all events +were tested. You can turn off cone limit filtering using the B<-n> +switch to see if this speeds up the processing (especially useful when +processing a large list of positions). + + +For example, the default cone search uses columns "RA" and "Dec" in hours +and degrees (respectively) and RA position in hours, Dec and radius in degrees: + + funone in.fits out.fits 23.45 34.56 0.01 + +To specify the RA position in degrees: + + funcone in.fits out.fits 23.45d 34.56 0.01 + +To get RA and Dec from a list but use a static value for radius (and +also write identifying info for each row in the list): + + funcone -x -l list.txt in.fits out.fits MYRA MYDec 0.01 + +User specified columns in degrees, RA position in hours (sexagesimal +notation), Dec position in degrees (sexagesimal notation) and radius +in arc minutes: + + funcone -r myRa:d -d myDec in.fits out.fits 12:30:15.5 30:12 15' + + + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + +=cut diff --git a/doc/pod/fundisp.pod b/doc/pod/fundisp.pod new file mode 100644 index 0000000..8f36d86 --- /dev/null +++ b/doc/pod/fundisp.pod @@ -0,0 +1,484 @@ +=pod + +=head1 NAME + + + +B + + + +=head1 SYNOPSIS + + + + + +fundisp [-f format] [-l] [-n] [-T] [columns|bitpix=n] + + + + + +=head1 OPTIONS + + + + + + -f # format string for display + -l # display image as a list containing the columns X, Y, VAL + -n # don't output header + -F [c] # use specified character as column separator (def: space) + -T # output in rdb/starbase format (tab separators) + + + + +=head1 DESCRIPTION + + + + +B displays the data in the specified +FITS Extension +and/or +Image Section +of a FITS file, or in a +Section +of a non-FITS array or raw event file. + +The first argument to the program specifies the FITS input image, array, or +raw event file to display. If "stdin" is specified, data are read from +the standard input. Use Funtools Bracket +Notation to specify FITS extensions, image sections, and filters. + + +If the data being displayed are columns (either in a FITS binary table +or a raw event file), the individual rows are listed. Filters can be +added using bracket notation. Thus: + + [sh] fundisp "test.ev[time-(int)time>.15]" + X Y PHA PI TIME DX DY + ------- ------- ------- --------- ---------------- ---------- ---------- + 10 8 10 8 17.1600 8.50 10.50 + 9 9 9 9 17.1600 9.50 9.50 + 10 9 10 9 18.1600 9.50 10.50 + 10 9 10 9 18.1700 9.50 10.50 + 8 10 8 10 17.1600 10.50 8.50 + 9 10 9 10 18.1600 10.50 9.50 + 9 10 9 10 18.1700 10.50 9.50 + 10 10 10 10 19.1600 10.50 10.50 + 10 10 10 10 19.1700 10.50 10.50 + 10 10 10 10 19.1800 10.50 10.50 + +[NB: The FITS binary table test file test.ev, as well as the FITS +image test.fits, are contained in the funtools funtest directory.] + + +When a table is being displayed using B, a second optional +argument can be used to specify the columns to display. For example: + + [sh] fundisp "test.ev[time-(int)time>=.99]" "x y time" + X Y TIME + -------- -------- --------------------- + 5 -6 40.99000000 + 4 -5 59.99000000 + -1 0 154.99000000 + -2 1 168.99000000 + -3 2 183.99000000 + -4 3 199.99000000 + -5 4 216.99000000 + -6 5 234.99000000 + -7 6 253.99000000 + + + +The special column B<$REGION> can be specified to display the +region id of each row: + + [sh $] fundisp "test.ev[time-(int)time>=.99&&annulus(0 0 0 10 n=3)]" 'x y time $REGION' + X Y TIME REGION + -------- -------- --------------------- ---------- + 5 -6 40.99000000 3 + 4 -5 59.99000000 2 + -1 0 154.99000000 1 + -2 1 168.99000000 1 + -3 2 183.99000000 2 + -4 3 199.99000000 2 + -5 4 216.99000000 2 + -6 5 234.99000000 3 + -7 6 253.99000000 3 + + +Here only rows with the proper fractional time and whose position also is +within one of the three annuli are displayed. + +Columns can be excluded from display using a minus sign before the +column: + + [sh $] fundisp "test.ev[time-(int)time>=.99]" "-time" + X Y PHA PI DX DY + -------- -------- -------- ---------- ----------- ----------- + 5 -6 5 -6 5.50 -6.50 + 4 -5 4 -5 4.50 -5.50 + -1 0 -1 0 -1.50 0.50 + -2 1 -2 1 -2.50 1.50 + -3 2 -3 2 -3.50 2.50 + -4 3 -4 3 -4.50 3.50 + -5 4 -5 4 -5.50 4.50 + -6 5 -6 5 -6.50 5.50 + -7 6 -7 6 -7.50 6.50 + +All columns except the time column are displayed. + +The special column B<$N> can be specified to display the +ordinal value of each row. Thus, continuing the previous example: + + fundisp "test.ev[time-(int)time>=.99]" '-time $n' + X Y PHA PI DX DY N + ------- -------- -------- ---------- ----------- ----------- ---------- + 5 -6 5 -6 5.50 -6.50 337 + 4 -5 4 -5 4.50 -5.50 356 + -1 0 -1 0 -1.50 0.50 451 + -2 1 -2 1 -2.50 1.50 465 + -3 2 -3 2 -3.50 2.50 480 + -4 3 -4 3 -4.50 3.50 496 + -5 4 -5 4 -5.50 4.50 513 + -6 5 -6 5 -6.50 5.50 531 + -7 6 -7 6 -7.50 6.50 550 + +Note that the column specification is enclosed in single quotes to protect +'$n' from begin expanded by the shell. + + +In general, the rules for activating and de-activating columns are: + + +=over 4 + + + + +=item * + +If only exclude columns are specified, then all columns but +the exclude columns will be activated. + + +=item * + +If only include columns are specified, then only the specified columns +are activated. + + +=item * + +If a mixture of include and exclude columns are specified, then +all but the exclude columns will be active; this last case +is ambiguous and the rule is arbitrary. + + +=back + + +In addition to specifying columns names explicitly, the special +symbols B<+> and B<-> can be used to activate and +de-activate B columns. This is useful if you want to +activate the $REGION column along with all other columns. According +to the rules, the syntax "$REGION" only activates the region column +and de-activates the rest. Use "+ $REGION" to activate all +columns as well as the region column. + + +If the data being displayed are image data (either in a FITS primary +image, a FITS image extension, or an array file), an mxn pixel display +is produced, where m and n are the dimensions of the image. By +default, pixel values are displayed using the same data type as in the +file. However, for integer data where the BSCALE and BZERO header parameters +are present, the data is displayed as floats. In either case, the +display data type can be overridden using an optional second argument +of the form: + + bitpix=n + +where n is 8,16,32,-32,-64, for unsigned char, short, int, float and double, +respectively. + + +Of course, running B on anything but the smallest image +usually results in a display whose size makes it unreadable. +Therefore, one can uses bracket notation (see below) +to apply section and/or blocking to the image before generating a +display. For example: + + [sh] fundisp "test.fits[2:6,2:7]" bitpix=-32 + 2 3 4 5 6 + ---------- ---------- ---------- ---------- ---------- + 2: 3.00 4.00 5.00 6.00 7.00 + 3: 4.00 5.00 6.00 7.00 8.00 + 4: 5.00 6.00 7.00 8.00 9.00 + 5: 6.00 7.00 8.00 9.00 10.00 + 6: 7.00 8.00 9.00 10.00 11.00 + 7: 8.00 9.00 10.00 11.00 12.00 + + + +Note that is is possible to display a FITS binary table as an image +simply by passing the table through B first: + + [sh] ./funimage test.ev stdout | fundisp "stdin[2:6,2:7]" bitpix=8 + 2 3 4 5 6 + ------- ------- ------- ------- ------- + 2: 3 4 5 6 7 + 3: 4 5 6 7 8 + 4: 5 6 7 8 9 + 5: 6 7 8 9 10 + 6: 7 8 9 10 11 + 7: 8 9 10 11 12 + + +If the B<-l> (list) switch is used, then an image is displayed as a +list containing the columns: X, Y, VAL. For example: + + fundisp -l "test1.fits[2:6,2:7]" bitpix=-32 + X Y VAL + ---------- ---------- ----------- + 2 2 6.00 + 3 2 1.00 + 4 2 1.00 + 5 2 1.00 + 6 2 1.00 + 2 3 1.00 + 3 3 5.00 + 4 3 1.00 + 5 3 1.00 + 6 3 1.00 + 2 4 1.00 + 3 4 1.00 + 4 4 4.00 + 5 4 1.00 + 6 4 1.00 + 2 5 1.00 + 3 5 1.00 + 4 5 1.00 + 5 5 3.00 + 6 5 1.00 + 2 6 1.00 + 3 6 1.00 + 4 6 1.00 + 5 6 1.00 + 6 6 2.00 + 2 7 1.00 + 3 7 1.00 + 4 7 1.00 + 5 7 1.00 + 6 7 1.00 + + + +If the B<-n> (nohead) switch is used, then no header is output for +tables. This is useful, for example, when fundisp output is being +directed into gnuplot. + + +The B program uses a default set of display formats: + + datatype TFORM format + -------- ----- -------- + double D "%21.8f" + float E "%11.2f" + int J "%10d" + short I "%8d" + byte B "%6d" + string A "%12.12s" + bits X "%8x" + logical L "%1x" + +Thus, the default display of 1 double and 2 shorts gives: + + [sh] fundisp snr.ev "time x y" + + TIME X Y + --------------------- -------- -------- + 79494546.56818075 546 201 + 79488769.94469175 548 201 + ... + +You can change the display format for individual columns or for all +columns of a given data types by means of the -f switch. The format +string that accompanies -f is a space-delimited list of keyword=format +values. The keyword values can either be column names (in which case +the associated format pertains only to that column) or FITS table +TFORM specifiers (in which case the format pertains to all columns +having that data type). For example, you can change the double and +short formats for all columns like this: + + [sh] fundisp -f "D=%22.11f I=%3d" snr.ev "time x y" + + TIME X Y + ---------------------- --- --- + 79494546.56818075478 546 201 + 79488769.94469174743 548 201 + ... + + + +Alternatively, you can change the format of the time and x columns like this: + + [sh] fundisp -f "time=%22.11f x=%3d" snr.ev "time x y" + + TIME X Y + ---------------------- --- -------- + 79494546.56818075478 546 201 + 79488769.94469174743 548 201 + ... + +Note that there is a potential conflict if a column has the same name +as one of the TFORM specifiers. In the examples above, the the "X" +column in the table has the same name as the X (bit) datatype. To +resolve this conflict, the format string is processed such that +TFORM datatype specifiers are checked for first, using a +case-sensitive comparison. If the specified format value is not an +upper case TFORM value, then a case-insensitive check is made on the +column name. This means that, in the examples above, "X=%3d" will refer +to the X (bit) datatype, while "x=%3d" will refer to the X column: + + [sh] fundisp -f "X=%3d" snr.ev "x y" + + X Y + -------- -------- + 546 201 + 548 201 + ... + + [sh] fundisp -f "x=%3d" snr.ev "x y" + + X Y + --- -------- + 546 201 + 548 201 + ... + +As a rule, therefore, it is best always to specify the column name in +lower case and TFORM data types in upper case. + + +The B<-f [format]> will change the format for a single execution +of fundisp. You also can use the B envronment variable +to change the format for all invocations of fundisp. The format of this +environment variable's value is identical to that used with +the B<-f> switch. This global value can be overridden in +individual cases by use of the B<-f [format]> switch. + + +Caveats: Please also note that it is the user's responsibility to +match the format specifier to the column data type correctly. Also +note that, in order to maintain visual alignment between names and +columns, the column name will be truncated (on the left) if the +format width is less than the length of the name. However, truncation +is not performed if the output is in RDB format (using the -T switch). + + +[An older-style format string is supported but deprecated. It +consists of space-delimited C format statements for all data types, +specified in the following order: + + double float int short byte string bit. + +This order of the list is based on the assumption that people generally +will want to change the float formats. + +If "-" is entered instead of a format statement for a given data type, the +default format is used. Also, the format string can be terminated without +specifying all formats, and defaults will be used for the rest of the +list. Note that you must supply a minimum field width, i.e., "%6d" and +"%-6d" are legal, "%d" is not legal. + +By using -f [format], you can change the double and short formats like this: + + [sh] fundisp -f "22.11f - - 3d" snr.ev "time x y" + + TIME X Y + ---------------------- --- --- + 79494546.56818075478 546 201 + 79488769.94469174743 548 201 + ... + +NB: This format is deprecated and will be removed in a future release.] + + +The B<-F[c]> switch can be used to specify a (single-character) +column separator (where the default is a space). Note that column +formatting will almost certainly also add spaces to pad individual +columns to the required width. These can be removed with a program +such as sed, at the cost of generating unaligned columns. For example: + +fundisp -F',' snr.ev'[cir 512 512 .1]' + X, Y, PHA, PI, TIME, DX, DY +--------,--------,--------,--------,---------------------,--------,-------- + 512, 512, 6, 7, 79493997.45854475, 578, 574 + 512, 512, 8, 9, 79494575.58943175, 579, 573 + 512, 512, 5, 6, 79493631.03866175, 578, 575 + 512, 512, 5, 5, 79493290.86521725, 578, 575 + 512, 512, 8, 9, 79493432.00990875, 579, 573 + +fundisp -F',' snr.ev'[cir 512 512 .1]' | sed 's/ *, */,/g' + X,Y,PHA,PI,TIME,DX,DY +--------,--------,--------,--------,---------------------,--------,-------- + 512,512,6,7,79493997.45854475,578,574 + 512,512,8,9,79494575.58943175,579,573 + 512,512,5,6,79493631.03866175,578,575 + 512,512,5,5,79493290.86521725,578,575 + 512,512,8,9,79493432.00990875,579,573 + +fundisp -f "x=%3d y=%3d pi=%1d pha=%1d time=%20.11f dx=%3d dy=%3d" -F',' snr.ev'[cir 512 512 .1]' | sed 's/ *, */,/g' + X,Y,A,I,TIME,DX,DY +---,---,-,-,--------------------,---,--- +512,512,6,7,79493997.45854474604,578,574 +512,512,8,9,79494575.58943174779,579,573 +512,512,5,6,79493631.03866174817,578,575 +512,512,5,5,79493290.86521725357,578,575 +512,512,8,9,79493432.00990875065,579,573 + + + + +If the B<-T> (rdb table) switch is used, the output will conform +to starbase/rdb data base format: tabs will be inserted between +columns rather than spaces. This format is not available when +displaying image pixels (except in conjunction with the B<-l> +switch). + + +Finally, note that B can be used to create column filters from +the auxiliary tables in a FITS file. For example, the following shell code +will generate a good-time interval (GTI) filter for X-ray data files that +contain a standard GTI extension: + + #!/bin/sh + sed '1,/---- .*/d + /^$/,$d' | awk 'tot>0{printf "||"};{printf "time="$1":"$2; tot++}' + +If this script is placed in a file called "mkgti", it can be used in a +command such as: + + fundisp foo.fits"[GTI]" | mkgti > gti.filter + +The resulting filter file can then be used in various funtools programs: + + funcnts foo.fits"[@gti.filter]" ... + +to process only the events in the good-time intervals. + + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + +=cut diff --git a/doc/pod/funds9.pod b/doc/pod/funds9.pod new file mode 100644 index 0000000..e1b5cc2 --- /dev/null +++ b/doc/pod/funds9.pod @@ -0,0 +1,113 @@ +=pod + +=head1 NAME + + + +B + + + +=head1 SYNOPSIS + + + + +Describes how funtools can be integrated into the ds9 Analysis menu. + + + +=head1 DESCRIPTION + + + + + + +SAOImage/DS9 is an astronomical imaging and data visualization +application used by astronomers around the world. DS9 can display +standard astronomical FITS images and binary tables, but also has +support for displaying raw array files, shared memory files, and data +files automatically retrieved via FTP and HTTP. Standard functional +capabilities include multiple frame buffers, colormap and region +manipulation, and many data scaling algorithms. DS9's advanced +features include TrueColor visuals, deep frame buffers, true +PostScript printing, and display of image mosaics. The program's +support of image tiling, "blinking", arbitrary zoom, rotation, and pan +is unparalleled in astronomy. It also has innovative support for +automatic retrieval and display of standard image data such as the +Digital Sky Survey (using servers at SAO, StScI, or ESO). + + +DS9 can communicate with external programs such as Funtools using the +XPA +messaging system. In addition, programs can be integrated directly +into the DS9 GUI by means of a configurable Analysis menu. By +default, the DS9 Analysis menu contains algorithms deemed essential to +the core functions of DS9, e.g., display cross-cuts of data, +iso-intensity contours, and WCS grids. However, new programs can be +added to DS9 by creating a set-up file which can be loaded into DS9 +to reconfigure the Analysis menu. + + +The basic format of the analysis set-up file is: + + # + # Analysis command descriptions: + # menu label/description + # file templates for this command + # "menu" (add to menu) |"bind" (bind to key) + # analysis command line + + +For example, the funcnts program can be specified in this way: + + Funcnts (counts in source/bkgd regions; options: none) + * + menu + funcnts $filename $regions(source,,) $regions(background,,) | $text + +As shown above, DS9 supports a macro facility to provide information +as well as task support to command lines. For example, the $regions +macro is expanded by DS9 to provide the current source and/or +background region to the analysis command. The $text macro is expanded +to generate a text window display. It also is possible to query for +parameters using a $param macro, plot data using a $plot macro, +etc. See the DS9 documentation for further details. + + +A set-up file called funtools.ds9 will +load some useful Funtools applications (counts in regions, radial +profile, X-ray light curve and energy spectrum, 1D histogram) into the DS9 +Analysis menu (version 2.1 and above). The file resides in the bin +directory where Funtools programs are installed. It can be manually +loaded into DS9 from the B option of +the B menu. Alternatively, you can tell DS9 to load +this file automatically at start-up time by adding the pathname to the +B->B->B->Analysis +File menu option. (NB: make sure you select +B->B->B after setting +the pathname.) + + +The tasks in this setup file generally process the original disk-based +FITS file. Funcnts-based results (radial profile, counts in regions) +are presented in WCS units, if present in the FITS header. For +situations where a disk file is not available (e.g., image data +generated and sent to DS9's 'fits' XPA access point), versions of the +radial profile and counts in regions tasks also are also offered +utilizing DS9's internal image data. Results are presented in pixels. +Aside from the units, the results should be identical to the file-based +results. + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + + +=cut diff --git a/doc/pod/funenv.pod b/doc/pod/funenv.pod new file mode 100644 index 0000000..0717a17 --- /dev/null +++ b/doc/pod/funenv.pod @@ -0,0 +1,349 @@ +=pod + +=head1 NAME + + + +B + + + +=head1 SYNOPSIS + + + + +Describes the environment variables which can be used to tailor the overall +Funtools environment. + + + +=head1 DESCRIPTION + + + + + +The following environment variables are supported by Funtools: + + +=over 4 + + + + + +=item * + +B + + +The B environment variable specifies the +default FITS extension name when FunOpen() is called on a file lacking +a primary image. Thus, + + setenv FITS_EXTNAME "NEWEV" + +will allow you to call FunOpen() on files without specifying NEWEV in +the +Funtools bracket specification. +If no FITS_EXTNAME variable is defined and the extension name also is +not passed in the bracket specification, then the default will be to +look for standard X-ray event table extension names "EVENTS" or +"STDEVT" (we are, after all, and X-ray astronomy group at heart!). + + + + +=item * + +B + + +The B environment variable specifies the +default FITS extension number when FunOpen() is called on a file lacking +a primary image. Thus, + + setenv FITS_EXTNUM 7 + +will allow you to call FunOpen() on files to open the seventh +extension without specifying the number in the +Funtools bracket specification. + + + + +=item * + +B and B + + +These environment variable specifies the default binning key for +FITS binary tables and raw event files, respectively. They can be +over-ridden using the B keyword in a +Funtools bracket specification. +The value of each environment variable +is a pair of comma-delimited columns, enclosed in parentheses, to use +for binning. For example, if you want to bin on detx and dety by +default, then use: + + setenv FITS_BINCOLS "(detx,dety)" + +in preference to adding a bincols specification to each filename: + + foo.fits[bincols=(detx,dety)] + + + + + +=item * + +B and B + + +These environment variable specifies the default bitpix value for +binning FITS binary tables and raw event files, respectively. They can +be over-ridden using the B keyword in a +Funtools bracket specification. The value +of each environment variable is one of the standard FITS bitpix values +(8,16,32,-32,-64). For example, if you want binning routines to +create a floating array, then use: + + setenv FITS_BITPIX -32 + +in preference to adding a bitpix specification to each filename: + + foo.fits[bitpix=-32] + + + + + +=item * + +B + + +The B environment variable specifies the default +definition of an array file for Funtools. +It is used if there is no array specification passed in the +B directive in a +Non-FITS Array specification. +The value of the environment variable is a valid array specification such as: + + setenv ARRAY "s100.150" + foo.arr[ARRAY()] + +This can be defined in preference to adding the specification to each filename: + + foo.arr[ARRAY(s100.150)] + + + + + +=item * + +B + + +The B environment variable specifies the default +definition of an raw event file for Funtools. +It is used if there is no EVENTS specification passed in the +B directive in a +Non-FITS EVENTS specification. +The value of the environment variable is a valid EVENTS specification such as: + + setenv EVENTS "x:J:1024,y:J:1024,pi:I,pha:I,time:D,dx:E:1024,dx:E:1024" + foo.ev[EVENTS()] + +This can be defined in preference to adding the specification to each filename: + + foo.ev[EVENTS(x:J:1024,y:J:1024,pi:I,pha:I,time:D,dx:E:1024,dx:E:1024)] + + + +=back + + + +The following filter-related environment variables are supported by Funtools: + + +=over 4 + + + + + + +=item * + +B + + +The B environment variable specifies how to +build a filter. There are three possible methods: + + +=over 4 + + + + +=item * + +process or p + + +The filter is compiled and linked against the funtools library (which +must therefore be accessible in the original install directory) to produce +a slave program. This program is fed events or image data and returns +filter results. + + + +=item * + +dynamic or d (gcc only) + + +The filter is compiled and linked against the funtools library (which +must therefore be accessible in the original install directory) to produce +a dynamic shared object, which is loaded into the funtools program and +executed as a subroutine. (Extensive testing has shown that, contrary to +expectations, this method is no faster than using a slave process.) + + + +=item * + +contained or c + + +The filter and all supporting region code is compiled and linked +without reference to the funtools library to produce a slave program +(which is fed events or image data and returns filter results). This method +is slower than the other two, because of the time it takes to compile the +region filtering code. It is used by stand-alone programs such as ds9, +which do not have access to the funtools library. + + +=back + + + +By default, B is generally used for gcc compilers and +B for other compilers. However the filter building algorithm +will check for required external files and will use B is +these are missing. + + + + +=item * + +B + + +The B environment variable is used by core +row-processing Funtools programs (funtable, fundisp, funcnts, funhist, +funmerge, and funcalc) to set the maximum number of rows read at once +(i.e. it sets the third argument to the FunTableRowGet() call). The +default is 8192. Note that this variable is a convention only: it will +not be a part of a non-core Funtools program unless code is explicitly +added, since each call to FunTableRowGet() specifies its own maximum +number of rows to read. NB: if you make this value very large, you +probably will need to increase B (see below) as well. + + + + +=item * + +B + + +The B environment variable is used to limit the +max buffer size that will be allocated to hold table row data. This +buffer size is calculated to be the row size of the table multiplied +by the maximum number of rows read at once (see above). Since the +row size is unlimited (and we have examples of it being larger than 5 +Mb), it is possible that the total buffer size will exceed the machine +capabilities. We therefore set a default value of 5Mb for the max buffer +size, and adjust maxrow so that the total size calculated is less than +this max buffer size. (If the row size is greater than this max buffer +size, then maxrow is set to 1.) This environment variable will change +the max buffer size allowed. + + + + +=item * + +B + + +The B environment variable specifies the compiler to +use for compiling a filter specification. You also can use the B +environment variable. If neither has been set, then gcc will be used +if available. Otherwise cc is used if available. + + + + +=item * + +B + + +The B environment variable specifies extra options +to add to a filter compile command line. In principle, you can add libraries, +include files, and compiler switches. This variable should be used with care. + + + + +=item * + +B + + +The B environment variable specifies the temporary +directory for filter compilation intermediate files. You also can use +the B and B variables. By default, /tmp is used +as the temporary directory. + + + + +=item * + +B + + +The B environment variable specifies whether the +intermediate filter files (i.e. C source file and compile log file) +should be saved after a filter is built. The default is "false", so that +these intermediate files are deleted. This variable is useful for debugging, +but care should be taken to reset its value to false when debugging is +complete. + + + +=back + + + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + + +=cut diff --git a/doc/pod/funfiles.pod b/doc/pod/funfiles.pod new file mode 100644 index 0000000..7efb464 --- /dev/null +++ b/doc/pod/funfiles.pod @@ -0,0 +1,1019 @@ +=pod + +=head1 NAME + + + +B + + + +=head1 SYNOPSIS + + + + +This document describes the data file formats (FITS, array, raw +events) as well as the file types (gzip, socket, etc.) supported +by Funtools. + + + +=head1 DESCRIPTION + + + + + +Funtools supports FITS images and binary tables, and binary files +containing array (homogeneous) data or event (heterogeneous) data. +IRAF-style brackets are appended to the filename to specify various +kinds of information needed to characterize these data: + + file[ext|ind|ARRAY()|EVENTS(),section][filters] + or + file[ext|ind|ARRAY()|EVENTS(),section,filters] + +where: + + +=over 4 + + + + +=item * + +B is the Funtools file name + + +=item * + +B is the FITS extension name + + +=item * + +B is the FITS extension number + + +=item * + +B is an array specification + + +=item * + +B is an event specification + + +=item * + +B
is the image section specification + + +=item * + +B are spatial region and table (row) filters + + +=back + + + +B + +Funtools programs (and the underlying libraries) support the +following data file formats: + + +=over 4 + + + + +=item * + +FITS images (and image extensions) + + +=item * + +FITS binary tables + + +=item * + +binary files containing an array of homogeneous data + + +=item * + +binary files containing events, i.e. records of heterogeneous data + + +=item * + +column-based text files, which are documented here + + +=item * + +non-disk files and lists of files + + +=back + + +Information needed to identify and characterize +the event or image data can be specified on the command line +using IRAF-style bracket notation appended to the filename: + + foo.fits # open FITS default extension + image.fits[3] # open FITS extension #3 + events.fits[EVENTS] # open EVENTS extension + array.file[ARRAY(s1024)] # open 1024x1024 short array + events.file[EVENTS(x:1024,y:1024...)] # open non-FITS event list + +Note that in many Unix shells (e.g., csh and tcsh), filenames must +be enclosed in quotes to protect the brackets from shell processing. + +B + +When FunOpen() opens a FITS file +without a bracket specifier, the default behavior is to look for a +valid image in the primary HDU. In the absence of a primary image, +Funtools will try to open an extension named either B or +B, if one of these exists. This default behavior supports +both FITS image processing and standard X-ray event list processing +(which, after all, is what we at SAO/HEAD do). + + +In order to open a FITS binary table or image extension explicitly, it +is necessary to specify either the extension name or the extension +number in brackets: + + foo.fits[1] # open extension #1: the primary HDU + foo.fits[3] # open extension #3 of a FITS file + foo.fits[GTI] # open GTI extension of a FITS file + +The ext argument specifies the name of the FITS extension (i.e. the +value of the EXTENSION header parameter in a FITS extension), while +the index specifies the value of the FITS EXTVER header parameter. +Following FITS conventions, extension numbers start at 1. + + +When a FITS data file is opened for reading using +FunOpen(), the specified extension +is automatically located and is used to initialize the Funtools internal +data structures. + +B + +In addition to FITS tables, Funtools programs and libraries can operate +on non-FITS files containing heterogeneous event records. To specify +such an event file, use: + + + +=over 4 + + + + +=item * + +file[EVENTS(event-spec)] + + +=item * + +file[EVENTS()] + + +=back + + +where B is a string that specified the names, data +types, and optional image dimensions for each element of the event +record: + + +=over 4 + + + + +=item * + +[name]:[n][type]:[(lodim:)hidim] + + +=back + + + + +Data types follow standard conventions for FITS binary tables, but include +two extra unsigned types ('U' and 'V'): + + +=over 4 + + + + +=item * + +B -- unsigned 8-bit char + + +=item * + +B -- signed 16-bit int + + +=item * + +B -- signed 32-bit int + + +=item * + +B -- signed 64-bit int + + +=item * + +B -- 32-bit float + + +=item * + +B -- 64-bit float + + +=item * + +B -- unsigned 16-bit int + + +=item * + +B -- unsigned 32-bit int + + +=back + + +An optional integer value B can be prefixed to the type to indicate +that the element is an array of n values. For example: + + foo.fits[EVENTS(x:I,y:I,status:4J)] + +defines x and y as 16-bit ints and status as an array of 4 32-bit ints. + + +Furthermore, image dimensions can be attached to the event specification +in order to tell Funtools how to bin the events into an image. They +follow the conventions for the FITS TLMIN/TLMAX keywords. If the low +image dimension is not specified, it defaults to 1. Thus: + + + +=over 4 + + + + +=item * + +RAWX:J:1:100 + + +=item * + +RAWX:J:100 + + +=back + + +both specify that the dimension of this column runs from 1 to 100. + + +NB: it is required that all padding be specified in the record +definition. Thus, when writing out whole C structs instead of +individual record elements, great care must be taken to include +the compiler-added padding in the event definition. + + +For example, suppose a FITS binary table has the following set of column +definitions: + + TTYPE1 = 'X ' / Label for field + TFORM1 = '1I ' / Data type for field + TLMIN1 = 1 / Min. axis value + TLMAX1 = 10 / Max. axis value + TTYPE2 = 'Y ' / Label for field + TFORM2 = '1I ' / Data type for field + TLMIN2 = 2 / Min. axis value + TLMAX2 = 11 / Max. axis value + TTYPE3 = 'PHA ' / Label for field + TFORM3 = '1I ' / Data type for field + TTYPE4 = 'PI ' / Label for field + TFORM4 = '1J ' / Data type for field + TTYPE5 = 'TIME ' / Label for field + TFORM5 = '1D ' / Data type for field + TTYPE6 = 'DX ' / Label for field + TFORM6 = '1E ' / Data type for field + TLMIN6 = 1 / Min. axis value + TLMAX6 = 10 / Max. axis value + TTYPE7 = 'DY ' / Label for field + TFORM7 = '1E ' / Data type for field + TLMIN7 = 3 / Min. axis value + TLMAX7 = 12 / Max. axis value + + +An raw event file containing these same data would have the event +specification: + + EVENTS(X:I:10,Y:I:2:11,PHA:I,PI:J,TIME:D,DX:E:10,DY:E:3:12) + + + +If no event specification string is included within the EVENTS() operator, +then the event specification is taken from the B environment +variable: + + setenv EVENTS "X:I:10,Y:I:10,PHA:I,PI:J,TIME:D,DX:E:10,DY:E:10" + + + +In addition to knowing the data structure, it is necessary to know the +I ordering of the data, i.e., whether or not the data is +in I format, so that we can convert to the native +format for this platform. This issue does not arise for FITS Binary +Tables because all FITS files use big-endian ordering, regardless of +platform. But for non-FITS data, big-endian data produced on a Sun +workstation but read on a Linux PC needs to be byte-swapped, since PCs +use little-endian ordering. To specify an ordering, use the +I or I keywords on the command-line +or the EVENTS_BIGENDIAN or EVENTS_ENDIAN environment variables. The +value of the I variables should be "true" or "false", +while the value of the I variables should be "little" or +"big". + + +For example, a PC can access data produced by a Sun using: + + hrc.nepr[EVENTS(),bigendian=true] +or + hrc.nepr[EVENTS(),endian=big] +or + setenv EVENTS_BIGENDIAN true +or + setenv EVENTS_ENDIAN big + +If none of these are specified, the data are assumed to follow the +format for that platform and no byte-swapping is performed. + +B + +In addition to FITS images, Funtools programs and libraries can operate +on non-FITS files containing arrays of homogeneous data. To specify +an array file, use: + + +=over 4 + + + + +=item * + +file[ARRAY(array-spec)] + + +=item * + +file[ARRAY()] + + +=back + + + +where array-spec is of the form: + + +=over 4 + + + + +=item * + +[type][dim1][.dim2][:skip][endian] + + +=back + + + +and where [type] is: + + +=over 4 + + + + +=item * + +b (8-bit unsigned char) + + +=item * + +s (16-bit short int) + + +=item * + +u (16-bit unsigned short int) + + +=item * + +i (32-bit int) + + +=item * + +r,f (32-bit float) + + +=item * + +d (64-bit float) + + +=back + + + + +The dim1 specification is required, but dim2 is optional and defaults +to dim1. The skip specification is optional and defaults to 0. The +optional endian specification can be 'l' or 'b' and defaults to the +endian type for the current machine. + + +If no array specification is included within the ARRAY() operator, +then the array specification is taken from the B environment +variable. For example: + + + foo.arr[ARRAY(r512)] # bitpix=-32 dim1=512 dim2=512 + foo.arr[ARRAY(r512.400)] # bitpix=-32 dim1=512 dim2=400 + foo.arr[ARRAY(r512.400]) # bitpix=-32 dim1=512 dim2=400 + foo.arr[ARRAY(r512.400:2880)] # bitpix=-32 dim1=512 dim2=400 skip=2880 + foo.arr[ARRAY(r512l)] # bitpix=-32 dim1=512 dim2=512 endian=little + setenv ARRAY "r512.400:2880" + foo.arr[ARRAY()] # bitpix=-32 dim1=512 dim2=400 skip=2880 + + +B + +Once a data file (and possibly, a FITS extension) has been specified, +the next (optional) part of a bracket specification can be used to +select image B
information, i.e., to specify the x,y +limits of an image section, as well as the blocking factor to apply to +that section. This information can be added to any file specification but +only is used by Funtools image processing routines. + + +The format of the image section specification is one of the following: + + +=over 4 + + + + +=item * + +file[xy0:xy1,block] + + +=item * + +file[x0:x1,y0:y1,block] + + +=item * + +file[x0:x1,*,block] + + +=item * + +file[*,y0:y1,block] + + +=item * + +file[*,block] + + +=back + + +where the limit values can be ints or "*" for default. A single "*" +can be used instead of val:val, as shown. Note that blocking is +applied to the section after it is extracted. + + +In addition to image sections specified by the lo and hi x,y limits, image +sections using center positions can be specified: + + +=over 4 + + + + +=item * + +file[dim1@xcen,dim2@ycen] + + +=item * + +file[xdim2@xcen@ycen] + + +=item * + +file[dim1@xcen,dim2@ycen,block] + + +=item * + +file[dim@xcen@ycen,block] + + +=back + + +Note that the (float) values for dim, dim1, dim2, xcen, ycen must be +specified or else the expression does not make sense! + + +In all cases, block is optional and defaults to 1. An 's' or 'a' can +be appended to signify "sum" or "average" blocking (default is "sum"). +Section specifications are given in image coordinates by default. If you +wish to specify physical coordinates, add a 'p' as the last character +of the section specification, before the closing bracket. +For example: + + + +=over 4 + + + + +=item * + +file[-8:-7,-8:-7p] + + +=item * + +file[-8:-7,-8:-7,2p] + + +=back + + + +A section can be specified in any Funtools file name. If the operation +to be applied to that file is an imaging operation, then the +specification will be utilized. If the operation is purely a table +operation, then the section specification is ignored. + + +Do not be confused by: + + foo.fits[2] + foo.fits[*,2] + +The former specifies opening the second extension of the FITS file. +The latter specifies application of block 2 to the image section. + + +Note that the section specification must come after +any of FITS B name or B number, +but all sensible defaults are supported: + + +=over 4 + + + + +=item * + +file[ext] + + +=item * + +file[ext,index] + + +=item * + +file[index] + + +=item * + +file[ext,section] + + +=item * + +file[ext,index,section] + + +=item * + +file[index,section] + + +=item * + +file[section] + + +=back + + + +B + +If a FITS binary table or a non-FITS raw event file is to be binned +into a 2D image (e.g., using the +funimage +program), it is necessary to specify the two columns to be used for the +binning, as well as the dimensions of the image. Funtools first looks +for a specifier of the form: + + bincols=([xnam[:tlmin[:tlmax:[binsiz]]]],[ynam[:tlmin[:tlmax[:binsiz]]]]) + +in bracket syntax, and uses the column names thus specified. The tlmin, tlmax, +and binsiz specifiers determine the image binning dimensions using: + + dim = (tlmax - tlmin)/binsiz (floating point data) + dim = (tlmax - tlmin)/binsiz + 1 (integer data) + +These tlmin, tlmax, and binsiz specifiers can be omitted if TLMIN, +TLMAX, and TDBIN header parameters are present in the FITS binary +table header, respectively. If only one parameter is specified, it is +assumed to be tlmax, and tlmin defaults to 1. If two parameters are +specified, they are assumed to be tlmin and tlmax. + +For example, to bin an HRC event list columns "VPOS" and "UPOS", use: + + hrc.nepr[bincols=(VPOS,UPOS)] + +or + + hrc.nepr[bincols=(VPOS:49152,UPOS:4096)] + +Note that you can optionally specify the dimensions of these columns +to cover cases where neither TLMAX keywords are defined in +the header. If either dimension is specified, then both must be specified. + + +You can set the FITS_BINCOLS or EVENTS_BINCOLS environment variable as +an alternative to adding the "bincols=" specifier to each file name +for FITS binary tables and raw event files, respectively. If no +binning keywords or environment variables are specified, or if the +specified columns are not in the binary table, the Chandra parameters +CPREF (or PREFX) are searched for in the FITS binary table header. +Failing this, columns named "X" and "Y" are sought. If these are not +found, the code looks for columns containing the characters "X" and +"Y". Thus, you can bin on "DETX" and "DETX" columns without +specifying them, if these are the only column names containing the "X" +and "Y" characters. + + +Ordinarily, each event or row contributes one count to an image pixel +during the 2D binning process. Thus, if five events all have the same +(x,y) position, the image pixel value for that position will have a +value of five. It is possible to specify a variable contribution +for each event by using the vcol=[colname] filter spec: + + vcol=[colname] + +The vcol colname is a column containing a numeric value in each event row +that will be used as the contribution of the given event to its image +pixel. For example, consider an event file that has the following content: + + x:e:4 y:e:4 v:e + ------ ------ ---- + 1 1 1.0 + 2 2 2.0 + 3 3 3.0 + 4 4 0.0 + 1 1 1.0 + 2 2 2.0 + 3 3 3.0 + 4 4 4.0 + +There are two events with x,y value of (1,1) so ordinarily a 2D image will +have a value of 2 in the (1,1) pixel. If the v column is specified as the +value column: + + foo.fits'[vcol=v]' + +then each pixel will contain the additive sum of the associated (x,y) +column values from the v column. For example, image pixel (1,1) will +contain 1. + 1. = 2, image pixel (2,2) will contain (2 + 2) = 4, etc. + + +An important variation on the use of a value column to specify the +contribution an event makes to an image pixel is when the value column +contains the reciprocal of the event contribution. For this case, the +column name should be prefixed with a / (divide sign) thus: + + foo.fits'[vcol=/v]' + +Each image pixel value will then be the sum of the reciprocals of the value +column. A zero in the value column results in NaN (not a number). +Thus, in the above example, image pixel (1.1) will contain 1/1 + 1/1 = 2, +image pixel (2,2) will contain (1/2 + 1/2) = 1, etc. Image pixel (4,4) +will contain (1/0 + 1/4) = NaN. + + +You can set the FITS_VCOL or EVENTS_VCOL environment variable as +an alternative to adding the "vcol=" specifier to each file name +for FITS binary tables and raw event files, respectively. + + +Finally, when binning events, the data type of the resulting 2D image +must be specified. This can be done with the "bitpix=[n]" keyword in +the bracket specification. For example: + + events.fits[bincols=(VPOS,UPOS),bitpix=-32] + +will create a floating point image binned on columns VPOS and UPOS. +If no bitpix keyword is specified, bitpix=32 is assumed. As with +bincols values, you also can use the FITS_BITPIX and EVENTS_BITPIX +environment variables to set this value for FITS binary tables and +raw event files, respectively. + + +The B program also allows you to create a 1D image projection +along any column of a table by using the B +filter specification and specifying a single column. +For example, the following command projects a 1D image along +the chipx column of a table: + + funimage ev.fits'[bincols=chipx]' im.fits + +See funimage for more +information about creating 1D and 2D images. + + +Finally, please note that Funtools supports most FITS standards. +We will add missing support as required by the community. In general, +however, we do not support non-standard extensions. For example, we +sense the presence of the binary table 'variable length array' +proposed extension and we pass it along when copying and filtering +files, but we do not process it. We will add support for new standards +as they become official. + +B + +Note that, in addition extensions and image sections, Funtools bracket +notation can be used to specify table and spatial region filters. These +filters are always placed after the image section information. They +can be specified in the same bracket or in a separate bracket +immediately following: + + +=over 4 + + + + +=item * + +file[ext|ind|ARRAY()|EVENTS(),section][filters] + + +=item * + +file[ext|ind|ARRAY()|EVENTS(),section,filters] + + +=back + + +where: + + +=over 4 + + + + +=item * + +B is the Funtools file name + + +=item * + +B is an array specification + + +=item * + +B is an event list specification + + +=item * + +B is the FITS extension name + + +=item * + +B is the FITS extension number + + +=item * + +B
is the image section to extract + + +=item * + +B are spatial region and table (row) filters to apply + + +=back + + + +The topics of table and region filtering are covered in detail in: + + +=over 4 + + + + +=item * + +Table Filtering + + +=item * + +Spatial Region Filtering + + +=back + + + +B + +The specified B usually is an ordinary disk file. In +addition, gzip'ed files are supported in Funtools: gzip'ed input files +are automatically uncompressed as they are read, and gzip'ed output +files are compressed as they are written. NB: if a FITS binary table +is written in gzip format, the number of rows in the table will be set +to -1. Such a file will work with Funtools programs but will not work +with other FITS programs such as ds9. + + +The special keywords "stdin" and "stdout" designate Unix standard +input and standard output, respectively. The string "-" (hyphen) will +be taken to mean "stdin" if the file is opened for reading and +"stdout" if the file is opened for writing. + + +A file also can be an INET socket on the same or another machine using +the syntax: + + machine:port + +Thus, for example: + + karapet:1428 + +specifies that I/O should be performed to/from port 1428 on the +machine karapet. If no machine name is specified, the default is to +use the current machine: + + :1428 + +This means to open port 1428 on the current machine. Socket support +allows you to generate a distributed pipe: + + on karapet: funtask1 in.fits bynars:1428 + on bynars: funtask2 :1428 out.fits + +The socket mechanism thus supports simple parallel processing using +B. Note that parallel processing using +B is supported via the B
specifier (see +below), and the B specifier, which is part of +Table Filtering. + + +A file also can be a pointer to shared memory using the syntax: + + shm:[id|@key][:size] + +A shared memory segment is specified with a B prefix, +followed by either the shared memory id or the shared memory key +(where the latter is prefixed by the '@' character). The size (in +bytes) of the shared memory segment can then be appended (preceded by +the ':' character). If the size specification is absent, the code will +attempt to determine the length automatically. + +If the open mode contains the string "w+", then the memory segment will be +created if it does not exist. (It also will be released and deleted when the +file is closed.) In the case where a memory segment is being created, the +length of the segment is required. + + +A file also can be Unix piped command (i.e. a program to run) using the syntax: + + "pipe: command arg1 ... argn" + +The output from the command must be a valid FITS file. It is important +to use quotes to protect spaces so that command arguments are passed +correctly. A silly example is: + + fundisp "pipe: funtable 'foo.fits[cir 512 512 .1]' stdout" + +This seemed like a good idea at the time ... + +B + + +Funtools also will process a list of files as a single file using the +syntax: + + "list: file1 file2 ... filen" + +The files in the list are separated by whitespace. Any of the +above file types can be used. For example, if two files, foo1.fits and +foo2.fits, are part of the same observation, they can be processed as +a single file (using their own filters): + + fundisp "list: foo1.fits[cir(512,512,10)] foo2.fits[cir(511,511,10)]" + X Y PHA PI TIME DX DY + -------- -------- -------- -------- --------------------- -------- -------- + 512 512 6 7 79493997.45854475 578 574 + 512 512 8 9 79494575.58943175 579 573 + 512 512 5 6 79493631.03866175 578 575 + 512 512 5 5 79493290.86521725 578 575 + 512 512 8 9 79493432.00990875 579 573 + 511 511 5 5 79488631.09462625 580 575 + 511 511 10 11 79488780.60006675 580 573 + 511 511 4 4 79494562.35474326 580 575 + 511 511 6 6 79488203.01561825 580 575 + 511 511 6 6 79488017.99730176 580 575 + 511 511 4 4 79494332.45355175 580 575 + 511 511 9 10 79492685.94014275 581 574 + 511 511 5 5 79487708.71298325 580 575 + 511 511 8 9 79493719.00160225 581 573 + +Again, note that it is important to avoid spaces in the filters +because the list separator also is whitespace. To protect whitespace +in a filter, enclose the file specification in quotes: + + fundisp "list: 'foo1.fits[cir 512 512 .1]' foo2.fits[cir(511,511,.1)]" + + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + + +=cut diff --git a/doc/pod/funfilters.pod b/doc/pod/funfilters.pod new file mode 100644 index 0000000..b9b6d83 --- /dev/null +++ b/doc/pod/funfilters.pod @@ -0,0 +1,521 @@ +=pod + +=head1 NAME + + + +B + + + +=head1 SYNOPSIS + + + + + +This document contains a summary of the user interface for +filtering rows in binary tables. + + + +=head1 DESCRIPTION + + + + + +Table filtering allows a program to select rows from an table (e.g., +X-ray event list) by checking each row against one or more expressions +involving the columns in the table. When a table is filtered, only +valid rows satisfying these expressions are passed through for processing. + + +A filter expression is specified using bracket notation appended to +the filename of the data being processed: + + foo.fits[pha==1&&pi==2] + +It is also possible to put region specification inside a file and +then pass the filename in bracket notation: + + foo.fits[@my.reg] + +Filters must be placed after the extension and image section +information, when such information is present. The correct order is: + + +=over 4 + + + + +=item * + +file[fileinfo,sectioninfo][filters] + + +=item * + +file[fileinfo,sectioninfo,filters] + + +=back + + +where: + + +=over 4 + + + + +=item * + +B is the Funtools file name + + +=item * + +B is an ARRAY, EVENT, FITS extension, or FITS index + + +=item * + +B is the image section to extract + + +=item * + +B are spatial region and table (row) filters to apply + + +=back + + +See Funtools Files for more information +on file and image section specifications. + +B + + +Table filtering can be performed on columns of data in a FITS +binary table or a raw event file. Table filtering is accomplished by +means of B
. An table filter +specification consists of one or more B Filter +specifications also can contain comments and local/global processing +directives. + + +More specifically, a filter specification consist of one or more lines +containing: + + # comment until end of line + # include the following file in the table descriptor + @file + # each row expression can contain filters separated by operators + [filter_expression] BOOLOP [filter_expression2], ... + # each row expression can contain filters separated by the comma operator + [filter_expression1], [filter_expression2], ... + # the special row# keyword allows a range of rows to be processed + row#=m:n + # or a single row + row#=m + # regions are supported -- but are described elsewhere + [spatial_region_expression] + + + +A single filter expression consists of an arithmetic, logical, or +other operations involving one or more column values from a +table. Columns can be compared to other columns, to header values, +or to numeric constants. Standard math functions can be applied to +columns. Separate filter expressions can be combined using boolean operators. +Standard C semantics can be used when constructing expressions, with +the usual precedence and associativity rules holding sway: + + Operator Associativity + -------- ------------- + () left to right + !! (logical not) right to left + ! (bitwise not) - (unary minus) right to left + * / left to right + + - left to right + < <= > >= left to right + == != left to right + & (bitwise and) left to right + ^ (bitwise exclusive or) left to right + | (bitwise inclusive or) left to right + && (logical and) left to right + || (logical or) left to right + = right to left + +For example, if energy and pha are columns in a table, +then the following are valid expressions: + + pha>1 + energy == pha + (pha>1) && (energy<=2) + max(pha,energy)>=2.5 + + + +Comparison values can be integers or floats. Integer comparison values can be +specified in decimal, octal (using '0' as prefix), hex (using '0x' as prefix) +or binary (using '0b' as prefix). Thus, the following all specify the same +comparison test of a status mask: + + (status & 15) == 8 # decimal + (status & 017) == 010 # octal + (status & 0xf) == 0x8 # hex + (status & 0b1111) == 0b1000 # binary + + +The special keyword row# allows you to process a range of rows. +When row# is specified, the filter code skips to the designated +row and only processes the specified number of rows. The +"*" character can be utilized as the high limit value to denote +processing of the remaining rows. Thus: + + row#=100:109 + +processes 10 rows, starting with row 100 (counting from 1), +while: + + row#=100:* + +specifies that all but the first 99 rows are to be processed. + + +Spatial region filtering allows a program to select regions of an +image or rows of a table (e.g., X-ray events) using simple geometric +shapes and boolean combinations of shapes. For a complete description +of regions, see Spatial Region Filtering. + +B + +As mentioned previously, multiple filter expressions can be specified +in a filter descriptor, separated by commas or new-lines. +When such a comma or new-line separator is used, the boolean AND operator +is automatically generated in its place. Thus and expression such as: + + pha==1,pi=2:4 + +is equivalent to: + + (pha==1) && (pi>=2&&pi<=4) + + +[Note that the behavior of separators is different for filter expressions +and spatial region expressions. The former uses AND as the operator, while +the latter user OR. See +Combining Region and Table Filters +for more information about these conventions and how they are treated +when combined.] + +B + +Aside from the standard C syntax, filter expressions can make use of +IRAF-style B which specify a range of values. The +syntax requires that the column name be followed by an '=' sign, which +is followed by one or more comma-delimited range expressions of the form: + + col = vv # col == vv in range + col = :vv # col <= vv in range + col = vv: # col >= vv in range + col = vv1:vv2 # vv1 <= col <= vv2 in range + +The vv's above must be numeric constants; the right hand side of a +range list cannot contain a column name or header value. + +Note that, unlike an ordinary comma separator, the comma separator used +between two or more range expressions denotes OR. Thus, when two or +more range expressions are combined with a comma separator, the resulting +expression is a shortcut for more complicated boolean logic. For example: + + col = :3,6:8,10: + +is equivalent to: + + (col=6 && col =10) + +Note also that the single-valued rangelist: + + col = val + +is equivalent to the C-based filter expression: + + col == val + +assuming, of course, that val is a numeric constant. + +B + +It is permissible to specify C math functions as part of the filter syntax. +When the filter parser recognizes a function call, it automatically +includes the math.h and links in the C math library. Thus, it is +possible to filter rows by expressions such as these: + + +=over 4 + + + + +=item * + +(pi+pha)>(2+log(pi)-pha) + + +=item * + +min(pi,pha)*14>x + + +=item * + +max(pi,pha)==(pi+1) + + +=item * + +feq(pi,pha) + + +=item * + +div(pi,pha)>0 + + +=back + + +The function feq(a,b) returns true (1) if the difference between a and b +(taken as double precision values) is less than approximately 10E-15. +The function div(a,b) divides a by b, but returns NaN (not a number) +if b is 0. It is a safe way to avoid floating point errors when +dividing one column by another. + +B + +The special B<@filename> directive specifies an include file +containing filter expressions. This file is processed as part of +the overall filter descriptor: + + foo.fits[pha==1,@foo] + + +B
+ +The filter syntax supports comparison between a column value and a +header parameter value of a FITS binary tables (raw event files have no +such header). The header parameters can be taken from the binary +table header or the primary header. For example, assuming there is a +header value MEAN_PHA in one of these headers, you can select photons +having exactly this value using: + + + +=over 4 + + + + +=item * + +pha==MEAN_PHA + + +=back + + + + + +Table filtering is more easily described by means of examples. +Consider data containing the following table structure: + + +=over 4 + + + + +=item * + +double TIME + + +=item * + +int X + + +=item * + +int Y + + +=item * + +short PI + + +=item * + +short PHA + + +=item * + +int DX + + +=item * + +int DY + + +=back + + + + +Tables can be filtered on these columns using IRAF/QPOE range syntax or +any valid C syntax. The following examples illustrate the possibilities: + + +=over 4 + + + + + + +=item * + +pha=10 + + +=item * + +pha==10 + + +select rows whose pha value is exactly 10 + + + + +=item * + +pha=10:50 + + +select rows whose pha value is in the range of 10 to 50 + + + + +=item * + +pha=10:50,100 + + +select rows whose pha value is in the range of 10 to 50 or is +equal to 100 + + + + +=item * + +pha>=10 && pha<=50 + + +select rows whose pha value is in the range of 10 to 50 + + + + +=item * + +pi=1,2&&pha>3 + + +select rows whose pha value is 1 or 2 and whose pi value is 3 + + + + +=item * + +pi=1,2 || pha>3 + + +select rows whose pha value is 1 or 2 or whose pi value is 3 + + + + +=item * + +pha==pi+1 + + +select rows whose pha value is 1 less than the pi value + + + + +=item * + +(pha==pi+1) && (time>50000.0) + + +select rows whose pha value is 1 less than the pi value +and whose time value is greater than 50000 + + + + +=item * + +(pi+pha)>20 + + +select rows in which the sum of the pi and pha values is greater +than 20 + + + + +=item * + +pi%2==1 + + +select rows in which the pi value is odd + + +=back + + + + +Currently, integer range list limits cannot be specified in binary +notation (use decimal, hex, or octal instead). Please contact us if +this is a problem. + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + + +=cut diff --git a/doc/pod/funflush.pod b/doc/pod/funflush.pod new file mode 100644 index 0000000..b525ad2 --- /dev/null +++ b/doc/pod/funflush.pod @@ -0,0 +1,107 @@ +=pod + +=head1 NAME + + + +B + + + +=head1 SYNOPSIS + + + + + + #include + + void FunFlush(Fun fun, char *plist) + + + + + +=head1 DESCRIPTION + + + + +The B routine will flush data to a FITS output file. In +particular, it can be called after all rows have been written (using +the FunTableRowPut() routine) +in order to add the null padding that is required to complete a FITS +block. It also should be called after completely writing an image using +FunImagePut() or after writing +the final row of an image using +FunTableRowPut(). + + +The B (i.e., parameter list) argument is a string +containing one or more comma-delimited B +parameters. If the plist string contains the parameter +"copy=remainder" and the file was opened with a reference file, which, +in turn, was opened for extension copying (i.e. the input +FunOpen() mode also was "c" or "C"), +then FunFlush also will copy the remainder of the FITS extensions from +the input reference file to the output file. This normally would be +done only at the end of processing. + + +Note that FunFlush() is called +with "copy=remainder" in the mode string by FunClose(). This means +that if you close the output file before the reference input file, it +is not necessary to call +FunFlush() explicitly, unless you +are writing more than one extension. See the +evmerge example code. However, it is safe to +call FunFlush() more than once +without fear of re-writing either the padding or the copied +extensions. + + +In addition, if FunFlush() is +called on an output file with the plist set to "copy=reference" and if +the file was opened with a reference file, the reference extension is +written to the output file. This mechanism provides a simple way to +copy input extensions to an output file without processing the former. +For example, in the code fragment below, an input extension is set to +be the reference file for a newly opened output extension. If that +reference extension is not a binary table, it is written to the output +file: + + /* process each input extension in turn */ + for(ext=0; ;ext++){ + /* get new extension name */ + sprintf(tbuf, "%s[%d]", argv[1], ext); + /* open input extension -- if we cannot open it, we are done */ + if( !(ifun=FunOpen(tbuf, "r", NULL)) ) + break; + /* make the new extension the reference handle for the output file */ + FunInfoPut(ofun, FUN_IFUN, &ifun, 0); + /* if its not a binary table, just write it out */ + if( !(s=FunParamGets(ifun, "XTENSION", 0, NULL, &got)) || + strcmp(s, "BINTABLE")){ + if( s ) free(s); + FunFlush(ofun, "copy=reference"); + FunClose(ifun); + continue; + } + else{ + /* process binary table */ + .... + } + } + + + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + +=cut diff --git a/doc/pod/funhead.pod b/doc/pod/funhead.pod new file mode 100644 index 0000000..ee224cc --- /dev/null +++ b/doc/pod/funhead.pod @@ -0,0 +1,218 @@ +=pod + +=head1 NAME + + + +B + + + +=head1 SYNOPSIS + + + + + +funhead [-a] [-s] [-t] [-L] [oname ename] + + + + + +=head1 OPTIONS + + + + + + -a # display all extension headers + -s # display 79 chars instead of 80 before the new-line + -t # prepend data type char to each line of output + -L # output in rdb/starbase list format + + + + +=head1 DESCRIPTION + + + + +B displays the FITS header parameters in the specified +FITS Extension. + +The first argument to the program specifies the Funtools input file +to display. If "stdin" is specified, data are read from +the standard input. Funtools Bracket +Notation is used to specify particular FITS extension to process. +Normally, the full 80 characters of each header card is output, +followed by a new-line. + + +If the B<-a> switch is specified, the header from each FITS +extensions in the file is displayed. Note, however, that the B<-a> +switch does not work with FITS files input via stdin. We hope to +remove this restriction in a future release. + + +If the B<-s> switch is specified, only 79 characters are output +before the new-line. This helps the display on 80 character terminals. + + +If the B<-t> switch is specified, the data type of the parameter +is output as a one character prefix, followed by 77 characters of the +param. The parameter data types are defined as: FUN_PAR_UNKNOWN +('u'), FUN_PAR_COMMENT ('c'), FUN_PAR_LOGICAL ('l'), FUN_PAR_INTEGER +('i'), FUN_PAR_STRING ('s'), FUN_PAR_REAL ('r'), FUN_PAR_COMPLEX ('x'). + + +If the B<-L> (rdb table) switch is used, the output will conform +to starbase/rdb data base list format. + + +For example to display the EVENTS extension (binary table): + + [sh] funhead "foo.fits[EVENTS]" + XTENSION= 'BINTABLE' / FITS 3D BINARY TABLE + BITPIX = 8 / Binary data + NAXIS = 2 / Table is a matrix + NAXIS1 = 20 / Width of table in bytes + NAXIS2 = 30760 / Number of entries in table + PCOUNT = 0 / Random parameter count + GCOUNT = 1 / Group count + TFIELDS = 7 / Number of fields in each row + EXTNAME = 'EVENTS ' / Table name + EXTVER = 1 / Version number of table + TFORM1 = '1I ' / Data type for field + TTYPE1 = 'X ' / Label for field + TUNIT1 = ' ' / Physical units for field + TFORM2 = '1I ' / Data type for field + etc. ... + END + + + +To display the third header: + + [sh] funhead "foo.fits[3]" + XTENSION= 'BINTABLE' / FITS 3D BINARY TABLE + BITPIX = 8 / Binary data + NAXIS = 2 / Table is a matrix + NAXIS1 = 32 / Width of table in bytes + NAXIS2 = 40 / Number of entries in table + PCOUNT = 0 / Random parameter count + GCOUNT = 1 / Group count + TFIELDS = 7 / Number of fields in each row + EXTNAME = 'TGR ' / Table name + EXTVER = 1 / Version number of table + TFORM1 = '1D ' / Data type for field + etc. ... + END + + + +To display the primary header (i.e., extension 0): + + sh> funhead "coma.fits[0]" + SIMPLE = T /STANDARD FITS FORMAT + BITPIX = 16 /2-BYTE TWOS-COMPL INTEGER + NAXIS = 2 /NUMBER OF AXES + NAXIS1 = 800 / + NAXIS2 = 800 / + DATATYPE= 'INTEGER*2' /SHORT INTEGER + END + + + +The funhead program also can edit (i.e. add, delete, or modify) or +display individual headers parameters. Edit mode is signalled by the +presence of two additional command-line arguments: output file and +edit command file, in that order. Edit mode acts as a filter: the +output file will contain the entire input FITS file, including other +extensions. The edit command file can be "stdin", in which case edit +command are read from the standard input. + + +The edit command file contains parameter comments (having '#' in the +first column) and delete and assignment(modify or add) operations. A +delete operation is specified by preceding the parameter name with a +minus sign "-". A display operation (very useful in interactive +sessions, i.e., where the edit commands are taken from stdin) is +specified by preceding the parameter name with a question mark "?". In +either case, a parameter value need not be specified. An assignment +operation is specified in the same two ways that a parameter is +specified in a text header (but without the comment character that +precedes header params), i.e.: + + + +=over 4 + + + + +=item * + +FITS-style comments have an equal sign "=" between the keyword and +value and an optional slash "/" to signify a comment. The strict FITS +rules on column positions are not enforced. + + + +=item * + +Free-form comments can have an optional colon separator between the +keyword and value. In the absence of quote, all tokens after the +keyword are part of the value, i.e. no comment is allowed. + + +=back + + + + +For example, the following interactive session checks for the +existence of parameters, adds new parameters, modifies them, and +modifies and deletes existing parameters: + + sh$ ./funhead snr.ev foo.fits - + # look for FOO1 + ? FOO1 + WARNING: FOO1 not found + # add new foo1 + FOO1 = 100 + # add foo2 + FOO2 = 200 + # reset foo1 to a different value + FOO1 -1 + # delete foo2 + -FOO2 + # change existing value + EXTVER 2 + ? XS-SORT + XS-SORT = 'EOF ' / type of event sort + # delete existing value + -XS-SORT + # exit + ^D + + + +See Column-based Text Files +for more information about header parameter format. + + + + + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + +=cut diff --git a/doc/pod/funhist.pod b/doc/pod/funhist.pod new file mode 100644 index 0000000..fc1885d --- /dev/null +++ b/doc/pod/funhist.pod @@ -0,0 +1,252 @@ +=pod + +=head1 NAME + + + +B + + + +=head1 SYNOPSIS + + + + + +funhist [-n|-w|-T] [column] [[lo:hi:]bins] + + + + + +=head1 OPTIONS + + + + + + -n # normalize bin value by the width of each bin + -w # specify bin width instead of number of bins in arg3 + -T # output in rdb/starbase format (tab separators) + + + + +=head1 DESCRIPTION + + + + +B creates a one-dimensional histogram from the specified +columns of a FITS Extension +binary table of a FITS file (or from a non-FITS raw event file), or +from a FITS image or array, and writes that histogram as an ASCII +table. Alternatively, the program can perform a 1D projection of one +of the image axes. + + +The first argument to the program is required, and specifies the +Funtools file: FITS table or image, raw event file, or array. If +"stdin" is specified, data are read from the standard input. Use +Funtools Bracket Notation to specify FITS +extensions, and filters. + + +For a table, the second argument also is required. It specifies the +column to use in generating the histogram. If the data file is of +type image (or array), the column is optional: if "x" (or "X"), "y" +(or "Y") is specified, then a projection is performed over the x +(dim1) or y (dim2) axes, respectively. (That is, this projection will +give the same results as a histogram performed on a table containing +the equivalent x,y event rows.) If no column name is specified or +"xy" (or "XY") is specified for the image, then a histogram is +performed on the values contained in the image pixels. + + +The argument that follows is optional and specifies the number of bins +to use in creating the histogram and, if desired, the range of bin +values. For image and table histograms, the range should specify the +min and max data values. For image histograms on the x and y axes, +the range should specify the min and max image bin values. If this +argument is omitted, the number of output bins for a table is +calculated either from the TLMIN/TLMAX headers values (if these exist +in the table FITS header for the specified column) or by going through +the data to calculate the min and max value. For an image, the number +of output bins is calculated either from the DATAMIN/DATAMAX header +values, or by going through the data to calculate min and max value. +(Note that this latter calculation might fail if the image cannot be +fit in memory.) If the data are floating point (table or image) and +the number of bins is not specified, an arbitrary default of 128 is +used. + + +For binary table processing, the B<-w> (bin width) switch can be used +to specify the width of each bin rather than the number of bins. Thus: + + funhist test.ev pha 1:100:5 + +means that 5 bins of width 20 are used in the histogram, while: + + funhist -w test.ev pha 1:100:5 + +means that 20 bins of width 5 are used in the histogram. + + +The data are divvied up into the specified number of bins and the +resulting 1D histogram (or projection) is output in ASCII table +format. For a table, the output displays the low_edge (inclusive) and +hi_edge (exclusive) values for the data. For example, a 15-row table +containing a "pha" column whose values range from -7.5 to 7.5 +can be processed thus: + + + [sh] funhist test.ev pha + # data file: /home/eric/data/test.ev + # column: pha + # min,max,bins: -7.5 7.5 15 + + bin value lo_edge hi_edge + ------ --------- --------------------- --------------------- + 1 22 -7.50000000 -6.50000000 + 2 21 -6.50000000 -5.50000000 + 3 20 -5.50000000 -4.50000000 + 4 19 -4.50000000 -3.50000000 + 5 18 -3.50000000 -2.50000000 + 6 17 -2.50000000 -1.50000000 + 7 16 -1.50000000 -0.50000000 + 8 30 -0.50000000 0.50000000 + 9 16 0.50000000 1.50000000 + 10 17 1.50000000 2.50000000 + 11 18 2.50000000 3.50000000 + 12 19 3.50000000 4.50000000 + 13 20 4.50000000 5.50000000 + 14 21 5.50000000 6.50000000 + 15 22 6.50000000 7.50000000 + + [sh] funhist test.ev pha 1:6 + # data file: /home/eric/data/test.ev + # column: pha + # min,max,bins: 0.5 6.5 6 + + bin value lo_edge hi_edge + ------ --------- --------------------- --------------------- + 1 16 0.50000000 1.50000000 + 2 17 1.50000000 2.50000000 + 3 18 2.50000000 3.50000000 + 4 19 3.50000000 4.50000000 + 5 20 4.50000000 5.50000000 + 6 21 5.50000000 6.50000000 + + [sh] funhist test.ev pha 1:6:3 + # data file: /home/eric/data/test.ev + # column: pha + # min,max,bins: 0.5 6.5 3 + + bin value lo_edge hi_edge + ------ --------- --------------------- --------------------- + 1 33 0.50000000 2.50000000 + 2 37 2.50000000 4.50000000 + 3 41 4.50000000 6.50000000 + + + +For a table histogram, the B<-n>(normalize) switch can be used to +normalize the bin value by the width of the bin (i.e., hi_edge-lo_edge): + + [sh] funhist -n test.ev pha 1:6:3 + # data file: test.ev + # column: pha + # min,max,bins: 0.5 6.5 3 + # width normalization (val/(hi_edge-lo_edge)) is applied + + bin value lo_edge hi_edge + ------ --------------------- --------------------- --------------------- + 1 16.50000000 0.50000000 2.50000000 + 2 6.16666667 2.50000000 4.50000000 + 3 4.10000000 4.50000000 6.50000000 + +This could used, for example, to produce a light curve with values +having units of counts/second instead of counts. + + +For an image histogram, the output displays the low and high image +values (both inclusive) used to generate the histogram. For example, +in the following example, 184 pixels had a value of 1, 31 had a value +of 2, while only 2 had a value of 3,4,5,6, or 7: + + [sh] funhist test.fits + # data file: /home/eric/data/test.fits + # min,max,bins: 1 7 7 + + bin value lo_val hi_val + ------ --------------------- --------------------- --------------------- + 1 184.00000000 1.00000000 1.00000000 + 2 31.00000000 2.00000000 2.00000000 + 3 2.00000000 3.00000000 3.00000000 + 4 2.00000000 4.00000000 4.00000000 + 5 2.00000000 5.00000000 5.00000000 + 6 2.00000000 6.00000000 6.00000000 + 7 2.00000000 7.00000000 7.00000000 + + + +For the axis projection of an image, the output displays the low and +high image bins (both inclusive) used to generate the projection. For +example, in the following example, 21 counts had their X bin value of +2, etc.: + + [sh] funhist test.fits x 2:7 + # data file: /home/eric/data/test.fits + # column: X + # min,max,bins: 2 7 6 + + bin value lo_bin hi_bin + ------ --------------------- --------------------- --------------------- + 1 21.00000000 2.00000000 2.00000000 + 2 20.00000000 3.00000000 3.00000000 + 3 19.00000000 4.00000000 4.00000000 + 4 18.00000000 5.00000000 5.00000000 + 5 17.00000000 6.00000000 6.00000000 + 6 16.00000000 7.00000000 7.00000000 + + [sh] funhist test.fits x 2:7:2 + # data file: /home/eric/data/test.fits + # column: X + # min,max,bins: 2 7 2 + + bin value lo_bin hi_bin + ------ --------------------- --------------------- --------------------- + 1 60.00000000 2.00000000 4.00000000 + 2 51.00000000 5.00000000 7.00000000 + + + +You can use gnuplot or other plotting programs to graph the +results, using a script such as: + + #!/bin/sh + sed -e '1,/---- .*/d + /^$/,$d' | \ + awk '\ + BEGIN{print "set nokey; set title \"funhist\"; set xlabel \"bin\"; set ylabel \"counts\"; plot \"-\" with boxes"} \ + {print $3, $2, $4-$3}' | \ + gnuplot -persist - 1>/dev/null 2>&1 + + +Similar plot commands are supplied in the script B: + + funhist test.ev pha ... | funhist.plot gnuplot + + + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + +=cut diff --git a/doc/pod/funidx.pod b/doc/pod/funidx.pod new file mode 100644 index 0000000..37bb712 --- /dev/null +++ b/doc/pod/funidx.pod @@ -0,0 +1,224 @@ +=pod + +=head1 NAME + + + +B + + + +=head1 SYNOPSIS + + + + + +This document contains a summary of the user interface for +filtering rows in binary tables with indexes. + + + +=head1 DESCRIPTION + + + + + +Funtools Table Filtering allows rows in a +table to be selected based on the values of one or more columns in the +row. Because the actual filter code is compiled on the fly, it is very +efficient. However, for very large files (hundreds of Mb or larger), +evaluating the filter expression on each row can take a long time. Therefore, +funtools supports index files for columns, which are used automatically during +filtering to reduce dramatically the number of row evaluations performed. +The speed increase for indexed filtering can be an order of magnitude or +more, depending on the size of the file. + + +The funindex program creates an +index on one or more columns in a binary table. For example, to create an index +for the column pi in the file huge.fits, use: + + funindex huge.fits pi + +This will create an index named huge_pi.idx. + + +When a filter expression is initialized for row evaluation, funtools +looks for an index file for each column in the filter expression. If +found, and if the file modification date of the index file is later +than that of the data file, then the index will be used to reduce the +number of rows that are evaluated in the filter. When +Spatial Region Filtering is part of the +expression, the columns associated with the region are checked for index +files. + + +If an index file is not available for a given column, then in general, +all rows must be checked when that column is part of a filter +expression. This is not true, however, when a non-indexed column is +part of an AND expression. In this case, only the rows that pass the +other part of the AND expression need to be checked. Thus, in some cases, +filtering speed can increase significantly even if all columns are not +indexed. + + +Also note that certain types of filter expression syntax cannot make +use of indices. For example, calling functions with column names as +arguments implies that all rows must be checked against the function +value. Once again, however, if this function is part of an AND +expression, then a significant improvement in speed still is possible +if the other part of the AND expression is indexed. + + +For example, note below the dramatic speedup in searching a 1 Gb +file using an AND filter, even when one of the columns (pha) has no +index: + + + time fundisp \ + huge.fits'[idx_activate=0,idx_debug=1,pha=2348&&cir 4000 4000 1]' \ + "x y pha" + x y pha + ---------- ----------- ---------- + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 42.36u 13.07s 6:42.89 13.7% + + time fundisp \ + huge.fits'[idx_activate=1,idx_debug=1,pha=2348&&cir 4000 4000 1]' \ + "x y pha" + x y pha + ---------- ----------- ---------- + idxeq: [INDEF] + idxand sort: x[ROW 8037025:8070128] y[ROW 5757665:5792352] + idxand(1): INDEF [IDX_OR_SORT] + idxall(1): [IDX_OR_SORT] + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 1.55u 0.37s 1:19.80 2.4% + + +When all columns are indexed, the increase in speed can be even more dramatic: + + time fundisp \ + huge.fits'[idx_activate=0,idx_debug=1,pi=770&&cir 4000 4000 1]' \ + "x y pi" + x y pi + ---------- ----------- ---------- + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 42.60u 12.63s 7:28.63 12.3% + + time fundisp \ + huge.fits'[idx_activate=1,idx_debug=1,pi=770&&cir 4000 4000 1]' \ + "x y pi" + x y pi + ---------- ----------- ---------- + idxeq: pi start=9473025,stop=9492240 => pi[ROW 9473025:9492240] + idxand sort: x[ROW 8037025:8070128] y[ROW 5757665:5792352] + idxor sort/merge: pi[ROW 9473025:9492240] [IDX_OR_SORT] + idxmerge(5): [IDX_OR_SORT] pi[ROW] + idxall(1): [IDX_OR_SORT] + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 1.67u 0.30s 0:24.76 7.9% + + + +The miracle of indexed filtering (and indeed, of any indexing) is the +speed of the binary search on the index, which is of order log2(n) +instead of n. (The funtools binary search method is taken from +http://www.tbray.org/ongoing/When/200x/2003/03/22/Binary, to whom +grateful acknowledgement is made.) This means that the larger the +file, the better the performance. Conversely, it also means that for +small files, using an index (and the overhead involved) can slow +filtering down somewhat. Our tests indicate that on a file containing +a few tens of thousands of rows, indexed filtering can be 10 to 20 +percent slower than non-indexed filtering. Of course, your mileage +will vary with conditions (disk access speed, amount of available +memory, process load, etc.) + + +Any problem encountered during index processing will result in +indexing being turned off, and replaced by filtering all rows. You can turn +filtering off manually by setting the idx_activate variable to 0 (in a filter +expression) or the FILTER_IDX_ACTIVATE environment variable to 0 (in the global +environment). Debugging output showing how the indexes are being processed can +be displayed to stderr by setting the idx_debug variable to 1 (in a filter +expression) or the FILTER_IDX_DEBUG environment variable to 1 (in the global +environment). + + +Currently, indexed filtering only works with FITS binary tables and raw +event files. It does not work with text files. This restriction might be +removed in a future release. + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + + +=cut diff --git a/doc/pod/funimage.pod b/doc/pod/funimage.pod new file mode 100644 index 0000000..7ec3f93 --- /dev/null +++ b/doc/pod/funimage.pod @@ -0,0 +1,314 @@ +=pod + +=head1 NAME + + + +B + + + +=head1 SYNOPSIS + + + + + +funimage [-a] [bitpix=n] +funimage [-l] [bitpix=n] +funimage [-p x|y] [bitpix=n] + + + + + +=head1 OPTIONS + + + + + + -a # append to existing output file as an image extension + -l # input is a list file containing xcol, ycol, value + -p [x|y] # project along x or y axis to create a 1D image + + + + +=head1 DESCRIPTION + + + + +B creates a primary FITS image from the specified +FITS Extension +and/or +Image Section +of a FITS file, or from an +Image Section +of a non-FITS array, or from a raw event file. + +The first argument to the program specifies the FITS input image, +array, or raw event file to process. If "stdin" is specified, data are +read from the standard input. Use Funtools +Bracket Notation to specify FITS extensions, image sections, and +filters. The second argument is the output FITS file. If "stdout" is +specified, the FITS image is written to the standard output. By +default, the output pixel values are of the same data type as those of the +input file (or type "int" when binning a table), but this can be +overridden using an optional third argument of the form: + + bitpix=n + +where n is 8,16,32,-32,-64, for unsigned char, short, int, float and double, +respectively. + + +If the input data are of type image, the appropriate section is +extracted and blocked (based on how the +Image Section is specified), and +the result is written to the FITS primary image. When an integer +image containing the BSCALE and BZERO keywords is converted to float, +the pixel values are scaled and the scaling keywords are deleted from the +output header. When converting integer scaled data to integer +(possibly of a different size), the pixels are not scaled and the +scaling keywords are retained. + + +If the input data is a binary table or raw event file, these are +binned into an image, from which a section is extracted and blocked, +and written to a primary FITS image. In this case, it is necessary to +specify the two columns that will be used in the 2D binning. This can +be done on the command line using the B keyword: + + funcnts "foo.ev[EVENTS,bincols=(detx,dety)]" + +The full form of the B specifier is: + + bincols=([xname[:tlmin[:tlmax:[binsiz]]]],[yname[:tlmin[:tlmax[:binsiz]]]]) + +where the tlmin, tlmax, and binsiz specifiers determine the image binning +dimensions: + + dim = (tlmax - tlmin)/binsiz (floating point data) + dim = (tlmax - tlmin)/binsiz + 1 (integer data) + +Using this syntax, it is possible to bin any two columns of a binary +table at any bin size. Note that the tlmin, tlmax, and binsiz +specifiers can be omitted if TLMIN, TLMAX, and TDBIN header parameters +(respectively) are present in the FITS binary table header for the +column in question. Note also that if only one parameter is specified, +it is assumed to be tlmax, and tlmin defaults to 1. If two parameters +are specified, they are assumed to be tlmin and tlmax. +See Binning FITS Binary Tables and Non-FITS +Event Files for more information about binning parameters. + + +By default, a new 2D FITS image file is created and the image is written +to the primary HDU. If the B<-a> (append) switch is specified, +the image is appended to an existing FITS file as an IMAGE extension. +(If the output file does not exist, the switch is effectively ignored +and the image is written to the primary HDU.) This can be useful in a +shell programming environment when processing multiple FITS images +that you want to combine into a single final FITS file. + + +B also can take input from a table containing columns of +x, y, and value (e.g., the output from B which +displays each image x and y and the number of counts at that +position.) When the B<-l> (list) switch is used, the input file is +taken to be a FITS or ASCII table containing (at least) three columns +that specify the x and y image coordinates and the value of that +image pixel. In this case, B requires four extra +arguments: xcolumn:xdims, ycolumn:ydims, vcolumn and bitpix=n. The x +and y col:dim information takes the form: + + name:dim # values range from 1 to dim + name:min:max # values range from min to max + name:min:max:binsiz # dimensions scaled by binsize + +In particular, the min value should be used whenever the +minimum coordinate value is something other than one. For example: + + funimage -l foo.lst foo.fits xcol:0:512 ycol:0:512 value bitpix=-32 + + + +The list feature also can be used to read unnamed columns from standard +input: simply replace the column name with a null string. Note +that the dimension information is still required: + + funimage -l stdin foo.fits "":0:512 "":0:512 "" bitpix=-32 + 240 250 1 + 255 256 2 + ... + ^D + + + +The list feature provides a simple way to generate a blank image. +If you pass a Column-based Text File +to funimage in which the text header contains the required image +information, then funimage will correctly make a blank image. For +example, consider the following text file (called foo.txt): + + x:I:1:10 y:I:1:10 + ------ ------ + 0 0 + +This text file defines two columns, x and y, each of data type 32-bit int and +image dimension 10. The command: + + funimage foo.txt foo.fits bitpix=8 + +will create an empty FITS image called foo.fits containing a 10x10 +image of unsigned char: + + fundisp foo.fits + 1 2 3 4 5 6 7 8 9 10 + ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ + 10: 0 0 0 0 0 0 0 0 0 0 + 9: 0 0 0 0 0 0 0 0 0 0 + 8: 0 0 0 0 0 0 0 0 0 0 + 7: 0 0 0 0 0 0 0 0 0 0 + 6: 0 0 0 0 0 0 0 0 0 0 + 5: 0 0 0 0 0 0 0 0 0 0 + 4: 0 0 0 0 0 0 0 0 0 0 + 3: 0 0 0 0 0 0 0 0 0 0 + 2: 0 0 0 0 0 0 0 0 0 0 + 1: 1 0 0 0 0 0 0 0 0 0 + + + +Note that the text file must contain at least +one row of data. However, in the present example, event position 0,0 is +outside the limits of the image and will be ignored. (You can, of course, +use real x,y values to seed the image with data.) + + +Furthermore, you can use the TEXT filter specification to obviate the need for +an input text file altogether. The following command will create the same +10x10 char image without an actual input file: + + funimage stdin'[TEXT(x:I:10,y:I:10)]' foo.fits bitpix=8 < /dev/null +or + funimage /dev/null'[TEXT(x:I:10,y:I:10)]' foo.fits bitpix=8 + + + +You also can use either of these methods to generate a region mask simply +by appending a region inside the filter brackets and specfying B +along with the bitpix. For example, the following command will generate a +10x10 char mask using 3 regions: + + funimage stdin'[TEXT(x:I:10,y:I:10),cir(5,5,4),point(10,1),-cir(5,5,2)]' \ + foo.fits bitpix=8,mask=all < /dev/null + +The resulting mask looks like this: + + fundisp foo.fits + 1 2 3 4 5 6 7 8 9 10 + ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ + 10: 0 0 0 0 0 0 0 0 0 0 + 9: 0 0 0 0 0 0 0 0 0 0 + 8: 0 0 1 1 1 1 1 0 0 0 + 7: 0 1 1 1 1 1 1 1 0 0 + 6: 0 1 1 0 0 0 1 1 0 0 + 5: 0 1 1 0 0 0 1 1 0 0 + 4: 0 1 1 0 0 0 1 1 0 0 + 3: 0 1 1 1 1 1 1 1 0 0 + 2: 0 0 1 1 1 1 1 0 0 0 + 1: 0 0 0 0 0 0 0 0 0 2 + + + +You can use B to create 1D image projections along the x +or y axis using the B<-p [x|y]> switch. This capability works for +both images and tables. For example consider a FITS table named ev.fits +containing the following rows: + + X Y + -------- -------- + 1 1 + 1 2 + 1 3 + 1 4 + 1 5 + 2 2 + 2 3 + 2 4 + 2 5 + 3 3 + 3 4 + 3 5 + 4 4 + 4 5 + 5 5 + + +A corresponding 5x5 image, called dim2.fits, would therefore contain: + + 1 2 3 4 5 + ---------- ---------- ---------- ---------- ---------- + 5: 1 1 1 1 1 + 4: 1 1 1 1 0 + 3: 1 1 1 0 0 + 2: 1 1 0 0 0 + 1: 1 0 0 0 0 + +A projection along the y axis can be performed on either the table or +the image: + + funimage -p y ev.fits stdout | fundisp stdin + 1 2 3 4 5 + ---------- ---------- ---------- ---------- ---------- + 1: 1 2 3 4 5 + + funimage -p y dim2.fits stdout | fundisp stdin + 1 2 3 4 5 + ---------- ---------- ---------- ---------- ---------- + 1: 1 2 3 4 5 + + + +Furthermore, you can create a 1D image projection along any column of +a table by using the B filter specification and +specifying a single column. For example, the following command +projects the same 1D image along the y axis of a table as use of +the B<-p y> switch: + + funimage ev.fits'[bincols=y]' stdout | fundisp stdin + 1 2 3 4 5 + ---------- ---------- ---------- ---------- ---------- + 1: 1 2 3 4 5 + + + +Examples: + +Create a FITS image from a FITS binary table: + + [sh] funimage test.ev test.fits + + + +Display the FITS image generated from a blocked section of FITS binary table: + + [sh] funimage "test.ev[2:8,3:7,2]" stdout | fundisp stdin + 1 2 3 + --------- --------- --------- + 1: 20 28 36 + 2: 28 36 44 + + + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + +=cut diff --git a/doc/pod/funimageget.pod b/doc/pod/funimageget.pod new file mode 100644 index 0000000..a569bba --- /dev/null +++ b/doc/pod/funimageget.pod @@ -0,0 +1,237 @@ +=pod + +=head1 NAME + + + +B + + + +=head1 SYNOPSIS + + + + + + #include + + void *FunImageGet(Fun fun, void *buf, char *plist) + + + + + +=head1 DESCRIPTION + + + + +The B routine returns an binned image array of the +specified section of a Funtools data file. If the input data are +already of type image, the array is generated by extracting the +specified image section and then binning it according to the specified +bin factor. If the input data are contained in a binary table or raw +event file, the rows are binned on the columns specified by the +B keyword (using appropriate default columns as +necessary), after which the image section and bin factors are +applied. In both cases, the data is automatically converted from FITS +to native format, if necessary. + +The first argument is the Funtools handle returned by +FunOpen(). The second B +argument is a pointer to a data buffer to fill. If NULL is specified, +FunImageGet will allocate a buffer of the appropriate size. Generally +speaking, you always want Funtools to allocate the buffer because +the image dimensions will be determined by +Funtools image sectioning +on the command line. + +The third B (i.e., parameter list) argument is a string +containing one or more comma-delimited B +parameters. It can be used to specify the return data type using the +B keyword. If no such keyword is specified in the plist +string, the data type of the returned image is the same as the data type +of the original input file, or is of type int for FITS binary tables. + + +If the B keyword is supplied in the plist string, the data +type of the returned image will be one of the supported FITS image +data types: + + +=over 4 + + + + +=item * + +8 unsigned char + + +=item * + +16 short + + +=item * + +32 int + + +=item * + +-32 float + + +=item * + +-64 double + + +=back + + +For example: + + void *buf; + /* extract data section into an image buffer */ + if( !(buf = FunImageGet(fun, NULL, NULL)) ) + gerror(stderr, "could not FunImageGet: %s\n", iname); + +will allocate buf and retrieve the image in the file data format. In +this case, you will have to determine the data type (using the +FUN_SECT_BITPIX value in the +FunInfoGet() +routine) +and then use a switch statement to process each data type: + + int bitpix; + void *buf; + unsigned char *cbuf; + short *sbuf; + int *ibuf; + ... + buf = FunImageGet(fun, NULL, NULL); + FunInfoGet(fun, FUN_SECT_BITPIX, &bitpix, 0); + /* set appropriate data type buffer to point to image buffer */ + switch(bitpix){ + case 8: + cbuf = (unsigned char *)buf; break; + case 16: + sbuf = (short *)buf; break; + case 32: + ibuf = (int *)buf; break; + ... + +See the +imblank example code +for more details on how to process an image when the data type is not +specified beforehand. + + +It often is easier to specify the data type directly: + + double *buf; + /* extract data section into a double image buffer */ + if( !(buf = FunImageGet(fun, NULL, "bitpix=-64")) ) + gerror(stderr, "could not FunImageGet: %s\n", iname); + +will extract the image while converting to type double. + + +On success, a pointer to the image buffer is returned. (This will be +the same as the second argument, if NULL is not passed to the latter.) +On error, NULL is returned. + + +In summary, to retrieve image or row data into a binned image, you simply +call FunOpen() followed by +FunImageGet(). Generally, you +then will want to call +FunInfoGet() +to retrieve the +axis dimensions (and data type) of the section you are processing +(so as to take account of sectioning and blocking of the original data): + + double *buf; + int i, j; + int dim1, dim2; + ... other declarations, etc. + + /* open the input FITS file */ + if( !(fun = FunOpen(argv[1], "rc", NULL)) ) + gerror(stderr, "could not FunOpen input file: %s\n", argv[1]); + + /* extract and bin the data section into a double float image buffer */ + if( !(buf = FunImageGet(fun, NULL, "bitpix=-64")) ) + gerror(stderr, "could not FunImageGet: %s\n", argv[1]); + + /* get dimension information from funtools structure */ + FunInfoGet(fun, FUN_SECT_DIM1, &dim1, FUN_SECT_DIM2, &dim2, 0); + + /* loop through pixels and reset values below limit to value */ + for(i=0; i keyword: + + funcnts "foo.ev[EVENTS,bincols=(detx,dety)]" + + + +The full form of the B specifier is: + + bincols=([xname[:tlmin[:tlmax:[binsiz]]]],[yname[:tlmin[:tlmax[:binsiz]]]]) + +where the tlmin, tlmax, and binsiz specifiers determine the image binning +dimensions: + + dim = (tlmax - tlmin)/binsiz (floating point data) + dim = (tlmax - tlmin)/binsiz + 1 (integer data) + +These tlmin, tlmax, and binsiz specifiers can be omitted if TLMIN, +TLMAX, and TDBIN header parameters (respectively) are present in the +FITS binary table header for the column in question. Note that if +only one parameter is specified, it is assumed to be tlmax, and tlmin +defaults to 1. If two parameters are specified, they are assumed to be +tlmin and tlmax. + + +If B is not specified on the command line, Funtools tries +to use appropriate defaults: it looks for the environment variable +FITS_BINCOLS (or FITS_BINKEY). Then it looks for the Chandra +parameters CPREF (or PREFX) in the FITS binary table header. Failing +this, it looks for columns named "X" and "Y" and if these are not +found, it looks for columns containing the characters "X" and "Y". + +See Binning FITS Binary Tables and +Non-FITS Event Files for more information. + + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + +=cut diff --git a/doc/pod/funimageput.pod b/doc/pod/funimageput.pod new file mode 100644 index 0000000..60eea7d --- /dev/null +++ b/doc/pod/funimageput.pod @@ -0,0 +1,145 @@ +=pod + +=head1 NAME + + + +B + + +=head1 SYNOPSIS + + + + + + #include + + int FunImagePut(Fun fun, void *buf, int dim1, int dim2, int bitpix, + char *plist) + + + + + +=head1 DESCRIPTION + + + +The B routine outputs an image array to a FITS +file. The image is written either as a primary header/data unit or as +an image extension, depending on whether other data have already been +written to the file. That is, if the current file position is at the +beginning of the file, a primary HDU is written. Otherwise, an +image extension is written. + + +The first argument is the Funtools handle returned by +FunOpen(). The second B +argument is a pointer to a data buffer to write. The Band +B arguments that follow specify the dimensions of the image, +where dim1 corresponds to naxis1 and dim2 corresponds to naxis2. The +B argument specifies the data type of the image and can +have the following FITS-standard values: + + +=over 4 + + + + +=item * + +8 unsigned char + + +=item * + +16 short + + +=item * + +32 int + + +=item * + +-32 float + + +=item * + +-64 double + + +=back + + + + +When FunTableRowPut() is first +called for a given image, Funtools checks to see if the primary header +has already been written (by having previously written an image or a +binary table.) If not, this image is written to the primary HDU. +Otherwise, it is written to an image extension. + +Thus, a simple program to generate a FITS image might look like this: + + int i; + int dim1=512, dim2=512; + double *dbuf; + Fun fun; + dbuf = malloc(dim1*dim2*sizeof(double)); + /* open the output FITS image, preparing to copy input params */ + if( !(fun = FunOpen(argv[1], "w", NULL)) ) + gerror(stderr, "could not FunOpen output file: %s\n", argv[1]); + for(i=0; i<(dim1*dim2); i++){ + ... fill dbuf ... + } + /* put the image (header will be generated automatically */ + if( !FunImagePut(fun, buf, dim1, dim2, -64, NULL) ) + gerror(stderr, "could not FunImagePut: %s\n", argv[1]); + FunClose(fun); + free(dbuf); + + + +In addition, if a +Funtools reference handle +was specified when this table was opened, the +parameters from this +Funtools reference handle +are merged into the new image +header. Furthermore, if a reference image was specified during +FunOpen(), the values of +B, B, and B in the calling sequence +can all be set to 0. In this case, default values are taken from the +reference image section. This is useful if you are reading an image +section in its native data format, processing it, and then writing +that section to a new FITS file. See the +imblank example code. + + +The data are assumed to be in the native machine format and will +automatically be swapped to FITS big-endian format if necessary. This +behavior can be over-ridden with the B +keyword in the B param list string. + + +When you are finished writing the image, you should call +FunFlush() to write out the FITS +image padding. However, this is not necessary if you subsequently call +FunClose() without doing any other I/O to the FITS file. + + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + +=cut diff --git a/doc/pod/funimagerowget.pod b/doc/pod/funimagerowget.pod new file mode 100644 index 0000000..91c776a --- /dev/null +++ b/doc/pod/funimagerowget.pod @@ -0,0 +1,137 @@ +=pod + +=head1 NAME + + + +B + + + +=head1 SYNOPSIS + + + + + + #include + + void *FunImageRowGet(Fun fun, void *buf, int rstart, int rstop, + char *plist) + + + + + +=head1 DESCRIPTION + + + + +The B routine returns one or more image rows +from the specified section of a Funtools data file. If the input data +are of type image, the array is generated by extracting the specified +image rows and then binning them according to the specified bin +factor. If the input data are contained in a binary table or raw +event file, the rows are binned on the columns specified by the +B keyword (using appropriate default columns as needed), +after which the image section and bin factors are applied. + + +The first argument is the Funtools handle returned by +FunOpen(). The second B +argument is a pointer to a data buffer to fill. If NULL is specified, +FunImageGet() will allocate a buffer of the appropriate size. + + +The third and fourth arguments specify the first and last row to +retrieve. Rows are counted starting from 1, up to the value of +FUN_YMAX(fun). The final B (i.e., parameter list) argument +is a string containing one or more comma-delimited +B parameters. It can be used to specify the return +data type using the B keyword. If no such keyword is +specified in the plist string, the data type of the image is the same +as the data type of the original input file, or is of type int for +FITS binary tables. + + +If the Bvalue is supplied in the plist string, the data +type of the returned image will be one of the supported FITS image +data types: + + +=over 4 + + + + +=item * + +8 unsigned char + + +=item * + +16 short + + +=item * + +32 int + + +=item * + +-32 float + + +=item * + +-64 double + + +=back + + + + +For example: + + double *drow; + Fun fun; + ... open files ... + /* get section dimensions */ + FunInfoGet(fun, FUN_SECT_DIM1, &dim1, FUN_SECT_DIM2, &dim2, 0); + /* allocate one line's worth */ + drow = malloc(dim1*sizeof(double)); + /* retrieve and process each input row (starting at 1) */ + for(i=1; i <= dim2; i++){ + if( !FunImageRowGet(fun, drow, i, i, "bitpix=-64") ) + gerror(stderr, "can't FunImageRowGet: %d %s\n", i, iname); + /* reverse the line */ + for(j=1; j<=dim1; j++){ + ... process drow[j-1] ... + } + } + ... + + + +On success, a pointer to the image buffer is returned. (This will be +the same as the second argument, if NULL is not passed to the latter.) +On error, NULL is returned. Note that the considerations described +above for specifying binning columns in +FunImageGet() also apply to +B. + + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + +=cut diff --git a/doc/pod/funimagerowput.pod b/doc/pod/funimagerowput.pod new file mode 100644 index 0000000..2ff05cc --- /dev/null +++ b/doc/pod/funimagerowput.pod @@ -0,0 +1,122 @@ +=pod + +=head1 NAME + + + +B + + + +=head1 SYNOPSIS + + + + + + #include + + void *FunImageRowPut(Fun fun, void *buf, int rstart, int rstop, + int dim1, int dim2, int bitpix, char *plist) + + + + + +=head1 DESCRIPTION + + + + +The B routine writes one or more image rows to +the specified FITS image file. The first argument is the Funtools +handle returned by FunOpen(). +The second B argument is a pointer to the row data buffer, +while the third and fourth arguments specify the starting and ending +rows to write. Valid rows values range from 1 to dim2, i.e., row is +one-valued. + + +The Band B arguments that follow specify the +dimensions, where dim1 corresponds to naxis1 and dim2 corresponds to +naxis2. The B argument data type of the image and can +have the following FITS-standard values: + + +=over 4 + + + + +=item * + +8 unsigned char + + +=item * + +16 short + + +=item * + +32 int + + +=item * + +-32 float + + +=item * + +-64 double + + +=back + + + +For example: + + double *drow; + Fun fun, fun2; + ... open files ... + /* get section dimensions */ + FunInfoGet(fun, FUN_SECT_DIM1, &dim1, FUN_SECT_DIM2, &dim2, 0); + /* allocate one line's worth */ + drow = malloc(dim1*sizeof(double)); + /* retrieve and process each input row (starting at 1) */ + for(i=1; i <= dim2; i++){ + if( !FunImageRowGet(fun, drow, i, i, "bitpix=-64") ) + gerror(stderr, "can't FunImageRowGet: %d %s\n", i, iname); + ... process drow ... + if( !FunImageRowPut(fun2, drow, i, i, 64, NULL) ) + gerror(stderr, "can't FunImageRowPut: %d %s\n", i, oname); + } + ... + + + +The data are assumed to be in the native machine format and will +automatically be swapped to big-endian FITS format if necessary. This +behavior can be over-ridden with the B +keyword in the B param list string. + + +When you are finished writing the image, you should call +FunFlush() to write out the FITS +image padding. However, this is not necessary if you subsequently call +FunClose() without doing any other I/O to the FITS file. + + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + +=cut diff --git a/doc/pod/funindex.pod b/doc/pod/funindex.pod new file mode 100644 index 0000000..cdc2fc7 --- /dev/null +++ b/doc/pod/funindex.pod @@ -0,0 +1,83 @@ +=pod + +=head1 NAME + + + +B + + + +=head1 SYNOPSIS + + + + + +funindex [oname] + + + + + +=head1 OPTIONS + + + + + + NB: these options are not compatible with Funtools processing. Please + use the defaults instead. + -c # compress output using gzip" + -a # ASCII output, ignore -c (default: FITS table)" + -f # FITS table output (default: FITS table)" + -l # long output, i.e. with key value(s) (default: long)" + -s # short output, i.e. no key value(s) (default: long)" + + + + +=head1 DESCRIPTION + + + + +The funindex script creates an index for the specified column (key) by +running funtable -s (sort) and then saving the column value and the +record number for each sorted row. This index will be used automatically + by funtools filtering of that column, provided the index file's modification +date is later than that of the data file. + + +The first required argument is the name of the FITS binary table +to index. Please note that text files cannot be indexed at this time. +The second required argument is the column (key) name to index. While +multiple keys can be specified in principle, the funtools index processing +assume a single key and will not recognize files containing multiple keys. + + +By default, the output index file name is [root]_[key].idx, where [root] +is the root of the input file. Funtools looks for this specific file name +when deciding whether to use an index for faster filtering. Therefore, the +optional third argument (output file name) should not be used for funtools +processing. + + +For example, to create an index on column Y for a given FITS file, use: + + funindex foo.fits Y + +This will generate an index named foo_y.idx, which will be used by funtools +for filters involving the Y column. + + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + +=cut diff --git a/doc/pod/funindexes.pod b/doc/pod/funindexes.pod new file mode 100644 index 0000000..e4cabaa --- /dev/null +++ b/doc/pod/funindexes.pod @@ -0,0 +1,215 @@ +=pod + +=head1 NAME + + + +B + + + +=head1 SYNOPSIS + + + + + +This document contains a summary of the user interface for +filtering rows in binary tables with indexes. + + + +=head1 DESCRIPTION + + + + + +Funtools Table Filtering allows rows in a +table to be selected based on the values of one or more columns in the +row. Because the actual filter code is compiled on the fly, it is very +efficient. For very large files (hundreds of Mb or larger), however, +evaluating the filter expression on each row can take a long time. Therefore, +funtools supports index files for columns, which are used automatically during +filtering to reduce dramatically the number of row evaluations performed. +The speed increase for indexed filtering can be an order of magnitude or +more, depending on the size of the file. + + +The funindex program creates a +index on column in a binary table. For example, to create an index +for the column pi in the file huge.fits, use: + + funindex huge.fits pi + +This will create an index named huge_pi.idx. + + +When a filter expression is initialized for row evaluation, funtools +looks for an index file for each column in the filter expression. If +found, and if the file modification date of the index file is later +than that of the data file, then the index will be used to reduce the +number of rows that are evaluated in the filter. When Spatial Region Filtering is part of the +expression, the columns associated with the region checked for index +files. + + +If an index file is not available for a given column, then in general, +all rows must be checked when that column is part of a filter +expression. This is not true, however, when a non-indexed column is +part of an AND expression. In this case, only the rows that pass the +other part of the AND expression need to be checked. Thus, in some cases, +filtering speed can increase significantly even if all columns are not +indexed. + + +Also note that certain types of filter expression syntax cannot make +use of indices. For example, calling functions with column names as +arguments implies that all rows must be checked against the function +value. Once again, however, if this function is part of an AND +expression, then a significant improvement in speed still is possible +if the other part of the AND expression is indexed. + + +As an example, note below the dramatic speedup in searching a 1 Gb +file using an AND filter, even when one of the columns (pha) has no +index: + + +bynars-16: time fundisp huge.fits'[idx_use=0,idx_debug=1,pha=2348&&cir 4000 4000 1]' "x y pha" + x y pha +----------- ----------- ---------- + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 +42.36u 13.07s 6:42.89 13.7% + +bynars-17: time fundisp huge.fits'[idx_use=1,idx_debug=1,pha=2348&&cir 4000 4000 1]' "x y pha" + x y pha +----------- ----------- ---------- +idxeq: [INDEF] +idxand sort: x[ROW 8037025:8070128] y[ROW 5757665:5792352] +idxand(1): INDEF [IDX_OR_SORT] +idxall(1): [IDX_OR_SORT] + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 + 3999.48 4000.47 2348 +1.55u 0.37s 1:19.80 2.4% + + +When all columns are indexed, the increase in speed can be even more dramatic: + +bynars-20: time fundisp huge.fits'[idx_use=0,idx_debug=1,pi=770&&cir 4000 4000 1]' "x y pi" + x y pi +----------- ----------- ---------- + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 +42.60u 12.63s 7:28.63 12.3% + +bynars-21: time fundisp huge.fits'[idx_use=1,idx_debug=1,pi=770&&cir 4000 4000 1]' "x y pi" + x y pi +----------- ----------- ---------- +idxeq: pi start=9473025,stop=9492240 => pi[ROW 9473025:9492240] +idxand sort: x[ROW 8037025:8070128] y[ROW 5757665:5792352] +idxor sort/merge: pi[ROW 9473025:9492240] [IDX_OR_SORT] +idxmerge(5): [IDX_OR_SORT] pi[ROW] +idxall(1): [IDX_OR_SORT] + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 + 3999.48 4000.47 770 +1.67u 0.30s 0:24.76 7.9% + + + +The miracle of indexed filtering (and indeed, of any indexing) is due +to the speed of the binary search on the index, which is of order +log2(n) instead of n. (The funtools binary search method is taken from +http://www.tbray.org/ongoing/When/200x/2003/03/22/Binary, to whom +grateful acknowledgement is made.) This means that the larger the +file, the better the performance. Conversely, it also means that +for small files, using an index (and the overhead involved) can slow +filtering down somewhat. Our tests indicate that on a file containing +a few tens of thousands of rows, indexed filtering can be 10-20 +percent slower. Of course, your mileage will vary with conditions +(disk access speed, amount of available memory, process load, etc.) + + +Any problem encountered during index processing is supposed to result in +indexing being turned off, replaced by filtering all rows. You can turn +filtering off manually by setting the idx_use variable to 0 (in a filter +expression) or the FILTER_IDX_USE environment variable to 0 (in the global +environment). Debugging output showing how the indexes are being processed can +be displayed to stderr by setting the idx_debug variable to 1 (in a filter +expression) or the FILTER_IDX_DEBUG environment variable to 1 (in the global +environment). + + +Currently, indexed filtering only works with FITS binary tables and raw +event files. It does not work with text files. This restriction might be +removed in a future release. + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + + +=cut diff --git a/doc/pod/funinfoget.pod b/doc/pod/funinfoget.pod new file mode 100644 index 0000000..456ac0c --- /dev/null +++ b/doc/pod/funinfoget.pod @@ -0,0 +1,226 @@ +=pod + +=head1 NAME + + + +B + + + +=head1 SYNOPSIS + + + + + + #include + + int FunInfoGet(Fun fun, int type, char *addr, ...) + + + + + +=head1 DESCRIPTION + + + + +The B routine returns information culled from the +Funtools structure. The first argument is the Fun handle from which +information is to be retrieved. This first required argument is followed +by a variable length list of pairs of arguments. Each pair consists +of an integer representing the type of information to retrieve and the +address where the information is to be stored. The list is terminated by a 0. +The routine returns the number of get actions performed. + + +The full list of available information is described below. Please note +that only a few of these will be useful to most application developers. +For imaging applications, the most important types are: + + FUN_SECT_DIM1 int /* dim1 for section */ + FUN_SECT_DIM2 int /* dim2 for section */ + FUN_SECT_BITPIX int /* bitpix for section */ + +These would be used to determine the dimensions and data type of image +data retrieved using the +FunImageGet() routine. For +example: + + /* extract and bin the data section into an image buffer */ + buf = FunImageGet(fun, NULL, NULL); + /* get required information from funtools structure. + this should come after the FunImageGet() call, in case the call + changed sect_bitpix */ + FunInfoGet(fun, + FUN_SECT_BITPIX, &bitpix, + FUN_SECT_DIM1, &dim1, + FUN_SECT_DIM2, &dim2, + 0); + /* loop through pixels and reset values below limit to value */ + for(i=0; i the call to +FunImageGet(), +in order to retrieve the updated bitpix value. +See the imblank example code for more +details. + + +It also can be useful to retrieve the World Coordinate System +information from the Funtools structure. Funtools uses the the WCS +Library developed by Doug Mink at SAO, which is available +here. +(More information about the WCSTools project in general can be found +here.) +The FunOpen() routine initializes +two WCS structures that can be used with this WCS Library. +Applications can retrieve either of these two WCS structures using +B: + + FUN_WCS struct WorldCoor * /* wcs structure, for image coordinates*/ + FUN_WCS0 struct WorldCoor * /* wcs structure, for physical coordinates */ + +The structure retrieved by FUN_WCS is a WCS library handle containing +parameters suitable for use with image coordinates, regardless of whether the +data are images or tables. For this structure, the WCS reference point +(CRPIX) has been converted to image coordinates if the underlying file +is a table (and therefore in physical coordinates). You therefore must +ensure that the positions being passed to a routine like pix2wcs are in +image coordinates. The FUN_WCS0 structure has not had its WCS +reference point converted to image coordinates. It therefore is useful +when passing processing physical coordinates from a table. + + +Once a WCS structure has been retrieved, it can be used as the first +argument to the WCS library routines. (If the structure is NULL, no +WCS information was contained in the file.) The two important WCS routines +that Funtools uses are: + + #include + + + +=head1 SYNOPSIS + + + + + + #include + + int FunInfoPut(Fun fun, int type, char *addr, ...) + + + + + +=head1 DESCRIPTION + + + + +The B routine puts information into a Funtools +structure. The first argument is the Fun handle from which +information is to be retrieved. After this first required argument +comes a variable length list of pairs of arguments. Each pair consists +of an integer representing the type of information to store and the +address of the new information to store in the struct. The variable +list is terminated by a 0. The routine returns the number of put +actions performed. + + +The full list of available information is described above with the +FunInfoPut() routine. Although +use of this routine is expected to be uncommon, there is one +important situation in which it plays an essential part: writing +multiple extensions to a single output file. + + +For input, multiple extensions are handled by calling +FunOpen() for each extension to be +processed. When opening multiple inputs, it sometimes is the case that +you will want to process them and then write them (including their +header parameters) to a single output file. To accomplish this, you +open successive input extensions using +FunOpen() and then call +B to set the +Funtools reference handle +of the output file to that of the newly opened input extension: + + /* open a new input extension */ + ifun=FunOpen(tbuf, "r", NULL)) ) + /* make the new extension the reference handle for the output file */ + FunInfoPut(ofun, FUN_IFUN, &ifun, 0); + + +Resetting FUN_IFUN has same effect as when a funtools handle is passed +as the final argument to +FunOpen(). The state of the output +file is reset so that a new extension is ready to be written. +Thus, the next I/O call on the output extension will output the +header, as expected. + + +For example, in a binary table, after resetting FUN_IFUN you can then +call FunColumnSelect() to +select the columns for output. When you then call +FunImagePut() or FunTableRowPut(), a new +extension will be written that contains the header parameters from the +reference extension. Remember to call +FunFlush() to complete output of a +given extension. + + +A complete example of this capability is given +in the evcol example code. +The central algorithm is: + + +=over 4 + + + + +=item * + +open the output file without a reference handle + + +=item * + +loop: open each input extension in turn + + +=over 4 + + + + +=item * + +set the reference handle for output to the newly opened input extension + + +=item * + +read the input rows or image and perform processing + + +=item * + +write new rows or image to the output file + + +=item * + +flush the output + + +=item * + +close input extension + + +=back + + + + +=item * + +close output file + + +=back + + +Note that FunFlush() is called +after processing each input extension in order to ensure that the +proper padding is written to the output file. A call to +FunFlush() also ensures that the +extension header is written to the output file in the case where there +are no rows to output. + + +If you wish to output a new extension without using a +Funtools reference handle, you can +call FunInfoPut() to reset the FUN_OPS value directly. For a binary +table, you would then call FunColumnSelect() to set up the columns for +this new extension. + + /* reset the operations performed on this handle */ + int ops=0; + FunInfoPut(ofun, FUN_OPS, &ops, 0); + FunColumnSelect(fun, sizeof(EvRec), NULL, + "MYCOL", "J", "w", FUN_OFFSET(Ev, mycol), + NULL); + +Once the FUN_OPS variable has been reset, the next I/O call on the +output extension will output the header, as expected. + + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + +=cut diff --git a/doc/pod/funjoin.pod b/doc/pod/funjoin.pod new file mode 100644 index 0000000..d7830f9 --- /dev/null +++ b/doc/pod/funjoin.pod @@ -0,0 +1,233 @@ +=pod + +=head1 NAME + + + +B + + + +=head1 SYNOPSIS + + + + + +funjoin [switches] ... + + + + + +=head1 OPTIONS + + + + + + -a cols # columns to activate in all files + -a1 cols ... an cols # columns to activate in each file + -b 'c1:bvl,c2:bv2' # blank values for common columns in all files + -bn 'c1:bv1,c2:bv2' # blank values for columns in specific files + -j col # column to join in all files + -j1 col ... jn col # column to join in each file + -m min # min matches to output a row + -M max # max matches to output a row + -s # add 'jfiles' status column + -S col # add col as status column + -t tol # tolerance for joining numeric cols [2 files only] + + + + +=head1 DESCRIPTION + + + +B joins rows from two or more (up to 32) +FITS Binary Table files, based on the values +of specified join columns in each file. NB: the join columns must have +an index file associated with it. These files are generated using the +B program. + + +The first argument to the program specifies the first input FITS table +or raw event file. If "stdin" is specified, data are read from the +standard input. Subsequent arguments specify additional event files +and tables to join. The last argument is the output FITS file. + + +NB: Do B use Funtools Bracket +Notation to specify FITS extensions and row filters when running +funjoin or you will get wrong results. Rows are accessed and joined +using the index files directly, and this bypasses all filtering. + + +The join columns are specified using the B<-j col> switch (which +specifies a column name to use for all files) or with B<-j1 col1>, +B<-j2 col2>, ... B<-jn coln> switches (which specify a column +name to use for each file). A join column must be specified for each file. +If both B<-j col> and B<-jn coln> are specified for a given +file, then the latter is used. Join columns must either be of type +string or type numeric; it is illegal to mix numeric and string +columns in a given join. For example, to join three files using the +same key column for each file, use: + + funjoin -j key in1.fits in2.fits in3.fits out.fits + +A different key can be specified for the third file in this way: + + funjoin -j key -j3 otherkey in1.fits in2.fits in3.fits out.fits + + + +The B<-a "cols"> switch (and B<-a1 "col1">, +B<-a2 "cols2"> counterparts) can be used to specify columns to +activate (i.e. write to the output file) for each input file. By +default, all columns are output. + + +If two or more columns from separate files have the same name, the +second (and subsequent) columns are renamed to have an underscore +and a numeric value appended. + + +The B<-m min> and B<-M max> switches specify the minimum +and maximum number of joins required to write out a row. The default +minimum is 0 joins (i.e. all rows are written out) and the default maximum +is 63 (the maximum number of possible joins with a limit of 32 input files). +For example, to write out only those rows in which exactly two files +have columns that match (i.e. one join): + + funjoin -j key -m 1 -M 1 in1.fits in2.fits in3.fits ... out.fits + + + +A given row can have the requisite number of joins without all of the +files being joined (e.g. three files are being joined but only two +have a given join key value). In this case, all of the columns of the +non-joined file are written out, by default, using blanks (zeros or NULLs). +The B<-b c1:bv1,c2:bv2> and +B<-b1 'c1:bv1,c2:bv2' -b2 'c1:bv1,c2:bv2' ...> +switches can be used to set the blank value for columns common to all +files and/or columns in a specified file, respectively. Each blank value +string contains a comma-separated list of column:blank_val specifiers. +For floating point values (single or double), a case-insensitive string +value of "nan" means that the IEEE NaN (not-a-number) should be +used. Thus, for example: + + funjoin -b "AKEY:???" -b1 "A:-1" -b3 "G:NaN,E:-1,F:-100" ... + +means that a non-joined AKEY column in any file will contain the +string "???", the non-joined A column of file 1 will contain a value +of -1, the non-joined G column of file 3 will contain IEEE NaNs, while +the non-joined E and F columns of the same file will contain values -1 +and -100, respectively. Of course, where common and specific blank values +are specified for the same column, the specific blank value is used. + + +To distinguish which files are non-blank components of a given row, +the B<-s> (status) switch can be used to add a bitmask column named +"JFILES" to the output file. In this column, a bit is set for each +non-blank file composing the given row, with bit 0 corresponds to the +first file, bit 1 to the second file, and so on. The file names +themselves are stored in the FITS header as parameters named JFILE1, +JFILE2, etc. The B<-S col> switch allows you to change the name +of the status column from the default "JFILES". + + +A join between rows is the Cartesian product of all rows in one file +having a given join column value with all rows in a second file having +the same value for its join column and so on. Thus, if file1 has 2 +rows with join column value 100, file2 has 3 rows with the same value, +and file3 has 4 rows, then the join results in 2*3*4=24 rows being output. + + +The join algorithm directly processes the index file associated with +the join column of each file. The smallest value of all the current +columns is selected as a base, and this value is used to join +equal-valued columns in the other files. In this way, the index files +are traversed exactly once. + + +The B<-t tol> switch specifies a tolerance value for numeric +columns. At present, a tolerance value can join only two files at a +time. (A completely different algorithm is required to join more than +two files using a tolerance, somethng we might consider implementing +in the future.) + + +The following example shows many of the features of funjoin. The input files +t1.fits, t2.fits, and t3.fits contain the following columns: + + [sh] fundisp t1.fits + AKEY KEY A B + ----------- ------ ------ ------ + aaa 0 0 1 + bbb 1 3 4 + ccc 2 6 7 + ddd 3 9 10 + eee 4 12 13 + fff 5 15 16 + ggg 6 18 19 + hhh 7 21 22 + +fundisp t2.fits + AKEY KEY C D + ----------- ------ ------ ------ + iii 8 24 25 + ggg 6 18 19 + eee 4 12 13 + ccc 2 6 7 + aaa 0 0 1 + +fundisp t3.fits + AKEY KEY E F G +------------ ------ -------- -------- ----------- + ggg 6 18 19 100.10 + jjj 9 27 28 200.20 + aaa 0 0 1 300.30 + ddd 3 9 10 400.40 + + + +Given these input files, the following funjoin command: + + + funjoin -s -a1 "-B" -a2 "-D" -a3 "-E" -b \ + "AKEY:???" -b1 "AKEY:XXX,A:255" -b3 "G:NaN,E:-1,F:-100" \ + -j key t1.fits t2.fits t3.fits foo.fits + +will join the files on the KEY column, outputting all columns except B +(in t1.fits), D (in t2.fits) and E (in t3.fits), and setting blank +values for AKEY (globally, but overridden for t1.fits) and A (in file +1) and G, E, and F (in file 3). A JFILES column will be output to +flag which files were used in each row: + + + AKEY KEY A AKEY_2 KEY_2 C AKEY_3 KEY_3 F G JFILES + ------------ ------ ------ ------------ ------ ------ ------------ ------ -------- ----------- -------- + aaa 0 0 aaa 0 0 aaa 0 1 300.30 7 + bbb 1 3 ??? 0 0 ??? 0 -100 nan 1 + ccc 2 6 ccc 2 6 ??? 0 -100 nan 3 + ddd 3 9 ??? 0 0 ddd 3 10 400.40 5 + eee 4 12 eee 4 12 ??? 0 -100 nan 3 + fff 5 15 ??? 0 0 ??? 0 -100 nan 1 + ggg 6 18 ggg 6 18 ggg 6 19 100.10 7 + hhh 7 21 ??? 0 0 ??? 0 -100 nan 1 + XXX 0 255 iii 8 24 ??? 0 -100 nan 2 + XXX 0 255 ??? 0 0 jjj 9 28 200.20 4 + + + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + +=cut diff --git a/doc/pod/funlib.pod b/doc/pod/funlib.pod new file mode 100644 index 0000000..354e217 --- /dev/null +++ b/doc/pod/funlib.pod @@ -0,0 +1,542 @@ +=pod + +=head1 NAME + + + +B + + + +=head1 SYNOPSIS + + + + +A description of the Funtools library. + + + +=head1 DESCRIPTION + + + +B + +To create a Funtools application, you need to include +the funtools.h definitions file in your code: + + #include + + +You then call Funtools subroutines and functions to access Funtools data. +The most important routines are: + + +=over 4 + + + + + + +=item * + +FunOpen: open a Funtools file + + +=item * + +FunInfoGet: get info about an image or table + + +=item * + +FunImageGet: retrieve image data + + +=item * + +FunImageRowGet: retrieve image data by row + + +=item * + +FunImagePut: output image data + + +=item * + +FunImageRowPut: output image data by row + + +=item * + +FunColumnSelect: select columns in a table for access + + +=item * + +FunTableRowGet: retrieve rows from a table + + +=item * + +FunTableRowPut: output rows to a table + + +=item * + +FunClose: close a Funtools file + + +=back + + + +Your program must be linked against the libfuntools.a library, +along with the math library. The following libraries also might be required +on your system: + + +=over 4 + + + + +=item * + +-lsocket -lnsl for socket support + + +=item * + +-ldl for dynamic loading + + +=back + + + +For example, on a Solaris system using gcc, use the following link line: + + gcc -o foo foo.c -lfuntools -lsocket -lnsl -ldl -lm + +On a Solaris system using Solaris cc, use the following link line: + + gcc -o foo foo.c -lfuntools -lsocket -lnsl -lm + +On a Linux system using gcc, use the following link line: + + gcc -o foo foo.c -lfuntools -ldl -lm + +Once configure has built a Makefile on your platform, the required +"extra" libraries (aside from -lm, which always is required) are +specified in that file's EXTRA_LIBS variable. For example, under +Linux you will find: + + grep EXTRA_LIBS Makefile + EXTRA_LIBS = -ldl + ... + + + +The Funtools library contains both the zlib library +(http://www.gzip.org/zlib/) and Doug Mink's WCS library +(http://tdc-www.harvard.edu/software/wcstools/). It is not necessary +to put these libraries on a Funtools link line. Include files +necessary for using these libraries are installed in the Funtools +include directory. + +B + +The +FunOpen() +function is used to open a FITS file, an array, or a raw event file: + + /* open the input FITS file for reading */ + ifun = FunOpen(iname, "r", NULL); + /* open the output FITS file for writing, and connect it to the input file */ + ofun = FunOpen(iname, "w", ifun); + +A new output file can inherit header parameters automatically from +existing input file by passing the input Funtools handle as the last +argument to the new file's +FunOpen() +call as shown above. + + +For image data, you then can call +FunImageGet() +to read an image into memory. + + float buf=NULL; + /* extract and bin the data section into an image buffer */ + buf = FunImageGet(fun, NULL, "bitpix=-32"); + +If the (second) buf argument to this call is NULL, buffer space is allocated +automatically. The (third) plist argument can be used to specify the +return data type of the array. If NULL is specified, the data type of +the input file is used. + + +To process an image buffer, you would generally make a call to +FunInfoGet() to determine the +dimensions of the image (which may have been changed from the original +file dimensions due to Funtools image +sectioning on the command line). In a FITS image, the index along +the dim1 axis varies most rapidly, followed by the dim2 axis, etc. +Thus, to access each pixel in an 2D image, use a double loop such as: + + buf = FunImageGet(fun, NULL, "bitpix=-32"); + FunInfoGet(fun, FUN_SECT_DIM1, &dim1, FUN_SECT_DIM2, &dim2, 0); + for(i=1; i<=dim2; i++){ + for(j=1; j<=dim1; j++){ + ... process buf[((i-1)*dim1)+(j-1)] ... + } + } + +or: + + buf = FunImageGet(fun, NULL, "bitpix=-32"); + FunInfoGet(fun, FUN_SECT_DIM1, &dim1, FUN_SECT_DIM2, &dim2, 0); + for(i=0; i<(dim1*dim2); i++){ + ... process buf[i] ... + } + +Finally, you can write the resulting image to disk using +FunImagePut(): + + FunImagePut(fun2, buf, dim1, dim2, -32, NULL); + +Note that Funtools automatically takes care of book-keeping tasks such as +reading and writing FITS headers (although you can, of course, write +your own header or add your own parameters to a header). + + +For binary tables and raw event files, a call to +FunOpen() +will be followed by a call to the +FunColumnSelect() +routine to select columns to be read from the input file and/or +written to the output file: + + + typedef struct evstruct{ + double time; + int time2; + } *Ev, EvRec; + FunColumnSelect(fun, sizeof(EvRec), NULL, + "time", "D", "rw", FUN_OFFSET(Ev, time), + "time2", "J", "w", FUN_OFFSET(Ev, time2), + NULL); + +Columns whose (third) mode argument contains an "r" are "readable", +i.e., columns will be read from the input file and converted into the +data type specified in the call's second argument. These columns +values then are stored in the specified offset of the user record +structure. Columns whose mode argument contains a "w" are +"writable", i.e., these values will be written to the output file. +The +FunColumnSelect() +routine also offers the option of automatically merging user +columns with the original input columns when writing the output +rows. + + +Once a set of columns has been specified, you can retrieve rows using +FunTableRowGet(), +and write the rows using +FunTableRowPut(): + + Ev ebuf, ev; + /* get rows -- let routine allocate the array */ + while( (ebuf = (Ev)FunTableRowGet(fun, NULL, MAXROW, NULL, &got)) ){ + /* process all rows */ + for(i=0; itime2 = (int)(ev->time+.5); + /* change the input time as well */ + ev->time = -(ev->time/10.0); + } + /* write out this batch of rows with the new column */ + FunTableRowPut(fun2, (char *)ebuf, got, 0, NULL); + /* free row data */ + if( ebuf ) free(ebuf); + } + +The input rows are retrieved into an array of user structs, which +can be accessed serially as shown above. Once again, Funtools +automatically takes care of book-keeping tasks such as reading and writing +FITS headers (although you can, of course, write your own header or +add your own parameters to a header). + + +When all processing is done, you can call +FunClose() +to close the file(s): + + FunClose(fun2); + FunClose(fun); + + + +These are the basics of processing FITS files (and arrays or raw event +data) using Funtools. The routines in these examples are described in +more detail below, along with a few other routines that support +parameter access, data flushing, etc. + +B + +To create a Funtools application, a software developer will include +the funtools.h definitions file in Funtools code: + + #include + +The program is linked against the libfuntools.a library, along with the +math library (and the dynamic load library, if the latter is available +on your system): + + gcc -o foo foo.c -lfuntools -ldl -lm + + +If gcc is used, Funtools filtering can be performed using dynamically +loaded shared objects that are built at run-time. Otherwise, filtering +is performed using a slave process. + +Funtools has been built on the following systems: + + +=over 4 + + + + +=item * + +Sun/Solaris 5.X + + +=item * + +Linux/RedHat Linux 5.X,6.X,7.X + + +=item * + +Dec Alpha/OSF1 V4.X + + +=item * + +WindowsNT/Cygwin 1.0 + + +=item * + +SGI/IRIX64 6.5 + + +=back + + + +B + +There is a natural order for all I/O access libraries. You would not +think of reading a file without first opening it, or writing a file +after closing it. A large part of the experiment in funtools is to use +the idea of "natural order" as a means of making programming +easier. We do this by maintaining the state of processing for a given +funtools file, so that we can do things like write headers and flush +extension padding at the right time, without you having to do it. + + +For example, if you open a new funtools file for writing using +FunOpen(), +then generate an array of image data and call +FunImagePut(), +funtools knows to write the image header automatically. +There is no need to think about writing a standard header. +Of course, you can add parameters to the file first by +calling one of the +FunParamPut() +routines, and these parameters will automatically be added +to the header when it is written out. There still is no +need to write the header explicitly. + + +Maintaining state in this way means that there are certain rules of +order which should be maintained in any funtools program. In particular, +we strongly recommend the following ordering rules be adhered to: + + + +=over 4 + + + + +=item * + +When specifying that input extensions be copied to an output file +via a reference handle, open the output file B reading the +input file. (Otherwise the initial copy will not occur). + + + +=item * + +Always write parameters to an output file using one of the +FunParamPut() calls +B writing any data. (This is a good idea for all FITS +libraries, to avoid having to recopy data is the FITS header needs +to be extended by adding a single parameter.) + + + +=item * + +If you retrieve an image, and need to know the data +type, use the FUN_SECT_BITPIX option of +FunInfoGet(), +B calling +FunImageGet(), since +it is possible to change the value of BITPIX from the latter. + + + +=item * + +When specifying that input extensions be copied to an output file +via a reference handle, close the output file B closing +input file, or else use +FunFlush() +explicitly on the output file +B closing the input file. (Otherwise the final copy will +not occur). + + +=back + + + + +We believe that these are the natural rules that are implied in most +FITS programming tasks. However, we recognize that making explicit use +of "natural order" to decide what automatic action to take on behalf +of the programmer is experimental. Therefore, if you find that your +needs are not compatible with our preferred order, please let us know +-- it will be most illuminating for us as we evaluate this experiment. + +B + +The following complete coding examples are provided to illustrate the +simplicity of Funtools applications. They can be found in the funtest +subdirectory of the Funtools distribution. In many cases, you should +be able to modify one of these programs to generate your own Funtools +program: + + +=over 4 + + + + +=item * + +evread.c: read and write binary tables + + +=item * + +evcols.c: add column and rows to binary tables + + +=item * + +evmerge.c: merge new columns with existing columns + + +=item * + +evnext.c: manipulate raw data pointers + + +=item * + +imblank.c: blank out image values below a threshold + + +=item * + +asc2fits.c: convert a specific ASCII table to FITS binary table + + +=back + + + +B + + +#include + +Fun FunOpen(char *name, char *mode, Fun ref) + +void *FunImageGet(Fun fun, void *buf, char *plist) + +int FunImagePut(Fun fun, void *buf, int dim1, int dim2, int bitpix, char *plist) + +void * FunImageRowGet(Fun fun, void *buf, int rstart, int rstop, char *plist) + +void * FunImageRowPut(Fun fun, void *buf, int rstart, int rstop, int dim1, int dim2, int bitpix, char *plist) + +int FunColumnSelect(Fun fun, int size, char *plist, ...) + +void FunColumnActivate(Fun fun, char *s, char *plist) + +int FunColumnLookup(Fun fun, char *s, int which, char **name, int *type, int *mode, int *offset, int *n, int *width) + +void *FunTableRowGet(Fun fun, void *rows, int maxrow, char *plist, int *nrow) + +int FunTableRowPut(Fun fun, void *rows, int nev, int idx, char *plist) + +int FunParamGetb(Fun fun, char *name, int n, int defval, int *got) + +int FunParamGeti(Fun fun, char *name, int n, int defval, int *got) + +double FunParamGetd(Fun fun, char *name, int n, double defval, int *got) + +char *FunParamGets(Fun fun, char *name, int n, char *defval, int *got) + +int FunParamPutb(Fun fun, char *name, int n, int value, char *comm, int append) + +int FunParamPuti(Fun fun, char *name, int n, int value, char *comm, int append) + +int FunParamPutd(Fun fun, char *name, int n, double value, int prec, char *comm, int append) + +int FunParamPuts(Fun fun, char *name, int n, char *value, char *comm, int append) + +int FunInfoGet(Fun fun, int type, ...) + +int FunInfoPut(Fun fun, int type, ...) + +void FunFlush(Fun fun, char *plist) + +void FunClose(Fun fun) + + + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + +=cut diff --git a/doc/pod/funmerge.pod b/doc/pod/funmerge.pod new file mode 100644 index 0000000..0cb9216 --- /dev/null +++ b/doc/pod/funmerge.pod @@ -0,0 +1,122 @@ +=pod + +=head1 NAME + + + +B + + + +=head1 SYNOPSIS + + + + + +funmerge [-w|-x] -f [colname] ... + + + + + +=head1 OPTIONS + + + + + + -f # output a column specifying file from which this event came + -w # adjust position values using WCS info + -x # adjust position values using WCS info and save old values + + + + +=head1 DESCRIPTION + + + + +B merges FITS data from one or more +FITS Binary Table files +or raw event files. + +The first argument to the program specifies the first input FITS table +or raw event file. If "stdin" is specified, data are read from the +standard input. Use Funtools Bracket +Notation to specify FITS extensions and row filters. Subsequent +arguments specify additional event files and tables to merge. (NB: Stdin +cannot not be used for any of these additional input file arguments.) +The last argument is the output FITS file. The columns in each input table +must be identical. + + +If an input file begins with the '@' character, it is processed as an +include file, i.e., as a text file containing event file names (as +well as blank lines and/or comment lines starting with the '#' sign). +If standard input is specified as an include file ('@stdin'), then +file names are read from the standard input until EOF (^D). Event +files and include files can be mixed on a command line. + + +Rows from each table are written sequentially to the output +file. If the switch B<-f [colname]> is specified on the command +line, an additional column is added to each row containing the number +of the file from which that row was taken (starting from one). In +this case, the corresponding file names are stored in the header +parameters having the prefix B, i.e., FUNFIL01, +FUNFIL02, etc. + + +Using the B<-w> switch (or B<-x> switch as described +below), B also can adjust the position column values +using the WCS information in each file. (By position columns, we mean +the columns that the table is binned on, i.e., those columns defined +by the B switch, or (X,Y) by default.) To perform WCS +alignment, the WCS of the first file is taken as the base WCS. Each +position in subsequent files is adjusted by first converting it to the +sky coordinate in its own WCS coordinate system, then by converting +this sky position to the sky position of the base WCS, and finally +converting back to a pixel position in the base system. Note that in +order to perform WCS alignment, the appropriate WCS and TLMIN/TLMAX +keywords must already exist in each FITS file. + +When performing WCS alignment, you can save the original positions in +the output file by using the B<-x> (for "xtra") switch instead +of the B<-w> switch (i.e., using this switch also implies using +B<-w>) The old positions are saved in columns having the same +name as the original positional columns, with the added prefix "OLD_". + +Examples: + + +Merge two tables, and preserve the originating file number for +each row in the column called "FILE" (along with the corresponding +file name in the header): + + [sh] funmerge -f "FILE" test.ev test2.ev merge.ev + + + +Merge two tables with WCS alignment, saving the old position values in +2 additional columns: + + [sh] funmerge -x test.ev test2.ev merge.ev + + + +This program only works on raw event files and binary tables. We have +not yet implemented image and array merging. + + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + +=cut diff --git a/doc/pod/funopen.pod b/doc/pod/funopen.pod new file mode 100644 index 0000000..3d6ab3e --- /dev/null +++ b/doc/pod/funopen.pod @@ -0,0 +1,166 @@ +=pod + +=head1 NAME + + + +B + + + +=head1 SYNOPSIS + + + + + + #include + + Fun FunOpen(char *name, char *mode, Fun ref); + + + + + +=head1 DESCRIPTION + + + + +The B routine opens a Funtools data file for reading or +appending, or creates a new FITS file for writing. The B +argument specifies the name of the Funtools data file to open. You can +use IRAF-style bracket notation to specify +Funtools Files, Extensions, and Filters. +A separate call should be made each time a different FITS extension is +accessed: + + Fun fun; + char *iname; + ... + if( !(fun = FunOpen(iname, "r", NULL)) ){ + fprintf(stderr, "could not FunOpen input file: %s\n", iname); + exit(1); + } + + +If B is "r", the file is opened for reading, and processing +is set up to begin at the specified extension. For reading, +B can be B, in which case the standard input is read. + + +If B is "w", the file is created if it does not exist, or +opened and truncated for writing if it does exist. Processing starts +at the beginning of the file. The B can be B, +in which case the standard output is readied for processing. + + +If B is "a", the file is created if it does not exist, or +opened if it does exist. Processing starts at the end of the file. +The B can be B, in which case the standard +output is readied for processing. + + +When a Funtools file is opened for writing or appending, a previously +opened Funtools reference +handle can be specified as the third argument. This handle +typically is associated with the input Funtools file that will be used +to generate the data for the output data. When a reference file is +specified in this way, the output file will inherit the (extension) +header parameters from the input file: + + Fun fun, fun2; + ... + /* open input file */ + if( !(fun = FunOpen(argv[1], "r", NULL)) ) + gerror(stderr, "could not FunOpen input file: %s\n", argv[1]); + /* open the output FITS image, inheriting params from input */ + if( !(fun2 = FunOpen(argv[2], "w", fun)) ) + gerror(stderr, "could not FunOpen output file: %s\n", argv[2]); + +Thus, in the above example, the output FITS binary table file will +inherit all of the parameters associated with the input binary table +extension. + +A file opened for writing with a +Funtools reference handle also +inherits the selected columns (i.e. those columns chosen for +processing using the +FunColumnSelect() routine) +from the reference file as its default columns. This makes it easy to +open an output file in such a way that the columns written to the +output file are the same as the columns read in the input file. Of +course, column selection can easily be tailored using the +FunColumnSelect() routine. +In particular, it is easy to merge user-defined columns with the input +columns to generate a new file. See the +evmerge for a complete example. + + +In addition, when a +Funtools reference handle +is supplied in a FunOpen() call, +it is possible also to specify that all other extensions from the +reference file (other than the input extension being processed) should +be copied from the reference file to the output file. This is useful, +for example, in a case where you are processing a FITS binary table +or image and you want to copy all of the other extensions to +the output file as well. Copy of other extensions is controlled by +adding a "C" or "c" to the mode string of the +FunOpen() call of the input +reference file. If "C" is specified, then other extensions are +B copied (i.e., copy is forced by the application). If +"c" is used, then other extensions are copied if the user requests +copying by adding a plus sign "+" to the extension name in the bracket +specification. For example, the B program utilizes +"c" mode, giving users the option of copying all other extensions: + + /* open input file -- allow user copy of other extensions */ + if( !(fun = FunOpen(argv[1], "rc", NULL)) ) + gerror(stderr, "could not FunOpen input file: %s\n", argv[1]); + /* open the output FITS image, inheriting params from input */ + if( !(fun2 = FunOpen(argv[2], "w", fun)) ) + gerror(stderr, "could not FunOpen output file: %s\n", argv[2]); + + +Thus, B supports either of these command lines: + + # copy only the EVENTS extension + csh> funtable "test.ev[EVENTS,circle(512,512,10)]" foo.ev + # copy ALL extensions + csh> funtable "test.ev[EVENTS+,circle(512,512,10)]" foo.ev + + + +Use of a Funtools reference +handle implies that the input file is opened before the output +file. However, it is important to note that if copy mode ("c" or "C") +is specified for the input file, the actual input file open is delayed +until just after the output file is opened, since the copy of prior +extensions to the output file takes place while Funtools is seeking to +the specified input extension. This implies that the output file +should be opened before any I/O is done on the input file or else the +copy will fail. Note also that the copy of subsequent extension will +be handled automatically by +FunClose() +if the output file is +closed before the input file. Alternatively, it can be done explicitly +by FunFlush(), but again, this +assumes that the input file still is open. + + +Upon success FunOpen() returns a +Fun handle that is used in subsequent Funtools calls. On error, NULL +is returned. + + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + +=cut diff --git a/doc/pod/funparamget.pod b/doc/pod/funparamget.pod new file mode 100644 index 0000000..6d06d10 --- /dev/null +++ b/doc/pod/funparamget.pod @@ -0,0 +1,153 @@ +=pod + +=head1 NAME + + + +B + + + +=head1 SYNOPSIS + + + + + + #include + + int FunParamGetb(Fun fun, char *name, int n, int defval, int *got) + + int FunParamGeti(Fun fun, char *name, int n, int defval, int *got) + + double FunParamGetd(Fun fun, char *name, int n, double defval, int *got) + + char *FunParamGets(Fun fun, char *name, int n, char *defval, int *got) + + + + + +=head1 DESCRIPTION + + + + +The four routines B, B, +B, and B, return the value of +a FITS header parameter as a boolean, int, double, and string, +respectively. The string returned by B is a malloc'ed +copy of the header value and should be freed when no longer needed. + + +The first argument is the Fun handle associated with the FITS header +being accessed. Normally, the header is associated with the FITS +extension that you opened with B. However, you can use +FunInfoPut() to specify access of the primary header. In particular, +if you set the FUN_PRIMARYHEADER parameter to 1, then the primary +header is used for all parameter access until the value is reset to +0. For example: + + int val; + FunParamGeti(fun, "NAXIS", 1, 0, &got); # current header + val=1; + FunInfoPut(fun, FUN_PRIMARYHEADER, &val, 0); # switch to ... + FunParamGeti(fun, "NAXIS", 1, 0, &got); # ... primary header + FunParamGeti(fun, "NAXIS", 2, 0, &got); # ... primary header + val=0; + FunInfoPut(fun, FUN_PRIMARYHEADER, &val, 0); # switch back to ... + FunParamGeti(fun, "NAXIS", 2, 0, &got); # current header + + + +Alternatively, you can use the FUN_PRIMARY macro to access parameters +from the primary header on a per-parameter basis: + + FunParamGeti(fun, "NAXIS1", 0, 0, &got); # current header + FunParamGeti(FUN_PRIMARY(fun), "NAXIS1", 0, 0, &got); # primary header + +B +It makes use of a global parameter and therefore will not not +appropriate for threaded applications, when we make funtools +thread-safe. We recommend use of FunInfoPut() to switch between the +extension header and the primary header. + + +For output data, access to the primary header is only possible until +the header is written out, which usually takes place when the first +data are written. + + +The second argument is the name of the parameter to access. The third +B argument, if non-zero, is an integer that will be added as a +suffix to the parameter name. This makes it easy to use a simple loop +to process parameters having the same root name. For example, to +gather up all values of TLMIN and TLMAX for each column in a binary +table, you can use: + + for(i=0, got=1; got; i++){ + fun->cols[i]->tlmin = (int)FunParamGeti(fun, "TLMIN", i+1, 0.0, &got); + fun->cols[i]->tlmax = (int)FunParamGeti(fun, "TLMAX", i+1, 0.0, &got); + } + + + +The fourth B argument is the default value to return if +the parameter does not exist. Note that the data type of this +parameter is different for each specific FunParamGet() call. The final +B argument will be 0 if no param was found. Otherwise the +data type of the parameter is returned as follows: FUN_PAR_UNKNOWN +('u'), FUN_PAR_COMMENT ('c'), FUN_PAR_LOGICAL ('l'), FUN_PAR_INTEGER +('i'), FUN_PAR_STRING ('s'), FUN_PAR_REAL ('r'), FUN_PAR_COMPLEX ('x'). + + +These routines return the value of the header parameter, or the +specified default value if the header parameter does not exist. The +returned value is a malloc'ed string and should be freed when no +longer needed. + + +By default, B returns the string value of the +named parameter. However, you can use FunInfoPut() to retrieve the +raw 80-character FITS card instead. In particular, if you set the +FUN_RAWPARAM parameter to 1, then card images will be returned by +FunParamGets() until the value is reset to 0. + + +Alternatively, if the FUN_RAW macro is applied to the name, then the +80-character raw FITS card is returned instead. +B +It makes use of a global parameter and therefore will not not +appropriate for threaded applications, when we make funtools +thread-safe. We recommend use of FunInfoPut() to switch between the +extension header and the primary header. + + +Note that in addition to the behaviors described above, the +routine B will return the 80 raw characters of the +B FITS card (including the comment) if B is specified as +NULL and B is positive. For example, to loop through all FITS +header cards in a given extension and print out the raw card, use: + + for(i=1; ;i++){ + if( (s = FunParamGets(fun, NULL, i, NULL, &got)) ){ + fprintf(stdout, "%.80s\n", s); + free(s); + } + else{ + break; + } + } + + + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + +=cut diff --git a/doc/pod/funparamput.pod b/doc/pod/funparamput.pod new file mode 100644 index 0000000..65d1b55 --- /dev/null +++ b/doc/pod/funparamput.pod @@ -0,0 +1,147 @@ +=pod + +=head1 NAME + + + +B + + + +=head1 SYNOPSIS + + + + + + #include + + int FunParamPutb(Fun fun, char *name, int n, int value, char *comm, + int append) + + int FunParamPuti(Fun fun, char *name, int n, int value, char *comm, + int append) + + int FunParamPutd(Fun fun, char *name, int n, double value, int prec, + char *comm, int append) + + int FunParamPuts(Fun fun, char *name, int n, char *value, char *comm, + int append) + + + + + +=head1 DESCRIPTION + + + + +The four routines B, B, +B, and B, will set the value +of a FITS header parameter as a boolean, int, double, and string, +respectively. + + +The first argument is the Fun handle associated with the FITS header +being accessed. Normally, the header is associated with the FITS +extension that you opened with B. +However, you can use FunInfoPut() to specify that use of the primary +header. In particular, if you set the FUN_PRIMARYHEADER parameter to +1, then the primary header is used for all parameter access until the +value is reset to 0. For example: + + int val; + FunParamPuti(fun, "NAXIS1", 0, 10, NULL, 1); # current header + val=1; + FunInfoPut(fun, FUN_PRIMARYHEADER, &val, 0); # switch to ... + FunParamPuti(fun, "NAXIS1", 0, 10, NULL, 1); # primary header + +(You also can use the deprecated FUN_PRIMARY macro, to access +parameters from the primary header.) + + +The second argument is the B of the parameter. ( +In accordance with FITS standards, the special names B +and B, as well as blank names, are output without the "= " +value indicator in columns 9 and 10. + + +The third B argument, if non-zero, is an integer that will be +added as a suffix to the parameter name. This makes it easy to use a +simple loop to process parameters having the same root name. For +example, to set the values of TLMIN and TLMAX for each column in a +binary table, you can use: + + for(i=0; i argument is the value to set. Note that the +data type of this argument is different for each specific +FunParamPut() call. The B argument is the comment +string to add to this header parameter. Its value can be NULL. The +final B argument determines whether the parameter is added +to the header if it does not exist. If set to a non-zero value, the +header parameter will be appended to the header if it does not exist. +If set to 0, the value will only be used to change an existing parameter. + + +Note that the double precision routine FunParamPutd() supports an +extra B argument after the B argument, in order +to specify the precision when converting the double value to ASCII. In +general a 20.[prec] format is used (since 20 characters are alloted to +a floating point number in FITS) as follows: if the double value being +put to the header is less than 0.1 or greater than or equal to +10**(20-2-[prec]), then %20.[prec]e format is used (i.e., scientific +notation); otherwise %20.[prec]f format is used (i.e., numeric +notation). + + +As a rule, parameters should be set before writing the table or image. +It is, however, possible to update the value of an B +parameter after writing an image or table (but not to add a new +one). Such updating only works if the parameter already exists and if +the output file is seekable, i.e. if it is a disk file or is stdout +being redirected to a disk file. + + +It is possible to add a new parameter to a header after the data has +been written, but only if space has previously been reserved. To reserve +space, add a blank parameter whose value is the name of the parameter you +eventually will update. Then, when writing the new parameter, specify a +value of 2 for the append flag. The parameter writing routine will +first look to update an existing parameter, as usual. If an existing +parameter is not found, an appropriately-valued blank parameter will be +searched for and replaced. For example: + + /* add blank card to be used as a place holder for IPAR1 update */ + FunParamPuts(fun, NULL, 0, "IPAR1", "INTEGER Param", 0); + ... + /* write header and data */ + FunTableRowPut(fun, events, got, 0, NULL); + ... + /* update param in file after writing data -- note append = 2 here */ + FunParamPuti(fun, "IPAR", 1, 400, "INTEGER Param", 2); + + + +The parameter routines return a 1 if the routine was successful and a 0 on +failure. In general, the major reason for failure is that you did not +set the append argument to a non-zero value and the parameter did not +already exist in the file. + + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + +=cut diff --git a/doc/pod/funref.pod b/doc/pod/funref.pod new file mode 100644 index 0000000..13b158f --- /dev/null +++ b/doc/pod/funref.pod @@ -0,0 +1,170 @@ +=pod + +=head1 NAME + + + +B + + + +=head1 SYNOPSIS + + + + +A description of how to use a Funtools reference handle to connect a +Funtools input file to an output file. + + + +=head1 DESCRIPTION + + + + + +The Funtools reference handle connects a Funtools input file to a +Funtools output file so that parameters (or even whole extensions) can +be copied from the one to the other. To make the connection, the Funtools +handle of the input file is passed to the +final argument of the +FunOpen() call for the output file: + + if( !(ifun = FunOpen(argv[1], "r", NULL)) ) + gerror(stderr, "could not FunOpen input file: %s\n", argv[1]); + if( !(ofun = FunOpen(argv[2], "w", ifun)) ) + gerror(stderr, "could not FunOpen output file: %s\n", argv[2]); + +It does not matter what type of input or output file (or extension) is +opened, or whether they are the same type. When the output image or +binary table is written using +FunImagePut() +or +FunTableRowPut() +an appropriate header will be written first, with parameters copied +from the input extension. Of course, invalid parameters will be +removed first, e.g., if the input is a binary table and the output is +an image, then binary table parameters such as TFORM, TUNIT, +etc. parameters will not be copied to the output. + + +Use of a reference handle also allows default values to be passed +to +FunImagePut() in order to +write out an output image with the same dimensions and data type +as the input image. To use the defaults from the input, a value +of 0 is entered for dim1, dim2, and bitpix. For example: + + fun = FunOpen(argv[1], "r", NULL); + fun2 = FunOpen(argv[2], "w", fun); + buf = FunImageGet(fun, NULL, NULL); + ... process image data ... + FunImagePut(fun2, buf, 0, 0, 0, NULL); + +Of course, you often want to get information about the data type +and dimensions of the image for processing. The above code +is equivalent to the following: + + fun = FunOpen(argv[1], "r", NULL); + fun2 = FunOpen(argv[2], "w", fun); + buf = FunImageGet(fun, NULL, NULL); + FunInfoGet(fun, FUN_SECT_DIM1, &dim1, FUN_SECT_DIM2, &dim2, + FUN_SECT_BITPIX, &bitpix, 0); + ... process image data ... + FunImagePut(fun2, buf, dim1, dim2, bitpix, NULL); + + + +It is possible to change the reference handle for a given output Funtools +handle using the +FunInfoPut() routine: + + /* make the new extension the reference handle for the output file */ + FunInfoPut(fun2, FUN_IFUN, &fun, 0); + +When this is done, Funtools specially resets the output file to start +a new output extension, which is connected to the new input reference +handle. You can use this mechanism to process multiple input extensions +into a single output file, by successively opening the former and +setting the reference handle for the latter. For example: + + /* open a new output FITS file */ + if( !(fun2 = FunOpen(argv[2], "w", NULL)) ) + gerror(stderr, "could not FunOpen output file: %s\n", argv[2]); + /* process each input extension in turn */ + for(ext=0; ;ext++){ + /* get new extension name */ + sprintf(tbuf, "%s[%d]", argv[1], ext); + /* open it -- if we cannot open it, we are done */ + if( !(fun=FunOpen(tbuf, "r", NULL)) ) + break; + /* make the new extension the reference handle for the output file */ + FunInfoPut(fun2, FUN_IFUN, &fun, 0); + ... process ... + /* flush output extension (write padding, etc.) */ + FunFlush(fun2, NULL); + /* close the input extension */ + FunClose(fun); + } + +In this example, the output file is opened first. Then each successive +input extension is opened, and the output reference handle is set to +the newly opened input handle. After data processing is performed, the +output extension is flushed and the input extension is closed, in +preparation for the next input extension. + +Finally, a reference handle can be used to copy other extensions from +the input file to the output file. Copy of other extensions is +controlled by adding a "C" or "c" to the mode string of the +FunOpen() +call B. If "C" is specified, then +other extensions are B copied (i.e., copy is forced by the +application). If "c" is used, then other extensions are copied if the +user requests copying by adding a plus sign "+" to the extension name +in the bracket specification. For example, the B +program utilizes user-specified "c" mode so that the second example +below will copy all extensions: + + # copy only the EVENTS extension + csh> funtable "test.ev[EVENTS,circle(512,512,10)]" foo.ev + # copy ALL extensions + csh> funtable "test.ev[EVENTS+,circle(512,512,10)]" foo.ev + +When extension copy is specified in the input file, the call to +FunOpen() +on the input file delays the actual file open until the output file +also is opened (or until I/O is performed on the input file, which +ever happens first). Then, when the output file is opened, the input +file is also opened and input extensions are copied to the output +file, up to the specific extension being opened. Processing of input +and output extensions then proceed. + +When extension processing is complete, the remaining extensions need to +be copied from input to output. This can be done explicitly, using the +FunFlush() +call with the "copy=remaining" plist: + + FunFlush(fun, "copy=remaining"); + +Alternatively, this will happen automatically, if the output file +is closed B the input file: + + /* we could explicitly flush remaining extensions that need copying */ + /* FunFlush(fun2, "copy=remaining"); */ + /* but if we close output before input, end flush is done automatically */ + FunClose(fun2); + FunClose(fun); + + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + + +=cut diff --git a/doc/pod/funregions.pod b/doc/pod/funregions.pod new file mode 100644 index 0000000..7f975ad --- /dev/null +++ b/doc/pod/funregions.pod @@ -0,0 +1,571 @@ +=pod + +=head1 NAME + + + +B + + + +=head1 SYNOPSIS + + + + + +This document contains a summary of the user interface for spatial +region filtering images and tables. + + + +=head1 DESCRIPTION + + + + + +Spatial region filtering allows a program to select regions of an +image or rows of a table (e.g., X-ray events) to process using +simple geometric shapes and boolean combinations of shapes. When an +image is filtered, only pixels found within these shapes are +processed. When a table is filtered, only rows found within these +shapes are processed. + + +Spatial region filtering for images and tables is accomplished by +means of B. A region specification +consists of one or more B, which are geometric +shapes,combined according to the rules of boolean algebra. Region +specifications also can contain comments and local/global processing +directives. + + +Typically, region specifications are specified using bracket notation +appended to the filename of the data being processed: + + foo.fits[circle(512,512,100)] + +It is also possible to put region specification inside a file and +then pass the filename in bracket notation: + + foo.fits[@my.reg] + + + +When region filters are passed in bracket notation in this manner, the +filtering is set up automatically when the file is opened and all +processing occurs through the filter. Programs also can use the filter +library API to open filters explicitly. + +B + +More specifically, region specifications consist of one or more lines +containing: + + # comment until end of line + global keyword=value keyword=value ... # set global value(s) + # include the following file in the region descriptor + @file + # use the FITS image as a mask (cannot be used with other regions) + @fitsimage + # each region expression contains shapes separated by operators + [region_expression1], [region_expression2], ... + [region_expression], [region_expression], ... + + + +A single region expression consists of: + + # parens and commas are optional, as is the + sign + [+-]shape(num , num , ...) OP1 shape num num num OP2 shape ... + +e.g.: + + ([+-]shape(num , num , ...) && shape num num || shape(num, num) + # a comment can come after a region -- reserved for local properties + [+-]shape(num , num , ...) # local properties go here, e.g. color=red + + + +Thus, a region descriptor consists of one or more region +expressions or B, separated by comas, new-lines, or +semi-colons. Each B consists of one or more geometric +shapes combined using standard boolean operation. Several types +of shapes are supported, including: + + + shape: arguments: + ----- ---------------------------------------- + ANNULUS xcenter ycenter inner_radius outer_radius + BOX xcenter ycenter xwidth yheight (angle) + CIRCLE xcenter ycenter radius + ELLIPSE xcenter ycenter xwidth yheight (angle) + FIELD none + LINE x1 y1 x2 y2 + PIE xcenter ycenter angle1 angle2 + POINT x1 y1 + POLYGON x1 y1 x2 y2 ... xn yn + + + +In addition, the following regions accept B syntax: + + + shape arguments + ----- ------------------------------------------ + ANNULUS xcenter ycenter radius1 radius2 ... radiusn + ANNULUS xcenter ycenter inner_radius outer_radius n=[number] + BOX xcenter ycenter xw1 yh1 xw2 yh2 ... xwn yhn (angle) + BOX xcenter ycenter xwlo yhlo xwhi yhhi n=[number] (angle) + CIRCLE xcenter ycenter r1 r2 ... rn # same as annulus + CIRCLE xcenter ycenter rinner router n=[number] # same as annulus + ELLIPSE xcenter ycenter xw1 yh1 xw2 yh2 ... xwn yhn (angle) + ELLIPSE xcenter ycenter xwlo yhlo xwhi yhhi n=[number] (angle) + PIE xcenter ycenter angle1 angle2 (angle3) (angle4) (angle5) ... + PIE xcenter ycenter angle1 angle2 (n=[number]) + POINT x1 y1 x2 y2 ... xn yn + +Note that the circle accelerators are simply aliases for the annulus +accelerators. See region geometry +for more information about accelerators. + + +Finally, the following are combinations of pie with different shapes +(called "panda" for "Pie AND Annulus") allow for easy specification of +radial sections: + + + shape: arguments: + ----- --------- + PANDA xcen ycen ang1 ang2 nang irad orad nrad # circular + CPANDA xcen ycen ang1 ang2 nang irad orad nrad # circular + BPANDA xcen ycen ang1 ang2 nang xwlo yhlo xwhi yhhi nrad (ang) # box + EPANDA xcen ycen ang1 ang2 nang xwlo yhlo xwhi yhhi nrad (ang) # ellipse + + +The panda and cpanda specify combinations of annulus and circle with pie, +respectively and give identical results. The bpanda combines box and pie, +while epanda combines ellipse and pie. +See region geometry +for more information about pandas. + + +The following "shapes" are ignored by funtools (generated by ds9): + + shape: arguments: + ----- --------- + PROJECTION x1 y1 x2 y2 width # NB: ignored by funtools + RULER x1 y1 x2 y2 # NB: ignored by funtools + TEXT x y # NB: ignored by funtools + GRID # NB: ignored by funtools + TILE # NB: ignored by funtools + COMPASS # NB: ignored by funtools + + + +All arguments to regions are real values; integer values are +automatically converted to real where necessary. All angles are in +degrees and run from the positive image x-axis to the positive image +y-axis. If a rotation angle is part of the associated WCS header, that +angle is added implicitly as well. + + +Note that 3-letter abbreviations are supported for all shapes, so that +you can specify "circle" or "cir". + + +B + +By default, the x,y values in a region expression refer to the two +"image binning" columns, i.e. the columns that would be used to +bin the data into an image. For images, these are just the 2 dimensions +of the image. For tables, these usually default to x and y but +can be changed as required. For example, in Funtools, new binning +columns are specified using a bincols=(col1,col2) statement within +the bracket string on the command line. + +Alternate columns for region filtering can be specified by the syntax: + + (col1,col2)=region(...) + +e.g.: + + (X,Y)=annulus(x,y,ri,ro) + (PHA,PI)=circle(x,y,r) + (DX,DY)=ellipse(x,y,a,b[,angle]) + + + +B + +(See also Region Algebra for more complete +information.) + + +Region shapes can be combined together using Boolean operators: + + Symbol Operation Use + -------- --------- ----------------------------------- + ! not Exclude this shape from this region + & or && and Include only the overlap of these shapes + | or || inclusive or Include all of both shapes + ^ exclusive or Include both shapes except their overlap + +Note that the !region syntax must be combined with another region in order +that we be able to assign a region id properly. That is, + + !circle(512,512,10) + +is not a legal region because there is no valid region id to work with. +To get the full field without a circle, combine the above with field(), +as in: + + field() && !circle(512,512,10) + + +B< Region Separators Also Are Operators> + + +As mentioned previously, multiple region expressions can be specified +in a region descriptor, separated by commas, new-lines, or +semi-colons. When such a separator is used, the boolean OR operator +is automatically generated in its place but, unlike explicit use of +the OR operator, the region ID is incremented (starting from 1). + + +For example, the two shapes specified in this example are given the +same region value: + + foo.fits[circle(512,512,10)||circle(400,400,20)] + +On the other hand, the two shapes defined in the following example are +given different region values: + + foo.fits[circle(512,512,10),circle(400,400,20)] + + + +Of course these two examples will both mask the same table rows or +pixels. However, in programs that distinguish region id's (such as +funcnts ), they will act +differently. The explicit OR operator will result in one region +expression consisting of two shapes having the same region id and +funcnts will report a single region. The comma operator will cause +funcnts to report two region expressions, each with one shape, in +its output. + + +In general, commas are used to separate region expressions entered +in bracket notation on the command line: + + # regions are added to the filename in bracket notation + foo.fits[circle(512,512,100),circle(400,400,20)] + +New-lines are used to separate region +expressions in a file: + + # regions usually are separated by new-lines in a file + # use @filename to include this file on the command line + circle(512,512,100) + circle(400,400,20) + +Semi-colons are provided for backward compatibility with the original +IRAF/PROS implementation and can be used in either case. + + +If a pixel is covered by two different regions expressions, it is +given the mask value of the B region that contains that +pixel. That is, successive regions B overwrite previous +regions in the mask, as was the case with the original PROS regions. +In this way, an individual pixel is covered by one and only one +region. This means that one must sometimes be careful about the order +in which regions are defined. If region N is fully contained within +region M, then N should be defined B M, or else it will be +"covered up" by the latter. + +B + +Shapes also can be globally excluded from all the region specifiers in +a region descriptor by using a minus sign before a region: + + + operator arguments: + -------- ----------- + - Globally exclude the region expression following '-' sign + from ALL regions specified in this file + +The global exclude region can be used by itself; in such a case, field() is +implied. + + +A global exclude differs from the local exclude (i.e. a shape prefixed +by the logical not "!" symbol) in that global excludes are logically +performed last, so that no region will contain pixels from a globally +excluded shape. A local exclude is used in a boolean expression with +an include shape, and only excludes pixels from that include shape. +Global excludes cannot be used in boolean expressions. + +B + + +The B<@filename> directive specifies an include file +containing region expressions. This file is processed as part of +the overall region descriptor: + + foo.fits[circle(512,512,10),@foo] + +A filter include file simply includes text without changing the state +of the filter. It therefore can be used in expression. That is, if the +file foo1 contains "pi==1" and foo2 contains "pha==2" then +the following expressions are equivalent: + + "[@foo1&&@foo2]" is equivalent to "[pi==1&&pha==2]" + "[pha==1||@foo2]" is equivalent to "[pi==1||pha==2]" + "[@foo1,@foo2]" is equivalent to "[pi==1,pha==2]" + +Be careful that you specify evaluation order properly using +parenthesis, especially if the include file contains multiple +filter statements. For example, consider a file containing two +regions such as: + + circle 512 512 10 + circle 520 520 10 + +If you want to include only events (or pixels) that are in these regions +and have a pi value of 4, then the correct syntax is: + + pi==4&&(@foo) + +since this is equivalent to: + + pi==4 && (circle 512 512 10 || circle 520 520 10) + +If you leave out the parenthesis, you are filtering this statement: + + pi==4 && circle 512 512 10 || circle 520 520 10) + +which is equivalent to: + + (pi==4 && circle 512 512 10) || circle 520 520 10) + +The latter syntax only applies the pi test to the first region. + + +For image-style filtering, the B<@filename> can specify an 8-bit +or 16-bit FITS image. In this case, the pixel values in the mask image +are used as the region mask. The valid pixels in the mask must have +positive values. Zero values are excluded from the mask and negative +values are not allowed. Moreover, the region id value is taken as +the image pixel value and the total number of regions is taken to be +the highest pixel value. The dimensions of the image mask must be less +than or equal to the image dimensions of the data. The mask will be +replicated as needed to match the size of the image. (Thus, best +results are obtained when the data dimensions are an even multiple of +the mask dimensions.) + + +An image mask can be used in any image filtering operation, regardless +of whether the data is of type image or table. For example, the +funcnts ) +program performs image filtering on images or tables, and so +FITS image masks are valid input for either type of data in this +program.. An image mask cannot be used in a program such as +fundisp ) +when the input data is a table, because fundisp displays +rows of a table and processes these rows using event-style filtering. + +B + + +The ds9 image display program describes a host of properties such as +color, font, fix/free state, etc. Such properties can be specified +globally (for all regions) or locally (for an individual region). +The B keyword specifies properties and qualifiers for all +regions, while local properties are specified in comments on the same +line as the region: + + global color=red + circle(10,10,2) + circle(20,20,3) # color=blue + circle(30,30,4) + +The first and third circles will be red, which the second circle will +be blue. Note that funtools currently ignores region properties, as +they are used in display only. + +B< Coordinate Systems> + +For each region, it is important to specify the coordinate system +used to interpret the region, i.e., to set the context in which position and +size values are interpreted. For this purpose, the following keywords +are recognized: + + + name description + ---- ------------------------------------------ + PHYSICAL pixel coords of original file using LTM/LTV + IMAGE pixel coords of current file + FK4, B1950 sky coordinate systems + FK5, J2000 sky coordinate systems + GALACTIC sky coordinate systems + ECLIPTIC sky coordinate systems + ICRS currently same as J2000 + LINEAR linear wcs as defined in file + AMPLIFIER mosaic coords of original file using ATM/ATV + DETECTOR mosaic coords of original file using DTM/DTV + + + +B + +The arguments to region shapes can be floats or integers describing +positions and sizes. They can be specified as pure numbers or using +explicit formatting directives: + + + position arguments description + ------------------ ------------------------------ + [num] context-dependent (see below) + [num]d degrees + [num]r radians + [num]p physical pixels + [num]i image pixels + [num]:[num]:[num] hms for 'odd' position arguments + [num]:[num]:[num] dms for 'even' position arguments + [num]h[num]m[num]s explicit hms + [num]d[num]m[num]s explicit dms + + size arguments description + -------------- ----------- + [num] context-dependent (see below) + [num]" arc seconds + [num]' arc minutes + [num]d degrees + [num]r radians + [num]p physical pixels + [num]i image pixels + + + +When a "pure number" (i.e. one without a format directive such as 'd' +for 'degrees') is specified, its interpretation depends on the context +defined by the 'coordsys' keyword. In general, the rule is: + + +All pure numbers have implied units corresponding to the current +coordinate system. + + +If no such system is explicitly specified, the default system is +implicitly assumed to be PHYSICAL. + + +In practice this means that for IMAGE and PHYSICAL systems, pure +numbers are pixels. Otherwise, for all systems other than linear, +pure numbers are degrees. For LINEAR systems, pure numbers are in the +units of the linear system. This rule covers both positions and +sizes. + + +The input values to each shape can be specified in several coordinate +systems including: + + + name description + ---- ---------------------------- + IMAGE pixel coords of current file + LINEAR linear wcs as defined in file + FK4, B1950 various sky coordinate systems + FK5, J2000 + GALACTIC + ECLIPTIC + ICRS + PHYSICAL pixel coords of original file using LTM/LTV + AMPLIFIER mosaic coords of original file using ATM/ATV + DETECTOR mosaic coords of original file using DTM/DTV + + + +If no coordinate system is specified, PHYSICAL is assumed. PHYSICAL or +a World Coordinate System such as J2000 is preferred and most general. +The coordinate system specifier should appear at the beginning of the +region description, on a separate line (in a file), or followed by a +new-line or semicolon; e.g., + + + global coordsys physical + circle 6500 9320 200 + + +The use of celestial input units automatically implies WORLD +coordinates of the reference image. Thus, if the world coordinate +system of the reference image is J2000, then + + + circle 10:10:0 20:22:0 3' + + +is equivalent to: + + + circle 10:10:0 20:22:0 3' # j2000 + + + +Note that by using units as described above, you may mix coordinate +systems within a region specifier; e.g., + + + circle 6500 9320 3' # physical + + + +Note that, for regions which accept a rotation angle: + + +ellipse (x, y, r1, r2, angle) +box(x, y, w, h, angle) + + +the angle is relative to the specified coordinate system. In +particular, if the region is specified in WCS coordinates, the angle +is related to the WCS system, not x/y image coordinate axis. For WCS +systems with no rotation, this obviously is not an issue. However, +some images do define an implicit rotation (e.g., by using a non-zero +CROTA value in the WCS parameters) and for these images, the angle +will be relative to the WCS axes. In such case, a region specification +such as: + + +fk4;ellipse(22:59:43.985, +58:45:26.92,320", 160", 30) + + +will not, in general, be the same region specified as: + + +physical;ellipse(465, 578, 40, 20, 30) + + +even when positions and sizes match. The angle is relative to WCS axes +in the first case, and relative to physical x,y axes in the second. + + + +More detailed descriptions are available for: +Region Geometry, +Region Algebra, +Region Coordinates, and +Region Boundaries. + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + + +=cut diff --git a/doc/pod/funsky.pod b/doc/pod/funsky.pod new file mode 100644 index 0000000..421d5d7 --- /dev/null +++ b/doc/pod/funsky.pod @@ -0,0 +1,260 @@ +=pod + +=head1 NAME + + + +B + + + +=head1 SYNOPSIS + + + + + + funsky iname[ext] # RA,Dec (deg) or image pix from stdin + funsky iname[ext] [lname] # RA, Dec (deg) or image pix from list + funsky iname[ext] [col1] [col2] # named cols:units from stdin + funsky iname[ext] [lname] [col1] [col2] # named cols:units from list + + + + + +=head1 OPTIONS + + + + + + -d # always use integer tlmin conversion (as ds9 does) + -r # convert x,y to RA,Dec (default: convert RA,Dec to x,y) + -o # include offset from the nominal target position (in arcsec) + -v # display input values also (default: display output only) + -T # output display in rdb format (w/header,tab delimiters) + + + + +=head1 DESCRIPTION + + + + +Funsky converts input sky coordinates (RA, Dec) to image coordinates (or vice +versa) using the WCS information contained in the specified FITS file. Several +calling sequences are supported in order to make it easy to specify +coordinate positions in different ways. + + +The first required argument is always the input FITS file (or +extension) containing the WCS information in an extension header. Note +that the data from this file is not used. By default, the program +converts input RA and Dec values to X and Y using this WCS +information. If the WCS is associated with a FITS image, then the X,Y +values are image values. If the WCS is associated with a binary table, +then the X, Y values are physical values. To convert X,Y to RA and +Dec, use the B<-r> (reverse) switch. + + +If no other command arguments are supplied, then the input positions +are read from the standard input. Each line is assumed to contain a +single coordinate position consisting of an RA in degrees (or X in +pixels) followed by a Dec in degrees (or Y in pixels). The usual +delimiters are supported (spaces, commas, tabs). For example: + + # read from stdin, default column names and units + [sh] funsky snr.ev + 22.982695 58.606523 # input RA (hrs), Dec(deg) + 510.00 510.00 + 22.982127 58.607634 # input + 512.00 510.50 + 22.981700 58.614301 # input + 513.50 513.50 + ^D # end of input + + + +If a second argument is supplied, this argument is assumed to be +a file containing RA (X) and Dec (Y) positions. The file can either be +an ASCII table or a FITS binary table. The order of columns is +unimportant, if the table has a column header. In this case, the +names of the columns must be one of "RA", "DEC", or "X", "Y" for sky +to image and image to sky conversions, respectively. If the table has +no header, then once again, RA (X) is assumed to first, followed +by DEC (Y). +For example: + + # read from file, default column names and units + [sh] cat hd.in + RA DEC + --------- --------- + 22.982695 58.606523 + 22.982127 58.607634 + 22.981700 58.614301 + + [sh] funsky snr.ev hd.in + 510.00 510.00 + 512.00 510.50 + 513.50 513.50 + + + +If three arguments are supplied, then the input positions again are +read from the standard input. Each line is assumed to contain a single +coordinate position consisting of an RA (or X in pixels) followed by a +Dec (or Y in pixels), with the usual delimiters supported. However, +the second and third arguments now specify the column names and/or +sky units using a colon-delimited syntax: + + [colname]:[h|d|r] + +If the colname is omitted, the names default to "RA", "DEC", "X", "Y", +"COL1", or "COL2" as above. If the units are omitted, the default is degrees +for both RA and Dec. When the -r switch is used (convert from image +to sky) the units are applied to the output instead of the input. The following +examples will serve to illustrate the options: + + # read from stdin, specifying column names (def. units: degrees) + [sh] cat hd.in + MYRA MYDEC + --------- --------- + 22.982695 58.606523 + 22.982127 58.607634 + 22.981700 58.614301 + + [sh] funsky snr.ev MYRA MYDEC < hd.in + 510.00 510.00 + 512.00 510.50 + 513.50 513.50 + + # read from stdin, specifying column names and units + [sh] cat dd.in + MYRA MYDEC + --------- --------- + 344.740432 58.606523 + 344.731900 58.607634 + 344.725500 58.614301 + + [sh] funsky snr.ev MYRA:d MYDEC:d < dd.in + 510.00 510.00 + 512.00 510.50 + 513.50 513.50 + + # read stdin, convert image to sky, specifying output sky units + [sh] cat im.in + 510.00 510.00 + 512.00 510.50 + 513.50 513.50 + + [sh] cat im.in | funsky -r snr.ev :d :d + 344.740432 58.606523 + 344.731900 58.607634 + 344.725500 58.614301 + + + +Finally, four command arguments specify both and input file and column names +and/or units: + + [sh] cat dd.in + MYRA MYDEC + --------- --------- + 344.740432 58.606523 + 344.731900 58.607634 + 344.725500 58.614301 + + [sh] funsky snr.ev dd.in MYRA:d MYDEC:d + 510.00 510.00 + 512.00 510.50 + 513.50 513.50 + + # read file, convert image to sky, specifying output sky units + [sh] cat im.in + 510.00 510.00 + 512.00 510.50 + 513.50 513.50 + + [sh] funsky -r snr.ev im.in :d :d + 344.740432 58.606523 + 344.731900 58.607634 + 344.725500 58.614301 + + + +By default, the output of funsky consists only of the converted coordinate +position(s), one per output line. This makes parsing in shell scripts easy. +Use the B<-v> (verbose) switch to specify that the input +coordinates should be pre-pended to each line. For example: + + [sh] cat dd.in + MYRA MYDEC + --------- --------- + 344.740432 58.606523 + 344.731900 58.607634 + 344.725500 58.614301 + + [sh] funsky snr.ev dd.in MYRA:d MYDEC:d + 510.00 510.00 + 512.00 510.50 + 513.50 513.50 + + [sh] funsky -v snr.ev dd.in MYRA:d MYDEC:d + 344.740432 58.606523 510.00 510.00 + 344.731900 58.607634 512.00 510.50 + 344.725500 58.614301 513.50 513.50 + + + +In addition, a full starbase table can be output using the B<-T> +(table) switch. This switch can be used with or without the -v +switch. If the -T and -v are both specified, then a descriptive header +parameters are output before the table (mainly to remind you of the +sky units): + + # output table in non-verbose mode + [sh] funsky -T snr.ev dd.in MYRA:d MYDEC:d + X Y + ------------ ------------ + 510.00 510.00 + 512.00 510.50 + 513.50 513.50 + + # output table in verbose mode + [sh] funsky -T -v snr.ev dd.in MYRA:d MYDEC:d + # IFILE = /Users/eric/data/snr.ev + # ICOL1 = MYRA + # ICOL2 = MYDEC + # IUNITS1 = d + # IUNITS2 = d + # OCOL1 = X + # OCOL2 = Y + + MYRA MYDEC X Y + ------------ ------------ ------------ ------------ + 344.740432 58.606523 510.00 510.00 + 344.731900 58.607634 512.00 510.50 + 344.725500 58.614301 513.50 513.50 + + + +Finally, the B<-d> (ds9) switch mimicks ds9's use of integer TLMIN +and TLMAX values for all coordinate transformations. FITS conventions +seem to call for use of floating point TLMIN and TLMAX when the data are +floats. This convention is followed by funsky but results in a +small discrepancy with ds9's converted values for floating point +data. We will remedy this conflict in the future, maybe. + + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + +=cut diff --git a/doc/pod/funtable.pod b/doc/pod/funtable.pod new file mode 100644 index 0000000..d4e8475 --- /dev/null +++ b/doc/pod/funtable.pod @@ -0,0 +1,296 @@ +=pod + +=head1 NAME + + + +B + + + +=head1 SYNOPSIS + + + + + +funtable [-a] [-i|-z] [-m] [-s cols] [columns] + + + + + +=head1 OPTIONS + + + + + + -a # append to existing output file as a table extension + -i # for image data, only generate X and Y columns + -m # for tables, write a separate file for each region + -s "col1 ..." # columns on which to sort + -z # for image data, output zero-valued pixels + + + + +=head1 DESCRIPTION + + + + +B selects rows from the specified +FITS Extension +(binary table only) of a FITS file, or from a non-FITS raw event +file, and writes those rows to a FITS binary table file. It also +will create a FITS binary table from an image or a raw array file. + + +The first argument to the program specifies the FITS file, raw event +file, or raw array file. If "stdin" is specified, data are read from +the standard input. Use Funtools Bracket +Notation to specify FITS extensions, and filters. The second +argument is the output FITS file. If "stdout" is specified, the FITS +binary table is written to the standard output. By default, all +columns of the input file are copied to the output file. Selected +columns can be output using an optional third argument in the form: + + "column1 column1 ... columnN" + + + +The B program generally is used to select rows from a +FITS binary table using +Table Filters +and/or +Spatial Region Filters. +For example, you can copy only selected rows (and output only selected +columns) by executing in a command such as: + + [sh] funtable "test.ev[pha==1&&pi==10]" stdout "x y pi pha" | fundisp stdin + X Y PHA PI + ------- ------- ------- --------- + 1 10 1 10 + 1 10 1 10 + 1 10 1 10 + 1 10 1 10 + 1 10 1 10 + 1 10 1 10 + 1 10 1 10 + 1 10 1 10 + 1 10 1 10 + 1 10 1 10 + + +The special column B<$REGION> can be specified to write the +region id of each row: + + [sh $] funtable "test.ev[time-(int)time>=.99&&annulus(0 0 0 10 n=3)]" stdout 'x y time $REGION' | fundisp stdin + X Y TIME REGION + -------- -------- --------------------- ---------- + 5 -6 40.99000000 3 + 4 -5 59.99000000 2 + -1 0 154.99000000 1 + -2 1 168.99000000 1 + -3 2 183.99000000 2 + -4 3 199.99000000 2 + -5 4 216.99000000 2 + -6 5 234.99000000 3 + -7 6 253.99000000 3 + + +Here only rows with the proper fractional time and whose position also is +within one of the three annuli are written. + +Columns can be excluded from display using a minus sign before the +column: + + [sh $] funtable "test.ev[time-(int)time>=.99]" stdout "-time" | fundisp stdin + X Y PHA PI DX DY + -------- -------- -------- ---------- ----------- ----------- + 5 -6 5 -6 5.50 -6.50 + 4 -5 4 -5 4.50 -5.50 + -1 0 -1 0 -1.50 0.50 + -2 1 -2 1 -2.50 1.50 + -3 2 -3 2 -3.50 2.50 + -4 3 -4 3 -4.50 3.50 + -5 4 -5 4 -5.50 4.50 + -6 5 -6 5 -6.50 5.50 + -7 6 -7 6 -7.50 6.50 + +All columns except the time column are written. + +In general, the rules for activating and de-activating columns are: + + +=over 4 + + + + +=item * + +If only exclude columns are specified, then all columns but +the exclude columns will be activated. + + +=item * + +If only include columns are specified, then only the specified columns +are activated. + + +=item * + +If a mixture of include and exclude columns are specified, then +all but the exclude columns will be active; this last case +is ambiguous and the rule is arbitrary. + + +=back + + +In addition to specifying columns names explicitly, the special +symbols I<+> and I<-> can be used to activate and +de-activate I columns. This is useful if you want to +activate the $REGION column along with all other columns. According +to the rules, the syntax "$REGION" only activates the region column +and de-activates the rest. Use "+ $REGION" to activate all +columns as well as the region column. + + +Ordinarily, only the selected table is copied to the output file. In +a FITS binary table, it sometimes is desirable to copy all of the +other FITS extensions to the output file as well. This can be done by +appending a '+' sign to the name of the extension in the input file +name. For example, the first command below copies only the EVENT table, +while the second command copies other extensions as well: + + [sh] funtable "/proj/rd/data/snr.ev[EVENTS]" events.ev + [sh] funtable "/proj/rd/data/snr.ev[EVENTS+]" eventsandmore.ev + + + +If the input file is an image or a raw array file, then +B will generate a FITS binary table from the pixel +values in the image. Note that it is not possible to specify the +columns to output (using command-line argument 3). Instead, there are +two ways to create such a binary table from an image. By default, a +3-column table is generated, where the columns are "X", "Y", and +"VALUE". For each pixel in the image, a single row (event) is +generated with the "X" and "Y" columns assigned the dim1 and dim2 +values of the image pixel, respectively and the "VALUE" column +assigned the value of the pixel. With sort of table, running +B on the "VALUE" column will give the same results as +running B on the original image. + + +If the B<-i> ("individual" rows) switch is specified, then only +the "X" and "Y" columns are generated. In this case, each positive +pixel value in the image generates n rows (events), where n is equal +to the integerized value of that pixel (plus 0.5, for floating point +data). In effect, B<-i> approximately recreates the rows of a +table that would have been binned into the input image. (Of course, +this is only approximately correct, since the resulting x,y positions +are integerized.) + + +If the B<-s [col1 col2 ... coln]> ("sort") switch is specified, +the output rows of a binary table will be sorted using the +specified columns as sort keys. The sort keys must be scalar columns +and also must be part of the output file (i.e. you cannot sort on a +column but not include it in the output). This facility uses the +B<_sort> program (included with funtools), which must be accessible +via your path. + + +For binary tables, the B<-m> ("multiple files") switch will +generate a separate file for each region in the filter specification +i.e. each file contains only the rows from that region. Rows +which pass the filter but are not in any region also are put in a +separate file. + + +The separate output file names generated by the B<-m> switch are +produced automatically from the root output file to contain the region id of +the associated region. (Note that region ids start at 1, so that the +file name associated with id 0 contains rows that pass the filter but +are not in any given region.) Output file names are generated as follows: + + + +=over 4 + + + + +=item * + +A $n specification can be used anywhere in the root file name (suitably +quoted to protect it from the shell) and will be expanded to be the id +number of the associated region. For example: + + funtable -m input.fits'[cir(512,512,1);cir(520,520,1)...]' 'foo.goo_$n.fits' + +will generate files named foo.goo_0.fits (for rows not in any region but +still passing the filter), foo.goo_1.fits (rows in region id #1, the first +region), foo.goo_2.fits (rows in region id #2), etc. Note that single quotes +in the output root are required to protect the '$' from the shell. + + + +=item * + +If $n is not specified, then the region id will be placed before +the first dot (.) in the filename. Thus: + + funtable -m input.fits'[cir(512,512,1);cir(520,520,1)...]' foo.evt.fits + +will generate files named foo0.evt.fits (for rows not in any region but +still passing the filter), foo1.evt.fits (rows in region id #1), +foo2.evt.fits (rows in region id #2), etc. + + + +=item * + +If no dot is specified in the root output file name, then +the region id will be appended to the filename. Thus: + + funtable -m input.fits'[cir(512,512,1);cir(520,520,1)...]' 'foo_evt' + +will generate files named foo_evt0 (for rows not in any region but +still passing the filter), foo_evt1 (rows in region id #1), +foo_evt2 (rows in region id #2), etc. + + +=back + + +The multiple file mechanism provide a simple way to generate +individual source data files with a single pass through the data. + + +By default, a new FITS file is created and the binary table is written +to the first extension. If the B<-a> (append) switch is specified, +the table is appended to an existing FITS file as a BINTABLE extension. +Note that the output FITS file must already exist. + + +If the B<-z> ("zero" pixel values) switch is specified and +B<-i> is not specified, then pixels having a zero value will +be output with their "VALUE" column set to zero. Obviously, this +switch does not make sense when individual events are output. + + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + +=cut diff --git a/doc/pod/funtablerowget.pod b/doc/pod/funtablerowget.pod new file mode 100644 index 0000000..86c1e66 --- /dev/null +++ b/doc/pod/funtablerowget.pod @@ -0,0 +1,111 @@ +=pod + +=head1 NAME + + + +B + + + +=head1 SYNOPSIS + + + + + + #include + + void *FunTableRowGet(Fun fun, void *rows, int maxrow, char *plist, + int *nrow) + + + + + +=head1 DESCRIPTION + + + + +The B routine retrieves rows from a Funtools +binary table or raw event file, and places the values of columns +selected by FunColumnSelect() +into an array of user structs. Selected column values are +automatically converted to the specified user data type (and to native +data format) as necessary. + + +The first argument is the Fun handle associated with this row data. +The second B argument is the array of user structs into +which the selected columns will be stored. If NULL is passed, the +routine will automatically allocate space for this array. (This +includes proper allocation of pointers within each struct, if the "@" +pointer type is used in the selection of columns. Note that if you +pass NULL in the second argument, you should free this space using the +standard free() system call when you are finished with the array of +rows.) The third B argument specifies the maximum number +of rows to be returned. Thus, if B is allocated by the +user, it should be at least of size maxrow*sizeof(evstruct). + + +The fourth B argument is a param list string. Currently, +the keyword/value pair "mask=transparent" is supported in the plist +argument. If this string is passed in the call's plist argument, then +all rows are passed back to the user (instead of just rows passing +the filter). This is only useful when +FunColumnSelect() also is +used to specify "$region" as a column to return for each row. In +such a case, rows found within a region have a returned region value +greater than 0 (corresponding to the region id of the region in which +they are located), rows passing the filter but not in a region have +region value of -1, and rows not passing any filter have region +value of 0. Thus, using "mask=transparent" and the returned region +value, a program can process all rows and decide on an action based +on whether a given row passed the filter or not. + + +The final argument is a pointer to an int variable that will return +the actual number of rows returned. The routine returns a pointer to +the array of stored rows, or NULL if there was an error. (This pointer +will be the same as the second argument, if the latter is non-NULL). + + /* get rows -- let routine allocate the row array */ + while( (buf = (Ev)FunTableRowGet(fun, NULL, MAXROW, NULL, &got)) ){ + /* process all rows */ + for(i=0; ienergy = (ev->pi+ev->pha)/2.0; + ev->pha = -ev->pha; + ev->pi = -ev->pi; + } + /* write out this batch of rows */ + FunTableRowPut(fun2, buf, got, 0, NULL); + /* free row data */ + if( buf ) free(buf); + } + +As shown above, successive calls to +FunTableRowGet() will return the +next set of rows from the input file until all rows have been read, +i.e., the routine behaves like sequential Unix I/O calls such as +fread(). See evmerge example code for a +more complete example. + + +Note that FunTableRowGet() also can be called as FunEventsGet(), for +backward compatibility. + + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + +=cut diff --git a/doc/pod/funtablerowput.pod b/doc/pod/funtablerowput.pod new file mode 100644 index 0000000..b063e43 --- /dev/null +++ b/doc/pod/funtablerowput.pod @@ -0,0 +1,200 @@ +=pod + +=head1 NAME + + + +B + + + +=head1 SYNOPSIS + + + + + +int FunTableRowPut(Fun fun, void *rows, int nev, int idx, char *plist) + + + + + +=head1 DESCRIPTION + + + +The B routine writes rows to a FITS binary +table, taking its input from an array of user structs that contain +column values selected by a previous call to +FunColumnSelect(). Selected +column values are automatically converted from native data format to +FITS data format as necessary. + + +The first argument is the Fun handle associated with this row data. +The second B argument is the array of user structs to +output. The third B argument specifies the number number of +rows to write. The routine will write B records, starting +from the location specified by B. + + +The fourth B argument is the index of the first raw input +row to write, in the case where rows from the user buffer are +being merged with their raw input row counterparts (see below). Note +that this B value is has nothing to do with the +row buffer specified in argument 1. It merely matches the row +being written with its corresponding (hidden) raw row. Thus, if you +read a number of rows, process them, and then write them out all at +once starting from the first user row, the value of B +should be 0: + + Ev ebuf, ev; + /* get rows -- let routine allocate the row array */ + while( (ebuf = (Ev)FunTableRowGet(fun, NULL, MAXROW, NULL, &got)) ){ + /* process all rows */ + for(i=0; i to the value of i: + + Ev ebuf, ev; + /* get rows -- let routine allocate the row array */ + while( (ebuf = (Ev)FunTableRowGet(fun, NULL, MAXROW, NULL, &got)) ){ + /* process all rows */ + for(i=0; i, then the entire corresponding +raw input row record will be merged with the output row according +to the B specification (see +FunColumnSelect() above). + + +A call to write rows can either be done once, after all rows in +the input batch have been processed, or it can be done (slightly less +efficiently) one row at a time (or anything in between). We do +recommend that you write all rows associated with a given batch of +input rows before reading new rows. This is B if +you are merging the output rows with the raw input rows (since +the raw rows are destroyed with each successive call to get new rows). + +For example: + + Ev buf, ev; + ... + /* get rows -- let routine allocate the row array */ + while( (buf = (Ev)FunTableRowGet(fun, NULL, MAXROW, NULL, &got)) ){ + /* point to the i'th row */ + ev = buf + i; + .... process + } + /* write out this batch of rows */ + FunTableRowPut(fun2, buf, got, 0, NULL); + /* free row data */ + if( buf ) free(buf); + } + + +or + + + Ev buf, ev; + ... + /* get rows -- let routine allocate the row array */ + while( (buf = (Ev)FunTableRowGet(fun, NULL, MAXROW, NULL, &got)) ){ + /* process all rows */ + for(i=0; i rows all at once and therefore passes +B in argument four, so that merging starts at the first raw +input row. In the second case, a check it made on each row to see +if it needs to be output. If so, the value of B is passed as +the value of the B
variable which points to the current row +being processed in the batch of input rows. + + +As shown above, successive calls to +FunTableRowPut() will write +rows sequentially. When you are finished writing all rows in a +table, you should call +FunFlush() to write out the FITS +binary table padding. However, this is not necessary if you +subsequently call FunClose() without doing any other I/O to the FITS +file. + + +Note that FunTableRowPut() also can be called as FunEventsPut(), for +backward compatibility. + + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + +=cut diff --git a/doc/pod/funtbl.pod b/doc/pod/funtbl.pod new file mode 100644 index 0000000..1fb9bb0 --- /dev/null +++ b/doc/pod/funtbl.pod @@ -0,0 +1,137 @@ +=pod + +=head1 NAME + + + +B + + + +=head1 SYNOPSIS + + + + + +funtable [-c cols] [-h] [-n table] [-p prog] [-s sep] + + + + + +=head1 DESCRIPTION + + + + +[NB: This program has been deprecated in favor of the ASCII text processing +support in funtools. You can now perform fundisp on funtools ASCII output +files (specifying the table using bracket notation) to extract tables +and columns.] + +The B script extracts a specified table (without the +header and comments) from a funtools ASCII output file and writes the +result to the standard output. The first non-switch argument is the +ASCII input file name (i.e. the saved output from funcnts, fundisp, +funhist, etc.). If no filename is specified, stdin is read. The +-n switch specifies which table (starting from 1) to extract. The +default is to extract the first table. The -c switch is a +space-delimited list of column numbers to output, e.g. -c "1 3 5" +will extract the first three odd-numbered columns. The default is to +extract all columns. The -s switch specifies the separator string to +put between columns. The default is a single space. The -h switch +specifies that column names should be added in a header line before +the data is output. Without the switch, no header is prepended. The +-p program switch allows you to specify an awk-like program to run +instead of the default (which is host-specific and is determined at +build time). The -T switch will output the data in rdb format (i.e., +with a 2-row header of column names and dashes, and with data columns +separated by tabs). The -help switch will print out a message +describing program usage. + + +For example, consider the output from the following funcnts command: + + [sh] funcnts -sr snr.ev "ann 512 512 0 9 n=3" + # source + # data file: /proj/rd/data/snr.ev + # arcsec/pixel: 8 + # background + # constant value: 0.000000 + # column units + # area: arcsec**2 + # surf_bri: cnts/arcsec**2 + # surf_err: cnts/arcsec**2 + + # summed background-subtracted results + upto net_counts error background berror area surf_bri surf_err + ---- ------------ --------- ------------ --------- --------- --------- --------- + 1 147.000 12.124 0.000 0.000 1600.00 0.092 0.008 + 2 625.000 25.000 0.000 0.000 6976.00 0.090 0.004 + 3 1442.000 37.974 0.000 0.000 15936.00 0.090 0.002 + + + # background-subtracted results + reg net_counts error background berror area surf_bri surf_err + ---- ------------ --------- ------------ --------- --------- --------- --------- + 1 147.000 12.124 0.000 0.000 1600.00 0.092 0.008 + 2 478.000 21.863 0.000 0.000 5376.00 0.089 0.004 + 3 817.000 28.583 0.000 0.000 8960.00 0.091 0.003 + + + # the following source and background components were used: + source_region(s) + ---------------- + ann 512 512 0 9 n=3 + + reg counts pixels sumcnts sumpix + ---- ------------ --------- ------------ --------- + 1 147.000 25 147.000 25 + 2 478.000 84 625.000 109 + 3 817.000 140 1442.000 249 + + +There are four tables in this output. To extract the last one, you +can execute: + + [sh] funcnts -s snr.ev "ann 512 512 0 9 n=3" | funtbl -n 4 + 1 147.000 25 147.000 25 + 2 478.000 84 625.000 109 + 3 817.000 140 1442.000 249 + +Note that the output has been re-formatted so that only a single space +separates each column, with no extraneous header or comment information. + + +To extract only columns 1,2, and 4 from the last example (but with a header +prepended and tabs between columns), you can execute: + + [sh] funcnts -s snr.ev "ann 512 512 0 9 n=3" | funtbl -c "1 2 4" -h -n 4 -s "\t" + #reg counts sumcnts + 1 147.000 147.000 + 2 478.000 625.000 + 3 817.000 1442.000 + + +Of course, if the output has previously been saved in a file named +foo.out, the same result can be obtained by executing: + + [sh] funtbl -c "1 2 4" -h -n 4 -s "\t" foo.out + #reg counts sumcnts + 1 147.000 147.000 + 2 478.000 625.000 + 3 817.000 1442.000 + + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + + +=cut diff --git a/doc/pod/funtext.pod b/doc/pod/funtext.pod new file mode 100644 index 0000000..9e20d1f --- /dev/null +++ b/doc/pod/funtext.pod @@ -0,0 +1,718 @@ +=pod + +=head1 NAME + + + +B + + + +=head1 SYNOPSIS + + + + + +This document contains a summary of the options for processing column-based +text files. + + + +=head1 DESCRIPTION + + + + + + +Funtools will automatically sense and process "standard" +column-based text files as if they were FITS binary tables without any +change in Funtools syntax. In particular, you can filter text files +using the same syntax as FITS binary tables: + + fundisp foo.txt'[cir 512 512 .1]' + fundisp -T foo.txt > foo.rdb + funtable foo.txt'[pha=1:10,cir 512 512 10]' foo.fits + + + +The first example displays a filtered selection of a text file. The +second example converts a text file to an RDB file. The third example +converts a filtered selection of a text file to a FITS binary table. + + +Text files can also be used in Funtools image programs. In this case, +you must provide binning parameters (as with raw event files), using +the bincols keyword specifier: + + + bincols=([xname[:tlmin[:tlmax:[binsiz]]]],[yname[:tlmin[:tlmax[:binsiz]]] + + +For example: + + funcnts foo'[bincols=(x:1024,y:1024)]' "ann 512 512 0 10 n=10" + + +B + + +Standard text files have the following characteristics: + + + +=over 4 + + + + +=item * + +Optional comment lines start with # + + +=item * + +Optional blank lines are considered comments + + +=item * + +An optional table header consists of the following (in order): + + +=over 4 + + + + +=item * + +a single line of alpha-numeric column names + + +=item * + +an optional line of unit strings containing the same number of cols + + +=item * + +an optional line of dashes containing the same number of cols + + +=back + + + + +=item * + +Data lines follow the optional header and (for the present) consist of + the same number of columns as the header. + + +=item * + +Standard delimiters such as space, tab, comma, semi-colon, and bar. + + +=back + + + + +Examples: + + + # rdb file + foo1 foo2 foo3 foos + ---- ---- ---- ---- + 1 2.2 3 xxxx + 10 20.2 30 yyyy + + # multiple consecutive whitespace and dashes + foo1 foo2 foo3 foos + --- ---- ---- ---- + 1 2.2 3 xxxx + 10 20.2 30 yyyy + + # comma delims and blank lines + foo1,foo2,foo3,foos + + 1,2.2,3,xxxx + 10,20.2,30,yyyy + + # bar delims with null values + foo1|foo2|foo3|foos + 1||3|xxxx + 10|20.2||yyyy + + # header-less data + 1 2.2 3 xxxx + 10 20.2 30 yyyy + + + +The default set of token delimiters consists of spaces, tabs, commas, +semi-colons, and vertical bars. Several parsers are used +simultaneously to analyze a line of text in different ways. One way +of analyzing a line is to allow a combination of spaces, tabs, and +commas to be squashed into a single delimiter (no null values between +consecutive delimiters). Another way is to allow tab, semi-colon, and +vertical bar delimiters to support null values, i.e. two consecutive +delimiters implies a null value (e.g. RDB file). A successful parser +is one which returns a consistent number of columns for all rows, with +each column having a consistent data type. More than one parser can +be successful. For now, it is assumed that successful parsers all +return the same tokens for a given line. (Theoretically, there are +pathological cases, which will be taken care of as needed). Bad parsers +are discarded on the fly. + + +If the header does not exist, then names "col1", "col2", etc. are +assigned to the columns to allow filtering. Furthermore, data types +for each column are determined by the data types found in the columns +of the first data line, and can be one of the following: string, int, +and double. Thus, all of the above examples return the following +display: + + fundisp foo'[foo1>5]' + FOO1 FOO2 FOO3 FOOS + ---------- --------------------- ---------- ------------ + 10 20.20000000 30 yyyy + + +B + + +Comments which precede data rows are converted into header parameters and +will be written out as such using funimage or funhead. Two styles of comments +are recognized: + + +1. FITS-style comments have an equal sign "=" between the keyword and +value and an optional slash "/" to signify a comment. The strict FITS +rules on column positions are not enforced. In addition, strings only +need to be quoted if they contain whitespace. For example, the following +are valid FITS-style comments: + + + # fits0 = 100 + # fits1 = /usr/local/bin + # fits2 = "/usr/local/bin /opt/local/bin" + # fits3c = /usr/local/bin /opt/local/bin /usr/bin + # fits4c = "/usr/local/bin /opt/local/bin" / path dir + + +Note that the fits3c comment is not quoted and therefore its value is the +single token "/usr/local/bin" and the comment is "opt/local/bin /usr/bin". +This is different from the quoted comment in fits4c. + + +2. Free-form comments can have an optional colon separator between the +keyword and value. In the absence of quote, all tokens after the +keyword are part of the value, i.e. no comment is allowed. If a string +is quoted, then slash "/" after the string will signify a comment. +For example: + + + # com1 /usr/local/bin + # com2 "/usr/local/bin /opt/local/bin" + # com3 /usr/local/bin /opt/local/bin /usr/bin + # com4c "/usr/local/bin /opt/local/bin" / path dir + + # com11: /usr/local/bin + # com12: "/usr/local/bin /opt/local/bin" + # com13: /usr/local/bin /opt/local/bin /usr/bin + # com14c: "/usr/local/bin /opt/local/bin" / path dir + + + +Note that com3 and com13 are not quoted, so the whole string is part of +the value, while comz4c and com14c are quoted and have comments following +the values. + + +Some text files have column name and data type information in the header. +You can specify the format of column information contained in the +header using the "hcolfmt=" specification. See below for a detailed +description. + +B + + +Multiple tables are supported in a single file. If an RDB-style file +is sensed, then a ^L (vertical tab) will signify end of +table. Otherwise, an end of table is sensed when a new header (i.e., +all alphanumeric columns) is found. (Note that this heuristic does not +work for single column tables where the column type is ASCII and the +table that follows also has only one column.) You also can specify +characters that signal an end of table condition using the B +keyword. See below for details. + + +You can access the nth table (starting from 1) in a multi-table file +by enclosing the table number in brackets, as with a FITS extension: + + + fundisp foo'[2]' + +The above example will display the second table in the file. +(Index values start at 1 in oder to maintain logical compatibility +with FITS files, where extension numbers also start at 1). + + +B + + +As with ARRAY() and EVENTS() specifiers for raw image arrays and raw +event lists respectively, you can use TEXT() on text files to pass +key=value options to the parsers. An empty set of keywords is +equivalent to not having TEXT() at all, that is: + + + fundisp foo + fundisp foo'[TEXT()]' + + +are equivalent. A multi-table index number is placed before the TEXT() +specifier as the first token, when indexing into a multi-table: + + fundisp foo'[2,TEXT(...)]' + + +The filter specification is placed after the TEXT() specifier, separated +by a comma, or in an entirely separate bracket: + + + fundisp foo'[TEXT(...),circle 512 512 .1]' + fundisp foo'[2,TEXT(...)][circle 512 512 .1]' + + +B + + +The following is a list of keywords that can be used within the TEXT() +specifier (the first three are the most important): + + + +=over 4 + + + + + + +=item * + +delims="[delims]" + + +Specify token delimiters for this file. Only a single parser having these +delimiters will be used to process the file. + + fundisp foo.fits'[TEXT(delims="!")]' + fundisp foo.fits'[TEXT(delims="\t%")]' + + + + + +=item * + +comchars="[comchars]" + + +Specify comment characters. You must include "\n" to allow blank lines. +These comment characters will be used for all standard parsers (unless delims +are also specified). + + fundisp foo.fits'[TEXT(comchars="!\n")]' + + + + + +=item * + +cols="[name1:type1 ...]" + + +Specify names and data type of columns. This overrides header +names and/or data types in the first data row or default names and +data types for header-less tables. + + fundisp foo.fits'[TEXT(cols="x:I,y:I,pha:I,pi:I,time:D,dx:E,dy:e")]' + + +If the column specifier is the only keyword, then the cols= is not +required (in analogy with EVENTS()): + + fundisp foo.fits'[TEXT(x:I,y:I,pha:I,pi:I,time:D,dx:E,dy:e)]' + +Of course, an index is allowed in this case: + + fundisp foo.fits'[2,TEXT(x:I,y:I,pha:I,pi:I,time:D,dx:E,dy:e)]' + + + + + +=item * + +eot="[eot delim]" + + +Specify end of table string specifier for multi-table files. RDB +files support ^L. The end of table specifier is a string and the whole +string must be found alone on a line to signify EOT. For example: + + fundisp foo.fits'[TEXT(eot="END")]' + +will end the table when a line contains "END" is found. Multiple lines +are supported, so that: + + fundisp foo.fits'[TEXT(eot="END\nGAME")]' + +will end the table when a line contains "END" followed by a line +containing "GAME". + +In the absence of an EOT delimiter, a new table will be sensed when a new +header (all alphanumeric columns) is found. + + + + +=item * + +null1="[datatype]" + + +Specify data type of a single null value in row 1. +Since column data types are determined by the first row, a null value +in that row will result in an error and a request to specify names and +data types using cols=. If you only have a one null in row 1, you don't +need to specify all names and columns. Instead, use null1="type" to +specify its data type. + + + + +=item * + +alen=[n] + + +Specify size in bytes for ASCII type columns. +FITS binary tables only support fixed length ASCII columns, so a +size value must be specified. The default is 16 bytes. + + + + +=item * + +nullvalues=["true"|"false"] + + +Specify whether to expect null values. +Give the parsers a hint as to whether null values should be allowed. The +default is to try to determine this from the data. + + + + +=item * + +whitespace=["true"|"false"] + + +Specify whether surrounding white space should be kept as part of +string tokens. By default surrounding white space is removed from +tokens. + + + + +=item * + +header=["true"|"false"] + + +Specify whether to require a header. This is needed by tables +containing all string columns (and with no row containing dashes), in +order to be able to tell whether the first row is a header or part of +the data. The default is false, meaning that the first row will be +data. If a row dashes are present, the previous row is considered the +column name row. + + + + +=item * + +units=["true"|"false"] + + +Specify whether to require a units line. +Give the parsers a hint as to whether a row specifying units should be +allowed. The default is to try to determine this from the data. + + + + +=item * + +i2f=["true"|"false"] + + +Specify whether to allow int to float conversions. +If a column in row 1 contains an integer value, the data type for that +column will be set to int. If a subsequent row contains a float in +that same column, an error will be signaled. This flag specifies that, +instead of an error, the float should be silently truncated to +int. Usually, you will want an error to be signaled, so that you can +specify the data type using cols= (or by changing the value of +the column in row 1). + + + + +=item * + +comeot=["true"|"false"|0|1|2] + + +Specify whether comment signifies end of table. +If comeot is 0 or false, then comments do not signify end of table and +can be interspersed with data rows. If the value is true or 1 (the +default for standard parsers), then non-blank lines (e.g. lines +beginning with '#') signify end of table but blanks are allowed +between rows. If the value is 2, then all comments, including blank +lines, signify end of table. + + + + +=item * + +lazyeot=["true"|"false"] + + +Specify whether "lazy" end of table should be permitted (default is +true for standard formats, except rdb format where explicit ^L is required +between tables). A lazy EOT can occur when a new table starts directly +after an old one, with no special EOT delimiter. A check for this EOT +condition is begun when a given row contains all string tokens. If, in +addition, there is a mismatch between the number of tokens in the +previous row and this row, or a mismatch between the number of string +tokens in the prev row and this row, a new table is assumed to have +been started. For example: + + ival1 sval3 + ----- ----- + 1 two + 3 four + + jval1 jval2 tval3 + ----- ----- ------ + 10 20 thirty + 40 50 sixty + +Here the line "jval1 ..." contains all string tokens. In addition, +the number of tokens in this line (3) differs from the number of +tokens in the previous line (2). Therefore a new table is assumed +to have started. Similarly: + + ival1 ival2 sval3 + ----- ----- ----- + 1 2 three + 4 5 six + + jval1 jval2 tval3 + ----- ----- ------ + 10 20 thirty + 40 50 sixty + +Again, the line "jval1 ..." contains all string tokens. The number of +string tokens in the previous row (1) differs from the number of +tokens in the current row(3). We therefore assume a new table as been +started. This lazy EOT test is not performed if lazyeot is explicitly +set to false. + + + + +=item * + +hcolfmt=[header column format] + + +Some text files have column name and data type information in the header. +For example, VizieR catalogs have headers containing both column names +and data types: + + #Column e_Kmag (F6.3) ?(k_msigcom) K total magnitude uncertainty (4) [ucd=ERROR] + #Column Rflg (A3) (rd_flg) Source of JHK default mag (6) [ucd=REFER_CODE] + #Column Xflg (I1) [0,2] (gal_contam) Extended source contamination (10) [ucd=CODE_MISC] + + +while Sextractor files have headers containing column names alone: + + + # 1 X_IMAGE Object position along x [pixel] + # 2 Y_IMAGE Object position along y [pixel] + # 3 ALPHA_J2000 Right ascension of barycenter (J2000) [deg] + # 4 DELTA_J2000 Declination of barycenter (J2000) [deg] + +The hcolfmt specification allows you to describe which header lines +contain column name and data type information. It consists of a string +defining the format of the column line, using "$col" (or "$name") to +specify placement of the column name, "$fmt" to specify placement of the +data format, and "$skip" to specify tokens to ignore. You also can +specify tokens explicitly (or, for those users familiar with how +sscanf works, you can specify scanf skip specifiers using "%*"). +For example, the VizieR hcolfmt above might be specified in several ways: + + Column $col ($fmt) # explicit specification of "Column" string + $skip $col ($fmt) # skip one token + %*s $col ($fmt) # skip one string (using scanf format) + +while the Sextractor format might be specified using: + + $skip $col # skip one token + %*d $col # skip one int (using scanf format) + +You must ensure that the hcolfmt statement only senses actual column +definitions, with no false positives or negatives. For example, the +first Sextractor specification, "$skip $col", will consider any header +line containing two tokens to be a column name specifier, while the +second one, "%*d $col", requires an integer to be the first token. In +general, it is preferable to specify formats as explicitly as +possible. + + +Note that the VizieR-style header info is sensed automatically by the +funtools standard VizieR-like parser, using the hcolfmt "Column $col +($fmt)". There is no need for explicit use of hcolfmt in this case. + + + + +=item * + +debug=["true"|"false"] + + +Display debugging information during parsing. + + + +=back + + + +B + + +Environment variables are defined to allow many of these TEXT() values to be +set without having to include them in TEXT() every time a file is processed: + + + keyword environment variable + ------- -------------------- + delims TEXT_DELIMS + comchars TEXT_COMCHARS + cols TEXT_COLUMNS + eot TEXT_EOT + null1 TEXT_NULL1 + alen TEXT_ALEN + bincols TEXT_BINCOLS + hcolfmt TEXT_HCOLFMT + + +B + + +As with raw event files, the '+' (copy extensions) specifier is not +supported for programs such as funtable. + + +String to int and int to string data conversions are allowed by the +text parsers. This is done more by force of circumstance than by +conviction: these transitions often happens with VizieR catalogs, +which we want to support fully. One consequence of allowing these +transitions is that the text parsers can get confused by columns which +contain a valid integer in the first row and then switch to a +string. Consider the following table: + + xxx yyy zzz + ---- ---- ---- + 111 aaa bbb + ccc 222 ddd + +The xxx column has an integer value in row one a string in row two, +while the yyy column has the reverse. The parser will erroneously +treat the first column as having data type int: + + fundisp foo.tab + XXX YYY ZZZ + ---------- ------------ ------------ + 111 'aaa' 'bbb' + 1667457792 '222' 'ddd' + +while the second column is processed correctly. This situation can be avoided +in any number of ways, all of which force the data type of the first column +to be a string. For example, you can edit the file and explicitly quote the +first row of the column: + + xxx yyy zzz + ---- ---- ---- + "111" aaa bbb + ccc 222 ddd + + [sh] fundisp foo.tab + XXX YYY ZZZ + ------------ ------------ ------------ + '111' 'aaa' 'bbb' + 'ccc' '222' 'ddd' + +You can edit the file and explicitly set the data type of the first column: + + xxx:3A yyy zzz + ------ ---- ---- + 111 aaa bbb + ccc 222 ddd + + [sh] fundisp foo.tab + XXX YYY ZZZ + ------------ ------------ ------------ + '111' 'aaa' 'bbb' + 'ccc' '222' 'ddd' + +You also can explicitly set the column names and data types of all columns, +without editing the file: + + [sh] fundisp foo.tab'[TEXT(xxx:3A,yyy:3A,zzz:3a)]' + XXX YYY ZZZ + ------------ ------------ ------------ + '111' 'aaa' 'bbb' + 'ccc' '222' 'ddd' + +The issue of data type transitions (which to allow and which to disallow) +is still under discussion. + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + + +=cut diff --git a/doc/pod/funtools.pod b/doc/pod/funtools.pod new file mode 100644 index 0000000..ff43cfb --- /dev/null +++ b/doc/pod/funtools.pod @@ -0,0 +1,542 @@ +=pod + +=head1 NAME + + + +B + + + +=head1 SYNOPSIS + + + + +This document is the Table of Contents for Funtools. + + + +=head1 DESCRIPTION + + + + +Funtools, is a "minimal buy-in" FITS library and utility package developed +at the the High Energy Astrophysics Division of SAO. The Funtools +library provides simplified access to a wide array of file types: +standard astronomical FITS images and binary tables, raw arrays and +binary event lists, and even tables of ASCII column data. A +sophisticated region filtering library (compatible with ds9) filters +images and tables using boolean operations between geometric shapes, +support world coordinates, etc. Funtools also supports advanced +capabilities such as optimized data searching using index files. + +The main goal of the Funtools project has been to develop a minimal buy-in +FITS library for researchers who are occasional (but serious) coders. In +this case, "minimal buy-in" means "easy to learn, easy to use, and easy to +re-learn next month". We have tried to achieve this goal by emphasizing two +essential capabilities. The first is the ability to develop FITS programs +without knowing much about FITS, i.e., without having to deal with the +arcane rules for generating a properly formatted FITS file. The second is +to support the use of already-familiar C/Unix facilities, especially C +structs and Unix stdio. Taken together, these two capabilities should allow +researchers to leverage their existing programming expertise while +minimizing the need to learn new and complex coding rules. + + + + +Choose from the following topics: + + + + +=over 4 + + + + +=item * + +Funtools User Programs + + +=over 4 + + + + +=item * + +funcalc: Funtools calculator (for binary tables) +[funcalc(1)] + + +=item * + +funcen: find centroid (for binary tables) +[funcen(1)] + + +=item * + +funcnts: count photons in specified regions +[funcnts(1)] + + +=item * + +funcone: cone search on RA, Dec columns +[funcone(1)] + + +=item * + +fundisp: display data in a Funtools data file +[fundisp(1)] + + +=item * + +funhead: display a header in a Funtools file +[funhead(1)] + + +=item * + +funhist: create a 1D histogram of a column +[funhist(1)] + + +=item * + +funimage: create a FITS image from a Funtools data file +[funimage(1)] + + +=item * + +funindex: create an index on a column in a binary table +[funindex(1)] + + +=item * + +funjoin: join two or more FITS binary tables on specified columns +[funjoin(1)] + + +=item * + +funmerge: merge one or more Funtools table files +[funmerge(1)] + + +=item * + +funsky: convert between image and sky coordinates, using WCS info from a FITS header +[funsky(1)] + + +=item * + +funtable: copy selected rows from a Funtools file to a FITS binary table +[funtable(1)] + + +=item * + +funtbl: extract a table from +Funtools ASCII output +[funtbl(1)] + + +=item * + +funtools and ds9 image display +[funds9(n)] + + +=back + + + + + +=item * + +Funtools Programming + + +=over 4 + + + + +=item * + +Funtools Programming Summary +[funlib(3)] + + +=item * + +Funtools Programming Tutorial +[funlib(3)] + + +=item * + +A Short Digression on Subroutine Order +[funlib(3)] + + +=item * + +Compiling and Linking +[funlib(3)] + + +=item * + +The Funtools Reference Handle +[funlib(3)] + + +=item * + +The Funtools Programming Reference Manual + + +=over 4 + + + + +=item * + +FunOpen: open a Funtools file +[funopen(3)] + + +=item * + +FunImageGet: retrieve image data +[funimageget(3)] + + +=item * + +FunImagePut: output image data +[funimageput(3)] + + +=item * + +FunImageRowGet: retrieve image data by row +[funimagerowget(3)] + + +=item * + +FunImageRowPut: output image data by row +[funimagerowput(3)] + + +=item * + +FunTableRowGet: retrieve rows from a table +[funtablerowget(3)] + + +=item * + +FunTableRowPut: output rows to a table +[funtablerowput(3)] + + +=item * + +FunColumnSelect: select columns in a table for access +[funcolumnselect(3)] + + +=item * + +FunColumnActivate: activate columns in a table for read/write +[funcolumnactivate(3)] + + +=item * + +FunColumnLookup: lookup info about the columns in a table +[funcolumnlookup(3)] + + +=item * + +FunInfoGet: get info about an image or table +[funinfoget(3)] + + +=item * + +FunInfoPut: put info about an image or table +[funinfoput(3)] + + +=item * + +FunParamGet: get header param +[funparamget(3)] + + +=item * + +FunParamPut: put header param +[funparamput(3)] + + +=item * + +FunFlush: flush I/O in a Funtools file +[funflush(3)] + + +=item * + +FunClose: close a Funtools file +[funclose(3)] + + +=back + + + + + +=item * + +Funtools Programming Examples +[funlib(3)] + + +=over 4 + + + + +=item * + +evmerge: merge new columns with existing columns + + +=item * + +evcols: add column and rows to binary tables + + +=item * + +imblank: blank out image values below a threshold + + +=back + + + + +=back + + + + + +=item * + +Funtools Data Files +[funfiles(n)] + + +=over 4 + + + + +=item * + +Supported Data Formats + + +=over 4 + + + + +=item * + +FITS File and Extensions + + +=item * + +Non-FITS Raw Event Files + + +=item * + +Non-FITS Array Files + + +=item * + +Column-based Text (ASCII) Files + + +=item * + +Database Views of Tables + + +=back + + + + +=item * + +Image Sections and Blocking + + +=item * + +Binning FITS Binary Tables and Non-FITS Event Files + + +=item * + +Disk Files and Other Supported File Types + + +=back + + + + + +=item * + +Funtools Data Filtering + + +=over 4 + + + + +=item * + +Table Filtering +[funfilters(n)] + + +=item * + +Fast Table Filtering using Indexes +[funidx(n)] + + +=item * + +Spatial Region Filtering +[funregions(n)] + + +=over 4 + + + + +=item * + +Region Geometry +[reggeometry(n)] + + +=item * + +Region Algebra +[regalgebra(n)] + + +=item * + +Region Coordinates +[regcoords(n)] + + +=item * + +Region Boundaries +[regbounds(n)] + + +=item * + +Differences Between Funtools and IRAF Regions +[regdiff(n)] + + +=back + + + + +=item * + +Combining Table and Region Filters +[funcombine(n)] + + +=back + + + + + +=item * + +Miscellaneous + + +=over 4 + + + + +=item * + +Funtools Environment Variables +[funenv(n)] + + +=item * + +Funtools ChangeLog + + +=back + + + + + +=back + + + + + + +=cut diff --git a/doc/pod/funview.pod b/doc/pod/funview.pod new file mode 100644 index 0000000..f0c2095 --- /dev/null +++ b/doc/pod/funview.pod @@ -0,0 +1,407 @@ +=pod + +=head1 NAME + + + +B + + + +=head1 SYNOPSIS + + + + + +This document contains a summary of the options for utilizing +database-inspired Views of tables. + + + +=head1 DESCRIPTION + + + + + +B + +In database parlance, a B defines a "virtual table", i.e., +a description of row and/or column selection filters (but with no +permanent storage space allocated). When used in place of a table, a +View selects the specified rows and/or columns from one or more real +tables. Views enable you to see complicated data tables in a more +convenient format. They also can be used as a security mechanism, by +restricting user access to specific columns and/or rows. [See: + +http://www.cs.unibo.it/~ciaccia/COURSES/RESOURCES/SQLTutorial/sqlch5.htm + +for a good discussion of SQL Views.] + + +Funtools supports an expanded notion of Views for all tabular data +(FITS tables, raw binary tables, and ASCII column files). Funtools +Views allow you to pre-set values for the filter specification, the +columns to activate, and display format (though the latter is for +fundisp only). Setting the filter and column activation values +provides functionality equivalent to that of a classical database +View, while the ability to set the format is similar to classical +report writing capabilities. + +B + +A Funtools View is a text file containing one or more of the following +columns: + + column description + ------ ----------------------------- + view name of view + file data file name or template + filter filter specification + columns columns to activate + format fundisp format specification + +All of the attribute columns are optional, including +the B name itself. This means that a View can be named or +unnamed. Unnamed Views can refer to a specific file or a template of +files (obviously if neither the view or the file column is specified, +the input View specification will never be used). You can specify any +combination of filter, column, and format parameters. (It also is +possible to apply file-specific View to other files; see the discussion +on B below). Each column has a size limit of 1024 characters. + + +For example, consider the following View file: + + view file format columns filter + ---- ---------------------- ------ ------------ ------- + x3 ${HOME}/data/snr.ev I=%4d x y pi pha cir 512 512 .1 + x2 ${HOME}/data/snr.ev x y pi pha cir 512 512 .1 + x1 ${HOME}/data/snr.ev cir 512 512 .1 + x1a ${HOME}/data/snr.ev x y pi pha + x0 ${HOME}/data/snr.ev + xf I=%4d + xc x y pi pha + xr cir 512 512 .1 + *.ev x y pi pha + *.fit x y dx dy cir 400 400 3 + *.fits I=%3d x y dx dy cir 400 400 3 + +This database example is in rdb format, i.e. using tab delimiters and +permitting null values. Any valid ASCII table format is acceptable, +but if you use a format that does not permit null values, it will be +necessary to quote the null strings. + + +The first five entries (x3, x2, x1, x1a, x0) are named entries defining +default values specifically for the snr.ev data file. Typically, you +would use these Views by specifying View name, and the corresponding +file, filter, column, and format values would be used. Note that the x0 +View is essentially an alias for the pathname of this file. + + +The next three entries define defaults that can be applied to any +file. You typically would use these View names in conjunction with +a specific file name (see B below) so that the associated +parameter(s) were applied to that file. + + +The last three entry in the database define unnamed Views that +pertains to all files ending with the specified templates. In these +cases, any View that specifies a file name matching the file template +would be processed with the associated parameter attributes. + +B + +To use a Funtools View, you simply pre-pend the "v:" prefix to a View name or +a file name where an input file name usually is specified. For example: + + fundisp v:x3 + +specifies that the View named x3 (with its file name and associated +parameters) is processed as the input file to fundisp. Using the +example database, above, this is equivalent to: + + fundisp -f "I=%4d" ${HOME}/data/snr.ev'[cir 512 512 .1]' "x y pi pha" + +That is, the format is used with fundisp's -f (format) switch, while the +filename and extension are composed of the x3 View's filename and +region filter. + + +Similarly, executing a command such as: + + fundisp v:foo.fit + +will match the unnamed View associated with the template "*.fit". +This is equivalent to executing: + + fundisp foo.fit'[cir 400 400 3]' "x y dx dy" + +Of course, if you omit the "v:" prefix, then no View processing takes place: + + fundisp foo.fit # process foo.fit without any View parameters + fundisp x3 # error (assuming there is no file named x3) + + +B + + +When a "v:" prefix is recognized, Funtools searches for a View database +file in the following order: + + location description + ------------ ------------------------------------ + FUN_VIEWFILE environment variable (any file name) + ./.funtools.vu hidden file, default name + $HOME/.funtools.vu hidden file, default name + +The first View database file located is used to construct a new +filename, as well as an activation column specification and a format +specification. The following rules are used: + + +1. An attempt is made to match the input name (i.e., the part of the +input View after the "v:" prefix) against the B column value +(if present) of each row in the database. If a match is found, the +values of all non-blank columns are saved for later use. Also note +that the first match terminates the search: i.e., the order of the +database rows matters. + + +2. If no B match is made, an attempt is made to match the input +name against the B column value (if present). Matching is +performed on the full pathname of both the input name and the +database file name, and on the non-directory (root) part of these +files. This means that the root specification: + + fundisp v:snr.ev + +will match a row in the database that has a full pathname in the file, +allowing you to use a B-matched View without having to +specify the full pathname. In this example, the "v:snr.ev" View +specification will match the first row (v:x3) in the database: + + x3 ${HOME}/data/snr.ev I=%4d x y pi pha cir 512 512 .1 + +even though the row contains a fully qualified pathname as the file +value. Once again, values of all non-blank columns are saved, and the +first match terminates the search. + + +3. If neither a B or a B match has been found, +then a simple template match is attempted against the B +values. Template matching supports a simplified version of file +globbing (not a regular expression), with support for a single "*" +(all characters), "?" (single character), or "[...]" (range) specification. + + +4. If no template match was found on the B column, then a +simple template match is attempted against the B columns. + + +5. If no match is found, then the filename (minus the "v:" prefix) is +returned. + +B + +The matching rules described above stop after the first match, +regardless of whether that match provides values for all three +parameters (filter, columns, and format). In cases where a B +or B match does not provide all three values, it is possible +that a template match might do so. With regard to the example View +database above, the x1 View provides only a filter, while omitting +both the format and columns values. But note that the final rows in +the database could provide the values via a template match on the +filename. This sort of multiple matching is especially valuable in +order to provide "global" values to several Views. + + +Obviously, multiple matching might not be wanted in every +case. Therefore, we support both multiple matching and single matching +according to the value of the FUN_VIEWMATCH environment variable. If +the FUN_VIEWMATCH environment variable exists and if its value begins +with "s", then a single match is used and missing parameters are not +filled in with subsequent template matches on the file name. That is, +matching rules above are followed exactly as explained above. If the +value of this environment variable begins with "m" (or does not exist), +then multiple matches are used to try to fill in missing parameters. +In this case, template matching always takes place and missing values are +taken from these template matches. + + +Thus, in the example above, the View specification: + + fundisp v:x1 + +will take the file name and filter value from the x1 View: + + x1 ${HOME}/data/snr.ev cir 512 512 .1 + +The column value then will be taken from the "*.ev" file template match +against the x1 file name: + + *.ev x y pi pha + +Note once again that order is important: missing values are taken in the +order in which the template matches are processed. + +B + + +It is possible to apply a named View, or even several Views, to any +data file by appending a B immediately after the standard "v:" +prefix. A viewlist takes the form: + + :v1,v2,...vn: + +where v1, v2, etc. are named Views. The two ":" colon characters surrounding +the list are required. Thus, the syntax for applying a viewlist to a file is: + + v::view1,view2,...viewn:filename + +Note that the name after the last ":" is assumed to be a file; it is +not permissible (or sensible) to use a View name. + + +For example, the View specification: + + fundisp v::x2:foo + +applies the x2 View to the file foo (even if there is a View named foo) +and (in using our example database) is equivalent to: + + ./fundisp foo'[cir 512 512 .1] "x y pi pha" + +The same command can be effected using a list of Views: + + fundisp v::x1,x1a:foo + + + +What happens if a viewlist is used and the file also matches a +template? Consider, for example, this View specification: + + fundisp v::x2:foo.fit + +Here, the x2 View will supply filter and column values, while the +template *.fit can also supply (different) filter and column +values. In this case, the explicitly specified Views of the viewlist +trump the matched view values. + + +On the other hand, if a file template match can supply a View value +that is not supplied by the viewlist, then that value will be taken +from the file template match. For example: + + fundisp v::x2:foo.fits + +does not explicitly supply a format value, but the file match on *.fits +can and does. You can avoid supplying missing values using file template +matching by replacing the first ":" with a "-" in a viewlist +specification: + + fundisp v:-x2:foo.fits + +The use of ":+" to explicitly allow file template matching is also +supported, but is the same as the default case. Note that the nuances +of viewlist support are subject to change as our experience and +understanding grow. + +B + + +To override values associated with a View, simply supply the override +values in the correct place on the command line. Thus, given +the example database described above, the command: + + fundisp v:x3 + +specifies that the View named x3, along with its file name and +associated parameters, be processed as the input file to fundisp in +this way: + + fundisp -f "I=%4d" ${HOME}/data/snr.ev'[cir 512 512 .1]' "x y pi pha" + +To override one or more of these values, simply specify a new value +for the format, filter, or columns. For example, if your input View file +contains a filter, then the View will use that filter as an override +of the View filter: + + fundisp v:x3'[cir 400 400 3]' + +will use the columns and format of the x3 View but not the x3 filter. Further +examples are: + + fundisp v:x3 "x y dx dy" # activate a different set of columns + fundisp -f "I=%3d" v:x3 # use a different format statement + + + +Note that extension names, extension index values, and other +non-filter specifications B override the View +filter. Thus: + + fundisp v:foo.fit[3] + +will still use the filter associated with the .fit template (see above), since +the "3" is an extension index, not a filter. + +B + +The following environment variables are used by Funtools Views: + + +=over 4 + + + + +=item * + +B + + +The B environment variable specifies the +name and location of the View database file. If not present, the +files ./.funtools.vu and $HOME/.funtools.vu are searched for, in +that order. + + + +=item * + +B + + +The B environment variable specifies whether a +single match or multiple match algorithm is used to locate parameter +values. If the value of this environment variable begins with "s", +then a single match is used and missing parameters are not filled in +with subsequent template matches on the file name. If the value begins +with "m", then multiple matches are used to try to fill in missing +parameters. The default is to use multiple matches. + + +=back + + + +B + +Support for overriding a filter (while not overriding extension names, +extension indexes, etc.) requires that we can sense the presence of a +filter in a bracket specification. It is unclear yet whether our +algorithm is perfect. + + +Go to Funtools Help Index + +Last updated: August 3, 2007 + + + + + +=cut diff --git a/doc/pod/funvu.pod b/doc/pod/funvu.pod new file mode 100644 index 0000000..528ea50 --- /dev/null +++ b/doc/pod/funvu.pod @@ -0,0 +1,404 @@ +=pod + +=head1 NAME + + + +B + + + +=head1 SYNOPSIS + + + + + +This document contains a summary of the options for utilizing +database-inspired Views of tables. + + + +=head1 DESCRIPTION + + + + + +B + +In database parlance, a B defines a "virtual table", i.e., +a description of row and/or column selection filters (but with no +permanent storage space allocated). When used in place of a table, a +View selects the specified rows and/or columns from one or more real +tables. Views enable users to see complicated data tables in a more +convenient format. They also can be used as a security mechanism, by +restricting user access to specific columns and/or rows. [See: +http://www.cs.unibo.it/~ciaccia/COURSES/RESOURCES/SQLTutorial/sqlch5.htm +for a good discussion of SQL Views.] + + +Funtools supports an expanded notion of Views for all tabular data +(FITS tables, raw binary tables, and ASCII column files). Funtools +Views allow you to pre-set values for the filter specification, the +columns to activate and display format (though the latter is for +fundisp only). Setting the filter and column activation values +provides functionality equivalent to that of a classical database +View, while the ability to set the format is similar to classical +report writing capabilities. + +B + +A Funtools View consists of one or more of the following attributes: + + column description + ------ ----------------------------- + view name of view + file data file name or template + filter filter specification + columns columns to activate + format fundisp format specification + +All of the attribute columns are optional, including +the B name itself. This means that a View can be named or +unnamed. Unnamed Views can refer to a specific file or a template of +files (obviously if neither the view or the file column is specified, +the input View specification will never be used). You can specify any +combination of filter, column, and format parameters. (It also is +possible to apply file-specific View to other files; see the discussion +on B below). Each column has a size limit of 1024 characters. + + +For example, consider the following View database: + + view file format columns filter + ---- ---------------------- ------ ------------ ------- + x3 ${HOME}/data/snr.ev I=%4d x y pi pha cir 512 512 .1 + x2 ${HOME}/data/snr.ev x y pi pha cir 512 512 .1 + x1 ${HOME}/data/snr.ev cir 512 512 .1 + x1a ${HOME}/data/snr.ev x y pi pha + x0 ${HOME}/data/snr.ev + xf I=%4d + xc x y pi pha + xr cir 512 512 .1 + *.ev x y pi pha + *.fit x y dx dy cir 400 400 3 + *.fits I=%3d x y dx dy cir 400 400 3 + +This database example is in rdb format, i.e. using tab delimiters and +permitting null values. Any valid ASCII table format is acceptable, +but if you use a format that does not permit null values, it will be +necessary to quote the null strings. + + +The first five entries (x3, x2, x1, x1a, x0) are named entries defining +default values specifically for the snr.ev data file. Typically, you +would use these Views by specifying View name, and the corresponding +file, filter, column, and format values would be used. Note that the x0 +View is essentially an alias for the pathname of this file. + + +The next three entries define defaults that can be applied to any +file. Here, you typically would use these View names in conjunction with +a specific file name (see B below) so that the associated +parameter(s) were applied to that file. + + +The last three entry in the database define unnamed Views that +pertains to all files ending with the specified templates. In these +cases, any View that specifies a file name matching the file template +would be processed with the associated parameter attributes. + +B + +To specify a Funtools View, pre-pend the "v:" prefix to a View name or +a file name where an input file name usually is specified. For example: + + fundisp v:x3 + +specifies that the View named x3, its file name and associated +parameters, be processed as the input file to fundisp. Using the +example database, above, this is equivalent to: + + fundisp -f "I=%4d" ${HOME}/data/snr.ev'[cir 512 512 .1]' "x y pi pha" + +That is, the format is used with fundisp's -f (format) switch, while the +filename and extension are composed of the x3 View's filename and +region filter. + + +Similarly, executing a command such as: + + fundisp v:foo.fit + +will match the unnamed View associated with the template "*.fit". +This is equivalent to executing: + + fundisp foo.fit'[cir 400 400 3]' "x y dx dy" + +Of course, if you omit the "v:" prefix, then no View processing takes place: + + fundisp foo.fit # process foo.fit without any View parameters + fundisp x3 # error (assuming there is no file named x3) + + +B + + +When a "v:" prefix is recognized, Funtools searches for a View database +file in the following order: + + location description + ------------ ------------------------------------ + FUN_VIEWFILE environment variable (any file name) + ./.funtools.vu hidden file, default name + $HOME/.funtools.vu hidden file, default name + +The first View database file located is used to construct a new +filename, as well as an activation column specification and a format +specification. The following rules are used: + + +1. An attempt is made to match the input name (i.e. the part of the +input View after the "v:" prefix) against the B column value +(if present) of each row in the database. If a match is found, the +values of all non-blank columns are saved for later use. Also note +that the first match terminates the search: i.e. the order of the +database rows does matter. + + +2. If no B match is made, an attempt is made to match the input +name against the B column value (if present). Matching is +performed on the full pathname of both the input name and the +database file name, and on the non-directory (root) part of these +files. This means that the root specification: + + fundisp v:snr.ev + +will match a row in the database that has a full pathname in the file, +allowing you to use a B-matched View without having to +specify the full pathname. In this example, the "v:snr.ev" View +specification will match the first row (v:x3) in the database: + + x3 ${HOME}/data/snr.ev I=%4d x y pi pha cir 512 512 .1 + +even though the row contains a fully qualified pathname as the file +value. Once again, values of all non-blank columns are saved, and the +first match terminates the search. + + +3. If neither a B or a B match has been found, +then a simple template is attempted against the B +values. The template matching supports a simplified version of file +globbing (not a regular expression), with support for a single "*" +(all characters), "?" (single character), or "[...]" (range) specification. + + +4. If no template match was found on the B column, then a +simple template match is attempted against the B columns. + + +5. If no match is found, then the filename (minus the "v:" prefix) is +returned. + +B + +The matching rules described above stop after the first match, +regardless of whether that match provides values for all three +parameters (filter, columns, and format). In cases where a B +or B match does not provide all three values, it is possible +that a template match might do so. With regard to the example View +database above, the x1 View provides only a filter, while omitting +both the format and columns values. But note that the final rows in +the database could provide the values via a template match on the +filename. This sort of multiple matching is especially valuable in +order to provide "global" values to several Views. + + +Obviously, multiple matching might not be wanted in every +case. Therefore, we support both multiple matching and single matching +according to the value of the FUN_VIEWMATCH environment variable. If +the FUN_VIEWMATCH environment variable exists and if its value begins +with "s", then a single match is used and missing parameters are not +filled in with subsequent template matches on the file name. That is, +matching rules above are followed exactly as explained above. If the +value of this environment variable begins with "m" (or does not exist), +then multiple matches are used to try to fill in missing parameters. +In this case, template matching always takes place and missing values are +taken from these template matches. + + +Thus, in the example above, the View specification: + + fundisp v:x1 + +will take the file name and filter value from the x1 View: + + x1 ${HOME}/data/snr.ev cir 512 512 .1 + +The column value then will be taken from the "*.ev" file template match +against the x1 file name: + + *.ev x y pi pha + +Note once again that order is important: missing values are taken in the +order in which the template matches are processed. + +B + + +It is possible to apply a named View, or even several Views, to any +data file by appending a B immediately after the standard "v:" +prefix. A viewlist takes the form: + + :v1,v2,...vn: + +where v1, v2, etc. are named Views. The two ":" colon characters surrounding +the list are required. Thus, the syntax for applying a viewlist to a file is: + + v::view1,view2,...viewn:filename + +Note that the name after the last ":" is assumed to be a file; it is +not permissible (or sensible) to use a View name. + + +For example, the View specification: + + fundisp v::x2:foo + +applies the x2 View to the file foo (even if there is a View named foo) +and (in using our example database) is equivalent to: + + ./fundisp foo'[cir 512 512 .1] "x y pi pha" + +The same command can be effected using a list of Views: + + fundisp v::x1,x1a:foo + + + +What happens if a viewlist is used and the file also matches a +template? Consider, for example, this View specification: + + fundisp v::x2:foo.fit + +Here, the x2 View will supply filter and column values, while the +template *.fit can also supply (different) filter and column +values. In this case, the explicitly specified Views of the viewlist +trump the matched view values. + + +On the other hand, if a file template match can supply a View value +that is not supplied by the viewlist, then that value will be taken +from the file template match. For example: + + fundisp v::x2:foo.fits + +does not explicitly supply a format value, but the file match on *.fits +can and does. You can avoid supplying missing values using file template +matching by replacing the first ":" with a "-" in a viewlist +specification: + + fundisp v:-x2:foo.fits + +The use of ":+" to explicitly allow file template matching is also +supported, but is the same as the default case. Note that the nuances +of viewlist support are subject to change as our experience and +understanding grows. + +B + + +To override values associated with a View, simply supply the override +values in the correct place on the command line. For example, given +the example database described above, the command: + + fundisp v:x3 + +specifies that the View named x3, along with its file name and +associated parameters, be processed as the input file to fundisp in +this way: + + fundisp -f "I=%4d" ${HOME}/data/snr.ev'[cir 512 512 .1]' "x y pi pha" + +To override one or more of these values, simply specify a new value +for the format, filter, or columns. For example, if your input View file +contains a filter, then the View will use that filter as an override +of the View filter: + + fundisp v:x3'[cir 400 400 3]' + +will use the columns and format of the x3 View but not the x3 filter. Further +examples are: + + fundisp v:x3 "x y dx dy" # activate a different set of columns + fundisp -f "I=%3d" v:x3 # use a different format statement + + + +Note that extension names, extension index values, and other +non-filter specifications B override the View +filter. Thus: + + fundisp v:foo.fit[3] + +will still use the filter associated with the .fit template (see above), since +the "3" is an extension index, not a filter. + +B + +The following environment variables are used by Funtools Views: + + +=over 4 + + + + +=item * + +B + + +The B environment variable specifies the +name and location of the View database file. If not present, the +files ./.funtools.vu and $HOME/.funtools.vu are searched for, in +that order. + + + +=item * + +B + + +The B environment variable specifies whether a +single match or multiple match algorithm is used to locate parameter +values. If the value of this environment variable begins with "s", +then a single match is used and missing parameters are not filled in +with subsequent template matches on the file name. If the value begins +with "m", then multiple matches are used to try to fill in missing +parameters. The default is to use multiple matches. + + +=back + + + +B + +Support for overriding a filter (while not overriding extension names, +extension indexes, etc.) requires that we can sense the presence of a +filter in a bracket specification. It is unclear yet whether our +algorithm is perfect. + + +Go to Funtools Help Index + +Last updated: January 3, 2006 + + + + + +=cut diff --git a/doc/pod/regalgebra.pod b/doc/pod/regalgebra.pod new file mode 100644 index 0000000..4c6da88 --- /dev/null +++ b/doc/pod/regalgebra.pod @@ -0,0 +1,286 @@ +=pod + +=head1 NAME + + + +B + + + +=head1 SYNOPSIS + + + + + +This document describes the boolean arithmetic defined for +region expressions. + + + +=head1 DESCRIPTION + + + + + +When defining a region, several shapes can be combined using boolean +operations. The boolean operators are (in order of precedence): + + Symbol Operator Associativity + ------ -------- ------------- + ! not right to left + & and left to right + ^ exclusive or left to right + | inclusive or left to right + + +For example, to create a mask consisting of a large circle with a +smaller box removed, one can use the B and B +operators: + + CIRCLE(11,11,15) & !BOX(11,11,3,6) + + +and the resulting mask is: + + 1234567890123456789012345678901234567890 + ---------------------------------------- + 1:1111111111111111111111.................. + 2:1111111111111111111111.................. + 3:11111111111111111111111................. + 4:111111111111111111111111................ + 5:111111111111111111111111................ + 6:1111111111111111111111111............... + 7:1111111111111111111111111............... + 8:1111111111111111111111111............... + 9:111111111...1111111111111............... + 10:111111111...1111111111111............... + 11:111111111...1111111111111............... + 12:111111111...1111111111111............... + 13:111111111...1111111111111............... + 14:111111111...1111111111111............... + 15:1111111111111111111111111............... + 16:1111111111111111111111111............... + 17:111111111111111111111111................ + 18:111111111111111111111111................ + 19:11111111111111111111111................. + 20:1111111111111111111111.................. + 21:1111111111111111111111.................. + 22:111111111111111111111................... + 23:..11111111111111111..................... + 24:...111111111111111...................... + 25:.....11111111111........................ + 26:........................................ + 27:........................................ + 28:........................................ + 29:........................................ + 30:........................................ + 31:........................................ + 32:........................................ + 33:........................................ + 34:........................................ + 35:........................................ + 36:........................................ + 37:........................................ + 38:........................................ + 39:........................................ + 40:........................................ + +A three-quarter circle can be defined as: + + CIRCLE(20,20,10) & !PIE(20,20,270,360) + + +and looks as follows: + + + 1234567890123456789012345678901234567890 + ---------------------------------------- + 1:........................................ + 2:........................................ + 3:........................................ + 4:........................................ + 5:........................................ + 6:........................................ + 7:........................................ + 8:........................................ + 9:........................................ + 10:........................................ + 11:...............111111111................ + 12:..............11111111111............... + 13:............111111111111111............. + 14:............111111111111111............. + 15:...........11111111111111111............ + 16:..........1111111111111111111........... + 17:..........1111111111111111111........... + 18:..........1111111111111111111........... + 19:..........1111111111111111111........... + 20:..........1111111111111111111........... + 21:..........1111111111.................... + 22:..........1111111111.................... + 23:..........1111111111.................... + 24:..........1111111111.................... + 25:...........111111111.................... + 26:............11111111.................... + 27:............11111111.................... + 28:..............111111.................... + 29:...............11111.................... + 30:........................................ + 31:........................................ + 32:........................................ + 33:........................................ + 34:........................................ + 35:........................................ + 36:........................................ + 37:........................................ + 38:........................................ + 39:........................................ + 40:........................................ + +Two non-intersecting ellipses can be made into the same region: + + ELL(20,20,10,20,90) | ELL(1,1,20,10,0) + + +and looks as follows: + + 1234567890123456789012345678901234567890 + ---------------------------------------- + 1:11111111111111111111.................... + 2:11111111111111111111.................... + 3:11111111111111111111.................... + 4:11111111111111111111.................... + 5:1111111111111111111..................... + 6:111111111111111111...................... + 7:1111111111111111........................ + 8:111111111111111......................... + 9:111111111111............................ + 10:111111111............................... + 11:...........11111111111111111............ + 12:........111111111111111111111111........ + 13:.....11111111111111111111111111111...... + 14:....11111111111111111111111111111111.... + 15:..11111111111111111111111111111111111... + 16:.1111111111111111111111111111111111111.. + 17:111111111111111111111111111111111111111. + 18:111111111111111111111111111111111111111. + 19:111111111111111111111111111111111111111. + 20:111111111111111111111111111111111111111. + 21:111111111111111111111111111111111111111. + 22:111111111111111111111111111111111111111. + 23:111111111111111111111111111111111111111. + 24:.1111111111111111111111111111111111111.. + 25:..11111111111111111111111111111111111... + 26:...11111111111111111111111111111111..... + 27:.....11111111111111111111111111111...... + 28:.......111111111111111111111111......... + 29:...........11111111111111111............ + 30:........................................ + 31:........................................ + 32:........................................ + 33:........................................ + 34:........................................ + 35:........................................ + 36:........................................ + 37:........................................ + 38:........................................ + 39:........................................ + 40:........................................ + +You can use several boolean operations in a single region expression, +to create arbitrarily complex regions. With the important exception +below, you can apply the operators in any order, using parentheses if +necessary to override the natural precedences of the operators. + + +NB: Using a panda shape is always much more efficient than explicitly +specifying "pie & annulus", due to the ability of panda to place a +limit on the number of pixels checked in the pie shape. If you are +going to specify the intersection of pie and annulus, use panda +instead. + + +As described in "help regreometry", the B slice goes to the +edge of the field. To limit its scope, B usually is is +combined with other shapes, such as circles and annuli, using boolean +operations. In this context, it is worth noting that that there is a +difference between B<-PIE> and B<&!PIE>. The former is a +global exclude of all pixels in the B slice, while the latter +is a local excludes of pixels affecting only the region(s) with which +the B is combined. For example, the following region uses +B<&!PIE> as a local exclude of a single circle. Two other circles +are also defined and are unaffected by the local exclude: + + + CIRCLE(1,8,1) + CIRCLE(8,8,7)&!PIE(8,8,60,120)&!PIE(8,8,240,300) + CIRCLE(15,8,2) + + 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + - - - - - - - - - - - - - - - + 15: . . . . . . . . . . . . . . . + 14: . . . . 2 2 2 2 2 2 2 . . . . + 13: . . . 2 2 2 2 2 2 2 2 2 . . . + 12: . . 2 2 2 2 2 2 2 2 2 2 2 . . + 11: . . 2 2 2 2 2 2 2 2 2 2 2 . . + 10: . . . . 2 2 2 2 2 2 2 . . . . + 9: . . . . . . 2 2 2 . . . . 3 3 + 8: 1 . . . . . . . . . . . . 3 3 + 7: . . . . . . 2 2 2 . . . . 3 3 + 6: . . . . 2 2 2 2 2 2 2 . . . . + 5: . . 2 2 2 2 2 2 2 2 2 2 2 . . + 4: . . 2 2 2 2 2 2 2 2 2 2 2 . . + 3: . . . 2 2 2 2 2 2 2 2 2 . . . + 2: . . . . 2 2 2 2 2 2 2 . . . . + 1: . . . . . . . . . . . . . . . + + +Note that the two other regions are not affected by the B<&!PIE>, +which only affects the circle with which it is combined. + + +On the other hand, a B<-PIE> is an global exclude that does +affect other regions with which it overlaps: + + + CIRCLE(1,8,1) + CIRCLE(8,8,7) + -PIE(8,8,60,120) + -PIE(8,8,240,300) + CIRCLE(15,8,2) + + 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + - - - - - - - - - - - - - - - + 15: . . . . . . . . . . . . . . . + 14: . . . . 2 2 2 2 2 2 2 . . . . + 13: . . . 2 2 2 2 2 2 2 2 2 . . . + 12: . . 2 2 2 2 2 2 2 2 2 2 2 . . + 11: . . 2 2 2 2 2 2 2 2 2 2 2 . . + 10: . . . . 2 2 2 2 2 2 2 . . . . + 9: . . . . . . 2 2 2 . . . . . . + 8: . . . . . . . . . . . . . . . + 7: . . . . . . 2 2 2 . . . . . . + 6: . . . . 2 2 2 2 2 2 2 . . . . + 5: . . 2 2 2 2 2 2 2 2 2 2 2 . . + 4: . . 2 2 2 2 2 2 2 2 2 2 2 . . + 3: . . . 2 2 2 2 2 2 2 2 2 . . . + 2: . . . . 2 2 2 2 2 2 2 . . . . + 1: . . . . . . . . . . . . . . . + + +The two smaller circles are entirely contained within the two exclude +B slices and therefore are excluded from the region. + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + + +=cut diff --git a/doc/pod/regbounds.pod b/doc/pod/regbounds.pod new file mode 100644 index 0000000..c63a0bd --- /dev/null +++ b/doc/pod/regbounds.pod @@ -0,0 +1,203 @@ +=pod + +=head1 NAME + + + +B + + + +=head1 SYNOPSIS + + + + +Describes how spatial region boundaries are handled. + + + +=head1 DESCRIPTION + + + + + +The golden rule for spatial region filtering was first enunciated by +Leon VanSpeybroeck in 1986: + + +Each photon will be counted once, and no photon will be counted +more than once. + + +This means that we must be careful about boundary +conditions. For example, if a circle is contained in an annulus such +that the inner radius of the annulus is the same as the radius of the +circle, then photons on that boundary must always be assigned to one +or the other region. That is, the number of photons in both regions +must equal the sum of the number of photons in each region taken +separately. + +With this in mind, the rules for determining whether a boundary image +pixel or table row are assigned to a region are defined below. + +B + +For image filtering, pixels whose center is inside the boundary are +included. This also applies non-radially-symmetric shapes. When a +pixel center is exactly on the boundary, the pixel assignment rule is: + + + +=over 4 + + + + +=item * + +the outer boundary of a symmetric shape does not include such pixels + + +=item * + +the inner boundary of a symmetric shape (annulus) includes such pixels + + +=back + + + +In this way, an annulus with radius from 0 to 1, centered exactly on a +pixel, includes the pixel on which it is centered, but none of its +neighbors. + +These rules ensure that when defining concentric shapes, no pixels are +omitted between concentric regions and no pixels are claimed by two +regions. When applied to small symmetric shapes, the shape is less +likely to be skewed, as would happen with non-radially-symmetric +rules. These rules differ from the rules for box-like shapes, which +are more likely to be positioned adjacent to one another. + +B + +For image filtering, pixels whose center is inside the boundary are +included. This also applies radially-symmetric shapes. When a pixel +center is exactly on the boundary of a non-radially symmetric region, +the pixel is included in the right or upper region, but not the left +or lower region. This ensures that geometrically adjoining regions +touch but don't overlap. + +B + +When filtering table rows, the boundary rules are the same as for +images, except that the calculation is not done on the center of a +pixel, (since table rows, especially X-ray events rows, often have +discrete, floating point positions) but are calculated exactly. That +is, an row is inside the boundary without regard to its integerized +pixel value. For rows that are exactly on a region boundary, the +above rules are applied to ensure that all rows are counted once and +no row is counted more than once. + + +Because row boundaries are calculated differently from image boundaries, +certain programs will give different results when filtering the same +region file. In particular, fundisp/funtable (which utilize analytic +row filtering) perform differently from funcnts (which performs image +filtering, even on tables). + +B + + +You will sometimes notice a discrepancy between running funcnts on an +binary table file and running fundisp on the same file with the same filter. +For example, consider the following: + + fundisp test1.fits"[box(4219,3887,6,6,0)]" | wc + 8893 320148 3752846 + +Since fundisp has a 2-line header, there are actually 8891 photons +that pass the filter. But then run funtable and select only the +rows that pass this filter, placing them in a new file: + + ./funtable test1.fits"[box(4219,3887,6,6,0)]" test2.fits + +Now run funcnts using the original filter on the derived file: + + ./funcnts test2.fits "physical; box(4219,3887,6,6,0)" + + [... lot of processed output ...] + + # the following source and background components were used: + source region(s) + ---------------- + physical; box(4219,3887,6,6,0) + + reg counts pixels + ---- ------------ --------- + 1 7847.000 36 + +There are 1044 rows (events) that pass the row filter in fundisp (or +funtable) but fail to make it through funcnts. Why? + + +The reason can be traced to how analytic row filtering (fundisp, funtable) +differs from integerized pixel filtering(funcnts, funimage). Consider the +region: + + box(4219,3887,6,6,0) + +Analytically (i.e., using row filtering), positions will pass this +filter successfully if: + + 4216 <= x <= 4222 + 3884 <= y <= 3890 + +For example, photons with position values of x=4216.4 or y=3884.08 will pass. + + +Integerized image filtering is different in that the pixels that will +pass this filter have centers at: + + x = 4217, 4218, 4219, 4220, 4221, 4222 + y = 3885, 3886, 3887, 3888, 3889, 3890 + +Note that there are 6 pixels in each direction, as specified by the region. +That means that positions will pass the filter successfully if: + + 4217 <= (int)x <= 4222 + 3885 <= (int)y <= 3890 + +Photons with position values of x=4216.4 or y=3884.08 will NOT pass. + + +Note that the position values are integerized, in effect, binned into +image values. This means that x=4222.4 will pass this filter, but not +the analytic filter above. We do this to maintain the design goal that +either all counts in a pixel are included in an integerized filter, or +else none are included. + + +[It could be argued that the correct photon limits for floating point +row data really should be: + + 4216.5 <= x <= 4222.5 + 3884.5 <= y <= 3890.5 + +since each pixel extends for .5 on either side of the center. We chose +to the maintain integerized algorithm for all image-style filtering so +that funcnts would give the exact same results regardless of whether +a table or a derived non-blocked binned image is used.] + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + + +=cut diff --git a/doc/pod/regcoords.pod b/doc/pod/regcoords.pod new file mode 100644 index 0000000..a026a5c --- /dev/null +++ b/doc/pod/regcoords.pod @@ -0,0 +1,247 @@ +=pod + +=head1 NAME + + + +B + + + +=head1 SYNOPSIS + + + + + +This document describes the specification of coordinate systems, and the +interpretation of coordinate values, for spatial region filtering. + + + +=head1 DESCRIPTION + + + +B + +The default coordinate system for regions is PHYSICAL, which means +that region position and size values are taken from the original +data. (Note that this is a change from the original IRAF/PROS +implementation, in which the IMAGE coordinate system was the default.) +PHYSICAL coordinates always refer to pixel positions on the original +image (using IRAF LTM and LTV keywords). With PHYSICAL coordinates, +if a set of coordinates specifies the position of an object in an +original FITS file, the same coordinates will specify the same object +in any FITS derived from the original. Physical coordinates are +invariant with blocking of FITS files or taking sections of images, +even when a blocked section is written to a new file. + + +Thus, although a value in pixels refers, by default, to the PHYSICAL +coordinate system, you may specify that position values refer to the +image coordinate system using the B or B +properties commands: + + + global coordsys image + circle 512 512 100 + + +The B command changes the coordinate system for all +regions that follow, while the B command changes the +coordinate system only for the region immediately following: + + local coordsys image + circle 512 512 100 + circle 1024 1024 200 + +This changes the coordinate system only for the region that follows. +In the above example, the second region uses the global coordinate +system (PHYSICAL by default). + + +B + +If World Coordinate System information is contained in the data file +being filtered, it also is possible to define regions using a sky +coordinate system. Supported systems include: + + + name description + ---- ----------- + PHYSICAL pixel coords of original file using LTM/LTV + IMAGE pixel coords of current file + FK4, B1950 sky coordinate systems + FK5, J2000 sky coordinate systems + GALACTIC sky coordinate systems + ECLIPTIC sky coordinate systems + ICRS currently same as J2000 + LINEAR linear wcs as defined in file + + +In addition, two mosaic coordinate systems have been defined that +utilize the (evolving) IRAF mosaic keywords: + + + name description + ---- ----------- + AMPLIFIER mosaic coords of original file using ATM/ATV + DETECTOR mosaic coords of original file using DTM/DTV + +Again, to use one of these coordinate systems, the B or +B properties commands are used: + + + global coordsys galactic + + +B + +In addition to pixels, positional values in a WCS-enabled region can +be specified using sexagesimal or degrees format: + + + position arguments description + ------------------ ----------- + [num] context-dependent (see below) + [num]d degrees + [num]r radians + [num]p physical pixels + [num]i image pixels + [num]:[num]:[num] hms for 'odd' position arguments + [num]:[num]:[num] dms for 'even' position arguments + [num]h[num]m[num]s explicit hms + [num]d[num]m[num]s explicit dms + + +If ':' is used as sexagesimal separator, the value is considered to be +specifying hours/minutes/seconds if it is the first argument of a +positional pair, and degrees/minutes/seconds for the second argument +of a pair (except for galactic coordinates, which always use degrees): + + + argument description + ----------- ----------- + 10:20:30.0 10 hours, 20 minutes, 30 seconds for 1st positional argument + 10 degrees, 20 minutes, 30 seconds for 2nd positional argument + 10h20m30.0 10 hours, 20 minutes, 30 seconds + 10d20m30.0 10 degrees, 20 minutes, 30 seconds + 10.20d 10.2 degrees + + +Similarly, the units of size values are defined by the formating +character(s) attached to a number: + + + size arguments description + -------------- ----------- + [num] context-dependent (see below) + [num]" arc seconds + [num]' arc minutes + [num]d degrees + [num]r radians + [num]p physical pixels + [num]i image pixels + + +For example: + + argument description + ----------- ----------- + 10 ten pixels + 10' ten minutes of arc + 10" ten seconds of arc + 10d ten degrees + 10p ten pixels + 0.5r half of a radian + + + +An example of using sky coordinate systems follows: + + + global coordsys B1950 + -box 175.54d 20.01156d 10' 10' + local coordsys J2000 + pie 179.57d 22.4d 0 360 n=4 && annulus 179.57d 22.4d 3' 24' n=5 + + +At the FK4 1950 coordinates 175.54d RA, 20.01156d DEC exclude a 10 +minute by 10 minute box. Then at the FK5 2000 coordinates 179.57d RA +22.4d DEC draw a radial profile regions pattern with 4 quadrants and 5 +annuli ranging from 3 minutes to 24 minutes in diameter. In this +example, the default coordinate system is overridden by the commands +in the regions spec. + +B + + +When a "pure number" (i.e. one without a format directive such as 'd' +for 'degrees') is specified as a position or size, its interpretation +depends on the context defined by the 'coordsys' keyword. In general, +the rule is: + + +All pure numbers have implied units corresponding to the current +coordinate system. + + +If no coordinate system is explicitly specified, the default system is +implicitly assumed to be PHYSICAL. In practice this means that for +IMAGE and PHYSICAL systems, pure numbers are pixels. Otherwise, +for all systems other than LINEAR, pure numbers are degrees. For +LINEAR systems, pure numbers are in the units of the linear system. +This rule covers both positions and sizes. + + +As a corollary, when a sky-formatted number is used with the IMAGE +or PHYSICAL coordinate system (which includes the default case of no +coordsys being specified), the formatted number is assumed to be in +the units of the WCS contained in the current file. If no sky WCS is +specified, an error results. + + +Examples: + + + circle(512,512,10) + ellipse 202.44382d 47.181656d 0.01d 0.02d + + + +In the absence of a specified coordinate system, the circle uses the +default PHYSICAL units of pixels, while the ellipse explicitly uses degrees, +presumably to go with the WCS in the current file. + + + global coordsys=fk5 + global color=green font="system 10 normal" + circle 202.44382 47.181656 0.01 + circle 202.44382 47.181656 10p + ellipse(512p,512p,10p,15p,20) + + + + +Here, the circles use the FK5 units of degrees (except for the +explicit use of pixels in the second radius), while the ellipse +explicitly specifies pixels. The ellipse angle is in degrees. + + +Note that Chandra data format appears to use "coordsys=physical" +implicitly. Therefore, for most Chandra applications, valid regions +can be generated safely by asking ds9 to save/display regions in +pixels using the PHYSICAL coordsys. + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + + +=cut diff --git a/doc/pod/regdiff.pod b/doc/pod/regdiff.pod new file mode 100644 index 0000000..e1c38ca --- /dev/null +++ b/doc/pod/regdiff.pod @@ -0,0 +1,99 @@ +=pod + +=head1 NAME + + + +B + + + +=head1 SYNOPSIS + + + + +Describes the differences between Funtools/ds9 regions and the old IRAF/PROS +regions. + + + +=head1 DESCRIPTION + + + + + +We have tried to make Funtools regions compatible with their +predecessor, IRAF/PROS regions. For simple regions and simple boolean +algebra between regions, there should be no difference between the two +implementations. The following is a list of differences and +incompatibilities between the two: + + + +=over 4 + + + + + + +=item * + +If a pixel is covered by two different regions expressions, +Funtools assigns the mask value of the B region that +contains that pixel. That is, successive regions B +overwrite previous regions in the mask, as was the case with the +original PROS regions. This means that one must define overlapping +regions in the reverse order in which they were defined in PROS. If +region N is fully contained within region M, then N should be defined +B M, or else it will be "covered up" by the latter. This +change is necessitated by the use of optimized filter compilation, i.e., +Funtools only tests individual regions until a proper match is made. + + + + +=item * + +The B region has replaced the old PROS syntax in which +a B accelerator was combined with an B accelerator +using B. That is, + + ANNULUS(20,20,0,15,n=4) & PIE(20,20,0,360,n=3) + +has been replaced by: + + PANDA(20,20,0,360,3,0,15,4) + +The PROS syntax was inconsistent with the meaning of the B operator. + + + + +=item * + +The meaning of pure numbers (i.e., without format specifiers) in +regions has been clarified, as has the syntax for specifying coordinate +systems. See the general discussion on +Spatial Region Filtering +for more information. + + + +=back + + + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + + +=cut diff --git a/doc/pod/reggeometry.pod b/doc/pod/reggeometry.pod new file mode 100644 index 0000000..0d442d5 --- /dev/null +++ b/doc/pod/reggeometry.pod @@ -0,0 +1,1156 @@ +=pod + +=head1 NAME + + + +B + + + +=head1 SYNOPSIS + + + + + +This document describes the geometry of regions available for spatial +filtering in IRAF/PROS analysis. + + + +=head1 DESCRIPTION + + + +B + +Several geometric shapes are used to describe regions. The valid +shapes are: + + + shape: arguments: + ----- ---------------------------------------- + ANNULUS xcenter ycenter inner_radius outer_radius + BOX xcenter ycenter xwidth yheight (angle) + CIRCLE xcenter ycenter radius + ELLIPSE xcenter ycenter xwidth yheight (angle) + FIELD none + LINE x1 y1 x2 y2 + PIE xcenter ycenter angle1 angle2 + POINT x1 y1 + POLYGON x1 y1 x2 y2 ... xn yn + + + +All arguments are real values; integer values are automatically +converted to real where necessary. All angles are in degrees and +specify angles that run counter-clockwise from the positive y-axis. + + +Shapes can be specified using "command" syntax: + + [shape] arg1 arg2 ... + +or using "routine" syntax: + + [shape](arg1, arg2, ...) + +or by any combination of the these. (Of course, the parentheses must +balance and there cannot be more commas than necessary.) The shape +keywords are case-insensitive. Furthermore, any shape can be +specified by a three-character unique abbreviation. For example, one +can specify three circular regions as: + + + "foo.fits[CIRCLE 512 512 50;CIR(128 128, 10);cir(650,650,20)]" + + +(Quotes generally are required to protect the region descriptor +from being processed by the Unix shell.) + + + + +The B shape specifies annuli, centered at xcenter, +ycenter, with inner and outer radii (r1, r2). For example, + + ANNULUS 25 25 5 10 + +specifies an annulus centered at 25.0 25.0 with an inner radius of 5.0 and +an outer radius of 10. Assuming (as will be done for all examples in this +document, unless otherwise noted) this shape is used in a mask of size 40x40, +it will look like this: + + 1234567890123456789012345678901234567890 + ---------------------------------------- + 40:........................................ + 39:........................................ + 38:........................................ + 37:........................................ + 36:........................................ + 35:........................................ + 34:....................111111111........... + 33:...................11111111111.......... + 32:.................111111111111111........ + 31:.................111111111111111........ + 30:................11111111111111111....... + 29:...............1111111.....1111111...... + 28:...............111111.......111111...... + 27:...............11111.........11111...... + 26:...............11111.........11111...... + 25:...............11111.........11111...... + 24:...............11111.........11111...... + 23:...............11111.........11111...... + 22:...............111111.......111111...... + 21:...............1111111.....1111111...... + 20:................11111111111111111....... + 19:.................111111111111111........ + 18:.................111111111111111........ + 17:...................11111111111.......... + 16:....................111111111........... + 15:........................................ + 14:........................................ + 13:........................................ + 12:........................................ + 11:........................................ + 10:........................................ + 9:........................................ + 8:........................................ + 7:........................................ + 6:........................................ + 5:........................................ + 4:........................................ + 3:........................................ + 2:........................................ + 1:........................................ + + + + + +The B shape specifies an orthogonally oriented box, +centered at xcenter, ycenter, of size xwidth, yheight. It requires four +arguments and accepts an optional fifth argument to specify a rotation angle. +When the rotation angle is specified (in degrees), the box is rotated by +an angle that runs counter-clockwise from the positive y-axis. + + +The B shape specifies a rotated box, centered at +xcenter, ycenter, of size xwidth, yheight. The box is rotated by an angle +specified in degrees that runs counter-clockwise from the positive y-axis. +If the angle argument is omitted, it defaults to 0. + + + + +The B shape specifies a circle, centered at xcenter, +ycenter, of radius r. It requires three arguments. + + + + +The B shape specifies an ellipse, centered at +xcenter, ycenter, with y-axis width a and the y-axis length b defined such +that: + + x**2/a**2 + y**2/b**2 = 1 + +Note that a can be less than, equal to, or greater than b. The ellipse +is rotated the specified number of degrees. The rotation is done according +to astronomical convention, counter-clockwise from the positive y-axis. +An ellipse defined by: + + ELLIPSE 20 20 5 10 45 + +will look like this: + + 1234567890123456789012345678901234567890 + ---------------------------------------- + 40:........................................ + 39:........................................ + 38:........................................ + 37:........................................ + 36:........................................ + 35:........................................ + 34:........................................ + 33:........................................ + 32:........................................ + 31:........................................ + 30:........................................ + 29:........................................ + 28:........................................ + 27:............111111...................... + 26:............11111111.................... + 25:............111111111................... + 24:............11111111111................. + 23:............111111111111................ + 22:............111111111111................ + 21:.............111111111111............... + 20:.............1111111111111.............. + 19:..............111111111111.............. + 18:...............111111111111............. + 17:...............111111111111............. + 16:................11111111111............. + 15:..................111111111............. + 14:...................11111111............. + 13:.....................111111............. + 12:........................................ + 11:........................................ + 10:........................................ + 9:........................................ + 8:........................................ + 7:........................................ + 6:........................................ + 5:........................................ + 4:........................................ + 3:........................................ + 2:........................................ + 1:........................................ + + + + + + +The B shape specifies the entire field as a +region. It is not usually specified explicitly, but is used implicitly in the +case where no regions are specified, that is, in cases where either a null +string or some abbreviation of the string "none" is input. +B takes no arguments. + + + + +The B shape specifies an angular wedge of the entire field, +centered at xcenter, ycenter. The wedge runs between the two specified angles. +The angles are given in degrees, running counter-clockwise from the positive +x-axis. For example, + + PIE 20 20 90 180 + +defines a region from 90 degrees to 180 degrees, i.e., quadrant 2 of the +Cartesian plane. The display of such a region looks like this: + + + 1234567890123456789012345678901234567890 + ---------------------------------------- + 40:11111111111111111111.................... + 39:11111111111111111111.................... + 38:11111111111111111111.................... + 37:11111111111111111111.................... + 36:11111111111111111111.................... + 35:11111111111111111111.................... + 34:11111111111111111111.................... + 33:11111111111111111111.................... + 32:11111111111111111111.................... + 31:11111111111111111111.................... + 30:11111111111111111111.................... + 29:11111111111111111111.................... + 28:11111111111111111111.................... + 27:11111111111111111111.................... + 26:11111111111111111111.................... + 25:11111111111111111111.................... + 24:11111111111111111111.................... + 23:11111111111111111111.................... + 22:11111111111111111111.................... + 21:11111111111111111111.................... + 20:........................................ + 19:........................................ + 18:........................................ + 17:........................................ + 16:........................................ + 15:........................................ + 14:........................................ + 13:........................................ + 12:........................................ + 11:........................................ + 10:........................................ + 9:........................................ + 8:........................................ + 7:........................................ + 6:........................................ + 5:........................................ + 4:........................................ + 3:........................................ + 2:........................................ + 1:........................................ + +The pie slice specified is always a counter-clockwise sweep between +the angles, starting at the first angle and ending at the second. Thus: + + PIE 10 15 30 60 + +describes a 30 degree sweep from 2 o'clock to 1 o'clock, while: + + PIE 10 15 60 30 + +describes a 330 degree counter-clockwise sweep from 1 o'clock to 2 o'clock +passing through 12 o'clock (0 degrees). Note in both of these examples that +the center of the slice can be anywhere on the plane. The second mask looks +like this: + + + 1234567890123456789012345678901234567890 + ---------------------------------------- + 40:111111111111111111111111................ + 39:11111111111111111111111................. + 38:11111111111111111111111................. + 37:1111111111111111111111.................. + 36:1111111111111111111111.................. + 35:111111111111111111111................... + 34:11111111111111111111.................... + 33:11111111111111111111.................... + 32:1111111111111111111....................1 + 31:1111111111111111111..................111 + 30:111111111111111111.................11111 + 29:111111111111111111................111111 + 28:11111111111111111...............11111111 + 27:1111111111111111..............1111111111 + 26:1111111111111111.............11111111111 + 25:111111111111111............1111111111111 + 24:111111111111111..........111111111111111 + 23:11111111111111.........11111111111111111 + 22:11111111111111........111111111111111111 + 21:1111111111111.......11111111111111111111 + 20:111111111111......1111111111111111111111 + 19:111111111111....111111111111111111111111 + 18:11111111111....1111111111111111111111111 + 17:11111111111..111111111111111111111111111 + 16:1111111111.11111111111111111111111111111 + 15:1111111111111111111111111111111111111111 + 14:1111111111111111111111111111111111111111 + 13:1111111111111111111111111111111111111111 + 12:1111111111111111111111111111111111111111 + 11:1111111111111111111111111111111111111111 + 10:1111111111111111111111111111111111111111 + 9:1111111111111111111111111111111111111111 + 8:1111111111111111111111111111111111111111 + 7:1111111111111111111111111111111111111111 + 6:1111111111111111111111111111111111111111 + 5:1111111111111111111111111111111111111111 + 4:1111111111111111111111111111111111111111 + 3:1111111111111111111111111111111111111111 + 2:1111111111111111111111111111111111111111 + 1:1111111111111111111111111111111111111111 + +The pie slice goes to the edge of the field. To limit its scope, pie +usually is is combined with other shapes, such as circles and annuli, +using boolean operations. (See below and in "help regalgebra"). + + +Pie Performance Notes: + +Pie region processing time is proportional to the size of the image, +and not the size of the region. This is because the pie shape is the +only infinite length shape, and we essentially must check all y rows +for inclusion (unlike other regions, where the y limits can be +calculated beforehand). Thus, pie can run very slowly on large images. +In particular, it will run MUCH more slowly than the panda shape in +image-based region operations (such as funcnts). We recommend use of +panda over pie where ever possible. + + +If you must use pie, always try to put it last in a boolean && +expression. The reason for this is that the filter code is optimized +to exit as soon as the result is know. Since pie is the slowest +region, it is better to avoid executing it if another region can decide +the result. Consider, for example, the difference in time required to +process a Chandra ACIS file when a pie and circle are combined in +two different orders: + + + time ./funcnts nacis.fits "circle 4096 4096 100 && pie 4096 4096 10 78" +2.87u 0.38s 0:35.08 9.2% + + time ./funcnts nacis.fits "pie 4096 4096 10 78 && circle 4096 4096 100 " +89.73u 0.36s 1:03.50 141.8% + + + +Black-magic performance note: + + +Panda region processing uses a B pie region instead of +the normal pie region when combining its annulus and pie shapes. This +B shape differs from the normal pie in that it utilizes the +y limits from the previous region with which it is combined. In a +panda shape, which is a series of annuli combined with pies, the +processing time is thus reduced to that of the annuli. + + +You can use the qtpie shape instead of pie in cases where you are +combining pie with another shape using the && operator. This will +cause the pie limits to be set using limits from the other shape, and +will speed up the processing considerably. For example, the above +execution of funcnts can be improved considerably using this technique: + + + time ./funcnts nacis.fits "circle 4096 4096 100 && qtpie 4096 4096 10 78" +4.66u 0.33s 0:05.87 85.0% + + + +We emphasize that this is a quasi-documented feature and might change in +the future. The qtpie shape is not recognized by ds9 or other programs. + + + + +The B shape allows single pixels in a line between (x1,y1) and +(x2,y2) to be included or excluded. For example: + + LINE (5,6, 24,25) + +displays as: + + 1234567890123456789012345678901234567890 + ---------------------------------------- + 40:........................................ + 39:........................................ + 38:........................................ + 37:........................................ + 36:........................................ + 35:........................................ + 34:........................................ + 33:........................................ + 32:........................................ + 31:........................................ + 30:........................................ + 29:........................................ + 28:........................................ + 27:........................................ + 26:........................................ + 25:.......................1................ + 24:......................1................. + 23:.....................1.................. + 22:....................1................... + 21:...................1.................... + 20:..................1..................... + 19:.................1...................... + 18:................1....................... + 17:...............1........................ + 16:..............1......................... + 15:.............1.......................... + 14:............1........................... + 13:...........1............................ + 12:..........1............................. + 11:.........1.............................. + 10:........1............................... + 9:.......1................................ + 8:......1................................. + 7:.....1.................................. + 6:....1................................... + 5:........................................ + 4:........................................ + 3:........................................ + 2:........................................ + 1:........................................ + + + + + +The B shape allows single pixels to be included or +excluded. Although the (x,y) values are real numbers, they are truncated +to integer and the corresponding pixel is included or excluded, as specified. + + +Several points can be put in one region declaration; unlike the +original IRAF implementation, each now is given a different region mask value. +This makes it easier, for example, for funcnts to determine the number of +photons in the individual pixels. For example, + + POINT (5,6, 10,11, 20,20, 35,30) + +will give the different region mask values to all four points, as shown below: + + + 1234567890123456789012345678901234567890 + ---------------------------------------- + 40:........................................ + 39:........................................ + 38:........................................ + 37:........................................ + 36:........................................ + 35:........................................ + 34:........................................ + 33:........................................ + 32:........................................ + 31:........................................ + 30:..................................4..... + 29:........................................ + 28:........................................ + 27:........................................ + 26:........................................ + 25:........................................ + 24:........................................ + 23:........................................ + 22:........................................ + 21:........................................ + 20:...................3.................... + 19:........................................ + 18:........................................ + 17:........................................ + 16:........................................ + 15:........................................ + 14:........................................ + 13:........................................ + 12:........................................ + 11:.........2.............................. + 10:........................................ + 9:........................................ + 8:........................................ + 7:........................................ + 6:....1................................... + 5:........................................ + 4:........................................ + 3:........................................ + 2:........................................ + 1:........................................ + + + + + +The B shape specifies a polygon with vertices +(x1, y1) ... (xn, yn). The polygon is closed automatically: one should +not specify the last vertex to be the same as the first. Any number of +vertices are allowed. For example, the following polygon defines a +right triangle as shown below: + + POLYGON (10,10, 10,30, 30,30) + + +looks like this: + + + 1234567890123456789012345678901234567890 + ---------------------------------------- + 40:........................................ + 39:........................................ + 38:........................................ + 37:........................................ + 36:........................................ + 35:........................................ + 34:........................................ + 33:........................................ + 32:........................................ + 31:........................................ + 30:..........11111111111111111111.......... + 29:..........1111111111111111111........... + 28:..........111111111111111111............ + 27:..........11111111111111111............. + 26:..........1111111111111111.............. + 25:..........111111111111111............... + 24:..........11111111111111................ + 23:..........1111111111111................. + 22:..........111111111111.................. + 21:..........11111111111................... + 20:..........1111111111.................... + 19:..........111111111..................... + 18:..........11111111...................... + 17:..........1111111....................... + 16:..........111111........................ + 15:..........11111......................... + 14:..........1111.......................... + 13:..........111........................... + 12:..........11............................ + 11:..........1............................. + 10:........................................ + 9:........................................ + 8:........................................ + 7:........................................ + 6:........................................ + 5:........................................ + 4:........................................ + 3:........................................ + 2:........................................ + 1:........................................ + +Note that polygons can get twisted upon themselves if edge lines +cross. Thus: + + POL (10,10, 20,20, 20,10, 10,20) + +will produce an area which is two triangles, like butterfly wings, as shown +below: + + + 1234567890123456789012345678901234567890 + ---------------------------------------- + 40:........................................ + 39:........................................ + 38:........................................ + 37:........................................ + 36:........................................ + 35:........................................ + 34:........................................ + 33:........................................ + 32:........................................ + 31:........................................ + 30:........................................ + 29:........................................ + 28:........................................ + 27:........................................ + 26:........................................ + 25:........................................ + 24:........................................ + 23:........................................ + 22:........................................ + 21:........................................ + 20:........................................ + 19:..........1........1.................... + 18:..........11......11.................... + 17:..........111....111.................... + 16:..........1111..1111.................... + 15:..........1111111111.................... + 14:..........1111..1111.................... + 13:..........111....111.................... + 12:..........11......11.................... + 11:..........1........1.................... + 10:........................................ + 9:........................................ + 8:........................................ + 7:........................................ + 6:........................................ + 5:........................................ + 4:........................................ + 3:........................................ + 2:........................................ + 1:........................................ + + + + + +The following are combinations of pie with different shapes +(called "panda" for "Pie AND Annulus") allow for easy specification of +radial sections: + + shape: arguments: + ----- --------- + PANDA xcen ycen ang1 ang2 nang irad orad nrad # circular + CPANDA xcen ycen ang1 ang2 nang irad orad nrad # circular + BPANDA xcen ycen ang1 ang2 nang xwlo yhlo xwhi yhhi nrad (ang) # box + EPANDA xcen ycen ang1 ang2 nang xwlo yhlo xwhi yhhi nrad (ang) # ellipse + + +The B (B

ies B Bnnuli) shape can be +used to create combinations of pie and annuli markers. It is analogous +to a Cartesian product on those shapes, i.e., the result is several +shapes generated by performing a boolean AND between pies and +annuli. Thus, the panda and cpanda specify combinations of annulus and +circle with pie, respectively and give identical results. The bpanda +combines box and pie, while epanda combines ellipse and pie. + + +Consider the example shown below: + + PANDA(20,20, 0,360,3, 0,15,4) + +Here, 3 pie slices centered at 20, 20 are combined with 4 annuli, also +centered at 20, 20. The result is a mask with 12 regions (displayed in +base 16 to save characters): + + 1234567890123456789012345678901234567890 + ---------------------------------------- + 40:........................................ + 39:........................................ + 38:........................................ + 37:........................................ + 36:........................................ + 35:........................................ + 34:..............44444444444............... + 33:............444444444444444............. + 32:...........88444444444444444............ + 31:.........888844443333344444444.......... + 30:........88888833333333333444444......... + 29:........88888733333333333344444......... + 28:.......8888877733333333333344444........ + 27:......888887777332222233333344444....... + 26:......888877777622222222333334444....... + 25:.....88887777766622222222333334444...... + 24:.....88887777666622222222233334444...... + 23:.....88887777666651111222233334444...... + 22:.....88877776666551111122223333444...... + 21:.....88877776666555111122223333444...... + 20:.....888777766665559999aaaabbbbccc...... + 19:.....888777766665559999aaaabbbbccc...... + 18:.....888777766665599999aaaabbbbccc...... + 17:.....88887777666659999aaaabbbbcccc...... + 16:.....888877776666aaaaaaaaabbbbcccc...... + 15:.....888877777666aaaaaaaabbbbbcccc...... + 14:......8888777776aaaaaaaabbbbbcccc....... + 13:......888887777bbaaaaabbbbbbccccc....... + 12:.......88888777bbbbbbbbbbbbccccc........ + 11:........888887bbbbbbbbbbbbccccc......... + 10:........888888bbbbbbbbbbbcccccc......... + 9:.........8888ccccbbbbbcccccccc.......... + 8:...........88ccccccccccccccc............ + 7:............ccccccccccccccc............. + 6:..............ccccccccccc............... + 5:........................................ + 4:........................................ + 3:........................................ + 2:........................................ + 1:........................................ + + + + + +Several regions with different mask values can be combined in the +same mask. This supports comparing data from the different regions. +(For information on how to combine different shapes into a single +region, see "help regalgebra".) For example, consider the following +set of regions: + + ANNULUS 25 25 5 10 + ELLIPSE 20 20 5 10 315 + BOX 15 15 5 10 + +The resulting mask will look as follows: + + + 1234567890123456789012345678901234567890 + ---------------------------------------- + 40:........................................ + 39:........................................ + 38:........................................ + 37:........................................ + 36:........................................ + 35:........................................ + 34:....................111111111........... + 33:...................11111111111.......... + 32:.................111111111111111........ + 31:.................111111111111111........ + 30:................11111111111111111....... + 29:...............1111111.....1111111...... + 28:...............111111.......111111...... + 27:...............11111.222222..11111...... + 26:...............111112222222..11111...... + 25:...............111112222222..11111...... + 24:...............111112222222..11111...... + 23:...............111112222222..11111...... + 22:...............111111222222.111111...... + 21:..............211111112222.1111111...... + 20:............322211111111111111111....... + 19:............32222111111111111111........ + 18:............22222111111111111111........ + 17:............222222211111111111.......... + 16:............22222222111111111........... + 15:............222222222................... + 14:............22222222.................... + 13:............222222...................... + 12:............33333....................... + 11:............33333....................... + 10:........................................ + 9:........................................ + 8:........................................ + 7:........................................ + 6:........................................ + 5:........................................ + 4:........................................ + 3:........................................ + 2:........................................ + 1:........................................ + +Note that when a pixel is in 2 or more regions, it is arbitrarily +assigned to a one of the regions in question (often based on how a +give C compiler optimizes boolean expressions). + + +B + + +Two types of \fBaccelerators, to simplify region specification, +are provided as natural extensions to the ways shapes are described. +These are: extended lists of parameters, specifying multiple regions, +valid for annulus, box, circle, ellipse, pie, and points; and +B, valid for annulus, box, circle, ellipse, and pie (not +point). In both cases, one specification is used to define several +different regions, that is, to define shapes with different mask +values in the region mask. + + +The following regions accept B syntax: + + shape arguments + ----- ------------------------------------------ + ANNULUS xcenter ycenter radius1 radius2 ... radiusn + ANNULUS xcenter ycenter inner_radius outer_radius n=[number] + BOX xcenter ycenter xw1 yh1 xw2 yh2 ... xwn yhn (angle) + BOX xcenter ycenter xwlo yhlo xwhi yhhi n=[number] (angle) + CIRCLE xcenter ycenter r1 r2 ... rn # same as annulus + CIRCLE xcenter ycenter rinner router n=[number] # same as annulus + ELLIPSE xcenter ycenter xw1 yh1 xw2 yh2 ... xwn yhn (angle) + ELLIPSE xcenter ycenter xwlo yhlo xwhi yhhi n=[number] (angle) + PIE xcenter ycenter angle1 angle2 (angle3) (angle4) (angle5) ... + PIE xcenter ycenter angle1 angle2 (n=[number]) + POINT x1 y1 x2 y2 ... xn yn + +Note that the circle accelerators are simply aliases for the annulus +accelerators. + + +For example, several annuli at the same center can be specified in one +region expression by specifying more than two radii. If B +radii are specified, then B-1 annuli result, with the outer +radius of each preceding annulus being the inner radius of the +succeeding annulus. Each annulus is considered a separate region, and +is given a separate mask value. For example, + + ANNULUS 20 20 0 2 5 10 15 20 + +specifies five different annuli centered at 20 20, and is equivalent to: + + ANNULUS 20.0 20.0 0 2 + ANNULUS 20.0 20.0 2 5 + ANNULUS 20.0 20.0 5 10 + ANNULUS 20.0 20.0 10 15 + ANNULUS 20.0 20.0 15 20 + +The mask is shown below: + + + 1234567890123456789012345678901234567890 + ---------------------------------------- + 40:........................................ + 39:.............5555555555555.............. + 38:...........55555555555555555............ + 37:.........555555555555555555555.......... + 36:........55555555555555555555555......... + 35:......555555555555555555555555555....... + 34:.....55555555544444444444555555555...... + 33:....5555555544444444444444455555555..... + 32:....5555555444444444444444445555555..... + 31:...555555444444444444444444444555555.... + 30:..55555544444444444444444444444555555... + 29:..55555544444443333333334444444555555... + 28:.5555554444444333333333334444444555555.. + 27:.5555544444433333333333333344444455555.. + 26:555555444444333333333333333444444555555. + 25:555554444443333333333333333344444455555. + 24:555554444433333332222233333334444455555. + 23:555554444433333322222223333334444455555. + 22:555554444433333222222222333334444455555. + 21:555554444433333222111222333334444455555. + 20:555554444433333222111222333334444455555. + 19:555554444433333222111222333334444455555. + 18:555554444433333222222222333334444455555. + 17:555554444433333322222223333334444455555. + 16:555554444433333332222233333334444455555. + 15:555554444443333333333333333344444455555. + 14:555555444444333333333333333444444555555. + 13:.5555544444433333333333333344444455555.. + 12:.5555554444444333333333334444444555555.. + 11:..55555544444443333333334444444555555... + 10:..55555544444444444444444444444555555... + 9:...555555444444444444444444444555555.... + 8:....5555555444444444444444445555555..... + 7:....5555555544444444444444455555555..... + 6:.....55555555544444444444555555555...... + 5:......555555555555555555555555555....... + 4:........55555555555555555555555......... + 3:.........555555555555555555555.......... + 2:...........55555555555555555............ + 1:.............5555555555555.............. + + + +For boxes and ellipses, if an odd number of arguments is specified, +then the last argument is assumed to be an angle. Otherwise, the +angle is assumed to be zero. For example: + + ellipse 20 20 3 5 6 10 9 15 12 20 45 + +specifies an 3 ellipses at a 45 degree angle: + + 1234567890123456789012345678901234567890 + ---------------------------------------- + 40:........................................ + 39:........................................ + 38:........................................ + 37:........................................ + 36:........33333333........................ + 35:......333333333333...................... + 34:.....3333333333333333................... + 33:....333333333333333333.................. + 32:....33333332222233333333................ + 31:...3333332222222222333333............... + 30:...33333222222222222233333.............. + 29:...333332222222222222223333............. + 28:...3333222222211112222223333............ + 27:...33332222211111111222223333........... + 26:...333322222111111111122223333.......... + 25:...3333222211111111111122223333......... + 24:....3332222111111..1111122223333........ + 23:....333322211111.....11112222333........ + 22:....33332222111.......11112223333....... + 21:.....33322221111.......11122223333...... + 20:.....33332221111.......11112223333...... + 19:.....33332222111.......11112222333...... + 18:......33332221111.......11122223333..... + 17:.......33322221111.....111112223333..... + 16:.......3333222211111..1111112222333..... + 15:........3333222211111111111122223333.... + 14:.........333322221111111111222223333.... + 13:..........33332222211111111222223333.... + 12:...........3333222222111122222223333.... + 11:............333322222222222222233333.... + 10:.............33333222222222222233333.... + 9:..............3333332222222222333333.... + 8:...............33333333222223333333..... + 7:.................333333333333333333..... + 6:..................3333333333333333...... + 5:.....................333333333333....... + 4:.......................33333333......... + 3:........................................ + 2:........................................ + 1:........................................ + +Note in the above example that the lower limit is not part of the +region for boxes, circles, and ellipses. This makes circles and annuli +equivalent, i.e.: + + circle 20 20 5 10 15 20 + annulus 20 20 5 10 15 20 + +both give the following region mask: + + 1234567890123456789012345678901234567890 + ---------------------------------------- + 40:........................................ + 39:.............3333333333333.............. + 38:...........33333333333333333............ + 37:.........333333333333333333333.......... + 36:........33333333333333333333333......... + 35:......333333333333333333333333333....... + 34:.....33333333322222222222333333333...... + 33:....3333333322222222222222233333333..... + 32:....3333333222222222222222223333333..... + 31:...333333222222222222222222222333333.... + 30:..33333322222222222222222222222333333... + 29:..33333322222221111111112222222333333... + 28:.3333332222222111111111112222222333333.. + 27:.3333322222211111111111111122222233333.. + 26:333333222222111111111111111222222333333. + 25:333332222221111111111111111122222233333. + 24:33333222221111111.....11111112222233333. + 23:3333322222111111.......1111112222233333. + 22:333332222211111.........111112222233333. + 21:333332222211111.........111112222233333. + 20:333332222211111.........111112222233333. + 19:333332222211111.........111112222233333. + 18:333332222211111.........111112222233333. + 17:3333322222111111.......1111112222233333. + 16:33333222221111111.....11111112222233333. + 15:333332222221111111111111111122222233333. + 14:333333222222111111111111111222222333333. + 13:.3333322222211111111111111122222233333.. + 12:.3333332222222111111111112222222333333.. + 11:..33333322222221111111112222222333333... + 10:..33333322222222222222222222222333333... + 9:...333333222222222222222222222333333.... + 8:....3333333222222222222222223333333..... + 7:....3333333322222222222222233333333..... + 6:.....33333333322222222222333333333...... + 5:......333333333333333333333333333....... + 4:........33333333333333333333333......... + 3:.........333333333333333333333.......... + 2:...........33333333333333333............ + 1:.............3333333333333.............. + + + + +As a final example, specifying several angles in one pie slice +expression is equivalent to specifying several separate slices with +the same center. As with the annulus, if B angles are +specified, then B-1 slices result, with the ending angle of +each preceding slice being the starting angle of the succeeding slice. +Each slice is considered a separate region, and is given a separate +mask value. For example, + + PIE 12 12 315 45 115 270 + +specifies three regions as shown below: + + 1234567890123456789012345678901234567890 + ---------------------------------------- + 40:2222222222222222222222222222222222222222 + 39:2222222222222222222222222222222222222221 + 38:2222222222222222222222222222222222222211 + 37:2222222222222222222222222222222222222111 + 36:2222222222222222222222222222222222221111 + 35:3222222222222222222222222222222222211111 + 34:3222222222222222222222222222222222111111 + 33:3322222222222222222222222222222221111111 + 32:3322222222222222222222222222222211111111 + 31:3332222222222222222222222222222111111111 + 30:3332222222222222222222222222221111111111 + 29:3333222222222222222222222222211111111111 + 28:3333222222222222222222222222111111111111 + 27:3333322222222222222222222221111111111111 + 26:3333322222222222222222222211111111111111 + 25:3333322222222222222222222111111111111111 + 24:3333332222222222222222221111111111111111 + 23:3333332222222222222222211111111111111111 + 22:3333333222222222222222111111111111111111 + 21:3333333222222222222221111111111111111111 + 20:3333333322222222222211111111111111111111 + 19:3333333322222222222111111111111111111111 + 18:3333333332222222221111111111111111111111 + 17:3333333332222222211111111111111111111111 + 16:3333333333222222111111111111111111111111 + 15:3333333333222221111111111111111111111111 + 14:3333333333322211111111111111111111111111 + 13:3333333333322111111111111111111111111111 + 12:33333333333.1111111111111111111111111111 + 11:3333333333331111111111111111111111111111 + 10:333333333333.111111111111111111111111111 + 9:333333333333..11111111111111111111111111 + 8:333333333333...1111111111111111111111111 + 7:333333333333....111111111111111111111111 + 6:333333333333.....11111111111111111111111 + 5:333333333333......1111111111111111111111 + 4:333333333333.......111111111111111111111 + 3:333333333333........11111111111111111111 + 2:333333333333.........1111111111111111111 + 1:333333333333..........111111111111111111 + + + +The annulus, box, circle, ellipse, and pie shapes also accept an +B syntax for specifying multiple regions. The +Bsyntax interprets the previous (shape-dependent) +arguments as lower and upper limits for the region and creates n +shapes with evenly spaced boundaries. For example, if B +is specified in an annulus, the two immediately preceding radii +(B and B) are divided into B annuli, such +that the inner radius of the first is B and the outer radius +of the last is B. For example, + + ANNULUS 20 20 5 20 n=3 + +is equivalent to: + + ANNULUS 20 20 5 10 15 20 + +If this syntax is used with an ellipse or box, then the two preceding +pairs of values are taken to be lower and upper limits for a set of +ellipses or boxes. A circle uses the two preceding arguments for upper +and lower radii. For pie, the two preceding angles are divided into n +wedges such that the starting angle of the first is the lower bound +and the ending angle of the last is the upper bound. In all cases, +the B syntax allows any single alphabetic character +before the "=", i.e, i=3, z=3, etc. are all equivalent. + + +Also note that for boxes and ellipses, the optional angle argument is +always specified after the B syntax. For example: + + ellipse 20 20 4 6 16 24 n=3 45 + +specifies 3 elliptical regions at an angle of 45 degrees: + + + 1234567890123456789012345678901234567890 + ---------------------------------------- + 40:........33333333........................ + 39:.....33333333333333..................... + 38:....33333333333333333................... + 37:...33333333333333333333................. + 36:..33333333333333333333333............... + 35:.3333333333222223333333333.............. + 34:3333333322222222222233333333............ + 33:33333332222222222222223333333........... + 32:333333222222222222222222333333.......... + 31:3333322222222222222222222333333......... + 30:33333222222222111122222222333333........ + 29:333332222222111111112222222333333....... + 28:3333222222211111111111222222333333...... + 27:3333222222111111111111112222233333...... + 26:33332222221111111111111112222233333..... + 25:33332222211111111.111111112222233333.... + 24:333322222111111......111111222223333.... + 23:333322222111111.......111112222233333... + 22:33333222221111.........11111222223333... + 21:333332222211111.........11112222233333.. + 20:.33332222211111.........11111222223333.. + 19:.33333222221111.........111112222233333. + 18:..33332222211111.........11112222233333. + 17:..333332222211111.......111111222233333. + 16:...333322222111111......111111222223333. + 15:...333332222211111111.111111112222233333 + 14:....333332222211111111111111122222233333 + 13:.....33333222221111111111111122222233333 + 12:.....33333322222211111111111222222233333 + 11:......3333332222222111111112222222333333 + 10:.......333333222222221111222222222333333 + 9:........33333322222222222222222222333333 + 8:.........333333222222222222222222333333. + 7:..........33333332222222222222223333333. + 6:...........3333333322222222222233333333. + 5:.............3333333333222223333333333.. + 4:..............33333333333333333333333... + 3:................33333333333333333333.... + 2:..................33333333333333333..... + 1:....................33333333333333...... + + + +Both the variable argument syntax and the B syntax must +occur alone in a region descriptor (aside from the optional angle for +boxes and ellipses). They cannot be combined. Thus, it is not valid +to precede or follow an B accelerator with more angles or +radii, as in this example: + + # INVALID -- one too many angles before a=5 ... + # and no angles are allowed after a=5 + PIE 12 12 10 25 50 a=5 85 135 + +Instead, use three separate specifications, such as: + + PIE 12 12 10 25 + PIE 12 12 25 50 a=5 + PIE 12 12 85 135 + +The original (IRAF) implementation of region filtering permitted this +looser syntax, but we found it caused more confusion than it was worth +and therefore removed it. + + +NB: Accelerators may be combined with other shapes in a boolean +expression in any order. (This is a change starting with funtools +v1.1.1. Prior to this release, the accelerator shape had to be +specified last). The actual region mask id values returned depend on the +order in which the shapes are specified, although the total number of +pixels or rows that pass the filter will be consistent. For this +reason, use of accelerators in boolean expressions is discouraged in +programs such as funcnts, where region mask id values are used +to count events or image pixels. + + +[All region masks displayed in this document were generated using the +B routine and the undocumented "mask=all" argument (with +spaced removed using sed ): + + fundisp "funtools/funtest/test40.fits[ANNULUS 25 25 5 10]" mask=all |\ + sed 's/ //g' + +Note that you must supply an image of the appropriate size -- in this case, +a FITS image of dimension 40x40 is used.] + + + +=head1 SEE ALSO + + + +See funtools(n) for a list of Funtools help pages + + + +=cut diff --git a/doc/programs.html b/doc/programs.html new file mode 100644 index 0000000..00d4dc7 --- /dev/null +++ b/doc/programs.html @@ -0,0 +1,3497 @@ + + +Funtools Programs + + +

Funtools Programs

+ +

Summary

+ +

+

+
+funcalc [-n] [-a argstr] [-e expr] [-f file] [-l link] [-p prog] [-u] <iname> [oname [columns]]
+
+funcen [-i] [-n iter] [-t tol] [-v lev] <iname> <region>
+
+funcnts [switches] <source_file> [source_region] [bkgd_file] [bkgd_region|bkgd_cnts]
+
+funcone [-n] [-x|-X|-j|-J] [[-l|-L] list] [-r ra_col] [-d dec_col]  <iname> <oname> <ra[hdr]> <dec[hdr]> <radius[dr'"]> [columns]
+
+fundisp [-f format] [-l] [-n] [-T] <iname> [columns|bitpix=n]
+
+funhead [-a] [-l] [-s] [-t] [-L] <iname> [oname ename]
+
+funhist [-n|-w|-T] <iname> [column] [[lo_edge:hi_edge:]bins] 
+
+funimage [-a] [-l] [-p x|y] <iname> <oname>  [bitpix=n]
+
+funindex <iname> <key> [oname]
+
+funjoin [switches] <ifile1> <ifile2> ... <ifilen> <ofile> 
+
+funmerge <iname1> <iname2> ... <oname>
+
+funsky [switches] <iname1> [<lname2> <col1> <col2>]
+
+funtable [-a] [-i|-z] [-m] [-s cols] <iname> <oname> [columns]
+
+funtbl [-c cols] [-h] [-n table] [-p prog] [-s sep] [-T] <iname>
+
+ + + + +

funcalc - Funtools calculator (for binary tables)

+ + +
+funcalc [-n] [-a argstr] [-e expr] [-f file] [-l link] [-p prog] <iname> [oname [columns]]
+
+
+ + +

+

+  -a argstr    # user arguments to pass to the compiled program
+  -e expr      # funcalc expression
+  -f file      # file containing funcalc expression
+  -l libs      # libs to add to link command  
+  -n           # output generated code instead of compiling and executing
+  -p prog      # generate named program, no execution
+  -u           # die if any variable is undeclared (don't auto-declare)
+
+ + +

+funcalc is a calculator program that allows arbitrary +expressions to be constructed, compiled, and executed on columns in a +Funtools table (FITS binary table or raw event file). It works by +integrating user-supplied expression(s) into a template C program, +then compiling and executing the program. funcalc expressions +are C statements, although some important simplifications (such +as automatic declaration of variables) are supported. + +

+funcalc expressions can be specified in three ways: on the +command line using the -e [expression] switch, in a file using +the -f [file] switch, or from stdin (if neither -e nor +-f is specified). Of course a file containing funcalc +expressions can be read from stdin. + +

+Each invocation of funcalc requires an input Funtools table +file to be specified as the first command line argument. The output +Funtools table file is the second optional argument. It is needed only +if an output FITS file is being created (i.e., in cases where the +funcalc expression only prints values, no output file is +needed). If input and output file are both specified, a third optional +argument can specify the list of columns to activate (using +FunColumnActivate()). Note +that funcalc determines whether or not to generate code for +writing an output file based on the presence or absence of an +output file argument. + +

+A funcalc expression executes on each row of a table and +consists of one or more C statements that operate on the columns of +that row (possibly using temporary variables). Within an expression, +reference is made to a column of the current row using the C +struct syntax cur->[colname], e.g. cur->x, cur->pha, etc. +Local scalar variables can be defined using C declarations at very the +beginning of the expression, or else they can be defined automatically +by funcalc (to be of type double). Thus, for example, a swap of +columns x and y in a table can be performed using either of the +following equivalent funcalc expressions: + +

+  double temp;
+  temp = cur->x;
+  cur->x = cur->y;
+  cur->y = temp;
+
+ +or: + +
+  temp = cur->x;
+  cur->x = cur->y;
+  cur->y = temp;
+
+ +When this expression is executed using a command such as: +
+  funcalc -f swap.expr itest.ev otest.ev
+
+the resulting file will have values of the x and y columns swapped. + +

+By default, the data type of the variable for a column is the same as +the data type of the column as stored in the file. This can be changed +by appending ":[dtype]" to the first reference to that column. In the +example above, to force x and y to be output as doubles, specify the +type 'D' explicitly: +

+  temp = cur->x:D;
+  cur->x = cur->y:D;
+  cur->y = temp;
+
+ +Data type specifiers follow standard FITS table syntax for defining +columns using TFORM: +
    +
  • A: ASCII characters +
  • B: unsigned 8-bit char +
  • I: signed 16-bit int +
  • U: unsigned 16-bit int (not standard FITS) +
  • J: signed 32-bit int +
  • V: unsigned 32-bit int (not standard FITS) +
  • E: 32-bit float +
  • D: 64-bit float +
  • X: bits (treated as an array of chars) +
+Note that only the first reference to a column should contain the +explicit data type specifier. + +

+Of course, it is important to handle the data type of the columns +correctly. One of the most frequent cause of error in funcalc +programming is the implicit use of the wrong data type for a column in +expression. For example, the calculation: +

+  dx = (cur->x - cur->y)/(cur->x + cur->y);
+
+usually needs to be performed using floating point arithmetic. In +cases where the x and y columns are integers, this can be done by +reading the columns as doubles using an explicit type specification: +
+  dx = (cur->x:D - cur->y:D)/(cur->x + cur->y);
+
+ +Alternatively, it can be done using C type-casting in the expression: +
+  dx = ((double)cur->x - (double)cur->y)/((double)cur->x + (double)cur->y);
+
+ +

+In addition to accessing columns in the current row, reference also +can be made to the previous row using prev->[colname], +and to the next row using next->[colname]. Note that if +prev->[colname] is specified in the funcalc +expression, the very first row is not processed. If +next->[colname] is specified in the funcalc +expression, the very last row is not processed. In this way, +prev and next are guaranteed always to point to valid +rows. For example, to print out the values of the current x column +and the previous y column, use the C fprintf function in a +funcalc expression: +

+  fprintf(stdout, "%d %d\n", cur->x, prev->y);
+
+ +

+New columns can be specified using the same cur->[colname] +syntax by appending the column type (and optional tlmin/tlmax/binsiz +specifiers), separated by colons. For example, cur->avg:D will define +a new column of type double. Type specifiers are the same those +used above to specify new data types for existing columns. + +

+For example, to create and output a new column that is the average value of the +x and y columns, a new "avg" column can be defined: +

+  cur->avg:D = (cur->x + cur->y)/2.0
+
+Note that the final ';' is not required for single-line expressions. + +

+As with FITS TFORM data type specification, the column data type +specifier can be preceded by a numeric count to define an array, e.g., +"10I" means a vector of 10 short ints, "2E" means two single precision +floats, etc. A new column only needs to be defined once in a +funcalc expression, after which it can be used without +re-specifying the type. This includes reference to elements of a +column array: + +

+  cur->avg[0]:2D = (cur->x + cur->y)/2.0;
+  cur->avg[1] = (cur->x - cur->y)/2.0;
+
+ +

+The 'X' (bits) data type is treated as a char array of dimension +(numeric_count/8), i.e., 16X is processed as a 2-byte char array. Each +8-bit array element is accessed separately: +

+  cur->stat[0]:16X  = 1;
+  cur->stat[1]      = 2;
+
+Here, a 16-bit column is created with the MSB is set to 1 and the LSB set to 2. + +

+By default, all processed rows are written to the specified output +file. If you want to skip writing certain rows, simply execute the C +"continue" statement at the end of the funcalc expression, +since the writing of the row is performed immediately after the +expression is executed. For example, to skip writing rows whose +average is the same as the current x value: + +

+  cur->avg[0]:2D = (cur->x + cur->y)/2.0;
+  cur->avg[1] = (cur->x - cur->y)/2.0;
+  if( cur->avg[0] == cur->x )
+    continue;
+
+ +

+If no output file argument is specified on the funcalc command +line, no output file is opened and no rows are written. This is useful +in expressions that simply print output results instead of generating +a new file: +

+  fpv = (cur->av3:D-cur->av1:D)/(cur->av1+cur->av2:D+cur->av3);
+  fbv =  cur->av2/(cur->av1+cur->av2+cur->av3);
+  fpu = ((double)cur->au3-cur->au1)/((double)cur->au1+cur->au2+cur->au3);
+  fbu =  cur->au2/(double)(cur->au1+cur->au2+cur->au3);
+  fprintf(stdout, "%f\t%f\t%f\t%f\n", fpv, fbv, fpu, fbu);
+
+In the above example, we use both explicit type specification +(for "av" columns) and type casting (for "au" columns) to ensure that +all operations are performed in double precision. + +

+When an output file is specified, the selected input table is +processed and output rows are copied to the output file. Note that +the output file can be specified as "stdout" in order to write the +output rows to the standard output. If the output file argument is +passed, an optional third argument also can be passed to specify which +columns to process. + +

+In a FITS binary table, it sometimes is desirable to copy all of the +other FITS extensions to the output file as well. This can be done by +appending a '+' sign to the name of the extension in the input file +name. See funtable for a related example. + +

+funcalc works by integrating the user-specified expression +into a template C program called tabcalc.c. +The completed program then is compiled and executed. Variable +declarations that begin the funcalc expression are placed in +the local declaration section of the template main program. All other +lines are placed in the template main program's inner processing +loop. Other details of program generation are handled +automatically. For example, column specifiers are analyzed to build a +C struct for processing rows, which is passed to +FunColumnSelect() and used +in FunTableRowGet(). If +an unknown variable is used in the expression, resulting in a +compilation error, the program build is retried after defining the +unknown variable to be of type double. + +

+Normally, funcalc expression code is added to +funcalc row processing loop. It is possible to add code +to other parts of the program by placing this code inside +special directives of the form: +

+  [directive name]
+    ... code goes here ...
+  end
+
+ +The directives are: +
    +
  • global add code and declarations in global space, before the main routine. + +
  • local add declarations (and code) just after the local declarations in +main + +
  • before add code just before entering the main row processing loop + +
  • after add code just after exiting the main row processing loop +
+ +Thus, the following funcalc expression will declare global +variables and make subroutine calls just before and just after the +main processing loop: +
+  global
+    double v1, v2;
+    double init(void);
+    double finish(double v);
+  end
+  before
+    v1  = init();
+  end
+  ... process rows, with calculations using v1 ...
+  after
+    v2 = finish(v1);
+    if( v2 < 0.0 ){
+      fprintf(stderr, "processing failed %g -> %g\n", v1, v2);
+      exit(1);
+    }
+  end
+
+Routines such as init() and finish() above are passed to the generated +program for linking using the -l [link directives ...] +switch. The string specified by this switch will be added to the link +line used to build the program (before the funtools library). For +example, assuming that init() and finish() are in the library +libmysubs.a in the /opt/special/lib directory, use: +
+  funcalc  -l "-L/opt/special/lib -lmysubs" ...
+
+ +

+User arguments can be passed to a compiled funcalc program using a string +argument to the "-a" switch. The string should contain all of the +user arguments. For example, to pass the integers 1 and 2, use: +

+  funcalc -a "1 2" ...
+
+The arguments are stored in an internal array and are accessed as +strings via the ARGV(n) macro. For example, consider the following +expression: +
+  local
+    int pmin, pmax;
+  end
+
+  before
+    pmin=atoi(ARGV(0));
+    pmax=atoi(ARGV(1));
+  end
+
+  if( (cur->pha >= pmin) && (cur->pha <= pmax) )
+    fprintf(stderr, "%d %d %d\n", cur->x, cur->y, cur->pha);
+
+This expression will print out x, y, and pha values for all rows in which +the pha value is between the two user-input values: +
+  funcalc -a '1 12' -f foo snr.ev'[cir 512 512 .1]'
+  512 512 6
+  512 512 8
+  512 512 5
+  512 512 5
+  512 512 8
+
+  funcalc -a '5 6' -f foo snr.ev'[cir 512 512 .1]'
+  512 512 6
+  512 512 5
+  512 512 5
+
+ +

+Note that it is the user's responsibility to ensure that the correct +number of arguments are passed. The ARGV(n) macro returns a NULL if a +requested argument is outside the limits of the actual number of args, +usually resulting in a SEGV if processed blindly. To check the +argument count, use the ARGC macro: +

+  local
+    long int seed=1;
+    double limit=0.8;
+  end
+
+  before
+    if( ARGC >= 1 ) seed = atol(ARGV(0));
+    if( ARGC >= 2 ) limit = atof(ARGV(1));
+    srand48(seed);
+  end
+
+  if ( drand48() > limit ) continue;
+
+ +

+The macro WRITE_ROW expands to the FunTableRowPut() call that writes +the current row. It can be used to write the row more than once. In +addition, the macro NROW expands to the row number currently being +processed. Use of these two macros is shown in the following example: +

+  if( cur->pha:I == cur->pi:I ) continue;
+  a = cur->pha;
+  cur->pha = cur->pi;
+  cur->pi = a;
+  cur->AVG:E  = (cur->pha+cur->pi)/2.0;
+  cur->NR:I = NROW;
+  if( NROW < 10 ) WRITE_ROW;
+
+ +

+If the -p [prog] switch is specified, the expression is not +executed. Rather, the generated executable is saved with the specified +program name for later use. + +

+If the -n switch is specified, the expression is not +executed. Rather, the generated code is written to stdout. This is +especially useful if you want to generate a skeleton file and add your +own code, or if you need to check compilation errors. Note that the +comment at the start of the output gives the compiler command needed +to build the program on that platform. (The command can change from +platform to platform because of the use of different libraries, +compiler switches, etc.) + +

+As mentioned previously, funcalc will declare a scalar +variable automatically (as a double) if that variable has been used +but not declared. This facility is implemented using a sed script +named funcalc.sed, which processes the +compiler output to sense an undeclared variable error. This script +has been seeded with the appropriate error information for gcc, and for +cc on Solaris, DecAlpha, and SGI platforms. If you find that automatic +declaration of scalars is not working on your platform, check this sed +script; it might be necessary to add to or edit some of the error +messages it senses. + +

+In order to keep the lexical analysis of funcalc expressions +(reasonably) simple, we chose to accept some limitations on how +accurately C comments, spaces, and new-lines are placed in the +generated program. In particular, comments associated with local +variables declared at the beginning of an expression (i.e., not in a +local...end block) will usually end up in the inner loop, not +with the local declarations: +

+  /* this comment will end up in the wrong place (i.e, inner loop) */
+  double a; /* also in wrong place */
+  /* this will be in the the right place (inner loop) */
+  if( cur->x:D == cur->y:D ) continue; /* also in right place */
+  a = cur->x;
+  cur->x = cur->y;
+  cur->y = a;
+  cur->avg:E  = (cur->x+cur->y)/2.0;
+
+Similarly, spaces and new-lines sometimes are omitted or added in a +seemingly arbitrary manner. Of course, none of these stylistic +blemishes affect the correctness of the generated code. + +

+Because funcalc must analyze the user expression using the data +file(s) passed on the command line, the input file(s) must be opened +and read twice: once during program generation and once during +execution. As a result, it is not possible to use stdin for the +input file: funcalc cannot be used as a filter. We will +consider removing this restriction at a later time. + +

+Along with C comments, funcalc expressions can have one-line +internal comments that are not passed on to the generated C +program. These internal comment start with the # character and +continue up to the new-line: +

+  double a; # this is not passed to the generated C file
+  # nor is this
+  a = cur->x;
+  cur->x = cur->y;
+  cur->y = a;
+  /* this comment is passed to the C file */
+  cur->avg:E  = (cur->x+cur->y)/2.0;
+
+ +

+As previously mentioned, input columns normally are identified by +their being used within the inner event loop. There are rare cases +where you might want to read a column and process it outside the main +loop. For example, qsort might use a column in its sort comparison +routine that is not processed inside the inner loop (and therefore not +implicitly specified as a column to be read). To ensure that such a +column is read by the event loop, use the explicit keyword. +The arguments to this keyword specify columns that should be read into +the input record structure even though they are not mentioned in the +inner loop. For example: +

+  explicit pi pha
+
+will ensure that the pi and pha columns are read for each row, +even if they are not processed in the inner event loop. The explicit +statement can be placed anywhere. + +

+Finally, note that funcalc currently works on expressions +involving FITS binary tables and raw event files. We will consider +adding support for image expressions at a later point, if there is +demand for such support from the community. + + + + +

funcen - find centroid (for binary tables)

+ + +
+funcen [-i] [-n iter] [-t tol] [-v lev] <iname> <region>
+
+
+ + +

+

+  -i            # use image filtering (default: event filtering)
+  -n iter       # max number of iterations (default: 0)
+  -t tol        # pixel tolerance distance (default: 1.0)
+  -v [0,1,2,3]  # output verbosity level (default: 0)
+
+ + +

+funcen iteratively calculates the centroid position within one +or more regions of a Funtools table (FITS binary table or raw event +file). Starting with an input table, an initial region specification, +and an iteration count, the program calculates the average x and y +position within the region and then uses this new position as the +region center for the next iteration. Iteration terminates when the +maximum number of iterations is reached or when the input tolerance +distance is met for that region. A count of events in the final region +is then output, along with the pixel position value (and, where +available, WCS position). + +

+The first argument to the program specifies the Funtools table file to +process. Since the file must be read repeatedly, a value of "stdin" +is not permitted when the number of iterations is non-zero. Use +Funtools Bracket Notation to specify FITS +extensions and filters. + +

+The second required argument is the initial region descriptor. Multiple +regions are permitted. However, compound regions (accelerators, +variable argument regions and regions connected via boolean algebra) +are not permitted. Points and polygons also are illegal. These +restrictions might be lifted in a future version, if warranted. + +

+The -n (iteration number) switch specifies the maximum number of +iterations to perform. The default is 0, which means that the program will +simply count and display the number of events in the initial region(s). +Note that when iterations is 0, the data can be input via stdin. + +

+The -t (tolerance) switch specifies a floating point tolerance +value. If the distance between the current centroid position value and +the last position values is less than this value, iteration terminates. +The default value is 1 pixel. + +

+The -v (verbosity) switch specifies the verbosity level of the +output. The default is 0, which results in a single line of output for +each input region consisting of the following values: +

+  counts x y [ra dec coordsys]
+
+The last 3 WCS values are output if WCS information is available in the +data file header. Thus, for example: +
+  [sh] funcen -n 0 snr.ev "cir 505 508 5"
+  915 505.00 508.00 345.284038 58.870920 j2000
+
+  [sh] funcen -n 3 snr.ev "cir 505 508 5"
+  1120 504.43 509.65 345.286480 58.874587 j2000
+
+The first example simply counts the number of events in the initial region. +The second example iterates the centroid calculation three times to determine +a final "best" position. + +

+Higher levels of verbosity obviously imply more verbose output. At +level 1, the output essentially contains the same information as level +0, but with keyword formatting: + + [sh] funcen -v 1 -n 3 snr.ev "cir 505 508 5" + event_file: snr.ev + initial_region: cir 505 508 5 + tolerance: 1.0000 + iterations: 1 + + events: 1120 + x,y(physical): 504.43 509.65 + ra,dec(j2000): 345.286480 58.874587 + final_region1: cir 504.43 509.65 5 + +Level 2 outputs results from intermediate calculations as well. + +

+Ordinarily, region filtering is performed using analytic (event) +filtering, i.e. that same style of filtering as is performed by +fundisp and funtable. Use the -i switch to specify image +filtering, i.e. the same style filtering as is performed by funcnts. +Thus, you can perform a quick calculation of counts in regions, using +either the analytic or image filtering method, by specifying the + -n 0 and optional -i switches. These two method often +give different results because of how boundary events are processed: +

+  [sh] funcen  snr.ev "cir 505 508 5"
+  915 505.00 508.00 345.284038 58.870920 j2000
+
+  [sh] funcen -i snr.ev "cir 505 508 5"
+  798 505.00 508.00 345.284038 58.870920 j2000
+
+See Region Boundaries for more information +about how boundaries are calculated using these two methods. + + + + +

funcnts - count photons in specified regions, with bkgd subtraction

+ + + +
+funcnts  [switches] <source_file> [source_region] [bkgd_file] [bkgd_region|bkgd_value]
+
+
+ + +

+

+  -e "source_exposure[;bkgd_exposure]"
+                # source (bkgd) FITS exposure image using matching files
+  -w "source_exposure[;bkgd_exposure]"
+                # source (bkgd) FITS exposure image using WCS transform
+  -t "source_timecorr[;bkgd_timecorr]"
+                # source (bkgd) time correction value or header parameter name
+  -g            # output using nice g format
+  -G            # output using %.14g format (maximum precision)
+  -i "[column;]int1;int2..." # column-based intervals
+  -m            # match individual source and bkgd regions
+  -p            # output in pixels, even if wcs is present
+  -r            # output inner/outer radii (and angles) for annuli (and pandas)
+  -s            # output summed values
+  -v "scol[;bcol]" # src and bkgd value columns for tables
+  -T            # output in starbase/rdb format
+  -z            # output regions with zero area
+
+
+ + +

+funcnts counts photons in the specified source regions and +reports the results for each region. Regions are specified using the +Spatial Region Filtering mechanism. +Photons are also counted in the specified bkgd regions applied to the +same data file or a different data file. (Alternatively, a constant +background value in counts/pixel**2 can be specified.) The bkgd regions +are either paired one-to-one with source regions or pooled and +normalized by area, and then subtracted from the source counts in each +region. Displayed results include the bkgd-subtracted counts in each +region, as well as the error on the counts, the area in +each region, and the surface brightness (cnts/area**2) calculated for +each region. + +

+The first argument to the program specifies the FITS input image, array, or +raw event file to process. If "stdin" is specified, data are read from +the standard input. Use Funtools Bracket +Notation to specify FITS extensions, image sections, and filters. + +

+The optional second argument is the source region descriptor. If no +region is specified, the entire field is used. + +

+The background arguments can take one of two forms, depending on +whether a separate background file is specified. If the source +file is to be used for background as well, the third argument can be +either the background region, or a constant value denoting background +cnts/pixel. Alternatively, the third argument can be a background +data file, in which case the fourth argument is the background region. +If no third argument is specified, a constant value of 0 is used +(i.e., no background). + +

+In summary, the following command arguments are valid: +

+  [sh] funcnts sfile                        # counts in source file
+  [sh] funcnts sfile sregion                # counts in source region
+  [sh] funcnts sfile sregion bregion        # bkgd reg. is from source file
+  [sh] funcnts sfile sregion bvalue         # bkgd reg. is constant
+  [sh] funcnts sfile sregion bfile bregion  # bkgd reg. is from separate file
+
+ +

+NB: unlike other Funtools programs, source and background regions are +specified as separate arguments on the command line, rather than being +placed inside brackets as part of the source and background filenames. +This is because regions in funcnts are not simply used as data +filters, but also are used to calculate areas, exposure, etc. If you +put the source region inside the brackets (i.e. use it simply as a +filter) rather than specifying it as argument two, the program still +will only count photons that pass the region filter. However, the area +calculation will be performed on the whole field, since field() is the +default source region. This rarely is the desired behavior. On the +other hand, with FITS binary tables, it often is useful to put a column +filter in the filename brackets, so that only events matching the +column filter are counted inside the region. + +

+For example, to extract the counts within a radius of 22 pixels from the +center of the FITS binary table snr.ev and subtract the background determined +from the same image within an annulus of radii 50-100 pixels: +

+  [sh] funcnts snr.ev "circle(502,512,22)" "annulus(502,512,50,100)"
+  # source
+  #   data file:        snr.ev
+  #   degrees/pix:      0.00222222
+  # background
+  #   data file:        snr.ev
+  # column units
+  #   area:             arcsec**2
+  #   surf_bri:         cnts/arcsec**2
+  #   surf_err:         cnts/arcsec**2
+
+  # background-subtracted results
+   reg   net_counts     error   background    berror      area  surf_bri  surf_err
+  ---- ------------ --------- ------------ --------- --------- --------- ---------
+     1     3826.403    66.465      555.597     5.972  96831.98     0.040     0.001
+  
+
+  # the following source and background components were used:
+  source region(s)
+  ----------------
+  circle(502,512,22)
+  
+   reg       counts    pixels
+  ---- ------------ ---------
+     1     4382.000      1513
+  
+  background region(s)
+  --------------------
+  annulus(502,512,50,100)
+  
+   reg       counts    pixels
+  ---- ------------ ---------
+  all      8656.000     23572
+
+The area units for the output columns labeled "area", "surf_bri" +(surface brightness) and "surf_err" will be given either in +arc-seconds (if appropriate WCS information is in the data file +header(s)) or in pixels. If the data file has WCS info, but you do not +want arc-second units, use the -p switch to force output in +pixels. Also, regions having zero area are not normally included in +the primary (background-subtracted) table, but are included in the +secondary source and bkgd tables. If you want these regions to be +included in the primary table, use the -z switch. + +

+Note that a simple sed command will extract the background-subtracted results +for further analysis: +

+  [sh] cat funcnts.sed
+  1,/---- .*/d
+  /^$/,$d
+
+  [sh] sed -f funcnts.sed funcnts.out
+  1     3826.403    66.465      555.597     5.972  96831.98     0.040     0.001
+
+ +

+If separate source and background files are specified, funcnts will +attempt to normalize the the background area so that the background +pixel size is the same as the source pixel size. This normalization +can only take place if the appropriate WCS information is contained in +both files (e.g. degrees/pixel values in CDELT). If either +file does not contain the requisite size information, the normalization +is not performed. In this case, it is the user's responsibility to +ensure that the pixel sizes are the same for the two files. + +

+Normally, if more than one background region is specified, funcnts +will combine them all into a single region and use this background +region to produce the background-subtracted results for each source +region. The -m (match multiple backgrounds) switch tells +funcnts to make a one to one correspondence between background and +source regions, instead of using a single combined background region. +For example, the default case is to combine 2 background +regions into a single region and then apply that region to each of the +source regions: + +

+  [sh] funcnts snr.ev "annulus(502,512,0,22,n=2)" "annulus(502,512,50,100,n=2)"
+  # source
+  #   data file:        snr.ev
+  #   degrees/pix:      0.00222222
+  # background
+  #   data file:        snr.ev
+  # column units
+  #   area:             arcsec**2
+  #   surf_bri:         cnts/arcsec**2
+  #   surf_err:         cnts/arcsec**2
+  
+  # background-subtracted results
+   reg   net_counts     error   background    berror      area  surf_bri  surf_err
+  ---- ------------ --------- ------------ --------- --------- --------- ---------
+     1     3101.029    56.922      136.971     1.472  23872.00     0.130     0.002
+     2      725.375    34.121      418.625     4.500  72959.99     0.010     0.000
+  
+  
+  # the following source and background components were used:
+  source region(s)
+  ----------------
+  annulus(502,512,0,22,n=2)
+  
+   reg       counts    pixels
+  ---- ------------ ---------
+     1     3238.000       373
+     2     1144.000      1140
+  
+  background region(s)
+  --------------------
+  annulus(502,512,50,100,n=2)
+  
+   reg       counts    pixels
+  ---- ------------ ---------
+  all      8656.000     23572
+
+Note that the basic region filter rule "each photon is counted once +and no photon is counted more than once" still applies when using The +-m to match background regions. That is, if two background +regions overlap, the overlapping pixels will be counted in only one of +them. In a worst-case scenario, if two background regions are the same +region, the first will get all the counts and area and the second +will get none. + +

+Using the -m switch causes funcnts to use each of the two +background regions independently with each of the two source regions: + +

+  [sh] funcnts -m snr.ev "annulus(502,512,0,22,n=2)" "ann(502,512,50,100,n=2)"
+  # source
+  #   data file:        snr.ev
+  #   degrees/pix:      0.00222222
+  # background
+  #   data file:        snr.ev
+  # column units
+  #   area:             arcsec**2
+  #   surf_bri:         cnts/arcsec**2
+  #   surf_err:         cnts/arcsec**2
+  
+  # background-subtracted results
+   reg   net_counts     error   background    berror      area  surf_bri  surf_err
+  ---- ------------ --------- ------------ --------- --------- --------- ---------
+     1     3087.015    56.954      150.985     2.395  23872.00     0.129     0.002
+     2      755.959    34.295      388.041     5.672  72959.99     0.010     0.000
+  
+  
+  # the following source and background components were used:
+  source region(s)
+  ----------------
+  annulus(502,512,0,22,n=2)
+  
+   reg       counts    pixels
+  ---- ------------ ---------
+     1     3238.000       373
+     2     1144.000      1140
+  
+  background region(s)
+  --------------------
+  ann(502,512,50,100,n=2)
+  
+   reg       counts    pixels
+  ---- ------------ ---------
+     1     3975.000      9820
+     2     4681.000     13752
+
+ +

+Note that most floating point quantities are displayed using "f" +format. You can change this to "g" format using the -g +switch. This can be useful when the counts in each pixel is very +small or very large. If you want maximum precision and don't care +about the columns lining up nicely, use -G, which outputs +all floating values as %.14g. + +

+When counting photons using the annulus and panda (pie and annuli) +shapes, it often is useful to have access to the radii (and panda +angles) for each separate region. The -r switch will add radii +and angle columns to the output table: + +

+  [sh] funcnts -r snr.ev "annulus(502,512,0,22,n=2)" "ann(502,512,50,100,n=2)"
+  # source
+  #   data file:        snr.ev
+  #   degrees/pix:      0.00222222
+  # background
+  #   data file:        snr.ev
+  # column units
+  #   area:             arcsec**2
+  #   surf_bri:         cnts/arcsec**2
+  #   surf_err:         cnts/arcsec**2
+  #   radii:            arcsecs
+  #   angles:           degrees
+  
+  # background-subtracted results
+   reg   net_counts     error   background    berror      area  surf_bri  surf_err   radius1   radius2    angle1    angle2
+  ---- ------------ --------- ------------ --------- --------- --------- --------- --------- --------- --------- ---------
+     1     3101.029    56.922      136.971     1.472  23872.00     0.130     0.002      0.00     88.00        NA        NA
+     2      725.375    34.121      418.625     4.500  72959.99     0.010     0.000     88.00    176.00        NA        NA
+  
+  
+  # the following source and background components were used:
+  source region(s)
+  ----------------
+  annulus(502,512,0,22,n=2)
+  
+   reg       counts    pixels
+  ---- ------------ ---------
+     1     3238.000       373
+     2     1144.000      1140
+  
+  background region(s)
+  --------------------
+  ann(502,512,50,100,n=2)
+  
+   reg       counts    pixels
+  ---- ------------ ---------
+  all      8656.000     23572
+
+ +

+Radii are given in units of pixels or arc-seconds (depending on the +presence of WCS info), while the angle values (when present) are in +degrees. These columns can be used to plot radial profiles. For +example, the script funcnts.plot in the funtools +distribution) will plot a radial profile using gnuplot (version 3.7 or +above). A simplified version of this script is shown below: + +

+  #!/bin/sh
+  
+  if [ x"$1" = xgnuplot ]; then
+    if [ x`which gnuplot 2>/dev/null` = x ]; then
+      echo "ERROR: gnuplot not available"
+      exit 1
+    fi
+    awk '
+    BEGIN{HEADER=1; DATA=0; FILES=""; XLABEL="unknown"; YLABEL="unknown"}
+    HEADER==1{
+      if( $1 == "#" && $2 == "data" && $3 == "file:" ){
+        if( FILES != "" ) FILES = FILES ","
+        FILES = FILES $4
+      }
+      else if( $1 == "#" && $2 == "radii:" ){
+        XLABEL = $3
+      }
+      else if( $1 == "#" && $2 == "surf_bri:" ){
+        YLABEL = $3
+      }
+      else if( $1 == "----" ){
+        printf "set nokey; set title \"funcnts(%s)\"\n", FILES
+        printf "set xlabel \" radius(%s)\"\n", XLABEL
+        printf "set ylabel \"surf_bri(%s)\"\n", YLABEL
+        print  "plot \"-\" using 3:4:6:7:8 with boxerrorbars"
+        HEADER = 0
+        DATA = 1
+        next
+      }
+    }
+    DATA==1{
+      if( NF == 12 ){
+        print $9, $10, ($9+$10)/2, $7, $8, $7-$8, $7+$8, $10-$9
+      }
+      else{
+        exit
+      }
+    }
+    ' | gnuplot -persist - 1>/dev/null 2>&1
+  
+  elif [ x"$1" = xds9 ]; then
+    awk '
+    BEGIN{HEADER=1; DATA=0; XLABEL="unknown"; YLABEL="unknown"}
+    HEADER==1{
+      if( $1 == "#" && $2 == "data" && $3 == "file:" ){
+        if( FILES != "" ) FILES = FILES ","
+        FILES = FILES $4
+      }
+      else if( $1 == "#" && $2 == "radii:" ){
+        XLABEL = $3
+      }
+      else if( $1 == "#" && $2 == "surf_bri:" ){
+        YLABEL = $3
+      }
+      else if( $1 == "----" ){
+        printf "funcnts(%s) radius(%s) surf_bri(%s) 3\n", FILES, XLABEL, YLABEL
+        HEADER = 0
+        DATA = 1
+        next
+      }
+    }
+    DATA==1{
+      if( NF == 12 ){
+        print $9, $7, $8
+      }
+      else{
+        exit
+      }
+    }
+    '
+  else
+    echo "funcnts -r ... | funcnts.plot [ds9|gnuplot]"
+    exit 1
+  fi
+
+ +Thus, to run funcnts and plot the results using gnuplot (version 3.7 +or above), use: +
+  funcnts -r snr.ev "annulus(502,512,0,50,n=5)" ...  | funcnts.plot gnuplot
+
+ +

+The -s (sum) switch causes funcnts to produce an +additional table of summed (integrated) background subtracted values, +along with the default table of individual values: + +

+  [sh] funcnts -s snr.ev "annulus(502,512,0,50,n=5)" "annulus(502,512,50,100)"
+  # source
+  #   data file:        snr.ev
+  #   degrees/pix:      0.00222222
+  # background
+  #   data file:        snr.ev
+  # column units
+  #   area:             arcsec**2
+  #   surf_bri:         cnts/arcsec**2
+  #   surf_err:         cnts/arcsec**2
+  
+  # summed background-subtracted results
+  upto   net_counts     error   background    berror      area  surf_bri  surf_err
+  ---- ------------ --------- ------------ --------- --------- --------- ---------
+     1     2880.999    54.722      112.001     1.204  19520.00     0.148     0.003
+     2     3776.817    65.254      457.183     4.914  79679.98     0.047     0.001
+     3     4025.492    71.972     1031.508    11.087 179775.96     0.022     0.000
+     4     4185.149    80.109     1840.851    19.786 320831.94     0.013     0.000
+     5     4415.540    90.790     2873.460    30.885 500799.90     0.009     0.000
+  
+  
+  # background-subtracted results
+   reg       counts     error   background    berror      area  surf_bri  surf_err
+  ---- ------------ --------- ------------ --------- --------- --------- ---------
+     1     2880.999    54.722      112.001     1.204  19520.00     0.148     0.003
+     2      895.818    35.423      345.182     3.710  60159.99     0.015     0.001
+     3      248.675    29.345      574.325     6.173 100095.98     0.002     0.000
+     4      159.657    32.321      809.343     8.699 141055.97     0.001     0.000
+     5      230.390    37.231     1032.610    11.099 179967.96     0.001     0.000
+  
+  
+  # the following source and background components were used:
+  source region(s)
+  ----------------
+  annulus(502,512,0,50,n=5)
+  
+   reg       counts    pixels      sumcnts    sumpix
+  ---- ------------ --------- ------------ ---------
+     1     2993.000       305     2993.000       305
+     2     1241.000       940     4234.000      1245
+     3      823.000      1564     5057.000      2809
+     4      969.000      2204     6026.000      5013
+     5     1263.000      2812     7289.000      7825
+  
+  background region(s)
+  --------------------
+  annulus(502,512,50,100)
+  
+   reg       counts    pixels
+  ---- ------------ ---------
+  all      8656.000     23572
+
+ +

+The -t and -e switches can be used to apply timing and +exposure corrections, respectively, to the data. Please note that +these corrections are meant to be used qualitatively, since +application of more accurate correction factors is a complex and +mission-dependent effort. The algorithm for applying these simple +corrections is as follows: +

+  C =  Raw Counts in Source Region
+  Ac=  Area of Source Region
+  Tc=  Exposure time for Source Data
+  Ec=  Average exposure in Source Region, from exposure map
+
+  B=   Raw Counts in Background Region
+  Ab=  Area of Background Region
+  Tb=  (Exposure) time for Background Data
+  Eb=  Average exposure in Background Region, from exposure map
+
+Then, Net Counts in Source region is +
+  Net=  C - B * (Ac*Tc*Ec)/(Ab*Tb*Eb)
+
+with the standard propagation of errors for the Error on Net. +The net rate would then be +
+  Net Rate = Net/(Ac*Tc*Ec)
+
+The average exposure in each region is calculated by summing up the +pixel values in the exposure map for the given region and then +dividing by the number of pixels in that region. Exposure maps often +are generated at a block factor > 1 (e.g., block 4 means that each +exposure pixel contains 4x4 pixels at full resolution) and +funcnts will deal with the blocking automatically. Using the +-e switch, you can supply both source and background exposure +files (separated by ";"), if you have separate source and background +data files. If you do not supply a background exposure file to go with +a separate background data file, funcnts assumes that exposure +already has been applied to the background data file. In addition, it +assumes that the error on the pixels in the background data file is +zero. + +

+NB: The -e switch assumes that the exposure map overlays the +image file exactly, except for the block factor. Each pixel in +the image is scaled by the block factor to access the corresponding +pixel in the exposure map. If your exposure map does not line up +exactly with the image, do not use the -e exposure +correction. In this case, it still is possible to perform exposure +correction if both the image and the exposure map have valid +WCS information: use the -w switch so that the transformation +from image pixel to exposure pixel uses the WCS information. That is, +each pixel in the image region will be transformed first from image +coordinates to sky coordinates, then from sky coordinates to exposure +coordinates. Please note that using -w can increase the time +required to process the exposure correction considerably. + +

+A time correction can be applied to both source and +background data using the -t switch. The value for the correction can +either be a numeric constant or the name of a header parameter in +the source (or background) file: +

+  [sh] funcnts -t 23.4 ...            # number for source
+  [sh] funcnts -t "LIVETIME;23.4" ... # param for source, numeric for bkgd
+
+When a time correction is specified, it is applied to the net counts +as well (see algorithm above), so that the units of surface brightness +become cnts/area**2/sec. + +

+The -i (interval) switch is used to run funcnts on multiple +column-based intervals with only a single pass through the data. It is +equivalent to running funcnts several times with a different column +filter added to the source and background data each time. For each +interval, the full funcnts output is generated, with a linefeed +character (^L) inserted between each run. In addition, the output for +each interval will contain the interval specification in its header. +Intervals are very useful for generating X-ray hardness ratios +efficiently. Of course, they are only supported when the input data +are contained in a table. + +

+Two formats are supported for interval specification. The most general +format is semi-colon-delimited list of filters to be used as intervals: +

+  funcnts -i "pha=1:5;pha=6:10;pha=11:15" snr.ev "circle(502,512,22)" ...
+
+Conceptually, this will be equivalent to running funcnts three times: +
+  funcnts snr.ev'[pha=1:5]' "circle(502,512,22)"
+  funcnts snr.ev'[pha=6:10]' "circle(502,512,22)"
+  funcnts snr.ev'[pha=11:15]' "circle(502,512,22)"
+
+However, using the -i switch will require only one pass through +the data. + +

+Note that complex filters can be used to specify intervals: +

+  funcnts -i "pha=1:5&&pi=4;pha=6:10&&pi=5;pha=11:15&&pi=6" snr.ev ...
+
+The program simply runs the data through each filter in turn and generates +three funcnts outputs, separated by the line-feed character. + +

+In fact, although the intent is to support intervals for hardness ratios, +the specified filters do not have to be intervals at all. Nor does one +"interval" filter have to be related to another. For example: +

+  funcnts -i "pha=1:5;pi=6:10;energy=11:15" snr.ev "circle(502,512,22)" ...
+
+is equivalent to running funcnts three times with unrelated filter +specifications. + +

+A second interval format is supported for the simple case in which a +single column is used to specify multiple homogeneous intervals for +that column. In this format, a column name is specified first, +followed by intervals: +

+  funcnts -i "pha;1:5;6:10;11:15" snr.ev "circle(502,512,22)" ...
+
+This is equivalent to the first example, but requires less typing. The +funcnts program will simply prepend "pha=" before each of the specified +intervals. (Note that this format does not contain the "=" character in +the column argument.) + +

+Ordinarily, when funcnts is run on a FITS binary table (or a +raw event table), one integral count is accumulated for each row +(event) contained within a given region. The -v "scol[;bcol]" +(value column) switch will accumulate counts using the value from the +specified column for the given event. If only a single column is +specified, it is used for both the source and background regions. Two +separate columns, separated by a semi-colon, can be specified for source +and background. The special token '$none' can be used to specify that +a value column is to be used for one but not the other. For example, +'pha;$none' will use the pha column for the source but use integral +counts for the background, while '$none;pha' will do the converse. +If the value column is of type logical, then the value used will be 1 +for T and 0 for F. Value columns are used, for example, to integrate +probabilities instead of integral counts. + +

+If the -T (rdb table) switch is used, the output will conform +to starbase/rdb data base format: tabs will be inserted between +columns rather than spaces and line-feed will be inserted between +tables. + +

+Finally, note that funcnts is an image program, even though it +can be run directly on FITS binary tables. This means that image +filtering is applied to the rows in order to ensure that the same +results are obtained regardless of whether a table or the equivalent +binned image is used. Because of this, however, the number of counts +found using funcnts can differ from the number of events found +using row-filter programs such as fundisp or funtable +For more information about these difference, see the discussion of +Region Boundaries. + + + + +

funcone - cone search of a binary table containing RA, Dec columns

+ + + +
+funcone <switches>  <iname> <oname> <ra[hdr]> <dec[hdr]> <radius[dr'"]> [columns]
+
+
+ + +

+

+  -d deccol:[hdr]  # Dec column name, units (def: DEC:d)
+  -j               # join columns from list file
+  -J               # join columns from list file, output all rows
+  -l listfile      # read centers and radii from a list
+  -L listfile      # read centers and radii from a list, output list rows
+  -n               # don't use cone limits as a filter
+  -r  racol:[hdr]  # RA column name, units (def: RA:h)
+  -x               # append RA_CEN, DEC_CEN, RAD_CEN, CONE_KEY cols
+  -X               # append RA_CEN, DEC_CEN, RAD_CEN, CONE_KEY cols, output all rows
+
+ + +

+Funcone performs a cone search on the RA and Dec columns of a FITS +binary table. The distance from the center RA, Dec position to the RA, +Dec in each row in the table is calculated. Rows whose distance is +less than the specified radius are output. + +

+The first argument to the program specifies the FITS file, raw event +file, or raw array file. If "stdin" is specified, data are read from +the standard input. Use Funtools Bracket +Notation to specify FITS extensions, and filters. The second +argument is the output FITS file. If "stdout" is specified, the FITS +binary table is written to the standard output. + +

+The third and fourth required arguments are the RA and Dec center +position. By default, RA is specified in hours while Dec is specified +in degrees. You can change the units of either of these by appending +the character "d" (degrees), "h" (hours) or "r" (radians). Sexagesimal +notation is supported, with colons or spaces separating hms and dms. +(When using spaces, please ensure that the entire string is quoted.) + +

+The fifth required argument is the radius of the cone search. By default, +the radius value is given in degrees. The units can be changed by appending +the character "d" (degrees), "r" (radians), "'" (arc minutes) or +'"' (arc seconds). + +

+By default, all +columns of the input file are copied to the output file. Selected +columns can be output using an optional sixth argument in the form: +

+  "column1 column1 ... columnN"
+
+A seventh argument allows you to output selected columns from the list +file when -j switch is used. Note that the RA and Dec columns +used in the cone calculation must not be de-selected. + +

+Also by default, the RA and Dec column names are named "RA" and "Dec", +and are given in units of hours and degrees respectively. You can +change both the name and the units using the -r [RA] and/or -d [Dec] +switches. Once again, one of "h", "d", or "r" is appended to the +column name to specify units but in this case, there must be a colon ":" +between the name and the unit specification. + +

+If the -l [listfile] switch is used, then one or more of the +center RA, center Dec, and radius can be taken from a list file (which +can be a FITS table or an ASCII column text file). In this case, the +third (center RA), fourth (center Dec), and fifth (radius) command +line arguments can either be a column name in the list file (if that +parameter varies) or else a numeric value (if that parameter is +static). When a column name is specified for the RA, Dec, or radius, +you can append a colon followed by "h", "d", or "r" to specify units +(also ' and " for radius). The cone search algorithm is run once for +each row in the list, taking RA, Dec, and radius values from the +specified columns or from static numeric values specified on the +command line. + +

+When using a list, all valid rows from each iteration are written to a +single output file. Use the -x switch to help delineate which +line of the list file was used to produce the given output row(s). +This switch causes the values for the center RA, Dec, radius, and row +number to be appended to the output file, in columns called RA_CEN, +DEC_CEN, RAD_CEN and CONE_KEY, respectively. Alternatively, the +-j (join) switch will append all columns from the list row to +the output row (essentially a join of the list row and input row), +along with the CONE_KEY row number. These two switches are mutually +exclusive. + +

+The -X and -J switches write out the same data as their +lower case counterparts for each row satisfying a cone search. In +addition, these switches also write out rows from the event file that +do not satisfy any cone search. In such cases, that CONE_KEY column +will be given a value of -1 and the center and list position information +will be set to zero for the given row. Thus, all rows of the input +event file are guaranteed to be output, with rows satisfying at least +one cone search having additional search information. + +

+The -L switch acts similarly to the -l switch in that it +takes centers from a list file. However, it also implicitly sets the +-j switch, so that output rows are the join of the input event row and +the center position row. In addition, this switch also writes out all +center position rows for which no event satisfies the cone search +criteria of that row. The CONE_KEY column will be given a value of -2 +for center rows that were not close to any data row and the event +columns will be zeroed out for such rows. In this way, all centers +rows are guaranteed to be output at least once. + +

+If any of "all row" switches (-X, -J, or -L) are +specified, then a new column named JSTAT is added to the output table. +The positive values in this column indicate the center position row number +(starting from 1) in the list file that this data row successful matched +in a cone search. A value of -1 means that the data row did not match +any center position. A value of -2 means that the center position was +not matched by any data row. + +

+Given a center position and radius, the cone search algorithm +calculates limit parameters for a box enclosing the specified cone, +and only tests rows whose positions values lie within those limits. +For small files, the overhead associated with this cone limit +filtering can cause the program to run more slowly than if all events +were tested. You can turn off cone limit filtering using the -n +switch to see if this speeds up the processing (especially useful when +processing a large list of positions). + +

+For example, the default cone search uses columns "RA" and "Dec" in hours +and degrees (respectively) and RA position in hours, Dec and radius in degrees: +

+  funone in.fits out.fits 23.45 34.56 0.01
+
+To specify the RA position in degrees: +
+  funcone in.fits out.fits 23.45d 34.56 0.01
+
+To get RA and Dec from a list but use a static value for radius (and +also write identifying info for each row in the list): +
+  funcone -x -l list.txt in.fits out.fits MYRA MYDec 0.01
+
+User specified columns in degrees, RA position in hours (sexagesimal +notation), Dec position in degrees (sexagesimal notation) and radius +in arc minutes: +
+  funcone -r myRa:d -d myDec in.fits out.fits 12:30:15.5 30:12 15'
+
+ + + + +

fundisp - display data in a Funtools data file

+ + + +
+fundisp  [-f format] [-l] [-n] [-T] <iname> [columns|bitpix=n]
+
+
+ + +

+

+  -f      # format string for display
+  -l      # display image as a list containing the columns X, Y, VAL
+  -n      # don't output header
+  -F [c]  # use specified character as column separator (def: space)
+  -T      # output in rdb/starbase format (tab separators) 
+
+ + +

+fundisp displays the data in the specified +FITS Extension +and/or +Image Section +of a FITS file, or in a +Section +of a non-FITS array or raw event file. +

+The first argument to the program specifies the FITS input image, array, or +raw event file to display. If "stdin" is specified, data are read from +the standard input. Use Funtools Bracket +Notation to specify FITS extensions, image sections, and filters. + +

+If the data being displayed are columns (either in a FITS binary table +or a raw event file), the individual rows are listed. Filters can be +added using bracket notation. Thus: +

+  [sh] fundisp "test.ev[time-(int)time>.15]"
+         X       Y     PHA        PI             TIME         DX         DY
+   ------- ------- ------- --------- ---------------- ---------- ----------
+        10       8      10         8          17.1600       8.50      10.50
+         9       9       9         9          17.1600       9.50       9.50
+        10       9      10         9          18.1600       9.50      10.50
+        10       9      10         9          18.1700       9.50      10.50
+         8      10       8        10          17.1600      10.50       8.50
+         9      10       9        10          18.1600      10.50       9.50
+         9      10       9        10          18.1700      10.50       9.50
+        10      10      10        10          19.1600      10.50      10.50
+        10      10      10        10          19.1700      10.50      10.50
+        10      10      10        10          19.1800      10.50      10.50
+
+[NB: The FITS binary table test file test.ev, as well as the FITS +image test.fits, are contained in the funtools funtest directory.] + +

+When a table is being displayed using fundisp, a second optional +argument can be used to specify the columns to display. For example: +

+  [sh] fundisp "test.ev[time-(int)time>=.99]" "x y time"
+          X        Y                  TIME
+   -------- -------- ---------------------
+          5       -6           40.99000000
+          4       -5           59.99000000
+         -1        0          154.99000000
+         -2        1          168.99000000
+         -3        2          183.99000000
+         -4        3          199.99000000
+         -5        4          216.99000000
+         -6        5          234.99000000
+         -7        6          253.99000000
+
+ +

+The special column $REGION can be specified to display the +region id of each row: +

+  [sh $] fundisp "test.ev[time-(int)time>=.99&&annulus(0 0 0 10 n=3)]" 'x y time $REGION'
+          X        Y                  TIME     REGION
+   -------- -------- --------------------- ----------
+          5       -6           40.99000000          3
+          4       -5           59.99000000          2
+         -1        0          154.99000000          1
+         -2        1          168.99000000          1
+         -3        2          183.99000000          2
+         -4        3          199.99000000          2
+         -5        4          216.99000000          2
+         -6        5          234.99000000          3
+         -7        6          253.99000000          3
+
+

+Here only rows with the proper fractional time and whose position also is +within one of the three annuli are displayed. +

+Columns can be excluded from display using a minus sign before the +column: +

+  [sh $] fundisp "test.ev[time-(int)time>=.99]" "-time"
+          X        Y      PHA         PI          DX          DY
+   -------- -------- -------- ---------- ----------- -----------
+          5       -6        5         -6        5.50       -6.50
+          4       -5        4         -5        4.50       -5.50
+         -1        0       -1          0       -1.50        0.50
+         -2        1       -2          1       -2.50        1.50
+         -3        2       -3          2       -3.50        2.50
+         -4        3       -4          3       -4.50        3.50
+         -5        4       -5          4       -5.50        4.50
+         -6        5       -6          5       -6.50        5.50
+         -7        6       -7          6       -7.50        6.50
+
+All columns except the time column are displayed. +

+The special column $N can be specified to display the +ordinal value of each row. Thus, continuing the previous example: +

+  fundisp "test.ev[time-(int)time>=.99]" '-time $n'
+         X        Y      PHA         PI          DX          DY          N
+   ------- -------- -------- ---------- ----------- ----------- ----------
+         5       -6        5         -6        5.50       -6.50        337
+         4       -5        4         -5        4.50       -5.50        356
+        -1        0       -1          0       -1.50        0.50        451
+        -2        1       -2          1       -2.50        1.50        465
+        -3        2       -3          2       -3.50        2.50        480
+        -4        3       -4          3       -4.50        3.50        496
+        -5        4       -5          4       -5.50        4.50        513
+        -6        5       -6          5       -6.50        5.50        531
+        -7        6       -7          6       -7.50        6.50        550
+
+Note that the column specification is enclosed in single quotes to protect +'$n' from begin expanded by the shell. + +

+In general, the rules for activating and de-activating columns are: +

    +
  • If only exclude columns are specified, then all columns but +the exclude columns will be activated. +
  • If only include columns are specified, then only the specified columns +are activated. +
  • If a mixture of include and exclude columns are specified, then +all but the exclude columns will be active; this last case +is ambiguous and the rule is arbitrary. +
+In addition to specifying columns names explicitly, the special +symbols + and - can be used to activate and +de-activate all columns. This is useful if you want to +activate the $REGION column along with all other columns. According +to the rules, the syntax "$REGION" only activates the region column +and de-activates the rest. Use "+ $REGION" to activate all +columns as well as the region column. + +

+If the data being displayed are image data (either in a FITS primary +image, a FITS image extension, or an array file), an mxn pixel display +is produced, where m and n are the dimensions of the image. By +default, pixel values are displayed using the same data type as in the +file. However, for integer data where the BSCALE and BZERO header parameters +are present, the data is displayed as floats. In either case, the +display data type can be overridden using an optional second argument +of the form: +

+  bitpix=n
+
+where n is 8,16,32,-32,-64, for unsigned char, short, int, float and double, +respectively. + +

+Of course, running fundisp on anything but the smallest image +usually results in a display whose size makes it unreadable. +Therefore, one can uses bracket notation (see below) +to apply section and/or blocking to the image before generating a +display. For example: +

+  [sh] fundisp "test.fits[2:6,2:7]" bitpix=-32
+                     2          3          4          5          6
+            ---------- ---------- ---------- ---------- ----------
+         2:       3.00       4.00       5.00       6.00       7.00
+         3:       4.00       5.00       6.00       7.00       8.00
+         4:       5.00       6.00       7.00       8.00       9.00
+         5:       6.00       7.00       8.00       9.00      10.00
+         6:       7.00       8.00       9.00      10.00      11.00
+         7:       8.00       9.00      10.00      11.00      12.00
+
+ +

+Note that is is possible to display a FITS binary table as an image +simply by passing the table through funimage first: +

+  [sh] ./funimage test.ev stdout | fundisp "stdin[2:6,2:7]" bitpix=8
+                  2       3       4       5       6
+            ------- ------- ------- ------- -------
+         2:       3       4       5       6       7
+         3:       4       5       6       7       8
+         4:       5       6       7       8       9
+         5:       6       7       8       9      10
+         6:       7       8       9      10      11
+         7:       8       9      10      11      12
+
+ +If the -l (list) switch is used, then an image is displayed as a +list containing the columns: X, Y, VAL. For example: +
+  fundisp -l "test1.fits[2:6,2:7]" bitpix=-32
+            X          Y         VAL
+   ---------- ---------- -----------
+            2          2        6.00
+            3          2        1.00
+            4          2        1.00
+            5          2        1.00
+            6          2        1.00
+            2          3        1.00
+            3          3        5.00
+            4          3        1.00
+            5          3        1.00
+            6          3        1.00
+            2          4        1.00
+            3          4        1.00
+            4          4        4.00
+            5          4        1.00
+            6          4        1.00
+            2          5        1.00
+            3          5        1.00
+            4          5        1.00
+            5          5        3.00
+            6          5        1.00
+            2          6        1.00
+            3          6        1.00
+            4          6        1.00
+            5          6        1.00
+            6          6        2.00
+            2          7        1.00
+            3          7        1.00
+            4          7        1.00
+            5          7        1.00
+            6          7        1.00
+
+ +

+If the -n (nohead) switch is used, then no header is output for +tables. This is useful, for example, when fundisp output is being +directed into gnuplot. + +

+The fundisp program uses a default set of display formats: +

+  datatype      TFORM   format
+  --------      -----   --------
+  double        D       "%21.8f"
+  float         E       "%11.2f"
+  int           J       "%10d"
+  short         I       "%8d"
+  byte          B       "%6d"
+  string        A       "%12.12s"
+  bits          X       "%8x"
+  logical       L       "%1x"
+
+Thus, the default display of 1 double and 2 shorts gives: +
+  [sh] fundisp snr.ev "time x y"
+  
+                    TIME        X        Y
+   --------------------- -------- --------
+       79494546.56818075      546      201
+       79488769.94469175      548      201
+       ...
+
+You can change the display format for individual columns or for all +columns of a given data types by means of the -f switch. The format +string that accompanies -f is a space-delimited list of keyword=format +values. The keyword values can either be column names (in which case +the associated format pertains only to that column) or FITS table +TFORM specifiers (in which case the format pertains to all columns +having that data type). For example, you can change the double and +short formats for all columns like this: +
+  [sh] fundisp -f "D=%22.11f I=%3d" snr.ev "time x y"
+  
+                    TIME   X   Y
+  ---------------------- --- ---
+    79494546.56818075478 546 201
+    79488769.94469174743 548 201
+    ...
+
+ +

+Alternatively, you can change the format of the time and x columns like this: +

+  [sh] fundisp -f "time=%22.11f x=%3d" snr.ev "time x y"
+  
+                    TIME   X        Y
+  ---------------------- --- --------
+    79494546.56818075478 546      201
+    79488769.94469174743 548      201
+    ...
+
+Note that there is a potential conflict if a column has the same name +as one of the TFORM specifiers. In the examples above, the the "X" +column in the table has the same name as the X (bit) datatype. To +resolve this conflict, the format string is processed such that +TFORM datatype specifiers are checked for first, using a +case-sensitive comparison. If the specified format value is not an +upper case TFORM value, then a case-insensitive check is made on the +column name. This means that, in the examples above, "X=%3d" will refer +to the X (bit) datatype, while "x=%3d" will refer to the X column: +
+  [sh] fundisp -f "X=%3d" snr.ev "x y"
+  
+         X        Y
+  -------- --------
+       546      201
+       548      201
+       ...
+  
+  [sh] fundisp -f "x=%3d" snr.ev "x y"
+  
+    X        Y
+  --- --------
+  546      201
+  548      201
+  ...
+
+As a rule, therefore, it is best always to specify the column name in +lower case and TFORM data types in upper case. + +

+The -f [format] will change the format for a single execution +of fundisp. You also can use the FUN_FORMAT envronment variable +to change the format for all invocations of fundisp. The format of this +environment variable's value is identical to that used with +the -f switch. This global value can be overridden in +individual cases by use of the -f [format] switch. + +

+Caveats: Please also note that it is the user's responsibility to +match the format specifier to the column data type correctly. Also +note that, in order to maintain visual alignment between names and +columns, the column name will be truncated (on the left) if the +format width is less than the length of the name. However, truncation +is not performed if the output is in RDB format (using the -T switch). + +

+[An older-style format string is supported but deprecated. It +consists of space-delimited C format statements for all data types, +specified in the following order: +

+ double float int short byte string bit.
+
+This order of the list is based on the assumption that people generally +will want to change the float formats. +

+If "-" is entered instead of a format statement for a given data type, the +default format is used. Also, the format string can be terminated without +specifying all formats, and defaults will be used for the rest of the +list. Note that you must supply a minimum field width, i.e., "%6d" and +"%-6d" are legal, "%d" is not legal. + +By using -f [format], you can change the double and short formats like this: +

+  [sh] fundisp -f "22.11f - - 3d" snr.ev "time x y"
+  
+                     TIME   X   Y
+   ---------------------- --- ---
+     79494546.56818075478 546 201
+     79488769.94469174743 548 201
+     ...
+
+NB: This format is deprecated and will be removed in a future release.] + +

+The -F[c] switch can be used to specify a (single-character) +column separator (where the default is a space). Note that column +formatting will almost certainly also add spaces to pad individual +columns to the required width. These can be removed with a program +such as sed, at the cost of generating unaligned columns. For example: +

+fundisp -F',' snr.ev'[cir 512 512 .1]'
+       X,       Y,     PHA,      PI,                 TIME,      DX,      DY
+--------,--------,--------,--------,---------------------,--------,--------
+     512,     512,       6,       7,    79493997.45854475,     578,     574
+     512,     512,       8,       9,    79494575.58943175,     579,     573
+     512,     512,       5,       6,    79493631.03866175,     578,     575
+     512,     512,       5,       5,    79493290.86521725,     578,     575
+     512,     512,       8,       9,    79493432.00990875,     579,     573
+
+fundisp -F',' snr.ev'[cir 512 512 .1]' | sed 's/ *, */,/g'
+       X,Y,PHA,PI,TIME,DX,DY
+--------,--------,--------,--------,---------------------,--------,--------
+     512,512,6,7,79493997.45854475,578,574
+     512,512,8,9,79494575.58943175,579,573
+     512,512,5,6,79493631.03866175,578,575
+     512,512,5,5,79493290.86521725,578,575
+     512,512,8,9,79493432.00990875,579,573
+
+fundisp -f "x=%3d y=%3d pi=%1d pha=%1d time=%20.11f dx=%3d dy=%3d" -F',' snr.ev'[cir 512 512 .1]' | sed 's/ *, */,/g'
+  X,Y,A,I,TIME,DX,DY
+---,---,-,-,--------------------,---,---
+512,512,6,7,79493997.45854474604,578,574
+512,512,8,9,79494575.58943174779,579,573
+512,512,5,6,79493631.03866174817,578,575
+512,512,5,5,79493290.86521725357,578,575
+512,512,8,9,79493432.00990875065,579,573
+
+
+ +

+If the -T (rdb table) switch is used, the output will conform +to starbase/rdb data base format: tabs will be inserted between +columns rather than spaces. This format is not available when +displaying image pixels (except in conjunction with the -l +switch). + +

+Finally, note that fundisp can be used to create column filters from +the auxiliary tables in a FITS file. For example, the following shell code +will generate a good-time interval (GTI) filter for X-ray data files that +contain a standard GTI extension: +

+  #!/bin/sh
+  sed '1,/---- .*/d
+  /^$/,$d' | awk 'tot>0{printf "||"};{printf "time="$1":"$2; tot++}' 
+
+If this script is placed in a file called "mkgti", it can be used in a +command such as: +
+  fundisp foo.fits"[GTI]" | mkgti > gti.filter
+
+The resulting filter file can then be used in various funtools programs: +
+  funcnts foo.fits"[@gti.filter]" ...
+
+to process only the events in the good-time intervals. + + + + +

funhead - display a header in a Funtools file

+ + + +
+funhead  [-a] [-s] [-t] [-L] <iname> [oname ename]
+
+
+ + +

+

+  -a    # display all extension headers
+  -s    # display 79 chars instead of 80 before the new-line
+  -t    # prepend data type char to each line of output
+  -L    # output in rdb/starbase list format
+
+ + +

+funhead displays the FITS header parameters in the specified +FITS Extension. +

+The first argument to the program specifies the Funtools input file +to display. If "stdin" is specified, data are read from +the standard input. Funtools Bracket +Notation is used to specify particular FITS extension to process. +Normally, the full 80 characters of each header card is output, +followed by a new-line. + +

+If the -a switch is specified, the header from each FITS +extensions in the file is displayed. Note, however, that the -a +switch does not work with FITS files input via stdin. We hope to +remove this restriction in a future release. + +

+If the -s switch is specified, only 79 characters are output +before the new-line. This helps the display on 80 character terminals. + +

+If the -t switch is specified, the data type of the parameter +is output as a one character prefix, followed by 77 characters of the +param. The parameter data types are defined as: FUN_PAR_UNKNOWN +('u'), FUN_PAR_COMMENT ('c'), FUN_PAR_LOGICAL ('l'), FUN_PAR_INTEGER +('i'), FUN_PAR_STRING ('s'), FUN_PAR_REAL ('r'), FUN_PAR_COMPLEX ('x'). + +

+If the -L (rdb table) switch is used, the output will conform +to starbase/rdb data base list format. + +

+For example to display the EVENTS extension (binary table): +

+  [sh] funhead "foo.fits[EVENTS]"
+  XTENSION= 'BINTABLE'            /  FITS 3D BINARY TABLE                      
+  BITPIX  =                    8  /  Binary data                               
+  NAXIS   =                    2  /  Table is a matrix                         
+  NAXIS1  =                   20  /  Width of table in bytes                   
+  NAXIS2  =                30760  /  Number of entries in table                
+  PCOUNT  =                    0  /  Random parameter count                    
+  GCOUNT  =                    1  /  Group count                               
+  TFIELDS =                    7  /  Number of fields in each row              
+  EXTNAME = 'EVENTS  '            /  Table name                                
+  EXTVER  =                    1  /  Version number of table                   
+  TFORM1  = '1I      '            /  Data type for field                       
+  TTYPE1  = 'X       '            /  Label for field                           
+  TUNIT1  = '        '            /  Physical units for field                  
+  TFORM2  = '1I      '            /  Data type for field                       
+    etc. ...
+  END                                                                          
+
+ +

+To display the third header: +

+  [sh] funhead "foo.fits[3]"
+  XTENSION= 'BINTABLE'            /  FITS 3D BINARY TABLE                      
+  BITPIX  =                    8  /  Binary data                               
+  NAXIS   =                    2  /  Table is a matrix                         
+  NAXIS1  =                   32  /  Width of table in bytes                   
+  NAXIS2  =                   40  /  Number of entries in table                
+  PCOUNT  =                    0  /  Random parameter count                    
+  GCOUNT  =                    1  /  Group count                               
+  TFIELDS =                    7  /  Number of fields in each row              
+  EXTNAME = 'TGR     '            /  Table name                                
+  EXTVER  =                    1  /  Version number of table                   
+  TFORM1  = '1D      '            /  Data type for field                       
+    etc. ...
+  END                                                                          
+
+ +

+To display the primary header (i.e., extension 0): +

+  sh> funhead "coma.fits[0]"
+  SIMPLE  =                    T /STANDARD FITS FORMAT                         
+  BITPIX  =                   16 /2-BYTE TWOS-COMPL INTEGER                    
+  NAXIS   =                    2 /NUMBER OF AXES                               
+  NAXIS1  =                  800 /                                             
+  NAXIS2  =                  800 /                                             
+  DATATYPE= 'INTEGER*2'          /SHORT INTEGER                                
+  END                                                                          
+
+ +

+The funhead program also can edit (i.e. add, delete, or modify) or +display individual headers parameters. Edit mode is signalled by the +presence of two additional command-line arguments: output file and +edit command file, in that order. Edit mode acts as a filter: the +output file will contain the entire input FITS file, including other +extensions. The edit command file can be "stdin", in which case edit +command are read from the standard input. + +

+The edit command file contains parameter comments (having '#' in the +first column) and delete and assignment(modify or add) operations. A +delete operation is specified by preceding the parameter name with a +minus sign "-". A display operation (very useful in interactive +sessions, i.e., where the edit commands are taken from stdin) is +specified by preceding the parameter name with a question mark "?". In +either case, a parameter value need not be specified. An assignment +operation is specified in the same two ways that a parameter is +specified in a text header (but without the comment character that +precedes header params), i.e.: + +

    +
  • FITS-style comments have an equal sign "=" between the keyword and +value and an optional slash "/" to signify a comment. The strict FITS +rules on column positions are not enforced. + +
  • Free-form comments can have an optional colon separator between the +keyword and value. In the absence of quote, all tokens after the +keyword are part of the value, i.e. no comment is allowed. +
+ +

+For example, the following interactive session checks for the +existence of parameters, adds new parameters, modifies them, and +modifies and deletes existing parameters: +

+  sh$ ./funhead snr.ev foo.fits -
+  # look for FOO1
+  ? FOO1
+  WARNING: FOO1 not found
+  # add new foo1
+  FOO1 = 100
+  # add foo2
+  FOO2 = 200
+  # reset foo1 to a different value
+  FOO1 -1
+  # delete foo2
+  -FOO2
+  # change existing value
+  EXTVER 2
+  ? XS-SORT
+  XS-SORT = 'EOF     '            /  type of event sort
+  # delete existing value
+  -XS-SORT
+  # exit
+  ^D
+
+ +

+See Column-based Text Files +for more information about header parameter format. + +

+ +

+ + + +

funhist - create a 1D histogram of a column (from a FITS binary table or raw event file) or an image

+ + + +
+funhist  [-n|-w|-T] <iname> [column] [[lo:hi:]bins]
+
+
+ + +

+

+  -n    # normalize bin value by the width of each bin
+  -w    # specify bin width instead of number of bins in arg3
+  -T    # output in rdb/starbase format (tab separators)
+
+ + +

+funhist creates a one-dimensional histogram from the specified +columns of a FITS Extension +binary table of a FITS file (or from a non-FITS raw event file), or +from a FITS image or array, and writes that histogram as an ASCII +table. Alternatively, the program can perform a 1D projection of one +of the image axes. + +

+The first argument to the program is required, and specifies the +Funtools file: FITS table or image, raw event file, or array. If +"stdin" is specified, data are read from the standard input. Use +Funtools Bracket Notation to specify FITS +extensions, and filters. + +

+For a table, the second argument also is required. It specifies the +column to use in generating the histogram. If the data file is of +type image (or array), the column is optional: if "x" (or "X"), "y" +(or "Y") is specified, then a projection is performed over the x +(dim1) or y (dim2) axes, respectively. (That is, this projection will +give the same results as a histogram performed on a table containing +the equivalent x,y event rows.) If no column name is specified or +"xy" (or "XY") is specified for the image, then a histogram is +performed on the values contained in the image pixels. + +

+The argument that follows is optional and specifies the number of bins +to use in creating the histogram and, if desired, the range of bin +values. For image and table histograms, the range should specify the +min and max data values. For image histograms on the x and y axes, +the range should specify the min and max image bin values. If this +argument is omitted, the number of output bins for a table is +calculated either from the TLMIN/TLMAX headers values (if these exist +in the table FITS header for the specified column) or by going through +the data to calculate the min and max value. For an image, the number +of output bins is calculated either from the DATAMIN/DATAMAX header +values, or by going through the data to calculate min and max value. +(Note that this latter calculation might fail if the image cannot be +fit in memory.) If the data are floating point (table or image) and +the number of bins is not specified, an arbitrary default of 128 is +used. + +

+For binary table processing, the -w (bin width) switch can be used +to specify the width of each bin rather than the number of bins. Thus: +

+  funhist test.ev pha 1:100:5
+
+means that 5 bins of width 20 are used in the histogram, while: +
+  funhist -w test.ev pha 1:100:5
+
+means that 20 bins of width 5 are used in the histogram. + +

+The data are divvied up into the specified number of bins and the +resulting 1D histogram (or projection) is output in ASCII table +format. For a table, the output displays the low_edge (inclusive) and +hi_edge (exclusive) values for the data. For example, a 15-row table +containing a "pha" column whose values range from -7.5 to 7.5 +can be processed thus: + +

+  [sh] funhist test.ev pha
+  # data file:        /home/eric/data/test.ev
+  # column:           pha
+  # min,max,bins:     -7.5 7.5 15
+  
+     bin     value               lo_edge               hi_edge
+  ------ --------- --------------------- ---------------------
+       1        22           -7.50000000           -6.50000000
+       2        21           -6.50000000           -5.50000000
+       3        20           -5.50000000           -4.50000000
+       4        19           -4.50000000           -3.50000000
+       5        18           -3.50000000           -2.50000000
+       6        17           -2.50000000           -1.50000000
+       7        16           -1.50000000           -0.50000000
+       8        30           -0.50000000            0.50000000
+       9        16            0.50000000            1.50000000
+      10        17            1.50000000            2.50000000
+      11        18            2.50000000            3.50000000
+      12        19            3.50000000            4.50000000
+      13        20            4.50000000            5.50000000
+      14        21            5.50000000            6.50000000
+      15        22            6.50000000            7.50000000
+  
+  [sh] funhist test.ev pha 1:6
+  # data file:          /home/eric/data/test.ev
+  # column:             pha
+  # min,max,bins:       0.5 6.5 6
+  
+     bin     value               lo_edge               hi_edge
+  ------ --------- --------------------- ---------------------
+       1        16            0.50000000            1.50000000
+       2        17            1.50000000            2.50000000
+       3        18            2.50000000            3.50000000
+       4        19            3.50000000            4.50000000
+       5        20            4.50000000            5.50000000
+       6        21            5.50000000            6.50000000
+  
+  [sh] funhist test.ev pha 1:6:3
+  # data file:          /home/eric/data/test.ev
+  # column:             pha
+  # min,max,bins:       0.5 6.5 3
+  
+     bin     value               lo_edge               hi_edge
+  ------ --------- --------------------- ---------------------
+       1        33            0.50000000            2.50000000
+       2        37            2.50000000            4.50000000
+       3        41            4.50000000            6.50000000
+
+ +

+For a table histogram, the -n(normalize) switch can be used to +normalize the bin value by the width of the bin (i.e., hi_edge-lo_edge): +

+  [sh] funhist -n test.ev pha 1:6:3 
+  # data file:          test.ev
+  # column:             pha
+  # min,max,bins:       0.5 6.5 3
+  # width normalization (val/(hi_edge-lo_edge)) is applied
+  
+     bin                 value               lo_edge               hi_edge
+  ------ --------------------- --------------------- ---------------------
+       1           16.50000000            0.50000000            2.50000000
+       2            6.16666667            2.50000000            4.50000000
+       3            4.10000000            4.50000000            6.50000000
+
+This could used, for example, to produce a light curve with values +having units of counts/second instead of counts. + +

+For an image histogram, the output displays the low and high image +values (both inclusive) used to generate the histogram. For example, +in the following example, 184 pixels had a value of 1, 31 had a value +of 2, while only 2 had a value of 3,4,5,6, or 7: +

+  [sh] funhist test.fits
+  # data file:           /home/eric/data/test.fits
+  # min,max,bins:        1 7 7
+  
+     bin                 value                lo_val                hi_val
+  ------ --------------------- --------------------- ---------------------
+       1          184.00000000            1.00000000            1.00000000
+       2           31.00000000            2.00000000            2.00000000
+       3            2.00000000            3.00000000            3.00000000
+       4            2.00000000            4.00000000            4.00000000
+       5            2.00000000            5.00000000            5.00000000
+       6            2.00000000            6.00000000            6.00000000
+       7            2.00000000            7.00000000            7.00000000
+
+ +

+For the axis projection of an image, the output displays the low and +high image bins (both inclusive) used to generate the projection. For +example, in the following example, 21 counts had their X bin value of +2, etc.: +

+  [sh] funhist test.fits x 2:7
+  # data file:            /home/eric/data/test.fits
+  # column:               X
+  # min,max,bins: 2 7 6
+   
+     bin                 value                lo_bin                hi_bin
+  ------ --------------------- --------------------- ---------------------
+       1           21.00000000            2.00000000            2.00000000
+       2           20.00000000            3.00000000            3.00000000
+       3           19.00000000            4.00000000            4.00000000
+       4           18.00000000            5.00000000            5.00000000
+       5           17.00000000            6.00000000            6.00000000
+       6           16.00000000            7.00000000            7.00000000
+  
+  [sh] funhist test.fits x 2:7:2
+  # data file:            /home/eric/data/test.fits
+  # column:               X
+  # min,max,bins: 2 7 2
+   
+     bin                 value                lo_bin                hi_bin
+  ------ --------------------- --------------------- ---------------------
+       1           60.00000000            2.00000000            4.00000000
+       2           51.00000000            5.00000000            7.00000000
+
+ +

+You can use gnuplot or other plotting programs to graph the +results, using a script such as: +

+  #!/bin/sh
+  sed -e '1,/---- .*/d
+  /^$/,$d' | \
+  awk '\
+  BEGIN{print "set nokey; set title \"funhist\"; set xlabel \"bin\"; set ylabel \"counts\"; plot \"-\" with boxes"}   \
+  {print $3, $2, $4-$3}'        | \
+  gnuplot -persist - 1>/dev/null 2>&1
+
+ +Similar plot commands are supplied in the script funhist.plot: +
+  funhist test.ev pha ...  | funhist.plot gnuplot
+
+ + + + +

funimage - create a FITS image from a Funtools data file

+ + + +
+funimage [-a] <iname> <oname> [bitpix=n]
+funimage [-l] <iname> <oname> <xcol:xdims> <ycol:ydims> <vcol> [bitpix=n]
+funimage [-p x|y] <iname> <oname> [bitpix=n]
+
+
+ + +

+

+  -a       # append to existing output file as an image extension
+  -l       # input is a list file containing xcol, ycol, value
+  -p [x|y] # project along x or y axis to create a 1D image
+
+ + +

+funimage creates a primary FITS image from the specified +FITS Extension +and/or +Image Section +of a FITS file, or from an +Image Section +of a non-FITS array, or from a raw event file. +

+The first argument to the program specifies the FITS input image, +array, or raw event file to process. If "stdin" is specified, data are +read from the standard input. Use Funtools +Bracket Notation to specify FITS extensions, image sections, and +filters. The second argument is the output FITS file. If "stdout" is +specified, the FITS image is written to the standard output. By +default, the output pixel values are of the same data type as those of the +input file (or type "int" when binning a table), but this can be +overridden using an optional third argument of the form: +

+  bitpix=n
+
+where n is 8,16,32,-32,-64, for unsigned char, short, int, float and double, +respectively. + +

+If the input data are of type image, the appropriate section is +extracted and blocked (based on how the +Image Section is specified), and +the result is written to the FITS primary image. When an integer +image containing the BSCALE and BZERO keywords is converted to float, +the pixel values are scaled and the scaling keywords are deleted from the +output header. When converting integer scaled data to integer +(possibly of a different size), the pixels are not scaled and the +scaling keywords are retained. + +

+If the input data is a binary table or raw event file, these are +binned into an image, from which a section is extracted and blocked, +and written to a primary FITS image. In this case, it is necessary to +specify the two columns that will be used in the 2D binning. This can +be done on the command line using the bincols=(x,y) keyword: +

+  funcnts "foo.ev[EVENTS,bincols=(detx,dety)]"
+
+The full form of the bincols= specifier is: +
+  bincols=([xname[:tlmin[:tlmax:[binsiz]]]],[yname[:tlmin[:tlmax[:binsiz]]]])
+
+where the tlmin, tlmax, and binsiz specifiers determine the image binning +dimensions: +
+  dim = (tlmax - tlmin)/binsiz     (floating point data)
+  dim = (tlmax - tlmin)/binsiz + 1 (integer data)
+
+Using this syntax, it is possible to bin any two columns of a binary +table at any bin size. Note that the tlmin, tlmax, and binsiz +specifiers can be omitted if TLMIN, TLMAX, and TDBIN header parameters +(respectively) are present in the FITS binary table header for the +column in question. Note also that if only one parameter is specified, +it is assumed to be tlmax, and tlmin defaults to 1. If two parameters +are specified, they are assumed to be tlmin and tlmax. +See Binning FITS Binary Tables and Non-FITS +Event Files for more information about binning parameters. + +

+By default, a new 2D FITS image file is created and the image is written +to the primary HDU. If the -a (append) switch is specified, +the image is appended to an existing FITS file as an IMAGE extension. +(If the output file does not exist, the switch is effectively ignored +and the image is written to the primary HDU.) This can be useful in a +shell programming environment when processing multiple FITS images +that you want to combine into a single final FITS file. + +

+funimage also can take input from a table containing columns of +x, y, and value (e.g., the output from fundisp -l which +displays each image x and y and the number of counts at that +position.) When the -l (list) switch is used, the input file is +taken to be a FITS or ASCII table containing (at least) three columns +that specify the x and y image coordinates and the value of that +image pixel. In this case, funimage requires four extra +arguments: xcolumn:xdims, ycolumn:ydims, vcolumn and bitpix=n. The x +and y col:dim information takes the form: +

+  name:dim               # values range from 1 to dim
+  name:min:max           # values range from min to max
+  name:min:max:binsiz    # dimensions scaled by binsize
+
+In particular, the min value should be used whenever the +minimum coordinate value is something other than one. For example: +
 
+  funimage -l foo.lst foo.fits xcol:0:512 ycol:0:512 value bitpix=-32
+
+ +

+The list feature also can be used to read unnamed columns from standard +input: simply replace the column name with a null string. Note +that the dimension information is still required: +

+  funimage -l stdin foo.fits "":0:512 "":0:512 "" bitpix=-32
+  240 250 1
+  255 256 2
+  ...
+  ^D
+
+ +

+The list feature provides a simple way to generate a blank image. +If you pass a Column-based Text File +to funimage in which the text header contains the required image +information, then funimage will correctly make a blank image. For +example, consider the following text file (called foo.txt): +

+  x:I:1:10  y:I:1:10
+  ------    ------
+  0         0
+
+This text file defines two columns, x and y, each of data type 32-bit int and +image dimension 10. The command: +
+  funimage foo.txt foo.fits bitpix=8
+
+will create an empty FITS image called foo.fits containing a 10x10 +image of unsigned char: +
+  fundisp foo.fits
+           1      2      3      4      5      6      7      8      9     10
+      ------ ------ ------ ------ ------ ------ ------ ------ ------ ------
+  10:      0      0      0      0      0      0      0      0      0      0
+   9:      0      0      0      0      0      0      0      0      0      0
+   8:      0      0      0      0      0      0      0      0      0      0
+   7:      0      0      0      0      0      0      0      0      0      0
+   6:      0      0      0      0      0      0      0      0      0      0
+   5:      0      0      0      0      0      0      0      0      0      0
+   4:      0      0      0      0      0      0      0      0      0      0
+   3:      0      0      0      0      0      0      0      0      0      0
+   2:      0      0      0      0      0      0      0      0      0      0
+   1:      1      0      0      0      0      0      0      0      0      0
+
+
+ +Note that the text file must contain at least +one row of data. However, in the present example, event position 0,0 is +outside the limits of the image and will be ignored. (You can, of course, +use real x,y values to seed the image with data.) + +

+Furthermore, you can use the TEXT filter specification to obviate the need for +an input text file altogether. The following command will create the same +10x10 char image without an actual input file: +

+  funimage stdin'[TEXT(x:I:10,y:I:10)]' foo.fits bitpix=8 < /dev/null
+or
+  funimage /dev/null'[TEXT(x:I:10,y:I:10)]' foo.fits bitpix=8
+
+ +

+You also can use either of these methods to generate a region mask simply +by appending a region inside the filter brackets and specfying mask=all +along with the bitpix. For example, the following command will generate a +10x10 char mask using 3 regions: +

+  funimage stdin'[TEXT(x:I:10,y:I:10),cir(5,5,4),point(10,1),-cir(5,5,2)]' \
+  foo.fits bitpix=8,mask=all < /dev/null
+
+The resulting mask looks like this: +
+  fundisp foo.fits
+           1      2      3      4      5      6      7      8      9     10
+      ------ ------ ------ ------ ------ ------ ------ ------ ------ ------
+  10:      0      0      0      0      0      0      0      0      0      0
+   9:      0      0      0      0      0      0      0      0      0      0
+   8:      0      0      1      1      1      1      1      0      0      0
+   7:      0      1      1      1      1      1      1      1      0      0
+   6:      0      1      1      0      0      0      1      1      0      0
+   5:      0      1      1      0      0      0      1      1      0      0
+   4:      0      1      1      0      0      0      1      1      0      0
+   3:      0      1      1      1      1      1      1      1      0      0
+   2:      0      0      1      1      1      1      1      0      0      0
+   1:      0      0      0      0      0      0      0      0      0      2
+
+ +

+You can use funimage to create 1D image projections along the x +or y axis using the -p [x|y] switch. This capability works for +both images and tables. For example consider a FITS table named ev.fits +containing the following rows: +

+         X        Y
+  -------- --------
+         1        1
+         1        2
+         1        3
+         1        4
+         1        5
+         2        2
+         2        3
+         2        4
+         2        5
+         3        3
+         3        4
+         3        5
+         4        4
+         4        5
+         5        5
+
+
+A corresponding 5x5 image, called dim2.fits, would therefore contain: +
+              1          2          3          4          5
+     ---------- ---------- ---------- ---------- ----------
+  5:          1          1          1          1          1
+  4:          1          1          1          1          0
+  3:          1          1          1          0          0
+  2:          1          1          0          0          0
+  1:          1          0          0          0          0
+
+A projection along the y axis can be performed on either the table or +the image: +
+  funimage -p y ev.fits stdout | fundisp stdin
+              1          2          3          4          5
+     ---------- ---------- ---------- ---------- ----------
+  1:          1          2          3          4          5
+
+  funimage -p y dim2.fits stdout | fundisp stdin
+              1          2          3          4          5
+     ---------- ---------- ---------- ---------- ----------
+  1:          1          2          3          4          5
+
+ +

+Furthermore, you can create a 1D image projection along any column of +a table by using the bincols=[column] filter specification and +specifying a single column. For example, the following command +projects the same 1D image along the y axis of a table as use of +the -p y switch: +

+  funimage ev.fits'[bincols=y]' stdout | fundisp stdin 
+              1          2          3          4          5
+     ---------- ---------- ---------- ---------- ----------
+  1:          1          2          3          4          5
+
+ +

+Examples: +

+Create a FITS image from a FITS binary table: +

+  [sh] funimage test.ev test.fits
+
+ +

+Display the FITS image generated from a blocked section of FITS binary table: +

+  [sh]  funimage "test.ev[2:8,3:7,2]" stdout | fundisp stdin
+                    1         2         3
+            --------- --------- ---------
+         1:        20        28        36
+         2:        28        36        44
+
+ + + + +

funindex - create an index for a column of a FITS binary table

+ + + +
+funindex <switches>  <iname> <key> [oname]
+
+
+ + +

+

+  NB: these options are not compatible with Funtools processing. Please
+  use the defaults instead.
+  -c        # compress output using gzip"
+  -a        # ASCII output, ignore -c (default: FITS table)"
+  -f        # FITS table output (default: FITS table)"
+  -l        # long output, i.e. with key value(s) (default: long)"
+  -s        # short output, i.e. no key value(s) (default: long)"
+
+ + +

+The funindex script creates an index for the specified column (key) by +running funtable -s (sort) and then saving the column value and the +record number for each sorted row. This index will be used automatically + by funtools filtering of that column, provided the index file's modification +date is later than that of the data file. + +

+The first required argument is the name of the FITS binary table +to index. Please note that text files cannot be indexed at this time. +The second required argument is the column (key) name to index. While +multiple keys can be specified in principle, the funtools index processing +assume a single key and will not recognize files containing multiple keys. + +

+By default, the output index file name is [root]_[key].idx, where [root] +is the root of the input file. Funtools looks for this specific file name +when deciding whether to use an index for faster filtering. Therefore, the +optional third argument (output file name) should not be used for funtools +processing. + +

+For example, to create an index on column Y for a given FITS file, use: +

+  funindex foo.fits Y
+
+This will generate an index named foo_y.idx, which will be used by funtools +for filters involving the Y column. + + + + +

funjoin - join two or more FITS binary tables on specified columns

+ + + +
+funjoin [switches] <ifile1> <ifile2> ... <ifilen> <ofile> 
+
+
+ + +

+

+  -a  cols             # columns to activate in all files
+  -a1 cols ... an cols # columns to activate in each file
+  -b  'c1:bvl,c2:bv2'  # blank values for common columns in all files
+  -bn 'c1:bv1,c2:bv2'  # blank values for columns in specific files
+  -j  col              # column to join in all files
+  -j1 col ... jn col   # column to join in each file
+  -m min               # min matches to output a row
+  -M max               # max matches to output a row
+  -s                   # add 'jfiles' status column
+  -S col               # add col as status column
+  -t tol               # tolerance for joining numeric cols [2 files only]
+
+ + +funjoin joins rows from two or more (up to 32) +FITS Binary Table files, based on the values +of specified join columns in each file. NB: the join columns must have +an index file associated with it. These files are generated using the +funindex program. + +

+The first argument to the program specifies the first input FITS table +or raw event file. If "stdin" is specified, data are read from the +standard input. Subsequent arguments specify additional event files +and tables to join. The last argument is the output FITS file. + +

+NB: Do not use Funtools Bracket +Notation to specify FITS extensions and row filters when running +funjoin or you will get wrong results. Rows are accessed and joined +using the index files directly, and this bypasses all filtering. + +

+The join columns are specified using the -j col switch (which +specifies a column name to use for all files) or with -j1 col1, +-j2 col2, ... -jn coln switches (which specify a column +name to use for each file). A join column must be specified for each file. +If both -j col and -jn coln are specified for a given +file, then the latter is used. Join columns must either be of type +string or type numeric; it is illegal to mix numeric and string +columns in a given join. For example, to join three files using the +same key column for each file, use: +

+  funjoin -j key in1.fits in2.fits in3.fits out.fits
+
+A different key can be specified for the third file in this way: +
+  funjoin -j key -j3 otherkey in1.fits in2.fits in3.fits out.fits
+
+ +

+The -a "cols" switch (and -a1 "col1", +-a2 "cols2" counterparts) can be used to specify columns to +activate (i.e. write to the output file) for each input file. By +default, all columns are output. + +

+If two or more columns from separate files have the same name, the +second (and subsequent) columns are renamed to have an underscore +and a numeric value appended. + +

+The -m min and -M max switches specify the minimum +and maximum number of joins required to write out a row. The default +minimum is 0 joins (i.e. all rows are written out) and the default maximum +is 63 (the maximum number of possible joins with a limit of 32 input files). +For example, to write out only those rows in which exactly two files +have columns that match (i.e. one join): +

+  funjoin -j key -m 1 -M 1 in1.fits in2.fits in3.fits ... out.fits
+
+ +

+A given row can have the requisite number of joins without all of the +files being joined (e.g. three files are being joined but only two +have a given join key value). In this case, all of the columns of the +non-joined file are written out, by default, using blanks (zeros or NULLs). +The -b c1:bv1,c2:bv2 and +-b1 'c1:bv1,c2:bv2' -b2 'c1:bv1,c2:bv2' ... +switches can be used to set the blank value for columns common to all +files and/or columns in a specified file, respectively. Each blank value +string contains a comma-separated list of column:blank_val specifiers. +For floating point values (single or double), a case-insensitive string +value of "nan" means that the IEEE NaN (not-a-number) should be +used. Thus, for example: +

+  funjoin -b "AKEY:???" -b1 "A:-1" -b3 "G:NaN,E:-1,F:-100" ...
+
+means that a non-joined AKEY column in any file will contain the +string "???", the non-joined A column of file 1 will contain a value +of -1, the non-joined G column of file 3 will contain IEEE NaNs, while +the non-joined E and F columns of the same file will contain values -1 +and -100, respectively. Of course, where common and specific blank values +are specified for the same column, the specific blank value is used. + +

+To distinguish which files are non-blank components of a given row, +the -s (status) switch can be used to add a bitmask column named +"JFILES" to the output file. In this column, a bit is set for each +non-blank file composing the given row, with bit 0 corresponds to the +first file, bit 1 to the second file, and so on. The file names +themselves are stored in the FITS header as parameters named JFILE1, +JFILE2, etc. The -S col switch allows you to change the name +of the status column from the default "JFILES". + +

+A join between rows is the Cartesian product of all rows in one file +having a given join column value with all rows in a second file having +the same value for its join column and so on. Thus, if file1 has 2 +rows with join column value 100, file2 has 3 rows with the same value, +and file3 has 4 rows, then the join results in 2*3*4=24 rows being output. + +

+The join algorithm directly processes the index file associated with +the join column of each file. The smallest value of all the current +columns is selected as a base, and this value is used to join +equal-valued columns in the other files. In this way, the index files +are traversed exactly once. + +

+The -t tol switch specifies a tolerance value for numeric +columns. At present, a tolerance value can join only two files at a +time. (A completely different algorithm is required to join more than +two files using a tolerance, somethng we might consider implementing +in the future.) + +

+The following example shows many of the features of funjoin. The input files +t1.fits, t2.fits, and t3.fits contain the following columns: +

+  [sh] fundisp t1.fits
+        AKEY    KEY      A      B 
+ ----------- ------ ------ ------
+         aaa      0      0      1
+         bbb      1      3      4
+         ccc      2      6      7
+         ddd      3      9     10
+         eee      4     12     13
+         fff      5     15     16
+         ggg      6     18     19
+         hhh      7     21     22
+
+fundisp t2.fits
+        AKEY    KEY      C      D 
+ ----------- ------ ------ ------
+         iii      8     24     25
+         ggg      6     18     19
+         eee      4     12     13
+         ccc      2      6      7
+         aaa      0      0      1
+
+fundisp t3.fits
+        AKEY    KEY        E        F           G
+------------ ------ -------- -------- -----------
+         ggg      6       18       19      100.10
+         jjj      9       27       28      200.20
+         aaa      0        0        1      300.30
+         ddd      3        9       10      400.40
+
+ +

+Given these input files, the following funjoin command: +

+
+  funjoin -s -a1 "-B" -a2 "-D" -a3 "-E" -b \
+  "AKEY:???" -b1 "AKEY:XXX,A:255" -b3 "G:NaN,E:-1,F:-100" \
+  -j key t1.fits t2.fits t3.fits foo.fits
+
+will join the files on the KEY column, outputting all columns except B +(in t1.fits), D (in t2.fits) and E (in t3.fits), and setting blank +values for AKEY (globally, but overridden for t1.fits) and A (in file +1) and G, E, and F (in file 3). A JFILES column will be output to +flag which files were used in each row: +
+
+        AKEY    KEY      A       AKEY_2  KEY_2      C       AKEY_3  KEY_3        F           G   JFILES
+  ------------ ------ ------ ------------ ------ ------ ------------ ------ -------- ----------- --------
+         aaa      0      0          aaa      0      0          aaa      0        1      300.30        7
+         bbb      1      3          ???      0      0          ???      0     -100         nan        1
+         ccc      2      6          ccc      2      6          ???      0     -100         nan        3
+         ddd      3      9          ???      0      0          ddd      3       10      400.40        5
+         eee      4     12          eee      4     12          ???      0     -100         nan        3
+         fff      5     15          ???      0      0          ???      0     -100         nan        1
+         ggg      6     18          ggg      6     18          ggg      6       19      100.10        7
+         hhh      7     21          ???      0      0          ???      0     -100         nan        1
+         XXX      0    255          iii      8     24          ???      0     -100         nan        2
+         XXX      0    255          ???      0      0          jjj      9       28      200.20        4
+
+
+ + + +

funmerge - merge one or more Funtools table files

+ + + +
+funmerge  [-w|-x] -f [colname] <iname1> <iname2>  ... <oname>
+
+
+ + +

+

+  -f    # output a column specifying file from which this event came
+  -w    # adjust position values using WCS info
+  -x    # adjust position values using WCS info and save old values
+
+ + +

+funmerge merges FITS data from one or more +FITS Binary Table files +or raw event files. +

+The first argument to the program specifies the first input FITS table +or raw event file. If "stdin" is specified, data are read from the +standard input. Use Funtools Bracket +Notation to specify FITS extensions and row filters. Subsequent +arguments specify additional event files and tables to merge. (NB: Stdin +cannot not be used for any of these additional input file arguments.) +The last argument is the output FITS file. The columns in each input table +must be identical. + +

+If an input file begins with the '@' character, it is processed as an +include file, i.e., as a text file containing event file names (as +well as blank lines and/or comment lines starting with the '#' sign). +If standard input is specified as an include file ('@stdin'), then +file names are read from the standard input until EOF (^D). Event +files and include files can be mixed on a command line. + +

+Rows from each table are written sequentially to the output +file. If the switch -f [colname] is specified on the command +line, an additional column is added to each row containing the number +of the file from which that row was taken (starting from one). In +this case, the corresponding file names are stored in the header +parameters having the prefix FUNFIL, i.e., FUNFIL01, +FUNFIL02, etc. + +

+Using the -w switch (or -x switch as described +below), funmerge also can adjust the position column values +using the WCS information in each file. (By position columns, we mean +the columns that the table is binned on, i.e., those columns defined +by the bincols= switch, or (X,Y) by default.) To perform WCS +alignment, the WCS of the first file is taken as the base WCS. Each +position in subsequent files is adjusted by first converting it to the +sky coordinate in its own WCS coordinate system, then by converting +this sky position to the sky position of the base WCS, and finally +converting back to a pixel position in the base system. Note that in +order to perform WCS alignment, the appropriate WCS and TLMIN/TLMAX +keywords must already exist in each FITS file. +

+When performing WCS alignment, you can save the original positions in +the output file by using the -x (for "xtra") switch instead +of the -w switch (i.e., using this switch also implies using +-w) The old positions are saved in columns having the same +name as the original positional columns, with the added prefix "OLD_". +

+Examples: + +

+Merge two tables, and preserve the originating file number for +each row in the column called "FILE" (along with the corresponding +file name in the header): +

+  [sh] funmerge -f "FILE" test.ev test2.ev merge.ev
+
+ +

+Merge two tables with WCS alignment, saving the old position values in +2 additional columns: +

+  [sh] funmerge -x test.ev test2.ev merge.ev
+
+ +

+This program only works on raw event files and binary tables. We have +not yet implemented image and array merging. + + + + +

funsky - convert between image and sky coordinates

+ + + +
+  funsky iname[ext]               # RA,Dec (deg) or image pix from stdin
+  funsky iname[ext] [lname]       # RA, Dec (deg) or image pix from list
+  funsky iname[ext] [col1] [col2]         # named cols:units from stdin
+  funsky iname[ext] [lname] [col1] [col2] # named cols:units from list
+
+
+ + +

+

+  -d        # always use integer tlmin conversion (as ds9 does)
+  -r        # convert x,y to RA,Dec (default: convert RA,Dec to x,y)
+  -o        # include offset from the nominal target position (in arcsec)
+  -v        # display input values also (default: display output only)
+  -T        # output display in rdb format (w/header,tab delimiters)
+
+ + +

+Funsky converts input sky coordinates (RA, Dec) to image coordinates (or vice +versa) using the WCS information contained in the specified FITS file. Several +calling sequences are supported in order to make it easy to specify +coordinate positions in different ways. + +

+The first required argument is always the input FITS file (or +extension) containing the WCS information in an extension header. Note +that the data from this file is not used. By default, the program +converts input RA and Dec values to X and Y using this WCS +information. If the WCS is associated with a FITS image, then the X,Y +values are image values. If the WCS is associated with a binary table, +then the X, Y values are physical values. To convert X,Y to RA and +Dec, use the -r (reverse) switch. + +

+If no other command arguments are supplied, then the input positions +are read from the standard input. Each line is assumed to contain a +single coordinate position consisting of an RA in degrees (or X in +pixels) followed by a Dec in degrees (or Y in pixels). The usual +delimiters are supported (spaces, commas, tabs). For example: +

+ # read from stdin, default column names and units
+ [sh] funsky snr.ev
+ 22.982695    58.606523   # input RA (hrs), Dec(deg)
+    510.00       510.00
+ 22.982127    58.607634   # input
+    512.00       510.50
+ 22.981700    58.614301   # input
+    513.50       513.50
+ ^D                       # end of input
+
+ +

+If a second argument is supplied, this argument is assumed to be +a file containing RA (X) and Dec (Y) positions. The file can either be +an ASCII table or a FITS binary table. The order of columns is +unimportant, if the table has a column header. In this case, the +names of the columns must be one of "RA", "DEC", or "X", "Y" for sky +to image and image to sky conversions, respectively. If the table has +no header, then once again, RA (X) is assumed to first, followed +by DEC (Y). +For example: +

+  # read from file, default column names and units
+  [sh] cat hd.in
+         RA          DEC
+  ---------    ---------
+  22.982695    58.606523
+  22.982127    58.607634
+  22.981700    58.614301
+
+  [sh] funsky snr.ev hd.in
+        510.00       510.00
+        512.00       510.50
+        513.50       513.50
+
+ +

+If three arguments are supplied, then the input positions again are +read from the standard input. Each line is assumed to contain a single +coordinate position consisting of an RA (or X in pixels) followed by a +Dec (or Y in pixels), with the usual delimiters supported. However, +the second and third arguments now specify the column names and/or +sky units using a colon-delimited syntax: +

+  [colname]:[h|d|r]
+
+If the colname is omitted, the names default to "RA", "DEC", "X", "Y", +"COL1", or "COL2" as above. If the units are omitted, the default is degrees +for both RA and Dec. When the -r switch is used (convert from image +to sky) the units are applied to the output instead of the input. The following +examples will serve to illustrate the options: +
+  # read from stdin, specifying column names (def. units: degrees)
+  [sh] cat hd.in
+       MYRA        MYDEC
+  ---------    ---------
+  22.982695    58.606523
+  22.982127    58.607634
+  22.981700    58.614301
+
+  [sh] funsky snr.ev MYRA MYDEC < hd.in
+        510.00       510.00
+        512.00       510.50
+        513.50       513.50
+
+  # read from stdin, specifying column names and units
+  [sh] cat dd.in
+       MYRA        MYDEC
+  ---------    ---------
+  344.740432    58.606523
+  344.731900    58.607634
+  344.725500    58.614301
+
+  [sh] funsky snr.ev MYRA:d MYDEC:d < dd.in
+        510.00       510.00
+        512.00       510.50
+        513.50       513.50
+
+  # read stdin, convert image to sky, specifying output sky units
+  [sh] cat im.in
+        510.00       510.00
+        512.00       510.50
+        513.50       513.50
+
+  [sh] cat im.in | funsky -r snr.ev :d :d
+  344.740432    58.606523
+  344.731900    58.607634
+  344.725500    58.614301
+
+ +

+Finally, four command arguments specify both and input file and column names +and/or units: +

+  [sh] cat dd.in
+       MYRA        MYDEC
+  ---------    ---------
+  344.740432    58.606523
+  344.731900    58.607634
+  344.725500    58.614301
+
+  [sh] funsky snr.ev dd.in MYRA:d MYDEC:d
+        510.00       510.00
+        512.00       510.50
+        513.50       513.50
+
+  # read file, convert image to sky, specifying output sky units
+  [sh] cat im.in
+        510.00       510.00
+        512.00       510.50
+        513.50       513.50
+
+  [sh] funsky -r snr.ev im.in :d :d
+    344.740432    58.606523
+    344.731900    58.607634
+    344.725500    58.614301
+
+ +

+By default, the output of funsky consists only of the converted coordinate +position(s), one per output line. This makes parsing in shell scripts easy. +Use the -v (verbose) switch to specify that the input +coordinates should be pre-pended to each line. For example: +

+  [sh] cat dd.in
+       MYRA        MYDEC
+  ---------    ---------
+  344.740432    58.606523
+  344.731900    58.607634
+  344.725500    58.614301
+
+  [sh] funsky snr.ev dd.in MYRA:d MYDEC:d
+        510.00       510.00
+        512.00       510.50
+        513.50       513.50
+
+  [sh] funsky -v snr.ev dd.in MYRA:d MYDEC:d
+    344.740432    58.606523       510.00       510.00
+    344.731900    58.607634       512.00       510.50
+    344.725500    58.614301       513.50       513.50
+
+ +

+In addition, a full starbase table can be output using the -T +(table) switch. This switch can be used with or without the -v +switch. If the -T and -v are both specified, then a descriptive header +parameters are output before the table (mainly to remind you of the +sky units): +

+  # output table in non-verbose mode
+  [sh] funsky -T snr.ev dd.in MYRA:d MYDEC:d
+             X               Y
+  ------------    ------------
+        510.00          510.00
+        512.00          510.50
+        513.50          513.50
+  
+  # output table in verbose mode
+  [sh] funsky -T -v snr.ev dd.in MYRA:d MYDEC:d
+  # IFILE = /Users/eric/data/snr.ev
+  # ICOL1 = MYRA
+  # ICOL2 = MYDEC
+  # IUNITS1 = d
+  # IUNITS2 = d
+  # OCOL1 = X
+  # OCOL2 = Y
+  
+          MYRA           MYDEC               X               Y
+  ------------    ------------    ------------    ------------
+    344.740432       58.606523          510.00          510.00
+    344.731900       58.607634          512.00          510.50
+    344.725500       58.614301          513.50          513.50
+
+ +

+Finally, the -d (ds9) switch mimicks ds9's use of integer TLMIN +and TLMAX values for all coordinate transformations. FITS conventions +seem to call for use of floating point TLMIN and TLMAX when the data are +floats. This convention is followed by funsky but results in a +small discrepancy with ds9's converted values for floating point +data. We will remedy this conflict in the future, maybe. + + + + +

funtable - copy selected rows from a Funtools file to a FITS binary table

+ + + +
+funtable [-a] [-i|-z] [-m] [-s cols] <iname> <oname> [columns]
+
+
+ + +

+

+  -a    # append to existing output file as a table extension
+  -i    # for image data, only generate X and Y columns
+  -m    # for tables, write a separate file for each region
+  -s "col1 ..." # columns on which to sort
+  -z    # for image data, output zero-valued pixels
+
+ + +

+funtable selects rows from the specified +FITS Extension +(binary table only) of a FITS file, or from a non-FITS raw event +file, and writes those rows to a FITS binary table file. It also +will create a FITS binary table from an image or a raw array file. + +

+The first argument to the program specifies the FITS file, raw event +file, or raw array file. If "stdin" is specified, data are read from +the standard input. Use Funtools Bracket +Notation to specify FITS extensions, and filters. The second +argument is the output FITS file. If "stdout" is specified, the FITS +binary table is written to the standard output. By default, all +columns of the input file are copied to the output file. Selected +columns can be output using an optional third argument in the form: +

+  "column1 column1 ... columnN"
+
+ +

+The funtable program generally is used to select rows from a +FITS binary table using +Table Filters +and/or +Spatial Region Filters. +For example, you can copy only selected rows (and output only selected +columns) by executing in a command such as: +

+  [sh] funtable "test.ev[pha==1&&pi==10]" stdout "x y pi pha" | fundisp stdin
+         X       Y     PHA        PI
+   ------- ------- ------- ---------
+         1      10       1        10
+         1      10       1        10
+         1      10       1        10
+         1      10       1        10
+         1      10       1        10
+         1      10       1        10
+         1      10       1        10
+         1      10       1        10
+         1      10       1        10
+         1      10       1        10
+
+

+The special column $REGION can be specified to write the +region id of each row: +

+  [sh $] funtable "test.ev[time-(int)time>=.99&&annulus(0 0 0 10 n=3)]" stdout 'x y time $REGION' | fundisp stdin
+          X        Y                  TIME     REGION
+   -------- -------- --------------------- ----------
+          5       -6           40.99000000          3
+          4       -5           59.99000000          2
+         -1        0          154.99000000          1
+         -2        1          168.99000000          1
+         -3        2          183.99000000          2
+         -4        3          199.99000000          2
+         -5        4          216.99000000          2
+         -6        5          234.99000000          3
+         -7        6          253.99000000          3
+
+

+Here only rows with the proper fractional time and whose position also is +within one of the three annuli are written. +

+Columns can be excluded from display using a minus sign before the +column: +

+  [sh $] funtable "test.ev[time-(int)time>=.99]" stdout "-time" | fundisp stdin
+          X        Y      PHA         PI          DX          DY
+   -------- -------- -------- ---------- ----------- -----------
+          5       -6        5         -6        5.50       -6.50
+          4       -5        4         -5        4.50       -5.50
+         -1        0       -1          0       -1.50        0.50
+         -2        1       -2          1       -2.50        1.50
+         -3        2       -3          2       -3.50        2.50
+         -4        3       -4          3       -4.50        3.50
+         -5        4       -5          4       -5.50        4.50
+         -6        5       -6          5       -6.50        5.50
+         -7        6       -7          6       -7.50        6.50
+
+All columns except the time column are written. +

+In general, the rules for activating and de-activating columns are: +

    +
  • If only exclude columns are specified, then all columns but +the exclude columns will be activated. +
  • If only include columns are specified, then only the specified columns +are activated. +
  • If a mixture of include and exclude columns are specified, then +all but the exclude columns will be active; this last case +is ambiguous and the rule is arbitrary. +
+In addition to specifying columns names explicitly, the special +symbols + and - can be used to activate and +de-activate all columns. This is useful if you want to +activate the $REGION column along with all other columns. According +to the rules, the syntax "$REGION" only activates the region column +and de-activates the rest. Use "+ $REGION" to activate all +columns as well as the region column. + +

+Ordinarily, only the selected table is copied to the output file. In +a FITS binary table, it sometimes is desirable to copy all of the +other FITS extensions to the output file as well. This can be done by +appending a '+' sign to the name of the extension in the input file +name. For example, the first command below copies only the EVENT table, +while the second command copies other extensions as well: +

+  [sh] funtable "/proj/rd/data/snr.ev[EVENTS]" events.ev
+  [sh] funtable "/proj/rd/data/snr.ev[EVENTS+]" eventsandmore.ev
+
+ +

+If the input file is an image or a raw array file, then +funtable will generate a FITS binary table from the pixel +values in the image. Note that it is not possible to specify the +columns to output (using command-line argument 3). Instead, there are +two ways to create such a binary table from an image. By default, a +3-column table is generated, where the columns are "X", "Y", and +"VALUE". For each pixel in the image, a single row (event) is +generated with the "X" and "Y" columns assigned the dim1 and dim2 +values of the image pixel, respectively and the "VALUE" column +assigned the value of the pixel. With sort of table, running +funhist on the "VALUE" column will give the same results as +running funhist on the original image. + +

+If the -i ("individual" rows) switch is specified, then only +the "X" and "Y" columns are generated. In this case, each positive +pixel value in the image generates n rows (events), where n is equal +to the integerized value of that pixel (plus 0.5, for floating point +data). In effect, -i approximately recreates the rows of a +table that would have been binned into the input image. (Of course, +this is only approximately correct, since the resulting x,y positions +are integerized.) + +

+If the -s [col1 col2 ... coln] ("sort") switch is specified, +the output rows of a binary table will be sorted using the +specified columns as sort keys. The sort keys must be scalar columns +and also must be part of the output file (i.e. you cannot sort on a +column but not include it in the output). This facility uses the +_sort program (included with funtools), which must be accessible +via your path. + +

+For binary tables, the -m ("multiple files") switch will +generate a separate file for each region in the filter specification +i.e. each file contains only the rows from that region. Rows +which pass the filter but are not in any region also are put in a +separate file. + +

+The separate output file names generated by the -m switch are +produced automatically from the root output file to contain the region id of +the associated region. (Note that region ids start at 1, so that the +file name associated with id 0 contains rows that pass the filter but +are not in any given region.) Output file names are generated as follows: + +

    +
  • A $n specification can be used anywhere in the root file name (suitably +quoted to protect it from the shell) and will be expanded to be the id +number of the associated region. For example: +
    +  funtable -m input.fits'[cir(512,512,1);cir(520,520,1)...]' 'foo.goo_$n.fits'
    +
    +will generate files named foo.goo_0.fits (for rows not in any region but +still passing the filter), foo.goo_1.fits (rows in region id #1, the first +region), foo.goo_2.fits (rows in region id #2), etc. Note that single quotes +in the output root are required to protect the '$' from the shell. + +
  • If $n is not specified, then the region id will be placed before +the first dot (.) in the filename. Thus: +
    +  funtable -m input.fits'[cir(512,512,1);cir(520,520,1)...]' foo.evt.fits
    +
    +will generate files named foo0.evt.fits (for rows not in any region but +still passing the filter), foo1.evt.fits (rows in region id #1), +foo2.evt.fits (rows in region id #2), etc. + +
  • If no dot is specified in the root output file name, then +the region id will be appended to the filename. Thus: +
    +  funtable -m input.fits'[cir(512,512,1);cir(520,520,1)...]' 'foo_evt'
    +
    +will generate files named foo_evt0 (for rows not in any region but +still passing the filter), foo_evt1 (rows in region id #1), +foo_evt2 (rows in region id #2), etc. +
+The multiple file mechanism provide a simple way to generate +individual source data files with a single pass through the data. + +

+By default, a new FITS file is created and the binary table is written +to the first extension. If the -a (append) switch is specified, +the table is appended to an existing FITS file as a BINTABLE extension. +Note that the output FITS file must already exist. + +

+If the -z ("zero" pixel values) switch is specified and +-i is not specified, then pixels having a zero value will +be output with their "VALUE" column set to zero. Obviously, this +switch does not make sense when individual events are output. + + + + +

funtbl - extract a table from Funtools ASCII output

+ + + +
+funtable [-c cols] [-h] [-n table] [-p prog] [-s sep] <iname>
+
+
+ + +

+[NB: This program has been deprecated in favor of the ASCII text processing +support in funtools. You can now perform fundisp on funtools ASCII output +files (specifying the table using bracket notation) to extract tables +and columns.] + +The funtbl script extracts a specified table (without the +header and comments) from a funtools ASCII output file and writes the +result to the standard output. The first non-switch argument is the +ASCII input file name (i.e. the saved output from funcnts, fundisp, +funhist, etc.). If no filename is specified, stdin is read. The +-n switch specifies which table (starting from 1) to extract. The +default is to extract the first table. The -c switch is a +space-delimited list of column numbers to output, e.g. -c "1 3 5" +will extract the first three odd-numbered columns. The default is to +extract all columns. The -s switch specifies the separator string to +put between columns. The default is a single space. The -h switch +specifies that column names should be added in a header line before +the data is output. Without the switch, no header is prepended. The +-p program switch allows you to specify an awk-like program to run +instead of the default (which is host-specific and is determined at +build time). The -T switch will output the data in rdb format (i.e., +with a 2-row header of column names and dashes, and with data columns +separated by tabs). The -help switch will print out a message +describing program usage. + +

+For example, consider the output from the following funcnts command: +

+  [sh] funcnts -sr snr.ev "ann 512 512 0 9 n=3"
+  # source
+  #   data file:        /proj/rd/data/snr.ev
+  #   arcsec/pixel:     8
+  # background
+  #   constant value:   0.000000
+  # column units
+  #   area:             arcsec**2
+  #   surf_bri:         cnts/arcsec**2
+  #   surf_err:         cnts/arcsec**2
+  
+  # summed background-subtracted results
+  upto   net_counts     error   background    berror      area  surf_bri  surf_err
+  ---- ------------ --------- ------------ --------- --------- --------- ---------
+     1      147.000    12.124        0.000     0.000   1600.00     0.092     0.008
+     2      625.000    25.000        0.000     0.000   6976.00     0.090     0.004
+     3     1442.000    37.974        0.000     0.000  15936.00     0.090     0.002
+  
+  
+  # background-subtracted results
+   reg   net_counts     error   background    berror      area  surf_bri  surf_err
+  ---- ------------ --------- ------------ --------- --------- --------- ---------
+     1      147.000    12.124        0.000     0.000   1600.00     0.092     0.008
+     2      478.000    21.863        0.000     0.000   5376.00     0.089     0.004
+     3      817.000    28.583        0.000     0.000   8960.00     0.091     0.003
+  
+  
+  # the following source and background components were used:
+  source_region(s)
+  ----------------
+  ann 512 512 0 9 n=3
+  
+   reg       counts    pixels      sumcnts    sumpix
+  ---- ------------ --------- ------------ ---------
+     1      147.000        25      147.000        25
+     2      478.000        84      625.000       109
+     3      817.000       140     1442.000       249
+
+

+There are four tables in this output. To extract the last one, you +can execute: +

+  [sh] funcnts -s snr.ev "ann 512 512 0 9 n=3" | funtbl -n 4
+  1 147.000 25 147.000 25
+  2 478.000 84 625.000 109
+  3 817.000 140 1442.000 249
+
+Note that the output has been re-formatted so that only a single space +separates each column, with no extraneous header or comment information. + +

+To extract only columns 1,2, and 4 from the last example (but with a header +prepended and tabs between columns), you can execute: +

+  [sh] funcnts -s snr.ev "ann 512 512 0 9 n=3" | funtbl -c "1 2 4" -h -n 4 -s "\t"
+  #reg    counts  sumcnts
+  1       147.000 147.000
+  2       478.000 625.000
+  3       817.000 1442.000
+
+

+Of course, if the output has previously been saved in a file named +foo.out, the same result can be obtained by executing: +

+  [sh] funtbl -c "1 2 4" -h -n 4 -s "\t" foo.out
+  #reg    counts  sumcnts
+  1       147.000 147.000
+  2       478.000 625.000
+  3       817.000 1442.000
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Go to Funtools Help Index + +

Last updated: April 1, 2007
+ + + diff --git a/doc/regalgebra.html b/doc/regalgebra.html new file mode 100644 index 0000000..c31dbf7 --- /dev/null +++ b/doc/regalgebra.html @@ -0,0 +1,278 @@ + + + +Region Algebra + + + + +

RegAlgebra: Boolean Algebra on Spatial Regions

+ + +

Summary

+

+This document describes the boolean arithmetic defined for +region expressions. + + +

Description

+

+When defining a region, several shapes can be combined using boolean +operations. The boolean operators are (in order of precedence): +

+  Symbol        Operator                Associativity
+  ------        --------                -------------
+  !             not                     right to left
+  &             and                     left to right
+  ^             exclusive or            left to right
+  |             inclusive or            left to right
+
+
+For example, to create a mask consisting of a large circle with a +smaller box removed, one can use the and and not +operators: +
+  CIRCLE(11,11,15) & !BOX(11,11,3,6)
+
+ +and the resulting mask is: +
+         1234567890123456789012345678901234567890
+         ----------------------------------------
+       1:1111111111111111111111..................
+       2:1111111111111111111111..................
+       3:11111111111111111111111.................
+       4:111111111111111111111111................
+       5:111111111111111111111111................
+       6:1111111111111111111111111...............
+       7:1111111111111111111111111...............
+       8:1111111111111111111111111...............
+       9:111111111...1111111111111...............
+      10:111111111...1111111111111...............
+      11:111111111...1111111111111...............
+      12:111111111...1111111111111...............
+      13:111111111...1111111111111...............
+      14:111111111...1111111111111...............
+      15:1111111111111111111111111...............
+      16:1111111111111111111111111...............
+      17:111111111111111111111111................
+      18:111111111111111111111111................
+      19:11111111111111111111111.................
+      20:1111111111111111111111..................
+      21:1111111111111111111111..................
+      22:111111111111111111111...................
+      23:..11111111111111111.....................
+      24:...111111111111111......................
+      25:.....11111111111........................
+      26:........................................
+      27:........................................
+      28:........................................
+      29:........................................
+      30:........................................
+      31:........................................
+      32:........................................
+      33:........................................
+      34:........................................
+      35:........................................
+      36:........................................
+      37:........................................
+      38:........................................
+      39:........................................
+      40:........................................
+
+A three-quarter circle can be defined as: +
+  CIRCLE(20,20,10) & !PIE(20,20,270,360)
+
+ +and looks as follows: +
+
+         1234567890123456789012345678901234567890
+         ----------------------------------------
+       1:........................................
+       2:........................................
+       3:........................................
+       4:........................................
+       5:........................................
+       6:........................................
+       7:........................................
+       8:........................................
+       9:........................................
+      10:........................................
+      11:...............111111111................
+      12:..............11111111111...............
+      13:............111111111111111.............
+      14:............111111111111111.............
+      15:...........11111111111111111............
+      16:..........1111111111111111111...........
+      17:..........1111111111111111111...........
+      18:..........1111111111111111111...........
+      19:..........1111111111111111111...........
+      20:..........1111111111111111111...........
+      21:..........1111111111....................
+      22:..........1111111111....................
+      23:..........1111111111....................
+      24:..........1111111111....................
+      25:...........111111111....................
+      26:............11111111....................
+      27:............11111111....................
+      28:..............111111....................
+      29:...............11111....................
+      30:........................................
+      31:........................................
+      32:........................................
+      33:........................................
+      34:........................................
+      35:........................................
+      36:........................................
+      37:........................................
+      38:........................................
+      39:........................................
+      40:........................................
+
+Two non-intersecting ellipses can be made into the same region: +
+  ELL(20,20,10,20,90) | ELL(1,1,20,10,0)
+
+ +and looks as follows: +
+         1234567890123456789012345678901234567890
+         ----------------------------------------
+       1:11111111111111111111....................
+       2:11111111111111111111....................
+       3:11111111111111111111....................
+       4:11111111111111111111....................
+       5:1111111111111111111.....................
+       6:111111111111111111......................
+       7:1111111111111111........................
+       8:111111111111111.........................
+       9:111111111111............................
+      10:111111111...............................
+      11:...........11111111111111111............
+      12:........111111111111111111111111........
+      13:.....11111111111111111111111111111......
+      14:....11111111111111111111111111111111....
+      15:..11111111111111111111111111111111111...
+      16:.1111111111111111111111111111111111111..
+      17:111111111111111111111111111111111111111.
+      18:111111111111111111111111111111111111111.
+      19:111111111111111111111111111111111111111.
+      20:111111111111111111111111111111111111111.
+      21:111111111111111111111111111111111111111.
+      22:111111111111111111111111111111111111111.
+      23:111111111111111111111111111111111111111.
+      24:.1111111111111111111111111111111111111..
+      25:..11111111111111111111111111111111111...
+      26:...11111111111111111111111111111111.....
+      27:.....11111111111111111111111111111......
+      28:.......111111111111111111111111.........
+      29:...........11111111111111111............
+      30:........................................
+      31:........................................
+      32:........................................
+      33:........................................
+      34:........................................
+      35:........................................
+      36:........................................
+      37:........................................
+      38:........................................
+      39:........................................
+      40:........................................
+
+You can use several boolean operations in a single region expression, +to create arbitrarily complex regions. With the important exception +below, you can apply the operators in any order, using parentheses if +necessary to override the natural precedences of the operators. + +

+NB: Using a panda shape is always much more efficient than explicitly +specifying "pie & annulus", due to the ability of panda to place a +limit on the number of pixels checked in the pie shape. If you are +going to specify the intersection of pie and annulus, use panda +instead. + +

+As described in "help regreometry", the PIE slice goes to the +edge of the field. To limit its scope, PIE usually is is +combined with other shapes, such as circles and annuli, using boolean +operations. In this context, it is worth noting that that there is a +difference between -PIE and &!PIE. The former is a +global exclude of all pixels in the PIE slice, while the latter +is a local excludes of pixels affecting only the region(s) with which +the PIE is combined. For example, the following region uses +&!PIE as a local exclude of a single circle. Two other circles +are also defined and are unaffected by the local exclude: +

+
+        CIRCLE(1,8,1)
+        CIRCLE(8,8,7)&!PIE(8,8,60,120)&!PIE(8,8,240,300)
+        CIRCLE(15,8,2)
+
+          1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+          - - - - - - - - - - - - - - -
+      15: . . . . . . . . . . . . . . .
+      14: . . . . 2 2 2 2 2 2 2 . . . .
+      13: . . . 2 2 2 2 2 2 2 2 2 . . .
+      12: . . 2 2 2 2 2 2 2 2 2 2 2 . .
+      11: . . 2 2 2 2 2 2 2 2 2 2 2 . .
+      10: . . . . 2 2 2 2 2 2 2 . . . .
+       9: . . . . . . 2 2 2 . . . . 3 3
+       8: 1 . . . . . . . . . . . . 3 3
+       7: . . . . . . 2 2 2 . . . . 3 3
+       6: . . . . 2 2 2 2 2 2 2 . . . .
+       5: . . 2 2 2 2 2 2 2 2 2 2 2 . .
+       4: . . 2 2 2 2 2 2 2 2 2 2 2 . .
+       3: . . . 2 2 2 2 2 2 2 2 2 . . .
+       2: . . . . 2 2 2 2 2 2 2 . . . .
+       1: . . . . . . . . . . . . . . .
+
+
+Note that the two other regions are not affected by the &!PIE, +which only affects the circle with which it is combined. + +

+On the other hand, a -PIE is an global exclude that does +affect other regions with which it overlaps: +

+
+        CIRCLE(1,8,1)
+        CIRCLE(8,8,7)
+        -PIE(8,8,60,120)
+        -PIE(8,8,240,300)
+        CIRCLE(15,8,2)
+
+          1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+          - - - - - - - - - - - - - - -
+      15: . . . . . . . . . . . . . . .
+      14: . . . . 2 2 2 2 2 2 2 . . . .
+      13: . . . 2 2 2 2 2 2 2 2 2 . . .
+      12: . . 2 2 2 2 2 2 2 2 2 2 2 . .
+      11: . . 2 2 2 2 2 2 2 2 2 2 2 . .
+      10: . . . . 2 2 2 2 2 2 2 . . . .
+       9: . . . . . . 2 2 2 . . . . . .
+       8: . . . . . . . . . . . . . . .
+       7: . . . . . . 2 2 2 . . . . . .
+       6: . . . . 2 2 2 2 2 2 2 . . . .
+       5: . . 2 2 2 2 2 2 2 2 2 2 2 . .
+       4: . . 2 2 2 2 2 2 2 2 2 2 2 . .
+       3: . . . 2 2 2 2 2 2 2 2 2 . . .
+       2: . . . . 2 2 2 2 2 2 2 . . . .
+       1: . . . . . . . . . . . . . . .
+
+
+The two smaller circles are entirely contained within the two exclude +PIE slices and therefore are excluded from the region. + + + + + +

+Go to Funtools Help Index + +

Last updated: November 17, 2005
+ + + diff --git a/doc/regbounds.html b/doc/regbounds.html new file mode 100644 index 0000000..4fef30f --- /dev/null +++ b/doc/regbounds.html @@ -0,0 +1,179 @@ + + + +Spatial Region Boundaries + + + + +

RegBounds: Region Boundaries

+ + +

Summary

+Describes how spatial region boundaries are handled. + + +

Description

+

+The golden rule for spatial region filtering was first enunciated by +Leon VanSpeybroeck in 1986: + +

+Each photon will be counted once, and no photon will be counted +more than once. + +

+This means that we must be careful about boundary +conditions. For example, if a circle is contained in an annulus such +that the inner radius of the annulus is the same as the radius of the +circle, then photons on that boundary must always be assigned to one +or the other region. That is, the number of photons in both regions +must equal the sum of the number of photons in each region taken +separately. + +With this in mind, the rules for determining whether a boundary image +pixel or table row are assigned to a region are defined below. + +

Image boundaries : radially-symmetric shapes (circle, annuli, ellipse)

+ +For image filtering, pixels whose center is inside the boundary are +included. This also applies non-radially-symmetric shapes. When a +pixel center is exactly on the boundary, the pixel assignment rule is: + +
    +
  • the outer boundary of a symmetric shape does not include such pixels +
  • the inner boundary of a symmetric shape (annulus) includes such pixels +
+ +In this way, an annulus with radius from 0 to 1, centered exactly on a +pixel, includes the pixel on which it is centered, but none of its +neighbors. + +These rules ensure that when defining concentric shapes, no pixels are +omitted between concentric regions and no pixels are claimed by two +regions. When applied to small symmetric shapes, the shape is less +likely to be skewed, as would happen with non-radially-symmetric +rules. These rules differ from the rules for box-like shapes, which +are more likely to be positioned adjacent to one another. + +

Image Boundaries: non-radially symmetric shapes (polygons, boxes)

+ +For image filtering, pixels whose center is inside the boundary are +included. This also applies radially-symmetric shapes. When a pixel +center is exactly on the boundary of a non-radially symmetric region, +the pixel is included in the right or upper region, but not the left +or lower region. This ensures that geometrically adjoining regions +touch but don't overlap. + +

Row Boundaries are Analytic

+ +When filtering table rows, the boundary rules are the same as for +images, except that the calculation is not done on the center of a +pixel, (since table rows, especially X-ray events rows, often have +discrete, floating point positions) but are calculated exactly. That +is, an row is inside the boundary without regard to its integerized +pixel value. For rows that are exactly on a region boundary, the +above rules are applied to ensure that all rows are counted once and +no row is counted more than once. + +

+Because row boundaries are calculated differently from image boundaries, +certain programs will give different results when filtering the same +region file. In particular, fundisp/funtable (which utilize analytic +row filtering) perform differently from funcnts (which performs image +filtering, even on tables). + +

Image Boundaries vs. Row Boundaries: Practical Considerations

+ +

+You will sometimes notice a discrepancy between running funcnts on an +binary table file and running fundisp on the same file with the same filter. +For example, consider the following: +

+  fundisp test1.fits"[box(4219,3887,6,6,0)]" | wc
+  8893  320148 3752846
+
+Since fundisp has a 2-line header, there are actually 8891 photons +that pass the filter. But then run funtable and select only the +rows that pass this filter, placing them in a new file: +
+  ./funtable test1.fits"[box(4219,3887,6,6,0)]" test2.fits
+
+Now run funcnts using the original filter on the derived file: +
+  ./funcnts test2.fits "physical; box(4219,3887,6,6,0)"
+
+  [... lot of processed output ...]
+
+  # the following source and background components were used:
+  source region(s)
+  ----------------
+  physical; box(4219,3887,6,6,0)
+ 
+   reg       counts    pixels
+  ---- ------------ ---------
+     1     7847.000        36
+
+There are 1044 rows (events) that pass the row filter in fundisp (or +funtable) but fail to make it through funcnts. Why? + +

+The reason can be traced to how analytic row filtering (fundisp, funtable) +differs from integerized pixel filtering(funcnts, funimage). Consider the +region: +

+  box(4219,3887,6,6,0)
+
+Analytically (i.e., using row filtering), positions will pass this +filter successfully if: +
+  4216 <= x <= 4222
+  3884 <= y <= 3890
+
+For example, photons with position values of x=4216.4 or y=3884.08 will pass. + +

+Integerized image filtering is different in that the pixels that will +pass this filter have centers at: +

+  x = 4217, 4218, 4219, 4220, 4221, 4222
+  y = 3885, 3886, 3887, 3888, 3889, 3890
+
+Note that there are 6 pixels in each direction, as specified by the region. +That means that positions will pass the filter successfully if: +
+  4217 <= (int)x <= 4222
+  3885 <= (int)y <= 3890
+
+Photons with position values of x=4216.4 or y=3884.08 will NOT pass. + +

+Note that the position values are integerized, in effect, binned into +image values. This means that x=4222.4 will pass this filter, but not +the analytic filter above. We do this to maintain the design goal that +either all counts in a pixel are included in an integerized filter, or +else none are included. + +

+[It could be argued that the correct photon limits for floating point +row data really should be: +

+  4216.5 <= x <= 4222.5
+  3884.5 <= y <= 3890.5
+
+since each pixel extends for .5 on either side of the center. We chose +to the maintain integerized algorithm for all image-style filtering so +that funcnts would give the exact same results regardless of whether +a table or a derived non-blocked binned image is used.] + + + + + +

+Go to Funtools Help Index + +

Last updated: November 16, 2005
+ + + diff --git a/doc/regcoords.html b/doc/regcoords.html new file mode 100644 index 0000000..ff656c2 --- /dev/null +++ b/doc/regcoords.html @@ -0,0 +1,239 @@ + + + +Spatial Region Coordinates + + + + +

RegCoords: Spatial Region Coordinates

+ + +

Summary

+

+This document describes the specification of coordinate systems, and the +interpretation of coordinate values, for spatial region filtering. + + +

Pixel coordinate systems

+

+The default coordinate system for regions is PHYSICAL, which means +that region position and size values are taken from the original +data. (Note that this is a change from the original IRAF/PROS +implementation, in which the IMAGE coordinate system was the default.) +PHYSICAL coordinates always refer to pixel positions on the original +image (using IRAF LTM and LTV keywords). With PHYSICAL coordinates, +if a set of coordinates specifies the position of an object in an +original FITS file, the same coordinates will specify the same object +in any FITS derived from the original. Physical coordinates are +invariant with blocking of FITS files or taking sections of images, +even when a blocked section is written to a new file. + +

+Thus, although a value in pixels refers, by default, to the PHYSICAL +coordinate system, you may specify that position values refer to the +image coordinate system using the global or local +properties commands: + +

+  global coordsys image
+  circle 512 512 100
+
+ +The global command changes the coordinate system for all +regions that follow, while the local command changes the +coordinate system only for the region immediately following: +
+  local coordsys image
+  circle 512 512 100
+  circle 1024 1024 200
+
+This changes the coordinate system only for the region that follows. +In the above example, the second region uses the global coordinate +system (PHYSICAL by default). + +

+

World Coordinate Systems

+ +If World Coordinate System information is contained in the data file +being filtered, it also is possible to define regions using a sky +coordinate system. Supported systems include: + +
+  name                  description
+  ----                  -----------
+  PHYSICAL              pixel coords of original file using LTM/LTV
+  IMAGE                 pixel coords of current file
+  FK4, B1950            sky coordinate systems
+  FK5, J2000            sky coordinate systems
+  GALACTIC              sky coordinate systems
+  ECLIPTIC              sky coordinate systems
+  ICRS                  currently same as J2000
+  LINEAR                linear wcs as defined in file
+
+ +In addition, two mosaic coordinate systems have been defined that +utilize the (evolving) IRAF mosaic keywords: + +
+  name                  description
+  ----                  -----------
+  AMPLIFIER             mosaic coords of original file using ATM/ATV
+  DETECTOR              mosaic coords of original file using DTM/DTV
+
+Again, to use one of these coordinate systems, the global or +local properties commands are used: + +
+  global coordsys galactic
+
+ +

WCS Positions and Sizes

+ +In addition to pixels, positional values in a WCS-enabled region can +be specified using sexagesimal or degrees format: + +
+  position arguments    description
+  ------------------    -----------
+  [num]                 context-dependent (see below)
+  [num]d                degrees
+  [num]r                radians
+  [num]p                physical pixels
+  [num]i                image pixels
+  [num]:[num]:[num]     hms for 'odd' position arguments
+  [num]:[num]:[num]     dms for 'even' position arguments
+  [num]h[num]m[num]s    explicit hms
+  [num]d[num]m[num]s    explicit dms
+
+ +If ':' is used as sexagesimal separator, the value is considered to be +specifying hours/minutes/seconds if it is the first argument of a +positional pair, and degrees/minutes/seconds for the second argument +of a pair (except for galactic coordinates, which always use degrees): + +
+  argument      description
+  -----------   -----------
+  10:20:30.0    10 hours, 20 minutes, 30 seconds for 1st positional argument
+                10 degrees, 20 minutes, 30 seconds for 2nd positional argument
+  10h20m30.0    10 hours, 20 minutes, 30 seconds
+  10d20m30.0    10 degrees, 20 minutes, 30 seconds
+  10.20d        10.2 degrees
+
+ +Similarly, the units of size values are defined by the formating +character(s) attached to a number: + +
+  size arguments        description
+  --------------        -----------
+  [num]                 context-dependent (see below)
+  [num]"                arc seconds
+  [num]'                arc minutes
+  [num]d                degrees
+  [num]r                radians
+  [num]p                physical pixels
+  [num]i                image pixels
+
+ +For example: +
+  argument      description
+  -----------   -----------
+  10            ten pixels
+  10'           ten minutes of arc
+  10"           ten seconds of arc
+  10d           ten degrees
+  10p           ten pixels
+  0.5r          half of a radian
+
+ +

+An example of using sky coordinate systems follows: + +

+  global coordsys B1950
+  -box 175.54d 20.01156d 10' 10'
+  local coordsys J2000
+  pie 179.57d 22.4d 0 360 n=4 && annulus 179.57d 22.4d 3' 24' n=5
+
+ +At the FK4 1950 coordinates 175.54d RA, 20.01156d DEC exclude a 10 +minute by 10 minute box. Then at the FK5 2000 coordinates 179.57d RA +22.4d DEC draw a radial profile regions pattern with 4 quadrants and 5 +annuli ranging from 3 minutes to 24 minutes in diameter. In this +example, the default coordinate system is overridden by the commands +in the regions spec. + +

NB: The Meaning of Pure Numbers Are Context Sensitive

+ +

+When a "pure number" (i.e. one without a format directive such as 'd' +for 'degrees') is specified as a position or size, its interpretation +depends on the context defined by the 'coordsys' keyword. In general, +the rule is: + +

+All pure numbers have implied units corresponding to the current +coordinate system. + +

+If no coordinate system is explicitly specified, the default system is +implicitly assumed to be PHYSICAL. In practice this means that for +IMAGE and PHYSICAL systems, pure numbers are pixels. Otherwise, +for all systems other than LINEAR, pure numbers are degrees. For +LINEAR systems, pure numbers are in the units of the linear system. +This rule covers both positions and sizes. + +

+As a corollary, when a sky-formatted number is used with the IMAGE +or PHYSICAL coordinate system (which includes the default case of no +coordsys being specified), the formatted number is assumed to be in +the units of the WCS contained in the current file. If no sky WCS is +specified, an error results. + +

+Examples: + +

+  circle(512,512,10)
+  ellipse 202.44382d 47.181656d 0.01d 0.02d
+
+ +

+In the absence of a specified coordinate system, the circle uses the +default PHYSICAL units of pixels, while the ellipse explicitly uses degrees, +presumably to go with the WCS in the current file. + +

+ global coordsys=fk5 
+ global color=green font="system 10 normal"
+ circle 202.44382 47.181656 0.01
+ circle 202.44382 47.181656 10p
+ ellipse(512p,512p,10p,15p,20)
+
+ + +

+Here, the circles use the FK5 units of degrees (except for the +explicit use of pixels in the second radius), while the ellipse +explicitly specifies pixels. The ellipse angle is in degrees. + +

+Note that Chandra data format appears to use "coordsys=physical" +implicitly. Therefore, for most Chandra applications, valid regions +can be generated safely by asking ds9 to save/display regions in +pixels using the PHYSICAL coordsys. + + + + + +

+Go to Funtools Help Index + +

Last updated: November 17, 2005
+ + + diff --git a/doc/regdiff.html b/doc/regdiff.html new file mode 100644 index 0000000..29c9658 --- /dev/null +++ b/doc/regdiff.html @@ -0,0 +1,71 @@ + + + +Differences Between Funtools and IRAF Regions + + + + +

RegDiff:Differences Between Funtools and IRAF Regions

+ + +

Summary

+Describes the differences between Funtools/ds9 regions and the old IRAF/PROS +regions. + + +

Description

+

+We have tried to make Funtools regions compatible with their +predecessor, IRAF/PROS regions. For simple regions and simple boolean +algebra between regions, there should be no difference between the two +implementations. The following is a list of differences and +incompatibilities between the two: + +

    + +

    +

  • If a pixel is covered by two different regions expressions, +Funtools assigns the mask value of the first region that +contains that pixel. That is, successive regions do not +overwrite previous regions in the mask, as was the case with the +original PROS regions. This means that one must define overlapping +regions in the reverse order in which they were defined in PROS. If +region N is fully contained within region M, then N should be defined +before M, or else it will be "covered up" by the latter. This +change is necessitated by the use of optimized filter compilation, i.e., +Funtools only tests individual regions until a proper match is made. + +

    +

  • The PANDA region has replaced the old PROS syntax in which +a PIE accelerator was combined with an ANNULUS accelerator +using AND. That is, +
    +  ANNULUS(20,20,0,15,n=4) & PIE(20,20,0,360,n=3)
    +
    +has been replaced by: +
    +  PANDA(20,20,0,360,3,0,15,4)
    +
    +The PROS syntax was inconsistent with the meaning of the AND operator. + +

    +

  • The meaning of pure numbers (i.e., without format specifiers) in +regions has been clarified, as has the syntax for specifying coordinate +systems. See the general discussion on +Spatial Region Filtering +for more information. + +
+ + + + + +

+Go to Funtools Help Index + +

Last updated: November 16, 2005
+ + + diff --git a/doc/reggeometry.html b/doc/reggeometry.html new file mode 100644 index 0000000..faca53f --- /dev/null +++ b/doc/reggeometry.html @@ -0,0 +1,1148 @@ + + + +Region Geometry + + + + +

RegGeometry: Geometric Shapes in Spatial Region Filtering

+ + +

Summary

+

+This document describes the geometry of regions available for spatial +filtering in IRAF/PROS analysis. + + +

Geometric shapes

+

+Several geometric shapes are used to describe regions. The valid +shapes are: + +

+  shape:        arguments:
+  -----         ----------------------------------------
+  ANNULUS       xcenter ycenter inner_radius outer_radius
+  BOX           xcenter ycenter xwidth yheight (angle)
+  CIRCLE        xcenter ycenter radius
+  ELLIPSE       xcenter ycenter xwidth yheight (angle)
+  FIELD         none
+  LINE          x1 y1 x2 y2
+  PIE           xcenter ycenter angle1 angle2
+  POINT         x1 y1
+  POLYGON       x1 y1 x2 y2 ... xn yn
+
+ + +All arguments are real values; integer values are automatically +converted to real where necessary. All angles are in degrees and +specify angles that run counter-clockwise from the positive y-axis. + +

+Shapes can be specified using "command" syntax: +

+  [shape] arg1 arg2 ...
+
+or using "routine" syntax: +
+  [shape](arg1, arg2, ...)
+
+or by any combination of the these. (Of course, the parentheses must +balance and there cannot be more commas than necessary.) The shape +keywords are case-insensitive. Furthermore, any shape can be +specified by a three-character unique abbreviation. For example, one +can specify three circular regions as: + +
+  "foo.fits[CIRCLE 512 512 50;CIR(128 128, 10);cir(650,650,20)]"
+
+ +(Quotes generally are required to protect the region descriptor +from being processed by the Unix shell.) + +
+ +

+The annulus shape specifies annuli, centered at xcenter, +ycenter, with inner and outer radii (r1, r2). For example, +

+  ANNULUS 25 25 5 10
+
+specifies an annulus centered at 25.0 25.0 with an inner radius of 5.0 and +an outer radius of 10. Assuming (as will be done for all examples in this +document, unless otherwise noted) this shape is used in a mask of size 40x40, +it will look like this: +
+	1234567890123456789012345678901234567890
+	----------------------------------------
+	40:........................................
+	39:........................................
+	38:........................................
+	37:........................................
+	36:........................................
+	35:........................................
+	34:....................111111111...........
+	33:...................11111111111..........
+	32:.................111111111111111........
+	31:.................111111111111111........
+	30:................11111111111111111.......
+	29:...............1111111.....1111111......
+	28:...............111111.......111111......
+	27:...............11111.........11111......
+	26:...............11111.........11111......
+	25:...............11111.........11111......
+	24:...............11111.........11111......
+	23:...............11111.........11111......
+	22:...............111111.......111111......
+	21:...............1111111.....1111111......
+	20:................11111111111111111.......
+	19:.................111111111111111........
+	18:.................111111111111111........
+	17:...................11111111111..........
+	16:....................111111111...........
+	15:........................................
+	14:........................................
+	13:........................................
+	12:........................................
+	11:........................................
+	10:........................................
+	9:........................................
+	8:........................................
+	7:........................................
+	6:........................................
+	5:........................................
+	4:........................................
+	3:........................................
+	2:........................................
+	1:........................................
+
+ +
+ +

+The box shape specifies an orthogonally oriented box, +centered at xcenter, ycenter, of size xwidth, yheight. It requires four +arguments and accepts an optional fifth argument to specify a rotation angle. +When the rotation angle is specified (in degrees), the box is rotated by +an angle that runs counter-clockwise from the positive y-axis. + +

+The box shape specifies a rotated box, centered at +xcenter, ycenter, of size xwidth, yheight. The box is rotated by an angle +specified in degrees that runs counter-clockwise from the positive y-axis. +If the angle argument is omitted, it defaults to 0. + +


+ +

+The circle shape specifies a circle, centered at xcenter, +ycenter, of radius r. It requires three arguments. + +


+ +

+The ellipse shape specifies an ellipse, centered at +xcenter, ycenter, with y-axis width a and the y-axis length b defined such +that: +

+  x**2/a**2 + y**2/b**2 = 1
+
+Note that a can be less than, equal to, or greater than b. The ellipse +is rotated the specified number of degrees. The rotation is done according +to astronomical convention, counter-clockwise from the positive y-axis. +An ellipse defined by: +
+  ELLIPSE 20 20 5 10 45
+
+will look like this: +
+         1234567890123456789012345678901234567890
+         ----------------------------------------
+      40:........................................
+      39:........................................
+      38:........................................
+      37:........................................
+      36:........................................
+      35:........................................
+      34:........................................
+      33:........................................
+      32:........................................
+      31:........................................
+      30:........................................
+      29:........................................
+      28:........................................
+      27:............111111......................
+      26:............11111111....................
+      25:............111111111...................
+      24:............11111111111.................
+      23:............111111111111................
+      22:............111111111111................
+      21:.............111111111111...............
+      20:.............1111111111111..............
+      19:..............111111111111..............
+      18:...............111111111111.............
+      17:...............111111111111.............
+      16:................11111111111.............
+      15:..................111111111.............
+      14:...................11111111.............
+      13:.....................111111.............
+      12:........................................
+      11:........................................
+      10:........................................
+       9:........................................
+       8:........................................
+       7:........................................
+       6:........................................
+       5:........................................
+       4:........................................
+       3:........................................
+       2:........................................
+       1:........................................
+
+ + +
+ +

+The field shape specifies the entire field as a +region. It is not usually specified explicitly, but is used implicitly in the +case where no regions are specified, that is, in cases where either a null +string or some abbreviation of the string "none" is input. +Field takes no arguments. + +


+ +

+The pie shape specifies an angular wedge of the entire field, +centered at xcenter, ycenter. The wedge runs between the two specified angles. +The angles are given in degrees, running counter-clockwise from the positive +x-axis. For example, +

+  PIE 20 20 90 180
+
+defines a region from 90 degrees to 180 degrees, i.e., quadrant 2 of the +Cartesian plane. The display of such a region looks like this: + +
+	1234567890123456789012345678901234567890
+	----------------------------------------
+	40:11111111111111111111....................
+	39:11111111111111111111....................
+	38:11111111111111111111....................
+	37:11111111111111111111....................
+	36:11111111111111111111....................
+	35:11111111111111111111....................
+	34:11111111111111111111....................
+	33:11111111111111111111....................
+	32:11111111111111111111....................
+	31:11111111111111111111....................
+	30:11111111111111111111....................
+	29:11111111111111111111....................
+	28:11111111111111111111....................
+	27:11111111111111111111....................
+	26:11111111111111111111....................
+	25:11111111111111111111....................
+	24:11111111111111111111....................
+	23:11111111111111111111....................
+	22:11111111111111111111....................
+	21:11111111111111111111....................
+	20:........................................
+	19:........................................
+	18:........................................
+	17:........................................
+	16:........................................
+	15:........................................
+	14:........................................
+	13:........................................
+	12:........................................
+	11:........................................
+	10:........................................
+	9:........................................
+	8:........................................
+	7:........................................
+	6:........................................
+	5:........................................
+	4:........................................
+	3:........................................
+	2:........................................
+	1:........................................
+
+The pie slice specified is always a counter-clockwise sweep between +the angles, starting at the first angle and ending at the second. Thus: +
+  PIE 10 15 30 60
+
+describes a 30 degree sweep from 2 o'clock to 1 o'clock, while: +
+  PIE 10 15 60 30
+
+describes a 330 degree counter-clockwise sweep from 1 o'clock to 2 o'clock +passing through 12 o'clock (0 degrees). Note in both of these examples that +the center of the slice can be anywhere on the plane. The second mask looks +like this: + +
+	1234567890123456789012345678901234567890
+	----------------------------------------
+	40:111111111111111111111111................
+	39:11111111111111111111111.................
+	38:11111111111111111111111.................
+	37:1111111111111111111111..................
+	36:1111111111111111111111..................
+	35:111111111111111111111...................
+	34:11111111111111111111....................
+	33:11111111111111111111....................
+	32:1111111111111111111....................1
+	31:1111111111111111111..................111
+	30:111111111111111111.................11111
+	29:111111111111111111................111111
+	28:11111111111111111...............11111111
+	27:1111111111111111..............1111111111
+	26:1111111111111111.............11111111111
+	25:111111111111111............1111111111111
+	24:111111111111111..........111111111111111
+	23:11111111111111.........11111111111111111
+	22:11111111111111........111111111111111111
+	21:1111111111111.......11111111111111111111
+	20:111111111111......1111111111111111111111
+	19:111111111111....111111111111111111111111
+	18:11111111111....1111111111111111111111111
+	17:11111111111..111111111111111111111111111
+	16:1111111111.11111111111111111111111111111
+	15:1111111111111111111111111111111111111111
+	14:1111111111111111111111111111111111111111
+	13:1111111111111111111111111111111111111111
+	12:1111111111111111111111111111111111111111
+	11:1111111111111111111111111111111111111111
+	10:1111111111111111111111111111111111111111
+	9:1111111111111111111111111111111111111111
+	8:1111111111111111111111111111111111111111
+	7:1111111111111111111111111111111111111111
+	6:1111111111111111111111111111111111111111
+	5:1111111111111111111111111111111111111111
+	4:1111111111111111111111111111111111111111
+	3:1111111111111111111111111111111111111111
+	2:1111111111111111111111111111111111111111
+	1:1111111111111111111111111111111111111111
+
+The pie slice goes to the edge of the field. To limit its scope, pie +usually is is combined with other shapes, such as circles and annuli, +using boolean operations. (See below and in "help regalgebra"). + +

+Pie Performance Notes: +

+Pie region processing time is proportional to the size of the image, +and not the size of the region. This is because the pie shape is the +only infinite length shape, and we essentially must check all y rows +for inclusion (unlike other regions, where the y limits can be +calculated beforehand). Thus, pie can run very slowly on large images. +In particular, it will run MUCH more slowly than the panda shape in +image-based region operations (such as funcnts). We recommend use of +panda over pie where ever possible. + +

+If you must use pie, always try to put it last in a boolean && +expression. The reason for this is that the filter code is optimized +to exit as soon as the result is know. Since pie is the slowest +region, it is better to avoid executing it if another region can decide +the result. Consider, for example, the difference in time required to +process a Chandra ACIS file when a pie and circle are combined in +two different orders: + +

+  time ./funcnts nacis.fits "circle 4096 4096 100 && pie 4096 4096 10 78"
+2.87u 0.38s 0:35.08 9.2%
+
+  time ./funcnts nacis.fits "pie 4096 4096 10 78 && circle 4096 4096 100 "
+89.73u 0.36s 1:03.50 141.8%
+
+ +

+Black-magic performance note: + +

+Panda region processing uses a quick test pie region instead of +the normal pie region when combining its annulus and pie shapes. This +qtpie shape differs from the normal pie in that it utilizes the +y limits from the previous region with which it is combined. In a +panda shape, which is a series of annuli combined with pies, the +processing time is thus reduced to that of the annuli. + +

+You can use the qtpie shape instead of pie in cases where you are +combining pie with another shape using the && operator. This will +cause the pie limits to be set using limits from the other shape, and +will speed up the processing considerably. For example, the above +execution of funcnts can be improved considerably using this technique: + +

+  time ./funcnts nacis.fits "circle 4096 4096 100 && qtpie 4096 4096 10 78"
+4.66u 0.33s 0:05.87 85.0%
+
+ +

+We emphasize that this is a quasi-documented feature and might change in +the future. The qtpie shape is not recognized by ds9 or other programs. + +


+ +

+The line shape allows single pixels in a line between (x1,y1) and +(x2,y2) to be included or excluded. For example: +

+  LINE (5,6, 24,25)
+
+displays as:
+
+         1234567890123456789012345678901234567890
+         ----------------------------------------
+      40:........................................
+      39:........................................
+      38:........................................
+      37:........................................
+      36:........................................
+      35:........................................
+      34:........................................
+      33:........................................
+      32:........................................
+      31:........................................
+      30:........................................
+      29:........................................
+      28:........................................
+      27:........................................
+      26:........................................
+      25:.......................1................
+      24:......................1.................
+      23:.....................1..................
+      22:....................1...................
+      21:...................1....................
+      20:..................1.....................
+      19:.................1......................
+      18:................1.......................
+      17:...............1........................
+      16:..............1.........................
+      15:.............1..........................
+      14:............1...........................
+      13:...........1............................
+      12:..........1.............................
+      11:.........1..............................
+      10:........1...............................
+       9:.......1................................
+       8:......1.................................
+       7:.....1..................................
+       6:....1...................................
+       5:........................................
+       4:........................................
+       3:........................................
+       2:........................................
+       1:........................................
+
+ +
+ +

+The point shape allows single pixels to be included or +excluded. Although the (x,y) values are real numbers, they are truncated +to integer and the corresponding pixel is included or excluded, as specified. + +

+Several points can be put in one region declaration; unlike the +original IRAF implementation, each now is given a different region mask value. +This makes it easier, for example, for funcnts to determine the number of +photons in the individual pixels. For example, +

+  POINT (5,6,  10,11,  20,20,  35,30)
+
+will give the different region mask values to all four points, as shown below: + +
+         1234567890123456789012345678901234567890
+         ----------------------------------------
+      40:........................................
+      39:........................................
+      38:........................................
+      37:........................................
+      36:........................................
+      35:........................................
+      34:........................................
+      33:........................................
+      32:........................................
+      31:........................................
+      30:..................................4.....
+      29:........................................
+      28:........................................
+      27:........................................
+      26:........................................
+      25:........................................
+      24:........................................
+      23:........................................
+      22:........................................
+      21:........................................
+      20:...................3....................
+      19:........................................
+      18:........................................
+      17:........................................
+      16:........................................
+      15:........................................
+      14:........................................
+      13:........................................
+      12:........................................
+      11:.........2..............................
+      10:........................................
+       9:........................................
+       8:........................................
+       7:........................................
+       6:....1...................................
+       5:........................................
+       4:........................................
+       3:........................................
+       2:........................................
+       1:........................................
+
+ +
+ +

+The polygon shape specifies a polygon with vertices +(x1, y1) ... (xn, yn). The polygon is closed automatically: one should +not specify the last vertex to be the same as the first. Any number of +vertices are allowed. For example, the following polygon defines a +right triangle as shown below: +

+  POLYGON (10,10,  10,30,  30,30)
+
+ +looks like this: + +
+         1234567890123456789012345678901234567890
+         ----------------------------------------
+      40:........................................
+      39:........................................
+      38:........................................
+      37:........................................
+      36:........................................
+      35:........................................
+      34:........................................
+      33:........................................
+      32:........................................
+      31:........................................
+      30:..........11111111111111111111..........
+      29:..........1111111111111111111...........
+      28:..........111111111111111111............
+      27:..........11111111111111111.............
+      26:..........1111111111111111..............
+      25:..........111111111111111...............
+      24:..........11111111111111................
+      23:..........1111111111111.................
+      22:..........111111111111..................
+      21:..........11111111111...................
+      20:..........1111111111....................
+      19:..........111111111.....................
+      18:..........11111111......................
+      17:..........1111111.......................
+      16:..........111111........................
+      15:..........11111.........................
+      14:..........1111..........................
+      13:..........111...........................
+      12:..........11............................
+      11:..........1.............................
+      10:........................................
+       9:........................................
+       8:........................................
+       7:........................................
+       6:........................................
+       5:........................................
+       4:........................................
+       3:........................................
+       2:........................................
+       1:........................................
+
+Note that polygons can get twisted upon themselves if edge lines +cross. Thus: +
+  POL (10,10,  20,20,  20,10,  10,20)
+
+will produce an area which is two triangles, like butterfly wings, as shown +below: + +
+         1234567890123456789012345678901234567890
+         ----------------------------------------
+      40:........................................
+      39:........................................
+      38:........................................
+      37:........................................
+      36:........................................
+      35:........................................
+      34:........................................
+      33:........................................
+      32:........................................
+      31:........................................
+      30:........................................
+      29:........................................
+      28:........................................
+      27:........................................
+      26:........................................
+      25:........................................
+      24:........................................
+      23:........................................
+      22:........................................
+      21:........................................
+      20:........................................
+      19:..........1........1....................
+      18:..........11......11....................
+      17:..........111....111....................
+      16:..........1111..1111....................
+      15:..........1111111111....................
+      14:..........1111..1111....................
+      13:..........111....111....................
+      12:..........11......11....................
+      11:..........1........1....................
+      10:........................................
+       9:........................................
+       8:........................................
+       7:........................................
+       6:........................................
+       5:........................................
+       4:........................................
+       3:........................................
+       2:........................................
+       1:........................................
+
+ +
+ +

+The following are combinations of pie with different shapes +(called "panda" for "Pie AND Annulus") allow for easy specification of +radial sections: +

+  shape:   arguments:
+  -----    ---------
+  PANDA    xcen ycen ang1 ang2 nang irad orad nrad   # circular
+  CPANDA   xcen ycen ang1 ang2 nang irad orad nrad   # circular
+  BPANDA   xcen ycen ang1 ang2 nang xwlo yhlo xwhi yhhi nrad (ang) # box
+  EPANDA   xcen ycen ang1 ang2 nang xwlo yhlo xwhi yhhi nrad (ang) # ellipse
+
+ +The panda (Pies AND Annuli) shape can be +used to create combinations of pie and annuli markers. It is analogous +to a Cartesian product on those shapes, i.e., the result is several +shapes generated by performing a boolean AND between pies and +annuli. Thus, the panda and cpanda specify combinations of annulus and +circle with pie, respectively and give identical results. The bpanda +combines box and pie, while epanda combines ellipse and pie. + +

+Consider the example shown below: +

+  PANDA(20,20, 0,360,3, 0,15,4)
+
+Here, 3 pie slices centered at 20, 20 are combined with 4 annuli, also +centered at 20, 20. The result is a mask with 12 regions (displayed in +base 16 to save characters): +
+	1234567890123456789012345678901234567890
+	----------------------------------------
+	40:........................................
+	39:........................................
+	38:........................................
+	37:........................................
+	36:........................................
+	35:........................................
+	34:..............44444444444...............
+	33:............444444444444444.............
+	32:...........88444444444444444............
+	31:.........888844443333344444444..........
+	30:........88888833333333333444444.........
+	29:........88888733333333333344444.........
+	28:.......8888877733333333333344444........
+	27:......888887777332222233333344444.......
+	26:......888877777622222222333334444.......
+	25:.....88887777766622222222333334444......
+	24:.....88887777666622222222233334444......
+	23:.....88887777666651111222233334444......
+	22:.....88877776666551111122223333444......
+	21:.....88877776666555111122223333444......
+	20:.....888777766665559999aaaabbbbccc......
+	19:.....888777766665559999aaaabbbbccc......
+	18:.....888777766665599999aaaabbbbccc......
+	17:.....88887777666659999aaaabbbbcccc......
+	16:.....888877776666aaaaaaaaabbbbcccc......
+	15:.....888877777666aaaaaaaabbbbbcccc......
+	14:......8888777776aaaaaaaabbbbbcccc.......
+	13:......888887777bbaaaaabbbbbbccccc.......
+	12:.......88888777bbbbbbbbbbbbccccc........
+	11:........888887bbbbbbbbbbbbccccc.........
+	10:........888888bbbbbbbbbbbcccccc.........
+	9:.........8888ccccbbbbbcccccccc..........
+	8:...........88ccccccccccccccc............
+	7:............ccccccccccccccc.............
+	6:..............ccccccccccc...............
+	5:........................................
+	4:........................................
+	3:........................................
+	2:........................................
+	1:........................................
+
+ +
+ +

+Several regions with different mask values can be combined in the +same mask. This supports comparing data from the different regions. +(For information on how to combine different shapes into a single +region, see "help regalgebra".) For example, consider the following +set of regions: +

+  ANNULUS 25 25 5 10
+  ELLIPSE 20 20 5 10 315 
+  BOX 15 15 5 10
+
+The resulting mask will look as follows: + +
+         1234567890123456789012345678901234567890
+         ----------------------------------------
+      40:........................................
+      39:........................................
+      38:........................................
+      37:........................................
+      36:........................................
+      35:........................................
+      34:....................111111111...........
+      33:...................11111111111..........
+      32:.................111111111111111........
+      31:.................111111111111111........
+      30:................11111111111111111.......
+      29:...............1111111.....1111111......
+      28:...............111111.......111111......
+      27:...............11111.222222..11111......
+      26:...............111112222222..11111......
+      25:...............111112222222..11111......
+      24:...............111112222222..11111......
+      23:...............111112222222..11111......
+      22:...............111111222222.111111......
+      21:..............211111112222.1111111......
+      20:............322211111111111111111.......
+      19:............32222111111111111111........
+      18:............22222111111111111111........
+      17:............222222211111111111..........
+      16:............22222222111111111...........
+      15:............222222222...................
+      14:............22222222....................
+      13:............222222......................
+      12:............33333.......................
+      11:............33333.......................
+      10:........................................
+       9:........................................
+       8:........................................
+       7:........................................
+       6:........................................
+       5:........................................
+       4:........................................
+       3:........................................
+       2:........................................
+       1:........................................
+
+Note that when a pixel is in 2 or more regions, it is arbitrarily +assigned to a one of the regions in question (often based on how a +give C compiler optimizes boolean expressions). + +

+

Region accelerators

+ +

+Two types of \fBaccelerators, to simplify region specification, +are provided as natural extensions to the ways shapes are described. +These are: extended lists of parameters, specifying multiple regions, +valid for annulus, box, circle, ellipse, pie, and points; and +n=, valid for annulus, box, circle, ellipse, and pie (not +point). In both cases, one specification is used to define several +different regions, that is, to define shapes with different mask +values in the region mask. + +

+The following regions accept accelerator syntax: +

+  shape      arguments
+  -----      ------------------------------------------
+  ANNULUS    xcenter ycenter radius1 radius2 ... radiusn
+  ANNULUS    xcenter ycenter inner_radius outer_radius n=[number]
+  BOX        xcenter ycenter xw1 yh1 xw2 yh2 ... xwn yhn (angle)
+  BOX        xcenter ycenter xwlo yhlo xwhi yhhi n=[number] (angle)
+  CIRCLE     xcenter ycenter r1 r2 ... rn              # same as annulus
+  CIRCLE     xcenter ycenter rinner router n=[number]  # same as annulus
+  ELLIPSE    xcenter ycenter xw1 yh1 xw2 yh2 ... xwn yhn (angle)
+  ELLIPSE    xcenter ycenter xwlo yhlo xwhi yhhi n=[number] (angle)
+  PIE        xcenter ycenter angle1 angle2 (angle3) (angle4) (angle5) ...
+  PIE        xcenter ycenter angle1 angle2 (n=[number])
+  POINT      x1 y1 x2 y2 ... xn yn
+
+Note that the circle accelerators are simply aliases for the annulus +accelerators. + +

+For example, several annuli at the same center can be specified in one +region expression by specifying more than two radii. If N +radii are specified, then N-1 annuli result, with the outer +radius of each preceding annulus being the inner radius of the +succeeding annulus. Each annulus is considered a separate region, and +is given a separate mask value. For example, +

+  ANNULUS 20 20 0 2 5 10 15 20 
+
+specifies five different annuli centered at 20 20, and is equivalent to: +
+  ANNULUS 20.0 20.0  0  2
+  ANNULUS 20.0 20.0  2  5
+  ANNULUS 20.0 20.0  5 10
+  ANNULUS 20.0 20.0 10 15
+  ANNULUS 20.0 20.0 15 20
+
+The mask is shown below: + +
+         1234567890123456789012345678901234567890
+         ----------------------------------------
+      40:........................................
+      39:.............5555555555555..............
+      38:...........55555555555555555............
+      37:.........555555555555555555555..........
+      36:........55555555555555555555555.........
+      35:......555555555555555555555555555.......
+      34:.....55555555544444444444555555555......
+      33:....5555555544444444444444455555555.....
+      32:....5555555444444444444444445555555.....
+      31:...555555444444444444444444444555555....
+      30:..55555544444444444444444444444555555...
+      29:..55555544444443333333334444444555555...
+      28:.5555554444444333333333334444444555555..
+      27:.5555544444433333333333333344444455555..
+      26:555555444444333333333333333444444555555.
+      25:555554444443333333333333333344444455555.
+      24:555554444433333332222233333334444455555.
+      23:555554444433333322222223333334444455555.
+      22:555554444433333222222222333334444455555.
+      21:555554444433333222111222333334444455555.
+      20:555554444433333222111222333334444455555.
+      19:555554444433333222111222333334444455555.
+      18:555554444433333222222222333334444455555.
+      17:555554444433333322222223333334444455555.
+      16:555554444433333332222233333334444455555.
+      15:555554444443333333333333333344444455555.
+      14:555555444444333333333333333444444555555.
+      13:.5555544444433333333333333344444455555..
+      12:.5555554444444333333333334444444555555..
+      11:..55555544444443333333334444444555555...
+      10:..55555544444444444444444444444555555...
+       9:...555555444444444444444444444555555....
+       8:....5555555444444444444444445555555.....
+       7:....5555555544444444444444455555555.....
+       6:.....55555555544444444444555555555......
+       5:......555555555555555555555555555.......
+       4:........55555555555555555555555.........
+       3:.........555555555555555555555..........
+       2:...........55555555555555555............
+       1:.............5555555555555..............
+
+ +

+For boxes and ellipses, if an odd number of arguments is specified, +then the last argument is assumed to be an angle. Otherwise, the +angle is assumed to be zero. For example: +

+  ellipse 20 20 3 5 6 10 9 15 12 20 45
+
+specifies an 3 ellipses at a 45 degree angle: +
+	1234567890123456789012345678901234567890
+	----------------------------------------
+	40:........................................
+	39:........................................
+	38:........................................
+	37:........................................
+	36:........33333333........................
+	35:......333333333333......................
+	34:.....3333333333333333...................
+	33:....333333333333333333..................
+	32:....33333332222233333333................
+	31:...3333332222222222333333...............
+	30:...33333222222222222233333..............
+	29:...333332222222222222223333.............
+	28:...3333222222211112222223333............
+	27:...33332222211111111222223333...........
+	26:...333322222111111111122223333..........
+	25:...3333222211111111111122223333.........
+	24:....3332222111111..1111122223333........
+	23:....333322211111.....11112222333........
+	22:....33332222111.......11112223333.......
+	21:.....33322221111.......11122223333......
+	20:.....33332221111.......11112223333......
+	19:.....33332222111.......11112222333......
+	18:......33332221111.......11122223333.....
+	17:.......33322221111.....111112223333.....
+	16:.......3333222211111..1111112222333.....
+	15:........3333222211111111111122223333....
+	14:.........333322221111111111222223333....
+	13:..........33332222211111111222223333....
+	12:...........3333222222111122222223333....
+	11:............333322222222222222233333....
+	10:.............33333222222222222233333....
+	9:..............3333332222222222333333....
+	8:...............33333333222223333333.....
+	7:.................333333333333333333.....
+	6:..................3333333333333333......
+	5:.....................333333333333.......
+	4:.......................33333333.........
+	3:........................................
+	2:........................................
+	1:........................................
+
+Note in the above example that the lower limit is not part of the +region for boxes, circles, and ellipses. This makes circles and annuli +equivalent, i.e.: +
+  circle  20 20 5 10 15 20
+  annulus 20 20 5 10 15 20
+
+both give the following region mask: +
+        1234567890123456789012345678901234567890
+        ----------------------------------------
+        40:........................................
+        39:.............3333333333333..............
+        38:...........33333333333333333............
+        37:.........333333333333333333333..........
+        36:........33333333333333333333333.........
+        35:......333333333333333333333333333.......
+        34:.....33333333322222222222333333333......
+        33:....3333333322222222222222233333333.....
+        32:....3333333222222222222222223333333.....
+        31:...333333222222222222222222222333333....
+        30:..33333322222222222222222222222333333...
+        29:..33333322222221111111112222222333333...
+        28:.3333332222222111111111112222222333333..
+        27:.3333322222211111111111111122222233333..
+        26:333333222222111111111111111222222333333.
+        25:333332222221111111111111111122222233333.
+        24:33333222221111111.....11111112222233333.
+        23:3333322222111111.......1111112222233333.
+        22:333332222211111.........111112222233333.
+        21:333332222211111.........111112222233333.
+        20:333332222211111.........111112222233333.
+        19:333332222211111.........111112222233333.
+        18:333332222211111.........111112222233333.
+        17:3333322222111111.......1111112222233333.
+        16:33333222221111111.....11111112222233333.
+        15:333332222221111111111111111122222233333.
+        14:333333222222111111111111111222222333333.
+        13:.3333322222211111111111111122222233333..
+        12:.3333332222222111111111112222222333333..
+        11:..33333322222221111111112222222333333...
+        10:..33333322222222222222222222222333333...
+        9:...333333222222222222222222222333333....
+        8:....3333333222222222222222223333333.....
+        7:....3333333322222222222222233333333.....
+        6:.....33333333322222222222333333333......
+        5:......333333333333333333333333333.......
+        4:........33333333333333333333333.........
+        3:.........333333333333333333333..........
+        2:...........33333333333333333............
+        1:.............3333333333333..............
+
+
+ +

+As a final example, specifying several angles in one pie slice +expression is equivalent to specifying several separate slices with +the same center. As with the annulus, if N angles are +specified, then N-1 slices result, with the ending angle of +each preceding slice being the starting angle of the succeeding slice. +Each slice is considered a separate region, and is given a separate +mask value. For example, +

+  PIE 12 12 315 45 115 270 
+
+specifies three regions as shown below: +
+	1234567890123456789012345678901234567890
+	----------------------------------------
+	40:2222222222222222222222222222222222222222
+	39:2222222222222222222222222222222222222221
+	38:2222222222222222222222222222222222222211
+	37:2222222222222222222222222222222222222111
+	36:2222222222222222222222222222222222221111
+	35:3222222222222222222222222222222222211111
+	34:3222222222222222222222222222222222111111
+	33:3322222222222222222222222222222221111111
+	32:3322222222222222222222222222222211111111
+	31:3332222222222222222222222222222111111111
+	30:3332222222222222222222222222221111111111
+	29:3333222222222222222222222222211111111111
+	28:3333222222222222222222222222111111111111
+	27:3333322222222222222222222221111111111111
+	26:3333322222222222222222222211111111111111
+	25:3333322222222222222222222111111111111111
+	24:3333332222222222222222221111111111111111
+	23:3333332222222222222222211111111111111111
+	22:3333333222222222222222111111111111111111
+	21:3333333222222222222221111111111111111111
+	20:3333333322222222222211111111111111111111
+	19:3333333322222222222111111111111111111111
+	18:3333333332222222221111111111111111111111
+	17:3333333332222222211111111111111111111111
+	16:3333333333222222111111111111111111111111
+	15:3333333333222221111111111111111111111111
+	14:3333333333322211111111111111111111111111
+	13:3333333333322111111111111111111111111111
+	12:33333333333.1111111111111111111111111111
+	11:3333333333331111111111111111111111111111
+	10:333333333333.111111111111111111111111111
+	9:333333333333..11111111111111111111111111
+	8:333333333333...1111111111111111111111111
+	7:333333333333....111111111111111111111111
+	6:333333333333.....11111111111111111111111
+	5:333333333333......1111111111111111111111
+	4:333333333333.......111111111111111111111
+	3:333333333333........11111111111111111111
+	2:333333333333.........1111111111111111111
+	1:333333333333..........111111111111111111
+
+ +

+The annulus, box, circle, ellipse, and pie shapes also accept an +n=[int] syntax for specifying multiple regions. The +n=[int]syntax interprets the previous (shape-dependent) +arguments as lower and upper limits for the region and creates n +shapes with evenly spaced boundaries. For example, if n=[int] +is specified in an annulus, the two immediately preceding radii +(rn and rm) are divided into int annuli, such +that the inner radius of the first is rn and the outer radius +of the last is rm. For example, +

+  ANNULUS 20 20 5 20 n=3
+
+is equivalent to: +
+  ANNULUS 20 20 5 10 15 20 
+
+If this syntax is used with an ellipse or box, then the two preceding +pairs of values are taken to be lower and upper limits for a set of +ellipses or boxes. A circle uses the two preceding arguments for upper +and lower radii. For pie, the two preceding angles are divided into n +wedges such that the starting angle of the first is the lower bound +and the ending angle of the last is the upper bound. In all cases, +the n=[int] syntax allows any single alphabetic character +before the "=", i.e, i=3, z=3, etc. are all equivalent. + +

+Also note that for boxes and ellipses, the optional angle argument is +always specified after the n=[int] syntax. For example: +

+  ellipse 20 20 4 6 16 24 n=3 45
+
+specifies 3 elliptical regions at an angle of 45 degrees:
+
+
+  1234567890123456789012345678901234567890
+  ----------------------------------------
+  40:........33333333........................
+  39:.....33333333333333.....................
+  38:....33333333333333333...................
+  37:...33333333333333333333.................
+  36:..33333333333333333333333...............
+  35:.3333333333222223333333333..............
+  34:3333333322222222222233333333............
+  33:33333332222222222222223333333...........
+  32:333333222222222222222222333333..........
+  31:3333322222222222222222222333333.........
+  30:33333222222222111122222222333333........
+  29:333332222222111111112222222333333.......
+  28:3333222222211111111111222222333333......
+  27:3333222222111111111111112222233333......
+  26:33332222221111111111111112222233333.....
+  25:33332222211111111.111111112222233333....
+  24:333322222111111......111111222223333....
+  23:333322222111111.......111112222233333...
+  22:33333222221111.........11111222223333...
+  21:333332222211111.........11112222233333..
+  20:.33332222211111.........11111222223333..
+  19:.33333222221111.........111112222233333.
+  18:..33332222211111.........11112222233333.
+  17:..333332222211111.......111111222233333.
+  16:...333322222111111......111111222223333.
+  15:...333332222211111111.111111112222233333
+  14:....333332222211111111111111122222233333
+  13:.....33333222221111111111111122222233333
+  12:.....33333322222211111111111222222233333
+  11:......3333332222222111111112222222333333
+  10:.......333333222222221111222222222333333
+  9:........33333322222222222222222222333333
+  8:.........333333222222222222222222333333.
+  7:..........33333332222222222222223333333.
+  6:...........3333333322222222222233333333.
+  5:.............3333333333222223333333333..
+  4:..............33333333333333333333333...
+  3:................33333333333333333333....
+  2:..................33333333333333333.....
+  1:....................33333333333333......
+
+ +

+Both the variable argument syntax and the n=[int] syntax must +occur alone in a region descriptor (aside from the optional angle for +boxes and ellipses). They cannot be combined. Thus, it is not valid +to precede or follow an n=[int] accelerator with more angles or +radii, as in this example: +

+  # INVALID -- one too many angles before a=5 ...
+  # and no angles are allowed after a=5
+  PIE 12 12 10 25 50 a=5 85 135
+
+Instead, use three separate specifications, such as: +
+  PIE 12 12 10 25
+  PIE 12 12 25 50 a=5
+  PIE 12 12 85 135
+
+The original (IRAF) implementation of region filtering permitted this +looser syntax, but we found it caused more confusion than it was worth +and therefore removed it. + +

+NB: Accelerators may be combined with other shapes in a boolean +expression in any order. (This is a change starting with funtools +v1.1.1. Prior to this release, the accelerator shape had to be +specified last). The actual region mask id values returned depend on the +order in which the shapes are specified, although the total number of +pixels or rows that pass the filter will be consistent. For this +reason, use of accelerators in boolean expressions is discouraged in +programs such as funcnts, where region mask id values are used +to count events or image pixels. + +

+[All region masks displayed in this document were generated using the +fundisp routine and the undocumented "mask=all" argument (with +spaced removed using sed ): +

+  fundisp "funtools/funtest/test40.fits[ANNULUS 25 25 5 10]" mask=all |\
+  sed 's/ //g'
+
+Note that you must supply an image of the appropriate size -- in this case, +a FITS image of dimension 40x40 is used.] + + + + + +

+Go to Funtools Help Index + +

Last updated: March 12, 2007
+ + + diff --git a/doc/regions.html b/doc/regions.html new file mode 100644 index 0000000..33a8cde --- /dev/null +++ b/doc/regions.html @@ -0,0 +1,563 @@ + + + +Spatial Region Filtering + + + + +

Regions: Spatial Region Filtering

+ + +

Summary

+

+This document contains a summary of the user interface for spatial +region filtering images and tables. + + +

Description

+

+Spatial region filtering allows a program to select regions of an +image or rows of a table (e.g., X-ray events) to process using +simple geometric shapes and boolean combinations of shapes. When an +image is filtered, only pixels found within these shapes are +processed. When a table is filtered, only rows found within these +shapes are processed. + +

+Spatial region filtering for images and tables is accomplished by +means of region specifications. A region specification +consists of one or more region expressions, which are geometric +shapes,combined according to the rules of boolean algebra. Region +specifications also can contain comments and local/global processing +directives. + +

+Typically, region specifications are specified using bracket notation +appended to the filename of the data being processed: +

+  foo.fits[circle(512,512,100)]
+
+It is also possible to put region specification inside a file and +then pass the filename in bracket notation: +
+  foo.fits[@my.reg]
+
+ +

+When region filters are passed in bracket notation in this manner, the +filtering is set up automatically when the file is opened and all +processing occurs through the filter. Programs also can use the filter +library API to open filters explicitly. + +

Region Expressions

+ +More specifically, region specifications consist of one or more lines +containing: +
+  # comment until end of line
+  global   keyword=value keyword=value  ... # set global value(s)
+  # include the following file in the region descriptor
+  @file
+  # use the FITS image as a mask (cannot be used with other regions)
+  @fitsimage
+  # each region expression contains shapes separated by operators
+  [region_expression1], [region_expression2], ...
+  [region_expression], [region_expression], ...
+
+ +

+A single region expression consists of: +

+  # parens and commas are optional, as is the + sign
+  [+-]shape(num , num , ...) OP1 shape num num num OP2 shape ...
+
+e.g.:
+
+  ([+-]shape(num , num , ...) && shape num  num || shape(num, num)
+  # a comment can come after a region -- reserved for local properties
+  [+-]shape(num , num , ...)  # local properties go here, e.g. color=red
+
+ +

+Thus, a region descriptor consists of one or more region +expressions or regions, separated by comas, new-lines, or +semi-colons. Each region consists of one or more geometric +shapes combined using standard boolean operation. Several types +of shapes are supported, including: + +

+  shape:        arguments:
+  -----         ----------------------------------------
+  ANNULUS       xcenter ycenter inner_radius outer_radius
+  BOX           xcenter ycenter xwidth yheight (angle)
+  CIRCLE        xcenter ycenter radius
+  ELLIPSE       xcenter ycenter xwidth yheight (angle)
+  FIELD         none
+  LINE          x1 y1 x2 y2
+  PIE           xcenter ycenter angle1 angle2
+  POINT         x1 y1
+  POLYGON       x1 y1 x2 y2 ... xn yn
+
+ +

+In addition, the following regions accept accelerator syntax: + +

+  shape      arguments
+  -----      ------------------------------------------
+  ANNULUS    xcenter ycenter radius1 radius2 ... radiusn
+  ANNULUS    xcenter ycenter inner_radius outer_radius n=[number]
+  BOX        xcenter ycenter xw1 yh1 xw2 yh2 ... xwn yhn (angle)
+  BOX        xcenter ycenter xwlo yhlo xwhi yhhi n=[number] (angle)
+  CIRCLE     xcenter ycenter r1 r2 ... rn              # same as annulus
+  CIRCLE     xcenter ycenter rinner router n=[number]  # same as annulus
+  ELLIPSE    xcenter ycenter xw1 yh1 xw2 yh2 ... xwn yhn (angle)
+  ELLIPSE    xcenter ycenter xwlo yhlo xwhi yhhi n=[number] (angle)
+  PIE        xcenter ycenter angle1 angle2 (angle3) (angle4) (angle5) ...
+  PIE        xcenter ycenter angle1 angle2 (n=[number])
+  POINT      x1 y1 x2 y2 ... xn yn
+
+Note that the circle accelerators are simply aliases for the annulus +accelerators. See region geometry +for more information about accelerators. + +

+Finally, the following are combinations of pie with different shapes +(called "panda" for "Pie AND Annulus") allow for easy specification of +radial sections: + +

+  shape:  arguments:
+  -----   ---------
+  PANDA   xcen ycen ang1 ang2 nang irad orad nrad   # circular
+  CPANDA  xcen ycen ang1 ang2 nang irad orad nrad   # circular
+  BPANDA  xcen ycen ang1 ang2 nang xwlo yhlo xwhi yhhi nrad (ang) # box
+  EPANDA  xcen ycen ang1 ang2 nang xwlo yhlo xwhi yhhi nrad (ang) # ellipse
+
+ +The panda and cpanda specify combinations of annulus and circle with pie, +respectively and give identical results. The bpanda combines box and pie, +while epanda combines ellipse and pie. +See region geometry +for more information about pandas. + +

+The following "shapes" are ignored by funtools (generated by ds9): +

+  shape:        arguments:
+  -----         ---------
+  PROJECTION    x1 y1 x2 y2 width    # NB: ignored by funtools
+  RULER         x1 y1 x2 y2          # NB: ignored by funtools
+  TEXT          x y                  # NB: ignored by funtools
+  GRID                               # NB: ignored by funtools
+  TILE                               # NB: ignored by funtools
+  COMPASS                            # NB: ignored by funtools
+
+ +

+All arguments to regions are real values; integer values are +automatically converted to real where necessary. All angles are in +degrees and run from the positive image x-axis to the positive image +y-axis. If a rotation angle is part of the associated WCS header, that +angle is added implicitly as well. + +

+Note that 3-letter abbreviations are supported for all shapes, so that +you can specify "circle" or "cir". + +

+

Columns Used in Region Filtering

+

+By default, the x,y values in a region expression refer to the two +"image binning" columns, i.e. the columns that would be used to +bin the data into an image. For images, these are just the 2 dimensions +of the image. For tables, these usually default to x and y but +can be changed as required. For example, in Funtools, new binning +columns are specified using a bincols=(col1,col2) statement within +the bracket string on the command line. +

+Alternate columns for region filtering can be specified by the syntax: +

+  (col1,col2)=region(...)
+
+e.g.: +
+  (X,Y)=annulus(x,y,ri,ro)
+  (PHA,PI)=circle(x,y,r)
+  (DX,DY)=ellipse(x,y,a,b[,angle])
+
+ +

+

Region Algebra

+ +(See also Region Algebra for more complete +information.) + +

+Region shapes can be combined together using Boolean operators: +

+  Symbol        Operation       Use
+  --------      ---------       -----------------------------------
+  !             not             Exclude this shape from this region
+  & or &&       and             Include only the overlap of these shapes
+  | or ||       inclusive or    Include all of both shapes
+  ^             exclusive or    Include both shapes except their overlap
+
+Note that the !region syntax must be combined with another region in order +that we be able to assign a region id properly. That is, +
+  !circle(512,512,10)
+
+is not a legal region because there is no valid region id to work with. +To get the full field without a circle, combine the above with field(), +as in: +
+  field() && !circle(512,512,10)
+
+ +

Region Separators Also Are Operators

+ +

+As mentioned previously, multiple region expressions can be specified +in a region descriptor, separated by commas, new-lines, or +semi-colons. When such a separator is used, the boolean OR operator +is automatically generated in its place but, unlike explicit use of +the OR operator, the region ID is incremented (starting from 1). + +

+For example, the two shapes specified in this example are given the +same region value: +

+  foo.fits[circle(512,512,10)||circle(400,400,20)]
+
+On the other hand, the two shapes defined in the following example are +given different region values: +
+  foo.fits[circle(512,512,10),circle(400,400,20)]
+
+ +

+Of course these two examples will both mask the same table rows or +pixels. However, in programs that distinguish region id's (such as +funcnts ), they will act +differently. The explicit OR operator will result in one region +expression consisting of two shapes having the same region id and +funcnts will report a single region. The comma operator will cause +funcnts to report two region expressions, each with one shape, in +its output. + +

+In general, commas are used to separate region expressions entered +in bracket notation on the command line: +

+  # regions are added to the filename in bracket notation
+  foo.fits[circle(512,512,100),circle(400,400,20)]
+
+New-lines are used to separate region +expressions in a file: +
+  # regions usually are separated by new-lines in a file
+  # use @filename to include this file on the command line
+  circle(512,512,100)
+  circle(400,400,20)
+
+Semi-colons are provided for backward compatibility with the original +IRAF/PROS implementation and can be used in either case. + +

+If a pixel is covered by two different regions expressions, it is +given the mask value of the first region that contains that +pixel. That is, successive regions do not overwrite previous +regions in the mask, as was the case with the original PROS regions. +In this way, an individual pixel is covered by one and only one +region. This means that one must sometimes be careful about the order +in which regions are defined. If region N is fully contained within +region M, then N should be defined before M, or else it will be +"covered up" by the latter. + +

Region Exclusion

+

+Shapes also can be globally excluded from all the region specifiers in +a region descriptor by using a minus sign before a region: + +

+  operator      arguments:
+  --------      -----------
+  -             Globally exclude the region expression following '-' sign
+                from ALL regions specified in this file
+
+The global exclude region can be used by itself; in such a case, field() is +implied. + +

+A global exclude differs from the local exclude (i.e. a shape prefixed +by the logical not "!" symbol) in that global excludes are logically +performed last, so that no region will contain pixels from a globally +excluded shape. A local exclude is used in a boolean expression with +an include shape, and only excludes pixels from that include shape. +Global excludes cannot be used in boolean expressions. + +

Include Files

+ +

+The @filename directive specifies an include file +containing region expressions. This file is processed as part of +the overall region descriptor: +

+  foo.fits[circle(512,512,10),@foo]
+
+A filter include file simply includes text without changing the state +of the filter. It therefore can be used in expression. That is, if the +file foo1 contains "pi==1" and foo2 contains "pha==2" then +the following expressions are equivalent: +
+  "[@foo1&&@foo2]"   is equivalent to   "[pi==1&&pha==2]"
+  "[pha==1||@foo2]"  is equivalent to   "[pi==1||pha==2]"
+  "[@foo1,@foo2]"    is equivalent to   "[pi==1,pha==2]"
+
+Be careful that you specify evaluation order properly using +parenthesis, especially if the include file contains multiple +filter statements. For example, consider a file containing two +regions such as: +
+  circle 512 512 10
+  circle 520 520 10
+
+If you want to include only events (or pixels) that are in these regions +and have a pi value of 4, then the correct syntax is: +
+    pi==4&&(@foo)
+
+since this is equivalent to: +
+    pi==4 && (circle 512 512 10 || circle 520 520 10)
+
+If you leave out the parenthesis, you are filtering this statement: +
+    pi==4 && circle 512 512 10 || circle 520 520 10)
+
+which is equivalent to: +
+    (pi==4 && circle 512 512 10) || circle 520 520 10)
+
+The latter syntax only applies the pi test to the first region. + +

+For image-style filtering, the @filename can specify an 8-bit +or 16-bit FITS image. In this case, the pixel values in the mask image +are used as the region mask. The valid pixels in the mask must have +positive values. Zero values are excluded from the mask and negative +values are not allowed. Moreover, the region id value is taken as +the image pixel value and the total number of regions is taken to be +the highest pixel value. The dimensions of the image mask must be less +than or equal to the image dimensions of the data. The mask will be +replicated as needed to match the size of the image. (Thus, best +results are obtained when the data dimensions are an even multiple of +the mask dimensions.) + +

+An image mask can be used in any image filtering operation, regardless +of whether the data is of type image or table. For example, the +funcnts ) +program performs image filtering on images or tables, and so +FITS image masks are valid input for either type of data in this +program.. An image mask cannot be used in a program such as +fundisp ) +when the input data is a table, because fundisp displays +rows of a table and processes these rows using event-style filtering. + +

Global and Local Properties of Regions

+ +

+The ds9 image display program describes a host of properties such as +color, font, fix/free state, etc. Such properties can be specified +globally (for all regions) or locally (for an individual region). +The global keyword specifies properties and qualifiers for all +regions, while local properties are specified in comments on the same +line as the region: +

+  global color=red
+  circle(10,10,2)
+  circle(20,20,3) # color=blue
+  circle(30,30,4)
+
+The first and third circles will be red, which the second circle will +be blue. Note that funtools currently ignores region properties, as +they are used in display only. + +

Coordinate Systems

+ +For each region, it is important to specify the coordinate system +used to interpret the region, i.e., to set the context in which position and +size values are interpreted. For this purpose, the following keywords +are recognized: + +
+  name                  description
+  ----                  ------------------------------------------
+  PHYSICAL              pixel coords of original file using LTM/LTV
+  IMAGE                 pixel coords of current file
+  FK4, B1950            sky coordinate systems
+  FK5, J2000            sky coordinate systems
+  GALACTIC              sky coordinate systems
+  ECLIPTIC              sky coordinate systems
+  ICRS                  currently same as J2000
+  LINEAR                linear wcs as defined in file
+  AMPLIFIER             mosaic coords of original file using ATM/ATV
+  DETECTOR              mosaic coords of original file using DTM/DTV
+
+ +

+

Specifying Positions, Sizes, and Angles

+ +The arguments to region shapes can be floats or integers describing +positions and sizes. They can be specified as pure numbers or using +explicit formatting directives: + +
+  position arguments    description
+  ------------------    ------------------------------
+  [num]                 context-dependent (see below)
+  [num]d                degrees
+  [num]r                radians
+  [num]p                physical pixels
+  [num]i                image pixels
+  [num]:[num]:[num]     hms for 'odd' position arguments
+  [num]:[num]:[num]     dms for 'even' position arguments
+  [num]h[num]m[num]s    explicit hms
+  [num]d[num]m[num]s    explicit dms
+
+  size arguments        description
+  --------------        -----------
+  [num]                 context-dependent (see below)
+  [num]"                arc seconds
+  [num]'                arc minutes
+  [num]d                degrees
+  [num]r                radians
+  [num]p                physical pixels
+  [num]i                image pixels
+
+ + +When a "pure number" (i.e. one without a format directive such as 'd' +for 'degrees') is specified, its interpretation depends on the context +defined by the 'coordsys' keyword. In general, the rule is: + +

+All pure numbers have implied units corresponding to the current +coordinate system. + +

+If no such system is explicitly specified, the default system is +implicitly assumed to be PHYSICAL. + +

+In practice this means that for IMAGE and PHYSICAL systems, pure +numbers are pixels. Otherwise, for all systems other than linear, +pure numbers are degrees. For LINEAR systems, pure numbers are in the +units of the linear system. This rule covers both positions and +sizes. + +

+The input values to each shape can be specified in several coordinate +systems including: + +

+  name                  description
+  ----                  ----------------------------
+  IMAGE                 pixel coords of current file
+  LINEAR                linear wcs as defined in file
+  FK4, B1950            various sky coordinate systems
+  FK5, J2000
+  GALACTIC
+  ECLIPTIC
+  ICRS
+  PHYSICAL              pixel coords of original file using LTM/LTV
+  AMPLIFIER             mosaic coords of original file using ATM/ATV
+  DETECTOR              mosaic coords of original file using DTM/DTV
+
+ +

+If no coordinate system is specified, PHYSICAL is assumed. PHYSICAL or +a World Coordinate System such as J2000 is preferred and most general. +The coordinate system specifier should appear at the beginning of the +region description, on a separate line (in a file), or followed by a +new-line or semicolon; e.g., + +

+  global coordsys physical
+  circle 6500 9320 200
+
+ +The use of celestial input units automatically implies WORLD +coordinates of the reference image. Thus, if the world coordinate +system of the reference image is J2000, then + +
+  circle 10:10:0 20:22:0 3'
+
+ +is equivalent to: + +
+  circle 10:10:0 20:22:0 3' # j2000
+
+ +
+Note that by using units as described above, you may mix coordinate +systems within a region specifier; e.g., + +
+  circle 6500 9320 3' # physical
+
+ +

+Note that, for regions which accept a rotation angle: + +

+ellipse (x, y, r1, r2, angle)
+box(x, y, w, h, angle)
+
+ +the angle is relative to the specified coordinate system. In +particular, if the region is specified in WCS coordinates, the angle +is related to the WCS system, not x/y image coordinate axis. For WCS +systems with no rotation, this obviously is not an issue. However, +some images do define an implicit rotation (e.g., by using a non-zero +CROTA value in the WCS parameters) and for these images, the angle +will be relative to the WCS axes. In such case, a region specification +such as: + +
+fk4;ellipse(22:59:43.985, +58:45:26.92,320", 160", 30)
+
+ +will not, in general, be the same region specified as: + +
+physical;ellipse(465, 578, 40, 20, 30)
+
+ +even when positions and sizes match. The angle is relative to WCS axes +in the first case, and relative to physical x,y axes in the second. + + +

+More detailed descriptions are available for: +Region Geometry, +Region Algebra, +Region Coordinates, and +Region Boundaries. + + + + + +

+Go to Funtools Help Index + +

Last updated: November 17, 2005
+ + + diff --git a/doc/sman/fun4.index b/doc/sman/fun4.index new file mode 100644 index 0000000..ce00526 Binary files /dev/null and b/doc/sman/fun4.index differ diff --git a/doc/sman/fun4.index.prop b/doc/sman/fun4.index.prop new file mode 100644 index 0000000..9b01bbd Binary files /dev/null and b/doc/sman/fun4.index.prop differ diff --git a/doc/sman/fun4.index.version b/doc/sman/fun4.index.version new file mode 100644 index 0000000..accb620 --- /dev/null +++ b/doc/sman/fun4.index.version @@ -0,0 +1,2 @@ +SMAN_DATA_VERSION 1.2 +VERSION 1.01 diff --git a/doc/sman/fun8.index b/doc/sman/fun8.index new file mode 100644 index 0000000..44fd94a Binary files /dev/null and b/doc/sman/fun8.index differ diff --git a/doc/sman/fun8.index.prop b/doc/sman/fun8.index.prop new file mode 100644 index 0000000..5fd8f14 Binary files /dev/null and b/doc/sman/fun8.index.prop differ diff --git a/doc/sman/fun8.index.version b/doc/sman/fun8.index.version new file mode 100644 index 0000000..accb620 --- /dev/null +++ b/doc/sman/fun8.index.version @@ -0,0 +1,2 @@ +SMAN_DATA_VERSION 1.2 +VERSION 1.01 diff --git a/doc/sman_conf.tmpl b/doc/sman_conf.tmpl new file mode 100644 index 0000000..abac8e4 --- /dev/null +++ b/doc/sman_conf.tmpl @@ -0,0 +1,96 @@ +# $Id: sman-defaults.conf,v 1.33 2006/05/02 02:09:18 joshr Exp $ +# by Josh Rabinowitz, 2005-2006. +# this is the default sman configuration file. +# if you need to make changes, copy this file to +# /usr/local/etc/sman.conf and make changes to that file. +# NOTE: if you do use a custom sman.conf you may need to manually +# NOTE: merge changes from this file to your configuration file +# NOTE: after upgrading sman versions + +# See 'perldoc sman.conf' for more documentation + +# sman-defaults.conf +# holds the defaults for sman. +# the directive names are case-insensitive + +SWISHECMD @SW@ -v 0 + +# MANCMD specifies how to manually convert the manpages to +# ASCII. For 'manual' parsing. +# %F is the quoted full [F]ilename of the manpage (ie, '/usr/share/man/man1/ls.1.gz) +# %S is the quoted [S]ection of the manpage (ie, '1') +# %C is the quoted (apparent) [C]ommand of the manpage (ie, 'ls') + +# NOTE: lack of a MANCMD (or a value of AUTOCONFIG) causes sman-update +# to autoconfigure the value of MANCMD. It will most likely choose +# one of the below: + +# this works for most linuxes we've tested. ie 'man /man/man1/ls.1' +# MANCMD man -c %F +# this works for freebsd 4.4 and Mac OS X. ie 'man 1 ls' +#MANCMD man -c %S %C +# -c means reparse man page sources (for line re-wrapping) + +# works for Solaris and OS X +MANCMD man -s %S %C + +# the COL program is used to strip out backspaces and +# such from the MAN output. + +COLCMD col -b + +# all vars starting with ENV_ get set in the +# environment, sans the ENV_ prefix. + +# Try to make MAN wrap lines at 256 chars (not 80!) +ENV_MANWIDTH 256 + +# where to put sman's temp files. +# (Use SWISHE_TMPDIR to set affect SWISH-E at index time) + +TMPDIR /tmp + +# meta and property aliases. If your XML has different tags. +# refentrytitle, manvolnum and refpurpose are the names from rman +# each ALIASES line turns into 2 lines for SWISH-E like this: +#MetaNameAlias swishtitle refentrytitle +#PropertyNameAlias swishtitle refentrytitle + +TITLEALIASES RefEntryTitle +SECALIASES ManVolNum +DESCALIASES RefPurpose +#MANPAGEALIASES swishdefault + +# All parameters beginning with SWISHE_ have the SWISHE_ prefix stripped +# and are written into a tmp config file for SWISH-E at index time. + +# SWISHE_IndexFile is also used by sman as which index to search. + +# SWISHE_IndexFile specifies which index to create and search +# NOTE: if the containing dir (ie, /var/lib/sman) is owned by an unprivileged +# user, then sman-update can be run as that user. + +SWISHE_IndexFile /var/lib/sman/sman.index + +# these have 'SWISHE_' stripped off and are used +# when indexing the man pages. + +SWISHE_IndexComments no + # don't index text in comments + +# These are important! You probably don't want to mess with these. +SWISHE_IndexPointer "format=%V;" + # for future use. %V becomes $Sman::SMAN_DATA_VERSION +#SWISHE_FuzzyIndexingMode Stem + # above was deprecated in 2.4.3, does not work in 2.4.4 +SWISHE_FuzzyIndexingMode Stemming_en2 +SWISHE_MetaNames desc sec swishtitle manpage digest +SWISHE_PropertyNames desc sec manpage digest + +# SWISHE_IgnoreWords File: ./stopwords/english.txt +# allow _ and : but not / +# .'s in middle of word are word chars, for files like 'named.conf'. +SWISHE_WordCharacters 0123456789abcdefghijklmnopqrstuvwxyz_:. +SWISHE_BeginCharacters 0123456789abcdefghijklmnopqrstuvwxyz_: +SWISHE_EndCharacters 0123456789abcdefghijklmnopqrstuvwxyz_: +SWISHE_IgnoreTotalWordCountWhenRanking 0 diff --git a/doc/szlong.c b/doc/szlong.c new file mode 100644 index 0000000..b0e84bc --- /dev/null +++ b/doc/szlong.c @@ -0,0 +1,8 @@ +#include + +int main(int argc, char **argv) +{ + fprintf(stdout, "%d\n", (int)sizeof(long)); + return 0; +} + diff --git a/doc/tabcalc.c b/doc/tabcalc.c new file mode 100644 index 0000000..5f1cb30 --- /dev/null +++ b/doc/tabcalc.c @@ -0,0 +1,196 @@ +/* + * + * This program was generated automatically by the funcalc program, + * by running the tabcalc.c template through the funcalc.l lexical analyzer. + * On this system, it was (or can be) built a command such as: + * + * $COMMAND + * + */ +#include + +extern char *optarg; +extern int optind; + +/* define the types of event records we have to handle */ +#define REC_CUR 1 +#define REC_PREV 2 +#define REC_NEXT 4 + +/* default number of rows to read at a time */ +#define MAXROW 8192 +int maxrow=MAXROW; + +typedef struct rowstruct{ +$MEMBERS +} *Row, RowRec; + +/* global definitions and init calls go here */ +$GLOBAL + +/* main program */ +int main (int argc, char **argv) +{ + int c, i, got, total, rectype, start, stop, skip, args; + int del=0; + char *s; + Fun fun, ofun; + Row rowbuf, rowptr; + Row cur, prev, next; + $AUTO + + /* local definitions, followed by init calls go here */ + $LOCAL + + /* exit on gio errors */ + setgerror(1); + + /* avoid shared library problems by using "process" type for filtering */ + putenv("FILTER_PTYPE=process"); + + /* process switch arguments */ + while ((c = getopt(argc, argv, "d")) != -1){ + switch(c){ + case 'd': + del = 1; + break; + } + } + /* check for required arguments */ + args = argc - optind; + /* make sure we have minimal arguments */ + if( args < $ARGS ){ + if( $ARGS == 1 ) + fprintf(stderr, + "usage: [expr] | funcalc [-e expr] [-f file] iname\n"); + else + fprintf(stderr, + "usage: [expr] | funcalc [-e expr] [-f file] iname oname [cols]\n"); + goto error; + } + + /* set rectype: determine whether we need prev,next records */ + rectype=$RECTYPE; + + /* get maxrow,if user-specified */ + if( (s=(char *)getenv("FUN_MAXROW")) != NULL ) + maxrow = atoi(s); + /* make sure max row is large enough to handle prev, next */ + if( rectype & (REC_PREV|REC_NEXT) ) maxrow = MAX(3,maxrow); + + /* open input file */ + if( !(fun = FunOpen(argv[optind+0], "rc", NULL)) ){ + gerror(stderr, "could not FunOpen input file: %s\n", argv[optind+0]); + goto error; + } + + /* open the output FITS image, inheriting params from input */ + if( $ARGS > 1 ){ + if( !(ofun = FunOpen(argv[optind+1], "w", fun)) ){ + gerror(stderr, "could not FunOpen output file: %s\n", argv[optind+1]); + goto error; + } + } + + /* select columns */ + FunColumnSelect(fun, sizeof(RowRec), "merge=replace", + $SELECT + NULL); + + /* activate specified columns -- these will be written to the output file */ + if( args >= 3 ) + FunColumnActivate(fun, argv[optind+2], NULL); + + /* allocate space for rowbuf -- we will manage this buffer ourselves */ + rowbuf = (Row)calloc(maxrow, sizeof(RowRec)); + + /* no record read yet */ + total = 0; + + /* any user-defined calls before we enter the row loop go here */ + $BEFORE + + /* main loop -- get rows and process */ + while( 1 ){ + /* need prev record */ + if( rectype & REC_PREV ){ + /* no records yet: read new batch of records into start of rowbuf */ + if( total == 0 ){ + rowptr = rowbuf; + } + /* we have read records: move last record from last batch into first + new record and read new records after that */ + else{ + /* if we are accessing next, we did not actually process final record, + therefore we do it now */ + if( rectype & REC_NEXT ){ + memcpy(rowbuf, rowbuf+(got-2), sizeof(RowRec)*2); + rowptr = rowbuf+2; + } + /* not accessing next, so we just move last record processed */ + else{ + memcpy(rowbuf, rowbuf+(got-1), sizeof(RowRec)); + rowptr = rowbuf+1; + } + } + /* start at 2nd record so as to have a valid prev */ + start = 1; + } + /* processing that does not require prev */ + else{ + rowptr = rowbuf; + start = 0; + } + + /* adjust maxrow to account for handling of prev record */ + skip = (rowptr - rowbuf)/sizeof(RowRec); + + /* read new rows */ + if( !FunTableRowGet(fun, rowptr, maxrow-skip, NULL, &got) ) + break; + + /* if we need access to next record, don't process the last one we read */ + if( rectype & REC_NEXT ){ + stop = got - 1; + } + /* processing that does not require acces to next, process as cur */ + else{ + stop = got; + } + + /* process all rows */ + for(i=start; i 1 ) + FunTableRowPut(ofun, (char *)cur, 1, i, NULL); + } + total += got; + } + + /* any user-defined calls after we finish the row loop go here */ + $AFTER + + /* free row data */ + if( rowbuf ) free(rowbuf); + + /* clean up -- close output before input to perform flush automatically */ + if( $ARGS > 1 ) + FunClose(ofun); + FunClose(fun); + + /* delete program if necessary */ + if( del ) unlink(argv[0]); + return(0); + +error: + /* delete program if necessary */ + if( del ) unlink(argv[0]); + return(1); +} diff --git a/doc/text.html b/doc/text.html new file mode 100644 index 0000000..f4fdac8 --- /dev/null +++ b/doc/text.html @@ -0,0 +1,564 @@ + + + +Column-based Text Files + + + + +

Funtext: Support for Column-based Text Files

+ + +

Summary

+

+This document contains a summary of the options for processing column-based +text files. + + +

Description

+ +

+Funtools will automatically sense and process "standard" +column-based text files as if they were FITS binary tables without any +change in Funtools syntax. In particular, you can filter text files +using the same syntax as FITS binary tables: +

+  fundisp foo.txt'[cir 512 512 .1]'
+  fundisp -T foo.txt > foo.rdb
+  funtable foo.txt'[pha=1:10,cir 512 512 10]' foo.fits
+
+ +

+The first example displays a filtered selection of a text file. The +second example converts a text file to an RDB file. The third example +converts a filtered selection of a text file to a FITS binary table. + +

+Text files can also be used in Funtools image programs. In this case, +you must provide binning parameters (as with raw event files), using +the bincols keyword specifier: + +

+  bincols=([xname[:tlmin[:tlmax:[binsiz]]]],[yname[:tlmin[:tlmax[:binsiz]]]
+
+ +For example: +
+  funcnts foo'[bincols=(x:1024,y:1024)]' "ann 512 512 0 10 n=10"
+
+ +

Standard Text Files

+ +

+Standard text files have the following characteristics: + +

    +
  • Optional comment lines start with # +
  • Optional blank lines are considered comments +
  • An optional table header consists of the following (in order): +
      +
    • a single line of alpha-numeric column names +
    • an optional line of unit strings containing the same number of cols +
    • an optional line of dashes containing the same number of cols +
    +
  • Data lines follow the optional header and (for the present) consist of + the same number of columns as the header. +
  • Standard delimiters such as space, tab, comma, semi-colon, and bar. +
+ +

+Examples: + +

+  # rdb file
+  foo1	foo2	foo3	foos
+  ----	----	----	----
+  1	2.2	3	xxxx
+  10	20.2	30	yyyy
+
+  # multiple consecutive whitespace and dashes
+  foo1   foo2    foo3 foos
+  ---    ----    ---- ----
+     1    2.2    3    xxxx
+    10   20.2    30   yyyy
+
+  # comma delims and blank lines
+  foo1,foo2,foo3,foos
+
+  1,2.2,3,xxxx
+  10,20.2,30,yyyy
+
+  # bar delims with null values
+  foo1|foo2|foo3|foos
+  1||3|xxxx
+  10|20.2||yyyy
+
+  # header-less data
+  1     2.2   3 xxxx
+  10    20.2 30 yyyy
+
+ +

+The default set of token delimiters consists of spaces, tabs, commas, +semi-colons, and vertical bars. Several parsers are used +simultaneously to analyze a line of text in different ways. One way +of analyzing a line is to allow a combination of spaces, tabs, and +commas to be squashed into a single delimiter (no null values between +consecutive delimiters). Another way is to allow tab, semi-colon, and +vertical bar delimiters to support null values, i.e. two consecutive +delimiters implies a null value (e.g. RDB file). A successful parser +is one which returns a consistent number of columns for all rows, with +each column having a consistent data type. More than one parser can +be successful. For now, it is assumed that successful parsers all +return the same tokens for a given line. (Theoretically, there are +pathological cases, which will be taken care of as needed). Bad parsers +are discarded on the fly. + +

+If the header does not exist, then names "col1", "col2", etc. are +assigned to the columns to allow filtering. Furthermore, data types +for each column are determined by the data types found in the columns +of the first data line, and can be one of the following: string, int, +and double. Thus, all of the above examples return the following +display: +

+  fundisp foo'[foo1>5]'
+        FOO1                  FOO2       FOO3         FOOS
+  ---------- --------------------- ---------- ------------
+          10           20.20000000         30         yyyy
+
+ +

Comments Convert to Header Params

+ +

+Comments which precede data rows are converted into header parameters and +will be written out as such using funimage or funhead. Two styles of comments +are recognized: + +

+1. FITS-style comments have an equal sign "=" between the keyword and +value and an optional slash "/" to signify a comment. The strict FITS +rules on column positions are not enforced. In addition, strings only +need to be quoted if they contain whitespace. For example, the following +are valid FITS-style comments: + +

+  # fits0 = 100
+  # fits1 = /usr/local/bin
+  # fits2 = "/usr/local/bin /opt/local/bin"
+  # fits3c = /usr/local/bin /opt/local/bin /usr/bin
+  # fits4c = "/usr/local/bin /opt/local/bin" / path dir
+
+ +Note that the fits3c comment is not quoted and therefore its value is the +single token "/usr/local/bin" and the comment is "opt/local/bin /usr/bin". +This is different from the quoted comment in fits4c. + +

+2. Free-form comments can have an optional colon separator between the +keyword and value. In the absence of quote, all tokens after the +keyword are part of the value, i.e. no comment is allowed. If a string +is quoted, then slash "/" after the string will signify a comment. +For example: + +

+  # com1 /usr/local/bin
+  # com2 "/usr/local/bin /opt/local/bin"
+  # com3 /usr/local/bin /opt/local/bin /usr/bin
+  # com4c "/usr/local/bin /opt/local/bin" / path dir
+  
+  # com11: /usr/local/bin
+  # com12: "/usr/local/bin /opt/local/bin"
+  # com13: /usr/local/bin /opt/local/bin /usr/bin
+  # com14c: "/usr/local/bin /opt/local/bin" / path dir
+
+ +

+Note that com3 and com13 are not quoted, so the whole string is part of +the value, while comz4c and com14c are quoted and have comments following +the values. + +

+Some text files have column name and data type information in the header. +You can specify the format of column information contained in the +header using the "hcolfmt=" specification. See below for a detailed +description. + +

Multiple Tables in a Single File

+ +

+Multiple tables are supported in a single file. If an RDB-style file +is sensed, then a ^L (vertical tab) will signify end of +table. Otherwise, an end of table is sensed when a new header (i.e., +all alphanumeric columns) is found. (Note that this heuristic does not +work for single column tables where the column type is ASCII and the +table that follows also has only one column.) You also can specify +characters that signal an end of table condition using the eot= +keyword. See below for details. + +

+You can access the nth table (starting from 1) in a multi-table file +by enclosing the table number in brackets, as with a FITS extension: + +

+  fundisp foo'[2]'
+
+The above example will display the second table in the file. +(Index values start at 1 in oder to maintain logical compatibility +with FITS files, where extension numbers also start at 1). + + +

TEXT() Specifier

+ +

+As with ARRAY() and EVENTS() specifiers for raw image arrays and raw +event lists respectively, you can use TEXT() on text files to pass +key=value options to the parsers. An empty set of keywords is +equivalent to not having TEXT() at all, that is: + +

+  fundisp foo
+  fundisp foo'[TEXT()]'
+
+ +are equivalent. A multi-table index number is placed before the TEXT() +specifier as the first token, when indexing into a multi-table: + + fundisp foo'[2,TEXT(...)]' + +

+The filter specification is placed after the TEXT() specifier, separated +by a comma, or in an entirely separate bracket: + +

+  fundisp foo'[TEXT(...),circle 512 512 .1]'
+  fundisp foo'[2,TEXT(...)][circle 512 512 .1]'
+
+ +

Text() Keyword Options

+ +

+The following is a list of keywords that can be used within the TEXT() +specifier (the first three are the most important): + +

+ +

+

delims="[delims]" +
Specify token delimiters for this file. Only a single parser having these +delimiters will be used to process the file. +
+  fundisp foo.fits'[TEXT(delims="!")]'
+  fundisp foo.fits'[TEXT(delims="\t%")]'
+
+ +

+

comchars="[comchars]" +
Specify comment characters. You must include "\n" to allow blank lines. +These comment characters will be used for all standard parsers (unless delims +are also specified). +
+  fundisp foo.fits'[TEXT(comchars="!\n")]'
+
+ +

+

cols="[name1:type1 ...]" +
Specify names and data type of columns. This overrides header +names and/or data types in the first data row or default names and +data types for header-less tables. +
+  fundisp foo.fits'[TEXT(cols="x:I,y:I,pha:I,pi:I,time:D,dx:E,dy:e")]'
+
+

+If the column specifier is the only keyword, then the cols= is not +required (in analogy with EVENTS()): +

+  fundisp foo.fits'[TEXT(x:I,y:I,pha:I,pi:I,time:D,dx:E,dy:e)]'
+
+Of course, an index is allowed in this case: +
+  fundisp foo.fits'[2,TEXT(x:I,y:I,pha:I,pi:I,time:D,dx:E,dy:e)]'
+
+ +

+

eot="[eot delim]" +
Specify end of table string specifier for multi-table files. RDB +files support ^L. The end of table specifier is a string and the whole +string must be found alone on a line to signify EOT. For example: +
+  fundisp foo.fits'[TEXT(eot="END")]' 
+
+will end the table when a line contains "END" is found. Multiple lines +are supported, so that: +
+  fundisp foo.fits'[TEXT(eot="END\nGAME")]'
+
+will end the table when a line contains "END" followed by a line +containing "GAME". +

+In the absence of an EOT delimiter, a new table will be sensed when a new +header (all alphanumeric columns) is found. + +

+

null1="[datatype]" +
Specify data type of a single null value in row 1. +Since column data types are determined by the first row, a null value +in that row will result in an error and a request to specify names and +data types using cols=. If you only have a one null in row 1, you don't +need to specify all names and columns. Instead, use null1="type" to +specify its data type. + +

+

alen=[n] +
Specify size in bytes for ASCII type columns. +FITS binary tables only support fixed length ASCII columns, so a +size value must be specified. The default is 16 bytes. + +

+

nullvalues=["true"|"false"] +
Specify whether to expect null values. +Give the parsers a hint as to whether null values should be allowed. The +default is to try to determine this from the data. + +

+

whitespace=["true"|"false"] +
Specify whether surrounding white space should be kept as part of +string tokens. By default surrounding white space is removed from +tokens. + +

+

header=["true"|"false"] +
Specify whether to require a header. This is needed by tables +containing all string columns (and with no row containing dashes), in +order to be able to tell whether the first row is a header or part of +the data. The default is false, meaning that the first row will be +data. If a row dashes are present, the previous row is considered the +column name row. + +

+

units=["true"|"false"] +
Specify whether to require a units line. +Give the parsers a hint as to whether a row specifying units should be +allowed. The default is to try to determine this from the data. + +

+

i2f=["true"|"false"] +
Specify whether to allow int to float conversions. +If a column in row 1 contains an integer value, the data type for that +column will be set to int. If a subsequent row contains a float in +that same column, an error will be signaled. This flag specifies that, +instead of an error, the float should be silently truncated to +int. Usually, you will want an error to be signaled, so that you can +specify the data type using cols= (or by changing the value of +the column in row 1). + +

+

comeot=["true"|"false"|0|1|2] +
Specify whether comment signifies end of table. +If comeot is 0 or false, then comments do not signify end of table and +can be interspersed with data rows. If the value is true or 1 (the +default for standard parsers), then non-blank lines (e.g. lines +beginning with '#') signify end of table but blanks are allowed +between rows. If the value is 2, then all comments, including blank +lines, signify end of table. + +

+

lazyeot=["true"|"false"] +
Specify whether "lazy" end of table should be permitted (default is +true for standard formats, except rdb format where explicit ^L is required +between tables). A lazy EOT can occur when a new table starts directly +after an old one, with no special EOT delimiter. A check for this EOT +condition is begun when a given row contains all string tokens. If, in +addition, there is a mismatch between the number of tokens in the +previous row and this row, or a mismatch between the number of string +tokens in the prev row and this row, a new table is assumed to have +been started. For example: +
+  ival1 sval3
+  ----- -----
+  1     two
+  3     four
+
+  jval1 jval2 tval3
+  ----- ----- ------
+  10    20    thirty
+  40    50    sixty
+
+Here the line "jval1 ..." contains all string tokens. In addition, +the number of tokens in this line (3) differs from the number of +tokens in the previous line (2). Therefore a new table is assumed +to have started. Similarly: +
+  ival1 ival2 sval3
+  ----- ----- -----
+  1     2     three
+  4     5     six
+
+  jval1 jval2 tval3
+  ----- ----- ------
+  10    20    thirty
+  40    50    sixty
+
+Again, the line "jval1 ..." contains all string tokens. The number of +string tokens in the previous row (1) differs from the number of +tokens in the current row(3). We therefore assume a new table as been +started. This lazy EOT test is not performed if lazyeot is explicitly +set to false. + +

+

hcolfmt=[header column format] +
Some text files have column name and data type information in the header. +For example, VizieR catalogs have headers containing both column names +and data types: +
+  #Column e_Kmag  (F6.3)  ?(k_msigcom) K total magnitude uncertainty (4)  [ucd=ERROR]
+  #Column Rflg    (A3)    (rd_flg) Source of JHK default mag (6)  [ucd=REFER_CODE]
+  #Column Xflg    (I1)    [0,2] (gal_contam) Extended source contamination (10) [ucd=CODE_MISC]
+
+ +while Sextractor files have headers containing column names alone: + +
+  #   1 X_IMAGE         Object position along x                         [pixel]
+  #   2 Y_IMAGE         Object position along y                         [pixel]
+  #   3 ALPHA_J2000     Right ascension of barycenter (J2000)           [deg]
+  #   4 DELTA_J2000     Declination of barycenter (J2000)               [deg]
+
+The hcolfmt specification allows you to describe which header lines +contain column name and data type information. It consists of a string +defining the format of the column line, using "$col" (or "$name") to +specify placement of the column name, "$fmt" to specify placement of the +data format, and "$skip" to specify tokens to ignore. You also can +specify tokens explicitly (or, for those users familiar with how +sscanf works, you can specify scanf skip specifiers using "%*"). +For example, the VizieR hcolfmt above might be specified in several ways: +
+  Column $col ($fmt)    # explicit specification of "Column" string
+  $skip  $col ($fmt)    # skip one token
+  %*s $col  ($fmt)      # skip one string (using scanf format)
+
+while the Sextractor format might be specified using: +
+  $skip $col            # skip one token  
+  %*d $col              # skip one int (using scanf format)
+
+You must ensure that the hcolfmt statement only senses actual column +definitions, with no false positives or negatives. For example, the +first Sextractor specification, "$skip $col", will consider any header +line containing two tokens to be a column name specifier, while the +second one, "%*d $col", requires an integer to be the first token. In +general, it is preferable to specify formats as explicitly as +possible. + +

+Note that the VizieR-style header info is sensed automatically by the +funtools standard VizieR-like parser, using the hcolfmt "Column $col +($fmt)". There is no need for explicit use of hcolfmt in this case. + +

+

debug=["true"|"false"] +
Display debugging information during parsing. + +
+ +

Environment Variables

+ +

+Environment variables are defined to allow many of these TEXT() values to be +set without having to include them in TEXT() every time a file is processed: + +

+  keyword       environment variable
+  -------       --------------------
+  delims        TEXT_DELIMS
+  comchars      TEXT_COMCHARS
+  cols          TEXT_COLUMNS
+  eot           TEXT_EOT
+  null1         TEXT_NULL1
+  alen          TEXT_ALEN
+  bincols       TEXT_BINCOLS
+  hcolfmt       TEXT_HCOLFMT
+
+ +

Restrictions and Problems

+ +

+As with raw event files, the '+' (copy extensions) specifier is not +supported for programs such as funtable. + +

+String to int and int to string data conversions are allowed by the +text parsers. This is done more by force of circumstance than by +conviction: these transitions often happens with VizieR catalogs, +which we want to support fully. One consequence of allowing these +transitions is that the text parsers can get confused by columns which +contain a valid integer in the first row and then switch to a +string. Consider the following table: +

+  xxx   yyy     zzz
+  ----  ----    ----
+  111   aaa     bbb
+  ccc   222     ddd
+
+The xxx column has an integer value in row one a string in row two, +while the yyy column has the reverse. The parser will erroneously +treat the first column as having data type int: +
+  fundisp foo.tab
+         XXX          YYY          ZZZ
+  ---------- ------------ ------------
+         111        'aaa'        'bbb'
+  1667457792        '222'        'ddd'
+
+while the second column is processed correctly. This situation can be avoided +in any number of ways, all of which force the data type of the first column +to be a string. For example, you can edit the file and explicitly quote the +first row of the column: +
+  xxx   yyy     zzz
+  ----  ----    ----
+  "111" aaa     bbb
+  ccc   222     ddd
+
+  [sh] fundisp foo.tab
+           XXX          YYY          ZZZ
+  ------------ ------------ ------------
+         '111'        'aaa'        'bbb'
+         'ccc'        '222'        'ddd'
+
+You can edit the file and explicitly set the data type of the first column: +
+  xxx:3A   yyy  zzz
+  ------   ---- ----
+  111      aaa  bbb
+  ccc      222  ddd
+
+  [sh] fundisp foo.tab
+           XXX          YYY          ZZZ
+  ------------ ------------ ------------
+         '111'        'aaa'        'bbb'
+         'ccc'        '222'        'ddd'
+
+You also can explicitly set the column names and data types of all columns, +without editing the file: +
+  [sh] fundisp foo.tab'[TEXT(xxx:3A,yyy:3A,zzz:3a)]'
+           XXX          YYY          ZZZ
+  ------------ ------------ ------------
+         '111'        'aaa'        'bbb'
+         'ccc'        '222'        'ddd'
+
+The issue of data type transitions (which to allow and which to disallow) +is still under discussion. + + + + + +

+Go to Funtools Help Index + +

Last updated: August 3, 2007
+ + + diff --git a/doc/twcs.c b/doc/twcs.c new file mode 100644 index 0000000..2da9319 --- /dev/null +++ b/doc/twcs.c @@ -0,0 +1,61 @@ +/* + * + * twcs.c -- example using WCS Library + * + */ + +#include + +int main(int argc, char **argv) +{ + int i; + Fun fun; + struct WorldCoor *wcs; /* WCS info */ + double x,y,ra,dec,xr,yr; + + if(argc == 1){ + fprintf(stderr, "usage: twcs iname\n"); + exit(1); + } + + /* open Funtools file */ + /* Funopen makes initial WCS library call: wcs = wcsinit(header_string) */ + if( !(fun = FunOpen(argv[1], "r ", NULL)) ){ + fprintf(stderr, "ERROR can't open file: %s\n", argv[1]); + exit(1); + } + + /* get wcs structure */ + FunInfoGet(fun,FUN_WCS,&wcs,0); + if( !wcs || !iswcs(wcs) ){ + fprintf(stderr,"No WCS data"); + return(1); + } + + /* read input, convert pixels to wcs and back */ + while(1){ + fprintf(stdout,"\nInput x y: "); + if(scanf("%lf %lf", &x, &y) != EOF){ + if(x <= -999) + break; + /* convert image pixels to sky coords */ + pix2wcs(wcs, x, y, &ra, &dec); + fprintf(stdout,"Convert from pixels to ra,dec using pix2wcs()\n"); + fprintf(stdout, "x=%.10g y=%.10g -> ra=%.10g dec=%.10g\n", + x, y, ra, dec); + /* convert sky coords to image pixels */ + fprintf(stdout,"Convert from ra,dec -> pixels using wcs2pix()\n"); + wcs2pix(wcs, ra, dec, &xr, &yr, &i); + fprintf(stdout, "ra=%.10g dec=%.10g -> x=%.10g y=%.10g offscale=%d\n", + ra, dec, xr, yr, i); + } + else + break; + } + + /* clean up */ + /* FunClose makes final WCS library call: wcsfree(wcs) */ + FunClose(fun); + return(0); +} + diff --git a/doc/view.html b/doc/view.html new file mode 100644 index 0000000..6f1faa8 --- /dev/null +++ b/doc/view.html @@ -0,0 +1,376 @@ + + + +Database View Support for Tables + + + + +

Funview: Database View Support for Tables

+ + +

Summary

+

+This document contains a summary of the options for utilizing +database-inspired Views of tables. + + +

Description

+ +

Database Views

+

+In database parlance, a View defines a "virtual table", i.e., +a description of row and/or column selection filters (but with no +permanent storage space allocated). When used in place of a table, a +View selects the specified rows and/or columns from one or more real +tables. Views enable you to see complicated data tables in a more +convenient format. They also can be used as a security mechanism, by +restricting user access to specific columns and/or rows. [See: +

+http://www.cs.unibo.it/~ciaccia/COURSES/RESOURCES/SQLTutorial/sqlch5.htm
+
+for a good discussion of SQL Views.] + +

+Funtools supports an expanded notion of Views for all tabular data +(FITS tables, raw binary tables, and ASCII column files). Funtools +Views allow you to pre-set values for the filter specification, the +columns to activate, and display format (though the latter is for +fundisp only). Setting the filter and column activation values +provides functionality equivalent to that of a classical database +View, while the ability to set the format is similar to classical +report writing capabilities. + +

Funtools View Attributes

+

+A Funtools View is a text file containing one or more of the following +columns: +

+  column         description
+  ------         -----------------------------
+  view           name of view
+  file           data file name or template
+  filter         filter specification
+  columns        columns to activate
+  format         fundisp format specification
+
+All of the attribute columns are optional, including +the view name itself. This means that a View can be named or +unnamed. Unnamed Views can refer to a specific file or a template of +files (obviously if neither the view or the file column is specified, +the input View specification will never be used). You can specify any +combination of filter, column, and format parameters. (It also is +possible to apply file-specific View to other files; see the discussion +on View Lists below). Each column has a size limit of 1024 characters. + +

+For example, consider the following View file: +

+  view    file                    format  columns       filter
+  ----    ----------------------  ------  ------------  -------
+  x3      ${HOME}/data/snr.ev     I=%4d   x y pi pha    cir 512 512 .1 
+  x2      ${HOME}/data/snr.ev             x y pi pha    cir 512 512 .1 
+  x1      ${HOME}/data/snr.ev                           cir 512 512 .1 
+  x1a     ${HOME}/data/snr.ev             x y pi pha
+  x0      ${HOME}/data/snr.ev
+  xf                              I=%4d
+  xc                                      x y pi pha
+  xr                                                    cir 512 512 .1
+          *.ev                            x y pi pha
+          *.fit                           x y dx dy     cir 400 400  3
+          *.fits                  I=%3d   x y dx dy     cir 400 400  3
+
+This database example is in rdb format, i.e. using tab delimiters and +permitting null values. Any valid ASCII table format is acceptable, +but if you use a format that does not permit null values, it will be +necessary to quote the null strings. + +

+The first five entries (x3, x2, x1, x1a, x0) are named entries defining +default values specifically for the snr.ev data file. Typically, you +would use these Views by specifying View name, and the corresponding +file, filter, column, and format values would be used. Note that the x0 +View is essentially an alias for the pathname of this file. + +

+The next three entries define defaults that can be applied to any +file. You typically would use these View names in conjunction with +a specific file name (see View Lists below) so that the associated +parameter(s) were applied to that file. + +

+The last three entry in the database define unnamed Views that +pertains to all files ending with the specified templates. In these +cases, any View that specifies a file name matching the file template +would be processed with the associated parameter attributes. + +

Invoking a Funtools View (in Place of an Input File)

+

+To use a Funtools View, you simply pre-pend the "v:" prefix to a View name or +a file name where an input file name usually is specified. For example: +

+  fundisp v:x3
+
+specifies that the View named x3 (with its file name and associated +parameters) is processed as the input file to fundisp. Using the +example database, above, this is equivalent to: +
+  fundisp  -f "I=%4d" ${HOME}/data/snr.ev'[cir 512 512 .1]'  "x y pi pha"
+
+That is, the format is used with fundisp's -f (format) switch, while the +filename and extension are composed of the x3 View's filename and +region filter. + +

+Similarly, executing a command such as: +

+  fundisp v:foo.fit
+
+will match the unnamed View associated with the template "*.fit". +This is equivalent to executing: +
+  fundisp foo.fit'[cir 400 400 3]' "x y dx dy"
+
+Of course, if you omit the "v:" prefix, then no View processing takes place: +
+  fundisp foo.fit    # process foo.fit without any View parameters
+  fundisp x3         # error (assuming there is no file named x3)
+
+ +

Basic View Matching Rules

+ +

+When a "v:" prefix is recognized, Funtools searches for a View database +file in the following order: +

+  location             description
+  ------------         ------------------------------------
+  FUN_VIEWFILE         environment variable (any file name)
+  ./.funtools.vu       hidden file, default name
+  $HOME/.funtools.vu   hidden file, default name
+
+The first View database file located is used to construct a new +filename, as well as an activation column specification and a format +specification. The following rules are used: + +

+1. An attempt is made to match the input name (i.e., the part of the +input View after the "v:" prefix) against the view column value +(if present) of each row in the database. If a match is found, the +values of all non-blank columns are saved for later use. Also note +that the first match terminates the search: i.e., the order of the +database rows matters. + +

+2. If no view match is made, an attempt is made to match the input +name against the file column value (if present). Matching is +performed on the full pathname of both the input name and the +database file name, and on the non-directory (root) part of these +files. This means that the root specification: +

+  fundisp v:snr.ev
+
+will match a row in the database that has a full pathname in the file, +allowing you to use a file-matched View without having to +specify the full pathname. In this example, the "v:snr.ev" View +specification will match the first row (v:x3) in the database: +
+  x3   ${HOME}/data/snr.ev     I=%4d   x y pi pha    cir 512 512 .1 
+
+even though the row contains a fully qualified pathname as the file +value. Once again, values of all non-blank columns are saved, and the +first match terminates the search. + +

+3. If neither a view or a view match has been found, +then a simple template match is attempted against the view +values. Template matching supports a simplified version of file +globbing (not a regular expression), with support for a single "*" +(all characters), "?" (single character), or "[...]" (range) specification. + +

+4. If no template match was found on the view column, then a +simple template match is attempted against the file columns. + +

+5. If no match is found, then the filename (minus the "v:" prefix) is +returned. + +

More on View Matching Rules: Single vs. Multiple Matches

+ +The matching rules described above stop after the first match, +regardless of whether that match provides values for all three +parameters (filter, columns, and format). In cases where a view +or file match does not provide all three values, it is possible +that a template match might do so. With regard to the example View +database above, the x1 View provides only a filter, while omitting +both the format and columns values. But note that the final rows in +the database could provide the values via a template match on the +filename. This sort of multiple matching is especially valuable in +order to provide "global" values to several Views. + +

+Obviously, multiple matching might not be wanted in every +case. Therefore, we support both multiple matching and single matching +according to the value of the FUN_VIEWMATCH environment variable. If +the FUN_VIEWMATCH environment variable exists and if its value begins +with "s", then a single match is used and missing parameters are not +filled in with subsequent template matches on the file name. That is, +matching rules above are followed exactly as explained above. If the +value of this environment variable begins with "m" (or does not exist), +then multiple matches are used to try to fill in missing parameters. +In this case, template matching always takes place and missing values are +taken from these template matches. + +

+Thus, in the example above, the View specification: +

+  fundisp v:x1
+
+will take the file name and filter value from the x1 View: +
+  x1      ${HOME}/data/snr.ev                           cir 512 512 .1 
+
+The column value then will be taken from the "*.ev" file template match +against the x1 file name: +
+          *.ev                            x y pi pha
+
+Note once again that order is important: missing values are taken in the +order in which the template matches are processed. + +

View Lists: Applying a View to Any File

+ +

+It is possible to apply a named View, or even several Views, to any +data file by appending a viewlist immediately after the standard "v:" +prefix. A viewlist takes the form: +

+  :v1,v2,...vn:
+
+where v1, v2, etc. are named Views. The two ":" colon characters surrounding +the list are required. Thus, the syntax for applying a viewlist to a file is: +
+  v::view1,view2,...viewn:filename
+
+Note that the name after the last ":" is assumed to be a file; it is +not permissible (or sensible) to use a View name. + +

+For example, the View specification: +

+  fundisp v::x2:foo
+
+applies the x2 View to the file foo (even if there is a View named foo) +and (in using our example database) is equivalent to: +
+  ./fundisp foo'[cir 512 512 .1] "x y pi pha"
+
+The same command can be effected using a list of Views: +
+  fundisp v::x1,x1a:foo
+
+ +

+What happens if a viewlist is used and the file also matches a +template? Consider, for example, this View specification: +

+  fundisp v::x2:foo.fit
+
+Here, the x2 View will supply filter and column values, while the +template *.fit can also supply (different) filter and column +values. In this case, the explicitly specified Views of the viewlist +trump the matched view values. + +

+On the other hand, if a file template match can supply a View value +that is not supplied by the viewlist, then that value will be taken +from the file template match. For example: +

+  fundisp v::x2:foo.fits
+
+does not explicitly supply a format value, but the file match on *.fits +can and does. You can avoid supplying missing values using file template +matching by replacing the first ":" with a "-" in a viewlist +specification: +
+  fundisp v:-x2:foo.fits
+
+The use of ":+" to explicitly allow file template matching is also +supported, but is the same as the default case. Note that the nuances +of viewlist support are subject to change as our experience and +understanding grow. + +

Overriding Values Associated with a View

+ +

+To override values associated with a View, simply supply the override +values in the correct place on the command line. Thus, given +the example database described above, the command: +

+  fundisp v:x3
+
+specifies that the View named x3, along with its file name and +associated parameters, be processed as the input file to fundisp in +this way: +
+  fundisp  -f "I=%4d" ${HOME}/data/snr.ev'[cir 512 512 .1]'  "x y pi pha"
+
+To override one or more of these values, simply specify a new value +for the format, filter, or columns. For example, if your input View file +contains a filter, then the View will use that filter as an override +of the View filter: +
+  fundisp v:x3'[cir 400 400 3]'
+
+will use the columns and format of the x3 View but not the x3 filter. Further +examples are: +
+  fundisp v:x3 "x y dx dy"    # activate a different set of columns
+  fundisp -f "I=%3d" v:x3     # use a different format statement
+
+ +

+Note that extension names, extension index values, and other +non-filter specifications do not override the View +filter. Thus: +

+  fundisp v:foo.fit[3]
+
+will still use the filter associated with the .fit template (see above), since +the "3" is an extension index, not a filter. + +

Environment Variables

+ +The following environment variables are used by Funtools Views: +
+
FUN_VIEWNAME +
The FUN_VIEWNAME environment variable specifies the +name and location of the View database file. If not present, the +files ./.funtools.vu and $HOME/.funtools.vu are searched for, in +that order. + +
FUN_VIEWMATCH +
The FUN_VIEWMATCH environment variable specifies whether a +single match or multiple match algorithm is used to locate parameter +values. If the value of this environment variable begins with "s", +then a single match is used and missing parameters are not filled in +with subsequent template matches on the file name. If the value begins +with "m", then multiple matches are used to try to fill in missing +parameters. The default is to use multiple matches. +
+ +

Restrictions and Problems

+ +Support for overriding a filter (while not overriding extension names, +extension indexes, etc.) requires that we can sense the presence of a +filter in a bracket specification. It is unclear yet whether our +algorithm is perfect. + +

+Go to Funtools Help Index + +

Last updated: August 3, 2007
+ + + diff --git a/faq/Makefile.in b/faq/Makefile.in new file mode 100644 index 0000000..09900f5 --- /dev/null +++ b/faq/Makefile.in @@ -0,0 +1,135 @@ +# +# This is a Makefile for the Funtools testing. If it has the name "Makefile.in" +# then it is a template for a Makefile; to generate the actual Makefile, +# run "./configure", which is a configuration script generated by the +# "autoconf" program (constructs like "@foo@" will get replaced in the +# actual Makefile. +# + +#---------------------------------------------------------------- +# Things you can change to personalize the Makefile for your own +# site (you can make these changes in either Makefile.in or +# Makefile, but changes to Makefile will get lost if you re-run +# the configuration script). +#---------------------------------------------------------------- + +# Default top-level directories in which to install architecture- +# specific files (exec_prefix) and machine-independent files such +# as scripts (prefix). The values specified here may be overridden +# at configure-time with the --exec-prefix and --prefix options +# to the "configure" script. + +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +# The following definition can be set to non-null for special systems +# like AFS with replication. It allows the pathnames used for installation +# to be different than those used for actually reference files at +# run-time. INSTALL_ROOT is prepended to $prefix and $exec_prefix +# when installing files. +INSTALL_ROOT = + +# extra includes for compiling +INCLUDES = -I. -I$(prefix)/include + +# extra libs +EXTRA_LIBS = @EXTRA_LIBS@ + +# the full set of libraries for linking +LIBS = -L.. -lfuntools $(EXTRA_LIBS) -lm + +# To change the compiler switches, for example to change from -O +# to -g, change the following line: +CFLAGS = @CFLAGS@ + +# To add ld switches, change the following line: +LDFLAGS = @LDFLAGS@ + +# Some versions of make, like SGI's, use the following variable to +# determine which shell to use for executing commands: +SHELL = /bin/sh + +# extra modules added by configure.in to fix OS bugs +EXTRA_OBJS = @EXTRA_OBJS@ + +# There are just too many different versions of "install" around; +# better to use the install-sh script that comes with the distribution, +# which is slower but guaranteed to work. + +INSTALL = @srcdir@/install-sh -c +INSTALL_PROGRAM = ${INSTALL} +INSTALL_DATA = ${INSTALL} -m 644 + +#---------------------------------------------------------------- +# The information below is modified by the configure script when +# Makefile is generated from Makefile.in. You shouldn't normally +# modify any of this stuff by hand. +#---------------------------------------------------------------- + +AC_FLAGS = @DEFS@ +RANLIB = @RANLIB@ + +# web site for installation +WEBDIR = /proj/rd/www/funtools + +#---------------------------------------------------------------- +# The information below should be usable as is. The configure +# script won't modify it and you shouldn't need to modify it +# either. +#---------------------------------------------------------------- + +CC = @CC@ + +CC_SWITCHES = ${CFLAGS} ${INCLUDES} ${AC_FLAGS} + +DEPEND_SWITCHES = ${CFLAGS} ${INCLUDES} ${AC_FLAGS} + +PROGS = tev tim + +all: $(PROGS) + +tev: tev.o + $(CC) $(LDFLAGS) tev.o -o tev $(LIBS) + +tim: tim.o + $(CC) $(LDFLAGS) tim.o -o tim $(LIBS) + +Makefile: Makefile.in + $(SHELL) config.status + +RM = rm -f + +clean: + $(RM) *.a *.so *.o *.exe core errs *pure* .nfs* \ + foo* *~ *.log \#* TAGS *.E a.out errors \ + $(PROGS) $(TESTPROGS) \ + gmon.out *.pg *.bak \ + config.info config.log \ + *fun*.out doc/*~ + $(RM) -r autom4te.cache + +distclean: clean + $(RM) Makefile config.status config.cache config.log + +install: + @echo "Nothing to install in faq" + +www: + -@( if [ -d ${WEBDIR} ]; then \ + echo "installing in Web site: ${WEBDIR}"; \ + mkdir -p ${WEBDIR}/faq; \ + cp -p *.html ${WEBDIR}/faq/.; \ + else \ + echo "Web site not available for install"; \ + fi;) + +pclean: + $(RM) $(PROGS) + +depend: + makedepend -- $(DEPEND_SWITCHES) -- $(SRCS) + +evread.o: evread.c + $(CC) -c $(CC_SWITCHES) evread.c + +# DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/faq/faq.html b/faq/faq.html new file mode 100644 index 0000000..d89d723 --- /dev/null +++ b/faq/faq.html @@ -0,0 +1,49 @@ +Funtools FAQ + +

+Welcome to the Funtools FAQ +

+The primary home page for this FAQ is +http://hea-www.harvard.edu/saord/funtools/faq/faq.html. + +

    + +
  1. Retrieving and Installing Funtools +
      +
    1. Where can I get funtools? +
    2. How do I build funtools? +
    3. What secondary build options might be useful? +
    + +
  2. Programming with Funtools +
      +
    1. What are the compile/link commands for various platforms? +
    2. What is the simplest possible program? +
    3. Working with Binary Tables (Event Files) +
        +
      1. How do I read and display events? +
      2. How do I change the values of a single column for all events? +
      3. How do I process events based on the region each is in? +
      4. How do I make a FITS event file from a non-FITS source (and add my own params)? +
      +
    4. Working with Images +
        +
      1. How do I process an image in double float format? +
      2. How do I process an image in its native format? +
      +
    + +
  3. Funtools Analysis Programs +
      +
    1. What programs are available and what do they do? +
    + +
  4. Using Filters and Regions +
      +
    1. Please show how to use column and regions filters +
    + +
+ + + diff --git a/faq/faq1.html b/faq/faq1.html new file mode 100644 index 0000000..d4f1fd8 --- /dev/null +++ b/faq/faq1.html @@ -0,0 +1,39 @@ +Funtools FAQ: Installing + +
    + +
  1. Where can I get funtools?

    +Funtools is available at: +http://hea-www.harvard.edu/saord/funtools. + +

  2. How do I build funtools?

    +

    +

    +
    +./configure --prefix="install_root"	# site-specific configuration
    +make			                # build the software
    +make install		                # install it
    +make clean		                # clean up unneeded temp files
    +
    +
    + +
  3. What secondary build options might be useful? +

    +

    +
    +# specify root dir to install funtools executables, libraries, man pages, etc.
    +# default is to install in /usr/local
    +configure --prefix="install_root"
    +
    +# create funtools as a shared library
    +configure --enable-shared=yes
    +
    +# create funtools as a shared library and use it to link funtools itself
    +configure --enable-shared=link
    +
    +# gcc: enable support for files larger than 2 Gb
    +configure CFLAGS="-D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64"
    +
    +
    + +
diff --git a/faq/faq2.html b/faq/faq2.html new file mode 100644 index 0000000..f5b424b --- /dev/null +++ b/faq/faq2.html @@ -0,0 +1,381 @@ +Funtools FAQ: Programming + +
    +
  1. What are the compile/link commands for various platforms? +

    +Assuming, for example, that funtools is installed in /soft/saord and that +gcc is the compiler being used: +

      +
    1. Linux: +
      +
      +gcc -g -I/soft/saord/include -c -o foo.o foo.c
      +gcc -g foo.o -o foo -L/soft/saord/lib -lfuntools -ldl -lm
      +
      +
      +
    2. Apple OS X: +
      +
      +gcc -g -no-cpp-precomp -fno-common -I/soft/saord/include -c -o foo.o foo.c
      +gcc -g foo.o -o foo -L/soft/saord/lib -lfuntools -lm
      +
      +
      +
    3. Sun Solaris: +
      +
      +gcc -g -no-cpp-precomp -fno-common -I/soft/saord/include -c -o foo.o foo.c
      +gcc -g foo.o -o foo -L/soft/saord/lib -lfuntools -lsocket -lnsl -ldl -lm
      +
      +
      + +
    + +
  2. What is the simplest possible program? +

    +

    +
    +#include <stdlib.h>
    +#include <funtools.h>
    +
    +int main(int argc, char **argv)
    +{
    +  Fun fun;
    +
    +  /* sanity check */
    +  if( argc < 2 ) return 1;
    +  /* open file for reading */
    +  if( !(fun=FunOpen(argv[1], "r", NULL)) ){
    +    fprintf(stderr, "ERROR: can't open funtools file: %s\n", argv[1]);
    +    return 1;
    +  }
    +  /* close file */
    +  FunClose(fun);
    +  return 0;
    +}
    +
    +
    + +
  3. How do I read and display events? +

    +

    +
    #
    +#include <stdlib.h>
    +#include <funtools.h>
    +
    +typedef struct evstruct{
    +  double x, y;
    +  int pi, pha;
    +} *Ev, EvRec;
    +
    +int main(int argc, char **argv)
    +{
    +  int i, got;
    +  int maxrow=1024;
    +  Ev ev, ebuf=NULL;
    +  Fun fun;
    +
    +  /* sanity check */
    +  if( argc < 2 ) return 1;
    +  /* open file for reading */
    +  if( !(fun=FunOpen(argv[1], "r", NULL)) ){
    +    fprintf(stderr, "ERROR: can't open funtools file: %s\n", argv[1]);
    +    return 1;
    +  }
    +  /* select columns to read (and data types to convert to) */
    +  got = FunColumnSelect(fun, sizeof(EvRec), NULL,
    +			"x",       "D", "r", FUN_OFFSET(Ev, x),
    +			"y",       "D", "r", FUN_OFFSET(Ev, y),
    +			"pha",     "J", "r", FUN_OFFSET(Ev, pha),
    +			"pi",      "J", "r", FUN_OFFSET(Ev, pi),
    +			NULL);
    +  /* read and process events */
    +  while( (ebuf=(void *)FunTableRowGet(fun, NULL, maxrow, NULL, &got)) && got ){
    +    for(i=0; i<got; i++){
    +      ev = (Ev)ebuf+i;
    +      fprintf(stdout, "%.1f %.1f %d %d\n", ev->x, ev->y, ev->pha, ev->pi);
    +    }
    +    if( ebuf) free(ebuf);
    +  }
    +  /* close file */
    +  FunClose(fun);
    +  return 0;
    +}
    +
    +
    + +
  4. How do I change the value of a single column in all events? +

    +

    +
    +#include <stdlib.h>
    +#include <funtools.h>
    +
    +typedef struct evstruct{
    +  int pi;
    +} *Ev, EvRec;
    +
    +int main(int argc, char **argv)
    +{
    +  int i, got;
    +  int maxrow=1024;
    +  Ev ev, ebuf=NULL;
    +  Fun fun, ofun;
    +
    +  /* sanity check */
    +  if( argc < 3 ) return 1;
    +  /* open file for reading */
    +  if( !(fun=FunOpen(argv[1], "r", NULL)) ){
    +    fprintf(stderr, "ERROR: can't open input funtools file: %s\n", argv[1]);
    +    return 1;
    +  }
    +  /* open output file and inherit header params, columns, etc. from input */
    +  if( !(ofun=FunOpen(argv[2], "w", fun)) ){
    +    fprintf(stderr, "ERROR: can't open output funtools file: %s\n", argv[2]);
    +    return 1;
    +  }
    +  /* select columns to read (and data types to convert to) */
    +  /* use "merge=update" to change value while keeping original data type */
    +  /* use "merge=replace" to change boh the value and data type */
    +  got = FunColumnSelect(fun, sizeof(EvRec), "merge=update",
    +			"pi",     "J", "rw", FUN_OFFSET(Ev, pi),
    +			NULL);
    +  /* read and process events */
    +  while( (ebuf=(void *)FunTableRowGet(fun, NULL, maxrow, NULL, &got)) && got ){
    +    for(i=0; i<got; i++){
    +      ev = (Ev)ebuf+i;
    +      ev->pi = ev->pi + 1;
    +    }
    +    /* write rows to output file */
    +    if( FunTableRowPut(ofun, ebuf, got, 0, NULL) != got ){
    +      fprintf(stderr, "ERROR: writing to funtools file: %s\n", argv[2]);
    +      return 1;
    +    }
    +    if( ebuf) free(ebuf);
    +  }
    +  /* close files */
    +  FunClose(ofun);
    +  FunClose(fun);
    +  return 0;
    +}
    +
    +
    + +
  5. How do I process events based on the region each is in? +

    +

    +
    +#include <stdlib.h>
    +#include <funtools.h>
    +
    +typedef struct evstruct{
    +  int x, y;
    +  int pi, pha;
    +  int region;
    +} *Ev, EvRec;
    +
    +int main(int argc, char **argv)
    +{
    +  int i, got;
    +  int maxrow=1024;
    +  Ev ev, ebuf=NULL;
    +  Fun fun;
    +
    +  /* sanity check */
    +  if( argc < 2 ) return 1;
    +  /* open file for reading */
    +  if( !(fun=FunOpen(argv[1], "r", NULL)) ){
    +    fprintf(stderr, "ERROR: can't open funtools file: %s\n", argv[1]);
    +    return 1;
    +  }
    +  /* select columns to read (and data types to convert to) */
    +  /* specifying $REGION will retrieve the one-indexed region number */
    +  /* events passing the filter but not in a region will have value -1 */
    +  got = FunColumnSelect(fun, sizeof(EvRec), NULL,
    +			"x",       "J", "r", FUN_OFFSET(Ev, x),
    +			"y",       "J", "r", FUN_OFFSET(Ev, y),
    +			"pha",     "J", "r", FUN_OFFSET(Ev, pha),
    +			"pi",      "J", "r", FUN_OFFSET(Ev, pi),
    +			"$REGION", "J", "r", FUN_OFFSET(Ev, region),
    +			NULL);
    +  /* read and process events */
    +  while( (ebuf=(void *)FunTableRowGet(fun, NULL, maxrow, NULL, &got)) && got ){
    +    for(i=0; i<got; i++){
    +      ev = (Ev)ebuf+i;
    +      fprintf(stdout, "%4d %4d %3d %3d %4d\n", 
    +	      ev->x, ev->y, ev->pha, ev->pi, ev->region);
    +    }
    +    if( ebuf) free(ebuf);
    +  }
    +  /* close file */
    +  FunClose(fun);
    +  return 0;
    +}
    +
    +
    + +
  6. How do I make a FITS event file from a non-FITS source (and add my own params)? +

    +

    +
    +#include <stdlib.h>
    +#include <funtools.h>
    +
    +typedef struct evstruct{
    +  int x, y;
    +  int pha;
    +  float pi;
    +} *Ev, EvRec;
    +
    +int main(int argc, char **argv)
    +{
    +  int i, nev;
    +  int pmod=16, put=1;
    +  double pinc=0.1234;
    +  char xbuf[32], ybuf[32];
    +  Ev ev;
    +  Fun ofun;
    +
    +  /* sanity check */
    +  if( argc < 3 ) return 1;
    +  /* open new file for writing */
    +  if( !(ofun=FunOpen(argv[1], "w", NULL)) ){
    +    fprintf(stderr, "ERROR: can't open funtools file: %s\n", argv[1]);
    +    return 1;
    +  }
    +  if( (nev = atoi(argv[2])) <=0 ) return 1;
    +  ev = (Ev)calloc(1, sizeof(EvRec));
    +  /* The pair of numeric values specify the data value range, used to bin
    +     x, y into an image. They are permitted but not needed for pi and pha */
    +  sprintf(xbuf, "J:1:%d", nev);
    +  sprintf(ybuf, "J:1:%d", nev);
    +  /* select columns to write */
    +  FunColumnSelect(ofun, sizeof(EvRec), NULL,
    +		  "x",   xbuf,      "w", FUN_OFFSET(Ev, x),
    +		  "y",   ybuf,      "w", FUN_OFFSET(Ev, y),
    +		  "pha", "J:1:16",  "w", FUN_OFFSET(Ev, pha),
    +		  "pi",  "E",       "w", FUN_OFFSET(Ev, pi),
    +		  NULL);
    +  /* write params to header; generally added before first event is written */
    +  FunParamPuti(ofun, "PMOD",  0, pmod,  "modulus for pha generation", 1);
    +  FunParamPutd(ofun, "PINC",  0, pinc,  7, "increment for pi generation", 1);
    +  /* make up events */
    +  for(i=1; i<=nev; i++){
    +    ev->x = i; ev->y = nev-i+1; ev->pha = i % pmod; ev->pi = ev->pha + pinc;
    +    /* write rows to output file -- this can be done in batches, of course */
    +    if( FunTableRowPut(ofun, ev, put, 0, NULL) != put ){
    +      fprintf(stderr, "ERROR: writing to funtools file: %s\n", argv[1]);
    +      return 1;
    +    }
    +  }
    +  if( ev) free(ev);
    +  /* close file */
    +  FunClose(ofun);
    +  return 0;
    +}
    +
    +
    + +
  7. How do I process an image in double float format? +

    +

    +
    +#include <stdlib.h>
    +#include <funtools.h>
    +
    +int main(int argc, char **argv)
    +{
    +  int i, j, dim1, dim2;
    +  double *buf;
    +  Fun fun;
    +
    +  /* sanity check */
    +  if( argc < 2 ) return 1;
    +  /* open file for reading */
    +  if( !(fun=FunOpen(argv[1], "r", NULL)) ){
    +    fprintf(stderr, "ERROR: can't open funtools file: %s\n", argv[1]);
    +    return 1;
    +  }
    +  /* extract (and bin, if necessary) data into a double prec. image buffer */
    +  if( !(buf = FunImageGet(fun, NULL, "bitpix=-64")) ){
    +    fprintf(stderr, "ERROR: can't get image: %s\n", argv[1]);
    +    return 1;
    +  }
    +  /* get image dimensions after FunImageGet, in case an image section
    +     was specified on the command line, which changes image dimensions */
    +  FunInfoGet(fun, FUN_SECT_DIM1, &dim1, FUN_SECT_DIM2, &dim2, 0);
    +  /* loop through image */
    +  for(i=0; i<dim2; i++){
    +    for(j=0; j<dim1; j++){
    +      fprintf(stdout, "%.1f ", buf[i*dim1+j]);
    +    }
    +    fprintf(stdout, "\n");
    +  }
    +  /* close file */
    +  FunClose(fun);
    +  return 0;
    +}
    +
    +
    + +
  8. How do I process an image in its native format? +
    +
    +#include <funtools.h>
    +
    +int main(int argc, char **argv)
    +{
    +  int i, j, bitpix, dim1, dim2;
    +  double *buf;
    +  unsigned char *cbuf;
    +  short *sbuf;
    +  int *ibuf;
    +  float *fbuf;
    +  double *dbuf;
    +  Fun fun;
    +
    +  /* sanity check */
    +  if( argc < 2 ) return 1;
    +  /* open file for reading */
    +  if( !(fun=FunOpen(argv[1], "r", NULL)) ){
    +    fprintf(stderr, "ERROR: can't open funtools file: %s\n", argv[1]);
    +    return 1;
    +  }
    +  /* extract (and bin, if necessary) data into a buffer whose
    +     data type is not specified and therefore is that of the file */
    +  if( !(buf = FunImageGet(fun, NULL, NULL)) ){
    +    fprintf(stderr, "ERROR: can't get image: %s\n", argv[1]);
    +    return 1;
    +  }
    +  /* get image dimensions after FunImageGet, in case an image section
    +     was specified on the command line, which changes image dimensions */
    +  FunInfoGet(fun, FUN_SECT_BITPIX, &bitpix, 
    +	     FUN_SECT_DIM1, &dim1, FUN_SECT_DIM2, &dim2, 0);
    +  /* set appropriate data type buffer to point to image buffer */
    +  switch(bitpix){
    +    case 8:   cbuf = (unsigned char *)buf; break;
    +    case 16:  sbuf = (short *)buf;         break;
    +    case 32:  ibuf = (int *)buf;           break;
    +    case -32: fbuf = (float *)buf;         break;
    +    case -64: dbuf = (double *)buf;        break;
    +  }
    +  /* loop through image */
    +  for(i=0; i<dim2; i++){
    +    for(j=0; j<dim1; j++){
    +      switch(bitpix){
    +        case 8:   fprintf(stdout, "%4d ",  cbuf[i*dim1+j]);  break;
    +        case 16:  fprintf(stdout, "%6d ",  sbuf[i*dim1+j]);  break;
    +        case 32:  fprintf(stdout, "%9d ",  ibuf[i*dim1+j]);  break;
    +        case -32: fprintf(stdout, "%.2f ", fbuf[i*dim1+j]);  break;
    +        case -64: fprintf(stdout, "%.6f ", dbuf[i*dim1+j]);  break;
    +      }
    +    }
    +    fprintf(stdout, "\n");
    +  }
    +  /* close file */
    +  FunClose(fun);
    +  return 0;
    +}
    +
    +
    + +
diff --git a/faq/faq3.html b/faq/faq3.html new file mode 100644 index 0000000..e55a4d0 --- /dev/null +++ b/faq/faq3.html @@ -0,0 +1,23 @@ +Funtools FAQ: Programs + +
    +
  1. What programs are available and what do they do? +

    +

      +
    1. funcalc: funtools calculator (for binary tables) +
    2. funcen: find centroid (for binary tables) +
    3. funcnts: count photons in specified regions with background subtraction +
    4. funcone: cone search on RA, Dec columns +
    5. fundisp: display data in a funtools data file +
    6. funhead: display a header in a funtools file +
    7. funhist: create a 1D histogram of a column +
    8. funimage: create a FITS image from a funtools data file +
    9. funindex: create a index on a column in a binary table +
    10. funjoin: join two or more FITS binary tables on specified columns +
    11. funmerge: merge one or more funtools table files +
    12. funsky: convert between image and sky coodinates, using WCS info from a FITS header +
    13. funtable: copy selected rows from a funtools file to a FITS binary table +
    14. funtbl: extract a table (obsolete) +
    + +
diff --git a/faq/faq4.html b/faq/faq4.html new file mode 100644 index 0000000..7e384a7 --- /dev/null +++ b/faq/faq4.html @@ -0,0 +1,211 @@ +Funtools FAQ: Filtering +

+NB: column filters work on tables only. Regions work on tables and images. + +

+

    +
  1. Please show how to use column and regions filters + +

    +

      +
    1. Filter events through a circular region using physical pixels +
      +
      +fundisp foo.fits'[circle(512,512,.5)]'
      + 
      +   X    Y PHA  PI                  TIME   DX   DY
      +---- ---- --- --- --------------------- ---- ----
      + 512  512   6   7     79493997.45854475  578  574
      + 512  512   8   9     79494575.58943175  579  573
      + 512  512   5   6     79493631.03866175  578  575
      + 512  512   5   5     79493290.86521725  578  575
      + 512  512   8   9     79493432.00990875  579  573
      +
      +
      + +
    2. Filter events through a circular region, for a single value of pha +
      +
      +fundisp foo.fits'[circle 512 512 .5 && pha==5]'
      + 
      +   X    Y PHA  PI                  TIME   DX   DY
      +---- ---- --- --- --------------------- ---- ----
      + 512  512   5   6     79493631.03866175  578  575
      + 512  512   5   5     79493290.86521725  578  575
      +
      +
      + +
    3. Filter events through a circular region, including a range of pha values +
      +
      +fundisp foo.fits'[circle(512,512,.5)&&pha=5:6]'
      + 
      +   X    Y PHA  PI                  TIME   DX   DY
      +---- ---- --- --- --------------------- ---- ----
      + 512  512   6   7     79493997.45854475  578  574
      + 512  512   5   6     79493631.03866175  578  575
      + 512  512   5   5     79493290.86521725  578  575
      +
      +
      + +
    4. Filter events through a circular region, excluding a range of pha values +
      +
      +fundisp foo.fits'[circle(512,512,.5)&&\!pha=5:6]'
      + 
      +   X    Y PHA  PI                  TIME   DX   DY
      +---- ---- --- --- --------------------- ---- ----
      + 512  512   8   9     79494575.58943175  579  573
      + 512  512   8   9     79493432.00990875  579  573
      +
      +
      + +
    5. Filter events through two circular regions +
      +
      +fundisp foo.fits'[circle(512,512,.5); circle 500 500 .1]'
      + 
      +   X    Y PHA  PI                  TIME   DX   DY
      +---- ---- --- --- --------------------- ---- ----
      + 500  500   5   5     79493733.05197725  600  577
      + 500  500   9   9     79488217.13936825  600  576
      + 500  500   2   2     79487590.99904275  599  581
      + 512  512   6   7     79493997.45854475  578  574
      + 512  512   8   9     79494575.58943175  579  573
      + 512  512   5   6     79493631.03866175  578  575
      + 512  512   5   5     79493290.86521725  578  575
      + 512  512   8   9     79493432.00990875  579  573
      +
      +
      + +
    6. Filter events through a circular region, selecting a single time value +
      +
      +fundisp foo.fits'[circle(512,512,.5)&&time==79493631.03866175]'
      + 
      +   X    Y PHA  PI                  TIME   DX   DY
      +---- ---- --- --- --------------------- ---- ----
      + 512  512   5   6     79493631.03866175  578  575
      +
      +
      + +
    7. Filter events through a circular region, selecting a single time value +(but using feq to avoid possible precision problems) +
      +
      +fundisp foo.fits'[circle(512,512,.5)&&feq(time,79493631.03866175)]'
      + 
      +   X    Y PHA  PI                  TIME   DX   DY
      +---- ---- --- --- --------------------- ---- ----
      + 512  512   5   6     79493631.03866175  578  575
      +
      +
      + +
    8. Filter events through a circular region, while excluding an inner circle +
      +
      +fundisp foo.fits'[circle(512,512,1);-cir 512 512 .5]'
      + 
      +   X    Y PHA  PI                  TIME   DX   DY
      +---- ---- --- --- --------------------- ---- ----
      + 512  511   9   9     79492909.11908525  580  572
      + 512  511   6   7     79492607.35239075  580  573
      + 512  511   6   7     79493574.08603576  580  573
      + 512  511   7   8     79488537.75487424  579  572
      + 511  512   5   5     79488781.64644176  579  576
      + 511  512   5   6     79492586.05470325  579  576
      + 511  512  10  10     79494397.55842775  580  574
      + 511  512   1   2     79493697.87522624  577  582
      + 511  512   6   7     79493997.75123225  579  575
      + 511  512  10  11     79487417.67703976  579  574
      + 513  512   6   6     79493306.47509325  578  573
      + 513  512   8   8     79487909.39373726  578  572
      + 512  513   4   4     79487403.52010125  576  577
      + 512  513   8   9     79492536.31151475  577  574
      + 512  513  10  10     79492589.71195325  578  574
      + 512  513   5   5     79488335.19512025  576  575
      + 512  513   8   8     79493661.25728776  578  574
      + 512  513   8   9     79487914.98186225  577  574
      + 512  513   5   5     79487392.91247626  577  576
      + 512  513   4   4     79492808.24789475  577  576
      + 512  513   7   8     79493236.90765475  577  574
      + 512  513   6   7     79493667.65710025  578  574
      +
      +
      + +
    9. Filter events through a circular region for a range of pha, while excluding an inner circle +
      +
      +fundisp foo.fits'[circle(512,512,1)&&pha=6:7;-cir 512 512 .5]'
      + 
      +   X    Y PHA  PI                  TIME   DX   DY
      +---- ---- --- --- --------------------- ---- ----
      + 512  511   6   7     79492607.35239075  580  573
      + 512  511   6   7     79493574.08603576  580  573
      + 512  511   7   8     79488537.75487424  579  572
      + 511  512   6   7     79493997.75123225  579  575
      + 513  512   6   6     79493306.47509325  578  573
      + 512  513   7   8     79493236.90765475  577  574
      + 512  513   6   7     79493667.65710025  578  574
      +
      +
      + +
    10. Filter events through a circular region for ranges of pha and pi, while excluding an inner circle +
      +
      +fundisp foo.fits'[circle(512,512,1)&&pha=5:7 && pi=6:8;-cir 512 512 .5]'
      + 
      +   X    Y PHA  PI                  TIME   DX   DY
      +---- ---- --- --- --------------------- ---- ----
      + 512  511   6   7     79492607.35239075  580  573
      + 512  511   6   7     79493574.08603576  580  573
      + 512  511   7   8     79488537.75487424  579  572
      + 511  512   5   6     79492586.05470325  579  576
      + 511  512   6   7     79493997.75123225  579  575
      + 513  512   6   6     79493306.47509325  578  573
      + 512  513   7   8     79493236.90765475  577  574
      + 512  513   6   7     79493667.65710025  578  574
      +
      +
      + +
    11. Filter events through a circular region in fk5 coords (degrees) +
      +
      +fundisp foo.fits'[fk5;circle(345.25391,58.879774,3.9999997")]'
      + 
      +   X    Y PHA  PI                  TIME   DX   DY
      +---- ---- --- --- --------------------- ---- ----
      + 512  512   6   7     79493997.45854475  578  574
      + 512  512   8   9     79494575.58943175  579  573
      + 512  512   5   6     79493631.03866175  578  575
      + 512  512   5   5     79493290.86521725  578  575
      + 512  512   8   9     79493432.00990875  579  573
      +
      +
      + +
    12. Filter events through a circular region retrieved from ds9 +
      +
      +cat foo.reg
      +# Region file format: DS9 version 4.0
      +# Filename: foo.fits'[EVENTS]'
      +global color=green font="helvetica 10 normal" select=1 highlite=1 edit=1 move=1 delete=1 include=1 fixed=0 source
      +fk5
      +circle(345.25391,58.879774,3.9999997")
      +
      +fundisp foo.fits'[@foo.reg]'
      + 
      +   X    Y PHA  PI                  TIME   DX   DY
      +---- ---- --- --- --------------------- ---- ----
      + 512  512   6   7     79493997.45854475  578  574
      + 512  512   8   9     79494575.58943175  579  573
      + 512  512   5   6     79493631.03866175  578  575
      + 512  512   5   5     79493290.86521725  578  575
      + 512  512   8   9     79493432.00990875  579  573
      +
      +
      +
      + +
    + +
diff --git a/faq/tdisp b/faq/tdisp new file mode 100755 index 0000000..e2ee633 --- /dev/null +++ b/faq/tdisp @@ -0,0 +1,15 @@ +#!/bin/sh + +if [ ! -r foo.fits ]; then + ln -s $HOME/data/snr.ev foo.fits +fi + +FUN_FORMAT='x=%4d y=%4d pha=%3d pi=%3d dx=%4d dy=%4d' +export FUN_FORMAT + +echo fundisp foo.fits"'[$1]'" | tee foo.log +echo " " | tee -a foo.log +../fundisp foo.fits"[$1]" | tee -a foo.log + + + diff --git a/faq/tev.c b/faq/tev.c new file mode 100644 index 0000000..9f9cf59 --- /dev/null +++ b/faq/tev.c @@ -0,0 +1,56 @@ +#include +#include + +typedef struct evstruct{ + int x, y; + int pha; + float pi; + int region; +} *Ev, EvRec; + +int main(int argc, char **argv) +{ + int i, nev; + int pmod=16, put=1; + double pinc=0.1234; + char xbuf[32], ybuf[32]; + Ev ev; + Fun ofun; + + /* sanity check */ + if( argc < 3 ) return 1; + /* open new file for writing */ + if( !(ofun=FunOpen(argv[1], "w", NULL)) ){ + fprintf(stderr, "ERROR: can't open funtools file: %s\n", argv[1]); + return 1; + } + if( (nev = atoi(argv[2])) <=0 ) return 1; + ev = (Ev)calloc(1, sizeof(EvRec)); + /* The pair of numeric values specify the data value range, used to bin + x, y into an image. They are permitted but not needed for pi and pha */ + sprintf(xbuf, "J:1:%d", nev); + sprintf(ybuf, "J:1:%d", nev); + /* select columns to write */ + FunColumnSelect(ofun, sizeof(EvRec), NULL, + "x", xbuf, "w", FUN_OFFSET(Ev, x), + "y", ybuf, "w", FUN_OFFSET(Ev, y), + "pha", "J:1:16", "w", FUN_OFFSET(Ev, pha), + "pi", "E", "w", FUN_OFFSET(Ev, pi), + NULL); + /* write params to header; generally added before first event is written */ + FunParamPuti(ofun, "PMOD", 0, pmod, "modulus for pha generation", 1); + FunParamPutd(ofun, "PINC", 0, pinc, 7, "increment for pi generation", 1); + /* make up events */ + for(i=1; i<=nev; i++){ + ev->x = i; ev->y = nev-i+1; ev->pha = i % pmod; ev->pi = ev->pha + pinc; + /* write rows to output file -- this can be done in batches, of course */ + if( FunTableRowPut(ofun, ev, put, 0, NULL) != put ){ + fprintf(stderr, "ERROR: writing to funtools file: %s\n", argv[1]); + return 1; + } + } + if( ev) free(ev); + /* close file */ + FunClose(ofun); + return 0; +} diff --git a/faq/tfaq.c b/faq/tfaq.c new file mode 100644 index 0000000..8913f44 --- /dev/null +++ b/faq/tfaq.c @@ -0,0 +1,41 @@ +#include + +typedef struct evstruct{ + int pi; +} *Ev, EvRec; + +int main(int argc, char **argv) +{ + int i, got; + int maxrow=1024; + Ev ev, ebuf=NULL; + Fun fun, ofun; + /* open file for reading */ + if( !(fun=FunOpen(argv[1], "r", NULL)) ){ + fprintf(stderr, "ERROR: can't open input funtools file: %s\n", argv[1]); + return 1; + } + if( !(ofun=FunOpen(argv[2], "w", fun)) ){ + fprintf(stderr, "ERROR: can't open output funtools file: %s\n", argv[2]); + return 1; + } + /* select columns to read (and data types to convert to) */ + got = FunColumnSelect(fun, sizeof(EvRec), "merge=update", + "pi", "J", "rw", FUN_OFFSET(Ev, pi), + NULL); + /* read and process events */ + while(ebuf=(void *)FunTableRowGet(fun, NULL, maxrow, NULL, &got) ){ + for(i=0; ipi = ev->pi + 1; + } + if( FunTableRowPut(ofun, ebuf, got, 0, NULL) != got ){ + fprintf(stderr, "ERROR: writing to funtools file: %s\n", argv[2]); + return 1; + } + if( ebuf) free(ebuf); + } + /* close files */ + FunClose(ofun); + FunClose(fun); +} diff --git a/faq/tim.c b/faq/tim.c new file mode 100644 index 0000000..5b0aa98 --- /dev/null +++ b/faq/tim.c @@ -0,0 +1,55 @@ +#include + +int main(int argc, char **argv) +{ + int i, j, bitpix, dim1, dim2; + double *buf; + unsigned char *cbuf; + short *sbuf; + int *ibuf; + float *fbuf; + double *dbuf; + Fun fun; + + /* sanity check */ + if( argc < 2 ) return 1; + /* open file for reading */ + if( !(fun=FunOpen(argv[1], "r", NULL)) ){ + fprintf(stderr, "ERROR: can't open funtools file: %s\n", argv[1]); + return 1; + } + /* extract (and bin, if necessary) data into a double prec. image buffer */ + /* data type is not specified and therefore is that of the file */ + if( !(buf = FunImageGet(fun, NULL, NULL)) ){ + fprintf(stderr, "ERROR: can't get image: %s\n", argv[1]); + return 1; + } + /* get image dimensions after FunImageGet, in case an image section + was specified on the command line, which changes image dimensions */ + FunInfoGet(fun, FUN_SECT_BITPIX, &bitpix, + FUN_SECT_DIM1, &dim1, FUN_SECT_DIM2, &dim2, 0); + /* set appropriate data type buffer to point to image buffer */ + switch(bitpix){ + case 8: cbuf = (unsigned char *)buf; break; + case 16: sbuf = (short *)buf; break; + case 32: ibuf = (int *)buf; break; + case -32: fbuf = (float *)buf; break; + case -64: dbuf = (double *)buf; break; + } + /* loop through image */ + for(i=0; i regions_h.h + +xalloc_c.h: ../util/xalloc.c inc.sed + $(RM) xalloc_c.h + ./inc.sed XALLOC_C < ../util/xalloc.c > xalloc_c.h + +swap_c.h: swap.c inc.sed + $(RM) swap_c.h + ./inc.sed SWAP_C < swap.c > swap_c.h + +events_c.h: evfilter.c inc.sed + $(RM) events_c.h + ./inc.sed EVENTS_C < evfilter.c > events_c.h + +image_c.h: imfilter.c inc.sed + $(RM) image_c.h + ./inc.sed IMAGE_C < imfilter.c > image_c.h + +evregions.c: evregions_c.tmpl Makefile + $(RM) evregions.c + sed 's/_FPUDBL_/$(FPU_DOUBLE)/' < evregions_c.tmpl > evregions.c + +imregions.c: imregions_c.tmpl Makefile + $(RM) imregions.c + sed 's/_FPUDBL_/$(FPU_DOUBLE)/' < imregions_c.tmpl > imregions.c + +evregions_c.h: evregions.c inc.sed + $(RM) evregions_c.h + ./inc.sed EVREGIONS_C < evregions.c > evregions_c.h + +imregions_c.h: imregions.c inc.sed + $(RM) imregions_c.h + ./inc.sed IMREGIONS_C < imregions.c > imregions_c.h + +headers: regions_h.h xalloc_c.h swap_c.h \ + events_c.h image_c.h evregions_c.h imregions_c.h + +# remake the parser +LEX = flex -i +parser: filt.l + @($(LEX) -Pfilt filt.l; \ + sed "s/yytext_ptr/filttext_ptr/g" < lex.filt.c > nlex.filt.c; \ + mv nlex.filt.c lex.filt.c) + +iparser: idx.l + @($(LEX) -Pidx idx.l; \ + sed "s/yytext_ptr/idxtext_ptr/g" < lex.idx.c > nlex.idx.c; \ + mv nlex.idx.c lex.idx.c) + +YACC = bison -d -v +igrammar: idx.y + $(YACC) -p idx idx.y + +pure: tfilt.pure + +tfilt.pure: $(FILDLIB) tfilt.o + purify $(CC) $(LDFLAGS) tfilt.o -o tfilt.pure \ + $(LIB) $(LIBS) + +# DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/filter/ZHTODO b/filter/ZHTODO new file mode 100644 index 0000000..6dce830 --- /dev/null +++ b/filter/ZHTODO @@ -0,0 +1,4 @@ +1. segments should be full statements +2. reverse order of segments +3. excludes are not moved to the end +4. allow specification of region id diff --git a/filter/ac_c_long_long.m4 b/filter/ac_c_long_long.m4 new file mode 100644 index 0000000..fb6df1e --- /dev/null +++ b/filter/ac_c_long_long.m4 @@ -0,0 +1,36 @@ +##### http://autoconf-archive.cryp.to/ac_c_long_long.html +# +# SYNOPSIS +# +# AC_C_LONG_LONG +# +# DESCRIPTION +# +# Provides a test for the existance of the long long int type and +# defines HAVE_LONG_LONG if it is found. +# +# LAST MODIFICATION +# +# 2006-10-30 +# +# COPYLEFT +# +# Copyright (c) 2006 Caolan McNamara +# +# Copying and distribution of this file, with or without +# modification, are permitted in any medium without royalty provided +# the copyright notice and this notice are preserved. + +AC_DEFUN([AC_C_LONG_LONG], +[AC_CACHE_CHECK(for long long int, ac_cv_c_long_long, +[if test "$GCC" = yes; then + ac_cv_c_long_long=yes + else + AC_TRY_COMPILE(,[long long int i;], + ac_cv_c_long_long=yes, + ac_cv_c_long_long=no) + fi]) + if test $ac_cv_c_long_long = yes; then + AC_DEFINE(HAVE_LONG_LONG, 1, [compiler understands long long]) + fi +]) diff --git a/filter/aclocal.m4 b/filter/aclocal.m4 new file mode 100644 index 0000000..65f68be --- /dev/null +++ b/filter/aclocal.m4 @@ -0,0 +1 @@ +builtin(include,ac_c_long_long.m4) diff --git a/filter/addld b/filter/addld new file mode 100644 index 0000000..5591871 --- /dev/null +++ b/filter/addld @@ -0,0 +1 @@ +setenv LD_LIBRARY_PATH "..:${LD_LIBRARY_PATH}" diff --git a/filter/column.c b/filter/column.c new file mode 100644 index 0000000..a1ad027 --- /dev/null +++ b/filter/column.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 1999-2003 Smithsonian Astrophysical Observatory + */ +#include + +#ifdef ANSI_FUNC +void +ColumnLoad(char *ibuf, int size, int n, int convert, void *obuf) +#else +void ColumnLoad(ibuf, size, n, convert, obuf) + char *ibuf; + int size; + int n; + int convert; + void *obuf; +#endif +{ + register char *iptr; + register char *optr; + int i, j; + + if( convert ){ + optr = (char *)obuf; + iptr = (char *)ibuf; + for(i=0; i=0; j--){ + *optr++ = *(iptr+j); + } + iptr += size; + } + } + else{ + memcpy(obuf, ibuf, n*size); + } +} + diff --git a/filter/column.h b/filter/column.h new file mode 100644 index 0000000..ffe9b0f --- /dev/null +++ b/filter/column.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 1999-2003 Smithsonian Astrophysical Observatory + */ + +/* + * + * column.h -- declarations for column processing + * + */ + +#ifndef __column_h +#define __column_h + +#if HAVE_CONFIG_H +#include "conf.h" +#endif + +#ifdef HAVE_STRING_H +#include +#endif + +#include "prsetup.h" +_PRbeg + +void ColumnLoad _PRx((char *ibuf, int size, int n, int convert, void *obuf)); + +_PRend + +#endif diff --git a/filter/compat/install-sh b/filter/compat/install-sh new file mode 100755 index 0000000..ab74c88 --- /dev/null +++ b/filter/compat/install-sh @@ -0,0 +1,238 @@ +#!/bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. +# + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +tranformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/filter/conf.h.in b/filter/conf.h.in new file mode 100644 index 0000000..12c728f --- /dev/null +++ b/filter/conf.h.in @@ -0,0 +1,62 @@ +/* Define as 1 if this compiler supports long long. */ +#undef HAVE_LONG_LONG + +/* Define as 1 if you have string.h */ +#undef HAVE_STRING_H + +/* Define as 1 if you have stdlib.h */ +#undef HAVE_STDLIB_H + +/* Define as 1 if you have malloc.h */ +#undef HAVE_MALLOC_H + +/* Define as 1 if you have unistd.h */ +#undef HAVE_UNISTD_H + +/* Define as 1 if you have getopt.h */ +#undef HAVE_GETOPT_H + +/* Define as 1 if you have values.h */ +#undef HAVE_VALUES_H + +/* Define as 1 if you have dlfcn.h */ +#undef HAVE_DLFCN_H + +/* Define as 1 if you have sys/un.h */ +#undef HAVE_SYS_UN_H + +/* Define as 1 if you have sys/shm.h */ +#undef HAVE_SYS_SHM_H + +/* Define as 1 if you have sys/mman.h */ +#undef HAVE_SYS_MMAN_H + +/* Define as 1 if you have sys/ipc.h */ +#undef HAVE_SYS_IPC_H + +/* Define as 1 if you have socklen_t */ +#undef HAVE_SOCKLEN_T + +/* Define as 1 if you have strchr */ +#undef HAVE_STRCHR + +/* Define as 1 if you have memcpy */ +#undef HAVE_MEMCPY + +/* Define as 1 if you have snprintf */ +#undef HAVE_SNPRINTF + +/* Define as 1 if you have Tcl */ +#undef HAVE_TCL + +/* Define as 1 if you have Xt */ +#undef HAVE_XT + +/* Define as 1 if you are running Cygwin. */ +#undef HAVE_CYGWIN + +/* Define as 1 if you are running MinGW. */ +#undef HAVE_MINGW32 + +/* Define if you have inline */ +#undef inline diff --git a/filter/config.guess b/filter/config.guess new file mode 100644 index 0000000..44290b8 --- /dev/null +++ b/filter/config.guess @@ -0,0 +1,1435 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright 1992-2015 Free Software Foundation, Inc. + +timestamp='2015-02-23' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). +# +# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. +# +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD +# +# Please send patches to . + + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright 1992-2015 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +case "${UNAME_SYSTEM}" in +Linux|GNU|GNU/*) + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + LIBC=gnu + + eval $set_cc_for_build + cat <<-EOF > $dummy.c + #include + #if defined(__UCLIBC__) + LIBC=uclibc + #elif defined(__dietlibc__) + LIBC=dietlibc + #else + LIBC=gnu + #endif + EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` + ;; +esac + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ + /sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || \ + echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + earmv*) + arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'` + endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'` + machine=${arch}${endian}-unknown + ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|earm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # Determine ABI tags. + case "${UNAME_MACHINE_ARCH}" in + earm*) + expr='s/^earmv[0-9]/-eabi/;s/eb$//' + abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"` + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}${abi}" + exit ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm*:riscos:*:*|arm*:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/lslpp ] ; then + IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | + awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`/usr/bin/uname -p` + case ${UNAME_PROCESSOR} in + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW64*:*) + echo ${UNAME_MACHINE}-pc-mingw64 + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + *:MSYS*:*) + echo ${UNAME_MACHINE}-pc-msys + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + aarch64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC="gnulibc1" ; fi + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + arc:Linux:*:* | arceb:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi + else + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + cris:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-${LIBC} + exit ;; + crisv32:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-${LIBC} + exit ;; + frv:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + hexagon:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + i*86:Linux:*:*) + echo ${UNAME_MACHINE}-pc-linux-${LIBC} + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } + ;; + openrisc*:Linux:*:*) + echo or1k-unknown-linux-${LIBC} + exit ;; + or32:Linux:*:* | or1k*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-${LIBC} + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-${LIBC} + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; + PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; + *) echo hppa-unknown-linux-${LIBC} ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-${LIBC} + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-${LIBC} + exit ;; + ppc64le:Linux:*:*) + echo powerpc64le-unknown-linux-${LIBC} + exit ;; + ppcle:Linux:*:*) + echo powerpcle-unknown-linux-${LIBC} + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux-${LIBC} + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + tile*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-${LIBC} + exit ;; + x86_64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configury will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + x86_64:Haiku:*:*) + echo x86_64-unknown-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + eval $set_cc_for_build + if test "$UNAME_PROCESSOR" = unknown ; then + UNAME_PROCESSOR=powerpc + fi + if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + fi + elif test "$UNAME_PROCESSOR" = i386 ; then + # Avoid executing cc on OS X 10.9, as it ships with a stub + # that puts up a graphical alert prompting to install + # developer tools. Any system running Mac OS X 10.7 or + # later (Darwin 11 and later) is required to have a 64-bit + # processor. This is not true of the ARM version of Darwin + # that Apple uses in portable devices. + UNAME_PROCESSOR=x86_64 + fi + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NEO-?:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk${UNAME_RELEASE} + exit ;; + NSE-*:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; + x86_64:VMkernel:*:*) + echo ${UNAME_MACHINE}-unknown-esx + exit ;; +esac + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/filter/config.sub b/filter/config.sub new file mode 100644 index 0000000..bc855a2 --- /dev/null +++ b/filter/config.sub @@ -0,0 +1,1807 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright 1992-2015 Free Software Foundation, Inc. + +timestamp='2015-02-22' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). + + +# Please send patches to . +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright 1992-2015 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ + linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + android-linux) + os=-linux-android + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray | -microblaze*) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*178) + os=-lynxos178 + ;; + -lynx*5) + os=-lynxos5 + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | aarch64 | aarch64_be \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arceb \ + | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ + | avr | avr32 \ + | be32 | be64 \ + | bfin \ + | c4x | c8051 | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | epiphany \ + | fido | fr30 | frv | ft32 \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | k1om \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa32r6 | mipsisa32r6el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64r6 | mipsisa64r6el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nios | nios2 | nios2eb | nios2el \ + | ns16k | ns32k \ + | open8 | or1k | or1knd | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pyramid \ + | riscv32 | riscv64 \ + | rl78 | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ + | visium \ + | we32k \ + | x86 | xc16x | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + leon|leon[3-9]) + basic_machine=sparc-$basic_machine + ;; + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + xgate) + basic_machine=$basic_machine-unknown + os=-none + ;; + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | aarch64-* | aarch64_be-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | be32-* | be64-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ + | c8051-* | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | hexagon-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | k1om-* \ + | le32-* | le64-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ + | microblaze-* | microblazeel-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa32r6-* | mipsisa32r6el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64r6-* | mipsisa64r6el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipsr5900-* | mipsr5900el-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ + | nios-* | nios2-* | nios2eb-* | nios2el-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ + | or1k*-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pyramid-* \ + | rl78-* | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ + | tahoe-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile*-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ + | visium-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16 | cr16-*) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + leon-*|leon[3-9]-*) + basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'` + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze*) + basic_machine=microblaze-xilinx + ;; + mingw64) + basic_machine=x86_64-pc + os=-mingw64 + ;; + mingw32) + basic_machine=i686-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + moxiebox) + basic_machine=moxie-unknown + os=-moxiebox + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + msys) + basic_machine=i686-pc + os=-msys + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc | ppcbe) basic_machine=powerpc-unknown + ;; + ppc-* | ppcbe-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos | rdos64) + basic_machine=x86_64-pc + os=-rdos + ;; + rdos32) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tile*) + basic_machine=$basic_machine-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + xscale-* | xscalee[bl]-*) + basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -auroraux) + os=-auroraux + ;; + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* | -plan9* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -bitrig* | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-musl* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -nacl*) + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + c8051-*) + os=-elf + ;; + hexagon-*) + os=-elf + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -cnk*|-aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/filter/configure-failsafe b/filter/configure-failsafe new file mode 100755 index 0000000..2017281 --- /dev/null +++ b/filter/configure-failsafe @@ -0,0 +1,6399 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.59 for filter 1.1. +# +# Report bugs to . +# +# Copyright (C) 2003 Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi +DUALCASE=1; export DUALCASE # for MKS sh + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +exec 6>&1 + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_config_libobj_dir=. +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Maximum number of lines to put in a shell here document. +# This variable seems obsolete. It should probably be removed, and +# only ac_max_sed_lines should be used. +: ${ac_max_here_lines=38} + +# Identity of this package. +PACKAGE_NAME='filter' +PACKAGE_TARNAME='filter' +PACKAGE_VERSION='1.1' +PACKAGE_STRING='filter 1.1' +PACKAGE_BUGREPORT='saord@cfa.harvard.edu' + +ac_unique_file="./filter.h" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#if HAVE_SYS_TYPES_H +# include +#endif +#if HAVE_SYS_STAT_H +# include +#endif +#if STDC_HEADERS +# include +# include +#else +# if HAVE_STDLIB_H +# include +# endif +#endif +#if HAVE_STRING_H +# if !STDC_HEADERS && HAVE_MEMORY_H +# include +# endif +# include +#endif +#if HAVE_STRINGS_H +# include +#endif +#if HAVE_INTTYPES_H +# include +#else +# if HAVE_STDINT_H +# include +# endif +#endif +#if HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT RANLIB ac_ct_RANLIB CPP EGREP FILTER_CC FILTER_CFLAGS LIB DEFLIB DOSHARED LLIB USE_FPU_DOUBLE USE_DL EXTRA_LIBS EXTRA_OBJS LIBOBJS LTLIBOBJS' +ac_subst_files='' + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +ac_prev= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_option in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + eval "enable_$ac_feature=no" ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "enable_$ac_feature='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package| sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "with_$ac_package='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/-/_/g'` + eval "with_$ac_package=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` + eval "$ac_envvar='$ac_optarg'" + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute paths. +for ac_var in exec_prefix prefix +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* | NONE | '' ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# Be sure to have absolute paths. +for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ + localstatedir libdir includedir oldincludedir infodir mandir +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_confdir=`(dirname "$0") 2>/dev/null || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 + { (exit 1); exit 1; }; } + else + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } + fi +fi +(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || + { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 + { (exit 1); exit 1; }; } +srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` +ac_env_build_alias_set=${build_alias+set} +ac_env_build_alias_value=$build_alias +ac_cv_env_build_alias_set=${build_alias+set} +ac_cv_env_build_alias_value=$build_alias +ac_env_host_alias_set=${host_alias+set} +ac_env_host_alias_value=$host_alias +ac_cv_env_host_alias_set=${host_alias+set} +ac_cv_env_host_alias_value=$host_alias +ac_env_target_alias_set=${target_alias+set} +ac_env_target_alias_value=$target_alias +ac_cv_env_target_alias_set=${target_alias+set} +ac_cv_env_target_alias_value=$target_alias +ac_env_CC_set=${CC+set} +ac_env_CC_value=$CC +ac_cv_env_CC_set=${CC+set} +ac_cv_env_CC_value=$CC +ac_env_CFLAGS_set=${CFLAGS+set} +ac_env_CFLAGS_value=$CFLAGS +ac_cv_env_CFLAGS_set=${CFLAGS+set} +ac_cv_env_CFLAGS_value=$CFLAGS +ac_env_LDFLAGS_set=${LDFLAGS+set} +ac_env_LDFLAGS_value=$LDFLAGS +ac_cv_env_LDFLAGS_set=${LDFLAGS+set} +ac_cv_env_LDFLAGS_value=$LDFLAGS +ac_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_env_CPPFLAGS_value=$CPPFLAGS +ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_cv_env_CPPFLAGS_value=$CPPFLAGS +ac_env_CPP_set=${CPP+set} +ac_env_CPP_value=$CPP +ac_cv_env_CPP_set=${CPP+set} +ac_cv_env_CPP_value=$CPP + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures filter 1.1 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +_ACEOF + + cat <<_ACEOF +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data [PREFIX/share] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --infodir=DIR info documentation [PREFIX/info] + --mandir=DIR man documentation [PREFIX/man] +_ACEOF + + cat <<\_ACEOF + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of filter 1.1:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-shared build shared libraries + --enable-dl allow use of dynamic loading if available + --enable-fpu_double set FPU in double round mode + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-filter-cc=CC compiler + --with-filter-cflags=CFLAGS compiler flags + --with-altlib=LIB library name + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have + headers in a nonstandard directory + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to . +_ACEOF +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + ac_popdir=`pwd` + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d $ac_dir || continue + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + cd $ac_dir + # Check for guested configure; otherwise get Cygnus style configure. + if test -f $ac_srcdir/configure.gnu; then + echo + $SHELL $ac_srcdir/configure.gnu --help=recursive + elif test -f $ac_srcdir/configure; then + echo + $SHELL $ac_srcdir/configure --help=recursive + elif test -f $ac_srcdir/configure.ac || + test -f $ac_srcdir/configure.in; then + echo + $ac_configure --help + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi + cd $ac_popdir + done +fi + +test -n "$ac_init_help" && exit 0 +if $ac_init_version; then + cat <<\_ACEOF +filter configure 1.1 +generated by GNU Autoconf 2.59 + +Copyright (C) 2003 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit 0 +fi +exec 5>config.log +cat >&5 <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by filter $as_me 1.1, which was +generated by GNU Autoconf 2.59. Invocation command line was + + $ $0 $@ + +_ACEOF +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +hostinfo = `(hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + echo "PATH: $as_dir" +done + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_sep= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$ac_configure_args1 '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" + # Get rid of the leading space. + ac_sep=" " + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Be sure not to use single quotes in there, as some shells, +# such as our DU 5.0 friend, will then `close' the trap. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +{ + (set) 2>&1 | + case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in + *ac_space=\ *) + sed -n \ + "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" + ;; + *) + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------- ## +## Output files. ## +## ------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + sed "/^$/d" confdefs.h | sort + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core && + rm -rf conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status + ' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo >confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . $cache_file;; + *) . ./$cache_file;; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in `(set) 2>&1 | + sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val="\$ac_cv_env_${ac_var}_value" + eval ac_new_val="\$ac_env_${ac_var}_value" + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ac_config_headers="$ac_config_headers conf.h" + + +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f $ac_dir/shtool; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 +echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} + { (exit 1); exit 1; }; } +fi +ac_config_guess="$SHELL $ac_aux_dir/config.guess" +ac_config_sub="$SHELL $ac_aux_dir/config.sub" +ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. + +# Make sure we can run config.sub. +$ac_config_sub sun4 >/dev/null 2>&1 || + { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5 +echo "$as_me: error: cannot run $ac_config_sub" >&2;} + { (exit 1); exit 1; }; } + +echo "$as_me:$LINENO: checking build system type" >&5 +echo $ECHO_N "checking build system type... $ECHO_C" >&6 +if test "${ac_cv_build+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_build_alias=$build_alias +test -z "$ac_cv_build_alias" && + ac_cv_build_alias=`$ac_config_guess` +test -z "$ac_cv_build_alias" && + { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 +echo "$as_me: error: cannot guess build type; you must specify one" >&2;} + { (exit 1); exit 1; }; } +ac_cv_build=`$ac_config_sub $ac_cv_build_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_build" >&5 +echo "${ECHO_T}$ac_cv_build" >&6 +build=$ac_cv_build +build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + +echo "$as_me:$LINENO: checking host system type" >&5 +echo $ECHO_N "checking host system type... $ECHO_C" >&6 +if test "${ac_cv_host+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_host_alias=$host_alias +test -z "$ac_cv_host_alias" && + ac_cv_host_alias=$ac_cv_build_alias +ac_cv_host=`$ac_config_sub $ac_cv_host_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_host" >&5 +echo "${ECHO_T}$ac_cv_host" >&6 +host=$ac_cv_host +host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + + +# +# checks that we use in most projects +# +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$ac_ct_CC" && break +done + + CC=$ac_ct_CC +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO:" \ + "checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 + (eval $ac_compiler --version &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 + (eval $ac_compiler -v &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 + (eval $ac_compiler -V &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 +echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6 +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 + (eval $ac_link_default) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Find the output, starting from the most likely. This scheme is +# not robust to junk in `.', hence go to wildcards (a.*) only as a last +# resort. + +# Be careful to initialize this variable, since it used to be cached. +# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. +ac_cv_exeext= +# b.out is created by i960 compilers. +for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) + ;; + conftest.$ac_ext ) + # This is the source file. + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + # FIXME: I believe we export ac_cv_exeext for Libtool, + # but it would be cool to find out if it's true. Does anybody + # maintain Libtool? --akim. + export ac_cv_exeext + break;; + * ) + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables +See \`config.log' for more details." >&5 +echo "$as_me: error: C compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6 + +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +rm -f a.out a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 +echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6 + +echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + export ac_cv_exeext + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6 + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6 +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_compiler_gnu=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +CFLAGS="-g" +echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_prog_cc_g=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 +echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_stdc=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std1 is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std1. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +# Don't try gcc -ansi; that turns off useful extensions and +# breaks some systems' header files. +# AIX -qlanglvl=ansi +# Ultrix and OSF/1 -std1 +# HP-UX 10.20 and later -Ae +# HP-UX older versions -Aa -D_HPUX_SOURCE +# SVR4 -Xc -D__EXTENSIONS__ +for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_stdc=$ac_arg +break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext +done +rm -f conftest.$ac_ext conftest.$ac_objext +CC=$ac_save_CC + +fi + +case "x$ac_cv_prog_cc_stdc" in + x|xno) + echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6 ;; + *) + echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 + CC="$CC $ac_cv_prog_cc_stdc" ;; +esac + +# Some people use a C++ compiler to compile C. Since we use `exit', +# in C++ we need to declare it. In case someone uses the same compiler +# for both compiling C and C++ we need to have the C++ compiler decide +# the declaration of exit, since it's the most demanding environment. +cat >conftest.$ac_ext <<_ACEOF +#ifndef __cplusplus + choke me +#endif +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + for ac_declaration in \ + '' \ + 'extern "C" void std::exit (int) throw (); using std::exit;' \ + 'extern "C" void std::exit (int); using std::exit;' \ + 'extern "C" void exit (int) throw ();' \ + 'extern "C" void exit (int);' \ + 'void exit (int);' +do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +#include +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +continue +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +done +rm -f conftest* +if test -n "$ac_declaration"; then + echo '#ifdef __cplusplus' >>confdefs.h + echo $ac_declaration >>confdefs.h + echo '#endif' >>confdefs.h +fi + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +if test x"${EXEEXT}" = "xno"; then + EXEEXT="" +fi + + +echo "$as_me:$LINENO: checking for long long int" >&5 +echo $ECHO_N "checking for long long int... $ECHO_C" >&6 +if test "${ac_cv_c_long_long+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$GCC" = yes; then + ac_cv_c_long_long=yes + else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +long long int i; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_long_long=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_c_long_long=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + fi +fi +echo "$as_me:$LINENO: result: $ac_cv_c_long_long" >&5 +echo "${ECHO_T}$ac_cv_c_long_long" >&6 + if test $ac_cv_c_long_long = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_LONG_LONG 1 +_ACEOF + + fi + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + echo "$as_me:$LINENO: result: $RANLIB" >&5 +echo "${ECHO_T}$RANLIB" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":" +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 +echo "${ECHO_T}$ac_ct_RANLIB" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + RANLIB=$ac_ct_RANLIB +else + RANLIB="$ac_cv_prog_RANLIB" +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +echo "$as_me:$LINENO: result: $CPP" >&5 +echo "${ECHO_T}$CPP" >&6 +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&5 +echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +echo "$as_me:$LINENO: checking for egrep" >&5 +echo $ECHO_N "checking for egrep... $ECHO_C" >&6 +if test "${ac_cv_prog_egrep+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if echo a | (grep -E '(a|b)') >/dev/null 2>&1 + then ac_cv_prog_egrep='grep -E' + else ac_cv_prog_egrep='egrep' + fi +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 +echo "${ECHO_T}$ac_cv_prog_egrep" >&6 + EGREP=$ac_cv_prog_egrep + + +echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_header_stdc=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + exit(2); + exit (0); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6 +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. + + + + + + + + + +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_Header=no" +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + +for ac_header in malloc.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------ ## +## Report this to saord@cfa.harvard.edu ## +## ------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in getopt.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------ ## +## Report this to saord@cfa.harvard.edu ## +## ------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in values.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------ ## +## Report this to saord@cfa.harvard.edu ## +## ------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in dlfcn.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------ ## +## Report this to saord@cfa.harvard.edu ## +## ------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in sys/un.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------ ## +## Report this to saord@cfa.harvard.edu ## +## ------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in sys/mman.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------ ## +## Report this to saord@cfa.harvard.edu ## +## ------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in sys/ipc.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------ ## +## Report this to saord@cfa.harvard.edu ## +## ------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +case $host_os in + *cygwin*|*Cygwin* ) + ;; + * ) + +for ac_header in sys/shm.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------ ## +## Report this to saord@cfa.harvard.edu ## +## ------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + ;; +esac + +echo "$as_me:$LINENO: checking for socklen_t" >&5 +echo $ECHO_N "checking for socklen_t... $ECHO_C" >&6 +if test "${ac_cv_type_socklen_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +int +main () +{ +if ((socklen_t *) 0) + return 0; +if (sizeof (socklen_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_socklen_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_socklen_t=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_socklen_t" >&5 +echo "${ECHO_T}$ac_cv_type_socklen_t" >&6 +if test $ac_cv_type_socklen_t = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_SOCKLEN_T 1 +_ACEOF + + +fi + + +echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 +echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6 +if test "${ac_cv_c_const+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +/* FIXME: Include the comments suggested by Paul. */ +#ifndef __cplusplus + /* Ultrix mips cc rejects this. */ + typedef int charset[2]; + const charset x; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *ccp; + char **p; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + ccp = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++ccp; + p = (char**) ccp; + ccp = (char const *const *) p; + { /* SCO 3.2v4 cc rejects this. */ + char *t; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; }; + struct s *b; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + } +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_const=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_c_const=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 +echo "${ECHO_T}$ac_cv_c_const" >&6 +if test $ac_cv_c_const = no; then + +cat >>confdefs.h <<\_ACEOF +#define const +_ACEOF + +fi + + + + + +for ac_func in strchr memcpy snprintf +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +echo "$as_me:$LINENO: checking for connect" >&5 +echo $ECHO_N "checking for connect... $ECHO_C" >&6 +if test "${ac_cv_func_connect+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define connect to an innocuous variant, in case declares connect. + For example, HP-UX 11i declares gettimeofday. */ +#define connect innocuous_connect + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char connect (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef connect + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char connect (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_connect) || defined (__stub___connect) +choke me +#else +char (*f) () = connect; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != connect; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_connect=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_connect=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_connect" >&5 +echo "${ECHO_T}$ac_cv_func_connect" >&6 + +if test $ac_cv_func_connect = no; then + echo "$as_me:$LINENO: checking for connect in -lsocket" >&5 +echo $ECHO_N "checking for connect in -lsocket... $ECHO_C" >&6 +if test "${ac_cv_lib_socket_connect+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsocket $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char connect (); +int +main () +{ +connect (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_socket_connect=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_socket_connect=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_socket_connect" >&5 +echo "${ECHO_T}$ac_cv_lib_socket_connect" >&6 +if test $ac_cv_lib_socket_connect = yes; then + EXTRA_LIBS="$EXTRA_LIBS -lsocket" +fi + +fi +echo "$as_me:$LINENO: checking for gethostbyname" >&5 +echo $ECHO_N "checking for gethostbyname... $ECHO_C" >&6 +if test "${ac_cv_func_gethostbyname+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define gethostbyname to an innocuous variant, in case declares gethostbyname. + For example, HP-UX 11i declares gettimeofday. */ +#define gethostbyname innocuous_gethostbyname + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char gethostbyname (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef gethostbyname + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gethostbyname (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_gethostbyname) || defined (__stub___gethostbyname) +choke me +#else +char (*f) () = gethostbyname; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != gethostbyname; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_gethostbyname=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_gethostbyname=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_gethostbyname" >&5 +echo "${ECHO_T}$ac_cv_func_gethostbyname" >&6 + +if test $ac_cv_func_gethostbyname = no; then + echo "$as_me:$LINENO: checking for gethostbyname in -lnsl" >&5 +echo $ECHO_N "checking for gethostbyname in -lnsl... $ECHO_C" >&6 +if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lnsl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gethostbyname (); +int +main () +{ +gethostbyname (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_nsl_gethostbyname=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_nsl_gethostbyname=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_gethostbyname" >&5 +echo "${ECHO_T}$ac_cv_lib_nsl_gethostbyname" >&6 +if test $ac_cv_lib_nsl_gethostbyname = yes; then + EXTRA_LIBS="$EXTRA_LIBS -lnsl" +fi + +fi +# AC_CHECK_LIB(db, snprintf, EXTRA_LIBS="$EXTRA_LIBS -ldb") + +# +# checks specific to this project +# +echo "$as_me:$LINENO: checking for inline" >&5 +echo $ECHO_N "checking for inline... $ECHO_C" >&6 +if test "${ac_cv_c_inline+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifndef __cplusplus +typedef int foo_t; +static $ac_kw foo_t static_foo () {return 0; } +$ac_kw foo_t foo () {return 0; } +#endif + +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_inline=$ac_kw; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +done + +fi +echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5 +echo "${ECHO_T}$ac_cv_c_inline" >&6 + + +case $ac_cv_c_inline in + inline | yes) ;; + *) + case $ac_cv_c_inline in + no) ac_val=;; + *) ac_val=$ac_cv_c_inline;; + esac + cat >>confdefs.h <<_ACEOF +#ifndef __cplusplus +#define inline $ac_val +#endif +_ACEOF + ;; +esac + + +echo "$as_me:$LINENO: checking for filter cc" >&5 +echo $ECHO_N "checking for filter cc... $ECHO_C" >&6 + +# Check whether --with-filter-cc or --without-filter-cc was given. +if test "${with_filter_cc+set}" = set; then + withval="$with_filter_cc" + FILTER_CC=\\\"$withval\\\" +else + FILTER_CC=NULL +fi; +echo "$as_me:$LINENO: result: $FILTER_CC" >&5 +echo "${ECHO_T}$FILTER_CC" >&6 + + +echo "$as_me:$LINENO: checking for filter cflags" >&5 +echo $ECHO_N "checking for filter cflags... $ECHO_C" >&6 + +# Check whether --with-filter-cflags or --without-filter-cflags was given. +if test "${with_filter_cflags+set}" = set; then + withval="$with_filter_cflags" + FILTER_CFLAGS=\\\"$withval\\\" +else + FILTER_CFLAGS=NULL +fi; +echo "$as_me:$LINENO: result: $FILTER_CFLAGS" >&5 +echo "${ECHO_T}$FILTER_CFLAGS" >&6 + + +DEFLIB="libfilter.a" +echo "$as_me:$LINENO: checking for alternate target library" >&5 +echo $ECHO_N "checking for alternate target library... $ECHO_C" >&6 + +# Check whether --with-altlib or --without-altlib was given. +if test "${with_altlib+set}" = set; then + withval="$with_altlib" + alt_lib=yes LIB=$withval +else + alt_lib=no LIB=$DEFLIB +fi; +echo "$as_me:$LINENO: result: $alt_lib ($LIB)" >&5 +echo "${ECHO_T}$alt_lib ($LIB)" >&6 + + + +echo "$as_me:$LINENO: checking for shared library build" >&5 +echo $ECHO_N "checking for shared library build... $ECHO_C" >&6 +# Check whether --enable-shared or --disable-shared was given. +if test "${enable_shared+set}" = set; then + enableval="$enable_shared" + fun_ok=$enableval +else + fun_ok=no +fi; +if test "$fun_ok" != "no"; then + fpic="yes" + DOSHARED=shlib + + if test "$fun_ok" = "link"; then + LLIB="-L. -l$PACKAGE_NAME" + else + LLIB='$(LIB)' + fi +else + LLIB='$(LIB)' +fi + +echo "$as_me:$LINENO: result: $fun_ok" >&5 +echo "${ECHO_T}$fun_ok" >&6 + +# Check whether --enable-dl or --disable-dl was given. +if test "${enable_dl+set}" = set; then + enableval="$enable_dl" + fun_ok=$enableval +else + fun_ok=no +fi; +if test "$fun_ok" = "yes"; then +echo "$as_me:$LINENO: checking for dynamic loading (with gcc) " >&5 +echo $ECHO_N "checking for dynamic loading (with gcc) ... $ECHO_C" >&6 +if test "$CC" = "gcc" -o `$CC -v 2>&1 | grep -c gcc` != "0" ; then + using_dl="yes" + echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 +echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 +if test "${ac_cv_lib_dl_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen (); +int +main () +{ +dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dl_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_dl_dlopen=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 +echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 +if test $ac_cv_lib_dl_dlopen = yes; then + have_dl=yes +else + have_dl=no +fi + + if test "$have_dl" = yes; then + USE_DL="-DUSE_DL=1" + fpic="yes" + EXTRA_LIBS="$EXTRA_LIBS -ldl" + if test `$CC -v -rdynamic 2>&1 | grep -c unrecognized` = "0" ; then + LDFLAGS="$LDFLAGS -rdynamic" + fi + else + echo "$as_me:$LINENO: checking for dlopen in -lc" >&5 +echo $ECHO_N "checking for dlopen in -lc... $ECHO_C" >&6 +if test "${ac_cv_lib_c_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lc $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen (); +int +main () +{ +dlopen (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_c_dlopen=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_c_dlopen=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_c_dlopen" >&5 +echo "${ECHO_T}$ac_cv_lib_c_dlopen" >&6 +if test $ac_cv_lib_c_dlopen = yes; then + have_dl=yes +else + have_dl=no +fi + + if test "$have_dl" = yes; then + USE_DL="-DUSE_DL=1" + fpic="yes" + if test `$CC -v -rdynamic 2>&1 | grep -c unrecognized` = "0" ; then + LDFLAGS="$LDFLAGS -rdynamic" + fi + else + using_dl="no" + fi + fi +else + using_dl="no" +fi +echo "$as_me:$LINENO: result: $using_dl ($CC)" >&5 +echo "${ECHO_T}$using_dl ($CC)" >&6 +fi + +# Check whether --enable-fpu_double or --disable-fpu_double was given. +if test "${enable_fpu_double+set}" = set; then + enableval="$enable_fpu_double" + fun_ok=$enableval +else + fun_ok=no +fi; +if test "$fun_ok" = "yes"; then +echo "$as_me:$LINENO: checking for setting fpu in double rounding mode (with gcc) " >&5 +echo $ECHO_N "checking for setting fpu in double rounding mode (with gcc) ... $ECHO_C" >&6 +if test "$CC" = "gcc" -o `$CC -v 2>&1 | grep -c gcc` != "0" ; then + using_fpu_double="yes" + USE_FPU_DOUBLE="1" +else + using_fpu_double="no" + USE_FPU_DOUBLE="0" +fi +echo "$as_me:$LINENO: result: $using_fpu_double" >&5 +echo "${ECHO_T}$using_fpu_double" >&6 +else + USE_FPU_DOUBLE="0" +fi + + +echo "$as_me:$LINENO: checking $host_os configuration" >&5 +echo $ECHO_N "checking $host_os configuration... $ECHO_C" >&6 +PRE="" +POST="|\& cat" +case $host_os in + *cygwin*|*Cygwin* ) + +cat >>confdefs.h <<\_ACEOF +#define HAVE_CYGWIN +_ACEOF + + echo "$as_me:$LINENO: result: flagging Cygwin" >&5 +echo "${ECHO_T}flagging Cygwin" >&6 + PRE="sh -c {" + POST="}" + ;; + *mingw32*|*Mingw32*) + CFLAGS="$CFLAGS -mconsole -D_WSTRING_DEFINED=1" + EXTRA_LIBS="$EXTRA_LIBS -lwsock32" + +cat >>confdefs.h <<\_ACEOF +#define HAVE_MINGW32 +_ACEOF + + echo "$as_me:$LINENO: result: flagging MinGW" >&5 +echo "${ECHO_T}flagging MinGW" >&6 + ;; + *osf*|*Osf*) + echo "$as_me:$LINENO: checking for snprintf in -ldb" >&5 +echo $ECHO_N "checking for snprintf in -ldb... $ECHO_C" >&6 +if test "${ac_cv_lib_db_snprintf+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldb $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char snprintf (); +int +main () +{ +snprintf (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_db_snprintf=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_db_snprintf=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_db_snprintf" >&5 +echo "${ECHO_T}$ac_cv_lib_db_snprintf" >&6 +if test $ac_cv_lib_db_snprintf = yes; then + EXTRA_LIBS="$EXTRA_LIBS -ldb" +fi + + ;; + *darwin*|*Darwin*) + LDFLAGS="$LDFLAGS $CFLAGS" + G=`$CC -v 2>&1 | grep version | awk '{print $3}' | awk -F. '{print $1$2}'` + if test x"$G" != x -a "$G" -lt 42; then + CFLAGS="$CFLAGS -no-cpp-precomp" + fi + CFLAGS="$CFLAGS -fno-common" + if test x"$fpic" = x"yes" ; then + CFLAGS="$CFLAGS -fPIC" + echo "$as_me:$LINENO: result: adding -fno-common, -fPIC to CFLAGS" >&5 +echo "${ECHO_T}adding -fno-common, -fPIC to CFLAGS" >&6 + else + echo "$as_me:$LINENO: result: adding -fno-common to CFLAGS" >&5 +echo "${ECHO_T}adding -fno-common to CFLAGS" >&6 + fi + ;; + * ) + if test x"$fpic" = x"yes" ; then + if test "$CC" = "gcc" -o `$CC -v 2>&1 | grep -c gcc` != "0" ; then + CFLAGS="$CFLAGS -fPIC" + echo "$as_me:$LINENO: result: adding -fPIC to gcc" >&5 +echo "${ECHO_T}adding -fPIC to gcc" >&6 + else + echo "$as_me:$LINENO: result: none" >&5 +echo "${ECHO_T}none" >&6 + fi + else + echo "$as_me:$LINENO: result: none" >&5 +echo "${ECHO_T}none" >&6 + fi + ;; +esac + + + + + + + ac_config_files="$ac_config_files Makefile" + + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +{ + (set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} | + sed ' + t clear + : clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + : end' >>confcache +if diff $cache_file confcache >/dev/null 2>&1; then :; else + if test -w $cache_file; then + test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" + cat confcache >$cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/; +s/:*\${srcdir}:*/:/; +s/:*@srcdir@:*/:/; +s/^\([^=]*=[ ]*\):*/\1/; +s/:*$//; +s/^[^=]*=[ ]*$//; +}' +fi + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_i=`echo "$ac_i" | + sed 's/\$U\././;s/\.o$//;s/\.obj$//'` + # 2. Add them. + ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi +DUALCASE=1; export DUALCASE # for MKS sh + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 +echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 +echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + +exec 6>&1 + +# Open the log real soon, to keep \$[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. Logging --version etc. is OK. +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX +} >&5 +cat >&5 <<_CSEOF + +This file was extended by filter $as_me 1.1, which was +generated by GNU Autoconf 2.59. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +_CSEOF +echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 +echo >&5 +_ACEOF + +# Files that config.status was made for. +if test -n "$ac_config_files"; then + echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_headers"; then + echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_links"; then + echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_commands"; then + echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS +fi + +cat >>$CONFIG_STATUS <<\_ACEOF + +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Report bugs to ." +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +filter config.status 1.1 +configured by $0, generated by GNU Autoconf 2.59, + with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2003 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." +srcdir=$srcdir +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "x$1" : 'x\([^=]*\)='` + ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` + ac_shift=: + ;; + -*) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + *) # This is not an option, so the user has probably given explicit + # arguments. + ac_option=$1 + ac_need_defaults=false;; + esac + + case $ac_option in + # Handling of the options. +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --vers* | -V ) + echo "$ac_cs_version"; exit 0 ;; + --he | --h) + # Conflict between --help and --header + { { echo "$as_me:$LINENO: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +if \$ac_cs_recheck; then + echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion +fi + +_ACEOF + + + + + +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_config_target in $ac_config_targets +do + case "$ac_config_target" in + # Handling of arguments. + "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "conf.h" ) CONFIG_HEADERS="$CONFIG_HEADERS conf.h" ;; + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason to put it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Create a temporary directory, and hook for its removal unless debugging. +$debug || +{ + trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} + +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./confstat$$-$RANDOM + (umask 077 && mkdir $tmp) +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF + +# +# CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "\$CONFIG_FILES"; then + # Protect against being on the right side of a sed subst in config.status. + sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; + s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF +s,@SHELL@,$SHELL,;t t +s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t +s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t +s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t +s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t +s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t +s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t +s,@exec_prefix@,$exec_prefix,;t t +s,@prefix@,$prefix,;t t +s,@program_transform_name@,$program_transform_name,;t t +s,@bindir@,$bindir,;t t +s,@sbindir@,$sbindir,;t t +s,@libexecdir@,$libexecdir,;t t +s,@datadir@,$datadir,;t t +s,@sysconfdir@,$sysconfdir,;t t +s,@sharedstatedir@,$sharedstatedir,;t t +s,@localstatedir@,$localstatedir,;t t +s,@libdir@,$libdir,;t t +s,@includedir@,$includedir,;t t +s,@oldincludedir@,$oldincludedir,;t t +s,@infodir@,$infodir,;t t +s,@mandir@,$mandir,;t t +s,@build_alias@,$build_alias,;t t +s,@host_alias@,$host_alias,;t t +s,@target_alias@,$target_alias,;t t +s,@DEFS@,$DEFS,;t t +s,@ECHO_C@,$ECHO_C,;t t +s,@ECHO_N@,$ECHO_N,;t t +s,@ECHO_T@,$ECHO_T,;t t +s,@LIBS@,$LIBS,;t t +s,@build@,$build,;t t +s,@build_cpu@,$build_cpu,;t t +s,@build_vendor@,$build_vendor,;t t +s,@build_os@,$build_os,;t t +s,@host@,$host,;t t +s,@host_cpu@,$host_cpu,;t t +s,@host_vendor@,$host_vendor,;t t +s,@host_os@,$host_os,;t t +s,@CC@,$CC,;t t +s,@CFLAGS@,$CFLAGS,;t t +s,@LDFLAGS@,$LDFLAGS,;t t +s,@CPPFLAGS@,$CPPFLAGS,;t t +s,@ac_ct_CC@,$ac_ct_CC,;t t +s,@EXEEXT@,$EXEEXT,;t t +s,@OBJEXT@,$OBJEXT,;t t +s,@RANLIB@,$RANLIB,;t t +s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t +s,@CPP@,$CPP,;t t +s,@EGREP@,$EGREP,;t t +s,@FILTER_CC@,$FILTER_CC,;t t +s,@FILTER_CFLAGS@,$FILTER_CFLAGS,;t t +s,@LIB@,$LIB,;t t +s,@DEFLIB@,$DEFLIB,;t t +s,@DOSHARED@,$DOSHARED,;t t +s,@LLIB@,$LLIB,;t t +s,@USE_FPU_DOUBLE@,$USE_FPU_DOUBLE,;t t +s,@USE_DL@,$USE_DL,;t t +s,@EXTRA_LIBS@,$EXTRA_LIBS,;t t +s,@EXTRA_OBJS@,$EXTRA_OBJS,;t t +s,@LIBOBJS@,$LIBOBJS,;t t +s,@LTLIBOBJS@,$LTLIBOBJS,;t t +CEOF + +_ACEOF + + cat >>$CONFIG_STATUS <<\_ACEOF + # Split the substitutions into bite-sized pieces for seds with + # small command number limits, like on Digital OSF/1 and HP-UX. + ac_max_sed_lines=48 + ac_sed_frag=1 # Number of current file. + ac_beg=1 # First line for current file. + ac_end=$ac_max_sed_lines # Line after last line for current file. + ac_more_lines=: + ac_sed_cmds= + while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + else + sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + fi + if test ! -s $tmp/subs.frag; then + ac_more_lines=false + else + # The purpose of the label and of the branching condition is to + # speed up the sed processing (if there are no `@' at all, there + # is no need to browse any of the substitutions). + # These are the two extra sed commands mentioned above. + (echo ':t + /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" + else + ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" + fi + ac_sed_frag=`expr $ac_sed_frag + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_lines` + fi + done + if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat + fi +fi # test -n "$CONFIG_FILES" + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + + + if test x"$ac_file" != x-; then + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + rm -f "$ac_file" + fi + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + configure_input= + else + configure_input="$ac_file. " + fi + configure_input=$configure_input"Generated from `echo $ac_file_in | + sed 's,.*/,,'` by configure." + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo "$f";; + *) # Relative + if test -f "$f"; then + # Build tree + echo "$f" + elif test -f "$srcdir/$f"; then + # Source tree + echo "$srcdir/$f" + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s,@configure_input@,$configure_input,;t t +s,@srcdir@,$ac_srcdir,;t t +s,@abs_srcdir@,$ac_abs_srcdir,;t t +s,@top_srcdir@,$ac_top_srcdir,;t t +s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t +s,@builddir@,$ac_builddir,;t t +s,@abs_builddir@,$ac_abs_builddir,;t t +s,@top_builddir@,$ac_top_builddir,;t t +s,@abs_top_builddir@,$ac_abs_top_builddir,;t t +" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out + rm -f $tmp/stdin + if test x"$ac_file" != x-; then + mv $tmp/out $ac_file + else + cat $tmp/out + rm -f $tmp/out + fi + +done +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + +# +# CONFIG_HEADER section. +# + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='[ ].*$,\1#\2' +ac_dC=' ' +ac_dD=',;t' +# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='$,\1#\2define\3' +ac_uC=' ' +ac_uD=',;t' + +for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + # Do quote $f, to prevent DOS paths from being IFS'd. + echo "$f";; + *) # Relative + if test -f "$f"; then + # Build tree + echo "$f" + elif test -f "$srcdir/$f"; then + # Source tree + echo "$srcdir/$f" + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } + # Remove the trailing spaces. + sed 's/[ ]*$//' $ac_file_inputs >$tmp/in + +_ACEOF + +# Transform confdefs.h into two sed scripts, `conftest.defines' and +# `conftest.undefs', that substitutes the proper values into +# config.h.in to produce config.h. The first handles `#define' +# templates, and the second `#undef' templates. +# And first: Protect against being on the right side of a sed subst in +# config.status. Protect against being in an unquoted here document +# in config.status. +rm -f conftest.defines conftest.undefs +# Using a here document instead of a string reduces the quoting nightmare. +# Putting comments in sed scripts is not portable. +# +# `end' is used to avoid that the second main sed command (meant for +# 0-ary CPP macros) applies to n-ary macro definitions. +# See the Autoconf documentation for `clear'. +cat >confdef2sed.sed <<\_ACEOF +s/[\\&,]/\\&/g +s,[\\$`],\\&,g +t clear +: clear +s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp +t end +s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp +: end +_ACEOF +# If some macros were called several times there might be several times +# the same #defines, which is useless. Nevertheless, we may not want to +# sort them, since we want the *last* AC-DEFINE to be honored. +uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines +sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs +rm -f confdef2sed.sed + +# This sed command replaces #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +cat >>conftest.undefs <<\_ACEOF +s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */, +_ACEOF + +# Break up conftest.defines because some shells have a limit on the size +# of here documents, and old seds have small limits too (100 cmds). +echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS +echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS +echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS +echo ' :' >>$CONFIG_STATUS +rm -f conftest.tail +while grep . conftest.defines >/dev/null +do + # Write a limited-size here document to $tmp/defines.sed. + echo ' cat >$tmp/defines.sed <>$CONFIG_STATUS + # Speed up: don't consider the non `#define' lines. + echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS + # Work around the forget-to-reset-the-flag bug. + echo 't clr' >>$CONFIG_STATUS + echo ': clr' >>$CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS + echo 'CEOF + sed -f $tmp/defines.sed $tmp/in >$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in +' >>$CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail + rm -f conftest.defines + mv conftest.tail conftest.defines +done +rm -f conftest.defines +echo ' fi # grep' >>$CONFIG_STATUS +echo >>$CONFIG_STATUS + +# Break up conftest.undefs because some shells have a limit on the size +# of here documents, and old seds have small limits too (100 cmds). +echo ' # Handle all the #undef templates' >>$CONFIG_STATUS +rm -f conftest.tail +while grep . conftest.undefs >/dev/null +do + # Write a limited-size here document to $tmp/undefs.sed. + echo ' cat >$tmp/undefs.sed <>$CONFIG_STATUS + # Speed up: don't consider the non `#undef' + echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS + # Work around the forget-to-reset-the-flag bug. + echo 't clr' >>$CONFIG_STATUS + echo ': clr' >>$CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS + echo 'CEOF + sed -f $tmp/undefs.sed $tmp/in >$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in +' >>$CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail + rm -f conftest.undefs + mv conftest.tail conftest.undefs +done +rm -f conftest.undefs + +cat >>$CONFIG_STATUS <<\_ACEOF + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + echo "/* Generated by configure. */" >$tmp/config.h + else + echo "/* $ac_file. Generated by configure. */" >$tmp/config.h + fi + cat $tmp/in >>$tmp/config.h + rm -f $tmp/in + if test x"$ac_file" != x-; then + if diff $ac_file $tmp/config.h >/dev/null 2>&1; then + { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 +echo "$as_me: $ac_file is unchanged" >&6;} + else + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + rm -f $ac_file + mv $tmp/config.h $ac_file + fi + else + cat $tmp/config.h + rm -f $tmp/config.h + fi +done +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi + diff --git a/filter/configure.ac b/filter/configure.ac new file mode 100644 index 0000000..ae2a3db --- /dev/null +++ b/filter/configure.ac @@ -0,0 +1,202 @@ +# This file is an input file used by the GNU "autoconf" program to +# generate the file "configure", which is run during XPA installation +# to configure the system for the local environment. +AC_INIT(filter, 1.1, saord@cfa.harvard.edu, filter) + +AC_CONFIG_HEADERS([conf.h]) +AC_CONFIG_SRCDIR(./filter.h) +AC_CANONICAL_HOST + +# +# checks that we use in most projects +# +AC_PROG_CC + +AC_EXEEXT +if test x"${EXEEXT}" = "xno"; then + EXEEXT="" +fi + +AC_C_LONG_LONG + +AC_PROG_RANLIB + +AC_HEADER_STDC +AC_CHECK_HEADERS(malloc.h) +AC_CHECK_HEADERS(getopt.h) +AC_CHECK_HEADERS(values.h) +AC_CHECK_HEADERS(dlfcn.h) +AC_CHECK_HEADERS(sys/un.h) +AC_CHECK_HEADERS(sys/mman.h) +AC_CHECK_HEADERS(sys/ipc.h) +case $host_os in + *cygwin*|*Cygwin* ) + ;; + * ) + AC_CHECK_HEADERS(sys/shm.h) + ;; +esac + +AC_CHECK_TYPES([socklen_t], [], [], [#include ]) + +AC_C_CONST + +AC_CHECK_FUNCS(strchr memcpy snprintf) + +AC_CHECK_FUNC(connect) +if test $ac_cv_func_connect = no; then + AC_CHECK_LIB(socket, connect, EXTRA_LIBS="$EXTRA_LIBS -lsocket") +fi +AC_CHECK_FUNC(gethostbyname) +if test $ac_cv_func_gethostbyname = no; then + AC_CHECK_LIB(nsl, gethostbyname, EXTRA_LIBS="$EXTRA_LIBS -lnsl") +fi +# AC_CHECK_LIB(db, snprintf, EXTRA_LIBS="$EXTRA_LIBS -ldb") + +# +# checks specific to this project +# +AC_C_INLINE + +AC_MSG_CHECKING(for filter cc) +AC_ARG_WITH(filter-cc, [ --with-filter-cc=CC compiler], + FILTER_CC=\\\"$withval\\\", FILTER_CC=NULL) +AC_MSG_RESULT($FILTER_CC) +AC_SUBST(FILTER_CC) + +AC_MSG_CHECKING(for filter cflags) +AC_ARG_WITH(filter-cflags, [ --with-filter-cflags=CFLAGS compiler flags], + FILTER_CFLAGS=\\\"$withval\\\", FILTER_CFLAGS=NULL) +AC_MSG_RESULT($FILTER_CFLAGS) +AC_SUBST(FILTER_CFLAGS) + +DEFLIB="libfilter.a" +AC_MSG_CHECKING(for alternate target library) +AC_ARG_WITH(altlib, [ --with-altlib=LIB library name], + alt_lib=yes LIB=$withval, alt_lib=no LIB=$DEFLIB) +AC_MSG_RESULT($alt_lib ($LIB)) +AC_SUBST(LIB) +AC_SUBST(DEFLIB) + +AC_MSG_CHECKING(for shared library build) +AC_ARG_ENABLE(shared, [ --enable-shared build shared libraries], + [fun_ok=$enableval], [fun_ok=no]) +if test "$fun_ok" != "no"; then + fpic="yes" + DOSHARED=shlib + AC_SUBST(DOSHARED) + if test "$fun_ok" = "link"; then + LLIB="-L. -l$PACKAGE_NAME" + else + LLIB='$(LIB)' + fi +else + LLIB='$(LIB)' +fi +AC_SUBST(LLIB) +AC_MSG_RESULT($fun_ok) + +AC_ARG_ENABLE(dl, [ --enable-dl allow use of dynamic loading if available], + [fun_ok=$enableval], [fun_ok=no]) +if test "$fun_ok" = "yes"; then +AC_MSG_CHECKING([for dynamic loading (with gcc) ]) +if test "$CC" = "gcc" -o `$CC -v 2>&1 | grep -c gcc` != "0" ; then + using_dl="yes" + AC_CHECK_LIB(dl, dlopen, have_dl=yes, have_dl=no) + if test "$have_dl" = yes; then + USE_DL="-DUSE_DL=1" + fpic="yes" + EXTRA_LIBS="$EXTRA_LIBS -ldl" + if test `$CC -v -rdynamic 2>&1 | grep -c unrecognized` = "0" ; then + LDFLAGS="$LDFLAGS -rdynamic" + fi + else + AC_CHECK_LIB(c, dlopen, have_dl=yes, have_dl=no) + if test "$have_dl" = yes; then + USE_DL="-DUSE_DL=1" + fpic="yes" + if test `$CC -v -rdynamic 2>&1 | grep -c unrecognized` = "0" ; then + LDFLAGS="$LDFLAGS -rdynamic" + fi + else + using_dl="no" + fi + fi +else + using_dl="no" +fi +AC_MSG_RESULT([$using_dl ($CC)]) +fi + +AC_ARG_ENABLE(fpu_double, [ --enable-fpu_double set FPU in double round mode], + [fun_ok=$enableval], [fun_ok=no]) +if test "$fun_ok" = "yes"; then +AC_MSG_CHECKING([for setting fpu in double rounding mode (with gcc) ]) +if test "$CC" = "gcc" -o `$CC -v 2>&1 | grep -c gcc` != "0" ; then + using_fpu_double="yes" + USE_FPU_DOUBLE="1" +else + using_fpu_double="no" + USE_FPU_DOUBLE="0" +fi +AC_MSG_RESULT([$using_fpu_double]) +else + USE_FPU_DOUBLE="0" +fi +AC_SUBST(USE_FPU_DOUBLE) + +AC_MSG_CHECKING([$host_os configuration]) +PRE="" +POST="|\& cat" +case $host_os in + *cygwin*|*Cygwin* ) + AC_DEFINE([HAVE_CYGWIN]) + AC_MSG_RESULT(flagging Cygwin) + PRE="sh -c {" + POST="}" + ;; + *mingw32*|*Mingw32*) + CFLAGS="$CFLAGS -mconsole -D_WSTRING_DEFINED=1" + EXTRA_LIBS="$EXTRA_LIBS -lwsock32" + AC_DEFINE([HAVE_MINGW32]) + AC_MSG_RESULT(flagging MinGW) + ;; + *osf*|*Osf*) + AC_CHECK_LIB(db, snprintf, EXTRA_LIBS="$EXTRA_LIBS -ldb") + ;; + *darwin*|*Darwin*) + LDFLAGS="$LDFLAGS $CFLAGS" + G=`$CC -v 2>&1 | grep version | awk '{print $3}' | awk -F. '{print $1$2}'` + if test x"$G" != x -a "$G" -lt 42; then + CFLAGS="$CFLAGS -no-cpp-precomp" + fi + CFLAGS="$CFLAGS -fno-common" + if test x"$fpic" = x"yes" ; then + CFLAGS="$CFLAGS -fPIC" + AC_MSG_RESULT([adding -fno-common, -fPIC to CFLAGS]) + else + AC_MSG_RESULT([adding -fno-common to CFLAGS]) + fi + ;; + * ) + if test x"$fpic" = x"yes" ; then + if test "$CC" = "gcc" -o `$CC -v 2>&1 | grep -c gcc` != "0" ; then + CFLAGS="$CFLAGS -fPIC" + AC_MSG_RESULT(adding -fPIC to gcc) + else + AC_MSG_RESULT(none) + fi + else + AC_MSG_RESULT(none) + fi + ;; +esac + +AC_SUBST(USE_DL) + +AC_SUBST(EXTRA_LIBS) +AC_SUBST(EXTRA_OBJS) + +AC_CONFIG_FILES(Makefile) + +AC_OUTPUT diff --git a/filter/dl.c b/filter/dl.c new file mode 100644 index 0000000..8e914f2 --- /dev/null +++ b/filter/dl.c @@ -0,0 +1,57 @@ +#ifdef USE_DL + +#include +#include +#include +#include + +int have_dl = 1; + +#ifdef ANSI_FUNC +void * +DLOpen(char *name) +#else +void *DLOpen(name) + char *name; +#endif +{ + void *d; + if( !(d=dlopen(name, RTLD_LAZY)) ) + gerror(stderr, "%s\n", dlerror()); + return d; +} + +#ifdef ANSI_FUNC +void * +DLSym(void *dl, char *name) +#else +void *DLSym(dl, name) + void *dl; + char *name; +#endif +{ + void *d; + if( !(d=dlsym(dl, name)) ) + gerror(stderr, "%s\n", dlerror()); + return d; +} + +#ifdef ANSI_FUNC +int +DLClose(void *dl) +#else +int DLClose(dl) + void *dl; +#endif +{ + if( dl ) + return dlclose(dl); + else + return -1; +} + +#else + +int have_dl = 0; + +#endif diff --git a/filter/dl.h b/filter/dl.h new file mode 100644 index 0000000..e3f1b09 --- /dev/null +++ b/filter/dl.h @@ -0,0 +1,23 @@ +#ifndef __dl_h +#define __dl_h + +#if HAVE_CONFIG_H +#include "conf.h" +#endif + +#ifdef HAVE_DLFCN_H +#include +#endif + +#include "prsetup.h" + +_PRbeg + +void *DLOpen _PRx((char *name)); +void *DLSym _PRx((void *dl, char *name)); +int DLClose _PRx((void *dl)); + + +_PRend + +#endif diff --git a/filter/events_c.h b/filter/events_c.h new file mode 100644 index 0000000..74f180e --- /dev/null +++ b/filter/events_c.h @@ -0,0 +1 @@ +static char *EVENTS_C="\n\n#ifdef TEST\n#include \n#define EVFILTRTN _FilterEvents\n#define NSHAPE 1\n#define NREGION 1\n#define _X_ X\n#define _Y_ Y\n#define FILTER ((circle(g,1,1,1,_X_,_Y_,1,2,3)))\n#define EVSIZE 4\n#define X *((short *)(eptr+0))\n#define Y *((short *)(eptr+2))\n#include \"regions.h\"\n#endif\n\nstatic char __abuf[EVSIZE+1];\nstatic char *acopy(void *s, int n)\n{\n memset(__abuf, 0, n+1);\n memmove(__abuf, s, n);\n return __abuf;\n}\n\nvoid *EVFILTRTN(void *tg, char *ebuf, int ne, int esize, int *rbuf)\n{\n int i, j;\n int *rptr;\n char *eptr;\n Scan scan, tscan;\n GFilt g = (GFilt)tg;\n\n \n \n eptr = ebuf;\n\n if( !g ){\n g = (GFilt)calloc(1, sizeof(GFiltRec));\n#if NSHAPE\n \n g->nshapes = NSHAPE;\n g->maxshapes = (NSHAPE*(XSNO+1))+1;\n g->shapes = (Shape)calloc(g->maxshapes, sizeof(ShapeRec));\n#endif\n#ifdef EVSECT\n \n g->evsect = EVSECT;\n sscanf(g->evsect, \"%d %d %d %d %d\",\n &g->xmin, &g->xmax, &g->ymin, &g->ymax, &g->block);\n \n g->x0 = 1;\n g->y0 = 1;\n g->x1 = (g->xmax-g->xmin)/g->block+1;\n g->y1 = (g->ymax-g->ymin)/g->block+1;\n \n g->ybuf = (int *)calloc(g->y1+1, sizeof(int));\n g->x0s = (int *)calloc(g->y1+1, sizeof(int));\n g->x1s = (int *)calloc(g->y1+1, sizeof(int));\n \n for(i=0; i<=g->y1; i++) g->x0s[i] = g->x0;\n for(i=0; i<=g->y1; i++) g->x1s[i] = g->x1;\n \n if( NMASK ){\n g->nmask = NMASK; \n g->maskdim = MASKDIM;\n g->masks = _masks;\n }\n \n#if DO_FILTER_SWAP\n memset(_swf, 0, EVSIZE);\n#endif\n if( eptr ) FINIT;\n \n g->tlminx = TLMINX;\n g->tlminy = TLMINY;\n g->usebinsiz = USEBINSIZ;\n if( BINSIZX > 0.0 )\n g->binsizx = BINSIZX;\n else\n g->binsizx = 1.0;\n if( BINSIZY > 0.0 )\n g->binsizy = BINSIZY;\n else\n g->binsizy = 1.0;\n g->tloff = TLOFF;\n#endif\n }\n\n \n if( !ebuf && !rbuf && (ne<0) ){\n#if NSHAPE\n \n for(i=0; imaxshapes; i++){\n if( g->shapes[i].scanlist ){\n for(j=0; jy1; j++){\n if( g->shapes[i].scanlist[j] ){\n for(scan=g->shapes[i].scanlist[j]; scan; ){\n tscan = scan->next;\n if( scan ) free(scan);\n scan = tscan;\n }\n }\n }\n if( g->shapes[i].scanlist ) free(g->shapes[i].scanlist);\n }\n if( g->shapes[i].pts ) free(g->shapes[i].pts);\n if( g->shapes[i].xv ) free(g->shapes[i].xv);\n }\n if( g->masks ) free(g->masks);\n if( g->shapes ) free(g->shapes);\n if( g->ybuf ) free(g->ybuf);\n if( g->x0s ) free(g->x0s);\n if( g->x1s ) free(g->x1s);\n if( g ) free(g);\n#endif\n return NULL;\n }\n else{\n \n for(rptr=rbuf, eptr=ebuf; ne--; rptr++, eptr += esize){\n g->rid = 0;\n#if DO_FILTER_SWAP\n memset(_swf, 0, EVSIZE);\n#endif\n *rptr = ((FILTER) ? (g->rid ? g->rid : -1) : 0);\n }\n return (void *)g;\n }\n}\n\nint main(int argc, char **argv)\n{\n int i;\n#if HAVE_MINGW32==0\n int pipes[4];\n#endif\n int get, got;\n#if DO_FILTER_SWAP\n int sgot;\n#endif\n int n;\n int *rbuf;\n char *ebuf, *etop;\n char *s=NULL, *t=NULL, *u=NULL;\n void *g=NULL;\n#if USE_WIN32\n HANDLE hStdin, hStdout; \n DWORD dwRead, dwWritten; \n#endif\n\n \n#if HAVE_MINGW32==0\n if( (s=getenv(\"LAUNCH_PIPES\")) ){\n t = (char *)strdup(s);\n for(i=0, u=(char *)strtok(t, \",\"); i<4 && u; \n i++, u=(char *)strtok(NULL,\",\")){\n pipes[i] = atoi(u);\n }\n if( t ) free(t);\n if( i < 4 ) return(1);\n close(pipes[0]);\n close(pipes[3]);\n dup2(pipes[2], 0); close(pipes[2]);\n dup2(pipes[1], 1); close(pipes[1]);\n }\n#endif\n\n#if USE_WIN32\n hStdout = GetStdHandle(STD_OUTPUT_HANDLE); \n hStdin = GetStdHandle(STD_INPUT_HANDLE); \n if( (hStdout == INVALID_HANDLE_VALUE) || (hStdin == INVALID_HANDLE_VALUE) ){\n unlink(argv[0]);\n return 0;\n }\n#endif\n\n \n#if USE_WIN32\n while((ReadFile(hStdin, &get, sizeof(int), &dwRead, NULL) >0) && \n (dwRead == sizeof(int)) ){\n#else\n while( read(0, &get, sizeof(int)) == sizeof(int) ){\n#endif\n#if DO_FILTER_SWAP\n switch(sizeof(int)){\n case 2:\n _sw2((char *)&get,2,NULL,0);\n break;\n case 4:\n _sw4((char *)&get,4,NULL,0);\n break;\n case 8:\n _sw8((char *)&get,8,NULL,0);\n break;\n }\n#endif\n ebuf = (char *)calloc(get, sizeof(char));\n#if USE_WIN32\n for(n=0, etop=ebuf; get>0; etop += got, get -= dwRead){\n if((ReadFile(hStdin, etop, get, &dwRead, NULL)==FALSE) || (dwRead==0))\n break;\n n += dwRead;\n }\n#else\n for(n=0, etop=ebuf; get>0; etop += got, get -= got){\n if( (got=read(0, etop, get)) <=0 ) \n break;\n n += got;\n }\n#endif\n n /= EVSIZE;\n \n rbuf = (int *)calloc(n, sizeof(int));\n \n g = EVFILTRTN(g, ebuf, n, EVSIZE, rbuf);\n \n got = n*sizeof(int);\n#if DO_FILTER_SWAP\n sgot = got;\n switch(sizeof(int)){\n case 2:\n _sw2((char *)&sgot,2,NULL,0);\n break;\n case 4:\n _sw4((char *)&sgot,4,NULL,0);\n break;\n case 8:\n _sw8((char *)&sgot,8,NULL,0);\n break;\n }\n#if USE_WIN32\n WriteFile(hStdout, &sgot, sizeof(int), &dwWritten, NULL); \n#else\n write(1, &sgot, sizeof(int));\n#endif\n#else\n#if USE_WIN32\n WriteFile(hStdout, &got, sizeof(int), &dwWritten, NULL); \n#else\n write(1, &got, sizeof(int));\n#endif\n#endif\n#if DO_FILTER_SWAP\n switch(sizeof(int)){\n case 2:\n _sw2((char *)rbuf,got,NULL,0);\n break;\n case 4:\n _sw4((char *)rbuf,got,NULL,0);\n break;\n case 8:\n _sw8((char *)rbuf,got,NULL,0);\n break;\n }\n#endif\n#if USE_WIN32\n WriteFile(hStdout, rbuf, got, &dwWritten, NULL); \n#else\n write(1, rbuf, got);\n#endif\n if( ebuf) free(ebuf);\n if( rbuf ) free(rbuf);\n }\n EVFILTRTN(g, NULL, -1, 0, NULL);\n unlink(argv[0]);\n return 0;\n}\n"; diff --git a/filter/events_py.h b/filter/events_py.h new file mode 100644 index 0000000..fdf775b --- /dev/null +++ b/filter/events_py.h @@ -0,0 +1 @@ +static char *EVENTS_PY="\n# load the funtools routines\n_libname = './libfuntools.so.1.0'\nlibfuntools=cdll.LoadLibrary(_libname)\nlibc=cdll.LoadLibrary(None)\n\n# region definitions\nimannulusi=libfuntools.imannulusi\nimboxi=libfuntools.imboxi\nimcirclei=libfuntools.imcirclei\nimellipsei=libfuntools.imellipsei\nimfieldi=libfuntools.imfieldi\nimlinei=libfuntools.imlinei\nimpiei=libfuntools.impiei\nimqtpiei=libfuntools.imqtpiei\nimpointi=libfuntools.impointi\nimpandai=libfuntools.impandai\nimnannulusi=libfuntools.imnannulusi\nimnboxi=libfuntools.imnboxi\nimnellipsei=libfuntools.imnellipsei\nimnpiei=libfuntools.imnpiei\nimpolygoni=libfuntools.impolygoni\nimvannulusi=libfuntools.imvannulusi\nimvboxi=libfuntools.imvboxi\nimvellipsei=libfuntools.imvellipsei\nimvpiei=libfuntools.imvpiei\nimvpointi=libfuntools.imvpointi\nimannulus=libfuntools.imannulus\nimbox=libfuntools.imbox\nimcircle=libfuntools.imcircle\nimellipse=libfuntools.imellipse\nimfield=libfuntools.imfield\nimline=libfuntools.imline\nimpie=libfuntools.impie\nimqtpie=libfuntools.imqtpie\nimpoint=libfuntools.impoint\nimpanda=libfuntools.impanda\nimnannulus=libfuntools.imnannulus\nimnbox=libfuntools.imnbox\nimnellipse=libfuntools.imnellipse\nimnpie=libfuntools.imnpie\nimpolygon=libfuntools.impolygon\nimvannulus=libfuntools.imvannulus\nimvbox=libfuntools.imvbox\nimvellipse=libfuntools.imvellipse\nimvpie=libfuntools.imvpie\nimvpoint=libfuntools.imvpoint\n\nevannulus=libfuntools.evannulus\nevbox=libfuntools.evbox\nevcircle=libfuntools.evcircle\nevellipse=libfuntools.evellipse\nevfield=libfuntools.evfield\nevline=libfuntools.evline\nevpie=libfuntools.evpie\nevqtpie=libfuntools.evqtpie\nevpoint=libfuntools.evpoint\nevnannulus=libfuntools.evnannulus\nevnbox=libfuntools.evnbox\nevnellipse=libfuntools.evnellipse\nevnpie=libfuntools.evnpie\nevpanda=libfuntools.evpanda\nevpolygon=libfuntools.evpolygon\nevvannulus=libfuntools.evvannulus\nevvbox=libfuntools.evvbox\nevvellipse=libfuntools.evvellipse\nevvpie=libfuntools.evvpie\nevvpoint=libfuntools.evvpoint\n\nevvcircle=libfuntools.evvannulus\nevncircle=libfuntools.evnannulus\nevcpanda=libfuntools.evpanda\n\nimvcirclei=libfuntools.imvannulusi\nimncirclei=libfuntools.imnannulusi\nimvcircle=libfuntools.imvannulus\nimncircle=libfuntools.imnannulus\nimcpandai=libfuntools.impandai\nimcpanda=libfuntools.impanda\n\n# from regions.h -- no idea what it is ...\nxsno=3\n\n# ... but its important!\nmaxshapes=(nshape*(xsno+1))+1\n\n# ctypes struct definitions (taken from filter.h)\nclass filtmask(Structure):\n _fields_ = [('region', c_int), ('y', c_int), ('xstart', c_int), ('xstop', c_int)]\n\nclass scanrec(Structure):\n pass\n\n# this is how you add a forward pointer\nscanrec._fields_ = [ ('next', POINTER(scanrec)), ('x', c_int) ]\n\nclass shaperec(Structure):\n _fields_ = [ ('init', c_int), ('ystart', c_double), ('ystop', c_double), ('scanlist', c_void_p), ('nv', c_int), ('xv', c_void_p), ('r1sq', c_double), ('r2sq', c_double), ('angl', c_double), ('sinangl', c_double), ('cosangl', c_double), ('cossq', c_double), ('sinsq', c_double), ('xradsq', c_double), ('yradsq', c_double), ('a', c_double), ('npt', c_int), ('pts', c_void_p), ('xonly', c_int), ('x1', c_double), ('x2', c_double), ('y1', c_double), ('invslope', c_double)]\n\nclass gfiltrec(Structure):\n _fields_ = [('nshapes', c_int), ('maxshapes', c_int), ('shapes', POINTER(shaperec * maxshapes)), ('rid', c_int), ('usebinsiz', c_int), ('evsect', c_char_p), ('tlminx', c_double), ('tlminy', c_double), ('binsizx', c_double), ('binsizy', c_double), ('tloff', c_double), ('xmin', c_int), ('xmax', c_int), ('ymin', c_int), ('ymax', c_int), ('block', c_int), ('x0', c_int), ('x1', c_int), ('y0', c_int), ('y1', c_int), ('ybuf', POINTER(c_int)), ('x0s', POINTER(c_int)), ('x1s', POINTER(c_int)), ('nmask', c_int), ('maskdim', c_int), ('masks', POINTER(filtmask))]\n\n# taken from the code in evfilter.c that initializes the g struct\n# allocate shape record\nshapearr = (shaperec * maxshapes)()\n# allocate g record\ngrec = gfiltrec()\n# fill in g record\ngrec.nshapes = nshape\ngrec.maxshapes = maxshapes\ngrec.shapes = pointer(shapearr)\n# pointer to g record\ng=pointer(grec)\n\n# # processing loop\n# while True:\n# rvals = ''\n# buf = sys.stdin.read(4)\n# if not buf: break\n# vals = struct.unpack('=i', buf)\n# nev = vals[0]/evsize\n# for i in range(nev):\n# evbuf = sys.stdin.read(evsize)\n# rvals += struct.pack('=i', xfilter(evdef, evbuf))\n# sys.stdout.write(struct.pack('=i', nev*4))\n# sys.stdout.write(rvals)\n# sys.stdout.flush()\n\n# processing loop\nobytes = 0\nwhile True:\n # get byte count\n nval = c_int(0)\n if libc.read(0, byref(nval), 4) != 4: break\n bytes = nval.value\n nev = bytes / evsize\n\n # create a new data buffer, if necessary\n if obytes != bytes:\n evbuf = create_string_buffer(bytes)\n pevbuf = addressof(evbuf)\n rvals = (c_int * nev)()\n obytes = bytes\n\n # read data\n if libc.read(0, evbuf, bytes) != bytes: break\n\n # process data\n ioff = 0\n for i in range(nev):\n rvals[i] = xfilter(evdef, evbuf[ioff:ioff+evsize])\n ioff += evsize\n\n # write result byte count and result data\n nval = c_int(nev*4)\n libc.write(1, byref(nval), 4)\n libc.write(1, rvals, nval)\n"; diff --git a/filter/evfilter.c b/filter/evfilter.c new file mode 100644 index 0000000..58add93 --- /dev/null +++ b/filter/evfilter.c @@ -0,0 +1,266 @@ +/* gcc -g -o foo event.body.c -lm */ +#ifdef TEST +#include +#define EVFILTRTN _FilterEvents +#define NSHAPE 1 +#define NREGION 1 +#define _X_ X +#define _Y_ Y +#define FILTER ((circle(g,1,1,1,_X_,_Y_,1,2,3))) +#define EVSIZE 4 +#define X *((short *)(eptr+0)) +#define Y *((short *)(eptr+2)) +#include "regions.h" +#endif + +static char __abuf[EVSIZE+1]; +static char *acopy(void *s, int n) +{ + memset(__abuf, 0, n+1); + memmove(__abuf, s, n); + return __abuf; +} + +void *EVFILTRTN(void *tg, char *ebuf, int ne, int esize, int *rbuf) +{ + int i, j; + int *rptr; + char *eptr; + Scan scan, tscan; + GFilt g = (GFilt)tg; + + /* set eptr to ebuf -- this must be done before FINIT, because the latter */ + /*passes X and Y to shape init routines, and these defines use eptr */ + eptr = ebuf; + + if( !g ){ + g = (GFilt)calloc(1, sizeof(GFiltRec)); +#if NSHAPE + /* allocate space for the globals */ + g->nshapes = NSHAPE; + g->maxshapes = (NSHAPE*(XSNO+1))+1; + g->shapes = (Shape)calloc(g->maxshapes, sizeof(ShapeRec)); +#endif +#ifdef EVSECT + /* if evsect is defined, we are filtering an image section */ + g->evsect = EVSECT; + sscanf(g->evsect, "%d %d %d %d %d", + &g->xmin, &g->xmax, &g->ymin, &g->ymax, &g->block); + /* get x and y limits on subsection */ + g->x0 = 1; + g->y0 = 1; + g->x1 = (g->xmax-g->xmin)/g->block+1; + g->y1 = (g->ymax-g->ymin)/g->block+1; + /* allocate a buffer for valid y row flags */ + g->ybuf = (int *)calloc(g->y1+1, sizeof(int)); + g->x0s = (int *)calloc(g->y1+1, sizeof(int)); + g->x1s = (int *)calloc(g->y1+1, sizeof(int)); + /* seed impossible values for x limits */ + for(i=0; i<=g->y1; i++) g->x0s[i] = g->x0; + for(i=0; i<=g->y1; i++) g->x1s[i] = g->x1; + /* save image mask values */ + if( NMASK ){ + g->nmask = NMASK; + g->maskdim = MASKDIM; + g->masks = _masks; + } + /* initialize shapes -- but check to make sure eptr is OK */ +#if DO_FILTER_SWAP + memset(_swf, 0, EVSIZE); +#endif + if( eptr ) FINIT; + /* these also must be defined if EVSECT is being used */ + g->tlminx = TLMINX; + g->tlminy = TLMINY; + g->usebinsiz = USEBINSIZ; + if( BINSIZX > 0.0 ) + g->binsizx = BINSIZX; + else + g->binsizx = 1.0; + if( BINSIZY > 0.0 ) + g->binsizy = BINSIZY; + else + g->binsizy = 1.0; + g->tloff = TLOFF; +#endif + } + + /* if we have negative events, we free the structs */ + if( !ebuf && !rbuf && (ne<0) ){ +#if NSHAPE + /* free polygon records */ + for(i=0; imaxshapes; i++){ + if( g->shapes[i].scanlist ){ + for(j=0; jy1; j++){ + if( g->shapes[i].scanlist[j] ){ + for(scan=g->shapes[i].scanlist[j]; scan; ){ + tscan = scan->next; + if( scan ) free(scan); + scan = tscan; + } + } + } + if( g->shapes[i].scanlist ) free(g->shapes[i].scanlist); + } + if( g->shapes[i].pts ) free(g->shapes[i].pts); + if( g->shapes[i].xv ) free(g->shapes[i].xv); + } + if( g->masks ) free(g->masks); + if( g->shapes ) free(g->shapes); + if( g->ybuf ) free(g->ybuf); + if( g->x0s ) free(g->x0s); + if( g->x1s ) free(g->x1s); + if( g ) free(g); +#endif + return NULL; + } + else{ + /* do the filtering on each event */ + for(rptr=rbuf, eptr=ebuf; ne--; rptr++, eptr += esize){ + g->rid = 0; +#if DO_FILTER_SWAP + memset(_swf, 0, EVSIZE); +#endif + *rptr = ((FILTER) ? (g->rid ? g->rid : -1) : 0); + } + return (void *)g; + } +} + +int main(int argc, char **argv) +{ + int i; +#if HAVE_MINGW32==0 + int pipes[4]; +#endif + int get, got; +#if DO_FILTER_SWAP + int sgot; +#endif + int n; + int *rbuf; + char *ebuf, *etop; + char *s=NULL, *t=NULL, *u=NULL; + void *g=NULL; +#if USE_WIN32 + HANDLE hStdin, hStdout; + DWORD dwRead, dwWritten; +#endif + + /* Launch() sometimes rearranges passed pipes to be stdin/stdout */ +#if HAVE_MINGW32==0 + if( (s=getenv("LAUNCH_PIPES")) ){ + t = (char *)strdup(s); + for(i=0, u=(char *)strtok(t, ","); i<4 && u; + i++, u=(char *)strtok(NULL,",")){ + pipes[i] = atoi(u); + } + if( t ) free(t); + if( i < 4 ) return(1); + close(pipes[0]); + close(pipes[3]); + dup2(pipes[2], 0); close(pipes[2]); + dup2(pipes[1], 1); close(pipes[1]); + } +#endif + +#if USE_WIN32 + hStdout = GetStdHandle(STD_OUTPUT_HANDLE); + hStdin = GetStdHandle(STD_INPUT_HANDLE); + if( (hStdout == INVALID_HANDLE_VALUE) || (hStdin == INVALID_HANDLE_VALUE) ){ + unlink(argv[0]); + return 0; + } +#endif + + /* read and filter events */ +#if USE_WIN32 + while((ReadFile(hStdin, &get, sizeof(int), &dwRead, NULL) >0) && + (dwRead == sizeof(int)) ){ +#else + while( read(0, &get, sizeof(int)) == sizeof(int) ){ +#endif +#if DO_FILTER_SWAP + switch(sizeof(int)){ + case 2: + _sw2((char *)&get,2,NULL,0); + break; + case 4: + _sw4((char *)&get,4,NULL,0); + break; + case 8: + _sw8((char *)&get,8,NULL,0); + break; + } +#endif + ebuf = (char *)calloc(get, sizeof(char)); +#if USE_WIN32 + for(n=0, etop=ebuf; get>0; etop += got, get -= dwRead){ + if((ReadFile(hStdin, etop, get, &dwRead, NULL)==FALSE) || (dwRead==0)) + break; + n += dwRead; + } +#else + for(n=0, etop=ebuf; get>0; etop += got, get -= got){ + if( (got=read(0, etop, get)) <=0 ) + break; + n += got; + } +#endif + n /= EVSIZE; + /* allocate return value buffer */ + rbuf = (int *)calloc(n, sizeof(int)); + /* filter events, with results going into rbuf */ + g = EVFILTRTN(g, ebuf, n, EVSIZE, rbuf); + /* write results */ + got = n*sizeof(int); +#if DO_FILTER_SWAP + sgot = got; + switch(sizeof(int)){ + case 2: + _sw2((char *)&sgot,2,NULL,0); + break; + case 4: + _sw4((char *)&sgot,4,NULL,0); + break; + case 8: + _sw8((char *)&sgot,8,NULL,0); + break; + } +#if USE_WIN32 + WriteFile(hStdout, &sgot, sizeof(int), &dwWritten, NULL); +#else + write(1, &sgot, sizeof(int)); +#endif +#else +#if USE_WIN32 + WriteFile(hStdout, &got, sizeof(int), &dwWritten, NULL); +#else + write(1, &got, sizeof(int)); +#endif +#endif +#if DO_FILTER_SWAP + switch(sizeof(int)){ + case 2: + _sw2((char *)rbuf,got,NULL,0); + break; + case 4: + _sw4((char *)rbuf,got,NULL,0); + break; + case 8: + _sw8((char *)rbuf,got,NULL,0); + break; + } +#endif +#if USE_WIN32 + WriteFile(hStdout, rbuf, got, &dwWritten, NULL); +#else + write(1, rbuf, got); +#endif + if( ebuf) free(ebuf); + if( rbuf ) free(rbuf); + } + EVFILTRTN(g, NULL, -1, 0, NULL); + unlink(argv[0]); + return 0; +} diff --git a/filter/evfilter.py b/filter/evfilter.py new file mode 100644 index 0000000..70e617c --- /dev/null +++ b/filter/evfilter.py @@ -0,0 +1,156 @@ +# load the funtools routines +_libname = './libfuntools.so.1.0' +libfuntools=cdll.LoadLibrary(_libname) +libc=cdll.LoadLibrary(None) + +# region definitions +imannulusi=libfuntools.imannulusi +imboxi=libfuntools.imboxi +imcirclei=libfuntools.imcirclei +imellipsei=libfuntools.imellipsei +imfieldi=libfuntools.imfieldi +imlinei=libfuntools.imlinei +impiei=libfuntools.impiei +imqtpiei=libfuntools.imqtpiei +impointi=libfuntools.impointi +impandai=libfuntools.impandai +imnannulusi=libfuntools.imnannulusi +imnboxi=libfuntools.imnboxi +imnellipsei=libfuntools.imnellipsei +imnpiei=libfuntools.imnpiei +impolygoni=libfuntools.impolygoni +imvannulusi=libfuntools.imvannulusi +imvboxi=libfuntools.imvboxi +imvellipsei=libfuntools.imvellipsei +imvpiei=libfuntools.imvpiei +imvpointi=libfuntools.imvpointi +imannulus=libfuntools.imannulus +imbox=libfuntools.imbox +imcircle=libfuntools.imcircle +imellipse=libfuntools.imellipse +imfield=libfuntools.imfield +imline=libfuntools.imline +impie=libfuntools.impie +imqtpie=libfuntools.imqtpie +impoint=libfuntools.impoint +impanda=libfuntools.impanda +imnannulus=libfuntools.imnannulus +imnbox=libfuntools.imnbox +imnellipse=libfuntools.imnellipse +imnpie=libfuntools.imnpie +impolygon=libfuntools.impolygon +imvannulus=libfuntools.imvannulus +imvbox=libfuntools.imvbox +imvellipse=libfuntools.imvellipse +imvpie=libfuntools.imvpie +imvpoint=libfuntools.imvpoint + +evannulus=libfuntools.evannulus +evbox=libfuntools.evbox +evcircle=libfuntools.evcircle +evellipse=libfuntools.evellipse +evfield=libfuntools.evfield +evline=libfuntools.evline +evpie=libfuntools.evpie +evqtpie=libfuntools.evqtpie +evpoint=libfuntools.evpoint +evnannulus=libfuntools.evnannulus +evnbox=libfuntools.evnbox +evnellipse=libfuntools.evnellipse +evnpie=libfuntools.evnpie +evpanda=libfuntools.evpanda +evpolygon=libfuntools.evpolygon +evvannulus=libfuntools.evvannulus +evvbox=libfuntools.evvbox +evvellipse=libfuntools.evvellipse +evvpie=libfuntools.evvpie +evvpoint=libfuntools.evvpoint + +evvcircle=libfuntools.evvannulus +evncircle=libfuntools.evnannulus +evcpanda=libfuntools.evpanda + +imvcirclei=libfuntools.imvannulusi +imncirclei=libfuntools.imnannulusi +imvcircle=libfuntools.imvannulus +imncircle=libfuntools.imnannulus +imcpandai=libfuntools.impandai +imcpanda=libfuntools.impanda + +# from regions.h -- no idea what it is ... +xsno=3 + +# ... but its important! +maxshapes=(nshape*(xsno+1))+1 + +# ctypes struct definitions (taken from filter.h) +class filtmask(Structure): + _fields_ = [('region', c_int), ('y', c_int), ('xstart', c_int), ('xstop', c_int)] + +class scanrec(Structure): + pass + +# this is how you add a forward pointer +scanrec._fields_ = [ ('next', POINTER(scanrec)), ('x', c_int) ] + +class shaperec(Structure): + _fields_ = [ ('init', c_int), ('ystart', c_double), ('ystop', c_double), ('scanlist', c_void_p), ('nv', c_int), ('xv', c_void_p), ('r1sq', c_double), ('r2sq', c_double), ('angl', c_double), ('sinangl', c_double), ('cosangl', c_double), ('cossq', c_double), ('sinsq', c_double), ('xradsq', c_double), ('yradsq', c_double), ('a', c_double), ('npt', c_int), ('pts', c_void_p), ('xonly', c_int), ('x1', c_double), ('x2', c_double), ('y1', c_double), ('invslope', c_double)] + +class gfiltrec(Structure): + _fields_ = [('nshapes', c_int), ('maxshapes', c_int), ('shapes', POINTER(shaperec * maxshapes)), ('rid', c_int), ('usebinsiz', c_int), ('evsect', c_char_p), ('tlminx', c_double), ('tlminy', c_double), ('binsizx', c_double), ('binsizy', c_double), ('tloff', c_double), ('xmin', c_int), ('xmax', c_int), ('ymin', c_int), ('ymax', c_int), ('block', c_int), ('x0', c_int), ('x1', c_int), ('y0', c_int), ('y1', c_int), ('ybuf', POINTER(c_int)), ('x0s', POINTER(c_int)), ('x1s', POINTER(c_int)), ('nmask', c_int), ('maskdim', c_int), ('masks', POINTER(filtmask))] + +# taken from the code in evfilter.c that initializes the g struct +# allocate shape record +shapearr = (shaperec * maxshapes)() +# allocate g record +grec = gfiltrec() +# fill in g record +grec.nshapes = nshape +grec.maxshapes = maxshapes +grec.shapes = pointer(shapearr) +# pointer to g record +g=pointer(grec) + +# # processing loop +# while True: +# rvals = '' +# buf = sys.stdin.read(4) +# if not buf: break +# vals = struct.unpack('=i', buf) +# nev = vals[0]/evsize +# for i in range(nev): +# evbuf = sys.stdin.read(evsize) +# rvals += struct.pack('=i', xfilter(evdef, evbuf)) +# sys.stdout.write(struct.pack('=i', nev*4)) +# sys.stdout.write(rvals) +# sys.stdout.flush() + +# processing loop +obytes = 0 +while True: + # get byte count + nval = c_int(0) + if libc.read(0, byref(nval), 4) != 4: break + bytes = nval.value + nev = bytes / evsize + + # create a new data buffer, if necessary + if obytes != bytes: + evbuf = create_string_buffer(bytes) + pevbuf = addressof(evbuf) + rvals = (c_int * nev)() + obytes = bytes + + # read data + if libc.read(0, evbuf, bytes) != bytes: break + + # process data + ioff = 0 + for i in range(nev): + rvals[i] = xfilter(evdef, evbuf[ioff:ioff+evsize]) + ioff += evsize + + # write result byte count and result data + nval = c_int(nev*4) + libc.write(1, byref(nval), 4) + libc.write(1, rvals, nval) diff --git a/filter/evregions.c b/filter/evregions.c new file mode 100644 index 0000000..2b28152 --- /dev/null +++ b/filter/evregions.c @@ -0,0 +1,1532 @@ +/* + NB: MAKE SURE YOU EDIT THE TEMPLATE FILE!!!! +*/ + +#ifndef FILTER_PTYPE +#include +#endif + + +#ifndef UNUSED +#ifdef __GNUC__ +# define UNUSED(x) UNUSED_ ## x __attribute__((__unused__)) +#else +# define UNUSED(x) UNUSED_ ## x +#endif +#endif + +/* panda and pie incorrectly used astronomical angles. fixed 4/2004 */ +#define USE_ASTRO_ANGLE 0 + +/* we might want to avoid (x86) extended precision problems */ +#define USE_FPU_DOUBLE 0 +#if USE_FPU_DOUBLE +#include +static fpu_control_t _cw; +#define FPU_DOUBLE {fpu_control_t _cw2; _FPU_GETCW(_cw); _cw2 = _cw & ~_FPU_EXTENDED; _cw2 |= _FPU_DOUBLE; _FPU_SETCW(_cw2);} +#define FPU_RESTORE {_FPU_SETCW(_cw);} +#else +#define FPU_DOUBLE +#define FPU_RESTORE +#endif + +/* alternate method of avoiding (x86) extended precision problems */ +#define USE_FLOAT_COMPARE 0 + +/* add this to FilterOpen to cause this module to be loaded for dynamic linking */ +static int evregno=0; +void initevregions(void) +{ + evregno++; + return; +} + +static int polypt(double x, double y, double* poly, int count, + double UNUSED(xstart), double ystart, int flag) +{ + /* x-- x value of point being tested */ + /* y-- y value of point being tested */ + /* poly-- bounding polygon, array of length (count*2) */ + /* count-- number of edges of bounding polygon */ + + /* This algorithm is from "An Introduction to Ray Tracing", Academic Press, */ + /* 1989, edited by Andrew Glassner, pg 53 */ + /* a point lies in a polygon if a line is extended from the point to infinite */ + /* in any direction and the number of intersections with the polygon is odd. */ + /* This is valid for both concave and convex polygons. */ + /* Points on a vertex are considered inside. */ + /* Points on a edge are considered inside. */ + + /* number of crossings */ + int crossings = 0; + + /* init sign for first vertice */ + int sign = ((poly[1] - y)>=0) ? 1 : -1; + + /* for all edges */ + int i; + + /* if flag is set, we check x, y against first point */ + if( flag && (x == poly[0]) && (y == poly[1]) ) return 1; + + for(i=0; i=0) ? 1 : -1; + + /* horiz line */ + if( (y1==0) && (y2==0) ){ + if( ((x2>=0) && (x1<=0)) || ((x1>=0) && (x2<=0)) ){ + /* we always return true for ystart horiz lines */ + if( y == ystart ) + return 1; + else + return fmod((double)crossings+1,2.0) ? 1 : 0; + } + } + /* vertical line */ + else if( (x1==0) && (x2==0) ){ + if( ((y2>=0) && (y1<=0)) || ((y1>=0) && (y2<=0)) ){ + return fmod((double)crossings+1,2.0) ? 1 : 0; + } + } + /* point on line */ + else if( feq((y1*(x2-x1)),(x1*(y2-y1))) ){ + if( (((x2>=0) && (x1<=0)) || ((x1>=0) && (x2<=0))) && + (((y2>=0) && (y1<=0)) || ((y1>=0) && (y2<=0))) ){ + return fmod((double)crossings+1,2.0) ? 1 : 0; + } + } +#if 0 + /* horiz line */ + if( (y1==0) && (y2==0) ){ + if( ((x2>=0) && (x1<=0)) || ((x1>=0) && (x2<=0)) ){ + if( y == ystart ){ + return 1; + } + } + } + /* vertical line */ + else if( (x1==0) && (x2==0) ){ + if( ((y2>=0) && (y1<=0)) || ((y1>=0) && (y2<=0)) ){ + if( x == xstart ){ + return 1; + } + } + } + /* point on line */ + else if( feq((y1*(x2-x1)),(x1*(y2-y1))) ){ + if( (((x2>=0) && (x1<=0)) || ((x1>=0) && (x2<=0))) && + (((y2>=0) && (y1<=0)) || ((y1>=0) && (y2<=0))) ){ + return 0; + } + } +#endif + if (sign != nextSign) { + if (x1>0 && x2>0) + crossings++; + else if (x1>0 || x2>0) { + if (x1-(y1*(x2-x1)/(y2-y1)) > 0) + crossings++; + } + sign = nextSign; + } + } + + return crossings%2 ? 1 : 0; /* if odd, point is inside */ +} + +static void quadeq(double a, double b, double c, + double *x1, double *x2, int *nr, int *nc) +{ + double dis, q; + if( feq(a,0.0) ){ + *nc = 0; + if( feq(b,0.0) ){ + *nr = 0; *x1 = 0.0; + } + else{ + *nr = 1; *x1 = -c / b; + } + *x2 = *x1; + } + else{ + dis = b*b - 4.0 * a * c; + if( dis > 0.0 ){ + *nr = 2; *nc = 0; + dis = sqrt(dis); + if( b < 0.0 ) dis = -dis; + q = -0.5 * (b + dis); + *x1 = q/a; *x2 = c/q; + if(*x1 > *x2){ + q = *x1; *x1 = *x2; *x2 = q; + } + } + else if( feq(dis,0.0) ){ + *nr = 1; *nc = 0; *x1 = - 0.5 * b / a; *x2 = *x1; + } + else{ + *nr = 0; *nc = 2; *x1 = - 0.5 * b / a; *x2 = 0.5 * sqrt(-dis) / a; + } + } +} + +static int corner_vertex(int index, int width, int height, + double *x, double *y) +{ + switch (index) { + case 1: + *x = 0.0; + *y = height + 1; + break; + case 2: + *x = 0.0; + *y = 0.0; + break; + case 3: + *x = width + 1; + *y = 0.0; + break; + case 4: + *x = width + 1; + *y = height + 1; + default: + break; + } + index = index + 1; + if(index > 4) index = 1; + return(index); +} + +static int pie_intercept(double width, double height, double xcen, double ycen, + double angle, double *xcept, double *ycept) +{ + double angl, slope; /* l: angle and slope of ray */ + angl = angle; + /* put angles in normal range */ + while (angl < 0.0) + angl = angl + 360.0; + while (angl >= 360.0) + angl = angl - 360.0; + /* check for a horizontal angle */ +#if USE_ASTRO_ANGLE + if(fabs(angl - 90.0) < SMALL_NUMBER) { +#else + if(fabs(angl - 180.0) < SMALL_NUMBER) { +#endif + *xcept = 0.0; + *ycept = ycen; + return(2); + } +#if USE_ASTRO_ANGLE + if(fabs(angl - 270.0) < SMALL_NUMBER) { +#else + if(fabs(angl - 0.0) < SMALL_NUMBER) { +#endif + *xcept = width + 1; + *ycept = ycen; + return(4); + } + /* convert to a Cartesian angle */ +#if USE_ASTRO_ANGLE + angl = angl + 90.0; +#endif + if(angl >= 360.0) + angl = angl - 360.0; + if(angl < 180.0) { + *ycept = height + 1; + /* rule out vertical line */ + if(fabs(angl - 90.0) < SMALL_NUMBER) { + *xcept = xcen; + return(1); + } + } else { + *ycept = 0.0; + /* rule out vertical line */ + if(fabs(angl - 270.0) < SMALL_NUMBER) { + *xcept = xcen; + return(3); + } + } + /* convert to radians */ + angl = (angl / 180.0) * M_PI; + /* calculate slope */ + slope = tan(angl); + /* calculate intercept with designated y edge */ + *xcept = xcen + ((*ycept - ycen) / slope); + if(*xcept < 0) { + *ycept = (ycen - (xcen * slope)); + *xcept = 0.0; + return(2); + } else if(*xcept > (width + 1)) { + *ycept = (ycen + ((width + 1 - xcen) * slope)); + *xcept = width + 1; + return(4); + } else { + if(*ycept < height) + return(3); + else + return(1); + } +} + +/* ***************************** shapes ********************************** */ + +int evannulus(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, double ri, double ro) +{ + /* use circle if possible */ + if( ri == 0 ){ + return(evcircle(g, rno, sno, flag, type, x, y, xcen, ycen, ro)); + } + + if( !g->shapes[sno].init ){ + g->shapes[sno].init = 1; + g->shapes[sno].ystart = ycen - ro; + g->shapes[sno].ystop = ycen + ro; + g->shapes[sno].r1sq = ri * ri; + g->shapes[sno].r2sq = ro * ro; + } + + if((((y>=g->shapes[sno].ystart) && (y<=g->shapes[sno].ystop)) && + (((xcen-x)*(xcen-x))+((ycen-y)*(ycen-y))<=g->shapes[sno].r2sq) && + (((xcen-x)*(xcen-x))+((ycen-y)*(ycen-y))>g->shapes[sno].r1sq)) == flag ){ + if( rno && flag ) g->rid = rno; + return 1; + } + else{ + return 0; + } +} + +int evbox(GFilt g, int rno, int sno, int flag, int UNUSED(type), + double x, double y, + double xcen, double ycen, double xwidth, double yheight, + double angle) +{ + int i; + double angl; /* l: Cartesian angle in radians */ + double half_width, half_height;/* l: radii (1/2 width and height) */ + double cosangl, sinangl; /* l: sine, cosine of the Cartesian angle */ + double hw_cos, hw_sin; /* l: products of half_width with sin, cos */ + double hh_cos, hh_sin; /* l: products of half_height with sin, cos */ + double xstart=0.0; + + if( (xwidth == 0) && (yheight==0) ){ + return(!flag); + } + if( !g->shapes[sno].init ){ + g->shapes[sno].init = 1; +#if USE_ASTRO_ANGLE + /* convert to a Cartesian angle; save angle for use in multi or slices */ + angl = angle + 90.0; +#else + angl = angle; +#endif + while (angl >= 360.0) angl = angl - 360.0; + /* convert to radians */ + angl = (angl / 180.0) * M_PI; + sinangl = sin (angl); + cosangl = cos (angl); +#if USE_ASTRO_ANGLE + /* since we rotate by 90.0 degrees to get from astro angle to cartesian, */ + /* we also need to switch the width and height. we do this secretly so */ + /* that the display will turn out right, by doing it in the half terms */ + half_width = yheight / 2.0; + half_height = xwidth / 2.0; +#else + half_width = xwidth / 2.0; + half_height = yheight / 2.0; +#endif + hw_cos = half_width * cosangl; + hw_sin = half_width * sinangl; + hh_cos = half_height * cosangl; + hh_sin = half_height * sinangl; + g->shapes[sno].pts = (double *)calloc(8, sizeof(double)); +#if USE_ASTRO_ANGLE + g->shapes[sno].pts[0] = xcen - hw_cos - hh_sin; + g->shapes[sno].pts[1] = ycen - hw_sin + hh_cos; + g->shapes[sno].pts[2] = xcen + hw_cos - hh_sin; + g->shapes[sno].pts[3] = ycen + hw_sin + hh_cos; + g->shapes[sno].pts[4] = xcen + hw_cos + hh_sin; + g->shapes[sno].pts[5] = ycen + hw_sin - hh_cos; + g->shapes[sno].pts[6] = xcen - hw_cos + hh_sin; + g->shapes[sno].pts[7] = ycen - hw_sin - hh_cos; +#else + g->shapes[sno].pts[0] = xcen - hw_cos + hh_sin; + g->shapes[sno].pts[1] = ycen - hh_cos - hw_sin; + g->shapes[sno].pts[2] = xcen - hw_cos - hh_sin; + g->shapes[sno].pts[3] = ycen + hh_cos - hw_sin; + g->shapes[sno].pts[4] = xcen + hw_cos - hh_sin; + g->shapes[sno].pts[5] = ycen + hh_cos + hw_sin; + g->shapes[sno].pts[6] = xcen + hw_cos + hh_sin; + g->shapes[sno].pts[7] = ycen - hh_cos + hw_sin; +#endif + g->shapes[sno].npt = 8; + /* now find the y limits */ + if( g->shapes[sno].npt ){ + xstart = g->shapes[sno].pts[0]; + g->shapes[sno].ystart = g->shapes[sno].pts[1]; + g->shapes[sno].ystop = g->shapes[sno].ystart; + for(i=1; ishapes[sno].npt; i+=2){ + if(g->shapes[sno].pts[i-1] < xstart) + xstart = g->shapes[sno].pts[i-1]; + if(g->shapes[sno].pts[i] > g->shapes[sno].ystop) + g->shapes[sno].ystop = g->shapes[sno].pts[i]; + if(g->shapes[sno].pts[i] < g->shapes[sno].ystart) + g->shapes[sno].ystart = g->shapes[sno].pts[i]; + } + } + } + if( (((y>=g->shapes[sno].ystart) && (y<=g->shapes[sno].ystop)) && + polypt(x, y, g->shapes[sno].pts, g->shapes[sno].npt/2, + xstart, g->shapes[sno].ystart, 0)) == flag ){ + if( rno && flag ) g->rid = rno; + return 1; + } + else + return 0; +} + +int evcircle(GFilt g, int rno, int sno, int flag, int UNUSED(type), + double x, double y, + double xcen, double ycen, double radius) +{ + if( radius == 0 ){ + return(!flag); + } + if( !g->shapes[sno].init ){ + g->shapes[sno].init = 1; + g->shapes[sno].ystart = ycen - radius; + g->shapes[sno].ystop = ycen + radius; + g->shapes[sno].r1sq = radius * radius; + } + if( (((y>=g->shapes[sno].ystart) && (y<=g->shapes[sno].ystop)) && + (((xcen-x)*(xcen-x))+((ycen-y)*(ycen-y))<=g->shapes[sno].r1sq)) == flag ){ + if( rno && flag ) g->rid = rno; + return 1; + } + else + return 0; +} + +int evellipse(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, double xrad, double yrad, double angle) +{ + double yhi, yoff; + double b, c; + double b_partial, c_partial; + double xboff, xfoff; + int nr, nc; + + /* use circle if possible */ + if( xrad == yrad ){ + return(evcircle(g, rno, sno, flag, type, x, y, xcen, ycen, xrad)); + } + + if( !g->shapes[sno].init ){ + g->shapes[sno].init = 1; + /* set worst case limits (xrad axis parallel to vertical axis) */ +#if USE_ASTRO_ANGLE + /* convert to a Cartesian angle; save "angle" for use by other routines */ + g->shapes[sno].angl = angle + 90.0; +#else + g->shapes[sno].angl = angle; +#endif + while( g->shapes[sno].angl >= 360.0 ) + g->shapes[sno].angl = g->shapes[sno].angl - 360.0; + /* convert to radians */ + g->shapes[sno].angl = (g->shapes[sno].angl / 180.0) * M_PI; + g->shapes[sno].sinangl = sin(g->shapes[sno].angl); + g->shapes[sno].cosangl = cos(g->shapes[sno].angl); + /* calculate approximate y limits */ + /* choose lesser of containing rotbox and circle */ +#if USE_ASTRO_ANGLE + yhi = fabs(g->shapes[sno].sinangl * yrad) + + fabs(g->shapes[sno].cosangl * xrad); +#else + yhi = fabs(g->shapes[sno].sinangl * xrad) + + fabs(g->shapes[sno].cosangl * yrad); +#endif + yhi = min(yhi, max(yrad, xrad)); + g->shapes[sno].ystart = ycen - yhi; + g->shapes[sno].ystop = ycen + yhi; + /* prepare partials for quadratic equation solutions to coordinates */ + g->shapes[sno].cossq = g->shapes[sno].cosangl * g->shapes[sno].cosangl; + g->shapes[sno].sinsq = g->shapes[sno].sinangl * g->shapes[sno].sinangl; +#if USE_ASTRO_ANGLE + /* because we rotate by 90.0 degrees to get from astro angle to */ + /* cartesian, we also need to switch the x and y axes. we do this */ + /* secretly so that the display will turn out right, by doing it in */ + /* the sq terms */ + g->shapes[sno].xradsq = yrad * yrad; + g->shapes[sno].yradsq = xrad * xrad; +#else + g->shapes[sno].xradsq = xrad * xrad; + g->shapes[sno].yradsq = yrad * yrad; +#endif + /* fill in as much of a,b,c as we can */ + g->shapes[sno].a = (g->shapes[sno].cossq / g->shapes[sno].xradsq) + + (g->shapes[sno].sinsq / g->shapes[sno].yradsq); + } + if( ((y>=g->shapes[sno].ystart) && (y<=g->shapes[sno].ystop)) ){ + b_partial = (2.0 * g->shapes[sno].sinangl) * + ((g->shapes[sno].cosangl / g->shapes[sno].xradsq) - + (g->shapes[sno].cosangl / g->shapes[sno].yradsq)); + c_partial = (g->shapes[sno].sinsq / g->shapes[sno].xradsq) + + (g->shapes[sno].cossq / g->shapes[sno].yradsq); + yoff = y - ycen; + b = b_partial * yoff; + c = (c_partial * yoff * yoff) - 1.0; + /* solve quadratic */ + quadeq (g->shapes[sno].a, b, c, &xboff, &xfoff, &nr, &nc); + /* if real roots */ + if( nr != 0 ) { + FPU_DOUBLE +#if USE_FLOAT_COMPARE + if( (((float)x>=(float)(xcen+xboff)) && + ((float)x<=(float)(xcen+xfoff))) == flag ){ +#else + if( ((x>=(xcen+xboff)) && (x<=(xcen+xfoff))) == flag ){ +#endif + if( rno && flag ) g->rid = rno; + FPU_RESTORE + return 1; + } + else{ + FPU_RESTORE + return 0; + } + } + else + return !flag; + } + return !flag; +} + +int evfield(GFilt g, int rno, int UNUSED(sno), int flag, int UNUSED(type), + double UNUSED(x), double UNUSED(y)) +{ + if( flag ){ + if( rno && flag ) g->rid = rno; + return 1; + } + else + return 0; +} + +int evline(GFilt g, int rno, int sno, int flag, int UNUSED(type), + double x, double y, + double x1, double y1, double x2, double y2) +{ + if( !g->shapes[sno].init ){ + g->shapes[sno].init = 1; + g->shapes[sno].ystart = min(y1,y2); + g->shapes[sno].ystop = max(y1,y2); + g->shapes[sno].x1 = x1; + g->shapes[sno].x2 = x2; + g->shapes[sno].y1 = y1; + if( feq(y1,y2) ){ + g->shapes[sno].xonly = 1; + g->shapes[sno].invslope = 0; + } + else{ + g->shapes[sno].xonly = 0; + g->shapes[sno].invslope = (x1 - x2) / (y1 - y2); + } + } + if( (((y>=g->shapes[sno].ystart) && (y<=g->shapes[sno].ystop)) && + ((!g->shapes[sno].xonly && + feq((((y-g->shapes[sno].y1)*g->shapes[sno].invslope)+g->shapes[sno].x1),x)) || + (g->shapes[sno].xonly && + ((x>=g->shapes[sno].x1)&&(x<=g->shapes[sno].x2))))) == flag){ + if( rno && flag ) g->rid = rno; + return 1; + } + else + return 0; +} + +int evpie(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, double angle1, double angle2) +{ + int i; + int width, height; /* l: image mask width and height */ + double sweep; /* l: sweep between cut angles */ + int intrcpt1, intrcpt2; /* l: side intercepted by each cut */ + double x2, y2; /* l: coordinates of second intercept */ + double xstart=0.0; + + /* use field if possible */ + if( (angle1==0) && (angle2==360) ){ + return(evfield(g, rno, sno, flag, type, x, y)); + } + + if( !g->shapes[sno].init ){ + g->shapes[sno].init = 1; + /* we have to fake width and height, since we do not know them! */ + width = LARGE_NUMBER; + height = LARGE_NUMBER; + /* start listing vertices of polygon */ + g->shapes[sno].pts = (double *)calloc(14, sizeof(double)); + g->shapes[sno].pts[0] = xcen; + g->shapes[sno].pts[1] = ycen; + sweep = angle2 - angle1; + /* if sweep is too small to be noticed, don't bother */ + if(fabs(sweep) < SMALL_NUMBER) + return !flag; + if (sweep < 0.0) sweep = sweep + 360.0; + intrcpt1 = pie_intercept((double)width, (double)height, xcen, ycen, angle1, + &(g->shapes[sno].pts[2]), + &(g->shapes[sno].pts[3])); + intrcpt2 = pie_intercept((double)width, (double)height, xcen, ycen, angle2, + &x2, &y2); + g->shapes[sno].npt = 4; + /* if angles intercept same side and slice is between them, no corners */ + /* else, mark corners until reaching side with second angle intercept */ + if((intrcpt1 != intrcpt2) || (sweep > 180.0)){ + do{ + intrcpt1 = corner_vertex(intrcpt1, width, height, + &(g->shapes[sno].pts[g->shapes[sno].npt]), + &(g->shapes[sno].pts[g->shapes[sno].npt+1])); + g->shapes[sno].npt = g->shapes[sno].npt + 2; + }while(intrcpt1 != intrcpt2); + } + g->shapes[sno].pts[g->shapes[sno].npt] = x2; + g->shapes[sno].pts[g->shapes[sno].npt+1] = y2; + g->shapes[sno].npt = g->shapes[sno].npt + 2; + /* now find the y limits */ + if( g->shapes[sno].npt ){ + xstart = g->shapes[sno].pts[0]; + g->shapes[sno].ystart = g->shapes[sno].pts[1]; + g->shapes[sno].ystop = g->shapes[sno].ystart; + for(i=1; ishapes[sno].npt; i+=2){ + if(g->shapes[sno].pts[i-1] < xstart) + xstart = g->shapes[sno].pts[i-1]; + if(g->shapes[sno].pts[i] > g->shapes[sno].ystop) + g->shapes[sno].ystop = g->shapes[sno].pts[i]; + if(g->shapes[sno].pts[i] < g->shapes[sno].ystart) + g->shapes[sno].ystart = g->shapes[sno].pts[i]; + } + } + } + if( (((y>=g->shapes[sno].ystart) && (y<=g->shapes[sno].ystop)) && + polypt(x, y, g->shapes[sno].pts, g->shapes[sno].npt/2, + xstart, g->shapes[sno].ystart, 1)) == flag ){ + if( rno && flag ) g->rid = rno; + return 1; + } + else{ + return 0; + } +} + +int evqtpie(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, double angle1, double angle2) +{ + return evpie(g, rno, sno, flag, type, x, y, xcen, ycen, angle1, angle2); +} + +int evpoint(GFilt g, int rno, int UNUSED(sno), int flag, int UNUSED(type), + double x, double y, + double xcen, double ycen) +{ + if( ((x==xcen) && (y==ycen)) == flag ){ + if( rno && flag ) g->rid = rno; + return 1; + } + else + return 0; +} + +#ifdef __STDC__ +int +evpolygon(GFilt g, int rno, int sno, int flag, int UNUSED(type), + double x, double y, ...) +{ + int i, maxpts; + double xstart=0.0; + va_list args; + va_start(args, y); +#else +int evpolygon(va_alist) va_dcl +{ + GFilt g; + int rno, sno, flag, type; + double x, y; + double xstart=0.0; + int i, maxpts; + va_list args; + va_start(args); + g = va_arg(args, GFilt); + rno = va_arg(args, int); + sno = va_arg(args, int); + flag = va_arg(args, int); + type = va_arg(args, int); + x = va_arg(args, double); + y = va_arg(args, double); +#endif + if( !g->shapes[sno].init ){ + g->shapes[sno].init = 1; + /* allocate space for x,y arguments */ + maxpts = MASKINC; + g->shapes[sno].pts = (double *)calloc(maxpts, sizeof(double)); + /* gather up arguments */ + g->shapes[sno].npt = 0; + while( 1 ){ + if( g->shapes[sno].npt >= maxpts ){ + maxpts += MASKINC; + g->shapes[sno].pts = (double *)realloc(g->shapes[sno].pts, + maxpts*sizeof(double)); + } + g->shapes[sno].pts[g->shapes[sno].npt] = va_arg(args, double); + /* two negatives in a row means we are at end of args */ + if( feq(g->shapes[sno].pts[g->shapes[sno].npt],PSTOP) && + feq(g->shapes[sno].pts[g->shapes[sno].npt-1],PSTOP) ){ + g->shapes[sno].npt--; + break; + } + g->shapes[sno].npt++; + } + va_end(args); + /* realloc to actual size */ + g->shapes[sno].pts = (double *)realloc(g->shapes[sno].pts, + g->shapes[sno].npt*sizeof(double)); + /* now find the y limits */ + if( g->shapes[sno].npt ){ + xstart = g->shapes[sno].pts[0]; + g->shapes[sno].ystart = g->shapes[sno].pts[1]; + g->shapes[sno].ystop = g->shapes[sno].ystart; + for(i=1; ishapes[sno].npt; i+=2){ + if(g->shapes[sno].pts[i-1] < xstart) + xstart = g->shapes[sno].pts[i-1]; + if(g->shapes[sno].pts[i] > g->shapes[sno].ystop) + g->shapes[sno].ystop = g->shapes[sno].pts[i]; + if(g->shapes[sno].pts[i] < g->shapes[sno].ystart) + g->shapes[sno].ystart = g->shapes[sno].pts[i]; + } + } + } + if( (((y>=g->shapes[sno].ystart) && (y<=g->shapes[sno].ystop)) && + polypt(x, y, g->shapes[sno].pts, g->shapes[sno].npt/2, + xstart, g->shapes[sno].ystart, 0)) == flag ){ + if( rno && flag ) g->rid = rno; + return 1; + } + else + return 0; +} + +/* accelerator regions -- lower and upper limits are given for n regions */ + +int evnannulus(GFilt g, int rno, int sno, int flag, int type, + double x, double y, double xcen, double ycen, + double lo, double hi, int n) +{ + int i; + int xsno; + double dinc; + + /* get limits */ + dinc = (hi - lo)/(double)n; + xsno = (g->nshapes+1)+((sno-1)*XSNO); + if( flag ){ + /* if its not somewhere inside the entire region we lose ... */ + if( !evannulus(g, 0, xsno, flag, type, x, y, xcen, ycen, lo, hi) ){ + return(0); + } + /* look through all of them to find the right one */ + for(i=0; inshapes+1)+((sno-1)*XSNO); + if( flag ){ + /* if its not somewhere inside the entire region we lose ... */ + if( !evbox(g, 0, xsno, flag, type, x, y, xcen, ycen, hix, hiy, ang) ){ + return(0); + } + /* if its in the inner region we lose */ + if( evbox(g, 0, xsno+1, flag, type, x, y, xcen, ycen, lox, loy, ang) ){ + return(0); + } + /* look through all of them to find the right one */ + for(i=0; inshapes+1)+((sno-1)*XSNO); + if( flag ){ + /* if its not somewhere inside the entire region we lose ... */ + if( !evellipse(g, 0, xsno, flag, type, x, y, xcen, ycen, hix, hiy, ang) ){ + return(0); + } + /* if its in the inner region we lose */ + if( evellipse(g, 0, xsno+1, flag, type, x, y, xcen, ycen, lox, loy, ang) ){ + return(0); + } + /* look through all of them to find the right one */ + for(i=0; i hi ) lo -= 360.0; + dinc = (hi - lo)/n; + xsno = (g->nshapes+1)+((sno-1)*XSNO); + if( flag ){ + /* check limits */ + if( !evpie(g, 0, xsno, flag, type, x, y, xcen, ycen, lo, hi) ){ + return(0); + } + /* look through all of them to find the right one */ + for(i=0; inshapes+1)+((sno-1)*XSNO); + if( flag ){ + /* if its not somewhere inside the entire region we lose ... */ + if( !evannulus(g, 0, xsno, flag, type, x, y, xcen, ycen, radlo, radhi) || + !evpie(g, 0, xsno+1, flag, type, x, y, xcen, ycen, anglo, anghi) ){ + return(0); + } + /* look through all of them to find the right one */ + for(a=1; a<=ahi; a++){ + for(r=1; r<=rhi; r++){ + if( evannulus(g, rno+n, sno+(2*n), flag, type, x, y, + xcen, ycen, radlo+((r-1)*rinc), radlo+(r*rinc)) && + evpie(g, rno+n, sno+(2*n+1), flag, type, x, y, + xcen, ycen, anglo+((a-1)*ainc), anglo+(a*ainc)) ){ + return(1); + } + n++; + } + } + return(0); + } + else{ + /* if its not somewhere inside the entire region we win ... */ + if( !evannulus(g, 0, xsno, 1, type, x, y, xcen, ycen, radlo, radhi) ) + return(1); + else if( !evpie(g, 0, xsno+1, 1, type, x, y, xcen, ycen, anglo, anghi) ){ + return(1); + } + else{ + return(0); + } + } +} + +int evbpanda(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, + double anglo, double anghi, double angn, + double xlo, double ylo, double xhi, double yhi, double radn, + double ang) +{ + + int a, r; + int ahi, rhi; + int xsno; + int n=0; + double ainc, xinc, yinc; + + /* get limits */ + anglo += ang; + anghi += ang; + ainc = (anghi - anglo)/angn; + ahi = (int)angn; + xinc = (xhi - xlo)/radn; + yinc = (yhi - ylo)/radn; + rhi = (int)radn; + xsno = (g->nshapes+1)+((sno-1)*XSNO); + if( flag ){ + /* if its not somewhere inside the entire region we lose ... */ + if( !evbox(g, 0, xsno, flag, type, x, y, xcen, ycen, xhi, yhi, + ang) ){ + return(0); + } + /* but if its in the inner region we lose */ + else if( evbox(g, 0, xsno+2, flag, type, x, y, xcen, ycen, xlo, ylo, + ang) ){ + return(0); + } + /* its in the box .. must also be in the pie */ + else if( !evpie(g, 0, xsno+1, flag, type, x, y, xcen, ycen, anglo, anghi)){ + return(0); + } + /* look through all of them to find the right one */ + for(a=0; anshapes+1)+((sno-1)*XSNO); + if( flag ){ + /* if its not somewhere inside the entire region we lose ... */ + if( !evellipse(g, 0, xsno, flag, type, x, y, xcen, ycen, xhi, yhi, + ang) ){ + return(0); + } + /* but if its in the inner region we lose */ + else if( evellipse(g, 0, xsno+2, flag, type, x, y, xcen, ycen, xlo, ylo, + ang) ){ + return(0); + } + /* its in the ellipse .. must also be in the pie */ + else if( !evpie(g, 0, xsno+1, flag, type, x, y, xcen, ycen, anglo, anghi)){ + return(0); + } + /* look through all of them to find the right one */ + for(a=0; anshapes+1)+((sno-1)*XSNO); + if( !g->shapes[xsno].xv ){ + maxpts = MASKINC; + g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double)); + g->shapes[xsno].nv = 0; + while( 1 ){ + if( g->shapes[xsno].nv >= maxpts ){ + maxpts += MASKINC; + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + maxpts*sizeof(double)); + } + g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double); + if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) && + feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){ + g->shapes[xsno].nv--; + break; + } + g->shapes[xsno].nv++; + } + va_end(args); + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + g->shapes[xsno].nv*sizeof(double)); + } + n = g->shapes[xsno].nv; + xv = g->shapes[xsno].xv; + /* this should be impossible ... */ + if( n == 2 ){ + return(evannulus(g, rno, sno, flag, type, x, y, xcen, ycen, xv[0], xv[1])); + } + if( flag ){ + /* if its not somewhere inside the entire region we lose ... */ + if( !evannulus(g, 0, xsno, flag, type, x, y, xcen, ycen, xv[0], xv[n-1]) ){ + return(0); + } + /* look through all of them to find the right one */ + for(i=0; inshapes+1)+((sno-1)*XSNO); + if( !g->shapes[xsno].xv ){ + maxpts = MASKINC; + g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double)); + g->shapes[xsno].nv = 0; + while( 1 ){ + if( g->shapes[xsno].nv >= maxpts ){ + maxpts += MASKINC; + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + maxpts*sizeof(double)); + } + g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double); + if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) && + feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){ + g->shapes[xsno].nv--; + break; + } + g->shapes[xsno].nv++; + } + va_end(args); + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + g->shapes[xsno].nv*sizeof(double)); + } + n = g->shapes[xsno].nv; + xv = g->shapes[xsno].xv; + ang = xv[--n]; + /* this should be impossible ... */ + if( n == 2 ){ + return(evbox(g, rno, sno, flag, type, x, y, + xcen, ycen, xv[0], xv[1], ang)); + } + if( flag ){ + /* if its not somewhere inside the entire region we lose ... */ + if( !evbox(g, 0, xsno, flag, type, x, y, xcen, ycen, xv[n-2], xv[n-1], + ang) ){ + return(0); + } + /* if its in the inner region we lose */ + if( evbox(g, 0, xsno+1, flag, type, x, y, xcen, ycen, xv[0], xv[1], ang) ){ + return(0); + } + /* look through all of them to find the right one */ + for(i=2, j=0; inshapes+1)+((sno-1)*XSNO); + if( !g->shapes[xsno].xv ){ + maxpts = MASKINC; + g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double)); + g->shapes[xsno].nv = 0; + while( 1 ){ + if( g->shapes[xsno].nv >= maxpts ){ + maxpts += MASKINC; + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + maxpts*sizeof(double)); + } + g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double); + if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) && + feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){ + g->shapes[xsno].nv--; + break; + } + g->shapes[xsno].nv++; + } + va_end(args); + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + g->shapes[xsno].nv*sizeof(double)); + } + n = g->shapes[xsno].nv; + xv = g->shapes[xsno].xv; + ang = xv[--n]; + /* this should be impossible ... */ + if( n == 2 ){ + return(evellipse(g, rno, sno, flag, type, x, y, + xcen, ycen, xv[0], xv[1], ang)); + } + if( flag ){ + /* if its not somewhere inside the entire region we lose ... */ + if( !evellipse(g, 0, xsno, flag, type, x, y, xcen, ycen, xv[n-2], xv[n-1], + ang) ){ + return(0); + } + /* if its in the inner region we lose */ + if( evellipse(g, 0, xsno+1, flag, type, x, y, xcen, ycen, xv[0], xv[1], + ang) ){ + return(0); + } + /* look through all of them to find the right one */ + for(i=2, j=0; inshapes+1)+((sno-1)*XSNO); + if( !g->shapes[xsno].xv ){ + maxpts = MASKINC; + g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double)); + g->shapes[xsno].nv = 0; + while( 1 ){ + if( g->shapes[xsno].nv >= maxpts ){ + maxpts += MASKINC; + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + maxpts*sizeof(double)); + } + g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double); + if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) && + feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){ + g->shapes[xsno].nv--; + break; + } + g->shapes[xsno].nv++; + } + va_end(args); + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + g->shapes[xsno].nv*sizeof(double)); + } + n = g->shapes[xsno].nv; + xv = g->shapes[xsno].xv; + /* this should be impossible ... */ + if( n == 2 ){ + return(evpie(g, rno, sno, flag, type, x, y, + xcen, ycen, xv[0], xv[1])); + } + if( flag ){ + /* if its not somewhere inside the entire region we lose ... */ + if( !evpie(g, 0, xsno, flag, type, x, y, xcen, ycen, xv[0], xv[n-1]) ){ + return(0); + } + /* look through all of them to find the right one */ + for(i=0; inshapes+1)+((sno-1)*XSNO); + if( !g->shapes[xsno].xv ){ + maxpts = MASKINC; + g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double)); + g->shapes[xsno].nv = 0; + while( 1 ){ + if( g->shapes[xsno].nv >= maxpts ){ + maxpts += MASKINC; + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + maxpts*sizeof(double)); + } + g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double); + if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) && + feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){ + g->shapes[xsno].nv--; + break; + } + g->shapes[xsno].nv++; + } + va_end(args); + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + g->shapes[xsno].nv*sizeof(double)); + } + n = g->shapes[xsno].nv; + xv = g->shapes[xsno].xv; + /* look through all of them to find the right one */ + for(i=0, j=0; i +#endif + + +#ifndef UNUSED +#ifdef __GNUC__ +# define UNUSED(x) UNUSED_ ## x __attribute__((__unused__)) +#else +# define UNUSED(x) UNUSED_ ## x +#endif +#endif + +/* panda and pie incorrectly used astronomical angles. fixed 4/2004 */ +#define USE_ASTRO_ANGLE 0 + +/* we might want to avoid (x86) extended precision problems */ +#define USE_FPU_DOUBLE _FPUDBL_ +#if USE_FPU_DOUBLE +#include +static fpu_control_t _cw; +#define FPU_DOUBLE {fpu_control_t _cw2; _FPU_GETCW(_cw); _cw2 = _cw & ~_FPU_EXTENDED; _cw2 |= _FPU_DOUBLE; _FPU_SETCW(_cw2);} +#define FPU_RESTORE {_FPU_SETCW(_cw);} +#else +#define FPU_DOUBLE +#define FPU_RESTORE +#endif + +/* alternate method of avoiding (x86) extended precision problems */ +#define USE_FLOAT_COMPARE 0 + +/* add this to FilterOpen to cause this module to be loaded for dynamic linking */ +static int evregno=0; +void initevregions(void) +{ + evregno++; + return; +} + +static int polypt(double x, double y, double* poly, int count, + double UNUSED(xstart), double ystart, int flag) +{ + /* x-- x value of point being tested */ + /* y-- y value of point being tested */ + /* poly-- bounding polygon, array of length (count*2) */ + /* count-- number of edges of bounding polygon */ + + /* This algorithm is from "An Introduction to Ray Tracing", Academic Press, */ + /* 1989, edited by Andrew Glassner, pg 53 */ + /* a point lies in a polygon if a line is extended from the point to infinite */ + /* in any direction and the number of intersections with the polygon is odd. */ + /* This is valid for both concave and convex polygons. */ + /* Points on a vertex are considered inside. */ + /* Points on a edge are considered inside. */ + + /* number of crossings */ + int crossings = 0; + + /* init sign for first vertice */ + int sign = ((poly[1] - y)>=0) ? 1 : -1; + + /* for all edges */ + int i; + + /* if flag is set, we check x, y against first point */ + if( flag && (x == poly[0]) && (y == poly[1]) ) return 1; + + for(i=0; i=0) ? 1 : -1; + + /* horiz line */ + if( (y1==0) && (y2==0) ){ + if( ((x2>=0) && (x1<=0)) || ((x1>=0) && (x2<=0)) ){ + /* we always return true for ystart horiz lines */ + if( y == ystart ) + return 1; + else + return fmod((double)crossings+1,2.0) ? 1 : 0; + } + } + /* vertical line */ + else if( (x1==0) && (x2==0) ){ + if( ((y2>=0) && (y1<=0)) || ((y1>=0) && (y2<=0)) ){ + return fmod((double)crossings+1,2.0) ? 1 : 0; + } + } + /* point on line */ + else if( feq((y1*(x2-x1)),(x1*(y2-y1))) ){ + if( (((x2>=0) && (x1<=0)) || ((x1>=0) && (x2<=0))) && + (((y2>=0) && (y1<=0)) || ((y1>=0) && (y2<=0))) ){ + return fmod((double)crossings+1,2.0) ? 1 : 0; + } + } +#if 0 + /* horiz line */ + if( (y1==0) && (y2==0) ){ + if( ((x2>=0) && (x1<=0)) || ((x1>=0) && (x2<=0)) ){ + if( y == ystart ){ + return 1; + } + } + } + /* vertical line */ + else if( (x1==0) && (x2==0) ){ + if( ((y2>=0) && (y1<=0)) || ((y1>=0) && (y2<=0)) ){ + if( x == xstart ){ + return 1; + } + } + } + /* point on line */ + else if( feq((y1*(x2-x1)),(x1*(y2-y1))) ){ + if( (((x2>=0) && (x1<=0)) || ((x1>=0) && (x2<=0))) && + (((y2>=0) && (y1<=0)) || ((y1>=0) && (y2<=0))) ){ + return 0; + } + } +#endif + if (sign != nextSign) { + if (x1>0 && x2>0) + crossings++; + else if (x1>0 || x2>0) { + if (x1-(y1*(x2-x1)/(y2-y1)) > 0) + crossings++; + } + sign = nextSign; + } + } + + return crossings%2 ? 1 : 0; /* if odd, point is inside */ +} + +static void quadeq(double a, double b, double c, + double *x1, double *x2, int *nr, int *nc) +{ + double dis, q; + if( feq(a,0.0) ){ + *nc = 0; + if( feq(b,0.0) ){ + *nr = 0; *x1 = 0.0; + } + else{ + *nr = 1; *x1 = -c / b; + } + *x2 = *x1; + } + else{ + dis = b*b - 4.0 * a * c; + if( dis > 0.0 ){ + *nr = 2; *nc = 0; + dis = sqrt(dis); + if( b < 0.0 ) dis = -dis; + q = -0.5 * (b + dis); + *x1 = q/a; *x2 = c/q; + if(*x1 > *x2){ + q = *x1; *x1 = *x2; *x2 = q; + } + } + else if( feq(dis,0.0) ){ + *nr = 1; *nc = 0; *x1 = - 0.5 * b / a; *x2 = *x1; + } + else{ + *nr = 0; *nc = 2; *x1 = - 0.5 * b / a; *x2 = 0.5 * sqrt(-dis) / a; + } + } +} + +static int corner_vertex(int index, int width, int height, + double *x, double *y) +{ + switch (index) { + case 1: + *x = 0.0; + *y = height + 1; + break; + case 2: + *x = 0.0; + *y = 0.0; + break; + case 3: + *x = width + 1; + *y = 0.0; + break; + case 4: + *x = width + 1; + *y = height + 1; + default: + break; + } + index = index + 1; + if(index > 4) index = 1; + return(index); +} + +static int pie_intercept(double width, double height, double xcen, double ycen, + double angle, double *xcept, double *ycept) +{ + double angl, slope; /* l: angle and slope of ray */ + angl = angle; + /* put angles in normal range */ + while (angl < 0.0) + angl = angl + 360.0; + while (angl >= 360.0) + angl = angl - 360.0; + /* check for a horizontal angle */ +#if USE_ASTRO_ANGLE + if(fabs(angl - 90.0) < SMALL_NUMBER) { +#else + if(fabs(angl - 180.0) < SMALL_NUMBER) { +#endif + *xcept = 0.0; + *ycept = ycen; + return(2); + } +#if USE_ASTRO_ANGLE + if(fabs(angl - 270.0) < SMALL_NUMBER) { +#else + if(fabs(angl - 0.0) < SMALL_NUMBER) { +#endif + *xcept = width + 1; + *ycept = ycen; + return(4); + } + /* convert to a Cartesian angle */ +#if USE_ASTRO_ANGLE + angl = angl + 90.0; +#endif + if(angl >= 360.0) + angl = angl - 360.0; + if(angl < 180.0) { + *ycept = height + 1; + /* rule out vertical line */ + if(fabs(angl - 90.0) < SMALL_NUMBER) { + *xcept = xcen; + return(1); + } + } else { + *ycept = 0.0; + /* rule out vertical line */ + if(fabs(angl - 270.0) < SMALL_NUMBER) { + *xcept = xcen; + return(3); + } + } + /* convert to radians */ + angl = (angl / 180.0) * M_PI; + /* calculate slope */ + slope = tan(angl); + /* calculate intercept with designated y edge */ + *xcept = xcen + ((*ycept - ycen) / slope); + if(*xcept < 0) { + *ycept = (ycen - (xcen * slope)); + *xcept = 0.0; + return(2); + } else if(*xcept > (width + 1)) { + *ycept = (ycen + ((width + 1 - xcen) * slope)); + *xcept = width + 1; + return(4); + } else { + if(*ycept < height) + return(3); + else + return(1); + } +} + +/* ***************************** shapes ********************************** */ + +int evannulus(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, double ri, double ro) +{ + /* use circle if possible */ + if( ri == 0 ){ + return(evcircle(g, rno, sno, flag, type, x, y, xcen, ycen, ro)); + } + + if( !g->shapes[sno].init ){ + g->shapes[sno].init = 1; + g->shapes[sno].ystart = ycen - ro; + g->shapes[sno].ystop = ycen + ro; + g->shapes[sno].r1sq = ri * ri; + g->shapes[sno].r2sq = ro * ro; + } + + if((((y>=g->shapes[sno].ystart) && (y<=g->shapes[sno].ystop)) && + (((xcen-x)*(xcen-x))+((ycen-y)*(ycen-y))<=g->shapes[sno].r2sq) && + (((xcen-x)*(xcen-x))+((ycen-y)*(ycen-y))>g->shapes[sno].r1sq)) == flag ){ + if( rno && flag ) g->rid = rno; + return 1; + } + else{ + return 0; + } +} + +int evbox(GFilt g, int rno, int sno, int flag, int UNUSED(type), + double x, double y, + double xcen, double ycen, double xwidth, double yheight, + double angle) +{ + int i; + double angl; /* l: Cartesian angle in radians */ + double half_width, half_height;/* l: radii (1/2 width and height) */ + double cosangl, sinangl; /* l: sine, cosine of the Cartesian angle */ + double hw_cos, hw_sin; /* l: products of half_width with sin, cos */ + double hh_cos, hh_sin; /* l: products of half_height with sin, cos */ + double xstart=0.0; + + if( (xwidth == 0) && (yheight==0) ){ + return(!flag); + } + if( !g->shapes[sno].init ){ + g->shapes[sno].init = 1; +#if USE_ASTRO_ANGLE + /* convert to a Cartesian angle; save angle for use in multi or slices */ + angl = angle + 90.0; +#else + angl = angle; +#endif + while (angl >= 360.0) angl = angl - 360.0; + /* convert to radians */ + angl = (angl / 180.0) * M_PI; + sinangl = sin (angl); + cosangl = cos (angl); +#if USE_ASTRO_ANGLE + /* since we rotate by 90.0 degrees to get from astro angle to cartesian, */ + /* we also need to switch the width and height. we do this secretly so */ + /* that the display will turn out right, by doing it in the half terms */ + half_width = yheight / 2.0; + half_height = xwidth / 2.0; +#else + half_width = xwidth / 2.0; + half_height = yheight / 2.0; +#endif + hw_cos = half_width * cosangl; + hw_sin = half_width * sinangl; + hh_cos = half_height * cosangl; + hh_sin = half_height * sinangl; + g->shapes[sno].pts = (double *)calloc(8, sizeof(double)); +#if USE_ASTRO_ANGLE + g->shapes[sno].pts[0] = xcen - hw_cos - hh_sin; + g->shapes[sno].pts[1] = ycen - hw_sin + hh_cos; + g->shapes[sno].pts[2] = xcen + hw_cos - hh_sin; + g->shapes[sno].pts[3] = ycen + hw_sin + hh_cos; + g->shapes[sno].pts[4] = xcen + hw_cos + hh_sin; + g->shapes[sno].pts[5] = ycen + hw_sin - hh_cos; + g->shapes[sno].pts[6] = xcen - hw_cos + hh_sin; + g->shapes[sno].pts[7] = ycen - hw_sin - hh_cos; +#else + g->shapes[sno].pts[0] = xcen - hw_cos + hh_sin; + g->shapes[sno].pts[1] = ycen - hh_cos - hw_sin; + g->shapes[sno].pts[2] = xcen - hw_cos - hh_sin; + g->shapes[sno].pts[3] = ycen + hh_cos - hw_sin; + g->shapes[sno].pts[4] = xcen + hw_cos - hh_sin; + g->shapes[sno].pts[5] = ycen + hh_cos + hw_sin; + g->shapes[sno].pts[6] = xcen + hw_cos + hh_sin; + g->shapes[sno].pts[7] = ycen - hh_cos + hw_sin; +#endif + g->shapes[sno].npt = 8; + /* now find the y limits */ + if( g->shapes[sno].npt ){ + xstart = g->shapes[sno].pts[0]; + g->shapes[sno].ystart = g->shapes[sno].pts[1]; + g->shapes[sno].ystop = g->shapes[sno].ystart; + for(i=1; ishapes[sno].npt; i+=2){ + if(g->shapes[sno].pts[i-1] < xstart) + xstart = g->shapes[sno].pts[i-1]; + if(g->shapes[sno].pts[i] > g->shapes[sno].ystop) + g->shapes[sno].ystop = g->shapes[sno].pts[i]; + if(g->shapes[sno].pts[i] < g->shapes[sno].ystart) + g->shapes[sno].ystart = g->shapes[sno].pts[i]; + } + } + } + if( (((y>=g->shapes[sno].ystart) && (y<=g->shapes[sno].ystop)) && + polypt(x, y, g->shapes[sno].pts, g->shapes[sno].npt/2, + xstart, g->shapes[sno].ystart, 0)) == flag ){ + if( rno && flag ) g->rid = rno; + return 1; + } + else + return 0; +} + +int evcircle(GFilt g, int rno, int sno, int flag, int UNUSED(type), + double x, double y, + double xcen, double ycen, double radius) +{ + if( radius == 0 ){ + return(!flag); + } + if( !g->shapes[sno].init ){ + g->shapes[sno].init = 1; + g->shapes[sno].ystart = ycen - radius; + g->shapes[sno].ystop = ycen + radius; + g->shapes[sno].r1sq = radius * radius; + } + if( (((y>=g->shapes[sno].ystart) && (y<=g->shapes[sno].ystop)) && + (((xcen-x)*(xcen-x))+((ycen-y)*(ycen-y))<=g->shapes[sno].r1sq)) == flag ){ + if( rno && flag ) g->rid = rno; + return 1; + } + else + return 0; +} + +int evellipse(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, double xrad, double yrad, double angle) +{ + double yhi, yoff; + double b, c; + double b_partial, c_partial; + double xboff, xfoff; + int nr, nc; + + /* use circle if possible */ + if( xrad == yrad ){ + return(evcircle(g, rno, sno, flag, type, x, y, xcen, ycen, xrad)); + } + + if( !g->shapes[sno].init ){ + g->shapes[sno].init = 1; + /* set worst case limits (xrad axis parallel to vertical axis) */ +#if USE_ASTRO_ANGLE + /* convert to a Cartesian angle; save "angle" for use by other routines */ + g->shapes[sno].angl = angle + 90.0; +#else + g->shapes[sno].angl = angle; +#endif + while( g->shapes[sno].angl >= 360.0 ) + g->shapes[sno].angl = g->shapes[sno].angl - 360.0; + /* convert to radians */ + g->shapes[sno].angl = (g->shapes[sno].angl / 180.0) * M_PI; + g->shapes[sno].sinangl = sin(g->shapes[sno].angl); + g->shapes[sno].cosangl = cos(g->shapes[sno].angl); + /* calculate approximate y limits */ + /* choose lesser of containing rotbox and circle */ +#if USE_ASTRO_ANGLE + yhi = fabs(g->shapes[sno].sinangl * yrad) + + fabs(g->shapes[sno].cosangl * xrad); +#else + yhi = fabs(g->shapes[sno].sinangl * xrad) + + fabs(g->shapes[sno].cosangl * yrad); +#endif + yhi = min(yhi, max(yrad, xrad)); + g->shapes[sno].ystart = ycen - yhi; + g->shapes[sno].ystop = ycen + yhi; + /* prepare partials for quadratic equation solutions to coordinates */ + g->shapes[sno].cossq = g->shapes[sno].cosangl * g->shapes[sno].cosangl; + g->shapes[sno].sinsq = g->shapes[sno].sinangl * g->shapes[sno].sinangl; +#if USE_ASTRO_ANGLE + /* because we rotate by 90.0 degrees to get from astro angle to */ + /* cartesian, we also need to switch the x and y axes. we do this */ + /* secretly so that the display will turn out right, by doing it in */ + /* the sq terms */ + g->shapes[sno].xradsq = yrad * yrad; + g->shapes[sno].yradsq = xrad * xrad; +#else + g->shapes[sno].xradsq = xrad * xrad; + g->shapes[sno].yradsq = yrad * yrad; +#endif + /* fill in as much of a,b,c as we can */ + g->shapes[sno].a = (g->shapes[sno].cossq / g->shapes[sno].xradsq) + + (g->shapes[sno].sinsq / g->shapes[sno].yradsq); + } + if( ((y>=g->shapes[sno].ystart) && (y<=g->shapes[sno].ystop)) ){ + b_partial = (2.0 * g->shapes[sno].sinangl) * + ((g->shapes[sno].cosangl / g->shapes[sno].xradsq) - + (g->shapes[sno].cosangl / g->shapes[sno].yradsq)); + c_partial = (g->shapes[sno].sinsq / g->shapes[sno].xradsq) + + (g->shapes[sno].cossq / g->shapes[sno].yradsq); + yoff = y - ycen; + b = b_partial * yoff; + c = (c_partial * yoff * yoff) - 1.0; + /* solve quadratic */ + quadeq (g->shapes[sno].a, b, c, &xboff, &xfoff, &nr, &nc); + /* if real roots */ + if( nr != 0 ) { + FPU_DOUBLE +#if USE_FLOAT_COMPARE + if( (((float)x>=(float)(xcen+xboff)) && + ((float)x<=(float)(xcen+xfoff))) == flag ){ +#else + if( ((x>=(xcen+xboff)) && (x<=(xcen+xfoff))) == flag ){ +#endif + if( rno && flag ) g->rid = rno; + FPU_RESTORE + return 1; + } + else{ + FPU_RESTORE + return 0; + } + } + else + return !flag; + } + return !flag; +} + +int evfield(GFilt g, int rno, int UNUSED(sno), int flag, int UNUSED(type), + double UNUSED(x), double UNUSED(y)) +{ + if( flag ){ + if( rno && flag ) g->rid = rno; + return 1; + } + else + return 0; +} + +int evline(GFilt g, int rno, int sno, int flag, int UNUSED(type), + double x, double y, + double x1, double y1, double x2, double y2) +{ + if( !g->shapes[sno].init ){ + g->shapes[sno].init = 1; + g->shapes[sno].ystart = min(y1,y2); + g->shapes[sno].ystop = max(y1,y2); + g->shapes[sno].x1 = x1; + g->shapes[sno].x2 = x2; + g->shapes[sno].y1 = y1; + if( feq(y1,y2) ){ + g->shapes[sno].xonly = 1; + g->shapes[sno].invslope = 0; + } + else{ + g->shapes[sno].xonly = 0; + g->shapes[sno].invslope = (x1 - x2) / (y1 - y2); + } + } + if( (((y>=g->shapes[sno].ystart) && (y<=g->shapes[sno].ystop)) && + ((!g->shapes[sno].xonly && + feq((((y-g->shapes[sno].y1)*g->shapes[sno].invslope)+g->shapes[sno].x1),x)) || + (g->shapes[sno].xonly && + ((x>=g->shapes[sno].x1)&&(x<=g->shapes[sno].x2))))) == flag){ + if( rno && flag ) g->rid = rno; + return 1; + } + else + return 0; +} + +int evpie(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, double angle1, double angle2) +{ + int i; + int width, height; /* l: image mask width and height */ + double sweep; /* l: sweep between cut angles */ + int intrcpt1, intrcpt2; /* l: side intercepted by each cut */ + double x2, y2; /* l: coordinates of second intercept */ + double xstart=0.0; + + /* use field if possible */ + if( (angle1==0) && (angle2==360) ){ + return(evfield(g, rno, sno, flag, type, x, y)); + } + + if( !g->shapes[sno].init ){ + g->shapes[sno].init = 1; + /* we have to fake width and height, since we do not know them! */ + width = LARGE_NUMBER; + height = LARGE_NUMBER; + /* start listing vertices of polygon */ + g->shapes[sno].pts = (double *)calloc(14, sizeof(double)); + g->shapes[sno].pts[0] = xcen; + g->shapes[sno].pts[1] = ycen; + sweep = angle2 - angle1; + /* if sweep is too small to be noticed, don't bother */ + if(fabs(sweep) < SMALL_NUMBER) + return !flag; + if (sweep < 0.0) sweep = sweep + 360.0; + intrcpt1 = pie_intercept((double)width, (double)height, xcen, ycen, angle1, + &(g->shapes[sno].pts[2]), + &(g->shapes[sno].pts[3])); + intrcpt2 = pie_intercept((double)width, (double)height, xcen, ycen, angle2, + &x2, &y2); + g->shapes[sno].npt = 4; + /* if angles intercept same side and slice is between them, no corners */ + /* else, mark corners until reaching side with second angle intercept */ + if((intrcpt1 != intrcpt2) || (sweep > 180.0)){ + do{ + intrcpt1 = corner_vertex(intrcpt1, width, height, + &(g->shapes[sno].pts[g->shapes[sno].npt]), + &(g->shapes[sno].pts[g->shapes[sno].npt+1])); + g->shapes[sno].npt = g->shapes[sno].npt + 2; + }while(intrcpt1 != intrcpt2); + } + g->shapes[sno].pts[g->shapes[sno].npt] = x2; + g->shapes[sno].pts[g->shapes[sno].npt+1] = y2; + g->shapes[sno].npt = g->shapes[sno].npt + 2; + /* now find the y limits */ + if( g->shapes[sno].npt ){ + xstart = g->shapes[sno].pts[0]; + g->shapes[sno].ystart = g->shapes[sno].pts[1]; + g->shapes[sno].ystop = g->shapes[sno].ystart; + for(i=1; ishapes[sno].npt; i+=2){ + if(g->shapes[sno].pts[i-1] < xstart) + xstart = g->shapes[sno].pts[i-1]; + if(g->shapes[sno].pts[i] > g->shapes[sno].ystop) + g->shapes[sno].ystop = g->shapes[sno].pts[i]; + if(g->shapes[sno].pts[i] < g->shapes[sno].ystart) + g->shapes[sno].ystart = g->shapes[sno].pts[i]; + } + } + } + if( (((y>=g->shapes[sno].ystart) && (y<=g->shapes[sno].ystop)) && + polypt(x, y, g->shapes[sno].pts, g->shapes[sno].npt/2, + xstart, g->shapes[sno].ystart, 1)) == flag ){ + if( rno && flag ) g->rid = rno; + return 1; + } + else{ + return 0; + } +} + +int evqtpie(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, double angle1, double angle2) +{ + return evpie(g, rno, sno, flag, type, x, y, xcen, ycen, angle1, angle2); +} + +int evpoint(GFilt g, int rno, int UNUSED(sno), int flag, int UNUSED(type), + double x, double y, + double xcen, double ycen) +{ + if( ((x==xcen) && (y==ycen)) == flag ){ + if( rno && flag ) g->rid = rno; + return 1; + } + else + return 0; +} + +#ifdef __STDC__ +int +evpolygon(GFilt g, int rno, int sno, int flag, int UNUSED(type), + double x, double y, ...) +{ + int i, maxpts; + double xstart=0.0; + va_list args; + va_start(args, y); +#else +int evpolygon(va_alist) va_dcl +{ + GFilt g; + int rno, sno, flag, type; + double x, y; + double xstart=0.0; + int i, maxpts; + va_list args; + va_start(args); + g = va_arg(args, GFilt); + rno = va_arg(args, int); + sno = va_arg(args, int); + flag = va_arg(args, int); + type = va_arg(args, int); + x = va_arg(args, double); + y = va_arg(args, double); +#endif + if( !g->shapes[sno].init ){ + g->shapes[sno].init = 1; + /* allocate space for x,y arguments */ + maxpts = MASKINC; + g->shapes[sno].pts = (double *)calloc(maxpts, sizeof(double)); + /* gather up arguments */ + g->shapes[sno].npt = 0; + while( 1 ){ + if( g->shapes[sno].npt >= maxpts ){ + maxpts += MASKINC; + g->shapes[sno].pts = (double *)realloc(g->shapes[sno].pts, + maxpts*sizeof(double)); + } + g->shapes[sno].pts[g->shapes[sno].npt] = va_arg(args, double); + /* two negatives in a row means we are at end of args */ + if( feq(g->shapes[sno].pts[g->shapes[sno].npt],PSTOP) && + feq(g->shapes[sno].pts[g->shapes[sno].npt-1],PSTOP) ){ + g->shapes[sno].npt--; + break; + } + g->shapes[sno].npt++; + } + va_end(args); + /* realloc to actual size */ + g->shapes[sno].pts = (double *)realloc(g->shapes[sno].pts, + g->shapes[sno].npt*sizeof(double)); + /* now find the y limits */ + if( g->shapes[sno].npt ){ + xstart = g->shapes[sno].pts[0]; + g->shapes[sno].ystart = g->shapes[sno].pts[1]; + g->shapes[sno].ystop = g->shapes[sno].ystart; + for(i=1; ishapes[sno].npt; i+=2){ + if(g->shapes[sno].pts[i-1] < xstart) + xstart = g->shapes[sno].pts[i-1]; + if(g->shapes[sno].pts[i] > g->shapes[sno].ystop) + g->shapes[sno].ystop = g->shapes[sno].pts[i]; + if(g->shapes[sno].pts[i] < g->shapes[sno].ystart) + g->shapes[sno].ystart = g->shapes[sno].pts[i]; + } + } + } + if( (((y>=g->shapes[sno].ystart) && (y<=g->shapes[sno].ystop)) && + polypt(x, y, g->shapes[sno].pts, g->shapes[sno].npt/2, + xstart, g->shapes[sno].ystart, 0)) == flag ){ + if( rno && flag ) g->rid = rno; + return 1; + } + else + return 0; +} + +/* accelerator regions -- lower and upper limits are given for n regions */ + +int evnannulus(GFilt g, int rno, int sno, int flag, int type, + double x, double y, double xcen, double ycen, + double lo, double hi, int n) +{ + int i; + int xsno; + double dinc; + + /* get limits */ + dinc = (hi - lo)/(double)n; + xsno = (g->nshapes+1)+((sno-1)*XSNO); + if( flag ){ + /* if its not somewhere inside the entire region we lose ... */ + if( !evannulus(g, 0, xsno, flag, type, x, y, xcen, ycen, lo, hi) ){ + return(0); + } + /* look through all of them to find the right one */ + for(i=0; inshapes+1)+((sno-1)*XSNO); + if( flag ){ + /* if its not somewhere inside the entire region we lose ... */ + if( !evbox(g, 0, xsno, flag, type, x, y, xcen, ycen, hix, hiy, ang) ){ + return(0); + } + /* if its in the inner region we lose */ + if( evbox(g, 0, xsno+1, flag, type, x, y, xcen, ycen, lox, loy, ang) ){ + return(0); + } + /* look through all of them to find the right one */ + for(i=0; inshapes+1)+((sno-1)*XSNO); + if( flag ){ + /* if its not somewhere inside the entire region we lose ... */ + if( !evellipse(g, 0, xsno, flag, type, x, y, xcen, ycen, hix, hiy, ang) ){ + return(0); + } + /* if its in the inner region we lose */ + if( evellipse(g, 0, xsno+1, flag, type, x, y, xcen, ycen, lox, loy, ang) ){ + return(0); + } + /* look through all of them to find the right one */ + for(i=0; i hi ) lo -= 360.0; + dinc = (hi - lo)/n; + xsno = (g->nshapes+1)+((sno-1)*XSNO); + if( flag ){ + /* check limits */ + if( !evpie(g, 0, xsno, flag, type, x, y, xcen, ycen, lo, hi) ){ + return(0); + } + /* look through all of them to find the right one */ + for(i=0; inshapes+1)+((sno-1)*XSNO); + if( flag ){ + /* if its not somewhere inside the entire region we lose ... */ + if( !evannulus(g, 0, xsno, flag, type, x, y, xcen, ycen, radlo, radhi) || + !evpie(g, 0, xsno+1, flag, type, x, y, xcen, ycen, anglo, anghi) ){ + return(0); + } + /* look through all of them to find the right one */ + for(a=1; a<=ahi; a++){ + for(r=1; r<=rhi; r++){ + if( evannulus(g, rno+n, sno+(2*n), flag, type, x, y, + xcen, ycen, radlo+((r-1)*rinc), radlo+(r*rinc)) && + evpie(g, rno+n, sno+(2*n+1), flag, type, x, y, + xcen, ycen, anglo+((a-1)*ainc), anglo+(a*ainc)) ){ + return(1); + } + n++; + } + } + return(0); + } + else{ + /* if its not somewhere inside the entire region we win ... */ + if( !evannulus(g, 0, xsno, 1, type, x, y, xcen, ycen, radlo, radhi) ) + return(1); + else if( !evpie(g, 0, xsno+1, 1, type, x, y, xcen, ycen, anglo, anghi) ){ + return(1); + } + else{ + return(0); + } + } +} + +int evbpanda(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, + double anglo, double anghi, double angn, + double xlo, double ylo, double xhi, double yhi, double radn, + double ang) +{ + + int a, r; + int ahi, rhi; + int xsno; + int n=0; + double ainc, xinc, yinc; + + /* get limits */ + anglo += ang; + anghi += ang; + ainc = (anghi - anglo)/angn; + ahi = (int)angn; + xinc = (xhi - xlo)/radn; + yinc = (yhi - ylo)/radn; + rhi = (int)radn; + xsno = (g->nshapes+1)+((sno-1)*XSNO); + if( flag ){ + /* if its not somewhere inside the entire region we lose ... */ + if( !evbox(g, 0, xsno, flag, type, x, y, xcen, ycen, xhi, yhi, + ang) ){ + return(0); + } + /* but if its in the inner region we lose */ + else if( evbox(g, 0, xsno+2, flag, type, x, y, xcen, ycen, xlo, ylo, + ang) ){ + return(0); + } + /* its in the box .. must also be in the pie */ + else if( !evpie(g, 0, xsno+1, flag, type, x, y, xcen, ycen, anglo, anghi)){ + return(0); + } + /* look through all of them to find the right one */ + for(a=0; anshapes+1)+((sno-1)*XSNO); + if( flag ){ + /* if its not somewhere inside the entire region we lose ... */ + if( !evellipse(g, 0, xsno, flag, type, x, y, xcen, ycen, xhi, yhi, + ang) ){ + return(0); + } + /* but if its in the inner region we lose */ + else if( evellipse(g, 0, xsno+2, flag, type, x, y, xcen, ycen, xlo, ylo, + ang) ){ + return(0); + } + /* its in the ellipse .. must also be in the pie */ + else if( !evpie(g, 0, xsno+1, flag, type, x, y, xcen, ycen, anglo, anghi)){ + return(0); + } + /* look through all of them to find the right one */ + for(a=0; anshapes+1)+((sno-1)*XSNO); + if( !g->shapes[xsno].xv ){ + maxpts = MASKINC; + g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double)); + g->shapes[xsno].nv = 0; + while( 1 ){ + if( g->shapes[xsno].nv >= maxpts ){ + maxpts += MASKINC; + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + maxpts*sizeof(double)); + } + g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double); + if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) && + feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){ + g->shapes[xsno].nv--; + break; + } + g->shapes[xsno].nv++; + } + va_end(args); + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + g->shapes[xsno].nv*sizeof(double)); + } + n = g->shapes[xsno].nv; + xv = g->shapes[xsno].xv; + /* this should be impossible ... */ + if( n == 2 ){ + return(evannulus(g, rno, sno, flag, type, x, y, xcen, ycen, xv[0], xv[1])); + } + if( flag ){ + /* if its not somewhere inside the entire region we lose ... */ + if( !evannulus(g, 0, xsno, flag, type, x, y, xcen, ycen, xv[0], xv[n-1]) ){ + return(0); + } + /* look through all of them to find the right one */ + for(i=0; inshapes+1)+((sno-1)*XSNO); + if( !g->shapes[xsno].xv ){ + maxpts = MASKINC; + g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double)); + g->shapes[xsno].nv = 0; + while( 1 ){ + if( g->shapes[xsno].nv >= maxpts ){ + maxpts += MASKINC; + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + maxpts*sizeof(double)); + } + g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double); + if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) && + feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){ + g->shapes[xsno].nv--; + break; + } + g->shapes[xsno].nv++; + } + va_end(args); + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + g->shapes[xsno].nv*sizeof(double)); + } + n = g->shapes[xsno].nv; + xv = g->shapes[xsno].xv; + ang = xv[--n]; + /* this should be impossible ... */ + if( n == 2 ){ + return(evbox(g, rno, sno, flag, type, x, y, + xcen, ycen, xv[0], xv[1], ang)); + } + if( flag ){ + /* if its not somewhere inside the entire region we lose ... */ + if( !evbox(g, 0, xsno, flag, type, x, y, xcen, ycen, xv[n-2], xv[n-1], + ang) ){ + return(0); + } + /* if its in the inner region we lose */ + if( evbox(g, 0, xsno+1, flag, type, x, y, xcen, ycen, xv[0], xv[1], ang) ){ + return(0); + } + /* look through all of them to find the right one */ + for(i=2, j=0; inshapes+1)+((sno-1)*XSNO); + if( !g->shapes[xsno].xv ){ + maxpts = MASKINC; + g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double)); + g->shapes[xsno].nv = 0; + while( 1 ){ + if( g->shapes[xsno].nv >= maxpts ){ + maxpts += MASKINC; + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + maxpts*sizeof(double)); + } + g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double); + if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) && + feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){ + g->shapes[xsno].nv--; + break; + } + g->shapes[xsno].nv++; + } + va_end(args); + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + g->shapes[xsno].nv*sizeof(double)); + } + n = g->shapes[xsno].nv; + xv = g->shapes[xsno].xv; + ang = xv[--n]; + /* this should be impossible ... */ + if( n == 2 ){ + return(evellipse(g, rno, sno, flag, type, x, y, + xcen, ycen, xv[0], xv[1], ang)); + } + if( flag ){ + /* if its not somewhere inside the entire region we lose ... */ + if( !evellipse(g, 0, xsno, flag, type, x, y, xcen, ycen, xv[n-2], xv[n-1], + ang) ){ + return(0); + } + /* if its in the inner region we lose */ + if( evellipse(g, 0, xsno+1, flag, type, x, y, xcen, ycen, xv[0], xv[1], + ang) ){ + return(0); + } + /* look through all of them to find the right one */ + for(i=2, j=0; inshapes+1)+((sno-1)*XSNO); + if( !g->shapes[xsno].xv ){ + maxpts = MASKINC; + g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double)); + g->shapes[xsno].nv = 0; + while( 1 ){ + if( g->shapes[xsno].nv >= maxpts ){ + maxpts += MASKINC; + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + maxpts*sizeof(double)); + } + g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double); + if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) && + feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){ + g->shapes[xsno].nv--; + break; + } + g->shapes[xsno].nv++; + } + va_end(args); + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + g->shapes[xsno].nv*sizeof(double)); + } + n = g->shapes[xsno].nv; + xv = g->shapes[xsno].xv; + /* this should be impossible ... */ + if( n == 2 ){ + return(evpie(g, rno, sno, flag, type, x, y, + xcen, ycen, xv[0], xv[1])); + } + if( flag ){ + /* if its not somewhere inside the entire region we lose ... */ + if( !evpie(g, 0, xsno, flag, type, x, y, xcen, ycen, xv[0], xv[n-1]) ){ + return(0); + } + /* look through all of them to find the right one */ + for(i=0; inshapes+1)+((sno-1)*XSNO); + if( !g->shapes[xsno].xv ){ + maxpts = MASKINC; + g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double)); + g->shapes[xsno].nv = 0; + while( 1 ){ + if( g->shapes[xsno].nv >= maxpts ){ + maxpts += MASKINC; + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + maxpts*sizeof(double)); + } + g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double); + if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) && + feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){ + g->shapes[xsno].nv--; + break; + } + g->shapes[xsno].nv++; + } + va_end(args); + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + g->shapes[xsno].nv*sizeof(double)); + } + n = g->shapes[xsno].nv; + xv = g->shapes[xsno].xv; + /* look through all of them to find the right one */ + for(i=0, j=0; i +#ifdef HAVE_MALLOC_H +#include +#endif +#ifdef HAVE_STDLIB_H +#include +#endif +#include +#include +#include +#include + +#define MAX_INCLUDE_DEPTH 100 +#define SEGINC 1024 +#define MASKINC 1024 + +#define LARGE_NUMBER 65536 + +/* must match regions.h */ +#define PSTOP -142857.142857 + +/* stolen from fitsy/xos.h */ +#define X__PI 3.14159265358979323846 +#define X_2PI ( 2 * X__PI ) +#define X_R2D (X_2PI / 360.0) +#define X_R2H (X_2PI / 24.0) +#define X_H2D (360.0 / 24.0) + +#define r2h(r) ( (r) / X_R2H ) +#define h2r(d) ( (d) * X_R2H ) +#define r2d(r) ( (r) / X_R2D ) +#define d2r(d) ( (d) * X_R2D ) +#define h2d(r) ( (r) * X_H2D ) +#define d2h(d) ( (d) / X_H2D ) + +/* region types */ +#define TY_ANNULUS 1 +#define TY_BOX 2 +#define TY_CIRCLE 3 +#define TY_ELLIPSE 4 +#define TY_FIELD 5 +#define TY_LINE 6 +#define TY_PANDA 7 +#define TY_BPANDA 8 +#define TY_CPANDA 9 +#define TY_EPANDA 10 +#define TY_PIE 11 +#define TY_QTPIE 11 +#define TY_POINT 12 +#define TY_POLYGON 13 +#define TY_IMAGEMASK 14 + +/* oft-used checks on argument and coord types */ +#define XARG ((narg % 2) == 1) +#define YARG ((narg % 2) == 0) +#define POSARG ((regid == TY_POLYGON) || (regid == TY_LINE) || (narg<=2)) +#define ANGARG (((regid == TY_PANDA) && (narg==3)) || \ + ((regid == TY_PANDA) && (narg==4)) || \ + ((regid == TY_BPANDA) && (narg==3)) || \ + ((regid == TY_BPANDA) && (narg==4)) || \ + ((regid == TY_CPANDA) && (narg==3)) || \ + ((regid == TY_CPANDA) && (narg==4)) || \ + ((regid == TY_EPANDA) && (narg==3)) || \ + ((regid == TY_EPANDA) && (narg==4)) || \ + ((regid == TY_PIE) && (narg>=3)) ) + +#define NUMARG (((regid == TY_PANDA) && (narg==5)) || \ + ((regid == TY_PANDA) && (narg==8)) || \ + ((regid == TY_BPANDA) && (narg==5)) || \ + ((regid == TY_BPANDA) && (narg==10)) || \ + ((regid == TY_CPANDA) && (narg==5)) || \ + ((regid == TY_CPANDA) && (narg==8)) || \ + ((regid == TY_EPANDA) && (narg==5)) || \ + ((regid == TY_EPANDA) && (narg==10)) ) + +#define SAVEANG ((regid == TY_BOX) || (regid == TY_ELLIPSE)) + +#define USEPHYS (filt->fhd->table && \ + (filt->type == TYPE_EVENTS) && !filt->evsect) + +#define USEWCS (gcoordsys && \ + strcmp(gcoordsys, "image") && strcmp(gcoordsys, "physical")) + +#define IMFLIP (USEWCS && wcs->imflip) + +#define WCSSIZE (iswcs(wcs) && (cdelt1!=0) && (cdelt2!=0)) + +/* format statements */ +#define DFMT1 ",%f" +#define DFMT2 ",%f,%f" +#define DFMT4 ",%f,%f,%f,%f" +#define SFMT1 ",%s" +#define IFMT1 ",%d" + +/* flex is not thread-safe, so we did not put any effort into avoiding + globals, i.e. by putting read-write variables below into a struct */ + +static YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH]; +static int include_stack_ptr = 0; +static int parse_error = 0; + +static int colargs; +static int filtlen; +static int radanglen; +static int initbindefs; +static int regtype; +static int regid; +static int laststart; +static int maxfiltseg; +static int setargs; +static int inexpr; +static int macropass; +static int narg; +static int nparen; +static int nsparen; +static int nrparen; +static int nfiltseg; +static int nrange; +static int nroutine; +static int nshape; +static int nregion; +static int nmask; +static int got; +static int offscl; +static int xtype, ytype; +static int tltyp[2]; + +static double lastd1; +static double lastd2; +static double xpos, ypos; +static double xpix, ypix; +static double cdelt1, cdelt2, crot; +static double dval, dval2; +static double tlmin[2]; +static double tlmax[2]; +static double binsiz[2]; + +static char lastarg[SZ_LINE]; +static char regname[SZ_LINE]; +static char colnames[2][SZ_LINE]; +static char wcsnames[2][SZ_LINE]; +static char macrobuf[SZ_LINE]; +static char rangename[SZ_LINE]; +static char sbuf[SZ_LINE]; +static char saveang[SZ_LINE]; + +static char *fcoordsys=NULL; +static char *gcoordsys=NULL; +static char *filter=NULL; +static char *radang=NULL; + +static struct WorldCoor *wcs=NULL; +static FiltSeg *filtseg=NULL; +static Filter filt=NULL; + +/* these are read-only */ +static char *rnames[] = {"annulus", "box", "circle", "ellipse", + "line", "panda", "pie", "qtpie", "point", + "polygon", "field", "bpanda", "cpanda", "epanda", + "imagemask", NULL}; +static int rargs[] = {4, 5, 3, 5, + 4, 8, 4, 4, 2, + 6, 0, 11, 8, 11, + 0, 0}; +static int vargs[] = {'y', 'o', 'y', 'o', + 'n', 'n', 'y', 'n', 'e', + 'e', 'n', 'n', 'n', 'n', + 'n', '\0'}; + +static int _FiltLexTypeCmp(const void *s1, const void *s2); +static int _FiltLexTypeMatch(int ftype, int ttype); +static int _FiltLexAccel _PRx((int n)); +static int _FiltLexRegionPanda _PRx((void)); +static int _FiltLexLcx _PRx((void)); +static int _FiltLexArgCheck _PRx((char *name, int args)); +static int _FiltLexNeedOp _PRx((int i, char *s)); +static void _FiltLexOp _PRx((char *s)); +static void _FiltLexTypeSet _PRx((int type)); +static void _FiltLexNew _PRx((void)); +static void _FiltLexParen _PRx((char *s)); +static void _FiltLexCat _PRx((char *s)); +static void _FiltLexRegionStart _PRx((int docols)); +static void _FiltLexRegionVal _PRx((char *s)); +static void _FiltLexRegionEnd _PRx((void)); +static void _FiltLexRangeAdd _PRx((char *xname, char *str, int type, int n, int maxlen)); +static void _FiltLexArgSave _PRx((double dval)); +static void _FiltLexSetWcs _PRx((char *s)); +static void _FiltLexWcsCols _PRx((FITSHead header, char *name1, char *name2)); +static void _FiltLexNum _PRx((int lcx)); +static void _FiltLexEnd _PRx((void)); +static void _FiltLexMake _PRx((void)); +static char *_FiltLexGetWcs _PRx((void)); +static int _FiltIncMask(FilterMask masks, int maxmask, int nmask); +static int _FiltFitsMask(char *filename, FilterMask *rmasks, FITSHead *rhead, int *nreg); +static void bin2num(char *d, char *s, int maxlen); + +int _filterror _PRx((char *msg)); +%} + +DIG [0-9] +DIG2 [0-9a-fA-F] +BINARY 0[bB][01]+ +INT1 [-+]?{DIG}+L? +INT2 [-+]?0[xX]{DIG2}+L? +INT ({INT1}|{INT2}) +FLOAT1 [-+]?{DIG}+\.?([eE][-+]?{DIG}+)? +FLOAT2 [-+]?{DIG}*\.{DIG}+([eE][-+]?{DIG}+)? +FLOAT ({FLOAT1}|{FLOAT2}) +NUM ({INT}|{FLOAT}|{BINARY}) +HMS {INT}{SP}[:hH]{SP}{INT}{SP}[:mM]{SP}{NUM}{SP}[s]? +DMS {INT}{SP}[:dD]{SP}{INT}{SP}[:mM]{SP}{NUM}{SP}[s]? +WCS {HMS}|{DMS} +DEG {NUM}d +RAD {NUM}r +IPIX {NUM}i +PPIX {NUM}p +ASEC {NUM}\" +AMIN {NUM}' +COORSYS (j2000|fk5|icrs|b1950|fk4|galactic|ecliptic|linear|image|physical|amplifier|detector) +NAME [A-Za-z_][0-9A-Za-z~_]*(\[[^\[]*\])? +FILE @[0-9A-Za-z~_/\-\.]*(\[.*\])? +REGION [\!+-]?(ann|annulus|box|cir|circle|ell|ellipse|lin|line|pan|panda|pie|poi|qtpie|qtp|point|pol|polygon|fie|field|bpanda|bpa|cpanda|cpa|epanda|epa) +REGVAL {SP}\{{INT}\} +LOP (&&|\|\||[&\|]) +OP (&&|\|\||==|!=|<=|>=|<<|>>|[&\|~=<>+\-*/%^]) +STR (\"[^\"]*\"|'[^']*') +SP [ \t]* +EOL ([;\n]|\\n) +SEP (,|{EOL}) +COM # +US (unsigned{SP})? +II (int{SP})? +DTYPE (\({US}char\)|\({US}short{II}\)|\({US}int\)|\({US}long{II}\)|\(float\)|\(double\)) + +%s RLIST +%s RTINE +%s REG +%x AREG +%x INCLUDE +%x COMM + +%% + +{DTYPE} { _FiltLexCat(yytext); } + +{COORSYS}[\n;,]* { _FiltLexSetWcs(yytext); } + +global { BEGIN COMM; } +tile { BEGIN COMM; } +compass { BEGIN COMM; } +{COM} { + /* comment acts like EOL */ + if( YY_START == REG ){ + _FiltLexRegionEnd(); + _FiltLexNew(); + } + else if( YY_START == RLIST ){ + _FiltLexParen(")"); + _FiltLexNew(); + } + else{ + _FiltLexNew(); + } + BEGIN COMM; +} +\n { BEGIN INITIAL; } +\\n { BEGIN INITIAL; } +. { /* ignore comments up to eol */ ; } + +[+-]?text([ \t]+|{SP}\({SP})[^;\n]*{EOL} { ; /* ignore */ } +[+-]?vector([ \t]+|{SP}\({SP})[^;\n]*{EOL} { ; /* ignore */ } +[+-]?ruler([ \t]+|{SP}\({SP})[^;\n]*{EOL} { ; /* ignore */ } +[+-]?projection([ \t]+|{SP}\({SP})[^;\n]*{EOL} { ; /* ignore */ } + +\(/{NAME},{NAME}\){SP}={SP}{REGION} { + if( YY_START == REG ){ + _FiltLexRegionEnd(); + _FiltLexNew(); + } + /* Found an asc-style region */ + colargs = 0; + laststart = YY_START; + BEGIN AREG; +} +{NAME} { + if( colargs > 2 ) + _filterror("illegal Chandra region (too many column args)"); + if( !FilterSymbolEnter(filt, yytext, &got) ){ + switch(got){ + case -1: + _filterror("missing column or header parameter"); + break; + case -2: + _filterror("column is not an array"); + break; + case -3: + _filterror("internal error while processing column"); + break; + } + } + strcpy(colnames[colargs],yytext); + colargs++; +} +, { ; } +\( { ; } +\) { ; } += { + /* end of asc part of region */ + if( colargs != 2 ) + _filterror("illegal Chandra region (wrong number of cols)"); + BEGIN INITIAL; +} + +[+-]?field([ \t]+|{SP}\({SP})? | +{REGION}([ \t]+|{SP}\({SP})/{NUM} { + /* finish off previous */ + if( YY_START == REG ){ + _FiltLexRegionEnd(); + _FiltLexNew(); + } + /* Found a region */ + BEGIN REG; + if( filt->type == TYPE_EVENTS ){ + /* if asc-style, re-do wcs for specified columns */ + if( colargs == 2 ){ + _FiltLexRegionStart(2); + _FiltLexWcsCols(filt->fhd, colnames[0], colnames[1]); + } + /* set up default columns */ + else{ + _FiltLexRegionStart(1); + } + } + /* its an image */ + else{ + _FiltLexRegionStart(0); + } +} +{REGION}([ \t]+|{SP}\({SP})/{NAME} { + /* can't happen */ + _filterror("invalid characters following the region name"); +} +{NUM} { + narg++; + /* process this pure number in the current coord system */ + _FiltLexNum(_FiltLexLcx()); +} +{IPIX} { + narg++; + /* remove trailing unit character */ + yytext[strlen(yytext)-1] = '\0'; + /* process this as a pure number in image coord sys */ + _FiltLexNum(LCX_IMAGE); +} +{PPIX} { + narg++; + /* remove trailing unit character */ + yytext[strlen(yytext)-1] = '\0'; + /* process this as a pure number in physical coord sys */ + _FiltLexNum(LCX_PHYS); +} +{WCS} { + char *coordsys; + if( nowcs(wcs) ) + _filterror("no WCS information in file"); + narg++; + /* save x value for processing with y next time */ + if( XARG ){ + xpos = SAOstrtod(yytext,NULL); + xtype = SAOdtype; + if( (xtype !=0) && (xtype != '.') && (xtype != 'd') ){ + coordsys = _FiltLexGetWcs(); + /* arg1 coords are hms, but ecliptic, galactic are deg */ + if( !coordsys || + (strncasecmp(coordsys, "ecl", 3) && + strncasecmp(coordsys, "gal", 3)) ){ + xpos = h2d(xpos); + } + } + } + else{ + ypos = SAOstrtod(yytext,NULL); + ytype = SAOdtype; + /* convert wcs to image pixels */ + wcsc2pix(wcs, xpos,ypos, _FiltLexGetWcs(), &xpix,&ypix, + &offscl); + /* convert to physical for single event filtering */ + if( USEPHYS ){ + xpix = tli2p(xpix, tlmin[0], binsiz[0], tltyp[0]); + ypix = tli2p(ypix, tlmin[1], binsiz[1], tltyp[1]); + } + snprintf(sbuf, SZ_LINE, DFMT2, xpix, ypix); + _FiltLexCat(sbuf); + } +} +{DEG} { + narg++; + /* handle position arguments */ + if( POSARG ){ + if( nowcs(wcs) ) + _filterror("no WCS information in file"); + /* save x value for processing with y next time */ + if( XARG ){ + xpos = strtod(yytext,NULL); + } + else{ + ypos = strtod(yytext,NULL); + /* convert wcs to image pixels */ + wcsc2pix(wcs, xpos, ypos, _FiltLexGetWcs(), + &xpix, &ypix, &offscl); + /* convert to physical for single event filtering */ + if( USEPHYS ){ + xpix = tli2p(xpix, tlmin[0], binsiz[0], tltyp[0]); + ypix = tli2p(ypix, tlmin[1], binsiz[1], tltyp[1]); + } + snprintf(sbuf, SZ_LINE, DFMT2, xpix, ypix); + _FiltLexCat(sbuf); + } + } + /* angle arguments are just passed along, with updated crot */ + else if( ANGARG ){ + dval = strtod(yytext,NULL); + if( USEWCS ) dval += crot; + if( IMFLIP ) dval = -dval; + snprintf(sbuf, SZ_LINE, DFMT1, dval); + _FiltLexCat(sbuf); + } + /* panda numeric args are just passed along */ + else if( NUMARG ){ + dval = strtod(yytext,NULL); + snprintf(sbuf, SZ_LINE, DFMT1, dval); + _FiltLexCat(sbuf); + } + /* handle size arguments */ + else{ + if( !WCSSIZE ) + _filterror("no WCS (or CDELT) information in file"); + if( SAVEANG ){ + dval = strtod(yytext,NULL); + if( USEWCS ) dval += crot; + if( IMFLIP ) dval = -dval; + snprintf(saveang, SZ_LINE, DFMT1, dval); + } + /* arg 1 is ra, arg2 is dec */ + if( XARG ) + dval = ABS(strtod(yytext,NULL)/cdelt1); + else + dval = ABS(strtod(yytext,NULL)/cdelt2); + snprintf(sbuf, SZ_LINE, DFMT1, dval); + _FiltLexCat(sbuf); + _FiltLexArgSave(dval); + } +} +{RAD} { + narg++; + /* handle position arguments */ + if( POSARG ){ + if( nowcs(wcs) ) + _filterror("no WCS information in file"); + /* save x value for processing with y next time */ + if( XARG ){ + xpos = r2d(strtod(yytext,NULL)); + } + else{ + ypos = r2d(strtod(yytext,NULL)); + /* convert wcs to image pixels */ + wcsc2pix(wcs, xpos, ypos, _FiltLexGetWcs(), + &xpix, &ypix, &offscl); + /* convert to physical for single event filtering */ + if( USEPHYS ){ + xpix = tli2p(xpix, tlmin[0], binsiz[0], tltyp[0]); + ypix = tli2p(ypix, tlmin[1], binsiz[1], tltyp[1]); + } + snprintf(sbuf, SZ_LINE, DFMT2, xpix, ypix); + _FiltLexCat(sbuf); + } + } + /* angle arguments are just passed along, with updated crot */ + else if( ANGARG ){ + dval = r2d(strtod(yytext,NULL)); + if( USEWCS ) dval += crot; + if( IMFLIP ) dval = -dval; + snprintf(sbuf, SZ_LINE, DFMT1, dval); + _FiltLexCat(sbuf); + } + /* panda numeric args are just passed along */ + else if( NUMARG ){ + dval = strtod(yytext,NULL); + snprintf(sbuf, SZ_LINE, DFMT1, dval); + _FiltLexCat(sbuf); + } + /* handle size arguments */ + else{ + if( !WCSSIZE ) + _filterror("no WCS (or CDELT) information in file"); + if( SAVEANG ){ + dval = r2d(strtod(yytext,NULL)); + if( USEWCS ) dval += crot; + if( IMFLIP ) dval = -dval; + snprintf(saveang, SZ_LINE, DFMT1, dval); + } + /* arg 1 is ra, arg2 is dec */ + if( XARG ) + dval = r2d(ABS(strtod(yytext,NULL)/cdelt1)); + else + dval = r2d(ABS(strtod(yytext,NULL)/cdelt2)); + snprintf(sbuf, SZ_LINE, DFMT1, dval); + _FiltLexCat(sbuf); + _FiltLexArgSave(dval); + } +} +{AMIN} { + if( !WCSSIZE ) + _filterror("no WCS (or CDELT) information in file"); + narg++; + /* arg 1 is ra, arg2 is dec */ + if( XARG ) + dval = ABS(strtod(yytext,NULL)/(cdelt1*60.0)); + else + dval = ABS(strtod(yytext,NULL)/(cdelt2*60.0)); + snprintf(sbuf, SZ_LINE, DFMT1, dval); + _FiltLexCat(sbuf); + _FiltLexArgSave(dval); +} +{ASEC} { + if( !WCSSIZE ) + _filterror("no WCS (or CDELT) information in file"); + narg++; + /* arg 1 is ra, arg2 is dec */ + if( XARG ) + dval = ABS(strtod(yytext,NULL)/(cdelt1*3600.0)); + else + dval = ABS(strtod(yytext,NULL)/(cdelt2*3600.0)); + snprintf(sbuf, SZ_LINE, DFMT1, dval); + _FiltLexCat(sbuf); + _FiltLexArgSave(dval); +} +[a-z]{SP}={SP}{NUM}{SP} { + int n; + n = strtol(strchr(yytext, '=')+1, NULL, 10); + if( n <=0 ){ + _filterror("invalid region accelerator"); + } + else{ + if( !_FiltLexAccel(n) ){ + _filterror("invalid region accelerator"); + } + } +} +{NUM}/{OP} { + if( _FiltLexArgCheck(regname, narg) == 0 ){ + /* new expression without an expression separator ... sigh */ + _FiltLexRegionEnd(); + _FiltLexNew(); + BEGIN INITIAL; + yyless(0); + } else { + narg++; + /* process this pure number in the current coord system */ + _FiltLexNum(_FiltLexLcx()); + } +} +({NAME}{OP}|{FILE}) { + /* new expression without an expression separator ... sigh */ + _FiltLexRegionEnd(); + _FiltLexNew(); + BEGIN INITIAL; + yyless(0); +} +, { + /* explicit rule avoids the _FiltLexNew of general rule */ + ; +} +{REGVAL} { + _FiltLexRegionVal(yytext); + if( !nsparen ){ + _FiltLexRegionEnd(); + BEGIN INITIAL; + } +} +\( { + nsparen++; +} +\){REGVAL} { + _FiltLexRegionVal(yytext+1); + if( nsparen ){ + nsparen--; + if( !nsparen ){ + _FiltLexRegionEnd(); + BEGIN INITIAL; + } + } else { + _FiltLexRegionEnd(); + BEGIN INITIAL; + /* REJECT; */ + /* explicit execution of general rule instead of REJECT */ + nparen--; + _FiltLexNew(); + _FiltLexCat(")"); + _FiltLexNew(); + } +} +\) { + if( nsparen ){ + nsparen--; + if( !nsparen ){ + _FiltLexRegionEnd(); + BEGIN INITIAL; + } + } else { + _FiltLexRegionEnd(); + BEGIN INITIAL; + /* REJECT; */ + /* explicit execution of general rule instead of REJECT */ + nparen--; + _FiltLexNew(); + _FiltLexCat(")"); + _FiltLexNew(); + } +} +{OP} { + _FiltLexRegionEnd(); + _FiltLexOp(yytext); + BEGIN INITIAL; +} +{EOL} { + _FiltLexRegionEnd(); + _FiltLexNew(); + BEGIN INITIAL; +} + +{NAME}{SP}/={SP}\(?({NAME}|:{NAME}) { + _filterror("you must use == to compare two columns,"); +} + +{NAME}{SP}/={SP}\(?({NUM}|:{NUM}) { + if( YY_START == REG ){ + _FiltLexRegionEnd(); + } + _FiltLexParen("("); + BEGIN RLIST; + narg = 0; + _FiltLexTypeSet(TOK_RLIST); + nrange = 0; + if( !FilterSymbolEnter(filt, yytext, &got) ){ + switch(got){ + case -1: + _filterror("missing column or header parameter"); + break; + case -2: + _filterror("column is not an array"); + break; + case -3: + _filterror("internal error while processing column"); + break; + } + } + strncpy(rangename, yytext, SZ_LINE-1); +} +{NUM}{SP}:{SP}{NUM} { + _FiltLexRangeAdd(rangename, yytext, 3, nrange++, SZ_LINE); +} +:{SP}{NUM} { + _FiltLexRangeAdd(rangename, yytext, 1, nrange++, SZ_LINE); +} +{NUM}{SP}: { + _FiltLexRangeAdd(rangename, yytext, 4, nrange++, SZ_LINE); +} +{NUM} { + _FiltLexRangeAdd(rangename, yytext, 2, nrange++, SZ_LINE); +} += { ; } +, { ; } +{SEP}{SP}/{NUM}\)*{LOP} { ; } +{SEP}{SP}/\(*({NAME}|{NUM}{SP}{OP}|{FILE}|{REGION}) { + _FiltLexParen(")"); + _FiltLexNew(); + BEGIN INITIAL; +} +\) { + _FiltLexParen(")"); + _FiltLexNew(); + _FiltLexParen(")"); + _FiltLexNew(); + BEGIN INITIAL; +} +{OP} { + _FiltLexParen(")"); + _FiltLexOp(yytext); + BEGIN INITIAL; +} +{EOL} { + _FiltLexParen(")"); + _FiltLexNew(); + BEGIN INITIAL; +} + +{NAME}{SP}/\( { + /* Found a routine */ + laststart = YY_START; + BEGIN RTINE; + narg = 0; + nrparen = 0; + _FiltLexTypeSet(TOK_RTINE); + _FiltLexCat(FilterLexRoutine1(filt, yytext)); + nroutine++; +} +, { + /* explicit rule avoids the _FiltLexNew of general rule */ + _FiltLexCat(","); +} +\( { + nrparen++; + _FiltLexCat("("); +} +\) { + nrparen--; + if( nrparen ){ + _FiltLexCat(")"); + } + else{ + /* end of routine */ + BEGIN laststart; + _FiltLexCat(FilterLexRoutine2(filt, ")")); + } +} + +{FILE} { + /* Found an include file */ + char *s, *t; + if( YY_START == REG ){ + _FiltLexRegionEnd(); + _FiltLexNew(); + } + /* handle FITS mask file specially */ + filt->nmask = _FiltFitsMask(yytext+1, + &(filt->masks), + &(filt->maskhd), + &(filt->nmaskreg)); + /* filt->nmask == -1 => its not a FITS file */ + if( filt->nmask != -1 ){ + switch(filt->nmask){ + case -2: + _filterror("FITS image mask must be image data -"); + break; + case -3: + _filterror("Invalid dimensions for FITS image mask -"); + break; + case -4: + _filterror("FITS image mask cannot contain negative values -"); + break; + default: + if( (filt->type != TYPE_IMAGE) && !filt->evsect ){ + _filterror("FITS image mask is valid for image filtering only -"); + } + else{ + if( nmask ) + _filterror("only one FITS image mask allowed at a time -"); + else + nmask++; + } + break; + } + } + else{ + if ( include_stack_ptr >= MAX_INCLUDE_DEPTH ) { + _filterror("include files are nested too deeply"); + } + if( (s = (char *)FileContents(yytext+1, 0, NULL)) == NULL ){ + _filterror("can't access include file"); + } + /* ignore empty include file */ + else if( *s == '\0' ){ + ; + } + else { + t = FilterClip(s); + xfree(s); + if( t && *t ){ + include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER; + _FiltLexNew(); + _FiltLexParen("("); + FiltScanString(t); + xfree(t); + } + } + } +} + +{NAME} { + if( !FilterSymbolEnter(filt, yytext, &got) ){ + switch(got){ + case -1: + _filterror("missing column or header parameter"); + break; + case -2: + _filterror("column is not an array"); + break; + case -3: + _filterror("internal error while processing column"); + break; + } + } + else{ + narg++; + /* add if initial condition (not region, routine, etc.) */ + if( YY_START == INITIAL ) _FiltLexTypeSet(TOK_NAME); + _FiltLexCat(FilterLexName(filt,yytext)); + } +} + +{SP} { ; /* ignore white space */ } + +{STR} { narg++; _FiltLexCat(yytext); } + +{NUM} { + char tbuf[SZ_LINE]; + bin2num(tbuf, yytext, SZ_LINE-1); + narg++; + _FiltLexCat(tbuf); + } + +{OP} { + _FiltLexOp(yytext); + if( YY_START != RTINE ) BEGIN INITIAL; +} + +\( { + nparen++; + _FiltLexNew(); + _FiltLexCat(yytext); + _FiltLexNew(); +} +\) { + nparen--; + _FiltLexNew(); + _FiltLexCat(yytext); + _FiltLexNew(); +} +{SEP} { + _FiltLexNew(); + BEGIN INITIAL; +} + +. { _FiltLexCat(yytext); } + +<> { + if ( --include_stack_ptr < 0 ){ + _FiltLexMake(); + yy_delete_buffer( YY_CURRENT_BUFFER ); + yyterminate(); + } else { + _FiltLexParen(")"); + _FiltLexNew(); + yy_delete_buffer( YY_CURRENT_BUFFER ); + yy_switch_to_buffer(include_stack[include_stack_ptr] ); + } +} + +%% + +/* + * + * Private Routines + * + * + */ + + +#ifdef YY_USE_PROTOS +static void floatprefix(void) +#else +static void floatprefix() +#endif +{ + if( filt->method == METHOD_C ) + _FiltLexCat("(double)"); +} + +#ifdef YY_USE_PROTOS +static void floatsuffix(void) +#else +static void floatsuffix() +#endif +{ + return; +} + +#ifdef YY_USE_PROTOS +static void +bin2num(char *d, char *s, int maxlen) +#else +static void +bin2num(d, s, maxlen) + char *d; + char *s; + int maxlen; +#endif +{ + unsigned long bits; + char *p=NULL; + + if( strlen(s) < 2 ){ + if( d != s ) strncpy(d, s, maxlen-1); + } + else{ + if( (*s=='0') && (*(s+1)=='b') ){ + bits = strtoul(s+2, &p, 2); + if( *p != '\0' ) _filterror("invalid binary value"); + snprintf(d, maxlen, "%lx", bits); + if( (strlen(d) <2) || (*d!='0') || ((*(d+1)!='x')&&((*(d+1)!='X'))) ){ + snprintf(d, maxlen, "0x%lx", bits); + } + } + else{ + if( d != s ) strncpy(d, s, maxlen-1); + } + } +} + +/* + * + * _FiltLexNew -- finish last start and set up new filter segment + * + */ +#ifdef YY_USE_PROTOS +static void +_FiltLexNew(void) +#else +static void _FiltLexNew() +#endif +{ + int i; + int last; + + if( nfiltseg >= maxfiltseg ){ + last = maxfiltseg; + if( maxfiltseg == 0 ){ + maxfiltseg = SEGINC; + filtseg = (FiltSeg *)xmalloc(maxfiltseg * sizeof(FiltSeg)); + } + else{ + maxfiltseg += SEGINC; + filtseg = (FiltSeg *)xrealloc(filtseg, maxfiltseg * sizeof(FiltSeg)); + } + /* clear the unused records */ + for(i=last; is) ){ + filtseg[nfiltseg] = (FiltSeg)xcalloc(1, sizeof(FiltSegRec)); + nfiltseg++; + } + filtseg[nfiltseg-1]->n = nfiltseg-1; + filtseg[nfiltseg-1]->nregion = 0; +} + +/* + * + * _FiltLexParen -- add a paren to the filter string buffer + * + */ +#ifdef YY_USE_PROTOS +static void +_FiltLexParen(char *str) +#else +static void _FiltLexParen(str) + char *str; +#endif +{ + /* _FiltLexNew(); */ + _FiltLexCat(str); + /* _FiltLexNew(); */ +} + +/* + * + * __FiltLexCat -- add a string to the filter string buffer + * + */ +#ifdef YY_USE_PROTOS +static void +__FiltLexCat(char *str, char **ostr, int *olen) +#else +static void __FiltLexCat(str, ostr, olen) + char *str; + char **ostr; + int *olen; +#endif +{ + int blen; + int slen; + + if( (str == NULL) || (*str == '\0') ) + return; + else + slen = strlen(str) + 1; + + if( (*ostr == NULL) || (**ostr == '\0') ) + blen = 0; + else + blen = strlen(*ostr); + + while( (blen + slen) >= *olen ){ + *olen += SEGINC; + } + if( blen == 0 ) + *ostr = (char *)xcalloc(*olen, sizeof(char)); + else + *ostr = (char *)xrealloc(*ostr, *olen); + strcat(*ostr, str); +} + +/* + * + * _FiltLexCat -- add a string to the filter string buffer + * + */ +#ifdef YY_USE_PROTOS +static void +_FiltLexCat(char *str) +#else +static void _FiltLexCat(str) + char *str; +#endif +{ + char *s; + if( !str || !*str ) + return; + if( nfiltseg ==0 ) + _FiltLexNew(); + s = xmalloc(strlen(str)+1); + nowhite(str, s); + __FiltLexCat(s, &(filtseg[nfiltseg-1]->s), &(filtseg[nfiltseg-1]->len)); + if( s ) xfree(s); +} + +/* + * + * _FiltLexArgSave -- save a radius or angle value to the temp string: + * this is a special hack for funcnts + * + */ +#ifdef YY_USE_PROTOS +static void +_FiltLexArgSave(double dval) +#else +static void _FiltLexArgSave(dval) + double dval; +#endif +{ + char tbuf[SZ_LINE]; + + if( narg < 3 ) + return; + snprintf(tbuf, SZ_LINE, DFMT1, dval); + if( narg == 3 ){ + *lastarg = '\0'; + lastd1 = 0.0; + lastd2 = 0.0; + if( filtseg[nfiltseg-1]->radang ){ + xfree(filtseg[nfiltseg-1]->radang); + filtseg[nfiltseg-1]->radang = NULL; + filtseg[nfiltseg-1]->ralen = 0; + } + } + switch(regid){ + case TY_ANNULUS: + case TY_CIRCLE: + if( *lastarg ){ + __FiltLexCat(lastarg, &(filtseg[nfiltseg-1]->radang), + &(filtseg[nfiltseg-1]->ralen)); + } + __FiltLexCat(tbuf, &(filtseg[nfiltseg-1]->radang), + &(filtseg[nfiltseg-1]->ralen)); + if( narg > 3 ){ + __FiltLexCat(",NA,NA\n", &(filtseg[nfiltseg-1]->radang), + &(filtseg[nfiltseg-1]->ralen)); + strcpy(lastarg, tbuf); + } + lastd1 = lastd2; + lastd2 = dval; + break; + + case TY_BOX: + case TY_ELLIPSE: + if( (narg%2) == 1 ){ + if( *lastarg ){ + __FiltLexCat(lastarg, &(filtseg[nfiltseg-1]->radang), + &(filtseg[nfiltseg-1]->ralen)); + } + __FiltLexCat(tbuf, &(filtseg[nfiltseg-1]->radang), + &(filtseg[nfiltseg-1]->ralen)); + if( narg > 3 ){ + __FiltLexCat(",NA,NA\n", &(filtseg[nfiltseg-1]->radang), + &(filtseg[nfiltseg-1]->ralen)); + strcpy(lastarg, tbuf); + } + lastd1 = lastd2; + lastd2 = dval; + } + break; + + case TY_PIE: + if( narg == 3 ){ + __FiltLexCat("NA,NA", &(filtseg[nfiltseg-1]->radang), + &(filtseg[nfiltseg-1]->ralen)); + } + else if( *lastarg ){ + __FiltLexCat("NA,NA,", &(filtseg[nfiltseg-1]->radang), + &(filtseg[nfiltseg-1]->ralen)); + __FiltLexCat(lastarg, &(filtseg[nfiltseg-1]->radang), + &(filtseg[nfiltseg-1]->ralen)); + } + __FiltLexCat(tbuf, &(filtseg[nfiltseg-1]->radang), + &(filtseg[nfiltseg-1]->ralen)); + if( narg > 3 ){ + __FiltLexCat("\n", &(filtseg[nfiltseg-1]->radang), + &(filtseg[nfiltseg-1]->ralen)); + strcpy(lastarg, tbuf); + } + lastd1 = lastd2; + lastd2 = dval; + break; + + case TY_POINT: + /* we have to process this here if its is a varargs */ + /* so, for the 3rd arg, we add a line for initial x, y pair */ + if( narg == 3 ){ + __FiltLexCat("NA,NA,NA,NA\n", &(filtseg[nfiltseg-1]->radang), + &(filtseg[nfiltseg-1]->ralen)); + } + /* and for every even arg, add a line for the preceeding x,y pair */ + else if( (narg % 2) == 0 ){ + __FiltLexCat("NA,NA,NA,NA\n", &(filtseg[nfiltseg-1]->radang), + &(filtseg[nfiltseg-1]->ralen)); + } + break; + default: + return; + } +} + +/* + * + * _FiltLexAccel -- appply acceleration to a segment + * + */ +#ifdef YY_USE_PROTOS +static int +_FiltLexAccel(int n) +#else +static int _FiltLexAccel(n) + int n; +#endif +{ + int i; + char tbuf[SZ_LINE]; + char *s; + double dinc; + + /* check region type */ + switch(regid){ + case TY_ANNULUS: + break; + case TY_BOX: + narg -= 2; + break; + case TY_CIRCLE: + narg -= 1; + break; + case TY_ELLIPSE: + narg -= 2; + break; + case TY_PIE: + break; + default: + _filterror("annulus, box, circle, ellipse, pie accelerators only - "); + break; + } + /* add the argument */ + snprintf(tbuf, SZ_LINE, IFMT1, n); + _FiltLexCat(tbuf); + /* change the name of the routine we will call */ + if( filtseg[nfiltseg-1]->s0 ){ + if( (s = xstrdup(&filtseg[nfiltseg-1]->s[filtseg[nfiltseg-1]->s0])) ){ + filtseg[nfiltseg-1]->s[filtseg[nfiltseg-1]->s0] = '\0'; + _FiltLexCat("n"); + _FiltLexCat(s); + snprintf(tbuf, SZ_LINE, "%d ", n); + __FiltLexCat(tbuf, &(filtseg[nfiltseg-1]->regions), + &(filtseg[nfiltseg-1]->nr)); + __FiltLexCat(tbuf, &(filtseg[nfiltseg-1]->shapes), + &(filtseg[nfiltseg-1]->ns)); + setargs = 1; + free (s); + } + if( filtseg[nfiltseg-1]->radang ){ + xfree(filtseg[nfiltseg-1]->radang); + filtseg[nfiltseg-1]->radang = NULL; + filtseg[nfiltseg-1]->ralen = 0; + } + switch(regid){ + case TY_ANNULUS: + case TY_BOX: + case TY_CIRCLE: + case TY_ELLIPSE: + dinc = (lastd2 - lastd1)/n; + for(i=1; i<=n; i++){ + snprintf(tbuf, SZ_LINE, DFMT2, lastd1+((i-1)*dinc), lastd1+(i*dinc)); + __FiltLexCat(tbuf, &(filtseg[nfiltseg-1]->radang), + &(filtseg[nfiltseg-1]->ralen)); + __FiltLexCat(",NA,NA", &(filtseg[nfiltseg-1]->radang), + &(filtseg[nfiltseg-1]->ralen)); + __FiltLexCat("\n", &(filtseg[nfiltseg-1]->radang), + &(filtseg[nfiltseg-1]->ralen)); + } + break; + case TY_PIE: + dinc = (lastd2 - lastd1)/n; + for(i=1; i<=n; i++){ + snprintf(tbuf, SZ_LINE, DFMT2, lastd1+((i-1)*dinc), lastd1+(i*dinc)); + __FiltLexCat("NA,NA", &(filtseg[nfiltseg-1]->radang), + &(filtseg[nfiltseg-1]->ralen)); + __FiltLexCat(tbuf, &(filtseg[nfiltseg-1]->radang), + &(filtseg[nfiltseg-1]->ralen)); + __FiltLexCat("\n", &(filtseg[nfiltseg-1]->radang), + &(filtseg[nfiltseg-1]->ralen)); + } + break; + default: + _filterror("annulus, box, circle, ellipse, pie accelerators only - "); + break; + } + _FiltLexTypeSet(TOK_ACCEL); + } + else{ + _filterror("misplaced accelerator"); + } + return(n); +} + +/* + * + * _FiltLexTypeSet -- add type info to the filter segment record + * + */ +#ifdef YY_USE_PROTOS +static void +_FiltLexTypeSet(int type) +#else +static void _FiltLexTypeSet(type) + int type; +#endif +{ + if( nfiltseg ==0 ) + _FiltLexNew(); + filtseg[nfiltseg-1]->type |= type; +} + +/* + * + * _FiltLexOp -- add an operator to the filter segment record + * + */ +#ifdef YY_USE_PROTOS +static void +_FiltLexOp(char *op) +#else +static void _FiltLexOp(op) + char *op; +#endif +{ + _FiltLexCat(op); + filtseg[nfiltseg-1]->ops += 1; +} + +#ifdef YY_USE_PROTOS +static void +_FiltLexRegionStart(int docols) +#else +static void _FiltLexRegionStart(docols) + int docols; +#endif +{ + char *s, *t; + char tbuf[SZ_LINE]; + + /* sanity check -- 1D images do not support regions */ + if( (filt->type == TYPE_IMAGE) && (ft_naxes(filt->fhd)==1) ){ + _filterror("2D region filters invalid for 1D images"); + } + narg = 0; + setargs=0; + s = xmalloc(strlen(yytext)+1); + nowhite(yytext, s); + if( *s == '+' ){ + regtype = TOK_IREG; + strcpy(regname, s+1); + } + else if( *s == '-' ){ + regtype = TOK_EREG; + strcpy(regname, s+1); + } + else if( *s == '!' ){ + regtype = TOK_NREG; + strcpy(regname, s+1); + } + else{ + regtype = TOK_IREG; + strcpy(regname, s); + } + _FiltLexTypeSet(regtype); + if( !(t=strchr(regname, '(')) ){ + nsparen=0; + } + /* remove the paren from the regname string -- we will explicitly add it */ + else{ + *t = '\0'; + nsparen=1; + } + /* convert to lower case, remove white space */ + culc(regname); + nowhite(regname, s); + strcpy(regname, s); + /* convert abbrev to region */ + if( !strncmp(regname, "ann", 3) ){ + strcpy(regname, "annulus"); + regid = TY_ANNULUS; + } + else if( !strncmp(regname, "box", 3) ){ + strcpy(regname, "box"); + regid = TY_BOX; + } + else if( !strncmp(regname, "cir", 3) ){ + strcpy(regname, "circle"); + regid = TY_CIRCLE; + } + else if( !strncmp(regname, "ell", 3) ){ + strcpy(regname, "ellipse"); + regid = TY_ELLIPSE; + } + else if( !strncmp(regname, "fie", 3) ){ + strcpy(regname, "field"); + regid = TY_FIELD; + } + else if( !strncmp(regname, "lin", 3) ){ + strcpy(regname, "line"); + regid = TY_LINE; + } + else if( !strncmp(regname, "pan", 3) ){ + strcpy(regname, "panda"); + regid = TY_PANDA; + } + else if( !strncmp(regname, "bpa", 3) ){ + strcpy(regname, "bpanda"); + regid = TY_BPANDA; + } + else if( !strncmp(regname, "cpa", 3) ){ + strcpy(regname, "cpanda"); + regid = TY_CPANDA; + } + else if( !strncmp(regname, "epa", 3) ){ + strcpy(regname, "epanda"); + regid = TY_EPANDA; + } + else if( !strncmp(regname, "pie", 3) ){ + strcpy(regname, "pie"); + regid = TY_PIE; + } + else if( !strncmp(regname, "qtp", 3) ){ + strcpy(regname, "qtpie"); + regid = TY_PIE; + } + else if( !strncmp(regname, "poi", 3) ){ + strcpy(regname, "point"); + regid = TY_POINT; + } + else if( !strncmp(regname, "pol", 3) ){ + strcpy(regname, "polygon"); + regid = TY_POLYGON; + } + else if( !strcmp(regname, "imagemask") ){ + regid = TY_IMAGEMASK; + } + /* append filter-type prefix */ + switch( filt->type ){ + case TYPE_EVENTS: + /* normally, we filter rows analytically using evregions.o */ + if( !filt->evsect ) + _FiltLexCat("ev"); + /* if evsect=xxx is specified, we filter by image pixels */ + else + _FiltLexCat("im"); + break; + case TYPE_IMAGE: + /* image are filtered by image pixels */ + _FiltLexCat("im"); + break; + } + /* no region value to start */ + filtseg[nfiltseg-1]->regval = 0; + /* save size of current string so we can get back to the region string */ + filtseg[nfiltseg-1]->s0 = strlen(filtseg[nfiltseg-1]->s); + /* append region */ + _FiltLexCat(FilterLexRegion1(filt,regname)); + /* append standard args */ + _FiltLexCat("(g,$RS,"); + /* add include/exclude and whether we mark y lines for this region + (we don't mark y on excludes as an optimization) */ + switch(regtype){ + case TOK_IREG: + snprintf(tbuf, SZ_LINE, "1,%d", TOK_IREG); + _FiltLexCat(tbuf); + break; + case TOK_NREG: + snprintf(tbuf, SZ_LINE, "0,%d", TOK_NREG); + _FiltLexCat(tbuf); + break; + case TOK_EREG: + snprintf(tbuf, SZ_LINE, "0,%d", TOK_EREG); + _FiltLexCat(tbuf); + break; + } + switch(docols){ + case 0: + /* initialize default columns for tables -- but don't enter symbols yet */ + FilterSymbolDefaults(filt, 0); + /* initialize wcs for default image case */ + _FiltLexWcsCols(filt->fhd, filt->xbin, filt->ybin); + _FiltLexCat(","); + floatprefix(); + _FiltLexCat("x"); + floatsuffix(); + _FiltLexCat(","); + floatprefix(); + _FiltLexCat("y"); + floatsuffix(); + break; + case 1: + if( !initbindefs ){ + /* initialize default columns for tables and enter symbols */ + FilterSymbolDefaults(filt, 1); + /* initialize wcs for default table case */ + _FiltLexWcsCols(filt->fhd, filt->xbin, filt->ybin); + initbindefs++; + } + if( !filt->xbin || !filt->ybin ){ + _filterror("two binning columns are required for regions"); + } + _FiltLexCat(","); + floatprefix(); + _FiltLexCat(filt->xbin); + floatsuffix(); + _FiltLexCat(","); + floatprefix(); + _FiltLexCat(filt->ybin); + floatsuffix(); + break; + case 2: + _FiltLexCat(","); + floatprefix(); + _FiltLexCat(colnames[0]); + floatsuffix(); + _FiltLexCat(","); + floatprefix(); + _FiltLexCat(colnames[1]); + floatsuffix(); + break; + } + if( s ) xfree(s); +} + +#ifdef YY_USE_PROTOS +static void +_FiltLexRegionVal(char *s) +#else +static void +_FiltLexRegionVal(s) + char *s; +#endif +{ + char *t=NULL; + if( (t=strchr(s, '{')) ){ + t++; + } + else{ + t = s; + } + filtseg[nfiltseg-1]->regval = atoi(t); +} + +#ifdef YY_USE_PROTOS +static void +_FiltLexRegionEnd(void) +#else +static void +_FiltLexRegionEnd() +#endif +{ + int n; + char *s; + char ebuf[SZ_LINE]; + char tbuf[SZ_LINE]; + + /* add final arguments as required */ + switch( regid ){ + case TY_BOX: + if( (narg%2) == 0 ){ + _FiltLexCat(",0.0"); narg++; + } + else{ + /* if we saved an angle arg, we need to replace the last position arg */ + if( *saveang ){ + if( (s=strrchr(filtseg[nfiltseg-1]->s, ',')) ){ + *s = '\0'; + _FiltLexCat(saveang); + } + } + } + break; + case TY_ELLIPSE: + if( (narg%2) == 0 ){ + _FiltLexCat(",0.0"); narg++; + } + else{ + /* if we saved an angle arg, we need to replace the last position arg */ + if( *saveang ){ + if( (s=strrchr(filtseg[nfiltseg-1]->s, ',')) ){ + *s = '\0'; + _FiltLexCat(saveang); + } + } + } + break; + case TY_BPANDA: + case TY_EPANDA: + if( (narg%2) == 0 ){ + _FiltLexCat(",0.0"); narg++; + } + /* drop through here to process panda */ + case TY_PANDA: + case TY_CPANDA: + _FiltLexRegionPanda(); + setargs = 1; + break; + default: + break; + } + + /* argument check */ + if( (n=_FiltLexArgCheck(regname, narg)) > 0 ){ + /* don't bother printing where we are in region */ + *yytext = '\0'; + switch( vargs[n-1] ){ + case 'n': + snprintf(ebuf, SZ_LINE, "'%s' requires %d args (%d found)", + rnames[n-1], rargs[n-1], narg); + break; + case 'e': + snprintf(ebuf, SZ_LINE, + "'%s' requires at least %d (even) args (%d found)", + rnames[n-1], rargs[n-1], narg); + break; + case 'o': + snprintf(ebuf, SZ_LINE, + "'%s' requires at least %d (odd) args (%d found)", + rnames[n-1], rargs[n-1], narg); + break; + case 'y': + default: + snprintf(ebuf, SZ_LINE, "'%s' requires %d args (%d found)", + rnames[n-1], rargs[n-1], narg); + break; + } + _filterror(ebuf); + } + + /* process varargs */ + if( (n < 0) || (regid == TY_POLYGON) ){ + if( filtseg[nfiltseg-1]->type & TOK_ACCEL ){ + _filterror("n= and variable arglist cannot be combined -"); + } + /* if its a varargs, we need to end with PSTOP values */ + snprintf(sbuf, SZ_LINE, DFMT2, PSTOP, PSTOP); + _FiltLexCat(sbuf); + /* change the name of the routine we will call */ + if( regid != TY_POLYGON ){ + if( filtseg[nfiltseg-1]->s0 ){ + if((s = xstrdup(&filtseg[nfiltseg-1]->s[filtseg[nfiltseg-1]->s0]))){ + filtseg[nfiltseg-1]->s[filtseg[nfiltseg-1]->s0] = '\0'; + _FiltLexCat("v"); + _FiltLexCat(s); + switch(regid){ + case TY_ANNULUS: + n = narg - 3; + break; + case TY_BOX: + n = (narg - 5)/2; + break; + case TY_CIRCLE: + n = narg - 3; + break; + case TY_ELLIPSE: + n = (narg - 5)/2; + break; + case TY_PIE: + n = narg - 3; + break; + case TY_POINT: + n = narg/2; + break; + default: + _filterror("varargs: annulus, box, circle, ellipse, pie, point;"); + break; + } + snprintf(tbuf, SZ_LINE, "%d ", n); + __FiltLexCat(tbuf, &(filtseg[nfiltseg-1]->regions), + &(filtseg[nfiltseg-1]->nr)); + __FiltLexCat(tbuf, &(filtseg[nfiltseg-1]->shapes), + &(filtseg[nfiltseg-1]->ns)); + setargs = 1; + free (s); + } + _FiltLexTypeSet(TOK_VARARGS); + } + else{ + _filterror("invalid varargs"); + } + } + } + + + /* set number of regions and shapes, if not already done */ + if( !setargs ){ + snprintf(tbuf, SZ_LINE, "%d ", 1); + __FiltLexCat(tbuf, &(filtseg[nfiltseg-1]->regions), + &(filtseg[nfiltseg-1]->nr)); + __FiltLexCat(tbuf, &(filtseg[nfiltseg-1]->shapes), + &(filtseg[nfiltseg-1]->ns)); + } + + /* finish off region string */ + _FiltLexCat(FilterLexRegion2(filt,")")); + + /* no column arguments */ + colargs = 0; + /* arguments are not set */ + setargs = 0; + /* save angle not set */ + *saveang = 0; +} + +#ifdef YY_USE_PROTOS +static int +_FiltLexRegionPanda(void) +#else +static int +_FiltLexRegionPanda() +#endif +{ + int i; + int n=0; + int got=0; + int a, r; + int ahi=0, rhi=0; + int hi=0; + double d[11]; + double ainc=0.0, rinc=0.0; + char tbuf[SZ_LINE]; + char *s=NULL; + char *t, *u; + + switch(regid){ + case TY_PANDA: + case TY_CPANDA: + hi = 7; + break; + case TY_BPANDA: + case TY_EPANDA: + hi = 10; + break; + default: + _filterror("unknown panda type -- contact saord@cfa.harvard.edu"); + break; + } + s = xstrdup(filtseg[nfiltseg-1]->s); + for(i=hi; i>=0; i--){ + /* look for last comma */ + t = strrchr(s, ','); + if( !t ) goto done; + /* null it out from base string */ + *t = '\0'; + /* point past comma and get double value */ + t++; + d[i] = strtod(t, &u); + if( t == u ) goto done; + } + + switch(regid){ + case TY_PANDA: + case TY_CPANDA: + ainc = (d[3] - d[2])/d[4]; + ahi = (int)d[4]; + rinc = (d[6] - d[5])/d[7]; + rhi = (int)d[7]; + break; + case TY_BPANDA: + case TY_EPANDA: + ainc = (d[3] - d[2])/d[4]; + ahi = (int)d[4]; + rinc = (d[7] - d[5])/d[9]; + rhi = (int)d[9]; + break; + default: + _filterror("unknown panda type -- contact saord@cfa.harvard.edu"); + break; + } + /* process limits arguments */ + for(a=1; a<=ahi; a++){ + for(r=1; r<=rhi; r++){ + snprintf(tbuf, SZ_LINE, DFMT4, + d[5]+((r-1)*rinc), d[5]+(r*rinc), + d[2]+((a-1)*ainc), d[2]+(a*ainc)); + __FiltLexCat(tbuf, &(filtseg[nfiltseg-1]->radang), + &(filtseg[nfiltseg-1]->ralen)); + __FiltLexCat("\n", &(filtseg[nfiltseg-1]->radang), + &(filtseg[nfiltseg-1]->ralen)); + n++; + } + } + + /* adjust region and shape count */ + snprintf(tbuf, SZ_LINE, "%d ", n); + __FiltLexCat(tbuf, &(filtseg[nfiltseg-1]->regions), + &(filtseg[nfiltseg-1]->nr)); + snprintf(tbuf, SZ_LINE, "%d ", 2*n); + __FiltLexCat(tbuf, &(filtseg[nfiltseg-1]->shapes), + &(filtseg[nfiltseg-1]->ns)); + _FiltLexTypeSet(TOK_ACCEL); + /* success */ + got = 1; + +done: + if( s ) xfree(s); + return got; +} + +/* + * + * _FiltLexRangeAdd -- add a rangelist string to the filter string buffer + * + */ +#ifdef YY_USE_PROTOS +static void +_FiltLexRangeAdd(char *xname, char *str, int type, int n, int maxlen) +#else +static void _FiltLexRangeAdd(xname, str, type, n, maxlen) + char *xname; + char *str; + int type; + int n; + int maxlen; +#endif +{ + char tbuf[SZ_LINE]; + char tbuf2[SZ_LINE]; + char *s; + char *t; + char *t2; + char *name; + + /* get "in-expression" name for current technique */ + name = FilterLexName(filt, xname); + + /* initialize pointers */ + s = str; + t = tbuf; + + /* clear working buffer */ + memset(t, 0, SZ_LINE); + + /* if this is not the beginning, we first need to OR with prev */ + if( n != 0 ) strncat(t, "||", maxlen-1); + + /* put in parens for safety */ + strncat(t, "(", maxlen-1); + + /* add the name */ + strncat(t, name, maxlen-1); + + /* add the rangelist */ + switch(type){ + case 1: + strncat(t, "<=", maxlen-1); + /* skip past : */ + s++; + /* append value */ + t2 = tbuf2; + while( *s ){ + *t2++ = *s++; + } + *t2 = '\0'; + bin2num(tbuf2, tbuf2, maxlen-1); + strncat(t, tbuf2, maxlen-1); + break; + case 2: + strncat(t, "==", maxlen-1); + /* append upper value */ + t2 = tbuf2; + while( *s ){ + *t2++ = *s++; + } + *t2 = '\0'; + bin2num(tbuf2, tbuf2, maxlen-1); + strncat(t, tbuf2, maxlen-1); + break; + case 3: + strncat(t, ">=", maxlen-1); + /* append lower value */ + t2 = tbuf2; + while( *s && (*s != ':') ){ + *t2++ = *s++; + } + *t2 = '\0'; + bin2num(tbuf2, tbuf2, maxlen-1); + strncat(t, tbuf2, maxlen-1); + /* skip past : */ + s++; + strncat(t, "&&", maxlen-1); + strncat(t, name, maxlen-1); + strncat(t, "<=", maxlen-1); + /* append upper value */ + t2 = tbuf2; + while( *s ){ + *t2++ = *s++; + } + *t2 = '\0'; + bin2num(tbuf2, tbuf2, maxlen-1); + strncat(t, tbuf2, maxlen-1); + break; + case 4: + strncat(t, ">=", maxlen-1); + /* append lower value */ + t2 = tbuf2; + while( *s && (*s != ':') ){ + *t2++ = *s++; + } + *t2 = '\0'; + bin2num(tbuf2, tbuf2, maxlen-1); + strncat(t, tbuf2, maxlen-1); + break; + } + strncat(t, ")", maxlen-1); + _FiltLexCat(tbuf); +} + +/* + * + * _FiltLexTypeCmp -- compare routine for qsort + * + */ +#ifdef YY_USE_PROTOS +static int +_FiltLexTypeCmp(const void *s1, const void *s2) +#else +static int _FiltLexTypeCmp(s1, s2) + const void *s1; + const void *s2; +#endif +{ + FiltSeg *f1 = (FiltSeg *)s1; + FiltSeg *f2 = (FiltSeg *)s2; + + /* check for broken qsort */ + if( !*f1 || !*f2 ){ + _filterror("qsort is broken -- contact saord@cfa.harvard.edu"); + /* will not happen */ + return 0; + } + + /* make sure null string is at the end */ + if( !(*f1)->s && !(*f2)->s ) return 0; + else if( !(*f1)->s ) return 1; + else if( !(*f2)->s ) return -1; + + /* paint: reverse order and make excludes local */ + if( filt->paint ){ + /* if both are regions, reverse order */ + if( ((*f1)->type & TOK_REG) && ((*f2)->type & TOK_REG) ){ + if( (*f1)->n < (*f2)->n ) return 1; + else if( (*f1)->n > (*f2)->n ) return -1; + else return 0; + } + /* keep same order */ + else{ + if( (*f1)->n < (*f2)->n ) return -1; + else if( (*f1)->n > (*f2)->n ) return 1; + else return 0; + } + } + else{ + /* if both or neither are eregions, keep them in the same order */ + if( ((*f1)->type & TOK_EREG) == ((*f2)->type & TOK_EREG) ){ + if( (*f1)->n < (*f2)->n ) return -1; + else if( (*f1)->n > (*f2)->n ) return 1; + else return 0; + } + /* exactly one is an eregion -- and we want eregions last */ + else{ + if( (*f1)->type & TOK_EREG ) return 1; + else if( (*f2)->type & TOK_EREG ) return -1; + /* should not happen */ + else return 0; + } + } +} + +/* + * + * _FiltLexTypeMatch -- see if the type of filtering we are doing + * matches the type of token we have + * + */ +#ifdef YY_USE_PROTOS +int +_FiltLexTypeMatch(int ftype, int ttype) +#else +int _FiltLexTypeMatch(ftype, ttype) + int ftype; + int ttype; +#endif +{ + switch(ftype){ + case TYPE_IMAGE: + /* we don't allow range list and col names in image filters */ + if( (ttype & TOK_RLIST) || (ttype & TOK_NAME) ) + return 0; + /* everything else is fine */ + else + return 1; + case TYPE_EVENTS: + return 1; + default: + return 1; + } +} + +#ifdef YY_USE_PROTOS +static int +_FiltLexArgCheck(char *name, int args) +#else +static int _FiltLexArgCheck(name, args) + char *name; + int args; +#endif +{ + int i; + + for(i=0; rnames[i]; i++){ + if( !strcmp(name, rnames[i]) ){ + if( args == rargs[i] ){ + return(0); + } + else{ + /* less than required min */ + if( args < rargs[i] ) + return(i+1); + /* more than min args -- could be varargs */ + else{ + /* check args allowed in varargs */ + switch(vargs[i]){ + case 'e': + if( (args%2) == 0 ) + return(-1); + else + return(i+1); + case 'o': + if( (args%2) == 1 ) + return(-1); + else + return(i+1); + case 'y': + return(-1); + default: + return(i+1); + } + } + } + } + } + return(0); +} + +#ifdef YY_USE_PROTOS +static void +_FiltLexSetWcs(char *s) +#else +static void _FiltLexSetWcs(s) + char *s; +#endif +{ + char name[SZ_LINE]; + int ip=0; + + newdtable(",=;"); + /* get name of global coordsys */ + if( word(s, name, &ip) ){ + if( gcoordsys ) xfree(gcoordsys); + gcoordsys = xstrdup(name); + culc(gcoordsys); + } + /* restore old delim table */ + freedtable(); +} + +#ifdef YY_USE_PROTOS +static char * +_FiltLexCB(char *name, void *client_data) +#else +static char *_FiltLexCB(name, client_data) + char *name; + void *client_data; +#endif +{ + FiltSeg f=(FiltSeg)client_data; + int ip=0; + int nr=0; + int ns=0; + char *s; + char tbuf[SZ_LINE]; + + if( !strcmp(name, "RS") ){ + /* exclude regions get no region value first time around */ + if( (macropass==0) && (f->type & TOK_EREG) ){ + return NULL; + } + /* get next region value and remove from string */ + if( word(f->regions, tbuf, &ip) ){ + nr = atoi(tbuf); + s = xstrdup(&(f->regions[ip])); + xfree(f->regions); + f->regions = s; + } + else{ + _filterror("internal error: no region string specified"); + return(NULL); + } + if( !inexpr || (f->type & (TOK_ACCEL|TOK_VARARGS)) ){ + if( f->regval ){ + snprintf(macrobuf, SZ_LINE, "%d,", f->regval); + } + else{ + snprintf(macrobuf, SZ_LINE, "%d,", nregion+1); + } + nregion += nr; + f->nregion += nr; + inexpr = 1; + } + else{ + if( f->regval ){ + snprintf(macrobuf, SZ_LINE, "%d,", f->regval); + } + else{ + snprintf(macrobuf, SZ_LINE, "%d,", nregion); + } + } + + /* get next shape value and remove from string */ + ip = 0; + if( word(f->shapes, tbuf, &ip) ){ + ns = atoi(tbuf); + s = xstrdup(&(f->shapes[ip])); + xfree(f->shapes); + f->shapes = s; + } + else{ + _filterror("internal error: no shape string specified"); + return(NULL); + } + /* concat shape value */ + nshape++; + snprintf(tbuf, SZ_LINE, "%d", nshape); + strcat(macrobuf, tbuf); + /* set new shape value */ + nshape += (ns-1); + + /* return macro value */ + return(macrobuf); + } + else{ + return NULL; + } +} + +/* + * + * _FiltLexNeedOp -- determine if we add a connecting operator for this segment + * + */ +#ifdef YY_USE_PROTOS +static int +_FiltLexNeedOp(int i, char *s) +#else +static int _FiltLexNeedOp(i, s) + int i; + char *s; +#endif +{ + int c; + /* check for operator in current string */ + if( s && *s ){ + c = *s; + switch(c){ + case '&': + case '|': + case '=': + case '!': + case '<': + case '>': + return 0; + default: + break; + } + } + /* not in this string check for operator in previous */ + for(i=i-1; i>=0; i--){ + if( !filtseg[i] || !filtseg[i]->s ) continue; + if( strcmp(filtseg[i]->s, "(") && strcmp(filtseg[i]->s, ")") ) + break; + } + if( i >= 0 ){ + c = filtseg[i]->s[strlen(filtseg[i]->s)-1]; + switch(c){ + case '&': + case '|': + case '=': + case '!': + case '<': + case '>': + return 0; + default: + return 1; + } + } + else{ + return 0; + } +} + +/* + * + * _FiltLexMake -- generate filter from filter segments + * + */ +#ifdef YY_USE_PROTOS +static void +_FiltLexMake(void) +#else +static void _FiltLexMake() +#endif +{ + int i, j, k, l; + int x, xtot; + int type=0; + int ltype=0; + int opar=0; + char *s; + + /* debugging */ + if( filt->debug ){ + for(i=0; is ) + fprintf(stderr, "unsorted #%d %s\n", filtseg[i]->n, filtseg[i]->s); + else + fprintf(stderr, "unsorted #%d %d is empty\n", i, filtseg[i]->n); + } + } + /* look for bad region expressions and determine how many regions we have */ + for(i=0, j=0, k=0, l=0; is ) continue; + type = filtseg[i]->type; + /* make sure we want the type being offered */ + if( !_FiltLexTypeMatch(filt->type, type) ){ + _filterror("column filters not permitted in an image filter expression"); + } + /* look for bad combinations */ + if( (type & TOK_NREG) && !(type & TOK_IREG) ) + _filterror("!region must be combined with another region (e.g., field()&&!region)"); + if( (type & TOK_EREG) && (type & TOK_IREG) ) + _filterror("-region must not be combined with another region (use !region instead)"); + if( (type & TOK_EREG) && (type & TOK_NAME) ) + _filterror("-region must not be combined with filters (use !region instead)"); + if( (type & TOK_EREG) && (type & TOK_RLIST) ) + _filterror("-region must not be combined with range lists (use !region instead)"); + if( (type & TOK_EREG) && (type & TOK_RTINE) ) + _filterror("-region must not be combined with routines (use !region instead)"); + /* count region types */ + if( filtseg[i]->type & TOK_IREG ) j++; + if( filtseg[i]->type & TOK_NREG ) k++; + if( filtseg[i]->type & TOK_EREG ) l++; + } + /* check for fits image mask and process specially */ + if( filt->masks ){ + /* can't have fits mask and ascii regions */ + if( j || k || l ){ + _filterror("FITS image masks cannot be combined with ASCII regions"); + } + /* image filtering of events uses a imagemask special routine */ + if( (filt->type == TYPE_EVENTS) && filt->evsect ){ + strcpy(yytext, "imagemask"); + _FiltLexRegionStart(1); + _FiltLexRegionEnd(); + } + else{ + __FiltLexCat("imagemask", &filter, &filtlen); + nregion = filt->nmaskreg; + return; + } + } + /* if we have only exclude regions, add field */ + if( !j && !k && l ){ + strcpy(yytext, "field"); + if( filt->type == TYPE_EVENTS ) + _FiltLexRegionStart(1); + else + _FiltLexRegionStart(0); + _FiltLexRegionEnd(); + } + + /* reset region and shape counts */ + nregion=0; + nshape=0; + + /* expand macro before reordering, to maintain region numbers in sequence */ + for(i=0; is ){ + if( _FiltLexNeedOp(i, NULL) ) inexpr=0; + macropass=0; + s = ExpandMacro(filtseg[i]->s, NULL, NULL, 0, _FiltLexCB, filtseg[i]); + xfree(filtseg[i]->s); + filtseg[i]->s = s; + } + } + + /* we want descending order so that eregions are last in the expression */ + qsort(filtseg, nfiltseg, sizeof(FiltSeg), _FiltLexTypeCmp); + + if( filt->debug ){ + for(i=0; is ) + fprintf(stderr, "sorted #%d %s\n", filtseg[i]->n, filtseg[i]->s); + else + fprintf(stderr, "sorted #%d %d is empty\n", i, filtseg[i]->n); + } + } + + /* add open paren and mark that we did it */ + __FiltLexCat("(", &filter, &filtlen); + opar = 1; + + /* run through segments, inserting proper boolean connectors */ + ltype = 0; + for(i=0; is ){ + /* no type probably means its a paren, so just add it and jump out */ + if( !filtseg[i]->type ){ + __FiltLexCat(filtseg[i]->s, &filter, &filtlen); + /* remove empty parens, if we just make them */ + x = strlen(filter); + if( (filter[x-2] == '(') && (filter[x-1] == ')') ) + filter[x-2] = '\0'; + i++; + continue; + } + type = filtseg[i]->type; + if( _FiltLexNeedOp(i, NULL) ) inexpr=0; + macropass=1; + s = ExpandMacro(filtseg[i]->s, NULL, NULL, 0, _FiltLexCB, filtseg[i]); + if( _FiltLexNeedOp(i, s) ){ + /* remove trailing open parens from prev. segment (add back later) */ + for(xtot=0, x=strlen(filter)-1; x>=0; x--){ + if( filter[x] != '(' ) break; + filter[x] = '\0'; + xtot++; + } + if( (ltype & TOK_IREG) && (type & TOK_IREG) ){ + __FiltLexCat("||", &filter, &filtlen); + } + else if( (ltype & TOK_IREG) && (type & TOK_EREG) ){ + if( opar > 0 ){ + __FiltLexCat(")", &filter, &filtlen); + opar--; + } + if( filt->paint ){ + if( opar > 0 ){ + __FiltLexCat(")", &filter, &filtlen); + opar --; + } + __FiltLexCat("||", &filter, &filtlen); + } + else{ + __FiltLexCat("&&", &filter, &filtlen); + } + __FiltLexCat("(", &filter, &filtlen); + opar++; + } + else if( (ltype & TOK_EREG) && (type & TOK_EREG) ){ + __FiltLexCat("&&", &filter, &filtlen); + } + else if( (ltype & TOK_EREG) && (type & TOK_IREG) ){ + if( filt->paint && (opar > 0) ){ + __FiltLexCat(")", &filter, &filtlen); + opar --; + } + __FiltLexCat("&&", &filter, &filtlen); + __FiltLexCat("(", &filter, &filtlen); + opar ++; + if( filt->paint ){ + __FiltLexCat("(", &filter, &filtlen); + opar++; + } + } + /* otherwise implied operator is AND */ + else{ + __FiltLexCat("&&", &filter, &filtlen); + } + /* add back parens */ + for(x=0; xpaint && (i==0) ){ + __FiltLexCat("((", &filter, &filtlen); + opar +=2; + } + } + __FiltLexCat(s, &filter, &filtlen); + if( s ) xfree(s); + if( filtseg[i]->radang ){ + if( *filtseg[i]->radang == ',' ) + __FiltLexCat(filtseg[i]->radang+1, &radang, &radanglen); + else + __FiltLexCat(filtseg[i]->radang, &radang, &radanglen); + } + else{ + __FiltLexCat("NA,NA,NA,NA\n", &radang, &radanglen); + } + i++; + for(; (itype==type); ){ + if( _FiltLexNeedOp(i, NULL) ) inexpr=0; + s = ExpandMacro(filtseg[i]->s, NULL, NULL, 0, _FiltLexCB, filtseg[i]); + if( _FiltLexNeedOp(i, s) ){ + for(xtot=0, x=strlen(filter)-1; x>=0; x--){ + if( filter[x] != '(' ) break; + filter[x] = '\0'; + xtot++; + } + /* if lhs and rhs are regions, implied operator is OR */ + if( type & TOK_IREG ) + __FiltLexCat("||", &filter, &filtlen); + /* otherwise implied operator is AND */ + else + __FiltLexCat("&&", &filter, &filtlen); + for(x=0; xradang ){ + if( *filtseg[i]->radang == ',' ) + __FiltLexCat(filtseg[i]->radang+1, &radang, &radanglen); + else + __FiltLexCat(filtseg[i]->radang, &radang, &radanglen); + } + else{ + __FiltLexCat("NA,NA,NA,NA\n", &radang, &radanglen); + } + i++; + } + } + /* ignore invalid arguments */ + else{ + i++; + } + /* save last type */ + ltype = type; + } + + /* if last segment was an exclude and we are in paint mode, ignore it */ + if( filt->paint && (ltype & TOK_EREG) ){ + __FiltLexCat("&&0", &filter, &filtlen); + } + + /* close off open parens (lots could be needed in paint mode) */ + while( opar-- ){ + __FiltLexCat(")", &filter, &filtlen); + } + + /* check for even number of parens */ + l = strlen(filter); + for(i=0, j=0; idebug ) fprintf(stderr, "paren error %d: %s\n", j, filter); + _filterror("unbalanced parentheses"); + } + if( filt->debug ) fprintf(stderr, "filter: %s\n", filter); +} + +/* + * + * _FiltLexEnd -- cleanup from parsing regions + * + */ +#ifdef YY_USE_PROTOS +static void +_FiltLexEnd(void) +#else +static void _FiltLexEnd() +#endif +{ + int i; + + /* reset state variables */ + colargs = 0; + initbindefs = 0; + include_stack_ptr = 0; + nroutine = 0; + nshape = 0; + nmask = 0; + nparen = 0; + parse_error = 0; + filtlen = 0; + radanglen = 0; + regid = 0; + regtype = 0; + inexpr = 0; + *regname = '\0'; + *saveang = 0; + *(wcsnames[0]) = '\0'; + *(wcsnames[1]) = '\0'; + binsiz[0] = 1; + binsiz[1] = 1; + /* free up previous filter */ + if( filter ){ + xfree(filter); + filter = NULL; + } + /* free up previous radang string */ + if( radang ){ + xfree(radang); + radang = NULL; + } + /* free up wcs */ + if( wcs ){ + wcsfree (wcs); + wcs = NULL; + } + /* no segments */ + if( filtseg ){ + for(i=0; is ) xfree(filtseg[i]->s); + if( filtseg[i]->regions ) xfree(filtseg[i]->regions); + if( filtseg[i]->shapes ) xfree(filtseg[i]->shapes); + if( filtseg[i]->radang ) xfree(filtseg[i]->radang); + xfree(filtseg[i]); + } + } + xfree(filtseg); + filtseg = NULL; + } + maxfiltseg = 0; + nfiltseg = 0; + if( gcoordsys ){ + xfree(gcoordsys); + gcoordsys = NULL; + } + if( fcoordsys ){ + xfree(fcoordsys); + fcoordsys = NULL; + } + cdelt1 = 0.0; + cdelt2 = 0.0; + crot = 0.0; +} + +/* + * + * _FiltLexGetWcs -- determine the WCS coord system to use for wcsc translation + * + */ +#ifdef YY_USE_PROTOS +static char * +_FiltLexGetWcs(void) +#else +static char *_FiltLexGetWcs() +#endif +{ + if( gcoordsys && + strcmp(gcoordsys, "image") && strcmp(gcoordsys, "physical") ) + return gcoordsys; + if( fcoordsys && + strcmp(fcoordsys, "image") && strcmp(fcoordsys, "physical") ) + return fcoordsys; + return NULL; +} + +/* + * + * _FiltLexWcsCols -- reset WCS for these columns + * + */ +#ifdef YY_USE_PROTOS +static void +_FiltLexWcsCols(FITSHead iheader, char *name0, char *name1) +#else +static void _FiltLexWcsCols(iheader, name0, name1) + FITSHead iheader; + char *name0; + char *name1; +#endif +{ + int i, which, ival; + int simple=1; + double dval, dval2; + char *s; + FITSHead oheader; + FITSCard card; + + /* make sure we have something to process */ + if( !iheader ) + return; + + if( filt->fhd->image ){ + /* free up old wcs */ + if( wcs ) wcsfree (wcs); + /* init new wcs */ + hlength(ft_cards(filt->fhd),0); + wcs = wcsinit(ft_cards(filt->fhd)); + tltyp[0] = 0; + tltyp[1] = 0; + } + /* for tables, we can init wcs only the specified columns */ + else if( name0 && *name0 && name1 && *name1 ){ + /* see if these are the same as the last set of columns */ + if( (*(wcsnames[0]) && !strcasecmp(name0,wcsnames[0])) && + (*(wcsnames[1]) && !strcasecmp(name1,wcsnames[1])) && wcs ){ + return; + } + + /* gather up important tl info about the binning columns */ + for(i=1; i<=iheader->table->tfields; i++){ + /* determine which bincol we are processing */ + if( !strcasecmp(iheader->table->col[i-1].name, name0) ) + which = 0; + else if( !strcasecmp(iheader->table->col[i-1].name, name1) ) + which = 1; + else + continue; + /* set tlinfo values for this column */ + tlmin[which] = ft_headgetr(iheader, "TLMIN", i, 1.0, &card); + tlmax[which] = ft_headgetr(iheader, "TLMAX", i, 1.0, &card); + binsiz[which] = ft_headgetr(iheader, "TDBIN", i, 1.0, &card); + tltyp[which] = iheader->table->col[i-1].type; + } + + /* free up old wcs */ + if( wcs ) wcsfree (wcs); + /* make a copy of the header */ + oheader = ft_headcopy(iheader); + + /* make sure this is a primary FITS file */ + ft_cardfmt((FITSCard)oheader->cards, + "SIMPLE", 0, FT_LOGICAL, &simple, 0, "Standard FITS"); + /* set dimension info, used by wcs code */ + ft_headseti(oheader, "NAXIS", 0, 2, "number of axes", 1); + /* set dimension info */ + for(i=0; i<=1; i++){ + ival = (int)tldim(tlmin[i], tlmax[i], binsiz[i], tltyp[i]); + ft_headseti(oheader, "NAXIS", i+1, ival, "axis dimension", 1); + } + /* set bitpix */ + ft_headseti(oheader, "BITPIX", 0, 32, "bits/pixel", 1); + /* synchronize the header and the cards after any changes */ + ft_syncdata(oheader); + + /* transform WCS cards for the specified columns, if we have such */ + for(i=1; i<=iheader->table->tfields; i++){ + /* determine which bincol we are processing */ + if( !strcasecmp(iheader->table->col[i-1].name, name0) ) + which = 0; + else if( !strcasecmp(iheader->table->col[i-1].name, name1) ) + which = 1; + else + continue; + /* convert event wcs header info image wcs info */ + if( (s=ft_headgets(iheader, "TCTYP", i, NULL, &card)) && card ){ + ft_headapps(oheader, "CTYPE", which+1, s, NULL); + xfree(s); + } + if( (s=ft_headgets(iheader, "TCRVL", i, NULL, &card)) && card ){ + ft_headappv(oheader, "CRVAL", which+1, s, NULL); + xfree(s); + } + if( (s=ft_headgets(iheader, "TCDLT", i, NULL, &card)) && card ){ + ft_headappv(oheader, "CDELT", which+1, s, NULL); + xfree(s); + } + if( (s=ft_headgets(iheader, "TCROT", i, NULL, &card)) && card ){ + ft_headappv(oheader, "CROTA", which+1, s, NULL); + xfree(s); + } + /* this value gets converted from physical to image */ + if( (dval=ft_headgetr(iheader, "TCRPX", i, 0.0, &card)) && card ){ + dval2 = tlp2i(dval, tlmin[which], binsiz[which], tltyp[which]); + ft_headsetr(oheader, "CRPIX", which+1, dval2, 7, NULL, 1); + } + } + + /* init new wcs */ + hlength(ft_cards(oheader),0); + wcs = wcsinit(ft_cards(oheader)); + ft_headfree(oheader, 1); + /* save names for next time */ + strcpy(wcsnames[0], name0); + strcpy(wcsnames[1], name1); + } + + /* set some extra wcs parameters */ + if( wcs && iswcs(wcs) ){ + if( fcoordsys ) xfree(fcoordsys); + fcoordsys = xstrdup(wcs->radecin); + culc(fcoordsys); + if( !wcs->coorflip ){ + cdelt1 = wcs->cdelt[0]; + cdelt2 = wcs->cdelt[1]; + } + else{ + cdelt1 = wcs->cdelt[1]; + cdelt2 = wcs->cdelt[0]; + } + if ( wcs->imflip ) { + crot = -wcs->rot; + } else { + crot = wcs->rot; + } + } + else{ + cdelt1 = 0.0; + cdelt2 = 0.0; + crot = 0.0; + } + /* set global coord system first time through */ + if( !gcoordsys ){ + if( (gcoordsys=xstrdup(getenv("COORDSYS"))) == NULL ) + gcoordsys = xstrdup(DEFAULT_COORDSYS); + } +} + +/* + * + * _FiltLexLcx -- determine if we have a linear-type WCS + * + */ +#ifdef YY_USE_PROTOS +static int +_FiltLexLcx(void) +#else +static int _FiltLexLcx() +#endif +{ + char *coordsys; + coordsys = gcoordsys; + if( !coordsys || !*coordsys ) + return 0; + if( !strcasecmp(coordsys, "image") ) return LCX_IMAGE; + if( !strcasecmp(coordsys, "physical") ) return LCX_PHYS; + if( !strcasecmp(coordsys, "amplifier") ) return LCX_AMP; + if( !strcasecmp(coordsys, "detector") ) return LCX_DET; + return 0; +} + +#ifdef YY_USE_PROTOS +static void +_FiltLexNum(int lcx) +#else +static void _FiltLexNum(lcx) + int lcx; +#endif +{ + char tbuf[SZ_LINE]; + + /* process binary number, if necessary */ + bin2num(tbuf, yytext, SZ_LINE); + + /* for linear coordinate systems (physical, amps, etc.), + we have to convert to image coords or physical coords, + depending on the type of data and type of filtering */ + if( lcx ){ + /* data is in a table: we can use image or physical coords */ + if( filt->fhd->table ){ + /* if we want to use physical coordinates ... */ + if( USEPHYS ){ + /* convert image positions to physical coords */ + if( lcx == LCX_IMAGE ){ + if( POSARG ){ + dval = tli2p(strtod(tbuf,NULL), + tlmin[(narg+1)%2], binsiz[(narg+1)%2], tltyp[(narg+1)%2]); + snprintf(sbuf, SZ_LINE, DFMT1, dval); + _FiltLexCat(sbuf); + _FiltLexArgSave(dval); + } + /* angle arguments are just passed along */ + else if( ANGARG ){ + dval = strtod(tbuf,NULL); + snprintf(sbuf, SZ_LINE, DFMT1, dval); + _FiltLexCat(sbuf); + _FiltLexArgSave(dval); + } + /* panda numeric args are just passed along */ + else if( NUMARG ){ + dval = strtod(tbuf,NULL); + snprintf(sbuf, SZ_LINE, DFMT1, dval); + _FiltLexCat(sbuf); + } + /* size arguments have to be converted using the binsize */ + else{ + if( SAVEANG ){ + dval = strtod(tbuf,NULL); + snprintf(saveang, SZ_LINE, DFMT1, dval); + } + dval = strtod(tbuf,NULL) * binsiz[(narg+1)%2]; + snprintf(sbuf, SZ_LINE, DFMT1, dval); + _FiltLexCat(sbuf); + _FiltLexArgSave(dval); + } + } + /* already in physical -- just pass along args */ + else{ + dval = strtod(tbuf,NULL); + snprintf(sbuf, SZ_LINE, DFMT1, dval); + _FiltLexCat(sbuf); + _FiltLexArgSave(dval); + } + } + /* we are using image coords (image-style filtering) */ + else{ + /* convert non-image positions to image coords */ + if( lcx != LCX_IMAGE ){ + if( POSARG ){ + dval = tlp2i(strtod(tbuf,NULL), + tlmin[(narg+1)%2], binsiz[(narg+1)%2], tltyp[(narg+1)%2]); + snprintf(sbuf, SZ_LINE, DFMT1, dval); + _FiltLexCat(sbuf); + _FiltLexArgSave(dval); + } + /* angle arguments are just passed along */ + else if( ANGARG ){ + dval = strtod(tbuf,NULL); + snprintf(sbuf, SZ_LINE, DFMT1, dval); + _FiltLexCat(sbuf); + _FiltLexArgSave(dval); + } + /* panda numeric args are just passed along */ + else if( NUMARG ){ + dval = strtod(tbuf,NULL); + snprintf(sbuf, SZ_LINE, DFMT1, dval); + _FiltLexCat(sbuf); + } + /* size arguments have to be converted using the binsize */ + else{ + if( SAVEANG ){ + dval = strtod(tbuf,NULL); + snprintf(saveang, SZ_LINE, DFMT1, dval); + } + dval = strtod(tbuf,NULL) / binsiz[(narg+1)%2]; + snprintf(sbuf, SZ_LINE, DFMT1, dval); + _FiltLexCat(sbuf); + _FiltLexArgSave(dval); + } + } + /* already in image -- just pass along args */ + else{ + dval = strtod(tbuf,NULL); + snprintf(sbuf, SZ_LINE, DFMT1, dval); + _FiltLexCat(sbuf); + _FiltLexArgSave(dval); + } + } + } + /* data is in an image: we use image coords */ + else{ + /* convert positional arguments to image */ + if( POSARG ){ + /* save x value for processing with y next time */ + if( XARG ){ + xpos = SAOstrtod(tbuf,NULL); + } + else{ + ypos = SAOstrtod(tbuf,NULL); + switch(lcx){ + case LCX_IMAGE: + xpix = xpos; + ypix = ypos; + break; + case LCX_PHYS: + ft_phy2img(filt->fhd, xpos, ypos, &xpix, &ypix); + break; + case LCX_AMP: + ft_amp2phy(filt->fhd, xpos, ypos, &dval, &dval2); + ft_phy2img(filt->fhd, dval, dval2, &xpix, &ypix); + break; + case LCX_DET: + ft_det2phy(filt->fhd, xpos, ypos, &dval, &dval2); + ft_phy2img(filt->fhd, dval, dval2, &xpix, &ypix); + break; + } + snprintf(sbuf, SZ_LINE, DFMT2, xpix, ypix); + _FiltLexCat(sbuf); + } + } + /* angle arguments are just passed along, with updated crot */ + else if( ANGARG ){ + dval = strtod(tbuf,NULL); + if( USEWCS ) dval += crot; + if( IMFLIP ) dval = -dval; + snprintf(sbuf, SZ_LINE, DFMT1, dval); + _FiltLexCat(sbuf); + } + /* panda numeric args are just passed along */ + else if( NUMARG ){ + dval = strtod(tbuf,NULL); + snprintf(sbuf, SZ_LINE, DFMT1, dval); + _FiltLexCat(sbuf); + } + /* convert size args, which may or may not be in pairs */ + else{ + if( SAVEANG ){ + dval = strtod(tbuf,NULL); + if( USEWCS ) dval += crot; + if( IMFLIP ) dval = -dval; + snprintf(saveang, SZ_LINE, DFMT1, dval); + } + /* arg 1 is associated with ra, arg2 with dec */ + if( XARG ){ + xpos = ABS(strtod(tbuf,NULL)); + ypos = 0.0; + switch(lcx){ + case LCX_IMAGE: + xpix = xpos; + break; + case LCX_PHYS: + ft_phy2img_size(filt->fhd, xpos, ypos, &xpix, &ypix); + break; + case LCX_AMP: + ft_amp2phy_size(filt->fhd, xpos,ypos, &dval,&dval2); + ft_phy2img_size(filt->fhd, dval,dval2, &xpix,&ypix); + break; + case LCX_DET: + ft_det2phy_size(filt->fhd, xpos,ypos, &dval,&dval2); + ft_phy2img_size(filt->fhd, dval,dval2, &xpix,&ypix); + break; + } + snprintf(sbuf, SZ_LINE, DFMT1, xpix); + _FiltLexArgSave(xpix); + } + else{ + xpos = 0.0; + ypos = ABS(strtod(tbuf,NULL)); + switch(lcx){ + case LCX_IMAGE: + ypix = ypos; + break; + case LCX_PHYS: + ft_phy2img_size(filt->fhd, xpos, ypos, &xpix, &ypix); + break; + case LCX_AMP: + ft_amp2phy_size(filt->fhd, xpos,ypos, &dval,&dval2); + ft_phy2img_size(filt->fhd, dval,dval2, &xpix,&ypix); + break; + case LCX_DET: + ft_det2phy_size(filt->fhd, xpos,ypos, &dval,&dval2); + ft_phy2img_size(filt->fhd, dval,dval2, &xpix,&ypix); + break; + } + snprintf(sbuf, SZ_LINE, DFMT1, ypix); + _FiltLexArgSave(ypix); + } + _FiltLexCat(sbuf); + } + } + } + /* not lcx -- angle arguments are just passed along with updated crot */ + else if( ANGARG ){ + dval = strtod(tbuf,NULL); + if( USEWCS ) dval += crot; + if( IMFLIP ) dval = -dval; + snprintf(sbuf, SZ_LINE, DFMT1, dval); + _FiltLexCat(sbuf); + } + /* panda numeric args are just passed along */ + else if( NUMARG ){ + dval = strtod(tbuf,NULL); + snprintf(sbuf, SZ_LINE, DFMT1, dval); + _FiltLexCat(sbuf); + } + /* not lcx -- everything else is assumed to be in units of "degrees" + in the default system. add 'd' and put back for reparsing */ + else{ + int i; + char *yycopy = xstrdup(tbuf); + unput('d'); + for(i=yyleng-1; i>=0; --i) + unput(yycopy[i]); + xfree(yycopy); + narg--; + } +} + +#ifdef YY_USE_PROTOS +static int +_FiltIncMask(FilterMask masks, int maxmask, int nmask) +#else +static int _FiltIncMask(masks, maxmask, nmask) + FilterMask masks; + int maxmask; + int nmask; +#endif +{ + int omax; + nmask++; + if( nmask >= maxmask ){ + omax = maxmask; + maxmask += MASKINC; + masks = (FilterMask)xrealloc(masks, maxmask*sizeof(FilterMaskRec)); + memset(masks+omax, 0, (maxmask-omax)*sizeof(FilterMaskRec)); + } + return nmask; +} + +#ifdef YY_USE_PROTOS +static int +_FiltFitsMask(char *filename, FilterMask *rmasks, FITSHead *rhead, int *nreg) +#else +static int _FiltFitsMask(filename, rmasks, rhead, nreg) + char *filename; + FilterMask *rmasks; + FITSHead *rhead; + int *nreg; +#endif +{ + short *dptr; + short *data=NULL; + int x, y; + int maxreg=-1; + int maxmask; /* max masks allocated thus far */ + int nmask=0; /* number of mask segments */ + FilterMask masks=NULL; /* array valid region masks for one row */ + FITSHead head=NULL; + + /* read fits image */ + if( !ft_simpleimageread(filename, &head, (void *)&data, NULL, 16) ){ + return(-1); + } + if( !head->image ){ + if( data ) xfree(data); + if( head ) ft_headfree(head, 1); + return(-2); + } + if( !ft_naxes(head) || !ft_naxis(head, 1) || !ft_naxis(head, 2) ){ + if( data ) xfree(data); + if( head ) ft_headfree(head, 1); + return(-3); + } + + /* allocate an array of masks, which will be returned to caller */ + maxmask = MASKINC; + masks = (FilterMask)xcalloc(maxmask, sizeof(FilterMaskRec)); + /* seed the first region mask value */ + masks[nmask].region = 0; + /* loop through y rows */ + for(y=1; y<=ft_naxis(head, 2); y++){ + dptr = data + ((y-1) * ft_naxis(head, 1)); + /* to start this line, we make a seed mask with no region */ + if( masks[nmask].region ){ + nmask = _FiltIncMask(masks, maxmask, nmask); + masks[nmask].region = 0; + } + /* process each pixel in the row */ + for(x=1; x<=ft_naxis(head, 1); x++, dptr++){ + /* we do not allow negative values */ + if( *dptr < 0 ){ + if( data ) xfree(data); + if( head ) ft_headfree(head, 1); + if( masks ) xfree(masks); + return(-4); + } + /* set max region as needed */ + if( *dptr > maxreg ) + maxreg = *dptr; + /* look for a change in the mask */ + if( *dptr != masks[nmask].region ){ + /* if previous was non-zero region, finish it and bump to next */ + if( masks[nmask].region ){ + masks[nmask].xstop = x - 1; + nmask = _FiltIncMask(masks, maxmask, nmask); + } + masks[nmask].y = y; + masks[nmask].region = *dptr; + masks[nmask].xstart = x; + } + } + /* finish last non-zero segment, inc number of mask segs */ + if( masks[nmask].region ){ + masks[nmask].xstop = x; + nmask = _FiltIncMask(masks, maxmask, nmask); + } + } + + /* free up data space */ + if( data ) xfree(data); + /* allocate just enough mask space */ + masks = (FilterMask)xrealloc(masks, nmask*sizeof(FilterMaskRec)); + if( rmasks ) + *rmasks = masks; + else + xfree(masks); + if( rhead ) + *rhead = head; + else + ft_headfree(head, 1); + if( nreg ) + *nreg = maxreg; + + return(nmask); +} + +/* + * + * Semi-public Routines + * + * + */ + +/* + * + * _FilterString -- return output filter from lexer + * + */ +#ifdef YY_USE_PROTOS +char * +_FilterString(void) +#else +char *_FilterString() +#endif +{ + if( filtlen <= 0 ) + _FiltLexMake(); + return(filter); +} + +#ifdef YY_USE_PROTOS +int +FilterRoutineCount(void) +#else +int FilterRoutineCount() +#endif +{ + return(nroutine); +} + +#ifdef YY_USE_PROTOS +int +FilterShapeCount(void) +#else +int FilterShapeCount() +#endif +{ + return(nshape); +} + +#ifdef YY_USE_PROTOS +int +FilterRegionCount(int type) +#else +int FilterRegionCount(type) + int type; +#endif +{ + int i, j; + + /* handle fits image masks specially */ + if( nmask ){ + if( type & TOK_IREG ) + return(nregion); + else + return(0); + } + + /* normal regions */ + for(i=0, j=0; itype & type ){ + j += filtseg[i]->nregion; + } + } + return(j); +} + +#ifdef YY_USE_PROTOS +char * +FilterRadAng(void) +#else +char *FilterRadAng() +#endif +{ + return(radang); +} + +#ifdef YY_USE_PROTOS +int +FilterParseError(void) +#else +int FilterParseError() +#endif +{ + return(parse_error); +} + +#ifdef YY_USE_PROTOS +int +FilterTlInfo(double *tlmins, double *binsizs, int *tltyps) +#else +int FilterTlInfo(tlmins, binsizs, tltyps) + double *tlmins; + double *binsizs; + int *tltyps; +#endif +{ + tlmins[0] = tlmin[0]; + tlmins[1] = tlmin[1]; + binsizs[0] = binsiz[0]; + binsizs[1] = binsiz[1]; + tltyps[0] = tltyp[0]; + tltyps[1] = tltyp[1]; + return 1; +} + +#ifdef YY_USE_PROTOS +void +FiltInitParser(void) +#else +void FiltInitParser() +#endif +{ + static int parser = 0; + /* make sure we free'd up all space from last time */ + _FiltLexEnd(); + /* set up some convenience variables */ + filt = FilterDefault(); +/* + if( parser ) + yyrestart(NULL); +*/ + BEGIN INITIAL; + parser++; + laststart=INITIAL; +} + +#ifdef YY_USE_PROTOS +void +FiltScanString(char *s) +#else +void FiltScanString(s) + char *s; +#endif +{ + int i; + char *t; + /* make sure there is an explicit delim at end so we are done before + lex finds EOF -- otherwise panda shapes don't get processed */ + i = strlen(s); + t = xmalloc(i+2); + strcpy(t, s); + if( (t[i-1] != ';') && (t[i-1] != '\n') ) + strcat(t, "\n"); + yy_scan_string(t); + if( t ) xfree(t); +} + +/* yyerror -- renamed to _filterror because flex -P does not change this */ +#ifdef YY_USE_PROTOS +int +_filterror(char *msg) +#else +int _filterror(msg) + char *msg; +#endif +{ + if( *yytext ) + gerror(stderr, "%s while parsing filter at: %s\n", + msg ? msg : "filterr", yytext); + else + gerror(stderr, "%s\n", msg ? msg : "filterr"); + YY_FLUSH_BUFFER; + parse_error = 1; + yyterminate(); +} + +#ifdef YY_USE_PROTOS +int yywrap(void) +#else +int yywrap() +#endif +{ + return 1; +} diff --git a/filter/filter.c b/filter/filter.c new file mode 100644 index 0000000..78d5383 --- /dev/null +++ b/filter/filter.c @@ -0,0 +1,1041 @@ +/* + * Copyright (c) 1999-2003 Smithsonian Astrophysical Observatory + */ + +/* + * + * filter.c -- hi-level management of filters + * + */ + +#include + +#if HAVE_CYGWIN||HAVE_MINGW32 +#include +#endif + +extern int idx_debug; + +/* + * + * private routines + * + */ + +/* this is needed by lex */ +static Filter default_filter = NULL; + +/* null filters return this special record */ +static FilterRec null_filter; + +#ifdef ANSI_FUNC +static void +FiltInitRegions(void) +#else +static void FiltInitRegions() +#endif +{ + initevregions(); + initimregions(); +} + +/* + * + * _FilterImageCmp -- compare routine for qsort + * + */ +#ifdef ANSI_FUNC +static int +_FilterImageCmp(const void *s1, const void *s2) +#else +static int _FilterImageCmp(s1, s2) + const void *s1; + const void *s2; +#endif +{ + FilterMask f1 = (FilterMask)s1; + FilterMask f2 = (FilterMask)s2; + + if( f1->y < f2->y ){ + return -1; + } + else if( f1->y > f2->y ){ + return 1; + } + else{ + if( f1->xstart < f2->xstart ){ + return -1; + } + else{ + return 1; + } + } +} + +/* + * + * semi-public routines, used by other modules + * + */ + +/* + * + * public routines + * + */ + +/* + * + * FilterClip -- save the filter without the enclosing brackets + * + */ +#ifdef ANSI_FUNC +char * +FilterClip(char *filter) +#else +char *FilterClip(filter) + char *filter; +#endif +{ + char *tbuf; + char *tptr; + char *ofilter; + int len; + int i; + + /* check for the obvious */ + if( !filter || (*filter == '\0') ) + return(NULL); + + /* save filter, but without the enclosing brackets */ + tbuf = xstrdup(filter); + nowhite(tbuf, tbuf); + tptr = tbuf; + if( *tbuf == '[' ){ + tptr++; + len = strlen(tptr); + for(i=len-1; i>=0; i-- ){ + if( tptr[i] == ']' ){ + tptr[i] = '\0'; + break; + } + } + } + if( tptr && (*tptr != '\0') ){ + /* we extend the buffer because flex has problems in filt_init_buffer + if its smaller than sizeof(FILE *) */ + ofilter = xcalloc(strlen(tptr)+SZ_LINE, sizeof(char)); + nowhite(tptr, ofilter); + } + else{ + ofilter = NULL; + } + xfree(tbuf); + return(ofilter); +} + +/* + * + * FilterDefault -- get the default filter handle for the parser + * + */ +#ifdef ANSI_FUNC +Filter +FilterDefault(void) +#else +Filter FilterDefault() +#endif +{ + return(default_filter); +} + +/* + * + * FilterNull -- get the null filter pointer + * + */ +#ifdef ANSI_FUNC +Filter +FilterNull(void) +#else +Filter FilterNull() +#endif +{ + return(&null_filter); +} + +/* + * + * FilterNum -- get a unique number associated with an open filter + * + */ +static int filter_num=0; +#ifdef ANSI_FUNC +int +FilterNum(void) +#else +int FilterNum() +#endif +{ + filter_num++; + return(filter_num); +} + +/* + * + * FilterPath -- get the path through which we look for things + * + */ +#ifdef ANSI_FUNC +char * +FilterPath(void) +#else +char *FilterPath() +#endif +{ + static char *filter_path=NULL; + if( filter_path == NULL ){ + filter_path = (char *)getenv("PATH"); + } + return(filter_path); +} + +/* + * + * FilterOpen -- open a filter and initialize the symbol table + * + */ +#ifdef ANSI_FUNC +Filter +FilterOpen(FITSHead header, char *string, char *mode) +#else +Filter FilterOpen(header, string, mode) + FITSHead header; /* fitsy header struct */ + char *string; /* filter string */ + char *mode; /* "C", "f77", "awk", etc. */ +#endif +{ + int lexonly=0; + int got=0; + char *s, *t; + char tbuf[SZ_LINE]; + Filter filter; + char *filtstr; + + /* return if we have no filter */ + if( (string == NULL) || (*string == '\0') || + !strcmp(string, "[]") || !strcmp(string, "\n") ) + return(NOFILTER); + + /* more checks for an essentially blank string */ + for(got=0, s=string; *s; s++){ + if( (*s != ' ') && (*s != '\t') && (*s != '\n') && (*s != ';') ){ + got++; + break; + } + } + if( !got ) + return(NOFILTER); + + /* allocate a new filter record */ + if( (filter = (Filter)xcalloc(1, sizeof(FilterRec))) == NULL ) + return(NULL); + + /* this is the default filter handle for the parser */ + default_filter = filter; + + /* clean up filter */ + s = FilterClip(string); + /* if its not a file, use string directly */ + if( *s != '@' ){ + t = xstrdup(s); + } + /* if it a FITS file, use string directly */ + else if( IsFits(&(s[1])) ){ + t = xstrdup(s); + } + /* replace ASCII file with contents, if possible */ + else if( !(t = FileContents(&(s[1]), 0, NULL)) ){ + t = xstrdup(s); + } + /* set the input filter string for the parser */ + filter->string = FilterClip(t); + if( s ) xfree(s); + if( t ) xfree(t); + /* return if we have no filter */ + if( !filter->string || (*filter->string == '\0') ){ + return(NOFILTER); + } + + /* save mode */ + filter->mode=xstrdup(mode); + + /* assume we will use an index */ +#if HAVE_MINGW32==0 + filter->doidx = 1; +#else + filter->doidx = 0; +#endif + + /* process the mode string */ + if( (s = xstrdup(filter->mode)) ){ + /* set global convert flag */ + if( keyword(s, "convert", tbuf, SZ_LINE) ) + filter->convert = istrue(tbuf); + /* set the event section */ + if( keyword(s, "evsect", tbuf, SZ_LINE) ) + filter->evsect = xstrdup(tbuf); + if( keyword(s, "lexonly", tbuf, SZ_LINE) ) + lexonly = 1; +#if HAVE_MINGW32==0 + if( keyword(s, "idx", tbuf, SZ_LINE) ){ + if( istrue(tbuf) ) + filter->doidx = 1; + else if( isfalse(tbuf) ) + filter->doidx = -1; + } +#endif + } + if( s ) xfree(s); + + /* determine which method of filter processing we will use: + currently we support only the C method */ + filter->method = DEFAULT_FILTER_METHOD; + *tbuf = '\0'; + if( (s=(char *)getenv("FILTER_METHOD")) ){ + strcpy(tbuf, s); + } + if( !*tbuf && (s=xstrdup(filter->mode)) ){ + keyword(s, "method", tbuf, SZ_LINE); + if( s ) xfree(s); + } + if( *tbuf ){ + if( !strcasecmp(tbuf, "c") ) + filter->method = METHOD_C; + } + + /* determine which type of filtering we do: event or image */ + filter->type = DEFAULT_FILTER_TYPE; + *tbuf = '\0'; + if( (s=(char *)getenv("FILTER_TYPE")) ){ + strcpy(tbuf, s); + } + if( !*tbuf && (s=xstrdup(filter->mode)) ){ + keyword(s, "type", tbuf, SZ_LINE); + if( s ) xfree(s); + } + if( *tbuf ){ + if( !strncasecmp(tbuf, "ev", 2) ) + filter->type = TYPE_EVENTS; + else if( !strncasecmp(tbuf, "im", 2) ) + filter->type = TYPE_IMAGE; + } + + /* determine which type of process execution we do */ + switch(filter->method){ + case METHOD_C: + filter->ptype = DEFAULT_FILTER_PTYPE; + *tbuf = '\0'; + if( (s=(char *)getenv("FILTER_PTYPE")) ){ + strcpy(tbuf, s); + } + if( !*tbuf && (s=xstrdup(filter->mode)) ){ + keyword(s, "ptype", tbuf, SZ_LINE); + if( s ) xfree(s); + } + if( *tbuf ){ + if( *tbuf == 'p' ) + filter->ptype = PTYPE_PROCESS; + else if( *tbuf == 'c' ) + filter->ptype = PTYPE_CONTAINED; +#ifdef USE_DL + else if( *tbuf == 'd' ) + filter->ptype = PTYPE_DYNAMIC; +#endif + } + break; + default: + filter->ptype = PTYPE_PROCESS; + break; + } + + /* determine region paint mode */ + *tbuf = '\0'; + if( (s=(char *)getenv("FILTER_PAINT")) ){ + strcpy(tbuf, s); + } + if( !*tbuf && (s=xstrdup(filter->mode)) ){ + keyword(s, "paint", tbuf, SZ_LINE); + if( s ) xfree(s); + } + if( !*tbuf ) + strcpy(tbuf, DEFAULT_PAINT_MODE); + if( *tbuf ){ + if( istrue(tbuf) ) + filter->paint = 1; + else + filter->paint = 0; + } + + /* debugging mode */ + *tbuf = '\0'; + if( (s=(char *)getenv("FILTER_DEBUG")) ){ + strcpy(tbuf, s); + } + if( !*tbuf && (s=xstrdup(filter->mode)) ){ + keyword(s, "debug", tbuf, SZ_LINE); + if( s ) xfree(s); + } + if( *tbuf ){ + if( isdigit((int)*tbuf) ) + filter->debug = atoi(tbuf); + else if( istrue(tbuf) ) + filter->debug = 1; + else if( isfalse(tbuf) ) + filter->debug = 0; + } + + /* save the fits header */ + filter->fhd = header; + + /* init the symbol table */ + if( !FilterSymbolInit(filter) ) + goto error; + + /* init parser variables */ + FiltInitParser(); + + /* init regions */ + FiltInitRegions(); + + /* set up to parse the input filter */ + FiltScanString(filter->string); + + /* parse filter */ + filtlex(); + + /* check for errors while parsing the string */ + if( FilterParseError() ) + goto error; + + /* make sure we have something to filter */ + if( !(filtstr = (char *)_FilterString()) || !strcmp(filtstr, "()") ){ + FilterClose(filter); + return(NOFILTER); + } + + /* imagemask processing of images does not use the compiled process */ + if( filter->nmask && filter->masks && (filter->type == TYPE_IMAGE) ) + goto done; + + /* for event filtering, we can use indexes */ +#if HAVE_MINGW32==0 + if( filter->type == TYPE_EVENTS ){ + /* run index grammar and see if we can get help from indexes */ + if( filter->doidx == 1 ){ + if( !idxinitparser(filtstr) ){ + filter->doidx = -1; + } + else{ + idxparse(); + idxfreeglobals(); + if( !filter->idx || (filter->idx->type == IDX_INDEF) ){ + if( filter->idx ){ + idxendparser(); + filter->idx = NULL; + } + filter->doidx = -1; + } + } + } + /* if we are using an index and we are only processing indexed columns, + we don't need to use compiled filter */ + if( FILTER_INDEX_ONLY(filter) ){ + if( idx_debug ) fprintf(stderr, "idx: skipping compiled filter\n"); + goto done; + } + } +#endif + + /* lexonly means we only wanted to run the lexer */ + if( lexonly ) + goto done; + + /* open the program file that we will compile from the filter */ + if( !FilterProgOpen(filter) ) + goto error; + + /* prepend the to C program as needed */ + if( !FilterProgPrepend(filter) ) + goto error; + + /* write the symbols to the appropriate program */ + if( !FilterProgWrite(filter) ) + goto error; + + /* append the program body to C program */ + if( !FilterProgAppend(filter) ) + goto error; + + /* that is all we need to output */ + if( !FilterProgClose(filter) ) + goto error; + + /* compile the filter program */ + if( !FilterProgCompile(filter) ) + goto error; + + if( filter->debug >= 2 ) goto done; + + switch(filter->method){ + case METHOD_C: + switch(filter->ptype){ + case PTYPE_PROCESS: + case PTYPE_CONTAINED: + switch(filter->pipeos){ + case PIPE_WIN32: +#if HAVE_CYGWIN||HAVE_MINGW32 + if( !WinProcessOpen(filter->prog, + &(filter->ihandle), &(filter->ohandle), &(filter->process)) ) + goto error; +#else + gerror(stderr, "internal error: no WinProcess without Windows"); + goto error; +#endif + break; + default: + if( !ProcessOpen(filter->prog, + &(filter->ichan), &(filter->ochan), &(filter->pid)) ) + goto error; + break; + } + break; +#ifdef USE_DL + case PTYPE_DYNAMIC: + if( !(filter->dl=DLOpen(filter->prog)) ) + goto error; + break; +#endif + default: + goto error; + } + break; + default: + goto error; + } + + /* return the good news */ +done: + return(filter); + +error: + FilterClose(filter); + return(NULL); + +} + +/* + * + * FilterEvents -- filter events by sending them to a co-process, + * which returns a char array of good event flags + * + */ +#ifdef ANSI_FUNC +int +FilterEvents(Filter filter, char *ebuf, int esize, int n, int *vbuf) +#else +int FilterEvents(filter, ebuf, esize, n, vbuf) + Filter filter; + char *ebuf; + int esize; + int n; + int *vbuf; +#endif +{ + int i; + int flag; + int get=0, got=0; + int bytes; + char *eptr; + char *etop; + char *obuf; + char *optr; +#ifdef USE_DL + FilterTableCall evrtn; +#endif + FilterSymbols sp; + + /* make sure we have a valid filter and a valid table */ + if( !filter || (filter == NOFILTER) || !filter->fhd || !filter->fhd->table ) + return(0); + + /* handle fits image mask specially */ + if( filter->nmask && filter->masks && !filter->evsect ){ + gerror(stderr, "event filtering cannot use image masks\n"); + return(0); + } + + /* if the index is enough, just return */ + if( FILTER_INDEX_ONLY(filter) ) + return 0; + + /* we only send the necessary parts of each event record */ + if( (obuf = (char *)xcalloc(n*filter->evsize, sizeof(char))) == NULL ) + return(0); + optr = obuf; + + /* extract (and convert) the necessary columns of the event */ + for(eptr=ebuf, etop=ebuf+(n*esize); eptrnsyms; i++){ + sp = &(filter->symtab[i]); + /* skip accidentally empty ones */ + if( (sp->name == NULL) || (*sp->name == '\0') ) + continue; + /* process this type of symbol */ + switch(sp->type){ + case SYM_COL: + if( filter->fhd->table->col[sp->idx].type == 'X' ){ + ColumnLoad(eptr+filter->fhd->table->col[sp->idx].offset, + filter->fhd->table->col[sp->idx].size, + (filter->fhd->table->col[sp->idx].n+7)/8, + filter->convert, optr+sp->offset); + } + else{ + ColumnLoad(eptr+filter->fhd->table->col[sp->idx].offset, + filter->fhd->table->col[sp->idx].size, + filter->fhd->table->col[sp->idx].n, + filter->convert, optr+sp->offset); + } + break; + default: + break; + } + } + /* bump to next output record */ + optr += filter->evsize; + } + + switch(filter->ptype){ + case PTYPE_PROCESS: + case PTYPE_CONTAINED: + switch(filter->pipeos){ + case PIPE_WIN32: +#if HAVE_CYGWIN||HAVE_MINGW32 + /* write events to the filter process */ + bytes = n*filter->evsize; + if((got=WinProcessWrite(filter->ohandle, obuf, bytes)) != bytes){ + gerror(stderr, + "event filter failed: wanted to write %d bytes but wrote %d\n", + bytes, got); + flag = -1; + } + /* read back result flags */ + get = n * sizeof(unsigned int); + WinProcessRead(filter->ihandle, vbuf, get, &got); +#else + gerror(stderr, "internal error: no WinProcess without Windows"); + flag = -1; +#endif + break; + default: + /* write events to the filter process */ + bytes = n*filter->evsize; + if((got=ProcessWrite(filter->ochan, obuf, bytes)) != bytes){ + gerror(stderr, + "event filter failed: wanted to write %d bytes but wrote %d\n", + bytes, got); + flag = -1; + } + /* read back result flags */ + get = n * sizeof(unsigned int); + ProcessRead(filter->ichan, vbuf, get, &got); + break; + } + /* we need one int back for each event we wrote */ + if( get == got ){ + flag = 1; + } + else{ + gerror(stderr, + "event filter failed: wanted to read %d bytes but got %d\n", + get, got); + flag = -1; + } + break; +#ifdef USE_DL + case PTYPE_DYNAMIC: + if( (evrtn=(FilterTableCall)DLSym(filter->dl, filter->pname)) ){ + filter->g = (*evrtn)(filter->g, obuf, n, filter->evsize, vbuf); + flag = 1; + } + else{ + flag = -1; + } + break; +#endif + default: + flag = -1; + break; + } + + /* free up malloc'ed space */ + if( obuf ) xfree(obuf); + /* return the news */ + return flag; +} + +/* + * + * FilterImage -- filter image by sending sections to a co-process, + * which returns segments of valid image data + * + */ +#ifdef ANSI_FUNC +int +FilterImage(Filter filter, int x0, int x1, int y0, int y1, int block, + FilterMask *masks, int *nreg) +#else +int FilterImage(filter, x0, x1, y0, y1, block, masks, nreg) + Filter filter; + int x0, x1, y0, y1, block; + FilterMask *masks; + int *nreg; +#endif +{ + int i, j; + int got; + int fsize; + int mblock; + char tbuf[SZ_LINE]; + FilterMask xmasks; +#ifdef USE_DL + FilterImageCall imrtn; +#endif + + /* make sure we have a valid filter */ + if( !filter || (filter == NOFILTER) ) + return(0); + + /* handle fits image mask specially */ + if( filter->nmask && filter->masks ){ + mblock = (int)(((double)((x1 - x0 + 1)/block)/(double)ft_naxis(filter->maskhd, 1)) + 0.5); + if( mblock < 1 ){ + gerror(stderr, "image mask cannot be larger than blocked image section"); + return(0); + } + /* copy mask records into return buffer */ + fsize = filter->nmask * sizeof(FilterMaskRec) * mblock; + xmasks = xmalloc(fsize); + /* copy all masks and translate x,y positions as needed */ + for(got=0, i=0; inmask; i++){ + xmasks[got].region = filter->masks[i].region; + xmasks[got].y = (filter->masks[i].y - 1.0) * mblock + 1.0; + xmasks[got].xstart = (filter->masks[i].xstart - 1.0) * mblock + 1.0; + xmasks[got].xstop = (filter->masks[i].xstop - 1.0) * mblock + 1.0; + /* replicate the segment up to the block factor */ + for(j=1; jnmaskreg; + return(got); + } + + /* if the index is enough, just return */ + if( FILTER_INDEX_ONLY(filter) ) + return(0); + + switch(filter->ptype){ + case PTYPE_PROCESS: + case PTYPE_CONTAINED: + switch(filter->pipeos){ + case PIPE_WIN32: +#if HAVE_CYGWIN||HAVE_MINGW32 + /* write command to process */ + snprintf(tbuf, SZ_LINE-1, "%d %d %d %d %d\n", x0, x1, y0, y1, block); + WinProcessWrite(filter->ohandle, tbuf, (int)strlen(tbuf)); + /* read back mask records */ + *masks = WinProcessRead(filter->ihandle, NULL, -1, &got); + got /= sizeof(FilterMaskRec); +#else + gerror(stderr, "internal error: no WinProcess without Windows"); + return(-1); +#endif + break; + default: + /* write command to process */ + snprintf(tbuf, SZ_LINE-1, "%d %d %d %d %d\n", x0, x1, y0, y1, block); + ProcessWrite(filter->ochan, tbuf, (int)strlen(tbuf)); + /* read back mask records */ + *masks = ProcessRead(filter->ichan, NULL, -1, &got); + got /= sizeof(FilterMaskRec); + break; + } + break; +#ifdef USE_DL + case PTYPE_DYNAMIC: + if( (imrtn=(FilterImageCall)DLSym(filter->dl, filter->pname)) ){ + *masks = (*imrtn)(x0, x1, y0, y1, block, &got); + } + else + return(-1); + break; +#endif + default: + return(-1); + } + + /* how many separate regions? */ + if( nreg ) *nreg = FilterRegionCount(TOK_IREG); + + /* return the news */ + return(got); +} + +/* + * + * FilterClose -- close a filter and free up memory + * + */ +#ifdef ANSI_FUNC +int FilterClose(Filter filter) +#else +int FilterClose(filter) + Filter filter; +#endif +{ + int status=0; + int i, j; + Scan scan, tscan; + + if( !filter || (filter == NOFILTER) ) + return(0); + + /* this is the default filter handle */ + default_filter = filter; + + switch(filter->ptype){ + case PTYPE_PROCESS: + case PTYPE_CONTAINED: + /* close the filter process */ + switch(filter->pipeos){ + case PIPE_WIN32: +#if HAVE_CYGWIN||HAVE_MINGW32 + if( filter->process ) WinProcessClose(filter->process, &status); +#else + gerror(stderr, "internal error: no WinProcess without Windows"); +#endif + break; + default: + if( filter->pid > 0 ) ProcessClose(filter->pid, &status); + break; + } + /* delete program */ + if( filter->prog ) unlink(filter->prog); + break; +#ifdef USE_DL + case PTYPE_DYNAMIC: + if( filter->dl ) + DLClose(filter->dl); + break; +#endif + default: + break; + } + + /* call any method-specific cleanup routines */ + FilterProgClose(filter); + FilterProgEnd(filter); + + /* free alloc'ed memory */ + FilterSymbolFree(filter); + if( filter->pname ) xfree(filter->pname); + if( filter->mode ) xfree(filter->mode); + if( filter->masks ) xfree(filter->masks); + if( filter->cc ) xfree(filter->cc); + if( filter->cflags ) xfree(filter->cflags); + if( filter->objs ) xfree(filter->objs); + if( filter->extra ) xfree(filter->extra); + if( filter->shflags ) xfree(filter->shflags); + if( filter->code ) xfree(filter->code); + if( filter->prog ) xfree(filter->prog); + if( filter->string ) xfree(filter->string); + if( filter->xbin ) xfree(filter->xbin); + if( filter->ybin ) xfree(filter->ybin); + if( filter->symtab ) xfree(filter->symtab); + if( filter->evsect ) xfree(filter->evsect); + if( filter->maskhd ) ft_headfree(filter->maskhd, 1); + /* free region information */ + if( filter->g ){ + for(i=0; ig->maxshapes; i++){ + if( filter->g->shapes[i].scanlist ){ + for(j=0; j<=filter->g->y1; j++){ + if( filter->g->shapes[i].scanlist[j] ){ + for(scan=filter->g->shapes[i].scanlist[j]; scan; ){ + tscan = scan->next; + xfree(scan); + scan = tscan; + } + } + } + xfree(filter->g->shapes[i].scanlist); + } + if( filter->g->shapes[i].pts ) xfree(filter->g->shapes[i].pts); + if( filter->g->shapes[i].xv ) xfree(filter->g->shapes[i].xv); + } + if( filter->g->shapes ) xfree(filter->g->shapes); + if( filter->g->ybuf ) xfree(filter->g->ybuf); + if( filter->g->x0s ) xfree(filter->g->x0s); + if( filter->g->x1s ) xfree(filter->g->x1s); + if( filter->g->masks ) xfree(filter->g->masks); + if( filter->g ) xfree(filter->g); + } + /* free index information */ +#if HAVE_MINGW32==0 + idxendparser(); +#endif + /* free main struct */ + xfree(filter); + /* return the status from closing the sub-process */ + return(status); +} + + +/* + * + * FilterConcats -- concat n filters, removing enclosing brackets as necessary + * + */ +#ifdef ANSI_FUNC +char * +FilterConcats(char **filters, int n) +#else +char *FilterConcats(filters, n) + char **filters; + int n; +#endif +{ + char *ofilter; + char *optr; + char *clip; + int i; + int len; + + /* need at least 1 string */ + if( n == 0 ) + return(NULL); + + /* get max length of output filter */ + for(len=0, i=0; istring; +} diff --git a/filter/filter.h b/filter/filter.h new file mode 100644 index 0000000..7a49bdc --- /dev/null +++ b/filter/filter.h @@ -0,0 +1,380 @@ +/* + * Copyright (c) 1999-2003 Smithsonian Astrophysical Observatory + */ + +/* + * + * filter.h - include file for "compile on the fly" filters + * + */ + +#ifndef __filter_h +#define __filter_h + +#if HAVE_CONFIG_H +#include "conf.h" +#endif + +/* avoid use of system -- its not secure */ +/* but funtools cannot use launch for the MinGW platform because the stdfiles + support is missing in the launch_spawnvp() implementation of launch */ +#ifndef USE_LAUNCH +#define USE_LAUNCH 1 +#endif +#if HAVE_MINGW32 +#undef USE_LAUNCH +#endif + +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_STRING_H +#include +#endif +#include +#include "prsetup.h" +#include "gio.h" +#include "file.h" +#include "find.h" +#include "macro.h" +#include "word.h" +#include "xalloc.h" +#include "strtod.h" +#define USE_XFILEIO 1 +#include "fitsy.h" +#undef USE_XFILEIO +#include "idx.h" +#include "wcs.h" +#include "column.h" +#include "tl.h" +#include "dl.h" +#include "mkrtemp.h" +#include "zprocess.h" +#include "winprocess.h" +#include "parse.h" +#ifdef USE_LAUNCH +#include "xlaunch.h" +#endif + +#ifndef OBJPATH +#define OBJPATH "." +#endif + +#ifndef FILTER_CC +#define FILTER_CC NULL +#endif + +#ifndef FILTER_CFLAGS +#define FILTER_CFLAGS NULL +#endif + +/* define methods of program generation */ +#define METHOD_C 1 + +/* define types of filtering */ +#define TYPE_EVENTS 1 +#define TYPE_IMAGE 2 + +/* define types of filtering process -- separate process, self-contained + separate process, or dynamic load (if defined) */ +#define PTYPE_PROCESS 1 +#define PTYPE_CONTAINED 2 +#define PTYPE_DYNAMIC 3 + +/* define how we connect the processes -- unix or windows pipes */ +#define PIPE_UNIX 0 +#define PIPE_WIN32 1 + + +/* defaults which can be overridden by environment variables */ +#define DEFAULT_FILTER_METHOD METHOD_C +#define DEFAULT_FILTER_TYPE TYPE_EVENTS +#ifdef USE_DL +#define DEFAULT_FILTER_PTYPE PTYPE_DYNAMIC +#else +#define DEFAULT_FILTER_PTYPE PTYPE_PROCESS +#endif +#define DEFAULT_PAINT_MODE "false" +#define DEFAULT_FILTER_TMPDIR "/tmp" + +/* define type of important tokens */ +#define TOK_EREG 1 +#define TOK_NREG 2 +#define TOK_IREG 4 +#define TOK_RLIST 8 +#define TOK_RTINE 16 +#define TOK_NAME 32 +#define TOK_ACCEL 64 +#define TOK_VARARGS 128 + +#define TOK_REG (TOK_EREG|TOK_NREG|TOK_IREG) + +/* default cordinate system for regions */ +#define DEFAULT_COORDSYS "physical" + +/* if we have gcc, we can use dynamic loading instead of a separate process */ +#define GCC_SHARED_FLAGS "-g -fPIC -shared" + +/* places to look for the compiler other than user's path */ +#define CC_PATH "/opt/SUNWspro/bin:/bin:/usr/bin:/usr/local/bin/:/opt/local/bin:" + +/* define non-WCS coordinate systems we handle specially */ +#define LCX_IMAGE 1 +#define LCX_PHYS 2 +#define LCX_AMP 3 +#define LCX_DET 4 + +/* define symbol types in symbol table */ +#define SYM_COL 1 +#define SYM_PAR 2 + +/* whether we use only the index and not the compiled filter */ +#define FILTER_INDEX_ONLY(f) \ + ((f->doidx==1)&&(f->idx)&&(f->idx->dofilt==0)&&(f->idx->rtype!=IDX_INDEF)) + +typedef struct filtmask { + int region; + int y; + int xstart, xstop; +} *FilterMask, FilterMaskRec; + +typedef struct scanrec{ + struct scanrec *next; + int x; +} *Scan, ScanRec; + +/* structs for use with region routines */ +typedef struct shaperec { + int init; + double ystart, ystop; + Scan *scanlist; + /* varargs */ + int nv; + double *xv; + /* circle, annulus */ + double r1sq, r2sq; + /* ellipse */ + double angl, sinangl, cosangl; + double cossq, sinsq; + double xradsq, yradsq; + double a; + /* polygon-style shapes */ + int npt; + double *pts; + /* line */ + int xonly; + double x1, x2, y1; + double invslope; +} *Shape, ShapeRec; + +typedef struct gfiltrec { + int nshapes; /* number of shapes */ + int maxshapes; /* number of shape records we allocate */ + Shape shapes; /* array holding range limits for one shape */ + int rid; /* first valid region for current pixel */ + int usebinsiz; /* whether bindizx,binsizy are used */ + char *evsect; /* value of event section */ + double tlminx, tlminy; /* tlmin for event section */ + double binsizx, binsizy; /* bin sizes for event section */ + double tloff; /* offset for quick p2i conversion */ + int xmin, xmax, ymin, ymax; /* section limits in original image coords */ + int block; /* block factor */ + int x0, x1, y0, y1; /* section limits in section coords */ + int *ybuf; /* valid y row flags */ + int *x0s; /* valid x start values */ + int *x1s; /* valid x stop values */ + int nmask; /* number of image mask record */ + int maskdim; /* size of mask image */ + FilterMask masks; /* mask records */ +} *GFilt, GFiltRec; + +typedef struct filtseg { + int n; + int type; + int ops; + int len; + int flag; + int nregion; + char *s; + int s0; + char *regions; + int nr; + char *shapes; + int ns; + int regval; + char *radang; + int ralen; +} *FiltSeg, FiltSegRec; + +/* structs for use with symbol table routines */ +typedef struct filtsymtab { + int type; + char *name; + char *value; + int idx; + int offset; + FITSCard card; +} *FilterSymbols, FilterSymRec; + +typedef struct filtrec { + /* general information */ + char *mode; + char *evsect; + int method; + int type; + int paint; + int debug; + /* the input filter string */ + char *string; + int size; + /* fits info */ + FITSHead fhd; + int convert; + char *xbin; + char *ybin; + /* compiled program info */ + char *code; + char *prog; + FILE *fp; + /* symbol table info */ + int maxsyms; + int nsyms; + int evsize; + FilterSymbols symtab; + /* method info */ + char *cc; + char *cflags; + char *objs; + char *extra; + char *shflags; + /* process info */ + char *pname; + int ptype; + /* which type of pipe? */ + int pipeos; + /* used by unix pipe */ + int pid; + int ichan; + int ochan; + /* used by Windows pipe */ + void *process; + void *ihandle; + void *ohandle; + /* used for dynamic linking */ + void *dl; + GFilt g; + /* loadable drivers for each technique */ + /* NB: can't use typdef because we refer to this struct */ + int (*filt_start) _PRx((struct filtrec *filter)); + int (*filt_open) _PRx((struct filtrec *filter)); + int (*filt_prepend) _PRx((struct filtrec *filter)); + int (*filt_write) _PRx((struct filtrec *filter)); + int (*filt_append) _PRx((struct filtrec *filter)); + int (*filt_close) _PRx((struct filtrec *filter)); + int (*filt_compile) _PRx((struct filtrec *filter)); + int (*filt_end) _PRx((struct filtrec *filter)); + char *(*filt_name) _PRx((struct filtrec *filter, char *name)); + char *(*filt_routine1) _PRx((struct filtrec *filter, char *name)); + char *(*filt_routine2) _PRx((struct filtrec *filter, char *name)); + char *(*filt_region1) _PRx((struct filtrec *filter, char *name)); + char *(*filt_region2) _PRx((struct filtrec *filter, char *name)); + /* fits image mask info */ + int nmask; + int nmaskreg; + FilterMask masks; + FITSHead maskhd; + /* indexing information */ + int doidx; + idxvalrec *valhead; + idxrowrec *rowhead; + idxrowrec *idx; +} *Filter, FilterRec; + +typedef void *(*FilterTableCall)( +#ifdef ANSI_FUNC + void *tg, char *ebuf, int ne, int esize, int *rbuf +#endif +); + +typedef FilterMask (*FilterImageCall)( +#ifdef ANSI_FUNC + int txmin, int txmax, int tymin, int tymax, int tblock, int *got +#endif +); + +/* this makes it look like a simple flag */ +#define NOFILTER FilterNull() + +_PRbeg + +/* filter.c */ +int FilterNum _PRx((void)); +char *FilterClip _PRx((char *filter)); +Filter FilterDefault _PRx((void)); +Filter FilterNull _PRx((void)); +char *FilterPath _PRx((void)); +Filter FilterOpen _PRx((FITSHead header, char *filter, char *mode)); +int FilterEvents _PRx((Filter filter, + char *ebuf, int esize, int n, int *vbuf)); +int FilterImage _PRx((Filter filter, + int x0, int x1, int y0, int y1, int block, + FilterMask *masks, int *nreg)); +int FilterClose _PRx((Filter filter)); +char *FilterConcats _PRx((char **filters, int n)); +char *FilterConcat _PRx((char *f1, char *f2, char *op)); +char *FilterString _PRx((Filter filter)); + +/* symbols.c */ +int FilterSymbolInit _PRx((Filter filter)); +char *FilterSymbolEnter _PRx((Filter filter, char *s, int *got)); +FilterSymbols FilterSymbolLookup _PRx((Filter filter, char *s)); +int FilterSymbolDefaults _PRx((Filter filter, int enter)); +void FilterSymbolFree _PRx((Filter filter)); + +/* filt.l */ +char *_FilterString _PRx((void)); +void FiltInitParser _PRx((void)); +void FiltScanString _PRx((char *s)); +int FilterRoutineCount _PRx((void)); +int FilterShapeCount _PRx((void)); +int FilterRegionCount _PRx((int type)); +int FilterParseError _PRx((void)); +int FilterTlInfo _PRx((double *tlmins, double *binsizs, int *tltyps)); +char *FilterRadAng _PRx((void)); + +int filterror _PRx((char *msg)); +int filtlex _PRx((void)); +int filtwrap _PRx((void)); +int filtparse _PRx((void)); + +/* filtprog.c */ +int FilterProgStart _PRx((Filter filter)); +int FilterProgOpen _PRx((Filter filter)); +int FilterProgPrepend _PRx((Filter filter)); +int FilterProgWrite _PRx((Filter filter)); +int FilterProgAppend _PRx((Filter filter)); +int FilterProgClose _PRx((Filter filter)); +int FilterProgCompile _PRx((Filter filter)); +int FilterProgEnd _PRx((Filter filter)); +char *FilterLexName _PRx((Filter filter, char *name)); +char *FilterLexRoutine1 _PRx((Filter filter, char *name)); +char *FilterLexRoutine2 _PRx((Filter filter, char *name)); +char *FilterLexRegion1 _PRx((Filter filter, char *name)); +char *FilterLexRegion2 _PRx((Filter filter, char *name)); + +/* filtprog_c.c */ +int FilterProgLoad_C _PRx((Filter filter)); + +/* evregions.c */ +void initevregions _PRx((void)); +/* imregions.c */ +void initimregions _PRx((void)); + +_PRend + +/* for compatibility with funtools */ +#define FilterTable FilterEvents + +#endif /* __filter.h */ diff --git a/filter/filter_pyh.py b/filter/filter_pyh.py new file mode 100644 index 0000000..fb98196 --- /dev/null +++ b/filter/filter_pyh.py @@ -0,0 +1,22 @@ +# from regions.h -- no idea what it is ... +xsno=3 + +# ... but its important! +maxshapes=(nshape*(xsno+1))+1 + +# ctypes struct definitions (taken from filter.h) +class filtmask(Structure): + _fields_ = [('region', c_int), ('y', c_int), ('xstart', c_int), ('xstop', c_int)] + +class scanrec(Structure): + pass + +# this is how you add a forward pointer +scanrec._fields_ = [ ('next', POINTER(scanrec)), ('x', c_int) ] + +class shaperec(Structure): + _fields_ = [ ('init', c_int), ('ystart', c_double), ('ystop', c_double), ('scanlist', c_void_p), ('nv', c_int), ('xv', c_void_p), ('r1sq', c_double), ('r2sq', c_double), ('angl', c_double), ('sinangl', c_double), ('cosangl', c_double), ('cossq', c_double), ('sinsq', c_double), ('xradsq', c_double), ('yradsq', c_double), ('a', c_double), ('npt', c_int), ('pts', c_void_p), ('xonly', c_int), ('x1', c_double), ('x2', c_double), ('y1', c_double), ('invslope', c_double)] + +class gfiltrec(Structure): + _fields_ = [('nshapes', c_int), ('maxshapes', c_int), ('shapes', POINTER(shaperec * maxshapes)), ('rid', c_int), ('usebinsiz', c_int), ('evsect', c_char_p), ('tlminx', c_double), ('tlminy', c_double), ('binsizx', c_double), ('binsizy', c_double), ('tloff', c_double), ('xmin', c_int), ('xmax', c_int), ('ymin', c_int), ('ymax', c_int), ('block', c_int), ('x0', c_int), ('x1', c_int), ('y0', c_int), ('y1', c_int), ('ybuf', POINTER(c_int)), ('x0s', POINTER(c_int)), ('x1s', POINTER(c_int)), ('nmask', c_int), ('maskdim', c_int), ('masks', POINTER(filtmask))] + diff --git a/filter/filtprog.c b/filter/filtprog.c new file mode 100644 index 0000000..81720f8 --- /dev/null +++ b/filter/filtprog.c @@ -0,0 +1,351 @@ +/* + * Copyright (c) 1999-2003 Smithsonian Astrophysical Observatory + */ + +/* + * + * filtprog.c -- hi level support for filters using different techniques + * + */ + +#include + +/* + * + * FilterProgStart -- start the filtering process + * + */ +#ifdef ANSI_FUNC +int +FilterProgStart (Filter filter) +#else +int FilterProgStart(filter) + Filter filter; +#endif +{ + /* make sure we have something to play with */ + if( filter == NULL) + return(0); + + /* call the technique-specific routine */ + if( filter->filt_start ) + return((filter->filt_start)(filter)); + else{ + return(0); + } +} + +/* + * + * FilterProgOpen -- return filter program as a file for writing + * + */ +#ifdef ANSI_FUNC +int +FilterProgOpen (Filter filter) +#else +int FilterProgOpen(filter) + Filter filter; +#endif +{ + /* make sure we have something to play with */ + if( filter == NULL) + return(0); + + /* check the mode for known techniques and load drivers */ + switch( filter->method ){ + case METHOD_C: + FilterProgLoad_C(filter); + break; + default: + gerror(stderr, "unknown filter technique: %d\n", filter->method); + return(0); + } + + /* call the technique-specific routine */ + if( filter->filt_open ){ + return((filter->filt_open)(filter)); + } + else{ + return(1); + } +} + +/* + * + * FilterProgPrepend -- prepend to the filter + * + */ +#ifdef ANSI_FUNC +int +FilterProgPrepend (Filter filter) +#else +int FilterProgPrepend(filter) + Filter filter; +#endif +{ + /* make sure we have something to play with */ + if( filter == NULL) + return(0); + + /* call the technique-specific routine */ + if( filter->filt_prepend ) + return((filter->filt_prepend)(filter)); + else + return(1); +} + +/* + * + * FilterProgWrite -- write the symbols + * + */ +#ifdef ANSI_FUNC +int +FilterProgWrite (Filter filter) +#else +int FilterProgWrite(filter) + Filter filter; +#endif +{ + /* make sure we have something to play with */ + if( filter == NULL) + return(0); + + /* call the technique-specific routine */ + if( filter->filt_write ) + return((filter->filt_write)(filter)); + else + return(1); +} + +/* + * + * FilterProgAppend -- append the filter program body + * + */ +#ifdef ANSI_FUNC +int +FilterProgAppend (Filter filter) +#else +int FilterProgAppend(filter) + Filter filter; +#endif +{ + /* make sure we have something to play with */ + if( filter == NULL) + return(0); + + /* call the technique-specific routine */ + if( filter->filt_append ) + return((filter->filt_append)(filter)); + else + return(1); +} + +/* + * + * FilterProgClose -- close the filter program file + * + */ +#ifdef ANSI_FUNC +int +FilterProgClose (Filter filter) +#else +int FilterProgClose(filter) + Filter filter; +#endif +{ + /* make sure we have something to play with */ + if( filter == NULL) + return(0); + + /* debugging only */ + if( filter->debug >= 2 ) + return(1); + + /* call the technique-specific routine */ + if( filter->filt_close ) + return((filter->filt_close)(filter)); + else + return(1); +} + +/* + * + * FilterProgCompile -- compile the filter program + * + */ +#ifdef ANSI_FUNC +int +FilterProgCompile (Filter filter) +#else +int FilterProgCompile(filter) + Filter filter; +#endif +{ + /* make sure we have something to play with */ + if( filter == NULL) + return(0); + + /* debugging only */ + if( filter->debug >= 2 ) + return(1); + + /* call the technique-specific routine */ + if( filter->filt_compile ) + return((filter->filt_compile)(filter)); + else + return(1); +} + +/* + * + * FilterProgEnd -- end the filtering process + * + */ +#ifdef ANSI_FUNC +int +FilterProgEnd (Filter filter) +#else +int FilterProgEnd(filter) + Filter filter; +#endif +{ + /* make sure we have something to play with */ + if( filter == NULL) + return(0); + + /* call the technique-specific routine */ + if( filter->filt_end ) + return((filter->filt_end)(filter)); + else{ + return(0); + } +} + +/* + * + * FilterLexName -- return the "in-expression" name + * + */ +#ifdef ANSI_FUNC +char * +FilterLexName (Filter filter, char *name) +#else +char *FilterLexName(filter, name) + Filter filter; + char *name; +#endif +{ + /* make sure we have something to play with */ + if( filter == NULL) + return(name); + + /* call the technique-specific routine */ + if( filter->filt_name ) + return((filter->filt_name)(filter, name)); + else + return(name); +} + +/* + * + * FilterLexRoutine1 -- return the beginning of the routine string + * + */ +#ifdef ANSI_FUNC +char * +FilterLexRoutine1 (Filter filter, char *name) +#else +char *FilterLexRoutine1(filter, name) + Filter filter; + char *name; +#endif +{ + /* make sure we have something to play with */ + if( filter == NULL) + return(NULL); + + /* call the technique-specific routine */ + if( filter->filt_routine1 ) + return((filter->filt_routine1)(filter, name)); + else + return(name); +} + +/* + * + * FilterLexRoutine2 -- return the beginning of the routine string + * + */ +#ifdef ANSI_FUNC +char * +FilterLexRoutine2 (Filter filter, char *name) +#else +char *FilterLexRoutine2(filter, name) + Filter filter; + char *name; +#endif +{ + /* make sure we have something to play with */ + if( filter == NULL) + return(NULL); + + /* call the technique-specific routine */ + if( filter->filt_routine2 ) + return((filter->filt_routine2)(filter, name)); + else + return(name); +} + +/* + * + * FilterLexRegion1 -- return the beginning of the region string + * + */ +#ifdef ANSI_FUNC +char * +FilterLexRegion1 (Filter filter, char *name) +#else +char *FilterLexRegion1(filter, name) + Filter filter; + char *name; +#endif +{ + /* make sure we have something to play with */ + if( filter == NULL) + return(NULL); + + /* call the technique-specific region */ + if( filter->filt_region1 ) + return((filter->filt_region1)(filter, name)); + else + return(name); +} + +/* + * + * FilterLexRegion2 -- return the end of the region string + * + */ +#ifdef ANSI_FUNC +char * +FilterLexRegion2 (Filter filter, char *name) +#else +char *FilterLexRegion2(filter, name) + Filter filter; + char *name; +#endif +{ + /* make sure we have something to play with */ + if( filter == NULL) + return(NULL); + + /* call the technique-specific region */ + if( filter->filt_region2 ) + return((filter->filt_region2)(filter, name)); + else + return(name); +} + diff --git a/filter/filtprog_c.c b/filter/filtprog_c.c new file mode 100644 index 0000000..dbebd60 --- /dev/null +++ b/filter/filtprog_c.c @@ -0,0 +1,1033 @@ +/* + * Copyright (c) 1999-2003 Smithsonian Astrophysical Observatory + */ + +/* + * + * filtprog_c.c -- support for filters using the C compiler + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * + * Private Routines + * + */ + +#ifdef ANSI_FUNC +static char * +GetType(int t) +#else +static char *GetType(t) + int t; +#endif +{ + switch(t){ + case 'A': + return("char"); + case 'B': + return("unsigned char"); + case 'I': + return("short"); + case 'U': + return("unsigned short"); + case 'J': + return("int"); + case 'V': + return("unsigned int"); + case 'K': + return("long long"); + case 'E': + return("float"); + case 'D': + return("double"); + case 'X': + return("char"); + case 'L': + return("char"); + default: + return("char"); + } +} + +#ifdef ANSI_FUNC +static double +GetTloff(int t) +#else +static double GetTloff(t) + int t; +#endif +{ + switch(t){ + case 'B': + case 'I': + case 'U': + case 'J': + case 'V': + case 'K': + case 'X': + return 1.0; + case 'E': + case 'D': + return 0.5; + default: + return 1.0; + } +} + +#ifdef ANSI_FUNC +static char * +_FilterInitString(char *filtstr) +#else +static char *_FilterInitString(filtstr) + char *filtstr; +#endif +{ + char *ibuf, *iptr, *fptr; + char *s, *t; + int paren=0; + + ibuf = xcalloc(strlen(filtstr)*10, sizeof(char)); + /* make sure we have at least one shape */ + if( !FilterShapeCount() ) + return ibuf; + iptr = ibuf; + fptr = filtstr; + while( *fptr ){ + /* look for beginning of region routine */ + if( !(s=strstr(fptr, "im")) && !(s=strstr(fptr, "ev")) ) + break; + t = s+2; + if( !*t ) + break; + /* which is followed by a region and open paren */ + if( strncmp(t, "annulus(", 8) && + strncmp(t, "box(", 4) && + strncmp(t, "circle(", 7) && + strncmp(t, "ellipse(", 8) && + strncmp(t, "line(", 5) && + strncmp(t, "panda(", 6) && + strncmp(t, "bpanda(", 7) && + strncmp(t, "cpanda(", 7) && + strncmp(t, "epanda(", 7) && + strncmp(t, "pie(", 4) && + strncmp(t, "qtpie(", 6) && + strncmp(t, "point(", 6) && + strncmp(t, "nannulus(", 9) && + strncmp(t, "nbox(", 5) && + strncmp(t, "ncircle(", 8) && + strncmp(t, "nellipse(", 9) && + strncmp(t, "npie(", 5) && + strncmp(t, "vannulus(", 9) && + strncmp(t, "vbox(", 5) && + strncmp(t, "vcircle(", 8) && + strncmp(t, "vellipse(", 9) && + strncmp(t, "vpie(", 5) && + strncmp(t, "vpoint(", 7) && + strncmp(t, "polygon(", 8) && + strncmp(t, "field(", 6) && + strncmp(t, "imagemask(", 10) ){ + fptr = t; + continue; + } + /* copy region name up to open paren */ + for(fptr=s; *fptr && *fptr!='('; fptr++){ + *iptr++ = *fptr; + } + /* append init suffix */ + *iptr++ = 'i'; + /* copy the paren */ + if( *fptr == '(' ){ + *iptr++ = *fptr++; + paren++; + } + /* copy til end of region, i.e., when paren goes to 0 */ + while( *fptr && paren ){ + if( *fptr == '(' ) + paren++; + if( *fptr == ')' ) + paren--; + *iptr++ = *fptr++; + } + /* copy ';' */ + *iptr++ = ';'; + } + return(ibuf); +} + +/* + * + * FilterProgOpen_C -- return filter program as a file for writing + * + */ +#ifdef ANSI_FUNC +static int +FilterProgOpen_C (Filter filter) +#else +static int FilterProgOpen_C(filter) + Filter filter; +#endif +{ + int fd; + char *ccstr=NULL; + char prefix[SZ_LINE]; + char tbuf[SZ_LINE]; + char *tmpdir=NULL; +#if HAVE_CYGWIN + char *s; +#endif + + /* make sure we have something to work with */ + if( !filter ) + return(0); + + /* see if the user specified a compiler explicitly */ + if( !(ccstr = getenv("FILTER_CC")) && + !(ccstr = getenv("CC")) && + !(ccstr = FILTER_CC) ){ + ccstr = "gcc"; + } + /* make sure we have a compiler */ + if( !(filter->cc = Access(ccstr, "x")) && + !(filter->cc = Find(ccstr, "x", NULL, FilterPath())) && + !(filter->cc = Find("gcc", "x", NULL, FilterPath())) && + !(filter->cc = Find("cc", "x", NULL, FilterPath())) && + !(filter->cc = Find("cc", "x", NULL, ".")) && + !(filter->cc = Find("cc", "x", NULL, CC_PATH)) ){ + gerror(stderr, "no compiler found for filter compilation\n"); + return(0); + } + + /* determine whether communication is via Unix pipes or Win32 pipes */ + filter->pipeos = PIPE_UNIX; +#if HAVE_MINGW32 + filter->pipeos = PIPE_WIN32; +#endif +#if HAVE_CYGWIN + if( (s=strrchr(filter->cc, '/')) ){ + s++; + } + else if( (s=strrchr(filter->cc, '\\')) ){ + s++; + } else { + s = filter->cc; + } + if( !strcasecmp(s, "tcc") || !strcasecmp(s, "tcc.exe") || + !strcasecmp(s, "pcc") || !strcasecmp(s, "pcc.exe") ){ + filter->pipeos = PIPE_WIN32; + } +#endif + + /* final check on ptype: if we wanted dynamic but had no gcc, use process */ + if( (filter->ptype == PTYPE_DYNAMIC) && !strstr(filter->cc, "gcc") ) + filter->ptype = PTYPE_PROCESS; + /* get default file names */ + snprintf(tbuf, SZ_LINE, "$FILTER_OBJDIR:$FILTER_LIBDIR:%s:$HOME/.funtools:$SAORD_ROOT/lib:/usr/lib:/usr/local/lib:/opt/local/lib", OBJPATH); + switch( filter->type ){ + case TYPE_EVENTS: + /* normally, we filter events analytically */ + if( !filter->evsect ) + /* filter->objs = Find("evregions.o", "r", NULL, tbuf); */ + filter->objs = Find("libfuntools.a", "r", NULL, tbuf); + /* if evsect=xxx is specified, we filter by image pixels */ + else + /* filter->objs = Find("imregions.o", "r", NULL, tbuf); */ + filter->objs = Find("libfuntools.a", "r", NULL, tbuf); + break; + case TYPE_IMAGE: + /* image are filtered by image pixels */ + /* filter->objs = Find("imregions.o", "r", NULL, tbuf); */ + filter->objs = Find("libfuntools.a", "r", NULL, tbuf); + break; + } + /* if we wanted to a process, but have no objects, use self-contained */ + if( (filter->ptype == PTYPE_PROCESS) && !filter->objs ) + filter->ptype = PTYPE_CONTAINED; + /* allow extra stuff on the command line */ + if( !(filter->cflags = xstrdup(getenv("FILTER_CFLAGS"))) && + !(filter->cflags = xstrdup(FILTER_CFLAGS)) ) + filter->cflags = xstrdup(" "); + if( !(filter->extra = xstrdup(getenv("FILTER_EXTRA"))) ) + filter->extra = xstrdup(" "); + /* set shared switches for gcc */ + if( strstr(filter->cc, "gcc") ) + filter->shflags = xstrdup(GCC_SHARED_FLAGS); + + /* get prefix for filter source and program */ + if( !(tmpdir = (char *)getenv("FILTER_TMPDIR")) && + !(tmpdir = (char *)getenv("TMPDIR")) && + !(tmpdir = (char *)getenv("TMP")) ) + tmpdir = DEFAULT_FILTER_TMPDIR; + if( !*tmpdir ) + tmpdir = "."; +#if HAVE_MINGW32 + snprintf(prefix, SZ_LINE, "%s\\f", tmpdir); +#else + snprintf(prefix, SZ_LINE, "%s/f", tmpdir); +#endif + + /* make up the routine name when we dynamically load */ + snprintf(tbuf, SZ_LINE, "Filter%d%d", (int)getpid(), FilterNum()); + filter->pname = xstrdup(tbuf); + + /* make up name of C source file we will generate */ + if( filter->debug >= 2 ){ + filter->fp = stdout; + return(1); + } + else{ + if( (fd=mkrtemp(prefix, ".c", tbuf, SZ_LINE, 1)) < 0 ){ + gerror(stderr, "could not generate C filter source name: %s\n", + prefix); + return(0); + } + filter->code = xstrdup(tbuf); + if( !(filter->fp = fdopen(fd, "w+b")) ){ + gerror(stderr, "could not open C filter source file: %s\n", + tbuf); + return(0); + } + } + + /* make up the name of the program we will compile into. + we make this different from the .c file name to make interception + by an intruder harder */ + if( mkrtemp(prefix, NULL, tbuf, SZ_LINE, 0) < 0 ){ + gerror(stderr, "could not generate C filter program name: %s\n", + prefix); + return(0); + } +#if HAVE_MINGW32 + strcat(tbuf, ".exe"); +#endif + filter->prog = xstrdup(tbuf); + return(1); +} + +/* + * + * FilterProgPrepend_C -- prepend the filter code + * + */ +#ifdef ANSI_FUNC +static int +FilterProgPrepend_C (Filter filter) +#else +static int FilterProgPrepend_C(filter) + Filter filter; +#endif +{ + char *s=NULL; + char *contents=NULL; + FILE *fd; + + /* make sure we have something to work with */ + if( !filter ) + return(0); + + /* make sure we are not in debug mode */ + if( filter->debug >= 2 ) + return(1); + + /* init temps */ + fd = filter->fp; + + /* initialize with process type */ + switch(filter->ptype){ + case PTYPE_CONTAINED: + fprintf(fd, "#define FILTER_PTYPE c\n"); + break; + case PTYPE_DYNAMIC: + fprintf(fd, "#define FILTER_PTYPE d\n"); + break; + case PTYPE_PROCESS: + fprintf(fd, "#define FILTER_PTYPE p\n"); + break; + } + + /* we want the byte order up at the top */ + if( is_bigendian() ){ + fprintf(fd, "#define MYBYTE_ORDER 4321\n"); + } + else{ + fprintf(fd, "#define MYBYTE_ORDER 1234\n"); + } + + /* for some compilers (e.g. pcc), we need to minimize use of #include */ + if( (s=strrchr(filter->cc, '/')) ){ + s++; + } else { + s = filter->cc; + } + if( !strcasecmp(s, "pcc") || !strcasecmp(s, "pcc.exe") ){ + fprintf(fd, "#define MINIMIZE_INCLUDES 1\n"); + } + + /* do we need windows pipes? */ + if( filter->pipeos == PIPE_WIN32 ){ + fprintf(fd, "#define USE_WIN32 1\n"); + fprintf(fd, "#include \n"); + } + + + /* prepend the filter header */ + contents = REGIONS_H; + if( (contents != NULL) && (*contents != '\0') ){ + fprintf(fd, "%s\n", contents); + } + + /* these are implemented as aliases */ + fprintf(fd, "#define evvcircle evvannulus\n"); + fprintf(fd, "#define evncircle evnannulus\n"); + fprintf(fd, "#define imvcirclei imvannulusi\n"); + fprintf(fd, "#define imncirclei imnannulusi\n"); + fprintf(fd, "#define imvcircle imvannulus\n"); + fprintf(fd, "#define imncircle imnannulus\n"); + fprintf(fd, "#define evcpanda evpanda\n"); + fprintf(fd, "#define imcpandai impandai\n"); + fprintf(fd, "#define imcpanda impanda\n"); + fprintf(fd, "\n"); + + /* add some math support */ + if( is_bigendian() ){ + fprintf(fd, "static unsigned char _nan[8]={0x7F,0xF0,1,1,1,1,1,1};\n"); + } + else{ + fprintf(fd, "static unsigned char _nan[8]={1,1,1,1,1,1,0xF0,0x7F};\n"); + } + fprintf(fd, "#define NaN *((double *)_nan)\n"); + fprintf(fd, "#define div(a,b) (feq(b,0)?(NaN):(a/b))\n"); + fprintf(fd, "\n"); + return(1); +} + +/* + * + * FilterProgWrite_C -- write the symbols for filtering + * + */ +#ifdef ANSI_FUNC +static int +FilterProgWrite_C(Filter filter) +#else +static int FilterProgWrite_C(filter) + Filter filter; +#endif +{ + int i; + int offset; + int pad; + int dsize; + int evsize; + int tltyps[2]; + double tlmins[2]; + double binsizs[2]; + char vbuf[1024]; + char *s, *t; + char *v; + char *ibuf; + char *filtstr; + char *contents=NULL; + char tbuf[SZ_LINE]; + FILE *fd; + FilterSymbols sp; + FITSHead fhd; + + /* make sure we have something to work with */ + if( !filter ) + return(0); + + /* make sure we are init'ed */ + if( filter->fhd == NULL ){ + gerror(stderr, "symbol table not initialized\n"); + return(0); + } + + /* make sure we are init'ed */ + if( filter->fp == NULL ){ + gerror(stderr, "no output file for parser\n"); + return(0); + } + + /* get the filter string */ + if( !(filtstr = (char *)_FilterString()) || !strcmp(filtstr, "()") ){ + return(0); + } + + /* init temps */ + fhd = filter->fhd; + fd= filter->fp; + offset = 0; + evsize = 0; + + /* ptype-specific processing */ + switch(filter->ptype){ + case PTYPE_CONTAINED: + /* Write code to output file -- must be done BEFORE we write the + region symbols, to avoid unintentional redefinitions */ + if( filter->debug < 2 ){ + /* we need the xalloc routines */ + contents = XALLOC_C; + if( (contents != NULL) && (*contents != '\0') ){ + fprintf(fd, "%s\n", contents); + } + /* region routines if not linking against previously compiled code */ + switch( filter->type ){ + case TYPE_EVENTS: + /* normally, we filter events analytically using evregions.o */ + if( !filter->evsect ) + contents = EVREGIONS_C; + /* if evsect=xxx is specified, we filter by image pixels */ + else + contents = IMREGIONS_C; + break; + case TYPE_IMAGE: + /* image are filtered by image pixels */ + contents = IMREGIONS_C; + break; + default: + break; + } + if( (contents != NULL) && (*contents != '\0') ){ + /* use fprintf so that we handle \n correctly in TEMPLATE */ + fprintf(fd, "%s\n", contents); + } + else{ + gerror(stderr, "could not write filter subroutines\n"); + return(0); + } + } + break; + } + + /* always need the swap routines (they're part of the filter) */ + contents = SWAP_C; + if( (contents != NULL) && (*contents != '\0') ){ + fprintf(fd, "%s\n", contents); + } + + /* output counts of shapes */ + fprintf(fd, "#define NSHAPE %d\n", + FilterShapeCount()); + fprintf(fd, "#define NREGION %d\n", + FilterRegionCount(TOK_IREG|TOK_EREG|TOK_NREG)); + /* output the filter itself */ + fprintf(fd, "#define FILTER %s\n", filtstr); + if( filter->debug < 2 ){ + /* string version of the filter -- used to check for FIELD optimization */ + fprintf(fd, "#define FILTSTR \"%s\"\n", filtstr); + /* output the initialization string */ + ibuf = _FilterInitString(filtstr); + fprintf(fd, "#define FINIT %s\n", (ibuf && *ibuf)?ibuf:""); + if( ibuf ) xfree(ibuf); + } + + /* for type image, we generate an initialization string */ + switch(filter->type){ + case TYPE_IMAGE: + fprintf(fd, "#define IMFILTRTN %s\n", filter->pname); + break; + case TYPE_EVENTS: + fprintf(fd, "#define EVFILTRTN %s\n", filter->pname); + /* output the event section and tlmin values, if necessary */ + if( filter->evsect && FilterTlInfo(tlmins,binsizs,tltyps) ){ + if( *filter->evsect == '"' ) + fprintf(fd, "#define EVSECT %s\n", filter->evsect); + else + fprintf(fd, "#define EVSECT \"%s\"\n", filter->evsect); + fprintf(fd, "#define TLMINX %f\n", tlmins[0]); + fprintf(fd, "#define TLMINY %f\n", tlmins[1]); + for(i=0; i<2; i++) + if( binsizs[i] <= 0.0 ) binsizs[i] = 1.0; + if( (binsizs[0] == 1.0) && (binsizs[1] == 1.0) ) + fprintf(fd, "#define USEBINSIZ 0\n"); + else + fprintf(fd, "#define USEBINSIZ 1\n"); + fprintf(fd, "#define BINSIZX %f\n", binsizs[0]); + fprintf(fd, "#define BINSIZY %f\n", binsizs[1]); + fprintf(fd, "#define TLOFF %f\n", GetTloff(tltyps[0])); + fprintf(fd, "#define TLOFF %f\n", GetTloff(tltyps[1])); + } + /* loop through the symbol table and process #defines */ + for(i=0; insyms; i++){ + sp = &(filter->symtab[i]); + /* skip accidentally empty ones */ + if( (sp->name == NULL) || (*sp->name == '\0') ) + continue; + /* process this type of symbol */ + switch(sp->type){ + case SYM_COL: + /* make sure we are aligned */ + if( fhd->table->col[sp->idx].type == 'X' ){ + switch(fhd->table->col[sp->idx].n){ + case 8: + dsize = 1; + break; + case 16: + dsize = 2; + break; + case 32: + dsize = 4; + break; + default: + dsize = ft_sizeof(filter->fhd->table->col[sp->idx].type); + } + } + else{ + dsize = ft_sizeof(filter->fhd->table->col[sp->idx].type); + } + pad = dsize - (offset % dsize); + if( pad == dsize ) pad = 0; + offset += pad; + evsize += pad; + sp->offset = offset; + if( fhd->table->col[sp->idx].scaled ){ + snprintf(tbuf, SZ_LINE, "(%f+%f*(", + fhd->table->col[sp->idx].zero, + fhd->table->col[sp->idx].scale); + s = tbuf; + t = "))"; + } + else{ + s = ""; + t = ""; + } + if( fhd->table->col[sp->idx].n == 1 ){ + fprintf(fd, "#define %s %s*((%s *)(SW%d(eptr+%d,%d,_swf,%d)))%s\n", + sp->name, + s, + GetType((int)fhd->table->col[sp->idx].type), + dsize, + offset, + dsize, + offset, + t); + } + else{ + if( fhd->table->col[sp->idx].type == 'X' ){ + switch(fhd->table->col[sp->idx].n){ + case 8: + fprintf(fd, "#define %s %s*((%s *)(eptr+%d))%s\n", + sp->name, s, "unsigned char", offset, t); + break; + case 16: + fprintf(fd, "#define %s %s*((%s *)(SW2(eptr+%d,%d,_swf,%d)))%s\n", + sp->name, s, "unsigned short", offset, 2, offset, t); + break; + case 32: + fprintf(fd, "#define %s %s*((%s *)(SW4(eptr+%d,%d,_swf,%d)))%s\n", + sp->name, s, "unsigned int", offset, 4, offset, t); + break; + default: + fprintf(fd, "#define %s %s((%s *)(SW%d(eptr+%d,%d,_swf,%d)))%s\n", + sp->name, + s, + GetType((int)fhd->table->col[sp->idx].type), + dsize, + offset, + dsize, + offset, + t); + } + } + else if( fhd->table->col[sp->idx].type == 'A' ){ + fprintf(fd, "#define %s acopy(eptr+%d,%d)\n", + sp->name, + offset, + fhd->table->col[sp->idx].n); + } + else{ + fprintf(fd, "#define %s %s((%s *)(SW%d(eptr+%d,%d,_swf,%d)))%s\n", + sp->name, + s, + GetType((int)fhd->table->col[sp->idx].type), + dsize, + offset, + dsize, + offset, + t); + } + } + /* lower and upper case are both acceptable */ + strcpy(vbuf, sp->name); + cluc(vbuf); + if( strcmp(vbuf, sp->name) ){ + fprintf(fd, "#define %s %s\n", vbuf, sp->name); + } + culc(vbuf); + if( strcmp(vbuf, sp->name) ){ + fprintf(fd, "#define %s %s\n", vbuf, sp->name); + } + /* bump pointers */ + if( fhd->table->col[sp->idx].type == 'X' ){ + offset += + ((fhd->table->col[sp->idx].size*fhd->table->col[sp->idx].n)+7)/8; + evsize += + ((fhd->table->col[sp->idx].size*fhd->table->col[sp->idx].n)+7)/8; + } + else{ + offset += fhd->table->col[sp->idx].size*fhd->table->col[sp->idx].n; + evsize += fhd->table->col[sp->idx].size*fhd->table->col[sp->idx].n; + } + break; + case SYM_PAR: + /* we have to distinguish between numbers and strings here */ + /* strip off enclosing white space */ + (void)nowhite(sp->value, vbuf); + /* check for all white space */ + if( *vbuf == '\0' ){ + fprintf(fd, "#define %s \"\"\n", sp->name); + } + else{ + /* see if its a pure number */ + (void)strtod(vbuf, &v); + if( (v == NULL) || (*v == '\0') ) + fprintf(fd, "#define %s %s\n", sp->name, vbuf); + else + fprintf(fd, "#define %s \"%s\"\n", sp->name, vbuf); + } + break; + } + } + /* make sure each record is aligned */ + pad = 8 - (evsize % 8); + if( pad == 8 ) pad = 0; + evsize += pad; + /* make sure we have at least one byte to send to co-process */ + if( evsize <=0 ) evsize = 1; + /* output the size of the filter record */ + fprintf(fd, "#define EVSIZE %d\n", evsize); + fprintf(fd, "static char _swf[%d];\n", evsize); + /* save for later use */ + filter->evsize = evsize; + break; + default: + break; + } + + /* write out the mask structure */ + if( filter->nmask && filter->masks && + (filter->type == TYPE_EVENTS) && filter->evsect ){ + fprintf(fd, "#define NMASK %d\n", filter->nmask); + fprintf(fd, "#define MASKDIM %d;\n", ft_naxis(filter->maskhd, 1)); + fprintf(fd, "static FilterMaskRec _masks[]={\n"); + /* copy all masks and translate x,y positions as needed */ + for(i=0; inmask; i++){ + fprintf(fd, "{%d,%d,%d,%d}", + filter->masks[i].region, + filter->masks[i].y, + filter->masks[i].xstart, + filter->masks[i].xstop); + if( i != (filter->nmask -1) ) + fprintf(fd, ","); + fprintf(fd, "\n"); + } + fprintf(fd, "};\n"); + } + else{ + fprintf(fd, "#define NMASK 0\n"); + fprintf(fd, "#define MASKDIM 0;\n"); + fprintf(fd, "static FilterMask _masks=NULL;\n"); + } + + /* write it now */ + fflush(fd); + return(1); +} + +/* + * + * FilterProgAppend_C -- append the filter program body + * + */ +#ifdef ANSI_FUNC +static int +FilterProgAppend_C (Filter filter) +#else +static int FilterProgAppend_C(filter) + Filter filter; +#endif +{ + char *contents=NULL; + + /* make sure we have something to work with */ + if( !filter ) + return(0); + + /* make sure we are not in debug mode */ + if( filter->debug >= 2 ) + return(1); + + /* get body of filter program */ + switch( filter->type ){ + case TYPE_EVENTS: + contents = EVENTS_C; + break; + case TYPE_IMAGE: + contents = IMAGE_C; + break; + } + if( (contents != NULL) && (*contents != '\0') ){ + /* use fprintf so that we handle \n correctly in TEMPLATE */ + fprintf(filter->fp, "%s\n", contents); + return(1); + } + else{ + gerror(stderr, "could not write body of filter program\n"); + return(0); + } +} + +/* + * + * FilterProgClose_C -- close the filter program file + * + */ +#ifdef ANSI_FUNC +static int +FilterProgClose_C (Filter filter) +#else +static int FilterProgClose_C(filter) + Filter filter; +#endif +{ + /* make sure we have something to work with */ + if( !filter ) + return(0); + + /* close file if we are not in debug mode */ + if( (filter->debug < 2) && filter->fp ){ + fclose(filter->fp); + filter->fp = NULL; + } + return(1); +} + +/* + * + * FilterProgCompile_C -- compile the filter program + * + */ +#ifdef ANSI_FUNC +static int +FilterProgCompile_C (Filter filter) +#else +static int FilterProgCompile_C(filter) + Filter filter; +#endif +{ + char *s; + char *math; + char tbuf[SZ_LINE]; + char pmode[SZ_LINE]; + char log[SZ_LINE]; + char *devnull; +#ifdef USE_LAUNCH + char *stdfiles[3]; +#else + char tbuf2[SZ_LINE]; +#endif + int len; + int got; + int keep=0; + + /* make sure we have something to work with */ + if( !filter ) + return(0); + + /* make sure we are not in debug mode */ + if( !filter->cc || (filter->debug >= 2) ) + return(1); + + /* flag whether to keep compiler files around */ + if( !(s=getenv("FILTER_KEEP")) || !istrue(s) ) + keep = 0; + else + keep = 1; + + /* add math library, if necessary */ + switch(filter->pipeos){ + case PIPE_WIN32: + math = ""; + break; + default: + math = "-lm"; + break; + } + + /* set up /dev/null */ +#if HAVE_MINGW32 + devnull = "nul"; +#else + devnull = "/dev/null"; +#endif + + /* get log file name */ + snprintf(log, SZ_LINE, "%s.log", filter->prog); + + /* delete old version */ + unlink(filter->prog); + + switch(filter->ptype){ + case PTYPE_PROCESS: + /* make up the compile command */ + snprintf(tbuf, SZ_LINE, "%s %s -o %s %s %s %s %s", + filter->cc, filter->cflags, filter->prog, filter->code, + filter->objs ? filter->objs : " ", + filter->extra, math); +#ifndef USE_LAUNCH + snprintf(tbuf2, SZ_LINE, " 1>%s 2>%s", devnull, log); + strcat(tbuf, tbuf2); +#endif + strcpy(pmode, "x"); + break; + case PTYPE_CONTAINED: + /* make up the compile command */ + snprintf(tbuf, SZ_LINE, "%s %s -o %s %s %s %s", + filter->cc, filter->cflags, filter->prog, filter->code, + filter->extra, math); +#ifndef USE_LAUNCH + snprintf(tbuf2, SZ_LINE, " 1>%s 2>%s", devnull, log); + strcat(tbuf, tbuf2); +#endif + strcpy(pmode, "x"); + break; +#ifdef USE_DL + case PTYPE_DYNAMIC: + snprintf(tbuf, SZ_LINE, "%s %s %s %s -o %s %s %s", + filter->cc, filter->cflags, filter->shflags, + filter->objs ? filter->objs : " ", + filter->prog, filter->code, filter->extra); +#ifndef USE_LAUNCH + snprintf(tbuf2, SZ_LINE, " 1>%s 2>%s", devnull, log); + strcat(tbuf, tbuf2); +#endif + strcpy(pmode, "r"); + break; +#endif + default: + return(0); + } + + /* issue the shell command to compile the program */ +#ifdef USE_LAUNCH + stdfiles[0] = NULL; + stdfiles[1] = devnull; + stdfiles[2] = log; + got = Launch(tbuf, 1, stdfiles, NULL); +#else + got = system(tbuf); +#endif + + /* delete the filter program body in any case */ + if( !keep ) + unlink(filter->code); + + /* Sun cc can leave an extraneous .o around, which we don't want */ + strcpy(tbuf, filter->code); + /* change .c to .o */ + tbuf[strlen(tbuf)-1] = 'o'; + unlink(tbuf); + /* ... actually its usually left in the current directory */ + if( (s = strrchr(tbuf, '/')) ) + unlink(s+1); + + /* now we can see if we succeeded in issuing the command */ + if( got < 0 ){ + gerror(stderr, "could not run filter compilation\n"); + return(0); + } + + /* if we have an executable program, we succeeded */ + if( (s=Find(filter->prog, pmode, NULL, NULL)) != NULL ){ + unlink(log); + if( s ) xfree(s); + } + else{ + s = FileContents(log, 0, &len); + if( s && *s && len ){ + fprintf(stderr, "Compilation error message:\n%s\n", s); + } + if( !keep ){ + unlink(log); + } + if( s ) xfree(s); + gerror(stderr, "filter compilation failed\n"); + return(0); + } + + /* good news */ + return(1); +} + + +/* + * + * FilterProgEnd_C -- end the filtering process + * + */ +#ifdef ANSI_FUNC +static int +FilterProgEnd_C (Filter filter) +#else +int FilterProgEnd_C(filter) + Filter filter; +#endif +{ + char *s; + int status=0; + + /* make sure we have something to play with */ + if( filter == NULL) + return(0); + + /* delete the filter program */ + unlink(filter->prog); + /* delete the filter program body, if necessary */ + if( !(s=getenv("FILTER_KEEP")) || !istrue(s) ) + unlink(filter->code); + return(status); +} + +/* + * + * Public Routines + * + */ + +/* + * + * FilterProgLoad_C -- load the routines needed to support C filtering + * + */ +#ifdef ANSI_FUNC +int +FilterProgLoad_C (Filter filter) +#else +int FilterProgLoad_C(filter) + Filter filter; +#endif +{ + /* make sure we have something to work with */ + if( !filter ) + return(0); + + filter->filt_open = FilterProgOpen_C; + filter->filt_prepend = FilterProgPrepend_C; + filter->filt_write = FilterProgWrite_C; + filter->filt_append = FilterProgAppend_C; + filter->filt_close = FilterProgClose_C; + filter->filt_compile = FilterProgCompile_C; + filter->filt_end = FilterProgEnd_C; + return(1); +} diff --git a/filter/idx.h b/filter/idx.h new file mode 100644 index 0000000..0eaf982 --- /dev/null +++ b/filter/idx.h @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2005 Smithsonian Astrophysical Observatory + */ + +/* + * + * idx.h - include file for indexed filters + * + */ +#ifndef __idx_h +#define __idx_h + +#if HAVE_CONFIG_H +#include "conf.h" +#endif +#include "prsetup.h" +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_STRING_H +#include +#endif +#include "fitsy.h" +#include "gio.h" +#include "xalloc.h" +#include "strtod.h" + +/* binary search edge */ +#define IDX_EDGE_LEFT 1 +#define IDX_EDGE_RIGHT 2 +#define IDX_EDGE_BOTH (IDX_EDGE_LEFT|IDX_EDGE_RIGHT) + +/* type of row record */ +#define IDX_ALLROWS 0 +#define IDX_INDEF 1 +#define IDX_ROW_LIST 2 +#define IDX_SORT 3 +#define IDX_OR_SORT 4 +#define IDX_AND_SORT 5 + +/* methods of accessing data record */ +#define IDX_IO_MMAP 1 +#define IDX_IO_LSEEK 2 + +#ifdef HAVE_SYS_MMAN_H +#define IDX_IO_DEFAULT IDX_IO_MMAP +#else +#define IDX_IO_DEFAULT IDX_IO_LSEEK +#endif + +/* increment for storing rowlists */ +#define IDX_ROW_INC 32 + +/* sort program */ +#define IDX_SORTPROG "_funsort" + +/* idxinfo which values */ +#define IDX_COLNAME 1 +#define IDX_FILENAME 2 +#define IDX_FILEROOT1 3 +#define IDX_FILEROOT2 4 +#define IDX_PATHNAME 5 +#define IDX_SORTNAME 6 + +/* rows can be in memory range lists or file-based row numbers */ +typedef struct _idxrowrec{ + struct _idxrowrec *next; + char *s; + int type; + int rtype; + int dofilt; + int dosort; + int rtot; + int maxrow; + int nrow; + int *startrow; + int *stoprow; + FILE *ifile; + int ichan; + int ochan; + int pid; + struct _idxvalrec *v; + char *fdata; + int flen; +} idxrowrec; + +/* values can be int, float, col, region, func */ +typedef struct _idxvalrec{ + struct _idxvalrec *next; + char *s; + int type; + int ntype; + longlong ival; + double dval; + char *iname; + GIO igio; + FITSHead ifits; + int itype; + int ioffset; + int in; + int vtype; + int voffset; + int vn; + int nrow; + char *idata; + int ilen; + struct _idxvalrec *rv[2]; + double rlo[2], rhi[2]; +} idxvalrec; + +_PRbeg + +idxrowrec *idxall _PRx((idxrowrec *row)); +idxrowrec *idxor _PRx((idxrowrec *row1, idxrowrec *row2)); +idxrowrec *idxand _PRx((idxrowrec *row1, idxrowrec *row2)); +idxrowrec *idxnot _PRx((idxrowrec *row)); + +idxrowrec *idxrowreg _PRx((idxvalrec *val)); +idxrowrec *idxrowfun _PRx((idxvalrec *val)); +idxrowrec *idxroweq _PRx((idxvalrec *val1, idxvalrec *val2)); +idxrowrec *idxrowne _PRx((idxvalrec *val1, idxvalrec *val2)); +idxrowrec *idxrowlt _PRx((idxvalrec *val1, idxvalrec *val2)); +idxrowrec *idxrowle _PRx((idxvalrec *val1, idxvalrec *val2)); +idxrowrec *idxrowgt _PRx((idxvalrec *val1, idxvalrec *val2)); +idxrowrec *idxrowge _PRx((idxvalrec *val1, idxvalrec *val2)); +idxrowrec *idxrownot _PRx((idxvalrec *val)); + +idxvalrec *idxvaladd _PRx((idxvalrec *val1, idxvalrec *val2)); + +idxvalrec *idxvalsub _PRx((idxvalrec *val1, idxvalrec *val2)); +idxvalrec *idxvalmul _PRx((idxvalrec *val1, idxvalrec *val2)); +idxvalrec *idxvaldiv _PRx((idxvalrec *val1, idxvalrec *val2)); +idxvalrec *idxvalmod _PRx((idxvalrec *val1, idxvalrec *val2)); +idxvalrec *idxvaland _PRx((idxvalrec *val1, idxvalrec *val2)); +idxvalrec *idxvalor _PRx((idxvalrec *val1, idxvalrec *val2)); +idxvalrec *idxvalxor _PRx((idxvalrec *val1, idxvalrec *val2)); +idxvalrec *idxvalnot _PRx((idxvalrec *val)); +idxvalrec *idxvalcom _PRx((idxvalrec *val)); +idxvalrec *idxvalmin _PRx((idxvalrec *val)); + +char *idxinfo _PRx((int which)); +int idxdebug _PRx((int debug)); +idxvalrec *idxvalnew _PRx((char *s)); +int idxvalfree _PRx((idxvalrec *v)); +idxrowrec *idxrownew _PRx((void)); +int idxrowfree _PRx((idxrowrec *r)); +int idxinitfilenames _PRx((char *s, int *flag)); +char *idxindexfilename _PRx((char *s, int *size)); +idxvalrec *idxlookupfilename _PRx((char *iname)); +void idxfreefilenames _PRx((void)); +void idxfreeglobals _PRx((void)); +int idxinitparser _PRx((char *s)); +void idxendparser _PRx((void)); +void *idxread _PRx((idxrowrec *row, GIO gio, FITSHead fits, + void *buf, size_t size, size_t get, size_t *got, + int *dofilt)); +void idxstring _PRx((char *s)); +int idxerror _PRx((char *mmsg)); +int idxlex _PRx((void)); +int idxparse _PRx((void)); + +_PRend + +#endif /* __idx.h */ diff --git a/filter/idx.l b/filter/idx.l new file mode 100644 index 0000000..a542505 --- /dev/null +++ b/filter/idx.l @@ -0,0 +1,559 @@ +%option caseless +%array + +%{ +#include +#include +#include +#include + +extern int idx_debug; + +static int _valint(char *s, idxvalrec **v); +static int _valfloat(char *s, idxvalrec **v); +static int _valname(char *s, idxvalrec **v); +static int _valreg(char *s, idxvalrec **v); +static int _valfunc(char *s, idxvalrec **v); +%} + +SP [ \t] +DIG [0-9] +DIG2 [0-9a-fA-F] +/* note that negative numbers are not defined here, but in the grammar */ +INT1 {DIG}+L? +INT2 0[xX]{DIG2}+L? +INT ({INT1}|{INT2}) +FLOAT1 {DIG}+\.?([eE][-+]?{DIG}+)? +FLOAT2 {DIG}*\.{DIG}+([eE][-+]?{DIG}+)? +XFLOAT -142857.142857 +FLOAT ({FLOAT1}|{FLOAT2}|{XFLOAT}) +NUM ({INT}|{FLOAT}) +NAME [A-Za-z_][0-9A-Za-z~_]*(\[[^\[]*\])? + +/* must match regions in filt.l */ +REGION (ev|im)[vn]?(annulus|box|circle|ellipse|line|panda|pie|qtpie|point|polygon|field|bpanda|cpanda|epanda) +%% + +{INT} {return _valint(yytext, &(idxlval.val));} + +{FLOAT} {return _valfloat(yytext, &(idxlval.val));} + + +evfield"(g",{INT},{INT},{INT},{INT},"(double)"{NAME},"(double)"{NAME}")" { + return _valreg(yytext, &(idxlval.val)); +} + +{REGION}"(g",{INT},{INT},{INT},{INT},"(double)"{NAME},"(double)"{NAME}(,[+-]?{FLOAT})*,[+-]?{FLOAT}")" { + return _valreg(yytext, &(idxlval.val)); +} + +{NAME}"("[^()]*("("[^()]*")")*")" { + /* support functions with one level of nested parens */ + return _valfunc(yytext, &(idxlval.val)); +} + +{NAME} {return _valname(yytext, &(idxlval.val));} + +"||" {return OR;} +"&&" {return AND;} +"==" {return EQ;} +"!=" {return NE;} +"<=" {return LE;} +">=" {return GE;} + +{SP} {;} + +<> { + yy_delete_buffer( YY_CURRENT_BUFFER ); + yyterminate(); + } + +. {return yytext[0];} + +%% + +#ifdef YY_USE_PROTOS +static int _valint(char *s, idxvalrec **v) +#else +static int _valint(s, v) + char *s; + idxvalrec **v; +#endif +{ + char *t; + *v = idxvalnew(s); + (*v)->ival = strtoll(s, &t, 0); + if( *t ) + idxerror("bad integer value"); + (*v)->type = NUM; + (*v)->ntype = PARSE_INTEGER; + (*v)->dval = (double)(*v)->ival; + return NUM; +} + +#ifdef YY_USE_PROTOS +static int _valfloat(char *s, idxvalrec **v) +#else +static int _valfloat(s, v) + char *s; + idxvalrec **v; +#endif +{ + char *t; + *v = idxvalnew(s); + (*v)->dval = strtod(s, &t); + if( *t ) + idxerror("bad float value"); + (*v)->type = NUM; + (*v)->ntype = PARSE_FLOAT; + return NUM; +} + +#ifdef YY_USE_PROTOS +static int _valname(char *s, idxvalrec **v) +#else +static int _valname(s, v) + char *s; + idxvalrec **v; +#endif +{ + int i; + int got; + int oflag; + int isize=0; + char *iname; + char *colname; + char tail[SZ_LINE]; + FilterSymbols sp=NULL; + idxvalrec *vv; + + *v = idxvalnew(s); + /* lookup the string */ + if( !(sp=FilterSymbolLookup(FilterDefault(), s)) ){ + idxerror("column name not found in data file"); + (*v)->type = INDEF; + return INDEF; + } + colname = idxinfo(IDX_COLNAME); + /* see what sort of symbol it is */ + switch(sp->type){ + case SYM_COL: + if( !(iname=idxindexfilename(s, &isize)) ){ + (*v)->type = INDEF; + return INDEF; + } + /* if we already have opened this index, just use the existing handle */ + if( (vv=idxlookupfilename(iname)) ){ + (*v)->igio = vv->igio; + (*v)->ifits = vv->ifits; + } + /* open index for first time and mark iname */ + else{ + oflag = setgerror(0); + (*v)->igio = ft_fitsheadopen(iname, &((*v)->ifits), tail, SZ_LINE, "r"); + setgerror(oflag); + if( !((*v)->igio) ){ + idxerror("existing index file can't be opened"); + (*v)->type = INDEF; + return INDEF; + } + else{ + (*v)->iname = xstrdup(iname); + } + } + xfree(iname); + if( (*v)->ifits ){ + for(got=0, i=0; i<(*v)->ifits->table->tfields; i++){ + if( !strcasecmp(s, (*v)->ifits->table->col[i].name) ){ + (*v)->vtype = (*v)->ifits->table->col[i].type; + (*v)->voffset = (*v)->ifits->table->col[i].offset; + (*v)->vn = (*v)->ifits->table->col[i].n; + got++; + } + if( !strcasecmp(colname, (*v)->ifits->table->col[i].name) ){ + (*v)->itype = (*v)->ifits->table->col[i].type; + (*v)->ioffset = (*v)->ifits->table->col[i].offset; + (*v)->in = (*v)->ifits->table->col[i].n; + got++; + } + } + if( got == 2 ){ +#ifdef HAVE_SYS_MMAN_H + if( !(*v)->igio->gz ){ + if(!((*v)->idata = mmap(NULL, isize, PROT_READ, MAP_PRIVATE, + fileno((*v)->igio->fp), 0)) ){ + idxerror("index file can't be mmap'ed"); + (*v)->type = INDEF; + return INDEF; + } + (*v)->ilen = isize; + } +#endif + (*v)->nrow = ft_naxis((*v)->ifits,2); + (*v)->type = COL; + return COL; + } + else{ + idxerror("column name and/or index not found in index file"); + } + } + else{ + (*v)->type = INDEF; + return INDEF; + } + case SYM_PAR: + (*v)->ntype=ParseDataType(sp->value, &(*v)->dval, &(*v)->ival); + (*v)->type = NUM; + switch((*v)->ntype){ + case PARSE_INTEGER: + case PARSE_HEXINT: + (*v)->dval = (double)(*v)->ival; + return NUM; + case PARSE_FLOAT: + return NUM; + default: + idxerror("invalid parameter type in index"); + return 0; + } + default: + idxerror("unknown symbol type in index"); + return 0; + } +} + +#ifdef YY_USE_PROTOS +static int _valreglims(idxvalrec *v, char *s) +#else +static int _valreglims(v, s) + idxvalrec *v; + char *s; +#endif +{ + int i; + int ip=0; + int nd=0, maxd=0; + double xcen, ycen; + double dval; + double *dvals; + double pts[8]; + char tbuf[SZ_LINE]; + char tbuf2[SZ_LINE]; + double angle; + double xwidth, yheight; + double angl; /* l: Cartesian angle in radians */ + double half_width, half_height;/* l: radii (1/2 width and height) */ + double cosangl, sinangl; /* l: sine, cosine of the Cartesian angle */ + double hw_cos, hw_sin; /* l: products of half_width with sin, cos */ + double hh_cos, hh_sin; /* l: products of half_height with sin, cos */ + + if( !strcmp(v->s, "circle") || !strcmp(v->s, "ncircle") || + !strcmp(v->s, "annulus") || !strcmp(v->s, "nannulus") ){ + if( !word(s, tbuf, &ip)||!word(s, tbuf2, &ip) ) return 0; + xcen = atof(tbuf); + ycen = atof(tbuf2); + dval = -1; + if( *v->s == 'n' ){ + if( !word(s, tbuf, &ip) || !word(s, tbuf, &ip) ) return 0; + dval = MAX(atof(tbuf),dval); + } + else{ + while( word(s, tbuf, &ip) && strcmp(tbuf, "-142857.142857") ){ + dval = MAX(atof(tbuf),dval); + } + } + v->rlo[0] = xcen - dval - 1; + v->rhi[0] = xcen + dval + 1; + v->rlo[1] = ycen - dval - 1; + v->rhi[1] = ycen + dval + 1; + return 1; + } + else if( !strcmp(v->s, "box") || !strcmp(v->s, "nbox") || + !strcmp(v->s, "ellipse") || !strcmp(v->s, "nellipse") ){ + if( !word(s, tbuf, &ip)||!word(s, tbuf2, &ip) ) return 0; + xcen = atof(tbuf); + ycen = atof(tbuf2); + maxd = SZ_LINE; + if( !(dvals=(double *)malloc(maxd*sizeof(double))) ) return 0; + if( *v->s == 'n' ){ + if( !word(s, tbuf, &ip) || !word(s, tbuf, &ip) ) return 0; + if( !word(s, tbuf, &ip) || !word(s, tbuf2, &ip) ) return 0; + dvals[nd++] = atof(tbuf); + dvals[nd++] = atof(tbuf2); + if( word(s, tbuf, &ip) && word(s, tbuf, &ip) ) + dvals[nd++] = atof(tbuf); + } + else{ + while( word(s, tbuf, &ip) && strcmp(tbuf, "-142857.142857") ){ + dvals[nd++] = atof(tbuf); + if( nd == maxd ){ + maxd += SZ_LINE; + if( !(dvals=(double *)realloc(dvals, maxd*sizeof(double))) ) return 0; + } + } + } +ellcom: + if( nd == 2 ){ + angle = 0.0; + xwidth = dvals[0]; + yheight = dvals[1]; + } + else{ + angle = dvals[nd-1]; + xwidth = dvals[nd-3]; + yheight = dvals[nd-2]; + } + if( dvals ) xfree(dvals); + + /* Why is this done in evfilter.c??? Doesn't seem necessary */ + /* angl = angle + 90.0; */ + angl = angle; + while (angl >= 360.0) angl = angl - 360.0; + /* convert to radians */ + angl = (angl / 180.0) * M_PI; + sinangl = sin (angl); + cosangl = cos (angl); + /* Why is this done in evfilter.c??? Doesn't seem necessary */ + /* since we rotate by 90.0 degrees to get from astro angle to cartesian, */ + /* we also need to switch the width and height. we do this secretly so */ + /* that the display will turn out right, by doing it in the half terms */ + if( !strcmp(v->s, "box") ){ + /* + half_width = yheight / 2.0; + half_height = xwidth / 2.0; + */ + half_width = xwidth / 2.0; + half_height = yheight / 2.0; + } + else{ + /* + half_width = yheight; + half_height = xwidth; + */ + half_width = xwidth; + half_height = yheight; + } + hw_cos = half_width * cosangl; + hw_sin = half_width * sinangl; + hh_cos = half_height * cosangl; + hh_sin = half_height * sinangl; + + pts[0] = xcen - hw_cos - hh_sin; + pts[1] = ycen - hw_sin + hh_cos; + pts[2] = xcen + hw_cos - hh_sin; + pts[3] = ycen + hw_sin + hh_cos; + pts[4] = xcen + hw_cos + hh_sin; + pts[5] = ycen + hw_sin - hh_cos; + pts[6] = xcen - hw_cos + hh_sin; + pts[7] = ycen - hw_sin - hh_cos; + + v->rlo[0] = pts[0]; + v->rhi[0] = pts[0]; + v->rlo[1] = pts[1]; + v->rhi[1] = pts[1]; + for(i=2; i<8; i+=2){ + v->rlo[0] = MIN(pts[i],v->rlo[0]); + v->rhi[0] = MAX(pts[i],v->rhi[0]); + v->rlo[1] = MIN(pts[i+1],v->rlo[1]); + v->rhi[1] = MAX(pts[i+1],v->rhi[1]); + } + return 1; + } + else if( !strcmp(v->s, "line") ){ + for(i=0; i<4; i++){ + if( word(s, tbuf, &ip) ){ + pts[i] = atof(tbuf); + } + } + v->rlo[0] = MIN(pts[0],pts[2]); + v->rhi[0] = MAX(pts[0],pts[2]); + v->rlo[1] = MIN(pts[1],pts[3]); + v->rhi[1] = MAX(pts[1],pts[3]); + return 1; + } + else if( !strcmp(v->s, "point") || !strcmp(v->s, "polygon") ){ + if( !word(s, tbuf, &ip)||!word(s, tbuf2, &ip) ) return 0; + xcen = atof(tbuf); + ycen = atof(tbuf2); + v->rlo[0] = xcen-1; + v->rhi[0] = xcen+1; + v->rlo[1] = ycen-1; + v->rhi[1] = ycen+1; + while( word(s, tbuf, &ip) && strcmp(tbuf, "-142857.142857") && + word(s, tbuf2, &ip) ){ + dval = atof(tbuf); + v->rlo[0] = MIN(dval-1,v->rlo[0]); + v->rhi[0] = MAX(dval+1,v->rhi[0]); + dval = atof(tbuf2); + v->rlo[1] = MIN(dval-1,v->rlo[1]); + v->rhi[1] = MAX(dval+1,v->rhi[1]); + } + return 1; + } + else if( !strcmp(v->s, "pie") || !strcmp(v->s, "qtpie") ){ + return 0; + } + else if( !strcmp(v->s, "panda") || !strcmp(v->s, "cpanda") ){ + maxd = SZ_LINE; + if( !(dvals=(double *)malloc(maxd*sizeof(double))) ) return 0; + while( word(s, tbuf, &ip) && strcmp(tbuf, "-142857.142857") ){ + dvals[nd++] = atof(tbuf); + if( nd == maxd ){ + maxd += SZ_LINE; + if( !(dvals=(double *)realloc(dvals, maxd*sizeof(double))) ) return 0; + } + } + v->rlo[0] = dvals[0] - dvals[6] - 1; + v->rhi[0] = dvals[0] + dvals[6] + 1; + v->rlo[1] = dvals[1] - dvals[6] - 1; + v->rhi[1] = dvals[1] + dvals[6] + 1; + if( dvals ) xfree(dvals); + return 1; + } + else if( !strcmp(v->s, "bpanda") || !strcmp(v->s, "epanda") ){ + maxd = 3; + if( !(dvals=(double *)malloc(maxd*sizeof(double))) ) return 0; + /* grab: xcen ycen */ + if( !word(s, tbuf, &ip)||!word(s, tbuf2, &ip) ) return 0; + xcen = atof(tbuf); + ycen = atof(tbuf2); + /* skip: ang1 ang2 nang xwlo yhlo */ + for(i=0; i<5; i++){ + if( !word(s, tbuf, &ip) ) return 0; + } + /* grab: xwhi yhhi */ + for(i=0; i<2; i++){ + if( !word(s, tbuf, &ip) ) return 0; + dvals[nd++] = atof(tbuf); + } + /* skip: nrad */ + if( !word(s, tbuf, &ip) ) return 0; + /* grab: ang */ + if( !word(s, tbuf, &ip) ) return 0; + dvals[nd++] = atof(tbuf); + /* we can now handle this with box/ellipse code */ + goto ellcom; + } + else if( !strcmp(v->s, "field") ){ + return 0; + } + else{ + return 0; + } +} + +#ifdef YY_USE_PROTOS +static int _valreg(char *s, idxvalrec **v) +#else +static int _valreg(s, v) + char *s; + idxvalrec **v; +#endif +{ + int ip=0; + char *t; + char tbuf[SZ_LINE]; + *v = idxvalnew(NULL); + newdtable("(),"); + while( *s == '(' ) s++; + if( !word(s, tbuf, &ip) ){ + (*v)->type = INDEF; + return REG; + } + if( strstr(tbuf, "field") ){ + (*v)->type = INDEF; + return REG; + } + t = tbuf+2; + if( *t == 'v' ) t++; + (*v)->s = xstrdup(t); + if( !word(s, tbuf, &ip) || !word(s, tbuf, &ip) || + !word(s, tbuf, &ip) || !word(s, tbuf, &ip) ){ + (*v)->type = INDEF; + return REG; + } + /* include/exclude */ + if( !atoi(tbuf) ){ + (*v)->type = INDEF; + return REG; + } + if( !word(s, tbuf, &ip) || !word(s, tbuf, &ip) || !word(s, tbuf, &ip) ){ + (*v)->type = INDEF; + return REG; + } + culc(tbuf); + _valname(tbuf, &(*v)->rv[0]); + if( !word(s, tbuf, &ip) || !word(s, tbuf, &ip) ){ + (*v)->type = INDEF; + return REG; + } + culc(tbuf); + _valname(tbuf, &(*v)->rv[1]); + if( !_valreglims(*v, &s[ip]) ){ + (*v)->type = INDEF; + return REG; + } + freedtable(); + (*v)->type = REG; + return REG; +} + +#ifdef YY_USE_PROTOS +static int _valfunc(char *s, idxvalrec **v) +#else +static int _valfunc(s, v) + char *s; + idxvalrec **v; +#endif +{ + *v = idxvalnew(s); + (*v)->type = FUNC; + return FUNC; +} + + +#ifdef YY_USE_PROTOS +void +idxstring(char *s) +#else +void idxstring(s) + char *s; +#endif +{ + idx_scan_string(s); +} + +#ifdef YY_USE_PROTOS +int +idxerror(char *msg) +#else +int idxerror(msg) + char *msg; +#endif +{ + Filter filter; + + YY_FLUSH_BUFFER; + /* turn indexing off */ + if( (filter=FilterDefault()) ){ + filter->doidx = -1; + } + /* output message, if necessary */ + if( idx_debug ){ + fprintf(stderr, "ERROR: %s", msg); + if( !strcmp(msg, "syntax error") ){ + fprintf(stderr, " (terminating index processing)"); + } + fprintf(stderr, "\n"); + } + yyterminate(); +} + +#ifdef YY_USE_PROTOS +int yywrap(void) +#else +int yywrap() +#endif +{ + return 1; +} + diff --git a/filter/idx.output b/filter/idx.output new file mode 100644 index 0000000..0a2de2d --- /dev/null +++ b/filter/idx.output @@ -0,0 +1,1007 @@ +State 3 conflicts: 1 reduce/reduce + + +Grammar + + 0 $accept: idx $end + + 1 idx: expr + + 2 expr: rowlist + 3 | expr OR expr + 4 | expr AND expr + 5 | '(' expr ')' + + 6 rowlist: REG + 7 | FUNC + 8 | value EQ value + 9 | value NE value + 10 | value '<' value + 11 | value LE value + 12 | value '>' value + 13 | value GE value + + 14 value: NUM + 15 | COL + 16 | INDEF + 17 | FUNC + 18 | value '+' value + 19 | value '-' value + 20 | value '*' value + 21 | value '/' value + 22 | value '%' value + 23 | value '&' value + 24 | value '|' value + 25 | value '^' value + 26 | '!' value + 27 | '~' value + 28 | '-' value + 29 | '(' value ')' + + +Terminals, with rules where they appear + +$end (0) 0 +'!' (33) 26 +'%' (37) 22 +'&' (38) 23 +'(' (40) 5 29 +')' (41) 5 29 +'*' (42) 20 +'+' (43) 18 +'-' (45) 19 28 +'/' (47) 21 +'<' (60) 10 +'>' (62) 12 +'^' (94) 25 +'|' (124) 24 +'~' (126) 27 +error (256) +NUM (258) 14 +COL (259) 15 +FUNC (260) 7 17 +REG (261) 6 +INDEF (262) 16 +OR (263) 3 +AND (264) 4 +NE (265) 9 +EQ (266) 8 +GE (267) 13 +LE (268) 11 +UMINUS (269) + + +Nonterminals, with rules where they appear + +$accept (29) + on left: 0 +idx (30) + on left: 1, on right: 0 +expr (31) + on left: 2 3 4 5, on right: 1 3 4 5 +rowlist (32) + on left: 6 7 8 9 10 11 12 13, on right: 2 +value (33) + on left: 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29, + on right: 8 9 10 11 12 13 18 19 20 21 22 23 24 25 26 27 28 29 + + +state 0 + + 0 $accept: . idx $end + + NUM shift, and go to state 1 + COL shift, and go to state 2 + FUNC shift, and go to state 3 + REG shift, and go to state 4 + INDEF shift, and go to state 5 + '-' shift, and go to state 6 + '!' shift, and go to state 7 + '~' shift, and go to state 8 + '(' shift, and go to state 9 + + idx go to state 10 + expr go to state 11 + rowlist go to state 12 + value go to state 13 + + +state 1 + + 14 value: NUM . + + $default reduce using rule 14 (value) + + +state 2 + + 15 value: COL . + + $default reduce using rule 15 (value) + + +state 3 + + 7 rowlist: FUNC . + 17 value: FUNC . + + $end reduce using rule 7 (rowlist) + OR reduce using rule 7 (rowlist) + AND reduce using rule 7 (rowlist) + ')' reduce using rule 7 (rowlist) + ')' [reduce using rule 17 (value)] + $default reduce using rule 17 (value) + + +state 4 + + 6 rowlist: REG . + + $default reduce using rule 6 (rowlist) + + +state 5 + + 16 value: INDEF . + + $default reduce using rule 16 (value) + + +state 6 + + 28 value: '-' . value + + NUM shift, and go to state 1 + COL shift, and go to state 2 + FUNC shift, and go to state 14 + INDEF shift, and go to state 5 + '-' shift, and go to state 6 + '!' shift, and go to state 7 + '~' shift, and go to state 8 + '(' shift, and go to state 15 + + value go to state 16 + + +state 7 + + 26 value: '!' . value + + NUM shift, and go to state 1 + COL shift, and go to state 2 + FUNC shift, and go to state 14 + INDEF shift, and go to state 5 + '-' shift, and go to state 6 + '!' shift, and go to state 7 + '~' shift, and go to state 8 + '(' shift, and go to state 15 + + value go to state 17 + + +state 8 + + 27 value: '~' . value + + NUM shift, and go to state 1 + COL shift, and go to state 2 + FUNC shift, and go to state 14 + INDEF shift, and go to state 5 + '-' shift, and go to state 6 + '!' shift, and go to state 7 + '~' shift, and go to state 8 + '(' shift, and go to state 15 + + value go to state 18 + + +state 9 + + 5 expr: '(' . expr ')' + 29 value: '(' . value ')' + + NUM shift, and go to state 1 + COL shift, and go to state 2 + FUNC shift, and go to state 3 + REG shift, and go to state 4 + INDEF shift, and go to state 5 + '-' shift, and go to state 6 + '!' shift, and go to state 7 + '~' shift, and go to state 8 + '(' shift, and go to state 9 + + expr go to state 19 + rowlist go to state 12 + value go to state 20 + + +state 10 + + 0 $accept: idx . $end + + $end shift, and go to state 21 + + +state 11 + + 1 idx: expr . + 3 expr: expr . OR expr + 4 | expr . AND expr + + OR shift, and go to state 22 + AND shift, and go to state 23 + + $default reduce using rule 1 (idx) + + +state 12 + + 2 expr: rowlist . + + $default reduce using rule 2 (expr) + + +state 13 + + 8 rowlist: value . EQ value + 9 | value . NE value + 10 | value . '<' value + 11 | value . LE value + 12 | value . '>' value + 13 | value . GE value + 18 value: value . '+' value + 19 | value . '-' value + 20 | value . '*' value + 21 | value . '/' value + 22 | value . '%' value + 23 | value . '&' value + 24 | value . '|' value + 25 | value . '^' value + + '|' shift, and go to state 24 + '^' shift, and go to state 25 + '&' shift, and go to state 26 + NE shift, and go to state 27 + EQ shift, and go to state 28 + '<' shift, and go to state 29 + '>' shift, and go to state 30 + GE shift, and go to state 31 + LE shift, and go to state 32 + '+' shift, and go to state 33 + '-' shift, and go to state 34 + '*' shift, and go to state 35 + '/' shift, and go to state 36 + '%' shift, and go to state 37 + + +state 14 + + 17 value: FUNC . + + $default reduce using rule 17 (value) + + +state 15 + + 29 value: '(' . value ')' + + NUM shift, and go to state 1 + COL shift, and go to state 2 + FUNC shift, and go to state 14 + INDEF shift, and go to state 5 + '-' shift, and go to state 6 + '!' shift, and go to state 7 + '~' shift, and go to state 8 + '(' shift, and go to state 15 + + value go to state 38 + + +state 16 + + 18 value: value . '+' value + 19 | value . '-' value + 20 | value . '*' value + 21 | value . '/' value + 22 | value . '%' value + 23 | value . '&' value + 24 | value . '|' value + 25 | value . '^' value + 28 | '-' value . + + $default reduce using rule 28 (value) + + +state 17 + + 18 value: value . '+' value + 19 | value . '-' value + 20 | value . '*' value + 21 | value . '/' value + 22 | value . '%' value + 23 | value . '&' value + 24 | value . '|' value + 25 | value . '^' value + 26 | '!' value . + + $default reduce using rule 26 (value) + + +state 18 + + 18 value: value . '+' value + 19 | value . '-' value + 20 | value . '*' value + 21 | value . '/' value + 22 | value . '%' value + 23 | value . '&' value + 24 | value . '|' value + 25 | value . '^' value + 27 | '~' value . + + $default reduce using rule 27 (value) + + +state 19 + + 3 expr: expr . OR expr + 4 | expr . AND expr + 5 | '(' expr . ')' + + OR shift, and go to state 22 + AND shift, and go to state 23 + ')' shift, and go to state 39 + + +state 20 + + 8 rowlist: value . EQ value + 9 | value . NE value + 10 | value . '<' value + 11 | value . LE value + 12 | value . '>' value + 13 | value . GE value + 18 value: value . '+' value + 19 | value . '-' value + 20 | value . '*' value + 21 | value . '/' value + 22 | value . '%' value + 23 | value . '&' value + 24 | value . '|' value + 25 | value . '^' value + 29 | '(' value . ')' + + '|' shift, and go to state 24 + '^' shift, and go to state 25 + '&' shift, and go to state 26 + NE shift, and go to state 27 + EQ shift, and go to state 28 + '<' shift, and go to state 29 + '>' shift, and go to state 30 + GE shift, and go to state 31 + LE shift, and go to state 32 + '+' shift, and go to state 33 + '-' shift, and go to state 34 + '*' shift, and go to state 35 + '/' shift, and go to state 36 + '%' shift, and go to state 37 + ')' shift, and go to state 40 + + +state 21 + + 0 $accept: idx $end . + + $default accept + + +state 22 + + 3 expr: expr OR . expr + + NUM shift, and go to state 1 + COL shift, and go to state 2 + FUNC shift, and go to state 3 + REG shift, and go to state 4 + INDEF shift, and go to state 5 + '-' shift, and go to state 6 + '!' shift, and go to state 7 + '~' shift, and go to state 8 + '(' shift, and go to state 9 + + expr go to state 41 + rowlist go to state 12 + value go to state 13 + + +state 23 + + 4 expr: expr AND . expr + + NUM shift, and go to state 1 + COL shift, and go to state 2 + FUNC shift, and go to state 3 + REG shift, and go to state 4 + INDEF shift, and go to state 5 + '-' shift, and go to state 6 + '!' shift, and go to state 7 + '~' shift, and go to state 8 + '(' shift, and go to state 9 + + expr go to state 42 + rowlist go to state 12 + value go to state 13 + + +state 24 + + 24 value: value '|' . value + + NUM shift, and go to state 1 + COL shift, and go to state 2 + FUNC shift, and go to state 14 + INDEF shift, and go to state 5 + '-' shift, and go to state 6 + '!' shift, and go to state 7 + '~' shift, and go to state 8 + '(' shift, and go to state 15 + + value go to state 43 + + +state 25 + + 25 value: value '^' . value + + NUM shift, and go to state 1 + COL shift, and go to state 2 + FUNC shift, and go to state 14 + INDEF shift, and go to state 5 + '-' shift, and go to state 6 + '!' shift, and go to state 7 + '~' shift, and go to state 8 + '(' shift, and go to state 15 + + value go to state 44 + + +state 26 + + 23 value: value '&' . value + + NUM shift, and go to state 1 + COL shift, and go to state 2 + FUNC shift, and go to state 14 + INDEF shift, and go to state 5 + '-' shift, and go to state 6 + '!' shift, and go to state 7 + '~' shift, and go to state 8 + '(' shift, and go to state 15 + + value go to state 45 + + +state 27 + + 9 rowlist: value NE . value + + NUM shift, and go to state 1 + COL shift, and go to state 2 + FUNC shift, and go to state 14 + INDEF shift, and go to state 5 + '-' shift, and go to state 6 + '!' shift, and go to state 7 + '~' shift, and go to state 8 + '(' shift, and go to state 15 + + value go to state 46 + + +state 28 + + 8 rowlist: value EQ . value + + NUM shift, and go to state 1 + COL shift, and go to state 2 + FUNC shift, and go to state 14 + INDEF shift, and go to state 5 + '-' shift, and go to state 6 + '!' shift, and go to state 7 + '~' shift, and go to state 8 + '(' shift, and go to state 15 + + value go to state 47 + + +state 29 + + 10 rowlist: value '<' . value + + NUM shift, and go to state 1 + COL shift, and go to state 2 + FUNC shift, and go to state 14 + INDEF shift, and go to state 5 + '-' shift, and go to state 6 + '!' shift, and go to state 7 + '~' shift, and go to state 8 + '(' shift, and go to state 15 + + value go to state 48 + + +state 30 + + 12 rowlist: value '>' . value + + NUM shift, and go to state 1 + COL shift, and go to state 2 + FUNC shift, and go to state 14 + INDEF shift, and go to state 5 + '-' shift, and go to state 6 + '!' shift, and go to state 7 + '~' shift, and go to state 8 + '(' shift, and go to state 15 + + value go to state 49 + + +state 31 + + 13 rowlist: value GE . value + + NUM shift, and go to state 1 + COL shift, and go to state 2 + FUNC shift, and go to state 14 + INDEF shift, and go to state 5 + '-' shift, and go to state 6 + '!' shift, and go to state 7 + '~' shift, and go to state 8 + '(' shift, and go to state 15 + + value go to state 50 + + +state 32 + + 11 rowlist: value LE . value + + NUM shift, and go to state 1 + COL shift, and go to state 2 + FUNC shift, and go to state 14 + INDEF shift, and go to state 5 + '-' shift, and go to state 6 + '!' shift, and go to state 7 + '~' shift, and go to state 8 + '(' shift, and go to state 15 + + value go to state 51 + + +state 33 + + 18 value: value '+' . value + + NUM shift, and go to state 1 + COL shift, and go to state 2 + FUNC shift, and go to state 14 + INDEF shift, and go to state 5 + '-' shift, and go to state 6 + '!' shift, and go to state 7 + '~' shift, and go to state 8 + '(' shift, and go to state 15 + + value go to state 52 + + +state 34 + + 19 value: value '-' . value + + NUM shift, and go to state 1 + COL shift, and go to state 2 + FUNC shift, and go to state 14 + INDEF shift, and go to state 5 + '-' shift, and go to state 6 + '!' shift, and go to state 7 + '~' shift, and go to state 8 + '(' shift, and go to state 15 + + value go to state 53 + + +state 35 + + 20 value: value '*' . value + + NUM shift, and go to state 1 + COL shift, and go to state 2 + FUNC shift, and go to state 14 + INDEF shift, and go to state 5 + '-' shift, and go to state 6 + '!' shift, and go to state 7 + '~' shift, and go to state 8 + '(' shift, and go to state 15 + + value go to state 54 + + +state 36 + + 21 value: value '/' . value + + NUM shift, and go to state 1 + COL shift, and go to state 2 + FUNC shift, and go to state 14 + INDEF shift, and go to state 5 + '-' shift, and go to state 6 + '!' shift, and go to state 7 + '~' shift, and go to state 8 + '(' shift, and go to state 15 + + value go to state 55 + + +state 37 + + 22 value: value '%' . value + + NUM shift, and go to state 1 + COL shift, and go to state 2 + FUNC shift, and go to state 14 + INDEF shift, and go to state 5 + '-' shift, and go to state 6 + '!' shift, and go to state 7 + '~' shift, and go to state 8 + '(' shift, and go to state 15 + + value go to state 56 + + +state 38 + + 18 value: value . '+' value + 19 | value . '-' value + 20 | value . '*' value + 21 | value . '/' value + 22 | value . '%' value + 23 | value . '&' value + 24 | value . '|' value + 25 | value . '^' value + 29 | '(' value . ')' + + '|' shift, and go to state 24 + '^' shift, and go to state 25 + '&' shift, and go to state 26 + '+' shift, and go to state 33 + '-' shift, and go to state 34 + '*' shift, and go to state 35 + '/' shift, and go to state 36 + '%' shift, and go to state 37 + ')' shift, and go to state 40 + + +state 39 + + 5 expr: '(' expr ')' . + + $default reduce using rule 5 (expr) + + +state 40 + + 29 value: '(' value ')' . + + $default reduce using rule 29 (value) + + +state 41 + + 3 expr: expr . OR expr + 3 | expr OR expr . + 4 | expr . AND expr + + AND shift, and go to state 23 + + $default reduce using rule 3 (expr) + + +state 42 + + 3 expr: expr . OR expr + 4 | expr . AND expr + 4 | expr AND expr . + + $default reduce using rule 4 (expr) + + +state 43 + + 18 value: value . '+' value + 19 | value . '-' value + 20 | value . '*' value + 21 | value . '/' value + 22 | value . '%' value + 23 | value . '&' value + 24 | value . '|' value + 24 | value '|' value . + 25 | value . '^' value + + '^' shift, and go to state 25 + '&' shift, and go to state 26 + '+' shift, and go to state 33 + '-' shift, and go to state 34 + '*' shift, and go to state 35 + '/' shift, and go to state 36 + '%' shift, and go to state 37 + + $default reduce using rule 24 (value) + + +state 44 + + 18 value: value . '+' value + 19 | value . '-' value + 20 | value . '*' value + 21 | value . '/' value + 22 | value . '%' value + 23 | value . '&' value + 24 | value . '|' value + 25 | value . '^' value + 25 | value '^' value . + + '&' shift, and go to state 26 + '+' shift, and go to state 33 + '-' shift, and go to state 34 + '*' shift, and go to state 35 + '/' shift, and go to state 36 + '%' shift, and go to state 37 + + $default reduce using rule 25 (value) + + +state 45 + + 18 value: value . '+' value + 19 | value . '-' value + 20 | value . '*' value + 21 | value . '/' value + 22 | value . '%' value + 23 | value . '&' value + 23 | value '&' value . + 24 | value . '|' value + 25 | value . '^' value + + '+' shift, and go to state 33 + '-' shift, and go to state 34 + '*' shift, and go to state 35 + '/' shift, and go to state 36 + '%' shift, and go to state 37 + + $default reduce using rule 23 (value) + + +state 46 + + 9 rowlist: value NE value . + 18 value: value . '+' value + 19 | value . '-' value + 20 | value . '*' value + 21 | value . '/' value + 22 | value . '%' value + 23 | value . '&' value + 24 | value . '|' value + 25 | value . '^' value + + '|' shift, and go to state 24 + '^' shift, and go to state 25 + '&' shift, and go to state 26 + '+' shift, and go to state 33 + '-' shift, and go to state 34 + '*' shift, and go to state 35 + '/' shift, and go to state 36 + '%' shift, and go to state 37 + + $default reduce using rule 9 (rowlist) + + +state 47 + + 8 rowlist: value EQ value . + 18 value: value . '+' value + 19 | value . '-' value + 20 | value . '*' value + 21 | value . '/' value + 22 | value . '%' value + 23 | value . '&' value + 24 | value . '|' value + 25 | value . '^' value + + '|' shift, and go to state 24 + '^' shift, and go to state 25 + '&' shift, and go to state 26 + '+' shift, and go to state 33 + '-' shift, and go to state 34 + '*' shift, and go to state 35 + '/' shift, and go to state 36 + '%' shift, and go to state 37 + + $default reduce using rule 8 (rowlist) + + +state 48 + + 10 rowlist: value '<' value . + 18 value: value . '+' value + 19 | value . '-' value + 20 | value . '*' value + 21 | value . '/' value + 22 | value . '%' value + 23 | value . '&' value + 24 | value . '|' value + 25 | value . '^' value + + '|' shift, and go to state 24 + '^' shift, and go to state 25 + '&' shift, and go to state 26 + '+' shift, and go to state 33 + '-' shift, and go to state 34 + '*' shift, and go to state 35 + '/' shift, and go to state 36 + '%' shift, and go to state 37 + + $default reduce using rule 10 (rowlist) + + +state 49 + + 12 rowlist: value '>' value . + 18 value: value . '+' value + 19 | value . '-' value + 20 | value . '*' value + 21 | value . '/' value + 22 | value . '%' value + 23 | value . '&' value + 24 | value . '|' value + 25 | value . '^' value + + '|' shift, and go to state 24 + '^' shift, and go to state 25 + '&' shift, and go to state 26 + '+' shift, and go to state 33 + '-' shift, and go to state 34 + '*' shift, and go to state 35 + '/' shift, and go to state 36 + '%' shift, and go to state 37 + + $default reduce using rule 12 (rowlist) + + +state 50 + + 13 rowlist: value GE value . + 18 value: value . '+' value + 19 | value . '-' value + 20 | value . '*' value + 21 | value . '/' value + 22 | value . '%' value + 23 | value . '&' value + 24 | value . '|' value + 25 | value . '^' value + + '|' shift, and go to state 24 + '^' shift, and go to state 25 + '&' shift, and go to state 26 + '+' shift, and go to state 33 + '-' shift, and go to state 34 + '*' shift, and go to state 35 + '/' shift, and go to state 36 + '%' shift, and go to state 37 + + $default reduce using rule 13 (rowlist) + + +state 51 + + 11 rowlist: value LE value . + 18 value: value . '+' value + 19 | value . '-' value + 20 | value . '*' value + 21 | value . '/' value + 22 | value . '%' value + 23 | value . '&' value + 24 | value . '|' value + 25 | value . '^' value + + '|' shift, and go to state 24 + '^' shift, and go to state 25 + '&' shift, and go to state 26 + '+' shift, and go to state 33 + '-' shift, and go to state 34 + '*' shift, and go to state 35 + '/' shift, and go to state 36 + '%' shift, and go to state 37 + + $default reduce using rule 11 (rowlist) + + +state 52 + + 18 value: value . '+' value + 18 | value '+' value . + 19 | value . '-' value + 20 | value . '*' value + 21 | value . '/' value + 22 | value . '%' value + 23 | value . '&' value + 24 | value . '|' value + 25 | value . '^' value + + '*' shift, and go to state 35 + '/' shift, and go to state 36 + '%' shift, and go to state 37 + + $default reduce using rule 18 (value) + + +state 53 + + 18 value: value . '+' value + 19 | value . '-' value + 19 | value '-' value . + 20 | value . '*' value + 21 | value . '/' value + 22 | value . '%' value + 23 | value . '&' value + 24 | value . '|' value + 25 | value . '^' value + + '*' shift, and go to state 35 + '/' shift, and go to state 36 + '%' shift, and go to state 37 + + $default reduce using rule 19 (value) + + +state 54 + + 18 value: value . '+' value + 19 | value . '-' value + 20 | value . '*' value + 20 | value '*' value . + 21 | value . '/' value + 22 | value . '%' value + 23 | value . '&' value + 24 | value . '|' value + 25 | value . '^' value + + $default reduce using rule 20 (value) + + +state 55 + + 18 value: value . '+' value + 19 | value . '-' value + 20 | value . '*' value + 21 | value . '/' value + 21 | value '/' value . + 22 | value . '%' value + 23 | value . '&' value + 24 | value . '|' value + 25 | value . '^' value + + $default reduce using rule 21 (value) + + +state 56 + + 18 value: value . '+' value + 19 | value . '-' value + 20 | value . '*' value + 21 | value . '/' value + 22 | value . '%' value + 22 | value '%' value . + 23 | value . '&' value + 24 | value . '|' value + 25 | value . '^' value + + $default reduce using rule 22 (value) diff --git a/filter/idx.tab.c b/filter/idx.tab.c new file mode 100644 index 0000000..d38c8af --- /dev/null +++ b/filter/idx.tab.c @@ -0,0 +1,2177 @@ +/* A Bison parser, made by GNU Bison 2.0. */ + +/* Skeleton parser for GLR parsing with Bison, + Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* This is the parser code for GLR (Generalized LR) parser. */ + +#include +#include +#include +#include +#include + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Skeleton name. */ +#define YYSKELETON_NAME "glr.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Using locations. */ +#define YYLSP_NEEDED 0 + +/* Substitute the variable and function names. */ +#define yyparse idxparse +#define yylex idxlex +#define yyerror idxerror +#define yylval idxlval +#define yychar idxchar +#define yydebug idxdebug +#define yynerrs idxnerrs +#define yylloc idxlloc + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + NUM = 258, + COL = 259, + FUNC = 260, + REG = 261, + INDEF = 262, + OR = 263, + AND = 264, + NE = 265, + EQ = 266, + GE = 267, + LE = 268, + UMINUS = 269 + }; +#endif +#define NUM 258 +#define COL 259 +#define FUNC 260 +#define REG 261 +#define INDEF 262 +#define OR 263 +#define AND 264 +#define NE 265 +#define EQ 266 +#define GE 267 +#define LE 268 +#define UMINUS 269 + + + + +/* Copy the first part of user declarations. */ +#line 1 "idx.y" + +#include +#include + + +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) +#line 6 "idx.y" +typedef union YYSTYPE { + idxrowrec *row; + idxvalrec *val; +} YYSTYPE; +/* Line 186 of glr.c. */ +#line 115 "idx.tab.c" +# define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 +#endif + +#if ! defined (YYLTYPE) && ! defined (YYLTYPE_IS_DECLARED) +typedef struct YYLTYPE +{ + + char yydummy; + +} YYLTYPE; +# define YYLTYPE_IS_DECLARED 1 +# define YYLTYPE_IS_TRIVIAL 1 +#endif + +/* Default (constant) value used for initialization for null + right-hand sides. Unlike the standard yacc.c template, + here we set the default value of $$ to a zeroed-out value. + Since the default value is undefined, this behavior is + technically correct. */ +static YYSTYPE yyval_default; + +/* Copy the second part of user declarations. */ + + +/* Line 217 of glr.c. */ +#line 142 "idx.tab.c" + +#ifndef YYFREE +# define YYFREE free +#endif +#ifndef YYMALLOC +# define YYMALLOC malloc +#endif +#ifndef YYREALLOC +# define YYREALLOC realloc +#endif + +#ifdef __cplusplus + typedef bool yybool; +#else + typedef unsigned char yybool; +#endif +#define yytrue 1 +#define yyfalse 0 + +/*-----------------. +| GCC extensions. | +`-----------------*/ + +#ifndef __attribute__ +/* This feature is available in gcc versions 2.5 and later. */ +# if !defined (__GNUC__) || __GNUC__ < 2 || \ +(__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__ +# define __attribute__(Spec) /* empty */ +# endif +#endif + +#ifndef YYASSERT +# define YYASSERT(condition) ((void) ((condition) || (abort (), 0))) +#endif + +#ifndef ATTRIBUTE_UNUSED +# define ATTRIBUTE_UNUSED __attribute__ ((__unused__)) +#endif + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 21 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 143 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 29 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 5 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 30 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 57 +/* YYMAXRHS -- Maximum number of symbols on right-hand side of rule. */ +#define YYMAXRHS 3 +/* YYMAXLEFT -- Maximum number of symbols to the left of a handle + accessed by $0, $-1, etc., in any rule. */ +#define YYMAXLEFT 0 + +/* YYTRANSLATE(X) -- Bison symbol number corresponding to X. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 269 + +#define YYTRANSLATE(YYX) \ + ((YYX <= 0) ? YYEOF : \ + (unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const unsigned char yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 24, 2, 2, 2, 23, 12, 2, + 27, 28, 21, 19, 2, 20, 2, 22, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 15, 2, 16, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 11, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 10, 2, 25, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 13, 14, 17, 18, 26 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const unsigned char yyprhs[] = +{ + 0, 0, 3, 5, 7, 11, 15, 19, 21, 23, + 27, 31, 35, 39, 43, 47, 49, 51, 53, 55, + 59, 63, 67, 71, 75, 79, 83, 87, 90, 93, + 96 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const signed char yyrhs[] = +{ + 30, 0, -1, 31, -1, 32, -1, 31, 8, 31, + -1, 31, 9, 31, -1, 27, 31, 28, -1, 6, + -1, 5, -1, 33, 14, 33, -1, 33, 13, 33, + -1, 33, 15, 33, -1, 33, 18, 33, -1, 33, + 16, 33, -1, 33, 17, 33, -1, 3, -1, 4, + -1, 7, -1, 5, -1, 33, 19, 33, -1, 33, + 20, 33, -1, 33, 21, 33, -1, 33, 22, 33, + -1, 33, 23, 33, -1, 33, 12, 33, -1, 33, + 10, 33, -1, 33, 11, 33, -1, 24, 33, -1, + 25, 33, -1, 20, 33, -1, 27, 33, 28, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const unsigned char yyrline[] = +{ + 0, 39, 39, 42, 43, 44, 45, 49, 50, 51, + 52, 53, 54, 55, 56, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, + 74 +}; +#endif + +#if (YYDEBUG) || YYERROR_VERBOSE +/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "NUM", "COL", "FUNC", "REG", "INDEF", + "OR", "AND", "'|'", "'^'", "'&'", "NE", "EQ", "'<'", "'>'", "GE", "LE", + "'+'", "'-'", "'*'", "'/'", "'%'", "'!'", "'~'", "UMINUS", "'('", "')'", + "$accept", "idx", "expr", "rowlist", "value", 0 +}; +#endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const unsigned char yyr1[] = +{ + 0, 29, 30, 31, 31, 31, 31, 32, 32, 32, + 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const unsigned char yyr2[] = +{ + 0, 2, 1, 1, 3, 3, 3, 1, 1, 3, + 3, 3, 3, 3, 3, 1, 1, 1, 1, 3, + 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, + 3 +}; + +/* YYDPREC[RULE-NUM] -- Dynamic precedence of rule #RULE-NUM (0 if none). */ +static const unsigned char yydprec[] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0 +}; + +/* YYMERGER[RULE-NUM] -- Index of merging function for rule #RULE-NUM. */ +static const unsigned char yymerger[] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0 +}; + +/* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE + doesn't specify something else to do. Zero means the default is an + error. */ +static const unsigned char yydefact[] = +{ + 0, 15, 16, 18, 7, 17, 0, 0, 0, 0, + 0, 2, 3, 0, 18, 0, 29, 27, 28, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, + 30, 4, 5, 25, 26, 24, 10, 9, 11, 13, + 14, 12, 19, 20, 21, 22, 23 +}; + +/* YYPDEFGOTO[NTERM-NUM]. */ +static const signed char yydefgoto[] = +{ + -1, 10, 11, 12, 13 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -17 +static const signed char yypact[] = +{ + 30, -17, -17, 4, -17, -17, 36, 36, 36, 30, + 8, 2, -17, 89, -17, 36, -17, -17, -17, 37, + 56, -17, 30, 30, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 70, -17, + -17, 5, -17, 108, 120, 114, 103, 103, 103, 103, + 103, 103, -16, -16, -17, -17, -17 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const signed char yypgoto[] = +{ + -17, -17, 29, -17, -6 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If zero, do what YYDEFACT says. + If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -9 +static const signed char yytable[] = +{ + 16, 17, 18, 20, -8, 35, 36, 37, 21, 38, + 22, 23, -8, -8, 23, 0, 0, 0, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, -8, 1, 2, 3, 4, 5, 19, 1, + 2, 14, 0, 5, 0, 22, 23, 0, 0, 0, + 6, 41, 42, 0, 7, 8, 6, 9, 0, 0, + 7, 8, 0, 15, 0, 39, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 24, 25, 26, 0, 40, 0, 0, 0, 0, 33, + 34, 35, 36, 37, 0, 0, 0, 0, 40, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 24, 25, 26, 0, 0, 0, 25, + 26, 0, 33, 34, 35, 36, 37, 33, 34, 35, + 36, 37, 26, 33, 34, 35, 36, 37, 0, 33, + 34, 35, 36, 37 +}; + +/* YYCONFLP[YYPACT[STATE-NUM]] -- Pointer into YYCONFL of start of + list of conflicting reductions corresponding to action entry for + state STATE-NUM in yytable. 0 means no conflicts. The list in + yyconfl is terminated by a rule number of 0. */ +static const unsigned char yyconflp[] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0 +}; + +/* YYCONFL[I] -- lists of conflicting rule numbers, each terminated by + 0, pointed into by YYCONFLP. */ +static const short int yyconfl[] = +{ + 0, 18, 0 +}; + +static const signed char yycheck[] = +{ + 6, 7, 8, 9, 0, 21, 22, 23, 0, 15, + 8, 9, 8, 9, 9, -1, -1, -1, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 28, 3, 4, 5, 6, 7, 9, 3, + 4, 5, -1, 7, -1, 8, 9, -1, -1, -1, + 20, 22, 23, -1, 24, 25, 20, 27, -1, -1, + 24, 25, -1, 27, -1, 28, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 10, 11, 12, -1, 28, -1, -1, -1, -1, 19, + 20, 21, 22, 23, -1, -1, -1, -1, 28, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 10, 11, 12, -1, -1, -1, 11, + 12, -1, 19, 20, 21, 22, 23, 19, 20, 21, + 22, 23, 12, 19, 20, 21, 22, 23, -1, 19, + 20, 21, 22, 23 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const unsigned char yystos[] = +{ + 0, 3, 4, 5, 6, 7, 20, 24, 25, 27, + 30, 31, 32, 33, 5, 27, 33, 33, 33, 31, + 33, 0, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 33, 28, + 28, 31, 31, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33 +}; + + +/* Prevent warning if -Wmissing-prototypes. */ +int yyparse (void); + +/* Error token number */ +#define YYTERROR 1 + +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + + +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) ((void) 0) +#endif + + +#ifndef YY_LOCATION_PRINT +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +#endif + + +/* YYLEX -- calling `yylex' with the right arguments. */ +#define YYLEX yylex () + +YYSTYPE yylval; + +YYLTYPE yylloc; + +int yynerrs; +int yychar; + +static const int YYEOF = 0; +static const int YYEMPTY = -2; + +typedef enum { yyok, yyaccept, yyabort, yyerr } YYRESULTTAG; + +#define YYCHK(YYE) \ + do { YYRESULTTAG yyflag = YYE; if (yyflag != yyok) return yyflag; } \ + while (0) + +#if YYDEBUG + +#if ! defined (YYFPRINTF) +# define YYFPRINTF fprintf +#endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +static void +yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) +{ + /* Pacify ``unused variable'' warnings. */ + (void) yyvaluep; + + if (yytype < YYNTOKENS) + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# endif + switch (yytype) + { + default: + break; + } + YYFPRINTF (yyoutput, ")"); +} + + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yysymprint (stderr, \ + Type, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; + +#else /* !YYDEBUG */ + +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) + +#endif /* !YYDEBUG */ + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + SIZE_MAX < YYMAXDEPTH * sizeof (GLRStackItem) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + +/* Minimum number of free items on the stack allowed after an + allocation. This is to allow allocation and initialization + to be completed by functions that call expandGLRStack before the + stack is expanded, thus insuring that all necessary pointers get + properly redirected to new data. */ +#define YYHEADROOM 2 + +#if (! defined (YYSTACKEXPANDABLE) \ + && (! defined (__cplusplus) \ + || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL))) +#define YYSTACKEXPANDABLE 1 +#else +#define YYSTACKEXPANDABLE 0 +#endif + +/** State numbers, as in LALR(1) machine */ +typedef int yyStateNum; + +/** Rule numbers, as in LALR(1) machine */ +typedef int yyRuleNum; + +/** Grammar symbol */ +typedef short int yySymbol; + +/** Item references, as in LALR(1) machine */ +typedef short int yyItemNum; + +typedef struct yyGLRState yyGLRState; +typedef struct yySemanticOption yySemanticOption; +typedef union yyGLRStackItem yyGLRStackItem; +typedef struct yyGLRStack yyGLRStack; +typedef struct yyGLRStateSet yyGLRStateSet; + +struct yyGLRState { + yybool yyisState; + yybool yyresolved; + yyStateNum yylrState; + yyGLRState* yypred; + size_t yyposn; + union { + yySemanticOption* yyfirstVal; + YYSTYPE yysval; + } yysemantics; + YYLTYPE yyloc; +}; + +struct yyGLRStateSet { + yyGLRState** yystates; + size_t yysize, yycapacity; +}; + +struct yySemanticOption { + yybool yyisState; + yyRuleNum yyrule; + yyGLRState* yystate; + yySemanticOption* yynext; +}; + +union yyGLRStackItem { + yyGLRState yystate; + yySemanticOption yyoption; +}; + +struct yyGLRStack { + int yyerrflag; + int yyerrState; + + + yySymbol* yytokenp; + jmp_buf yyexception_buffer; + yyGLRStackItem* yyitems; + yyGLRStackItem* yynextFree; + int yyspaceLeft; + yyGLRState* yysplitPoint; + yyGLRState* yylastDeleted; + yyGLRStateSet yytops; +}; + +static void yyinitGLRStack (yyGLRStack* yystack, size_t yysize); +static void yyexpandGLRStack (yyGLRStack* yystack); +static void yyfreeGLRStack (yyGLRStack* yystack); + +static void +yyFail (yyGLRStack* yystack, const char* yyformat, ...) +{ + yystack->yyerrflag = 1; + if (yyformat != NULL) + { + char yymsg[256]; + va_list yyap; + va_start (yyap, yyformat); + vsprintf (yymsg, yyformat, yyap); + yyerror (yymsg); + } + longjmp (yystack->yyexception_buffer, 1); +} + +#if YYDEBUG || YYERROR_VERBOSE +/** A printable representation of TOKEN. Valid until next call to + * tokenName. */ +static inline const char* +yytokenName (yySymbol yytoken) +{ + if (yytoken == YYEMPTY) + return ""; + + return yytname[yytoken]; +} +#endif + +/** Fill in YYVSP[YYLOW1 .. YYLOW0-1] from the chain of states starting + * at YYVSP[YYLOW0].yystate.yypred. Leaves YYVSP[YYLOW1].yystate.yypred + * containing the pointer to the next state in the chain. Assumes + * YYLOW1 < YYLOW0. */ +static void yyfillin (yyGLRStackItem *, int, int) ATTRIBUTE_UNUSED; +static void +yyfillin (yyGLRStackItem *yyvsp, int yylow0, int yylow1) +{ + yyGLRState* s; + int i; + s = yyvsp[yylow0].yystate.yypred; + for (i = yylow0-1; i >= yylow1; i -= 1) + { + YYASSERT (s->yyresolved); + yyvsp[i].yystate.yyresolved = yytrue; + yyvsp[i].yystate.yysemantics.yysval = s->yysemantics.yysval; + yyvsp[i].yystate.yyloc = s->yyloc; + s = yyvsp[i].yystate.yypred = s->yypred; + } +} + +/* Do nothing if YYNORMAL or if *YYLOW <= YYLOW1. Otherwise, fill in + YYVSP[YYLOW1 .. *YYLOW-1] as in yyfillin and set *YYLOW = YYLOW1. + For convenience, always return YYLOW1. */ +static inline int yyfill (yyGLRStackItem *, int *, int, yybool) + ATTRIBUTE_UNUSED; +static inline int +yyfill (yyGLRStackItem *yyvsp, int *yylow, int yylow1, yybool yynormal) +{ + if (!yynormal && yylow1 < *yylow) + { + yyfillin (yyvsp, *yylow, yylow1); + *yylow = yylow1; + } + return yylow1; +} + +/** Perform user action for rule number YYN, with RHS length YYRHSLEN, + * and top stack item YYVSP. YYLVALP points to place to put semantic + * value ($$), and yylocp points to place for location information + * (@$). Returns yyok for normal return, yyaccept for YYACCEPT, + * yyerr for YYERROR, yyabort for YYABORT. */ +static YYRESULTTAG +yyuserAction (yyRuleNum yyn, int yyrhslen, yyGLRStackItem* yyvsp, + YYSTYPE* yyvalp, + YYLTYPE* yylocp ATTRIBUTE_UNUSED, + yyGLRStack* yystack + ) +{ + yybool yynormal ATTRIBUTE_UNUSED = (yystack->yysplitPoint == NULL); + int yylow; + +# undef yyerrok +# define yyerrok (yystack->yyerrState = 0) +# undef YYACCEPT +# define YYACCEPT return yyaccept +# undef YYABORT +# define YYABORT return yyabort +# undef YYERROR +# define YYERROR return yyerrok, yyerr +# undef YYRECOVERING +# define YYRECOVERING (yystack->yyerrState != 0) +# undef yyclearin +# define yyclearin (yychar = *(yystack->yytokenp) = YYEMPTY) +# undef YYFILL +# define YYFILL(N) yyfill (yyvsp, &yylow, N, yynormal) +# undef YYBACKUP +# define YYBACKUP(Token, Value) \ + return yyerror ("syntax error: cannot back up"), \ + yyerrok, yyerr + + yylow = 1; + if (yyrhslen == 0) + *yyvalp = yyval_default; + else + *yyvalp = yyvsp[YYFILL (1-yyrhslen)].yystate.yysemantics.yysval; + YYLLOC_DEFAULT (*yylocp, yyvsp - yyrhslen, yyrhslen); + + switch (yyn) + { + case 2: +#line 39 "idx.y" + { idxall((((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.row)); ;} + break; + + case 4: +#line 43 "idx.y" + { ((*yyvalp).row) = idxor((((yyGLRStackItem const *)yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.row),(((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.row)); ;} + break; + + case 5: +#line 44 "idx.y" + { ((*yyvalp).row) = idxand((((yyGLRStackItem const *)yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.row),(((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.row)); ;} + break; + + case 6: +#line 45 "idx.y" + { ((*yyvalp).row) = (((yyGLRStackItem const *)yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.row); ;} + break; + + case 7: +#line 49 "idx.y" + { ((*yyvalp).row) = idxrowreg((((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.val)); ;} + break; + + case 8: +#line 50 "idx.y" + { ((*yyvalp).row) = idxrowfun((((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.val)); ;} + break; + + case 9: +#line 51 "idx.y" + { ((*yyvalp).row) = idxroweq((((yyGLRStackItem const *)yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.val),(((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.val)); ;} + break; + + case 10: +#line 52 "idx.y" + { ((*yyvalp).row) = idxrowne((((yyGLRStackItem const *)yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.val),(((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.val)); ;} + break; + + case 11: +#line 53 "idx.y" + { ((*yyvalp).row) = idxrowlt((((yyGLRStackItem const *)yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.val),(((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.val)); ;} + break; + + case 12: +#line 54 "idx.y" + { ((*yyvalp).row) = idxrowle((((yyGLRStackItem const *)yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.val),(((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.val)); ;} + break; + + case 13: +#line 55 "idx.y" + { ((*yyvalp).row) = idxrowgt((((yyGLRStackItem const *)yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.val),(((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.val)); ;} + break; + + case 14: +#line 56 "idx.y" + { ((*yyvalp).row) = idxrowge((((yyGLRStackItem const *)yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.val),(((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.val)); ;} + break; + + case 19: +#line 63 "idx.y" + { ((*yyvalp).val) = idxvaladd((((yyGLRStackItem const *)yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.val),(((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.val)); ;} + break; + + case 20: +#line 64 "idx.y" + { ((*yyvalp).val) = idxvalsub((((yyGLRStackItem const *)yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.val),(((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.val)); ;} + break; + + case 21: +#line 65 "idx.y" + { ((*yyvalp).val) = idxvalmul((((yyGLRStackItem const *)yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.val),(((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.val)); ;} + break; + + case 22: +#line 66 "idx.y" + { ((*yyvalp).val) = idxvaldiv((((yyGLRStackItem const *)yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.val),(((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.val)); ;} + break; + + case 23: +#line 67 "idx.y" + { ((*yyvalp).val) = idxvalmod((((yyGLRStackItem const *)yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.val),(((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.val)); ;} + break; + + case 24: +#line 68 "idx.y" + { ((*yyvalp).val) = idxvaland((((yyGLRStackItem const *)yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.val),(((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.val)); ;} + break; + + case 25: +#line 69 "idx.y" + { ((*yyvalp).val) = idxvalor((((yyGLRStackItem const *)yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.val),(((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.val)); ;} + break; + + case 26: +#line 70 "idx.y" + { ((*yyvalp).val) = idxvalxor((((yyGLRStackItem const *)yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.val),(((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.val)); ;} + break; + + case 27: +#line 71 "idx.y" + { ((*yyvalp).val) = idxvalnot((((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.val)); ;} + break; + + case 28: +#line 72 "idx.y" + { ((*yyvalp).val) = idxvalcom((((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.val)); ;} + break; + + case 29: +#line 73 "idx.y" + { ((*yyvalp).val) = idxvalmin((((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.val)); ;} + break; + + case 30: +#line 74 "idx.y" + { ((*yyvalp).val) = (((yyGLRStackItem const *)yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.val); ;} + break; + + + } + + return yyok; +# undef yyerrok +# undef YYABORT +# undef YYACCEPT +# undef YYERROR +# undef YYBACKUP +# undef yyclearin +# undef YYRECOVERING +/* Line 750 of glr.c. */ +#line 890 "idx.tab.c" +} + + +static void +yyuserMerge (int yyn, YYSTYPE* yy0, YYSTYPE* yy1) +{ + /* `Use' the arguments. */ + (void) yy0; + (void) yy1; + + switch (yyn) + { + + } +} + + /* Bison grammar-table manipulation. */ + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +{ + /* Pacify ``unused variable'' warnings. */ + (void) yyvaluep; + + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + switch (yytype) + { + + default: + break; + } +} + +/** Number of symbols composing the right hand side of rule #RULE. */ +static inline int +yyrhsLength (yyRuleNum yyrule) +{ + return yyr2[yyrule]; +} + +/** Left-hand-side symbol for rule #RULE. */ +static inline yySymbol +yylhsNonterm (yyRuleNum yyrule) +{ + return yyr1[yyrule]; +} + +#define yyis_pact_ninf(yystate) \ + ((yystate) == YYPACT_NINF) + +/** True iff LR state STATE has only a default reduction (regardless + * of token). */ +static inline yybool +yyisDefaultedState (yyStateNum yystate) +{ + return yyis_pact_ninf (yypact[yystate]); +} + +/** The default reduction for STATE, assuming it has one. */ +static inline yyRuleNum +yydefaultAction (yyStateNum yystate) +{ + return yydefact[yystate]; +} + +#define yyis_table_ninf(yytable_value) \ + 0 + +/** Set *YYACTION to the action to take in YYSTATE on seeing YYTOKEN. + * Result R means + * R < 0: Reduce on rule -R. + * R = 0: Error. + * R > 0: Shift to state R. + * Set *CONFLICTS to a pointer into yyconfl to 0-terminated list of + * conflicting reductions. + */ +static inline void +yygetLRActions (yyStateNum yystate, int yytoken, + int* yyaction, const short int** yyconflicts) +{ + int yyindex = yypact[yystate] + yytoken; + if (yyindex < 0 || YYLAST < yyindex || yycheck[yyindex] != yytoken) + { + *yyaction = -yydefact[yystate]; + *yyconflicts = yyconfl; + } + else if (! yyis_table_ninf (yytable[yyindex])) + { + *yyaction = yytable[yyindex]; + *yyconflicts = yyconfl + yyconflp[yyindex]; + } + else + { + *yyaction = 0; + *yyconflicts = yyconfl + yyconflp[yyindex]; + } +} + +static inline yyStateNum +yyLRgotoState (yyStateNum yystate, yySymbol yylhs) +{ + int yyr; + yyr = yypgoto[yylhs - YYNTOKENS] + yystate; + if (0 <= yyr && yyr <= YYLAST && yycheck[yyr] == yystate) + return yytable[yyr]; + else + return yydefgoto[yylhs - YYNTOKENS]; +} + +static inline yybool +yyisShiftAction (int yyaction) +{ + return 0 < yyaction; +} + +static inline yybool +yyisErrorAction (int yyaction) +{ + return yyaction == 0; +} + + /* GLRStates */ + +static void +yyaddDeferredAction (yyGLRStack* yystack, yyGLRState* yystate, + yyGLRState* rhs, yyRuleNum yyrule) +{ + yySemanticOption* yynewItem; + yynewItem = &yystack->yynextFree->yyoption; + yystack->yyspaceLeft -= 1; + yystack->yynextFree += 1; + yynewItem->yyisState = yyfalse; + yynewItem->yystate = rhs; + yynewItem->yyrule = yyrule; + yynewItem->yynext = yystate->yysemantics.yyfirstVal; + yystate->yysemantics.yyfirstVal = yynewItem; + if (yystack->yyspaceLeft < YYHEADROOM) + yyexpandGLRStack (yystack); +} + + /* GLRStacks */ + +/** Initialize SET to a singleton set containing an empty stack. */ +static void +yyinitStateSet (yyGLRStateSet* yyset) +{ + yyset->yysize = 1; + yyset->yycapacity = 16; + yyset->yystates = (yyGLRState**) YYMALLOC (16 * sizeof yyset->yystates[0]); + yyset->yystates[0] = NULL; +} + +static void yyfreeStateSet (yyGLRStateSet* yyset) +{ + YYFREE (yyset->yystates); +} + +/** Initialize STACK to a single empty stack, with total maximum + * capacity for all stacks of SIZE. */ +static void +yyinitGLRStack (yyGLRStack* yystack, size_t yysize) +{ + yystack->yyerrflag = 0; + yystack->yyerrState = 0; + yynerrs = 0; + yystack->yyspaceLeft = yysize; + yystack->yynextFree = yystack->yyitems = + (yyGLRStackItem*) YYMALLOC (yysize * sizeof yystack->yynextFree[0]); + yystack->yysplitPoint = NULL; + yystack->yylastDeleted = NULL; + yyinitStateSet (&yystack->yytops); +} + +#define YYRELOC(YYFROMITEMS,YYTOITEMS,YYX,YYTYPE) \ + &((YYTOITEMS) - ((YYFROMITEMS) - (yyGLRStackItem*) (YYX)))->YYTYPE + +/** If STACK is expandable, extend it. WARNING: Pointers into the + stack from outside should be considered invalid after this call. + We always expand when there are 1 or fewer items left AFTER an + allocation, so that we can avoid having external pointers exist + across an allocation. */ +static void +yyexpandGLRStack (yyGLRStack* yystack) +{ +#if YYSTACKEXPANDABLE + yyGLRStack yynewStack; + yyGLRStackItem* yyp0, *yyp1; + size_t yysize, yynewSize; + size_t yyn; + yysize = yystack->yynextFree - yystack->yyitems; + if (YYMAXDEPTH <= yysize) + yyFail (yystack, "parser stack overflow"); + yynewSize = 2*yysize; + if (YYMAXDEPTH < yynewSize) + yynewSize = YYMAXDEPTH; + yyinitGLRStack (&yynewStack, yynewSize); + for (yyp0 = yystack->yyitems, yyp1 = yynewStack.yyitems, yyn = yysize; + 0 < yyn; + yyn -= 1, yyp0 += 1, yyp1 += 1) + { + *yyp1 = *yyp0; + if (*(yybool *) yyp0) + { + yyGLRState* yys0 = &yyp0->yystate; + yyGLRState* yys1 = &yyp1->yystate; + if (yys0->yypred != NULL) + yys1->yypred = + YYRELOC (yyp0, yyp1, yys0->yypred, yystate); + if (! yys0->yyresolved && yys0->yysemantics.yyfirstVal != NULL) + yys1->yysemantics.yyfirstVal = + YYRELOC(yyp0, yyp1, yys0->yysemantics.yyfirstVal, yyoption); + } + else + { + yySemanticOption* yyv0 = &yyp0->yyoption; + yySemanticOption* yyv1 = &yyp1->yyoption; + if (yyv0->yystate != NULL) + yyv1->yystate = YYRELOC (yyp0, yyp1, yyv0->yystate, yystate); + if (yyv0->yynext != NULL) + yyv1->yynext = YYRELOC (yyp0, yyp1, yyv0->yynext, yyoption); + } + } + if (yystack->yysplitPoint != NULL) + yystack->yysplitPoint = YYRELOC (yystack->yyitems, yynewStack.yyitems, + yystack->yysplitPoint, yystate); + + for (yyn = 0; yyn < yystack->yytops.yysize; yyn += 1) + if (yystack->yytops.yystates[yyn] != NULL) + yystack->yytops.yystates[yyn] = + YYRELOC (yystack->yyitems, yynewStack.yyitems, + yystack->yytops.yystates[yyn], yystate); + YYFREE (yystack->yyitems); + yystack->yyitems = yynewStack.yyitems; + yystack->yynextFree = yynewStack.yynextFree + yysize; + yystack->yyspaceLeft = yynewStack.yyspaceLeft - yysize; + +#else + + yyFail (yystack, "parser stack overflow"); +#endif +} + +static void +yyfreeGLRStack (yyGLRStack* yystack) +{ + YYFREE (yystack->yyitems); + yyfreeStateSet (&yystack->yytops); +} + +/** Assuming that S is a GLRState somewhere on STACK, update the + * splitpoint of STACK, if needed, so that it is at least as deep as + * S. */ +static inline void +yyupdateSplit (yyGLRStack* yystack, yyGLRState* yys) +{ + if (yystack->yysplitPoint != NULL && yystack->yysplitPoint > yys) + yystack->yysplitPoint = yys; +} + +/** Invalidate stack #K in STACK. */ +static inline void +yymarkStackDeleted (yyGLRStack* yystack, int yyk) +{ + if (yystack->yytops.yystates[yyk] != NULL) + yystack->yylastDeleted = yystack->yytops.yystates[yyk]; + yystack->yytops.yystates[yyk] = NULL; +} + +/** Undelete the last stack that was marked as deleted. Can only be + done once after a deletion, and only when all other stacks have + been deleted. */ +static void +yyundeleteLastStack (yyGLRStack* yystack) +{ + if (yystack->yylastDeleted == NULL || yystack->yytops.yysize != 0) + return; + yystack->yytops.yystates[0] = yystack->yylastDeleted; + yystack->yytops.yysize = 1; + YYDPRINTF ((stderr, "Restoring last deleted stack as stack #0.\n")); + yystack->yylastDeleted = NULL; +} + +static inline void +yyremoveDeletes (yyGLRStack* yystack) +{ + size_t yyi, yyj; + yyi = yyj = 0; + while (yyj < yystack->yytops.yysize) + { + if (yystack->yytops.yystates[yyi] == NULL) + { + if (yyi == yyj) + { + YYDPRINTF ((stderr, "Removing dead stacks.\n")); + } + yystack->yytops.yysize -= 1; + } + else + { + yystack->yytops.yystates[yyj] = yystack->yytops.yystates[yyi]; + if (yyj != yyi) + { + YYDPRINTF ((stderr, "Rename stack %lu -> %lu.\n", + (unsigned long int) yyi, (unsigned long int) yyj)); + } + yyj += 1; + } + yyi += 1; + } +} + +/** Shift to a new state on stack #K of STACK, corresponding to LR state + * LRSTATE, at input position POSN, with (resolved) semantic value SVAL. */ +static inline void +yyglrShift (yyGLRStack* yystack, int yyk, yyStateNum yylrState, size_t yyposn, + YYSTYPE yysval, YYLTYPE* yylocp) +{ + yyGLRStackItem* yynewItem; + + yynewItem = yystack->yynextFree; + yystack->yynextFree += 1; + yystack->yyspaceLeft -= 1; + yynewItem->yystate.yyisState = yytrue; + yynewItem->yystate.yylrState = yylrState; + yynewItem->yystate.yyposn = yyposn; + yynewItem->yystate.yyresolved = yytrue; + yynewItem->yystate.yypred = yystack->yytops.yystates[yyk]; + yystack->yytops.yystates[yyk] = &yynewItem->yystate; + yynewItem->yystate.yysemantics.yysval = yysval; + yynewItem->yystate.yyloc = *yylocp; + if (yystack->yyspaceLeft < YYHEADROOM) + yyexpandGLRStack (yystack); +} + +/** Shift stack #K of YYSTACK, to a new state corresponding to LR + * state YYLRSTATE, at input position YYPOSN, with the (unresolved) + * semantic value of YYRHS under the action for YYRULE. */ +static inline void +yyglrShiftDefer (yyGLRStack* yystack, int yyk, yyStateNum yylrState, + size_t yyposn, yyGLRState* rhs, yyRuleNum yyrule) +{ + yyGLRStackItem* yynewItem; + + yynewItem = yystack->yynextFree; + yynewItem->yystate.yyisState = yytrue; + yynewItem->yystate.yylrState = yylrState; + yynewItem->yystate.yyposn = yyposn; + yynewItem->yystate.yyresolved = yyfalse; + yynewItem->yystate.yypred = yystack->yytops.yystates[yyk]; + yynewItem->yystate.yysemantics.yyfirstVal = NULL; + yystack->yytops.yystates[yyk] = &yynewItem->yystate; + yystack->yynextFree += 1; + yystack->yyspaceLeft -= 1; + yyaddDeferredAction (yystack, &yynewItem->yystate, rhs, yyrule); +} + +/** Pop the symbols consumed by reduction #RULE from the top of stack + * #K of STACK, and perform the appropriate semantic action on their + * semantic values. Assumes that all ambiguities in semantic values + * have been previously resolved. Set *VALP to the resulting value, + * and *LOCP to the computed location (if any). Return value is as + * for userAction. */ +static inline YYRESULTTAG +yydoAction (yyGLRStack* yystack, int yyk, yyRuleNum yyrule, + YYSTYPE* yyvalp, YYLTYPE* yylocp) +{ + int yynrhs = yyrhsLength (yyrule); + + if (yystack->yysplitPoint == NULL) + { + /* Standard special case: single stack. */ + yyGLRStackItem* rhs = (yyGLRStackItem*) yystack->yytops.yystates[yyk]; + YYASSERT (yyk == 0); + yystack->yynextFree -= yynrhs; + yystack->yyspaceLeft += yynrhs; + yystack->yytops.yystates[0] = & yystack->yynextFree[-1].yystate; + return yyuserAction (yyrule, yynrhs, rhs, + yyvalp, yylocp, yystack); + } + else + { + int yyi; + yyGLRState* yys; + yyGLRStackItem yyrhsVals[YYMAXRHS + YYMAXLEFT + 1]; + yys = yyrhsVals[YYMAXRHS + YYMAXLEFT].yystate.yypred + = yystack->yytops.yystates[yyk]; + for (yyi = 0; yyi < yynrhs; yyi += 1) + { + yys = yys->yypred; + YYASSERT (yys); + } + yyupdateSplit (yystack, yys); + yystack->yytops.yystates[yyk] = yys; + return yyuserAction (yyrule, yynrhs, yyrhsVals + YYMAXRHS + YYMAXLEFT - 1, + yyvalp, yylocp, yystack); + } +} + +#if !YYDEBUG +# define YY_REDUCE_PRINT(K, Rule) +#else +# define YY_REDUCE_PRINT(K, Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (K, Rule); \ +} while (0) + +/*----------------------------------------------------------. +| Report that the RULE is going to be reduced on stack #K. | +`----------------------------------------------------------*/ + +static inline void +yy_reduce_print (size_t yyk, yyRuleNum yyrule) +{ + int yyi; + YYFPRINTF (stderr, "Reducing stack %lu by rule %d (line %lu), ", + (unsigned long int) yyk, yyrule - 1, + (unsigned long int) yyrline[yyrule]); + /* Print the symbols being reduced, and their result. */ + for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) + YYFPRINTF (stderr, "%s ", yytokenName (yyrhs[yyi])); + YYFPRINTF (stderr, "-> %s\n", yytokenName (yyr1[yyrule])); +} +#endif + +/** Pop items off stack #K of STACK according to grammar rule RULE, + * and push back on the resulting nonterminal symbol. Perform the + * semantic action associated with RULE and store its value with the + * newly pushed state, if FORCEEVAL or if STACK is currently + * unambiguous. Otherwise, store the deferred semantic action with + * the new state. If the new state would have an identical input + * position, LR state, and predecessor to an existing state on the stack, + * it is identified with that existing state, eliminating stack #K from + * the STACK. In this case, the (necessarily deferred) semantic value is + * added to the options for the existing state's semantic value. + */ +static inline YYRESULTTAG +yyglrReduce (yyGLRStack* yystack, size_t yyk, yyRuleNum yyrule, + yybool yyforceEval) +{ + size_t yyposn = yystack->yytops.yystates[yyk]->yyposn; + + if (yyforceEval || yystack->yysplitPoint == NULL) + { + YYSTYPE yysval; + YYLTYPE yyloc; + + YY_REDUCE_PRINT (yyk, yyrule); + YYCHK (yydoAction (yystack, yyk, yyrule, &yysval, &yyloc)); + yyglrShift (yystack, yyk, + yyLRgotoState (yystack->yytops.yystates[yyk]->yylrState, + yylhsNonterm (yyrule)), + yyposn, yysval, &yyloc); + } + else + { + size_t yyi; + int yyn; + yyGLRState* yys, *yys0 = yystack->yytops.yystates[yyk]; + yyStateNum yynewLRState; + + for (yys = yystack->yytops.yystates[yyk], yyn = yyrhsLength (yyrule); + 0 < yyn; yyn -= 1) + { + yys = yys->yypred; + YYASSERT (yys); + } + yyupdateSplit (yystack, yys); + yynewLRState = yyLRgotoState (yys->yylrState, yylhsNonterm (yyrule)); + YYDPRINTF ((stderr, + "Reduced stack %lu by rule #%d; action deferred. Now in state %d.\n", + (unsigned long int) yyk, yyrule - 1, yynewLRState)); + for (yyi = 0; yyi < yystack->yytops.yysize; yyi += 1) + if (yyi != yyk && yystack->yytops.yystates[yyi] != NULL) + { + yyGLRState* yyp, *yysplit = yystack->yysplitPoint; + yyp = yystack->yytops.yystates[yyi]; + while (yyp != yys && yyp != yysplit && yyp->yyposn >= yyposn) + { + if (yyp->yylrState == yynewLRState && yyp->yypred == yys) + { + yyaddDeferredAction (yystack, yyp, yys0, yyrule); + yymarkStackDeleted (yystack, yyk); + YYDPRINTF ((stderr, "Merging stack %lu into stack %lu.\n", + (unsigned long int) yyk, + (unsigned long int) yyi)); + return yyok; + } + yyp = yyp->yypred; + } + } + yystack->yytops.yystates[yyk] = yys; + yyglrShiftDefer (yystack, yyk, yynewLRState, yyposn, yys0, yyrule); + } + return yyok; +} + +static int +yysplitStack (yyGLRStack* yystack, int yyk) +{ + if (yystack->yysplitPoint == NULL) + { + YYASSERT (yyk == 0); + yystack->yysplitPoint = yystack->yytops.yystates[yyk]; + } + if (yystack->yytops.yysize >= yystack->yytops.yycapacity) + { + yystack->yytops.yycapacity *= 2; + yystack->yytops.yystates = + (yyGLRState**) YYREALLOC (yystack->yytops.yystates, + (yystack->yytops.yycapacity + * sizeof yystack->yytops.yystates[0])); + } + yystack->yytops.yystates[yystack->yytops.yysize] + = yystack->yytops.yystates[yyk]; + yystack->yytops.yysize += 1; + return yystack->yytops.yysize-1; +} + +/** True iff Y0 and Y1 represent identical options at the top level. + * That is, they represent the same rule applied to RHS symbols + * that produce the same terminal symbols. */ +static yybool +yyidenticalOptions (yySemanticOption* yyy0, yySemanticOption* yyy1) +{ + if (yyy0->yyrule == yyy1->yyrule) + { + yyGLRState *yys0, *yys1; + int yyn; + for (yys0 = yyy0->yystate, yys1 = yyy1->yystate, + yyn = yyrhsLength (yyy0->yyrule); + yyn > 0; + yys0 = yys0->yypred, yys1 = yys1->yypred, yyn -= 1) + if (yys0->yyposn != yys1->yyposn) + return yyfalse; + return yytrue; + } + else + return yyfalse; +} + +/** Assuming identicalOptions (Y0,Y1), (destructively) merge the + * alternative semantic values for the RHS-symbols of Y1 into the + * corresponding semantic value sets of the symbols of Y0. */ +static void +yymergeOptionSets (yySemanticOption* yyy0, yySemanticOption* yyy1) +{ + yyGLRState *yys0, *yys1; + int yyn; + for (yys0 = yyy0->yystate, yys1 = yyy1->yystate, + yyn = yyrhsLength (yyy0->yyrule); + yyn > 0; + yys0 = yys0->yypred, yys1 = yys1->yypred, yyn -= 1) + if (yys0 == yys1) + break; + else if (! yys0->yyresolved && ! yys1->yyresolved) + { + yySemanticOption* yyz; + for (yyz = yys0->yysemantics.yyfirstVal; yyz->yynext != NULL; + yyz = yyz->yynext) + continue; + yyz->yynext = yys1->yysemantics.yyfirstVal; + } +} + +/** Y0 and Y1 represent two possible actions to take in a given + * parsing state; return 0 if no combination is possible, + * 1 if user-mergeable, 2 if Y0 is preferred, 3 if Y1 is preferred. */ +static int +yypreference (yySemanticOption* y0, yySemanticOption* y1) +{ + yyRuleNum r0 = y0->yyrule, r1 = y1->yyrule; + int p0 = yydprec[r0], p1 = yydprec[r1]; + + if (p0 == p1) + { + if (yymerger[r0] == 0 || yymerger[r0] != yymerger[r1]) + return 0; + else + return 1; + } + if (p0 == 0 || p1 == 0) + return 0; + if (p0 < p1) + return 3; + if (p1 < p0) + return 2; + return 0; +} + +static YYRESULTTAG yyresolveValue (yySemanticOption* yyoptionList, + yyGLRStack* yystack, YYSTYPE* yyvalp, + YYLTYPE* yylocp); + +static YYRESULTTAG +yyresolveStates (yyGLRState* yys, int yyn, yyGLRStack* yystack) +{ + YYRESULTTAG yyflag; + if (0 < yyn) + { + YYASSERT (yys->yypred); + yyflag = yyresolveStates (yys->yypred, yyn-1, yystack); + if (yyflag != yyok) + return yyflag; + if (! yys->yyresolved) + { + yyflag = yyresolveValue (yys->yysemantics.yyfirstVal, yystack, + &yys->yysemantics.yysval, &yys->yyloc + ); + if (yyflag != yyok) + return yyflag; + yys->yyresolved = yytrue; + } + } + return yyok; +} + +static YYRESULTTAG +yyresolveAction (yySemanticOption* yyopt, yyGLRStack* yystack, + YYSTYPE* yyvalp, YYLTYPE* yylocp) +{ + yyGLRStackItem yyrhsVals[YYMAXRHS + YYMAXLEFT + 1]; + int yynrhs; + + yynrhs = yyrhsLength (yyopt->yyrule); + YYCHK (yyresolveStates (yyopt->yystate, yynrhs, yystack)); + yyrhsVals[YYMAXRHS + YYMAXLEFT].yystate.yypred = yyopt->yystate; + return yyuserAction (yyopt->yyrule, yynrhs, + yyrhsVals + YYMAXRHS + YYMAXLEFT - 1, + yyvalp, yylocp, yystack); +} + +#if YYDEBUG +static void +yyreportTree (yySemanticOption* yyx, int yyindent) +{ + int yynrhs = yyrhsLength (yyx->yyrule); + int yyi; + yyGLRState* yys; + yyGLRState* yystates[YYMAXRHS]; + yyGLRState yyleftmost_state; + + for (yyi = yynrhs, yys = yyx->yystate; 0 < yyi; yyi -= 1, yys = yys->yypred) + yystates[yyi] = yys; + if (yys == NULL) + { + yyleftmost_state.yyposn = 0; + yystates[0] = &yyleftmost_state; + } + else + yystates[0] = yys; + + if (yyx->yystate->yyposn < yys->yyposn + 1) + YYFPRINTF (stderr, "%*s%s -> \n", + yyindent, "", yytokenName (yylhsNonterm (yyx->yyrule)), + yyx->yyrule); + else + YYFPRINTF (stderr, "%*s%s -> \n", + yyindent, "", yytokenName (yylhsNonterm (yyx->yyrule)), + yyx->yyrule, (unsigned long int) (yys->yyposn + 1), + (unsigned long int) yyx->yystate->yyposn); + for (yyi = 1; yyi <= yynrhs; yyi += 1) + { + if (yystates[yyi]->yyresolved) + { + if (yystates[yyi-1]->yyposn+1 > yystates[yyi]->yyposn) + YYFPRINTF (stderr, "%*s%s \n", yyindent+2, "", + yytokenName (yyrhs[yyprhs[yyx->yyrule]+yyi-1])); + else + YYFPRINTF (stderr, "%*s%s \n", yyindent+2, "", + yytokenName (yyrhs[yyprhs[yyx->yyrule]+yyi-1]), + (unsigned long int) (yystates[yyi - 1]->yyposn + 1), + (unsigned long int) yystates[yyi]->yyposn); + } + else + yyreportTree (yystates[yyi]->yysemantics.yyfirstVal, yyindent+2); + } +} +#endif + +static void +yyreportAmbiguity (yySemanticOption* yyx0, yySemanticOption* yyx1, + yyGLRStack* yystack) +{ + /* `Unused' warnings. */ + (void) yyx0; + (void) yyx1; + +#if YYDEBUG + YYFPRINTF (stderr, "Ambiguity detected.\n"); + YYFPRINTF (stderr, "Option 1,\n"); + yyreportTree (yyx0, 2); + YYFPRINTF (stderr, "\nOption 2,\n"); + yyreportTree (yyx1, 2); + YYFPRINTF (stderr, "\n"); +#endif + yyFail (yystack, "ambiguity detected"); +} + + +/** Resolve the ambiguity represented by OPTIONLIST, perform the indicated + * actions, and return the result. */ +static YYRESULTTAG +yyresolveValue (yySemanticOption* yyoptionList, yyGLRStack* yystack, + YYSTYPE* yyvalp, YYLTYPE* yylocp) +{ + yySemanticOption* yybest; + yySemanticOption* yyp; + int yymerge; + + yybest = yyoptionList; + yymerge = 0; + for (yyp = yyoptionList->yynext; yyp != NULL; yyp = yyp->yynext) + { + if (yyidenticalOptions (yybest, yyp)) + yymergeOptionSets (yybest, yyp); + else + switch (yypreference (yybest, yyp)) + { + case 0: + yyreportAmbiguity (yybest, yyp, yystack); + break; + case 1: + yymerge = 1; + break; + case 2: + break; + case 3: + yybest = yyp; + yymerge = 0; + break; + } + } + + if (yymerge) + { + int yyprec = yydprec[yybest->yyrule]; + YYCHK (yyresolveAction (yybest, yystack, yyvalp, yylocp)); + for (yyp = yybest->yynext; yyp != NULL; yyp = yyp->yynext) + { + if (yyprec == yydprec[yyp->yyrule]) + { + YYSTYPE yyval1; + YYLTYPE yydummy; + YYCHK (yyresolveAction (yyp, yystack, &yyval1, &yydummy)); + yyuserMerge (yymerger[yyp->yyrule], yyvalp, &yyval1); + } + } + return yyok; + } + else + return yyresolveAction (yybest, yystack, yyvalp, yylocp); +} + +static YYRESULTTAG +yyresolveStack (yyGLRStack* yystack) +{ + if (yystack->yysplitPoint != NULL) + { + yyGLRState* yys; + int yyn; + + for (yyn = 0, yys = yystack->yytops.yystates[0]; + yys != yystack->yysplitPoint; + yys = yys->yypred, yyn += 1) + continue; + YYCHK (yyresolveStates (yystack->yytops.yystates[0], yyn, yystack + )); + } + return yyok; +} + +static void +yycompressStack (yyGLRStack* yystack) +{ + yyGLRState* yyp, *yyq, *yyr; + + if (yystack->yytops.yysize != 1 || yystack->yysplitPoint == NULL) + return; + + for (yyp = yystack->yytops.yystates[0], yyq = yyp->yypred, yyr = NULL; + yyp != yystack->yysplitPoint; + yyr = yyp, yyp = yyq, yyq = yyp->yypred) + yyp->yypred = yyr; + + yystack->yyspaceLeft += yystack->yynextFree - yystack->yyitems; + yystack->yynextFree = ((yyGLRStackItem*) yystack->yysplitPoint) + 1; + yystack->yyspaceLeft -= yystack->yynextFree - yystack->yyitems; + yystack->yysplitPoint = NULL; + yystack->yylastDeleted = NULL; + + while (yyr != NULL) + { + yystack->yynextFree->yystate = *yyr; + yyr = yyr->yypred; + yystack->yynextFree->yystate.yypred = & yystack->yynextFree[-1].yystate; + yystack->yytops.yystates[0] = &yystack->yynextFree->yystate; + yystack->yynextFree += 1; + yystack->yyspaceLeft -= 1; + } +} + +static YYRESULTTAG +yyprocessOneStack (yyGLRStack* yystack, int yyk, + size_t yyposn, YYSTYPE* yylvalp, YYLTYPE* yyllocp + ) +{ + int yyaction; + const short int* yyconflicts; + yyRuleNum yyrule; + yySymbol* const yytokenp = yystack->yytokenp; + + while (yystack->yytops.yystates[yyk] != NULL) + { + yyStateNum yystate = yystack->yytops.yystates[yyk]->yylrState; + YYDPRINTF ((stderr, "Stack %d Entering state %d\n", yyk, yystate)); + + YYASSERT (yystate != YYFINAL); + + if (yyisDefaultedState (yystate)) + { + yyrule = yydefaultAction (yystate); + if (yyrule == 0) + { + YYDPRINTF ((stderr, "Stack %d dies.\n", yyk)); + yymarkStackDeleted (yystack, yyk); + return yyok; + } + YYCHK (yyglrReduce (yystack, yyk, yyrule, yyfalse)); + } + else + { + if (*yytokenp == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + *yytokenp = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", *yytokenp, yylvalp, yyllocp); + } + yygetLRActions (yystate, *yytokenp, &yyaction, &yyconflicts); + + while (*yyconflicts != 0) + { + int yynewStack = yysplitStack (yystack, yyk); + YYDPRINTF ((stderr, "Splitting off stack %d from %d.\n", + yynewStack, yyk)); + YYCHK (yyglrReduce (yystack, yynewStack, + *yyconflicts, yyfalse)); + YYCHK (yyprocessOneStack (yystack, yynewStack, yyposn, + yylvalp, yyllocp)); + yyconflicts += 1; + } + + if (yyisShiftAction (yyaction)) + { + YYDPRINTF ((stderr, "On stack %d, ", yyk)); + YY_SYMBOL_PRINT ("shifting", *yytokenp, yylvalp, yyllocp); + yyglrShift (yystack, yyk, yyaction, yyposn+1, + *yylvalp, yyllocp); + YYDPRINTF ((stderr, ", now in state #%d\n", + yystack->yytops.yystates[yyk]->yylrState)); + break; + } + else if (yyisErrorAction (yyaction)) + { + YYDPRINTF ((stderr, "Stack %d dies.\n", yyk)); + yymarkStackDeleted (yystack, yyk); + break; + } + else + YYCHK (yyglrReduce (yystack, yyk, -yyaction, yyfalse)); + } + } + return yyok; +} + +static void +yyreportSyntaxError (yyGLRStack* yystack, + YYSTYPE* yylvalp, YYLTYPE* yyllocp) +{ + /* `Unused' warnings. */ + (void) yylvalp; + (void) yyllocp; + + if (yystack->yyerrState == 0) + { +#if YYERROR_VERBOSE + yySymbol* const yytokenp = yystack->yytokenp; + int yyn; + yyn = yypact[yystack->yytops.yystates[0]->yylrState]; + if (YYPACT_NINF < yyn && yyn < YYLAST) + { + size_t yysize = 0; + const char* yyprefix; + char* yymsg; + int yyx; + + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yycount = 0; + + yyprefix = ", expecting "; + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + yysize += strlen (yyprefix) + strlen (yytokenName (yyx)); + yycount += 1; + if (yycount == 5) + { + yysize = 0; + break; + } + yyprefix = " or "; + } + yysize += (sizeof ("syntax error, unexpected ") + + strlen (yytokenName (*yytokenp))); + yymsg = (char*) YYMALLOC (yysize); + if (yymsg != 0) + { + char* yyp = yymsg; + sprintf (yyp, "syntax error%s%s", + (*yytokenp == YYEMPTY ? "" : ", unexpected "), + yytokenName (*yytokenp)); + yyp += strlen (yyp); + if (yycount < 5) + { + yyprefix = ", expecting "; + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + sprintf (yyp, "%s%s", yyprefix, yytokenName (yyx)); + yyp += strlen (yyp); + yyprefix = " or "; + } + } + yyerror (yymsg); + YYFREE (yymsg); + } + else + yyerror ("syntax error; also virtual memory exhausted"); + } + else +#endif /* YYERROR_VERBOSE */ + yyerror ("syntax error"); + yynerrs += 1; + } +} + +/* Recover from a syntax error on YYSTACK, assuming that YYTOKENP, + YYLVALP, and YYLLOCP point to the syntactic category, semantic + value, and location of the look-ahead. */ +static void +yyrecoverSyntaxError (yyGLRStack* yystack, + YYSTYPE* yylvalp, + YYLTYPE* yyllocp ATTRIBUTE_UNUSED + ) +{ + yySymbol* const yytokenp = yystack->yytokenp; + size_t yyk; + int yyj; + + if (yystack->yyerrState == 3) + /* We just shifted the error token and (perhaps) took some + reductions. Skip tokens until we can proceed. */ + while (yytrue) + { + if (*yytokenp == YYEOF) + { + /* Now pop stack until empty and fail. */ + while (yystack->yytops.yystates[0] != NULL) + { + yyGLRState *yys = yystack->yytops.yystates[0]; + + yydestruct ("Error: popping", + yystos[yys->yylrState], + &yys->yysemantics.yysval); + yystack->yytops.yystates[0] = yys->yypred; + yystack->yynextFree -= 1; + yystack->yyspaceLeft += 1; + } + yyFail (yystack, NULL); + } + if (*yytokenp != YYEMPTY) + { + yydestruct ("Error: discarding", + *yytokenp, yylvalp); + } + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + *yytokenp = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", *yytokenp, yylvalp, yyllocp); + yyj = yypact[yystack->yytops.yystates[0]->yylrState]; + if (yyis_pact_ninf (yyj)) + return; + yyj += *yytokenp; + if (yyj < 0 || YYLAST < yyj || yycheck[yyj] != *yytokenp) + { + if (yydefact[yystack->yytops.yystates[0]->yylrState] != 0) + return; + } + else if (yytable[yyj] != 0 && ! yyis_table_ninf (yytable[yyj])) + return; + } + + /* Reduce to one stack. */ + for (yyk = 0; yyk < yystack->yytops.yysize; yyk += 1) + if (yystack->yytops.yystates[yyk] != NULL) + break; + if (yyk >= yystack->yytops.yysize) + yyFail (yystack, NULL); + for (yyk += 1; yyk < yystack->yytops.yysize; yyk += 1) + yymarkStackDeleted (yystack, yyk); + yyremoveDeletes (yystack); + yycompressStack (yystack); + + /* Now pop stack until we find a state that shifts the error token. */ + yystack->yyerrState = 3; + while (yystack->yytops.yystates[0] != NULL) + { + yyGLRState *yys = yystack->yytops.yystates[0]; + yyj = yypact[yys->yylrState]; + if (! yyis_pact_ninf (yyj)) + { + yyj += YYTERROR; + if (0 <= yyj && yyj <= YYLAST && yycheck[yyj] == YYTERROR + && yyisShiftAction (yytable[yyj])) + { + /* Shift the error token having adjusted its location. */ + YYLTYPE yyerrloc; + YY_SYMBOL_PRINT ("Shifting", yystos[yytable[yyj]], + yylvalp, &yyerrloc); + yyglrShift (yystack, 0, yytable[yyj], + yys->yyposn, *yylvalp, &yyerrloc); + yys = yystack->yytops.yystates[0]; + break; + } + } + + yydestruct ("Error: popping", + yystos[yys->yylrState], + &yys->yysemantics.yysval); + yystack->yytops.yystates[0] = yys->yypred; + yystack->yynextFree -= 1; + yystack->yyspaceLeft += 1; + } + if (yystack->yytops.yystates[0] == NULL) + yyFail (yystack, NULL); +} + +#define YYCHK1(YYE) \ + do { \ + switch (YYE) { \ + default: \ + break; \ + case yyabort: \ + yystack.yyerrflag = 1; \ + goto yyDone; \ + case yyaccept: \ + yystack.yyerrflag = 0; \ + goto yyDone; \ + case yyerr: \ + goto yyuser_error; \ + } \ + } while (0) + + +/*----------. +| yyparse. | +`----------*/ + +int +yyparse (void) +{ + yySymbol yytoken; + yyGLRStack yystack; + size_t yyposn; + + + YYSTYPE* const yylvalp = &yylval; + YYLTYPE* const yyllocp = &yylloc; + + yyinitGLRStack (&yystack, YYINITDEPTH); + yystack.yytokenp = &yytoken; + + YYDPRINTF ((stderr, "Starting parse\n")); + + if (setjmp (yystack.yyexception_buffer) != 0) + goto yyDone; + + yylval = yyval_default; + + + yyglrShift (&yystack, 0, 0, 0, yylval, &yylloc); + yytoken = YYEMPTY; + yyposn = 0; + + while (yytrue) + { + /* For efficiency, we have two loops, the first of which is + specialized to deterministic operation (single stack, no + potential ambiguity). */ + /* Standard mode */ + while (yytrue) + { + yyRuleNum yyrule; + int yyaction; + const short int* yyconflicts; + + yyStateNum yystate = yystack.yytops.yystates[0]->yylrState; + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + if (yystate == YYFINAL) + goto yyDone; + if (yyisDefaultedState (yystate)) + { + yyrule = yydefaultAction (yystate); + if (yyrule == 0) + { + + yyreportSyntaxError (&yystack, yylvalp, yyllocp); + goto yyuser_error; + } + YYCHK1 (yyglrReduce (&yystack, 0, yyrule, yytrue)); + } + else + { + if (yytoken == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, yylvalp, yyllocp); + } + yygetLRActions (yystate, yytoken, &yyaction, &yyconflicts); + if (*yyconflicts != 0) + break; + if (yyisShiftAction (yyaction)) + { + YY_SYMBOL_PRINT ("Shifting", yytoken, yylvalp, yyllocp); + if (yytoken != YYEOF) + yytoken = YYEMPTY; + yyposn += 1; + yyglrShift (&yystack, 0, yyaction, yyposn, + yylval, yyllocp); + if (0 < yystack.yyerrState) + yystack.yyerrState -= 1; + } + else if (yyisErrorAction (yyaction)) + { + + yyreportSyntaxError (&yystack, yylvalp, yyllocp); + goto yyuser_error; + } + else + YYCHK1 (yyglrReduce (&yystack, 0, -yyaction, yytrue)); + } + } + + while (yytrue) + { + int yys; + int yyn = yystack.yytops.yysize; + for (yys = 0; yys < yyn; yys += 1) + YYCHK1 (yyprocessOneStack (&yystack, yys, yyposn, + yylvalp, yyllocp)); + yytoken = YYEMPTY; + yyposn += 1; + yyremoveDeletes (&yystack); + if (yystack.yytops.yysize == 0) + { + yyundeleteLastStack (&yystack); + if (yystack.yytops.yysize == 0) + yyFail (&yystack, "syntax error"); + YYCHK1 (yyresolveStack (&yystack)); + YYDPRINTF ((stderr, "Returning to deterministic operation.\n")); + + yyreportSyntaxError (&yystack, yylvalp, yyllocp); + goto yyuser_error; + } + else if (yystack.yytops.yysize == 1) + { + YYCHK1 (yyresolveStack (&yystack)); + YYDPRINTF ((stderr, "Returning to deterministic operation.\n")); + yycompressStack (&yystack); + break; + } + } + continue; + yyuser_error: + yyrecoverSyntaxError (&yystack, yylvalp, yyllocp); + yyposn = yystack.yytops.yystates[0]->yyposn; + } + yyDone: + /* On YYABORT, free the lookahead. */ + if (yystack.yyerrflag == 1 && yytoken != YYEMPTY) + yydestruct ("Error: discarding lookahead", + yytoken, yylvalp); + + yyfreeGLRStack (&yystack); + return yystack.yyerrflag; +} + +/* DEBUGGING ONLY */ +#ifdef YYDEBUG +static void yypstack (yyGLRStack* yystack, int yyk) ATTRIBUTE_UNUSED; +static void yypdumpstack (yyGLRStack* yystack) ATTRIBUTE_UNUSED; + +static void +yy_yypstack (yyGLRState* yys) +{ + if (yys->yypred) + { + yy_yypstack (yys->yypred); + fprintf (stderr, " -> "); + } + fprintf (stderr, "%d@%lu", yys->yylrState, (unsigned long int) yys->yyposn); +} + +static void +yypstates (yyGLRState* yyst) +{ + if (yyst == NULL) + fprintf (stderr, ""); + else + yy_yypstack (yyst); + fprintf (stderr, "\n"); +} + +static void +yypstack (yyGLRStack* yystack, int yyk) +{ + yypstates (yystack->yytops.yystates[yyk]); +} + +#define YYINDEX(YYX) \ + ((YYX) == NULL ? -1 : (yyGLRStackItem*) (YYX) - yystack->yyitems) + + +static void +yypdumpstack (yyGLRStack* yystack) +{ + yyGLRStackItem* yyp; + size_t yyi; + for (yyp = yystack->yyitems; yyp < yystack->yynextFree; yyp += 1) + { + fprintf (stderr, "%3lu. ", (unsigned long int) (yyp - yystack->yyitems)); + if (*(yybool *) yyp) + { + fprintf (stderr, "Res: %d, LR State: %d, posn: %lu, pred: %ld", + yyp->yystate.yyresolved, yyp->yystate.yylrState, + (unsigned long int) yyp->yystate.yyposn, + (long int) YYINDEX (yyp->yystate.yypred)); + if (! yyp->yystate.yyresolved) + fprintf (stderr, ", firstVal: %ld", + (long int) YYINDEX (yyp->yystate.yysemantics.yyfirstVal)); + } + else + { + fprintf (stderr, "Option. rule: %d, state: %ld, next: %ld", + yyp->yyoption.yyrule, + (long int) YYINDEX (yyp->yyoption.yystate), + (long int) YYINDEX (yyp->yyoption.yynext)); + } + fprintf (stderr, "\n"); + } + fprintf (stderr, "Tops:"); + for (yyi = 0; yyi < yystack->yytops.yysize; yyi += 1) + fprintf (stderr, "%lu: %ld; ", (unsigned long int) yyi, + (long int) YYINDEX (yystack->yytops.yystates[yyi])); + fprintf (stderr, "\n"); +} +#endif + + +#line 77 "idx.y" + + diff --git a/filter/idx.tab.h b/filter/idx.tab.h new file mode 100644 index 0000000..00ac7cd --- /dev/null +++ b/filter/idx.tab.h @@ -0,0 +1,83 @@ +/* A Bison parser, made by GNU Bison 2.0. */ + +/* Skeleton parser for GLR parsing with Bison, + Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + NUM = 258, + COL = 259, + FUNC = 260, + REG = 261, + INDEF = 262, + OR = 263, + AND = 264, + NE = 265, + EQ = 266, + GE = 267, + LE = 268, + UMINUS = 269 + }; +#endif +#define NUM 258 +#define COL 259 +#define FUNC 260 +#define REG 261 +#define INDEF 262 +#define OR 263 +#define AND 264 +#define NE 265 +#define EQ 266 +#define GE 267 +#define LE 268 +#define UMINUS 269 + + + + +#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) +#line 6 "idx.y" +typedef union YYSTYPE { + idxrowrec *row; + idxvalrec *val; +} YYSTYPE; +/* Line 2089 of glr.c. */ +#line 65 "idx.tab.h" +# define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 +#endif + +extern YYSTYPE idxlval; + +#if ! defined (YYLTYPE) && ! defined (YYLTYPE_IS_DECLARED) +typedef struct YYLTYPE +{ + + char yydummy; + +} YYLTYPE; +# define YYLTYPE_IS_DECLARED 1 +# define YYLTYPE_IS_TRIVIAL 1 +#endif + + + diff --git a/filter/idx.y b/filter/idx.y new file mode 100644 index 0000000..1846fec --- /dev/null +++ b/filter/idx.y @@ -0,0 +1,77 @@ +%{ +#include +#include +%} + +%union{ + idxrowrec *row; + idxvalrec *val; +} + +%token NUM +%token COL +%token FUNC +%token REG +%token INDEF + +%left OR +%left AND +%left '|' +%left '^' +%left '&' +%nonassoc EQ NE +%nonassoc '<' LE '>' GE +%left '+' '-' +%left '*' '/' '%' +%right '!' '~' UMINUS + +%type idx +%type expr +%type rowlist +%type value + +%glr-parser +%expect-rr 1 + +%% + +/* combines lists of row numbers */ +idx: expr { idxall($1); } +; + +expr: rowlist +| expr OR expr { $$ = idxor($1,$3); } +| expr AND expr { $$ = idxand($1,$3); } +| '(' expr ')' { $$ = $2; } +; + +/* generates lists of row numbers */ +rowlist:REG { $$ = idxrowreg($1); } +| FUNC { $$ = idxrowfun($1); } +| value EQ value { $$ = idxroweq($1,$3); } +| value NE value { $$ = idxrowne($1,$3); } +| value '<' value { $$ = idxrowlt($1,$3); } +| value LE value { $$ = idxrowle($1,$3); } +| value '>' value { $$ = idxrowgt($1,$3); } +| value GE value { $$ = idxrowge($1,$3); } +; + +value: NUM +| COL +| INDEF +| FUNC +| value '+' value { $$ = idxvaladd($1,$3); } +| value '-' value { $$ = idxvalsub($1,$3); } +| value '*' value { $$ = idxvalmul($1,$3); } +| value '/' value { $$ = idxvaldiv($1,$3); } +| value '%' value { $$ = idxvalmod($1,$3); } +| value '&' value { $$ = idxvaland($1,$3); } +| value '|' value { $$ = idxvalor($1,$3); } +| value '^' value { $$ = idxvalxor($1,$3); } +| '!' value { $$ = idxvalnot($2); } +| '~' value { $$ = idxvalcom($2); } +| '-' value %prec UMINUS { $$ = idxvalmin($2); } +| '(' value ')' { $$ = $2; } +; + +%% diff --git a/filter/idxacts.c b/filter/idxacts.c new file mode 100644 index 0000000..4989267 --- /dev/null +++ b/filter/idxacts.c @@ -0,0 +1,2368 @@ +/* + * Copyright (c) 2005 Smithsonian Astrophysical Observatory + */ + +/* + * + * idxacts.c -- action routines for idx + * + */ + +#include +#include +#include + +#if HAVE_LONG_LONG +#define LFMT "%lld" +#else +#define LFMT "%ld" +#endif + +#define IDX_DEBUG 1 +#if IDX_DEBUG +#define IPRINTF(x) if( idx_debug ) fprintf x +#else +#define IPRINTF(x) +#endif + +/* used by idx.l, so it must be global */ +int idx_debug=0; + +/* + * + * private routines + * + */ + +#define MAXD 3 +static char dbuf[MAXD][SZ_LINE]; +static int nd=0; + +static char _swapped[8]; +static int idx_io=IDX_IO_DEFAULT; + +static char *idxcolname=NULL; +static char *idxfilename=NULL; +static char *idxfileroot1=NULL; +static char *idxfileroot2=NULL; +static char *idxpath=NULL; +static char *idxsort=NULL; + +static char fmt[SZ_LINE]; + +#ifdef ANSI_FUNC +static void * +_swap(void *ibuf, int isize) +#else +static void *_swap(ibuf, isize) + void *ibuf; + int isize; +#endif +{ + return ft_dataswap(_swapped, ibuf, isize, isize*8); +} + +#if IDX_DEBUG +#ifdef ANSI_FUNC +static char * +rowdisp(idxrowrec *row) +#else +static char *rowdisp(row) + idxrowrec *row; +#endif +{ + int i; + char tbuf[SZ_LINE]; + + if( nd >= MAXD ) nd = 0; + *dbuf[nd] = '\0'; + switch(row->rtype){ + case IDX_ROW_LIST: + if( row->s ){ + snprintf(dbuf[nd], SZ_LINE-1, "%s[ROW", row->s); + } + else{ + snprintf(dbuf[nd], SZ_LINE-1, "[ROW"); + } + for(i=0; inrow; i++){ + strncat(dbuf[nd], " ", SZ_LINE-1); + snprintf(tbuf, SZ_LINE-1, "%d:%d", row->startrow[i], row->stoprow[i]); + strncat(dbuf[nd], tbuf, SZ_LINE-1); + } + strncat(dbuf[nd], "]", SZ_LINE-1); + break; + case IDX_SORT: + snprintf(dbuf[nd], SZ_LINE-1, "[IDX_SORT]"); + break; + case IDX_OR_SORT: + snprintf(dbuf[nd], SZ_LINE-1, "[IDX_OR_SORT]"); + break; + case IDX_AND_SORT: + snprintf(dbuf[nd], SZ_LINE-1, "[IDX_AND_SORT]"); + break; + case IDX_INDEF: + snprintf(dbuf[nd], SZ_LINE-1, "[INDEF]"); + break; + } + if( !*dbuf[nd] ){ + snprintf(dbuf[nd], SZ_LINE-1, "type=%d?", row->rtype); + } + return dbuf[nd++]; +} +#endif + +#ifdef ANSI_FUNC +static int +_idxvalfree(idxvalrec *v) +#else +static int _idxvalfree(v) + idxvalrec *v; +#endif +{ + if( !v ) return 0; + if( v->s ) xfree(v->s); +#ifdef HAVE_SYS_MMAN_H + if( v->idata ) munmap(v->idata, v->ilen); +#endif + /* these are linked (i.e. if iname does not exist, its a copy of another */ + if( v->iname && v->igio && v->ifits ){ + gclose(v->igio); + xfree(v->iname); + ft_headfree(v->ifits, 1); + } + xfree(v); + return 1; +} + +#ifdef ANSI_FUNC +static int +_idxrowfree(idxrowrec *r) +#else +static int _idxrowfree(r) + idxrowrec *r; +#endif +{ + int tries=0; + int exit_status; + + if( !r ) return 0; + if( r->s ) xfree(r->s); + if( r->startrow ) xfree(r->startrow); + if( r->stoprow ) xfree(r->stoprow); + if( r->ifile ) + fclose(r->ifile); + else if( r->ichan ) + close(r->ichan); + if( r->ochan ) + close(r->ochan); +#if HAVE_MINGW32==0 + if( r->pid ){ + while( (waitpid(r->pid, &exit_status, WNOHANG)==0) && (tries<10) ){ + gsleep(10); + tries++; + } + r->pid = 0; + } +#endif + if( r->fdata ){ +#ifdef HAVE_SYS_MMAN_H + munmap(r->fdata, r->flen); +#endif + } + xfree(r); + return 1; +} + + +#ifdef ANSI_FUNC +static int +_idxstartsort(int type, int *ichan, int *ochan, int *pid) +#else +static int _idxstartsort(type, ichan, ochan, pid) + int type; + int *ichan; + int *ochan; + int *pid; +#endif +{ + char *s; + char cmd[SZ_LINE]; + + if( !idxsort ){ + if( idxpath ) return 0; + if( (s=(char *)getenv("PATH")) ){ + idxpath = xstrdup(s); + } + if( !(idxsort=Find(IDX_SORTPROG, "x", NULL, idxpath)) && + !(idxsort=Find(IDX_SORTPROG, "x", NULL, ".")) ){ + idxerror("index sort program cannot be found"); + return 0; + } + } + /* construct command line for sort program */ + switch(type){ + case IDX_SORT: + snprintf(cmd, SZ_LINE-1, "%s -B4 +i0", idxsort); + break; + case IDX_OR_SORT: + snprintf(cmd, SZ_LINE-1, "%s -B4 +i0 -u", idxsort); + break; + case IDX_AND_SORT: + snprintf(cmd, SZ_LINE-1, "%s -B4 +i0 -D", idxsort); + break; + default: + snprintf(cmd, SZ_LINE-1, "%s -B4 +i0", idxsort); + break; + } + /* start the sort program */ + if( !ProcessOpen(cmd, ichan, ochan, pid) ){ + idxerror("index sort process cannot be started"); + return 0; + } + return 1; +} + +#ifdef ANSI_FUNC +static int +_idxwritesort(idxrowrec *x, idxrowrec *row) +#else +static int _idxwritesort(x, row) + idxrowrec *x; + idxrowrec *row; +#endif +{ + int i, j, k=0; + int rowsize; + int ioffset; + int itype; + int isize; + int obuf[SZ_LINE]; + long ipos; + char nbuf[8]; + idxvalrec *v=NULL; + + v = row->v; + rowsize = ft_naxis(v->ifits, 1); + ioffset = v->ioffset; + itype = v->itype; + isize = ft_sizeof(v->itype); + for(i=0; inrow; i++){ + for(j=row->startrow[i]; j<=row->stoprow[i]; j++){ + ipos = v->ifits->data + ((j-1)*rowsize) + ioffset; + switch( idx_io ){ + case IDX_IO_MMAP: + if( v->idata ){ +#ifdef HAVE_SYS_MMAN_H + memcpy(nbuf, &v->idata[ipos], isize); +#else + idxerror("mmap not supported on this system"); +#endif + break; + } + case IDX_IO_LSEEK: + if( gseek(v->igio, (off_t)ipos, 0) < 0 ){ + idxerror("can't lseek into index file"); + return 0; + } + if( !gread(v->igio, nbuf, isize, 1) ){ + idxerror("can't read index file"); + return 0; + } + break; + } + switch(itype){ + case 'B': + obuf[k++] = (int)*(unsigned char *)(nbuf); + break; + case 'I': + obuf[k++] = (int)*(short *)_swap(nbuf,2); + break; + case 'U': + obuf[k++] = (int)*(unsigned short *)_swap(nbuf,2); + break; + case 'J': + obuf[k++] = (int)*(int *)_swap(nbuf,4); + break; + case 'V': + obuf[k++] = (int)*(unsigned int *)_swap(nbuf,4); + break; + case 'K': + idxerror("64-bit integer not supported for index"); + break; + default: + idxerror("illegal index data type"); + } + if( k == SZ_LINE ){ + if( write(x->ochan, obuf, k*sizeof(int)) != (int)(k*sizeof(int)) ){ + idxerror("can't write index value to sort"); + return 0; + } + k = 0; + } + } + } + if( k ){ + if( write(x->ochan, obuf, k*sizeof(int)) != (int)(k*sizeof(int)) ){ + idxerror("can't write index value to sort"); + return 0; + } + } + return 1; +} + +#ifdef ANSI_FUNC +static int +_idxcompare(char *buf, int type, int offset, int n, + double d, longlong l, int t) +#else +static int _idxcompare(buf, type, offset, n, d, l, t) + char *buf; + int type; + int offset; + int n; + double d; + longlong l; + int t; +#endif +{ + unsigned short sval; + unsigned int xval; + int xn; + double dval=0.0; + longlong lval=0; + int isint=0; + + switch(type){ + case 'X': + isint = 1; + if( n == 16 ){ + xn = 1; + n = 1; + } + else if( n == 32 ){ + xn = 2; + n = 1; + } + else if( n == 64 ){ + xn = 3; + n = 1; + } + else{ + xn = 0; + n = (n+7)/8; + } + switch(xn){ + case 1: + memcpy(&sval, _swap(buf+offset,2), sizeof(unsigned short)); + dval = (double)sval; + lval = (longlong)sval; + break; + case 2: + memcpy(&xval, _swap(buf+offset,4), sizeof(unsigned int)); + dval = (double)xval; + lval = (longlong)xval; + break; + case 3: + memcpy(&lval, _swap(buf+offset,8), sizeof(unsigned int)); + dval = (double)lval; + break; + case 0: + default: + xval = (unsigned int)*(unsigned char *)(buf+offset); + dval = (double)xval; + lval = (longlong)xval; + break; + } + case 'B': + isint = 1; + dval = (double)*(unsigned char *)(buf+offset); + lval = (longlong)*(unsigned char *)(buf+offset); + break; + case 'I': + isint = 1; + dval = (double)*(short *)_swap(buf+offset,2); + lval = (longlong)*(short *)_swap(buf+offset,2); + break; + case 'U': + isint = 1; + dval = (double)*(unsigned short *)_swap(buf+offset,2); + lval = (longlong)*(unsigned short *)_swap(buf+offset,2); + break; + case 'J': + isint = 1; + dval = (double)*(int *)_swap(buf+offset,4); + lval = (longlong)*(int *)_swap(buf+offset,4); + break; + case 'V': + isint = 1; + dval = (double)*(unsigned int *)_swap(buf+offset,4); + lval = (longlong)*(unsigned int *)_swap(buf+offset,4); + break; + case 'K': + isint = 1; + dval = (double)*(longlong *)_swap(buf+offset,8); + lval = (longlong)*(longlong *)_swap(buf+offset,8); + break; + case 'E': + isint = 0; + dval = (double)*(float *)_swap(buf+offset,4); + lval = (longlong)*(float *)_swap(buf+offset,4); + break; + case 'D': + isint = 0; + dval = *(double *)_swap(buf+offset,8); + lval = *(longlong *)_swap(buf+offset,8); + break; + case 'L': + isint = 1; + dval = (double)*(unsigned char *)(buf+offset); + lval = (longlong)*(unsigned char *)(buf+offset); + break; + case 'A': + default: + gerror(stderr, "illegal numeric value for compare: %d\n", type); + break; + } + if( t == PARSE_INTEGER ){ + if( isint ){ + if( lval < l ) + return -1; + else if( lval > l ) + return 1; + else + return 0; + } + else{ + if( dval < l ) + return -1; + else if( dval > l ) + return 1; + else + return 0; + } + } + else{ + if( isint ){ + if( lval < d ) + return -1; + else if( lval > d ) + return 1; + else + return 0; + } + else{ + if( dval < d ) + return -1; + else if( dval > d ) + return 1; + else + return 0; + } + } +} + +#ifdef ANSI_FUNC +static int +_idxbsearch(GIO gio, FITSHead fits, int type, int offset, int n, + int exact, int edge, double d, longlong l, int t) +#else +static int _idxbsearch(gio, fits, type, offset, n, exact, edge, d, l, t) + GIO gio; + FITSHead fits; + int type; + int offset; + int n; + int exact; + int edge; + double d; + longlong l; + int t; +#endif +{ + int high, low, try; + int cmp; + int rowsize; + size_t got; + long ipos; + char *buf=NULL; + + /* sanity check */ + if( !gio || !fits ) return -1; + + /* set limits */ + low = 0; + high = ft_naxis(fits, 2)+1; + rowsize = ft_naxis(fits, 1); + /* search */ + while( (high - low) > 1){ + try = (high + low) / 2; + /* grab desired row in index */ + ipos = fits->data + ((try-1)*rowsize); + if( gseek(gio, (off_t)ipos, 0) < 0 ) return -1; + buf = _gread(gio, NULL, sizeof(char), rowsize, &got); + if( !buf || (got != (size_t)rowsize) ) return -1; + /* compare row to key value */ + cmp = _idxcompare(buf, type, offset, n, d, l, t); + if( buf ) xfree(buf); + switch(cmp){ + /* thisval < val */ + case -1: + low = try; + break; + /* thisval == val */ + case 0: + /* to find first record, set hi */ + if( edge == -1 ) + high = try; + /* for last record, set lo */ + else + low = try; + break; + /* thisval > val */ + case 1: + high = try; + break; + } + } + /* check for out of bounds and get candidate row */ + if( edge == 1 ){ + if( low == 0 ) { + if( exact ) + return -1; + else + return 0; + } + try = low; + } + else{ + if( high == (ft_naxis(fits, 2)+1) ){ + if( exact ) + return -1; + else + return ft_naxis(fits, 2)+1;; + } + try = high; + } + /* grab desired row in index */ + ipos = fits->data + ((try-1)*rowsize); + if( gseek(gio, (off_t)ipos, 0) < 0 ) return -1; + buf = _gread(gio, NULL, sizeof(char), rowsize, &got); + if( !buf || (got != (size_t)rowsize) ) return -1; + /* compare row to key value */ + cmp = _idxcompare(buf, type, offset, n, d, l, t); + if( buf ) xfree(buf); + /* if row == key value, we got a match */ + if( !cmp || !exact ){ + if( edge == 1 ) + return low; + else + return high; + } + else + return -1; +} + +#ifdef ANSI_FUNC +static int +_idxrowcommon(idxvalrec *val1, idxvalrec *val2, int exact, int which, + idxrowrec **x, int *start, int *stop, int *nrow) +#else +static int _idxrowcommon(val1, val2, exact, which, x, start, stop, nrow) + idxvalrec *val1, *val2; + int exact; + int which; + idxrowrec **x; + int *start, *stop; + int *nrow +#endif +{ + idxvalrec *v1=NULL, *v2=NULL; + + *start = -1; + *stop = -1; + *nrow = -1; + *x = idxrownew(); + if( (val1->type == COL) && (val2->type == NUM) ){ + v1 = val1; + v2 = val2; + } + if( v1 && v2 ){ + (*x)->type = COL; + (*x)->rtype = IDX_ROW_LIST; + (*x)->dofilt = 0; + (*x)->s = xstrdup(v1->s); + (*x)->v = v1; + *nrow = v1->nrow; + if( which & IDX_EDGE_LEFT ) + *start = _idxbsearch(v1->igio, v1->ifits, v1->vtype, v1->voffset, v1->vn, + exact, -1, v2->dval, v2->ival, v2->ntype); + if( which & IDX_EDGE_RIGHT ) + *stop = _idxbsearch(v1->igio, v1->ifits, v1->vtype, v1->voffset, v1->vn, + exact, 1, v2->dval, v2->ival, v2->ntype); + return 1; + } + else{ + (*x)->type = IDX_INDEF; + (*x)->rtype = IDX_INDEF; + (*x)->dofilt = 1; + return 0; + } +} + +#ifdef ANSI_FUNC +static int +_idxrowaddrow(idxrowrec *r, int start, int stop) +#else + static int _idxrowaddrow(r, start, stop) + idxrowrec *r; + int start; + int stop; +#endif +{ + if( !r ) return 0; + if( r->nrow >= r->maxrow ){ + r->maxrow += IDX_ROW_INC; + r->startrow = xrealloc(r->startrow, r->maxrow*sizeof(int)); + r->stoprow = xrealloc(r->stoprow, r->maxrow*sizeof(int)); + } + r->startrow[r->nrow] = start; + r->stoprow[r->nrow] = stop; + r->nrow++; + return r->nrow; +} + +#ifdef ANSI_FUNC +static void +idxrowmark(idxrowrec *row1, idxrowrec *row2, char **mbuf, int *nm) +#else +static void idxrowmark(row1, row2, mbuf, nm) + idxrowrec *row1, *row2; + char **mbuf; + int *nm; +#endif +{ + int i, j; + + *nm=0; + for(i=0; inrow; i++){ + *nm = MAX(*nm, row1->stoprow[i]); + } + for(i=0; inrow; i++){ + *nm = MAX(*nm, row2->stoprow[i]); + } + *nm += 1; + if( !(*mbuf = xcalloc(*nm, sizeof(char))) ){ + idxerror("can't allocate memory for index"); + } + for(i=0; inrow; i++){ + for(j=row1->startrow[i]; j<=row1->stoprow[i]; j++){ + (*mbuf)[j-1] |= 1; + } + } + for(i=0; inrow; i++){ + for(j=row2->startrow[i]; j<=row2->stoprow[i]; j++){ + (*mbuf)[j-1] |= 2; + } + } +} + +#ifdef ANSI_FUNC +static idxrowrec * +_idxrowmerge(idxrowrec *x, idxrowrec *row1, idxrowrec *row2, int type) +#else +static idxrowrec *_idxrowmerge(x, row1, row2, type) + idxrowrec *x; + idxrowrec *row1; + idxrowrec *row2 + int type; +#endif +{ + int last=-1; + int in1=-1, in2=-1, on=0; + int igot1=-1, igot2=-1; + int fd[2]; + int ibuf1[SZ_LINE]; + int ibuf2[SZ_LINE]; + int obuf[SZ_LINE]; + FILE *ifd1, *ifd2, *ofd; + +#if HAVE_MINGW32==0 + /* we fork a process that will read the output from 2 instances of sort and + either OR and AND the results. Doing this avoids having the main process + read the output of the sorts and write to a new merge process */ + if( pipe(fd) < 0 ){ + x->type = IDX_INDEF; + x->rtype = IDX_INDEF; + x->dofilt = 1; + return x; + } + if( (x->pid = fork()) < 0 ){ + x->type = IDX_INDEF; + x->rtype = IDX_INDEF; + x->dofilt = 1; + return x; + } else if( x->pid != 0 ){ /* parent */ + IPRINTF((stderr, "idxmerge(%d): %s %s\n", + type, rowdisp(row1), rowdisp(row2))); + close(fd[1]); + x->ichan = fd[0]; + close(row1->ichan); row1->ichan=0; + close(row2->ichan); row2->ichan=0; + return x; + } + else{ /* child */ + close(fd[0]); + if( !(ifd1 = fdopen(row1->ichan, "r")) || + !(ifd2 = fdopen(row2->ichan, "r")) || + !(ofd = fdopen(fd[1], "w")) ){ + _exit(1); + } + while( 1 ){ + if( in1 == igot1 ){ + igot1 = fread(ibuf1, sizeof(int), SZ_LINE, ifd1); + if( igot1 != 0 ){ + in1 = 0; + } + } + if( in2 == igot2 ){ + igot2 = fread(ibuf2, sizeof(int), SZ_LINE, ifd2); + if( igot2 != 0 ){ + in2 = 0; + } + } + if( igot1 && igot2 ){ + if( ibuf1[in1] < ibuf2[in2] ){ + switch(type){ + case IDX_SORT: + obuf[on++] = ibuf1[in1]; + break; + case IDX_AND_SORT: + if( ibuf1[in1] == last ) + obuf[on++] = ibuf1[in1]; + break; + case IDX_OR_SORT: + if( ibuf1[in1] != last ) + obuf[on++] = ibuf1[in1]; + break; + } + last = ibuf1[in1++]; + } + else{ + switch(type){ + case IDX_SORT: + obuf[on++] = ibuf2[in2]; + break; + case IDX_AND_SORT: + if( ibuf2[in2] == last ) + obuf[on++] = ibuf2[in2]; + break; + case IDX_OR_SORT: + if( ibuf2[in2] != last ) + obuf[on++] = ibuf2[in2]; + break; + } + last = ibuf2[in2++]; + } + } + else if( igot1 ){ + switch(type){ + case IDX_SORT: + obuf[on++] = ibuf2[in2]; + break; + case IDX_AND_SORT: + if( ibuf1[in1] == last ) + obuf[on++] = ibuf1[in1]; + break; + case IDX_OR_SORT: + if( ibuf1[in1] != last ) + obuf[on++] = ibuf1[in1]; + break; + } + last = ibuf1[in1++]; + } + else if( igot2 ){ + switch(type){ + case IDX_SORT: + obuf[on++] = ibuf2[in2]; + break; + case IDX_AND_SORT: + if( ibuf2[in2] == last ) + obuf[on++] = ibuf2[in2]; + break; + case IDX_OR_SORT: + if( ibuf2[in2] != last ) + obuf[on++] = ibuf2[in2]; + break; + } + last = ibuf2[in2++]; + } + else{ + break; + } + if( on == SZ_LINE ){ + fwrite(obuf, sizeof(int), on, ofd); + fflush(ofd); + on = 0; + } + } + fwrite(obuf, sizeof(int), on, ofd); + fflush(ofd); + _exit(0); + } +#else + idxerror("can't use index optimization with MinGW"); +#endif + /* shouldn't get here */ + return NULL; +} + +/* + * + * public routines + * + */ + +#ifdef ANSI_FUNC +idxrowrec *idxall(idxrowrec *row) +#else +idxrowrec *idxall(row) + idxrowrec *row; +#endif +{ + Filter filt; + idxrowrec *x; + + /* sanity check */ + if( !(filt = FilterDefault()) ) + idxerror("filter symbol table not initialized"); + /* most range list columns need to be sorted; col==val already is sorted */ + if( (row->type == COL) && (row->rtype == IDX_ROW_LIST) && row->dosort ){ + x = idxrownew(); + if( _idxstartsort(0, &(x->ichan), &(x->ochan), &(x->pid)) && + _idxwritesort(x, row) ){ + x->type = row->type; + /* doesn't matter which sort we use here */ + x->rtype = IDX_SORT; + x->dofilt = row->dofilt; + /* close input to start sort */ + close(x->ochan); + x->ochan = 0; + } + else{ + x->type = IDX_INDEF; + x->rtype = IDX_INDEF; + x->dofilt = 1; + } + } + /* everything else is fine as is */ + else{ + x = row; + } + IPRINTF((stderr, "idxall(%d): %s\n", x->dofilt, rowdisp(x))); + filt->idx = x; + return x; +} + +#ifdef ANSI_FUNC +void * +idxread(idxrowrec *row, GIO gio, FITSHead fits, + void *buf, size_t size, size_t get, size_t *got, int *dofilt) +#else + void *idxread(row, gio, fits, buf, size, get, got, dofilt) + idxrowrec *row; + GIO gio; + FITSHead fits; + void *buf; + size_t size; + size_t get; + size_t *got; + int *dofilt; +#endif +{ + int j, k=0; + int left; + int nrow; + int rowsize; + int ioffset; + int itype; + int isize; + int start, stop; + int *ibuf=NULL; + size_t i; + char nbuf[8]; + long ipos; + struct stat fbuf; + + /* initialize */ + *got = 0; + *dofilt = row->dofilt; + + /* handle particular io method */ + switch( idx_io ){ + case IDX_IO_MMAP: +#ifdef HAVE_SYS_MMAN_H + if( !row->fdata ){ + if( fstat(fileno(gio->fp), &fbuf) < 0 ){ + *got = 0; + idxerror("can't fstat data file"); + goto done; + } + row->flen = fbuf.st_size; + if( (row->fdata = mmap(NULL, row->flen, PROT_READ, MAP_PRIVATE, + fileno(gio->fp), 0)) == MAP_FAILED ){ + *got = 0; + idxerror("can't mmap data file"); + perror("mmap"); + goto done; + } + } +#else + idxerror("mmap not supported on this system"); +#endif + break; + case IDX_IO_LSEEK: + break; + } + + /* get rows */ + switch(row->rtype){ + case IDX_ROW_LIST: + if( !(ibuf = xcalloc(get, sizeof(int))) ){ + *got = 0; + idxerror("can't allocate index record buffer"); + goto done; + } + rowsize = ft_naxis(row->v->ifits, 1); + ioffset = row->v->ioffset; + itype = row->v->itype; + isize = ft_sizeof(row->v->itype); + for(left=get, i=0; (left>0) && (i<(size_t)row->nrow); i++){ + if( (row->startrow[i]<0) && (row->stoprow[i]<0) ) continue; + nrow = row->stoprow[i] - row->startrow[i] + 1; + if( left > nrow ){ + start = row->startrow[i]; + stop = row->stoprow[i]; + row->startrow[i] = -1; + row->stoprow[i] = -1; + *got += nrow; + left -= nrow; + } + else if( nrow == left ){ + start = row->startrow[i]; + stop = row->stoprow[i]; + row->startrow[i] = -1; + row->stoprow[i] = -1; + *got += nrow; + left = 0; + } + else{ + start = row->startrow[i]; + stop = start + left - 1; + row->startrow[i] += left; + *got += left; + left = 0; + } + for(j=start; j<=stop; j++){ + ipos = row->v->ifits->data + ((j-1)*rowsize) + ioffset; + switch( idx_io ){ + case IDX_IO_MMAP: + if( row->v->idata ){ +#ifdef HAVE_SYS_MMAN_H + memcpy(nbuf, &(row->v->idata[ipos]), isize); +#else + idxerror("mmap not supported on this system"); +#endif + break; + } + case IDX_IO_LSEEK: + if( gseek(row->v->igio, (off_t)ipos, 0) < 0 ){ + *got = 0; + idxerror("can't seek into index file"); + goto done; + } + if( !gread(row->v->igio, nbuf, isize, 1) ){ + *got = 0; + idxerror("can't read index file"); + goto done; + } + break; + } + switch(itype){ + case 'B': + ibuf[k++] = (int)*(unsigned char *)(nbuf); + break; + case 'I': + ibuf[k++] = (int)*(short *)_swap(nbuf,2); + break; + case 'U': + ibuf[k++] = (int)*(unsigned short *)_swap(nbuf,2); + break; + case 'J': + ibuf[k++] = (int)*(int *)_swap(nbuf,4); + break; + case 'V': + ibuf[k++] = (int)*(unsigned int *)_swap(nbuf,4); + break; + case 'K': + idxerror("64-bit integer not supported for index"); + break; + default: + *got = 0; + idxerror("illegal index data type"); + goto done; + } + } + } + /* now grab the row associated with each row value */ + for(i=0; i<*got; i++){ + /* grab desired row in index */ + ipos = fits->data + ((ibuf[i]-1)*size); + switch( idx_io ){ + case IDX_IO_MMAP: +#ifdef HAVE_SYS_MMAN_H + memcpy((char *)buf+(i*size), &(row->fdata[ipos]), size); +#else + idxerror("mmap not supported on this system"); +#endif + break; + case IDX_IO_LSEEK: + if( gseek(gio, (off_t)ipos, 0) < 0 ){ + return 0; + } + if( !gread(gio, (char *)buf+(i*size), size, 1) ){ + *got = i; + } + break; + } + } + break; + case IDX_SORT: + case IDX_OR_SORT: + case IDX_AND_SORT: + if( !row->ifile && !(row->ifile = fdopen(row->ichan, "r")) ){ + *got = 0; + idxerror("can't fdup input index records"); + goto done; + } + if( !(ibuf = xcalloc(get, sizeof(int))) ){ + *got = 0; + idxerror("can't allocate index record buffer"); + goto done; + } + /* read the row values */ + *got=fread(ibuf, sizeof(int), get, row->ifile); + /* now grab the row associated with each row value */ + for(i=0; i<*got; i++){ + /* grab desired row in index */ + ipos = fits->data + ((ibuf[i]-1)*size); + switch( idx_io ){ + case IDX_IO_MMAP: +#ifdef HAVE_SYS_MMAN_H + memcpy((char *)buf+(i*size), &(row->fdata[ipos]), size); +#else + idxerror("mmap not supported on this system"); +#endif + break; + case IDX_IO_LSEEK: + if( gseek(gio, (off_t)ipos, 0) < 0 ){ + return 0; + } + if( !gread(gio, (char *)buf+(i*size), size, 1) ){ + *got = i; + } + break; + } + } + break; + case IDX_INDEF: + default: + *dofilt = 1; + _gread(gio, (void *)buf, size, get, got); + break; + } + +done: + if( ibuf ) xfree(ibuf); + return (void *)buf; +} + +#ifdef ANSI_FUNC +idxrowrec *idxor(idxrowrec *row1, idxrowrec *row2) +#else +idxrowrec *idxor(row1, row2) + idxrowrec *row1, *row2; +#endif +{ + int i; + int nm=0; + int start=0, stop=0; + char *mbuf=NULL; + idxrowrec *x=NULL; + idxrowrec *r1, *r2;; + + x = idxrownew(); + if( (row1->type == IDX_INDEF) || (row2->type == IDX_INDEF) ){ + /* if we have an indef we will have to go through all of the rows. */ + x->type = IDX_INDEF; + x->rtype = IDX_INDEF; + x->dofilt = 1; + IPRINTF((stderr, "idxor(%d): INDEF %s\n", x->dofilt, rowdisp(x))); + return x; + } + if( (row1->type == COL) && (row2->type == COL) && + (row1->rtype == IDX_ROW_LIST) && (row2->rtype == IDX_ROW_LIST) && + row1->s && row2->s && !strcmp(row1->s, row2->s) ){ + IPRINTF((stderr, "idxor: %s %s", rowdisp(row1), rowdisp(row2))); + x->type = COL; + x->rtype = IDX_ROW_LIST; + x->dofilt = 0; + x->s = xstrdup(row1->s); + x->v = row1->v; + /* a bit quicker when we have a simple OR */ + if( (row1->nrow == 1) && (row2->nrow == 1) ){ + if( (row1->stoprow[0] < row2->startrow[0]) || + (row2->stoprow[0] < row1->startrow[0]) ){ + _idxrowaddrow(x, row1->startrow[0], row1->stoprow[0]); + _idxrowaddrow(x, row2->startrow[0], row2->stoprow[0]); + } + else{ + start = MIN(row1->startrow[0], row2->startrow[0]); + stop = MAX(row1->stoprow[0], row2->stoprow[0]); + _idxrowaddrow(x, start, stop); + } + IPRINTF((stderr, " =>(q) %s\n", rowdisp(x))); + return x; + } + idxrowmark(row1, row2, &mbuf, &nm); + for(i=0; i %s\n", rowdisp(x))); + return x; + } + else{ + if( (row1->type == REG) || (row2->type == REG) ){ + x->type = REG; + x->dofilt = 1; + } + else{ + x->type = COL; + x->dofilt = 0; + } + x->rtype = IDX_OR_SORT; + /* two row lists: we sort both at once */ + if( (row1->rtype == IDX_ROW_LIST) && (row2->rtype == IDX_ROW_LIST) ){ + IPRINTF((stderr, "idxor sort: %s %s\n", rowdisp(row1), rowdisp(row2))); + /* open sort program and return only unique records */ + if( !_idxstartsort(IDX_OR_SORT, &(x->ichan), &(x->ochan), &(x->pid)) || + !_idxwritesort(x, row1) || !_idxwritesort(x, row2) ){ + x->type = IDX_INDEF; + x->rtype = IDX_INDEF; + x->dofilt = 1; + return x; + } + /* close input to start sort */ + close(x->ochan); + x->ochan = 0; + /* return here */ + return x; + } + /* at least one sorted process: we set up a merge (and maybe a sort) */ + else if( row1->rtype == IDX_ROW_LIST ){ + IPRINTF((stderr, "idxor sort/merge: %s %s\n", + rowdisp(row1), rowdisp(row2))); + r1 = row2; + r2 = idxrownew(); + r2->type = row1->type; + r2->rtype = row1->rtype; + r2->s = xstrdup(row1->s); + r2->dofilt = row1->dofilt; + /* open sort program to return all records */ + if( !_idxstartsort(0, &(r2->ichan), &(r2->ochan), &(r2->pid)) || + !_idxwritesort(r2, row1) ){ + x->type = IDX_INDEF; + x->rtype = IDX_INDEF; + x->dofilt = 1; + return x; + } + /* close input to start sort */ + close(r2->ochan); + r2->ochan = 0; + /* common merge code */ + return _idxrowmerge(x, r1, r2, IDX_OR_SORT); + } + /* at least one sorted process: we set up a merge (and maybe a sort) */ + else if( row2->rtype == IDX_ROW_LIST ){ + r1 = row1; + IPRINTF((stderr, "idxor sort/merge: %s %s\n", + rowdisp(row1), rowdisp(row2))); + r2 = idxrownew(); + r2->type = row2->type; + r2->rtype = row2->rtype; + r2->s = xstrdup(row2->s); + r2->dofilt = row2->dofilt; + /* open sort program to return all records */ + if( !_idxstartsort(0, &(r2->ichan), &(r2->ochan), &(r2->pid)) || + !_idxwritesort(r2, row2) ){ + x->type = IDX_INDEF; + x->rtype = IDX_INDEF; + x->dofilt = 1; + return x; + } + /* close input to start sort */ + close(r2->ochan); + r2->ochan = 0; + /* common merge code */ + return _idxrowmerge(x, r1, r2, IDX_OR_SORT); + } + else{ + return _idxrowmerge(x, row1, row2, IDX_OR_SORT); + } + } +} + +#ifdef ANSI_FUNC +idxrowrec *idxand(idxrowrec *row1, idxrowrec *row2) +#else +idxrowrec *idxand(row1, row2) + idxrowrec *row1, *row2; +#endif +{ + int i; + int nm=0; + int start=0, stop=0; + char *mbuf=NULL; + idxrowrec *x=NULL; + idxrowrec *r1, *r2; + + if( (row1->type == IDX_INDEF) || (row2->type == IDX_INDEF) ){ + /* if we have an indef we return the other row and turn dofilter on. + this works with AND but not with OR */ + if( (row1->type != IDX_INDEF) ){ + x = row1; + x->dofilt = 1; + } + else if( (row2->type != IDX_INDEF) ){ + x = row2; + x->dofilt = 1; + } + /* can't happen */ + else{ + x = idxrownew(); + x->type = IDX_INDEF; + x->rtype = IDX_INDEF; + x->dofilt = 1; + } + IPRINTF((stderr, "idxand(%d): INDEF %s\n", x->dofilt, rowdisp(x))); + return x; + } + x = idxrownew(); + if( (row1->type == COL) && (row2->type == COL) && + (row1->rtype == IDX_ROW_LIST) && (row2->rtype == IDX_ROW_LIST) && + row1->s && row2->s && !strcmp(row1->s, row2->s) ){ + IPRINTF((stderr, "idxand: %s %s", rowdisp(row1), rowdisp(row2))); + x->type = COL; + x->rtype = IDX_ROW_LIST; + x->dofilt = 0; + x->s = xstrdup(row1->s); + x->v = row1->v; + /* a bit quicker when we have a simple AND */ + if( (row1->nrow == 1) && (row2->nrow == 1) ){ + start = MAX(row1->startrow[0], row2->startrow[0]); + stop = MIN(row1->stoprow[0], row2->stoprow[0]); + if( start <= stop ){ + _idxrowaddrow(x, start, stop); + } + IPRINTF((stderr, " =>(q) %s\n", rowdisp(x))); + return x; + } + idxrowmark(row1, row2, &mbuf, &nm); + for(i=0; i %s\n", rowdisp(x))); + return x; + } + else{ + if( (row1->type == REG) || (row2->type == REG) ){ + x->type = REG; + x->dofilt = 1; + } + else{ + x->type = COL; + x->dofilt = 0; + } + x->rtype = IDX_OR_SORT; + /* two row lists: we sort both at once */ + if( (row1->rtype == IDX_ROW_LIST) && (row2->rtype == IDX_ROW_LIST) ){ + IPRINTF((stderr, "idxand sort: %s %s\n", rowdisp(row1), rowdisp(row2))); + /* open sort program and return only dup records */ + if( !_idxstartsort(IDX_AND_SORT, &(x->ichan), &(x->ochan), &(x->pid)) || + !_idxwritesort(x, row1) || !_idxwritesort(x, row2) ){ + x->type = IDX_INDEF; + x->rtype = IDX_INDEF; + x->dofilt = 1; + return x; + } + /* close input to start sort */ + close(x->ochan); + x->ochan = 0; + /* return here */ + return x; + } + /* at least one sorted process: we set up a merge (and maybe a sort) */ + else if( row1->rtype == IDX_ROW_LIST ){ + IPRINTF((stderr, "idxor sort/merge: %s %s\n", + rowdisp(row1), rowdisp(row2))); + r1 = row2; + r2 = idxrownew(); + r2->type = row1->type; + r2->rtype = row1->rtype; + r2->s = xstrdup(row1->s); + r2->dofilt = row1->dofilt; + /* open sort program to return all records */ + if( !_idxstartsort(0, &(r2->ichan), &(r2->ochan), &(r2->pid)) || + !_idxwritesort(r2, row1) ){ + x->type = IDX_INDEF; + x->rtype = IDX_INDEF; + x->dofilt = 1; + return x; + } + /* close input to start sort */ + close(r2->ochan); + r2->ochan = 0; + /* common merge code */ + return _idxrowmerge(x, r1, r2, IDX_AND_SORT); + } + /* at least one sorted process: we set up a merge (and maybe a sort) */ + else if( row2->rtype == IDX_ROW_LIST ){ + r1 = row1; + IPRINTF((stderr, "idxor sort/merge: %s %s\n", + rowdisp(row1), rowdisp(row2))); + r2 = idxrownew(); + r2->type = row2->type; + r2->rtype = row2->rtype; + r2->s = xstrdup(row2->s); + r2->dofilt = row2->dofilt; + /* open sort program to return all records */ + if( !_idxstartsort(0, &(r2->ichan), &(r2->ochan), &(r2->pid)) || + !_idxwritesort(r2, row2) ){ + x->type = IDX_INDEF; + x->rtype = IDX_INDEF; + x->dofilt = 1; + return x; + } + /* close input to start sort */ + close(r2->ochan); + r2->ochan = 0; + /* common merge code */ + return _idxrowmerge(x, r1, r2, IDX_AND_SORT); + } + else{ + return _idxrowmerge(x, row1, row2, IDX_AND_SORT); + } + } +} + +#ifdef ANSI_FUNC +idxrowrec *idxrowreg(idxvalrec *val) +#else +idxrowrec *idxrowreg(idxvalrec *val) + idxvalrec *val; +#endif +{ + int i=0, j=0; + idxrowrec *x=NULL; + idxrowrec *r[2]; + int start[2], stop[2]; + + x = idxrownew(); + if( (val->type == INDEF) || + ((val->rv[0]->type == INDEF) && (val->rv[1]->type == INDEF)) ){ + x->type = IDX_INDEF; + x->rtype = IDX_INDEF; + x->dofilt = 1; + return x; + } + for(i=0; i<2; i++){ + r[i] = idxrownew(); + /* handle case where one of the regions has no index */ + if( val->rv[i]->type == INDEF ){ + r[i]->type = IDX_INDEF; + r[i]->rtype = IDX_INDEF; + r[i]->dofilt = 1; + continue; + } + /* j will be the index of the valid val record we use in the output row */ + j = i; + r[i]->type = REG; + r[i]->rtype = IDX_ROW_LIST; + r[i]->s = xstrdup(val->rv[i]->s); + r[i]->v = val->rv[i]; + start[i] = _idxbsearch(val->rv[i]->igio, + val->rv[i]->ifits, val->rv[i]->vtype, + val->rv[i]->voffset, val->rv[i]->vn, + 0, -1, val->rlo[i], (longlong)0, PARSE_FLOAT); + stop[i] = _idxbsearch(val->rv[i]->igio, + val->rv[i]->ifits, val->rv[i]->vtype, + val->rv[i]->voffset, val->rv[i]->vn, + 0, 1, val->rhi[i], (longlong)0, PARSE_FLOAT); + if( (start[i] > 0) && (stop[i] > 0) ){ + _idxrowaddrow(r[i], start[i], stop[i]); + } + } + x = idxand(r[0], r[1]); + x->type = REG; + x->dofilt = 1; + x->v = val->rv[j]; + return x; +} + +#ifdef ANSI_FUNC +idxrowrec *idxrowfun(idxvalrec *UNUSED(val)) +#else +idxrowrec *idxrowfun(idxvalrec *val) + idxvalrec *val; +#endif +{ + idxrowrec *x=NULL; + + x = idxrownew(); + x->type = IDX_INDEF; + x->rtype = IDX_INDEF; + x->dofilt = 1; + return x; +} + +#ifdef ANSI_FUNC +idxrowrec *idxroweq(idxvalrec *val1, idxvalrec *val2) +#else +idxrowrec *idxroweq(val1, val2) + idxvalrec *val1, *val2; +#endif +{ + int start, stop; + int nrow; + idxrowrec *x=NULL; + + if( (val1->type == NUM) && (val2->type == COL) ){ + return idxroweq(val2, val1); + } + IPRINTF((stderr, "idxeq: ")); + if( _idxrowcommon(val1, val2, 1, IDX_EDGE_BOTH, &x, &start, &stop, &nrow) ){ + IPRINTF((stderr, "%s start=%d,stop=%d", x->s, start, stop)); + if( (start > 0) && (stop > 0) ){ + _idxrowaddrow(x, start, stop); + } + IPRINTF((stderr, " => ")); + } + IPRINTF((stderr, "%s\n", rowdisp(x))); + /* this is the only operator resulting in a sorted range list */ + x->dosort = 0; + return x; +} + +#ifdef ANSI_FUNC +idxrowrec *idxrowne(idxvalrec *val1, idxvalrec *val2) +#else +idxrowrec *idxrowne(val1, val2) + idxvalrec *val1, *val2; +#endif +{ + int start, stop; + int nrow; + int i=0; + idxrowrec *x=NULL; + + if( (val1->type == NUM) && (val2->type == COL) ){ + return idxrowne(val2, val1); + } + IPRINTF((stderr, "idxne: ")); + if( _idxrowcommon(val1, val2, 0, IDX_EDGE_BOTH, &x, &start, &stop, &nrow) ){ + IPRINTF((stderr, "%s start=%d,stop=%d", x->s, start, stop)); + if( start > 1 ){ + _idxrowaddrow(x, 1, start-1); + i++; + } + if( stop && (stop < nrow) ){ + _idxrowaddrow(x, stop+1, nrow); + IPRINTF((stderr, " start=%d,stop=%d", x->startrow[i], x->stoprow[i])); + } + IPRINTF((stderr, " => ")); + } + IPRINTF((stderr, "%s\n", rowdisp(x))); + return x; +} + +#ifdef ANSI_FUNC +idxrowrec *idxrowlt(idxvalrec *val1, idxvalrec *val2) +#else +idxrowrec *idxrowlt(val1, val2) + idxvalrec *val1, *val2; +#endif +{ + int start, stop; + int nrow; + int i=0; + idxrowrec *x=NULL; + + if( (val1->type == NUM) && (val2->type == COL) ){ + return idxrowgt(val2, val1); + } + IPRINTF((stderr, "idxlt: ")); + if( _idxrowcommon(val1, val2, 0, IDX_EDGE_LEFT, &x, &start, &stop, &nrow) ){ + IPRINTF((stderr, "%s start=%d,stop=%d", x->s, start, stop)); + if( start > 1 ){ + _idxrowaddrow(x, 1, start-1); + i++; + } + IPRINTF((stderr, " => ")); + } + IPRINTF((stderr, "%s\n", rowdisp(x))); + return x; +} + +#ifdef ANSI_FUNC +idxrowrec *idxrowle(idxvalrec *val1, idxvalrec *val2) +#else +idxrowrec *idxrowle(val1, val2) + idxvalrec *val1, *val2; +#endif +{ + int start, stop; + int nrow; + idxrowrec *x=NULL; + + if( (val1->type == NUM) && (val2->type == COL) ){ + return idxrowge(val2, val1); + } + IPRINTF((stderr, "idxle: ")); + if( _idxrowcommon(val1, val2, 0, IDX_EDGE_RIGHT, &x, &start, &stop, &nrow) ){ + IPRINTF((stderr, "%s start=%d,stop=%d", x->s, start, stop)); + if( stop > 0 ){ + _idxrowaddrow(x, 1, stop); + } + IPRINTF((stderr, " => ")); + } + IPRINTF((stderr, "%s\n", rowdisp(x))); + return x; +} + +#ifdef ANSI_FUNC +idxrowrec *idxrowgt(idxvalrec *val1, idxvalrec *val2) +#else +idxrowrec *idxrowgt(val1, val2) + idxvalrec *val1, *val2; +#endif +{ + int start, stop; + int nrow; + int i=0; + idxrowrec *x=NULL; + + if( (val1->type == NUM) && (val2->type == COL) ){ + return idxrowlt(val2, val1); + } + IPRINTF((stderr, "idxgt: ")); + if( _idxrowcommon(val1, val2, 0, IDX_EDGE_RIGHT, &x, &start, &stop, &nrow) ){ + IPRINTF((stderr, "%s start=%d,stop=%d ", x->s, start, stop)); + if( (stop >= 0) && (stop < nrow) ){ + _idxrowaddrow(x, stop+1, nrow); + i++; + } + IPRINTF((stderr, " => ")); + } + IPRINTF((stderr, "%s\n", rowdisp(x))); + return x; +} + +#ifdef ANSI_FUNC +idxrowrec *idxrowge(idxvalrec *val1, idxvalrec *val2) +#else +idxrowrec *idxrowge(val1, val2) + idxvalrec *val1, *val2; +#endif +{ + int start, stop; + int nrow; + int i=0; + idxrowrec *x=NULL; + + if( (val1->type == NUM) && (val2->type == COL) ){ + return idxrowle(val2, val1); + } + IPRINTF((stderr, "idxge: ")); + if( _idxrowcommon(val1, val2, 0, IDX_EDGE_LEFT, &x, &start, &stop, &nrow) ){ + IPRINTF((stderr, "%s start=%d,stop=%d ", x->s, start, stop)); + if( (start > 0) && (start <= nrow) ){ + _idxrowaddrow(x, start, nrow); + i++; + } + IPRINTF((stderr, " => ")); + } + IPRINTF((stderr, "%s\n", rowdisp(x))); + return x; +} + +#ifdef ANSI_FUNC +idxvalrec *idxvaladd(idxvalrec *val1, idxvalrec *val2) +#else +idxvalrec *idxvaladd(val1, val2) + idxvalrec *val1, *val2; +#endif +{ + idxvalrec *x=NULL; + + x = idxvalnew(NULL); + if( (val1->type == NUM) && (val2->type == NUM) ){ + x->type = NUM; + if( (val1->ntype == PARSE_FLOAT) || (val2->ntype == PARSE_FLOAT) ){ + x->ntype = PARSE_FLOAT; + x->dval = val1->dval + val2->dval; + IPRINTF((stderr, "valadd: %f + %f => %f\n", + val1->dval, val2->dval, x->dval)); + } + else{ + x->ntype = PARSE_INTEGER; + x->ival = val1->ival + val2->ival; + x->dval = x->ival; + snprintf(fmt, SZ_LINE, "valadd: %s + %s => %s\n", LFMT, LFMT, LFMT); + IPRINTF((stderr, fmt, val1->ival, val2->ival, x->ival)); + } + } + else{ + x->type = INDEF; + } + return x; +} + +#ifdef ANSI_FUNC +idxvalrec *idxvalsub(idxvalrec *val1, idxvalrec *val2) +#else +idxvalrec *idxvalsub(val1, val2) + idxvalrec *val1, *val2; +#endif +{ + idxvalrec *x=NULL; + + x = idxvalnew(NULL); + if( (val1->type == NUM) && (val2->type == NUM) ){ + x->type = NUM; + if( (val1->ntype == PARSE_FLOAT) || (val2->ntype == PARSE_FLOAT) ){ + x->ntype = PARSE_FLOAT; + x->dval = val1->dval - val2->dval; + IPRINTF((stderr, "valsub: %f - %f => %f\n", + val1->dval, val2->dval, x->dval)); + } + else{ + x->ntype = PARSE_INTEGER; + x->ival = val1->ival - val2->ival; + x->dval = x->ival; + snprintf(fmt, SZ_LINE, "valsub: %s - %s => %s\n", LFMT, LFMT, LFMT); + IPRINTF((stderr, fmt, val1->ival, val2->ival, x->ival)); + } + } + else{ + x->type = INDEF; + } + return x; +} + +#ifdef ANSI_FUNC +idxvalrec *idxvalmul(idxvalrec *val1, idxvalrec *val2) +#else +idxvalrec *idxvalmul(val1, val2) + idxvalrec *val1, *val2; +#endif +{ + idxvalrec *x=NULL; + + x = idxvalnew(NULL); + if( (val1->type == NUM) && (val2->type == NUM) ){ + x->type = NUM; + if( (val1->ntype == PARSE_FLOAT) || (val2->ntype == PARSE_FLOAT) ){ + x->ntype = PARSE_FLOAT; + x->dval = val1->dval * val2->dval; + IPRINTF((stderr, "valmul: %f * %f => %f\n", + val1->dval, val2->dval, x->dval)); + } + else{ + x->ntype = PARSE_INTEGER; + x->ival = val1->ival * val2->ival; + x->dval = x->ival; + snprintf(fmt, SZ_LINE, "valmul: %s * %s => %s\n", LFMT, LFMT, LFMT); + IPRINTF((stderr, fmt, val1->ival, val2->ival, x->ival)); + } + } + else{ + x->type = INDEF; + } + return x; +} + +#ifdef ANSI_FUNC +idxvalrec *idxvaldiv(idxvalrec *val1, idxvalrec *val2) +#else +idxvalrec *idxvaldiv(val1, val2) + idxvalrec *val1, *val2; +#endif +{ + idxvalrec *x=NULL; + + x = idxvalnew(NULL); + if( (val1->type == NUM) && (val2->type == NUM) ){ + x->type = NUM; + if( val2->dval == 0.0 ) + idxerror("can't divide by zero"); + if( (val1->ntype == PARSE_FLOAT) || (val2->ntype == PARSE_FLOAT) ){ + x->dval = val1->dval / val2->dval; + x->ntype = PARSE_FLOAT; + } + else{ + x->ival = val1->ival / val2->ival; + x->ntype = PARSE_INTEGER; + } + IPRINTF((stderr, "valdiv: %f / %f => %f\n", + val1->dval, val2->dval, x->dval)); + } + else{ + x->type = INDEF; + } + return x; +} + +#ifdef ANSI_FUNC +idxvalrec *idxvalmod(idxvalrec *val1, idxvalrec *val2) +#else +idxvalrec *idxvalmod(val1, val2) + idxvalrec *val1, *val2; +#endif +{ + idxvalrec *x=NULL; + + x = idxvalnew(NULL); + if( (val1->type == NUM) && (val2->type == NUM) ){ + x->type = NUM; + if( (val1->ntype == PARSE_FLOAT) || (val2->ntype == PARSE_FLOAT) ){ + idxerror("can't use mod operator with floating point value"); + } + else{ + x->ntype = PARSE_INTEGER; + x->ival = val1->ival % val2->ival; + x->dval = x->ival; + snprintf(fmt, SZ_LINE, "valmod: %s mod %s => %s\n", LFMT, LFMT, LFMT); + IPRINTF((stderr, fmt, val1->ival, val2->ival, x->ival)); + } + } + else{ + x->type = INDEF; + } + return x; +} + +#ifdef ANSI_FUNC +idxvalrec *idxvaland(idxvalrec *val1, idxvalrec *val2) +#else +idxvalrec *idxvaland(val1, val2) + idxvalrec *val1, *val2; +#endif +{ + idxvalrec *x=NULL; + + x = idxvalnew(NULL); + if( (val1->type == NUM) && (val2->type == NUM) ){ + x->type = NUM; + x->ntype = PARSE_INTEGER; + if( (val1->ntype == PARSE_FLOAT) || (val2->ntype == PARSE_FLOAT) ) + x->ival = (longlong)val1->dval & (longlong)val2->dval; + else + x->ival = val1->ival & val2->ival; + x->dval = x->ival; + snprintf(fmt, SZ_LINE, "valand: %s & %s => %s\n", LFMT, LFMT, LFMT); + IPRINTF((stderr, fmt, val1->ival, val2->ival, x->ival)); + } + else{ + x->type = INDEF; + } + return x; +} + +#ifdef ANSI_FUNC +idxvalrec *idxvalor(idxvalrec *val1, idxvalrec *val2) +#else +idxvalrec *idxvalor(val1, val2) + idxvalrec *val1, *val2; +#endif +{ + idxvalrec *x=NULL; + + x = idxvalnew(NULL); + if( (val1->type == NUM) && (val2->type == NUM) ){ + x->type = NUM; + x->ntype = PARSE_INTEGER; + if( (val1->ntype == PARSE_FLOAT) || (val2->ntype == PARSE_FLOAT) ) + x->ival = (longlong)val1->dval | (longlong)val2->dval; + else + x->ival = val1->ival | val2->ival; + x->dval = x->ival; + snprintf(fmt, SZ_LINE, "valor: %s | %s => %s\n", LFMT, LFMT, LFMT); + IPRINTF((stderr, fmt, val1->ival, val2->ival, x->ival)); + } + else{ + x->type = INDEF; + } + return x; +} + +#ifdef ANSI_FUNC +idxvalrec *idxvalxor(idxvalrec *val1, idxvalrec *val2) +#else +idxvalrec *idxvalxor(val1, val2) + idxvalrec *val1, *val2; +#endif +{ + idxvalrec *x=NULL; + + x = idxvalnew(NULL); + if( (val1->type == NUM) && (val2->type == NUM) ){ + x->type = NUM; + x->ntype = PARSE_INTEGER; + if( (val1->ntype == PARSE_FLOAT) || (val2->ntype == PARSE_FLOAT) ) + x->ival = (longlong)val1->dval ^ (longlong)val2->dval; + else + x->ival = val1->ival ^ val2->ival; + x->dval = x->ival; + snprintf(fmt, SZ_LINE, "valxor: %s ^ %s => %s\n", LFMT, LFMT, LFMT); + IPRINTF((stderr, fmt, val1->ival, val2->ival, x->ival)); + } + else{ + x->type = INDEF; + } + return x; +} + +#ifdef ANSI_FUNC +idxvalrec *idxvalnot(idxvalrec *val) +#else +idxvalrec *idxvalnot(val) + idxvalrec *val; +#endif +{ + idxvalrec *x=NULL; + + x = idxvalnew(NULL); + x->type = NUM; + x->ntype = PARSE_INTEGER; + if( val->ntype == PARSE_FLOAT ) + x->ival = !val->dval; + else + x->ival = !val->ival; + x->dval = x->ival; + snprintf(fmt, SZ_LINE, "valnot: %s => %s\n", LFMT, LFMT); + IPRINTF((stderr, fmt, val->ival, x->ival)); + return x; +} + +#ifdef ANSI_FUNC +idxvalrec *idxvalcom(idxvalrec *val) +#else +idxvalrec *idxvalcom(val) + idxvalrec *val; +#endif +{ + idxvalrec *x=NULL; + + x = idxvalnew(NULL); + x->type = NUM; + x->ntype = PARSE_INTEGER; + if( val->ntype == PARSE_FLOAT ) + x->ival = ~(longlong)val->dval; + else + x->ival = ~val->ival; + x->dval = x->ival; + snprintf(fmt, SZ_LINE, "valcom: %s => %s\n", LFMT, LFMT); + IPRINTF((stderr, fmt, val->ival, x->ival)); + return x; +} + +#ifdef ANSI_FUNC +idxvalrec *idxvalmin(idxvalrec *val) +#else +idxvalrec *idxvalmin(val) + idxvalrec *val; +#endif +{ + idxvalrec *x=NULL; + + x = idxvalnew(NULL); + x->type = NUM; + x->ntype = val->ntype; + x->dval = -val->dval; + x->ival = -val->ival; + if( val->ntype == PARSE_FLOAT ){ + IPRINTF((stderr, "valmin: %f => %f\n", val->dval, x->dval)); + } + else{ + snprintf(fmt, SZ_LINE, "valmin: %s => %s\n", LFMT, LFMT); + IPRINTF((stderr, fmt, val->ival, x->ival)); + } + return x; +} + +#ifdef ANSI_FUNC +idxvalrec *idxvalnew(char *s) +#else +idxvalrec *idxvalnew(s) + char *s; +#endif +{ + idxvalrec *v=NULL; + Filter filt; + + if( !(filt = FilterDefault()) ) + idxerror("filter symbol table not initialized"); + if( !(v=xcalloc(1, sizeof(struct _idxvalrec))) ) + idxerror("can't allocate idxvalrec"); + if( s ) v->s = xstrdup(s); + v->next = filt->valhead; + filt->valhead = v; + return v; +} + + +#ifdef ANSI_FUNC +int idxvalfree(idxvalrec *v) +#else +int idxvalfree(v) + idxvalrec *v; +#endif +{ + idxvalrec *t; + int n=0; + Filter filt; + + if( !(filt = FilterDefault()) ) + idxerror("filter symbol table not initialized"); + if( v ){ + if( filt->valhead == v ){ + filt->valhead = v->next; + } + else{ + for(t=filt->valhead; t; t=t->next){ + if( t->next == v ){ + t->next = v->next; + break; + } + } + } + _idxvalfree(v); + n = 1; + } + else{ + for(v=filt->valhead; v; n++){ + t = v->next; + _idxvalfree(v); + v = t; + } + filt->valhead = NULL; + } + return n; +} + +#ifdef ANSI_FUNC +idxvalrec * +idxlookupfilename(char *iname) +#else +idxvalrec *idxlookupfilename(iname) + char *iname +#endif +{ + idxvalrec *t; + Filter filt; + + if( !(filt = FilterDefault()) ) + return NULL; + for(t=filt->valhead; t; t=t->next){ + if( t->iname && !strcmp(t->iname, iname) ){ + return t; + } + } + return NULL; +} + +#ifdef ANSI_FUNC +idxrowrec *idxrownew(void) +#else +idxrowrec *idxrownew() +#endif +{ + idxrowrec *r=NULL; + Filter filt; + + if( !(filt = FilterDefault()) ) + idxerror("filter symbol table not initialized"); + if( !(r=xcalloc(1, sizeof(struct _idxrowrec))) ) + idxerror("can't allocate idxrowrec"); + r->maxrow = IDX_ROW_INC; + r->startrow = xcalloc(r->maxrow, sizeof(int)); + r->stoprow = xcalloc(r->maxrow, sizeof(int)); + r->nrow = 0; + r->dosort = 1; + r->next = filt->rowhead; + filt->rowhead = r; + return r; +} + +#ifdef ANSI_FUNC +int idxrowfree(idxrowrec *r) +#else +int idxrowfree(r) + idxrowrec *r; +#endif +{ + idxrowrec *t; + int n=0; + Filter filt; + + if( !(filt = FilterDefault()) ) + idxerror("filter symbol table not initialized"); + if( r ){ + if( filt->rowhead == r ){ + filt->rowhead = r->next; + } + else{ + for(t=filt->rowhead; t; t=t->next){ + if( t->next == r ){ + t->next = r->next; + break; + } + } + } + _idxrowfree(r); + n = 1; + } + else{ + for(r=filt->rowhead; r; n++){ + t = r->next; + _idxrowfree(r); + r = t; + } + filt->rowhead = NULL; + } + return n; +} + +#ifdef ANSI_FUNC +int +idxinitfilenames(char *t, int *flag) +#else +int idxinitfilenames(t, flag) + char *t; + int *flag; +#endif +{ + char *u=NULL; + int havegz=0; + + /* initialize */ + if( flag ) *flag = 0; + /* free current values */ + idxfreefilenames(); + + /* sanity check */ + if( !t || !*t) return 0; + + if( (u=strchr(t, ':')) ){ + if( !strncasecmp(t, "pipe:", 5) || !strncasecmp(t, "mmap:", 5) || + !strncasecmp(t, "shm:", 4) || !strncasecmp(t, "mem:", 4) || + !strncasecmp(t, "buf:", 4) || !strncasecmp(t, "file:", 5) || + !strncasecmp(t, "gzip:", 5) || !strncasecmp(t, "unfile:", 7) ){ + t = u+1; + } + } + idxfilename = xstrdup(t); + if( (idxfileroot2=xstrdup(t)) ){ + if( (t=strrchr(idxfileroot2, '.')) ){ + if( !strcmp(t, ".gz") ){ + havegz=1; + *t = '\0'; + if( (t=strrchr(idxfileroot2, '.')) ){ + *t = '\0'; + } + } + else{ + *t = '\0'; + } + } + if( (t=strrchr(idxfileroot2, '/')) ){ + idxfileroot1 = xstrdup(t+1); + } + else{ + idxfileroot1 = xstrdup(idxfileroot2); + } + } + if( flag ) *flag = havegz; + return 1; +} + +#ifdef ANSI_FUNC +void +idxfreefilenames(void) +#else +void idxfreefilenames() +#endif +{ + if( idxfilename ){ + xfree(idxfilename); + idxfilename=NULL; + } + if( idxfileroot1 ){ + xfree(idxfileroot1); + idxfileroot1=NULL; + } + if( idxfileroot2 ){ + xfree(idxfileroot2); + idxfileroot2=NULL; + } +} + +#ifdef ANSI_FUNC +void +idxfreeglobals(void) +#else +void idxfreeglobals() +#endif +{ + if( idxcolname ){ + xfree(idxcolname); + idxcolname=NULL; + } + if( idxpath ){ + xfree(idxpath); + idxpath=NULL; + } + if( idxsort ){ + xfree(idxsort); + idxsort=NULL; + } + idxfreefilenames(); +} + +#ifdef ANSI_FUNC +char * +idxindexfilename(char *col, int *size) +#else +char *idxindexfilename(col, size) + char *col; + int *size; +#endif +{ + int i; + char *iname=NULL; + char *fname=NULL; + char *idxname=NULL; + char *suffix=""; + char colbuf[SZ_LINE]; + char tbuf[SZ_LINE]; + char tbuf1[SZ_LINE]; + char tbuf2[SZ_LINE]; + struct stat ibuf; + struct stat fbuf; + + /* sanity checks */ + if( !col ) return NULL; + if( !idxinfo(IDX_FILENAME) ) return NULL; + if( !idxinfo(IDX_FILEROOT1) || !idxinfo(IDX_FILEROOT2) ) return NULL; + + /* we try using the column name as is, in lower case, and in upper case */ + /* we also try with and without a .gz extension */ + strncpy(colbuf, col, SZ_LINE-1); + for(i=0; i<6; i++){ + switch(i){ + case 0: + break; + case 1: + culc(colbuf); + break; + case 2: + cluc(colbuf); + break; + case 3: + suffix=".gz"; + break; + case 4: + culc(colbuf); + suffix=".gz"; + break; + case 5: + cluc(colbuf); + suffix=".gz"; + break; + } + snprintf(tbuf1, SZ_LINE-1, "%s_%s.idx%s", idxinfo(IDX_FILEROOT1), + colbuf, suffix); + snprintf(tbuf2, SZ_LINE-1, "%s_%s.idx%s", idxinfo(IDX_FILEROOT2), + colbuf, suffix); + if( (iname=Find(tbuf1, "r", NULL, "." )) || + (iname=Find(tbuf1, "r", NULL, FilterPath())) || + (iname=Find(tbuf2, "r", NULL, "." )) || + (iname=Find(tbuf2, "r", NULL, FilterPath())) ){ + if( (fname=Find(idxinfo(IDX_FILENAME), "r", NULL, "." )) || + (fname=Find(idxinfo(IDX_FILENAME), "r", NULL, FilterPath())) ){ + if( (stat(fname, &fbuf) <0) || (stat(iname, &ibuf) <0) ){ + goto done; + } + else if( fbuf.st_mtime > ibuf.st_mtime ){ + goto done; + } + } + snprintf(tbuf, SZ_LINE-1, "%s[1]", iname); + idxname = xstrdup(tbuf); + break; + } + } + +done: + if( iname ) xfree(iname); + if( fname ) xfree(fname); + if( size ) *size = ibuf.st_size; + return idxname; +} + +#ifdef ANSI_FUNC +int +idxinitparser(char *s) +#else +int idxinitparser(s) + char *s; +#endif +{ + char *t; + int havegz=0; + Filter filt; + + /* sanity checks */ + if( !(filt = FilterDefault()) ) return 0; + if( !filt->fhd->filename ) return 0; + + /* initialize index file name info */ + idxinitfilenames(filt->fhd->filename, &havegz); + + /* process index environent */ + if( (t=getenv("FILTER_IDX_COLNAME")) ){ + idxcolname = xstrdup(t); + } + else{ + idxcolname = xstrdup("n"); + } + if( (t=getenv("FILTER_IDX_IO")) ){ + if( !strncasecmp(t, "mmap", 4) ){ +#ifdef HAVE_SYS_MMAN_H + idx_io = IDX_IO_MMAP; +#else + idx_io = IDX_IO_LSEEK; +#endif + } + else if( !strncasecmp(t, "lseek", 5) ){ + idx_io = IDX_IO_LSEEK; + } + else{ + idx_io = IDX_IO_DEFAULT; + } + } + /* oops ... if we have a gz file, we can't use mmap */ + if( havegz ){ + idx_io = IDX_IO_LSEEK; + } + if( s ) idxstring(s); + return 1; +} + +#ifdef ANSI_FUNC +void +idxendparser(void) +#else +void idxendparser() +#endif +{ + idxvalfree(NULL); + idxrowfree(NULL); + idxfreeglobals(); +} + +#ifdef ANSI_FUNC +char * +idxinfo(int which) +#else +char *idxinfo(which) + int which; +#endif +{ + switch(which){ + case IDX_COLNAME: + return idxcolname; + case IDX_FILENAME: + return idxfilename; + case IDX_FILEROOT1: + return idxfileroot1; + case IDX_FILEROOT2: + return idxfileroot2; + case IDX_PATHNAME: + return idxpath; + case IDX_SORTNAME: + return idxsort; + default: + return NULL; + } +} + +#ifdef ANSI_FUNC +int +idxdebug(int debug) +#else +int idxdebug(debug) + int debug; +#endif +{ + int odebug; + + odebug = idx_debug; + idx_debug = debug; + return odebug; +} diff --git a/filter/image_c.h b/filter/image_c.h new file mode 100644 index 0000000..4db125b --- /dev/null +++ b/filter/image_c.h @@ -0,0 +1 @@ +static char *IMAGE_C="\n\n#ifdef TEST\n#include \n#include \n#define IMFILTRTN _FilterImage\n#define NMASK 0\n#define MASKDIM 0\n#define _masks NULL\n#define NSHAPE 2\n#define NREGION 2\n#define FILTER ((imcircle(g,1,1,1,4,(double)x,(double)y,8.0,8.0,5.0)))&&(imcircle(g,2,2,0,1,(double)x,(double)y,8.0,8.0,3.0))\n#define FILTSTR \"((imcircle(g,1,1,1,4,(double)x,(double)y,8.0,8.0,5.0)))&&(imcircle(g,2,2,0,1,(double)x,(double)y,8.0,8.0,3.0))\"\n#define FINIT imcirclei(g,1,1,1,4,(double)x,(double)y,8.0,8.0,5.0);imcirclei(g,2,2,0,1,(double)x,(double)y,8.0,8.0,3.0);\n#include \"regions.h\"\n#endif\n\n\nFilterMask masks=NULL; \nint maxmask; \nint nmask; \nint nreg; \nint rid; \nint x, y; \nint rlen; \nint *rbuf; \nint *rptr; \n\nvoid incnmask(void)\n{\n int omax;\n nmask++;\n if( nmask >= maxmask ){\n omax = maxmask;\n maxmask += MASKINC;\n masks = (FilterMask)realloc(masks, maxmask*sizeof(FilterMaskRec));\n memset(masks+omax, 0, (maxmask-omax)*sizeof(FilterMaskRec));\n }\n}\n\nFilterMask\nIMFILTRTN(int txmin, int txmax, int tymin, int tymax, int tblock, int *got)\n{\n int i, j;\n int fieldonly;\n GFilt g;\n Scan scan, tscan;\n\n \n if( NSHAPE <=0 ){\n *got = 0;\n return NULL;\n }\n \n g = (GFilt)calloc(1, sizeof(GFiltRec));\n \n fieldonly = (NSHAPE==1) && strstr(FILTSTR, \"field\");\n \n g->nshapes = NSHAPE;\n g->maxshapes = (NSHAPE*(XSNO+1))+1;\n g->shapes = (Shape)calloc(g->maxshapes, sizeof(ShapeRec));\n \n g->block= max(1,tblock);\n g->xmin = max(1,txmin); \n g->xmax = txmax;\n g->ymin = max(1,tymin);\n g->ymax = tymax;\n \n g->x0 = 1;\n g->y0 = 1;\n g->x1 = (g->xmax-g->xmin)/g->block+1;\n g->y1 = (g->ymax-g->ymin)/g->block+1;\n \n rlen = g->x1 - g->x0 + 1;\n rbuf = (int *)calloc(rlen+1, sizeof(int));\n \n maxmask = MASKINC;\n masks = (FilterMask)calloc(maxmask, sizeof(FilterMaskRec));\n \n nmask = 0;\n masks[nmask].region = 0;\n \n nreg = 0;\n \n g->ybuf = (int *)calloc(g->y1+1, sizeof(int));\n g->x0s = (int *)calloc(g->y1+1, sizeof(int));\n g->x1s = (int *)calloc(g->y1+1, sizeof(int));\n \n for(i=0; i<=g->y1; i++) g->x0s[i] = g->x1;\n for(i=0; i<=g->y1; i++) g->x1s[i] = g->x0;\n \n if( NMASK ){\n g->nmask = NMASK; \n g->maskdim = MASKDIM;\n g->masks = _masks;\n }\n \n FINIT;\n \n for(y=g->y0; y<=g->y1; y++){\n if( fieldonly ){\n \n masks[nmask].region = 1;\n masks[nmask].y = y - g->y0 + 1;\n masks[nmask].xstart = 1;\n masks[nmask].xstop = (g->x1 - g->x0 + 1);\n incnmask();\n continue;\n }\n if( g->ybuf[y] ){\n \n if( masks[nmask].region ){\n \n incnmask();\n masks[nmask].region = 0;\n }\n \n for(x=g->x0s[y], rptr=&rbuf[1+(g->x0s[y]-g->x0)]; x<=g->x1s[y];\n x++, rptr++){\n \n g->rid = 0;\n if( FILTER ){\n \n if( *rptr == 0 ){\n nreg++;\n *rptr = g->rid ? g->rid : -1;\n }\n \n else if( (*rptr == -1) && (g->rid >0) ){\n *rptr = g->rid;\n }\n }\n }\n }\n \n if( nreg ){\n for(i=1; i<=rlen; i++){\n if( rbuf[i] != masks[nmask].region ){\n \n if( masks[nmask].region ){\n masks[nmask].xstop = i - 1;\n \n incnmask();\n }\n masks[nmask].y = y - g->y0 + 1;\n masks[nmask].region = rbuf[i];\n masks[nmask].xstart = i;\n }\n }\n \n if( masks[nmask].region ){\n masks[nmask].xstop = (g->x1 - g->x0 + 1);\n \n incnmask();\n }\n \n (void)memset(rbuf, 0, (rlen+1)*sizeof(int));\n rptr = rbuf;\n nreg = 0;\n }\n }\n \n if( rbuf) free(rbuf);\n \n if( g ){\n for(i=0; imaxshapes; i++){\n if( g->shapes[i].scanlist ){\n for(j=0; j<=g->y1; j++){\n if( g->shapes[i].scanlist[j] ){\n for(scan=g->shapes[i].scanlist[j]; scan; ){\n tscan = scan->next;\n free(scan);\n scan = tscan;\n }\n }\n }\n free(g->shapes[i].scanlist);\n }\n if( g->shapes[i].pts ) free(g->shapes[i].pts);\n if( g->shapes[i].xv ) free(g->shapes[i].xv);\n }\n if( g->masks ) free(g->masks);\n if( g->shapes ) free(g->shapes);\n if( g->ybuf ) free(g->ybuf);\n if( g->x0s ) free(g->x0s);\n if( g->x1s ) free(g->x1s);\n if( g ) free(g);\n }\n \n *got = nmask;\n return masks;\n}\n\nint main(int argc, char **argv)\n{\n int i;\n int get, got;\n#if DO_FILTER_SWAP\n int sgot;\n#endif\n#if HAVE_MINGW32==0\n int pipes[4];\n#endif\n int txmin, txmax, tymin, tymax, tblock;\n char tbuf[SZ_LINE];\n char *s=NULL, *t=NULL, *u=NULL;\n#if USE_WIN32\n HANDLE hStdin, hStdout; \n DWORD dwRead, dwWritten; \n#endif\n\n \n#if HAVE_MINGW32==0\n if( (s=getenv(\"LAUNCH_PIPES\")) ){\n t = (char *)strdup(s);\n for(i=0, u=(char *)strtok(t, \",\"); i<4 && u; \n i++, u=(char *)strtok(NULL,\",\")){\n pipes[i] = atoi(u);\n }\n if( t ) free(t);\n if( i < 4 ) return(1);\n close(pipes[0]);\n close(pipes[3]);\n dup2(pipes[2], 0); close(pipes[2]);\n dup2(pipes[1], 1); close(pipes[1]);\n }\n#endif\n\n#if USE_WIN32\n hStdout = GetStdHandle(STD_OUTPUT_HANDLE); \n hStdin = GetStdHandle(STD_INPUT_HANDLE); \n if( (hStdout == INVALID_HANDLE_VALUE) || (hStdin == INVALID_HANDLE_VALUE) ){\n unlink(argv[0]);\n return 0;\n }\n#endif\n\n \n#ifdef TEST\n while( fgets(tbuf, SZ_LINE, stdin) ){\n#else\n#if USE_WIN32\n while((ReadFile(hStdin, &get, sizeof(int), &dwRead, NULL) != FALSE) && \n (dwRead == sizeof(int)) ){\n#else\n while( read(0, &get, sizeof(int)) == sizeof(int) ){\n#endif\n#if DO_FILTER_SWAP\n switch(sizeof(int)){\n case 2:\n _sw2((char *)&get,2,NULL,0);\n break;\n case 4:\n _sw4((char *)&get,4,NULL,0);\n break;\n case 8:\n _sw8((char *)&get,8,NULL,0);\n break;\n }\n#endif\n#if USE_WIN32\n if((ReadFile(hStdin, tbuf, get, &dwRead, NULL)==FALSE) || (dwRead != get))\n break;\n#else\n if(read(0, tbuf, get) != get) \n break;\n#endif\n#endif \n if(sscanf(tbuf, \"%d %d %d %d %d\",\n &txmin, &txmax, &tymin, &tymax, &tblock)!=5){\n break;\n }\n masks = IMFILTRTN(txmin, txmax, tymin, tymax, tblock, &got);\n#ifdef TEST\n \n fprintf(stdout, \"nmask=%d\\n\", nmask);\n for(i=0; i +#include +#define IMFILTRTN _FilterImage +#define NMASK 0 +#define MASKDIM 0 +#define _masks NULL +#define NSHAPE 2 +#define NREGION 2 +#define FILTER ((imcircle(g,1,1,1,4,(double)x,(double)y,8.0,8.0,5.0)))&&(imcircle(g,2,2,0,1,(double)x,(double)y,8.0,8.0,3.0)) +#define FILTSTR "((imcircle(g,1,1,1,4,(double)x,(double)y,8.0,8.0,5.0)))&&(imcircle(g,2,2,0,1,(double)x,(double)y,8.0,8.0,3.0))" +#define FINIT imcirclei(g,1,1,1,4,(double)x,(double)y,8.0,8.0,5.0);imcirclei(g,2,2,0,1,(double)x,(double)y,8.0,8.0,3.0); +#include "regions.h" +#endif + +/* these are global for use with special region routines */ +FilterMask masks=NULL; /* array valid region masks for one row */ +int maxmask; /* max masks allocated thus far */ +int nmask; /* number of mask segments */ +int nreg; /* number of regions in this set of rows */ +int rid; /* first valid region for current pixel */ +int x, y; /* current row and column */ +int rlen; /* length of temp region buf */ +int *rbuf; /* temp region flags */ +int *rptr; /* pointer into region buffer */ + +void incnmask(void) +{ + int omax; + nmask++; + if( nmask >= maxmask ){ + omax = maxmask; + maxmask += MASKINC; + masks = (FilterMask)realloc(masks, maxmask*sizeof(FilterMaskRec)); + memset(masks+omax, 0, (maxmask-omax)*sizeof(FilterMaskRec)); + } +} + +FilterMask +IMFILTRTN(int txmin, int txmax, int tymin, int tymax, int tblock, int *got) +{ + int i, j; + int fieldonly; + GFilt g; + Scan scan, tscan; + + /* make sure we have something to process */ + if( NSHAPE <=0 ){ + *got = 0; + return NULL; + } + /* allocate space for the globals */ + g = (GFilt)calloc(1, sizeof(GFiltRec)); + /* see if we have only the field shape */ + fieldonly = (NSHAPE==1) && strstr(FILTSTR, "field"); + /* allocate region records */ + g->nshapes = NSHAPE; + g->maxshapes = (NSHAPE*(XSNO+1))+1; + g->shapes = (Shape)calloc(g->maxshapes, sizeof(ShapeRec)); + /* make sure we start at 1 */ + g->block= max(1,tblock); + g->xmin = max(1,txmin); + g->xmax = txmax; + g->ymin = max(1,tymin); + g->ymax = tymax; + /* get x and y limits on subsection */ + g->x0 = 1; + g->y0 = 1; + g->x1 = (g->xmax-g->xmin)/g->block+1; + g->y1 = (g->ymax-g->ymin)/g->block+1; + /* allocate a temp region buffer */ + rlen = g->x1 - g->x0 + 1; + rbuf = (int *)calloc(rlen+1, sizeof(int)); + /* allocate an array of masks, which will be written to caller */ + maxmask = MASKINC; + masks = (FilterMask)calloc(maxmask, sizeof(FilterMaskRec)); + /* seed the first region mask value */ + nmask = 0; + masks[nmask].region = 0; + /* keep track of how many hits we had for this set of rows */ + nreg = 0; + /* allocate a buffer for valid y row flags */ + g->ybuf = (int *)calloc(g->y1+1, sizeof(int)); + g->x0s = (int *)calloc(g->y1+1, sizeof(int)); + g->x1s = (int *)calloc(g->y1+1, sizeof(int)); + /* seed impossible values for x limits */ + for(i=0; i<=g->y1; i++) g->x0s[i] = g->x1; + for(i=0; i<=g->y1; i++) g->x1s[i] = g->x0; + /* save image mask values */ + if( NMASK ){ + g->nmask = NMASK; + g->maskdim = MASKDIM; + g->masks = _masks; + } + /* initialize ybuf */ + FINIT; + /* process all valid rows */ + for(y=g->y0; y<=g->y1; y++){ + if( fieldonly ){ + /* inc the mask count, (extend mask array, if necessary) */ + masks[nmask].region = 1; + masks[nmask].y = y - g->y0 + 1; + masks[nmask].xstart = 1; + masks[nmask].xstop = (g->x1 - g->x0 + 1); + incnmask(); + continue; + } + if( g->ybuf[y] ){ + /* to start this line, we make a seed mask with no region */ + if( masks[nmask].region ){ + /* inc the mask count, (extend mask array, if necessary) */ + incnmask(); + masks[nmask].region = 0; + } + /* process each pixel in this row where there is a region */ + for(x=g->x0s[y], rptr=&rbuf[1+(g->x0s[y]-g->x0)]; x<=g->x1s[y]; + x++, rptr++){ + /* get filter result, which is the region id or 0 */ + g->rid = 0; + if( FILTER ){ + /* never change a region id to a -1 */ + if( *rptr == 0 ){ + nreg++; + *rptr = g->rid ? g->rid : -1; + } + /* but always overwrite a -1 */ + else if( (*rptr == -1) && (g->rid >0) ){ + *rptr = g->rid; + } + } + } + } + /* if we have processed a row, make up the segments */ + if( nreg ){ + for(i=1; i<=rlen; i++){ + if( rbuf[i] != masks[nmask].region ){ + /* if previous was non-zero region, finish it and bump to next */ + if( masks[nmask].region ){ + masks[nmask].xstop = i - 1; + /* inc the mask count, (extend mask array, if necessary) */ + incnmask(); + } + masks[nmask].y = y - g->y0 + 1; + masks[nmask].region = rbuf[i]; + masks[nmask].xstart = i; + } + } + /* finish last non-zero segment, inc number of mask segs */ + if( masks[nmask].region ){ + masks[nmask].xstop = (g->x1 - g->x0 + 1); + /* inc the mask count, (extend mask array, if necessary) */ + incnmask(); + } + /* reset counters for next set of rows */ + (void)memset(rbuf, 0, (rlen+1)*sizeof(int)); + rptr = rbuf; + nreg = 0; + } + } + /* free buffers */ + if( rbuf) free(rbuf); + /* free region information */ + if( g ){ + for(i=0; imaxshapes; i++){ + if( g->shapes[i].scanlist ){ + for(j=0; j<=g->y1; j++){ + if( g->shapes[i].scanlist[j] ){ + for(scan=g->shapes[i].scanlist[j]; scan; ){ + tscan = scan->next; + free(scan); + scan = tscan; + } + } + } + free(g->shapes[i].scanlist); + } + if( g->shapes[i].pts ) free(g->shapes[i].pts); + if( g->shapes[i].xv ) free(g->shapes[i].xv); + } + if( g->masks ) free(g->masks); + if( g->shapes ) free(g->shapes); + if( g->ybuf ) free(g->ybuf); + if( g->x0s ) free(g->x0s); + if( g->x1s ) free(g->x1s); + if( g ) free(g); + } + /* return mask info */ + *got = nmask; + return masks; +} + +int main(int argc, char **argv) +{ + int i; + int get, got; +#if DO_FILTER_SWAP + int sgot; +#endif +#if HAVE_MINGW32==0 + int pipes[4]; +#endif + int txmin, txmax, tymin, tymax, tblock; + char tbuf[SZ_LINE]; + char *s=NULL, *t=NULL, *u=NULL; +#if USE_WIN32 + HANDLE hStdin, hStdout; + DWORD dwRead, dwWritten; +#endif + + /* Launch() sometimes rearranges passed pipes to be stdin/stdout */ +#if HAVE_MINGW32==0 + if( (s=getenv("LAUNCH_PIPES")) ){ + t = (char *)strdup(s); + for(i=0, u=(char *)strtok(t, ","); i<4 && u; + i++, u=(char *)strtok(NULL,",")){ + pipes[i] = atoi(u); + } + if( t ) free(t); + if( i < 4 ) return(1); + close(pipes[0]); + close(pipes[3]); + dup2(pipes[2], 0); close(pipes[2]); + dup2(pipes[1], 1); close(pipes[1]); + } +#endif + +#if USE_WIN32 + hStdout = GetStdHandle(STD_OUTPUT_HANDLE); + hStdin = GetStdHandle(STD_INPUT_HANDLE); + if( (hStdout == INVALID_HANDLE_VALUE) || (hStdin == INVALID_HANDLE_VALUE) ){ + unlink(argv[0]); + return 0; + } +#endif + + /* process requests for region information for sections of the image */ +#ifdef TEST + while( fgets(tbuf, SZ_LINE, stdin) ){ +#else +#if USE_WIN32 + while((ReadFile(hStdin, &get, sizeof(int), &dwRead, NULL) != FALSE) && + (dwRead == sizeof(int)) ){ +#else + while( read(0, &get, sizeof(int)) == sizeof(int) ){ +#endif +#if DO_FILTER_SWAP + switch(sizeof(int)){ + case 2: + _sw2((char *)&get,2,NULL,0); + break; + case 4: + _sw4((char *)&get,4,NULL,0); + break; + case 8: + _sw8((char *)&get,8,NULL,0); + break; + } +#endif +#if USE_WIN32 + if((ReadFile(hStdin, tbuf, get, &dwRead, NULL)==FALSE) || (dwRead != get)) + break; +#else + if(read(0, tbuf, get) != get) + break; +#endif +#endif /* #ifdef TEST */ + if(sscanf(tbuf, "%d %d %d %d %d", + &txmin, &txmax, &tymin, &tymax, &tblock)!=5){ + break; + } + masks = IMFILTRTN(txmin, txmax, tymin, tymax, tblock, &got); +#ifdef TEST + /* display segments for debugging */ + fprintf(stdout, "nmask=%d\n", nmask); + for(i=0; i +#endif + +#ifndef UNUSED +#ifdef __GNUC__ +# define UNUSED(x) UNUSED_ ## x __attribute__((__unused__)) +#else +# define UNUSED(x) UNUSED_ ## x +#endif +#endif + +/* panda and pie incorrectly used astronomical angles. fixed 4/2004 */ +#define USE_ASTRO_ANGLE 0 + +/* we might want to avoid (x86) extended precision problems */ +#define USE_FPU_DOUBLE 0 +#if USE_FPU_DOUBLE +#include +static fpu_control_t _cw; +#define FPU_DOUBLE {fpu_control_t _cw2; _FPU_GETCW(_cw); _cw2 = _cw & ~_FPU_EXTENDED; _cw2 |= _FPU_DOUBLE; _FPU_SETCW(_cw2);} +#define FPU_RESTORE {_FPU_SETCW(_cw);} +#else +#define FPU_DOUBLE +#define FPU_RESTORE +#endif + +/* add to FilterOpen to cause this module to be loaded for dynamic linking */ +static int imregno=0; +void initimregions(void) +{ + imregno++; + return; +} + +static void markx(GFilt g, int UNUSED(sno), int flag, int type, int x, int y) +{ + /* don't mark exclude regions */ + if( type == TOK_EREG ) + return; + /* for include, we might extend the x limits */ + if( flag ){ + if( x <= g->x0s[y] ) + g->x0s[y] = max(x,g->x0); + if( x >= g->x1s[y] ) + g->x1s[y] = min(x,g->x1); + } + /* for exclude, we have to look at the full line */ + else{ + g->x0s[y] = g->x0; + g->x1s[y] = g->x1; + } +} + +static void marky(GFilt g, int sno, int flag, int type) +{ + int i; + /* don't mark exclude regions */ + if( type == TOK_EREG ) + return; + /* mark include shape */ + if( flag ){ + for(i=max(g->y0,g->shapes[sno].ystart); + i<=min(g->y1,g->shapes[sno].ystop); + i++) + g->ybuf[i] = 1; + } + /* mark exclude shape */ + else{ + for(i=g->y0; i<=g->shapes[sno].ystart-1; i++) + g->ybuf[i] = 1; + for(i=g->shapes[sno].ystop+1; i<=g->y1; i++) + g->ybuf[i] = 1; + } +} + +static int +imagemaskcmp(const void *s1, const void *s2) +{ + FilterMask f1 = (FilterMask)s1; + FilterMask f2 = (FilterMask)s2; + + if( f1->y < f2->y ){ + return -1; + } + else if( f1->y > f2->y ){ + return 1; + } + else{ + if( f1->xstart < f2->xstart ){ + return -1; + } + else{ + return 1; + } + } +} + +/* ***************************** shape support ***************************** */ + +static void quadeq(double a, double b, double c, + double *x1, double *x2, int *nr, int *nc) +{ + double dis, q; + if( feq(a,0.0) ){ + *nc = 0; + if( feq(b,0.0) ){ + *nr = 0; *x1 = 0.0; + } + else{ + *nr = 1; *x1 = -c / b; + } + *x2 = *x1; + } + else{ + dis = b*b - 4.0 * a * c; + if( dis > 0.0 ){ + *nr = 2; *nc = 0; + dis = sqrt(dis); + if( b < 0.0 ) dis = -dis; + q = -0.5 * (b + dis); + *x1 = q/a; *x2 = c/q; + if(*x1 > *x2){ + q = *x1; *x1 = *x2; *x2 = q; + } + } + else if( feq(dis,0.0) ){ + *nr = 1; *nc = 0; *x1 = - 0.5 * b / a; *x2 = *x1; + } + else{ + *nr = 0; *nc = 2; *x1 = - 0.5 * b / a; *x2 = 0.5 * sqrt(-dis) / a; + } + } +} + +static void rgs_mark(GFilt g, Scan *scanlist, + int sno, int flag, int type, int xval, int yval ) +{ + Scan scanmark, mark; + /* since yval is used as an index, make sure its within limits */ + if(yval < g->y0) yval = g->y0; + if(yval > g->y1) yval = g->y1; + mark = (Scan)calloc(1, sizeof(ScanRec)); + mark->x = xval; + /* sanity check */ + if( !scanlist ) return; + /* starts are installed at back of list for given x */ + if( !scanlist[yval] || ((scanlist[yval])->x > xval) ){ + mark->next = scanlist[yval]; + scanlist[yval] = mark; + } else { + scanmark = scanlist[yval]; + while( scanmark->next && ((scanmark->next)->x < xval) ) + scanmark = scanmark->next; + mark->next = scanmark->next; + scanmark->next = mark; + } + markx(g, sno, flag, type, xval, yval); +} + +static void rgs_segment(GFilt g, Scan *scanlist, int width, int height, + int sno, int flag, int type, + double x1, double y1, double x2, double y2) +{ + int ystart, ystop, yval, xval; + double invslope, xoffset; + + ystart = PIXINCL(y1); + if( ystart < 1 ) ystart = 1; + /* note: PIXINCL(stop) is 1st pixel not counted */ + ystop = PIXINCL(y2) - 1; + if( ystop > height ) ystop = height; + /* ignore segment if there is no positive slope in integer coords */ + if( (ystart > ystop) || (ystop < 1) ) + return; + /* use inverse slope (run/rise) to get x given y with a multiply */ + invslope = (x1 - x2) / (y1 - y2); + xoffset = x1 + ((ystart - y1) * invslope); + for(yval=ystart; yval<=ystop; yval++){ + xval = PIXINCL(xoffset); + /* clip line to edges of image area (actually bend line) */ + if(xval < 1) xval = 1; + if(xval > width) xval = width + 1; + rgs_mark(g, scanlist, sno, flag, type, xval, yval); + xoffset = xoffset + invslope; + } +} + +static void _polygoni(GFilt g, int qt, int UNUSED(rno), int sno, int flag, + int type, double *vx, double *vy, int count) +{ + int i, j; + double xlo, xhi; + double ylo, yhi; + +#ifdef ALREADY_DONE + /* divide by block factor to get real endpoints */ + for(i=0; ixmin)/g->block + 1.0; + vy[i] = (vy[i] - g->ymin)/g->block + 1.0; + } +#endif + /* find the limits */ + xlo = vx[0]; + xhi = xlo; + ylo = vy[0]; + yhi = ylo; + for(i=0; i xhi) xhi = vx[i]; + if(vx[i] < xlo) xlo = vx[i]; + if(vy[i] > yhi) yhi = vy[i]; + if(vy[i] < ylo) ylo = vy[i]; + } + if( qt && (sno > 1) ){ + g->shapes[sno].ystart = g->shapes[sno-1].ystart; + g->shapes[sno].ystop = g->shapes[sno-1].ystop; + } + else{ + g->shapes[sno].ystart = max(g->y0,PIXINCL(ylo)); + g->shapes[sno].ystop = min(g->y1,PIXINCL(yhi) - 1); + } + g->shapes[sno].scanlist = (Scan *)calloc(g->y1+1, sizeof(Scan)); + marky(g, sno, flag, type); + + /* mark all horizontal segment crossings */ + /* start with segment between last and first point */ + j = count-1; + for(i=0; i vy[j]){ + rgs_segment(g, g->shapes[sno].scanlist, g->x1, g->y1, + sno, flag, type, vx[j], vy[j], vx[i], vy[i]); + } + else{ + rgs_segment(g, g->shapes[sno].scanlist, g->x1, g->y1, + sno, flag, type, vx[i], vy[i], vx[j], vy[j]); + } + j = i; + } +} + +static int corner_vertex(int index, int width, int height, + double *x, double *y) +{ + switch (index) { + case 1: + *x = 0.0; + *y = height + 1; + break; + case 2: + *x = 0.0; + *y = 0.0; + break; + case 3: + *x = width + 1; + *y = 0.0; + break; + case 4: + *x = width + 1; + *y = height + 1; + default: + break; + } + index = index + 1; + if(index > 4) index = 1; + return(index); +} + +static int pie_intercept(int width, int height, double xcen, double ycen, + double angle, double *xcept, double *ycept) +{ + double angl, slope; /* l: angle and slope of ray */ + angl = angle; + /* put angles in normal range */ + while (angl < 0.0) + angl = angl + 360.0; + while (angl >= 360.0) + angl = angl - 360.0; + /* check for a horizontal angle */ +#if USE_ASTRO_ANGLE + if(fabs(angl - 90.0) < SMALL_NUMBER) { +#else + if(fabs(angl - 180.0) < SMALL_NUMBER) { +#endif + *xcept = 0.0; + *ycept = ycen; + return(2); + } +#if USE_ASTRO_ANGLE + if(fabs(angl - 270.0) < SMALL_NUMBER) { +#else + if(fabs(angl - 0.0) < SMALL_NUMBER) { +#endif + *xcept = width + 1; + *ycept = ycen; + return(4); + } +#if USE_ASTRO_ANGLE + /* convert to a Cartesian angle */ + angl = angl + 90.0; +#endif + if(angl >= 360.0) + angl = angl - 360.0; + if(angl < 180.0) { + *ycept = height + 1; + /* rule out vertical line */ + if(fabs(angl - 90.0) < SMALL_NUMBER) { + *xcept = xcen; + return(1); + } + } else { + *ycept = 0.0; + /* rule out vertical line */ + if(fabs(angl - 270.0) < SMALL_NUMBER) { + *xcept = xcen; + return(3); + } + } + /* convert to radians */ + angl = (angl / 180.0) * M_PI; + /* calculate slope */ + slope = tan(angl); + /* calculate intercept with designated y edge */ + *xcept = xcen + ((*ycept - ycen) / slope); + if(*xcept < 0) { + *ycept = (ycen - (xcen * slope)); + *xcept = 0.0; + return(2); + } else if(*xcept > (width + 1)) { + *ycept = (ycen + ((width + 1 - xcen) * slope)); + *xcept = width + 1; + return(4); + } else { + if(*ycept < height) + return(3); + else + return(1); + } +} + +void _impiei(GFilt g, int qt, int rno, int sno, int flag, int type, + double UNUSED(x), double UNUSED(y), + double xcen, double ycen, double angle1, double angle2) +{ + int width, height; /* l: image mask width and height */ + double sweep; /* l: sweep between cut angles */ + double vx[7], vy[7]; /* l: arrays of vertices for polygon */ + int count; /* l: number of polygon vertices */ + int intrcpt1, intrcpt2; /* l: side intercepted by each cut */ + double x2, y2; /* l: coordinates of second intercept */ + + /* NB: do not use x and y variables, they have bogus values */ + /* divide by block factor to get "real" parameters */ + xcen = (xcen - g->xmin)/g->block + 1.0; + ycen = (ycen - g->ymin)/g->block + 1.0; + /* temps */ + width = g->x1; + height = g->y1; + /* start listing vertices of polygon */ + vx[0] = xcen; + vy[0] = ycen; + sweep = angle2 - angle1; + /* if sweep is too small to be noticed, don't bother */ + if(fabs(sweep) < SMALL_NUMBER) + return; + if (sweep < 0.0) sweep = sweep + 360.0; + intrcpt1 = pie_intercept(width, height, xcen, ycen, angle1, + &(vx[1]), &(vy[1])); + intrcpt2 = pie_intercept(width, height, xcen, ycen, angle2, + &x2, &y2); + count = 2; + /* if angles intercept same side and slice is between them, no corners */ + /* else, mark corners until reaching side with second angle intercept */ + if((intrcpt1 != intrcpt2) || (sweep > 180.0)){ + do{ + intrcpt1 = corner_vertex(intrcpt1, width, height, + &(vx[count]), &(vy[count])); + count = count + 1; + }while(intrcpt1 != intrcpt2); + } + vx[count] = x2; + vy[count] = y2; + count++; + _polygoni(g, qt, rno, sno, flag, type, vx, vy, count); +} + +/* ***************************** shapes ********************************** */ + +void imannulusi(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, double iradius, double oradius) +{ + int yy; + double dval; + double xoff, yoff; + Scan *scanlist; + + /* NB: do not use x and y variables, they have bogus values */ + + if( iradius == 0 ){ + imcirclei(g, rno, sno, flag, type, x, y, xcen, ycen, oradius); + return; + } + /* divide by block factor to get "real" parameters */ + xcen = (xcen - g->xmin)/g->block + 1.0; + ycen = (ycen - g->ymin)/g->block + 1.0; + iradius /= (double)g->block; + oradius /= (double)g->block; + /* set y limits */ + if( PIXSTART(ycen - oradius) < PIXSTOP(ycen + oradius) ){ + g->shapes[sno].ystart = max(g->y0,PIXSTART(ycen - oradius)); + g->shapes[sno].ystop = min(g->y1,PIXSTOP(ycen + oradius)); + } + else{ + g->shapes[sno].ystart = min(g->y1,PIXSTOP(ycen + oradius)); + g->shapes[sno].ystop = max(g->y0,PIXSTART(ycen - oradius)); + } + g->shapes[sno].scanlist = (Scan *)calloc(g->y1+1, sizeof(Scan)); + scanlist = g->shapes[sno].scanlist; + marky(g, sno, flag, type); + /* calculate start/stop values for each y line */ + for(yy=g->shapes[sno].ystart; yy<=g->shapes[sno].ystop; yy++){ + yoff = PIXCEN(yy) - ycen; + if( (dval=(oradius * oradius) - (yoff * yoff)) > 0.0 ){ + xoff = sqrt(dval); + if( PIXSTART(xcen - xoff) <= PIXSTOP(xcen + xoff) ){ + rgs_mark(g, scanlist, sno, flag, type, PIXSTART(xcen - xoff), yy); + rgs_mark(g, scanlist, sno, flag, type, PIXSTOP(xcen + xoff), yy); + } + if( (dval=(iradius * iradius) - (yoff * yoff)) > 0.0 ){ + xoff = sqrt(dval); + if( PIXSTART(xcen - xoff) <= PIXSTOP(xcen + xoff) ){ + rgs_mark(g, scanlist, sno, flag, type, PIXSTART(xcen - xoff), yy); + rgs_mark(g, scanlist, sno, flag, type, PIXSTOP(xcen + xoff), yy); + } + } + } + } +} + +int imannulus(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, double iradius, double oradius) +{ + Scan scan; + + if( iradius == 0 ){ + return(imcircle(g, rno, sno, flag, type, x, y, xcen, ycen, oradius)); + } + if( g->evsect ){ + if( g->usebinsiz ){ + x = (int)((x - g->tlminx)/g->binsizx + 1.0); + y = (int)((y - g->tlminy)/g->binsizy + 1.0); + } + else{ + x = (int)((x - g->tlminx) + 1.0); + y = (int)((y - g->tlminy) + 1.0); + } + x = (int)((x - g->xmin)/g->block + 1.0); + y = (int)((y - g->ymin)/g->block + 1.0); + if(y < g->y0) return 0; + if(y > g->y1) return 0; + if(x < g->x0) return 0; + if(x > g->x1) return 0; + } + if( flag ){ + if(y < g->shapes[sno].ystart ) return 0; + if(y > g->shapes[sno].ystop ) return 0; + } + scan = g->shapes[sno].scanlist[(int)y]; + if( (scan && + ((y >= g->shapes[sno].ystart) && (y <= g->shapes[sno].ystop)) && + (scan->next->next ? + (((x >= scan->x) && (x <= scan->next->next->next->x)) && + !((x >= scan->next->x) && (x <= scan->next->next->x))) : + ((x >= scan->x) && (x <= scan->next->x)))) + ==flag ){ + if( rno && flag ) g->rid = rno; + return 1; + } + else + return 0; +} + +void imboxi(GFilt g, int rno, int sno, int flag, int type, + double UNUSED(x), double UNUSED(y), + double xcen, double ycen, double xwidth, double yheight, + double angle) +{ + double angl; /* l: Cartesian angle in radians */ + double half_width, half_height;/* l: radii (1/2 width and height) */ + double cosangl, sinangl; /* l: sine, cosine of the Cartesian angle */ + double hw_cos, hw_sin; /* l: products of half_width with sin, cos */ + double hh_cos, hh_sin; /* l: products of half_height with sin, cos */ + double cornerx[4], cornery[4]; /* l: arrays of x and y coords of 4 corners */ + + /* NB: do not use x and y variables, they have bogus values */ + if( (xwidth == 0) && (yheight==0) ){ + return; + } + /* divide by block factor to get "real" parameters */ + xcen = (xcen - g->xmin)/g->block + 1.0; + ycen = (ycen - g->ymin)/g->block + 1.0; + xwidth /= (double)g->block; + yheight /= (double)g->block; +#if USE_ASTRO_ANGLE + /* convert to a Cartesian angle; save angle for use in multi or slices */ + angl = angle + 90.0; +#else + angl = angle; +#endif + while (angl >= 360.0) angl = angl - 360.0; + /* convert to radians */ + angl = (angl / 180.0) * M_PI; + sinangl = sin (angl); + cosangl = cos (angl); +#if USE_ASTRO_ANGLE + /* since we rotate by 90.0 degrees to get from astro angle to cartesian, */ + /* we also need to switch the width and height. we do this secretly so */ + /* that the display will turn out right, by doing it in the half terms */ + half_width = yheight / 2.0; + half_height = xwidth / 2.0; +#else + half_width = xwidth / 2.0; + half_height = yheight / 2.0; +#endif + hw_cos = half_width * cosangl; + hw_sin = half_width * sinangl; + hh_cos = half_height * cosangl; + hh_sin = half_height * sinangl; +#if USE_ASTRO_ANGLE + cornerx[0] = xcen - hw_cos - hh_sin; + cornery[0] = ycen - hw_sin + hh_cos; + cornerx[1] = xcen + hw_cos - hh_sin; + cornery[1] = ycen + hw_sin + hh_cos; + cornerx[2] = xcen + hw_cos + hh_sin; + cornery[2] = ycen + hw_sin - hh_cos; + cornerx[3] = xcen - hw_cos + hh_sin; + cornery[3] = ycen - hw_sin - hh_cos; +#else + cornerx[0] = xcen - hw_cos + hh_sin; + cornery[0] = ycen - hh_cos - hw_sin; + cornerx[1] = xcen - hw_cos - hh_sin; + cornery[1] = ycen + hh_cos - hw_sin; + cornerx[2] = xcen + hw_cos - hh_sin; + cornery[2] = ycen + hh_cos + hw_sin; + cornerx[3] = xcen + hw_cos + hh_sin; + cornery[3] = ycen - hh_cos + hw_sin; +#endif + _polygoni(g, 0, rno, sno, flag, type, cornerx, cornery, 4); +} + +int imbox(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double UNUSED(xcen), double UNUSED(ycen), + double xwidth, double yheight, + double UNUSED(angle)) +{ + if( (xwidth == 0) && (yheight==0) ){ + return(!flag); + } + return impolygon(g, rno, sno, flag, type, x, y); +} + +void imcirclei(GFilt g, int UNUSED(rno), int sno, int flag, int type, + double UNUSED(x), double UNUSED(y), + double xcen, double ycen, double radius) +{ + int yy; + double dval; + double xoff, yoff; + Scan *scanlist; + + /* NB: do not use x and y variables, they have bogus values */ + if( radius == 0 ){ + return; + } + /* divide by block factor to get "real" parameters */ + xcen = (xcen - g->xmin)/g->block + 1.0; + ycen = (ycen - g->ymin)/g->block + 1.0; + radius /= (double)g->block; + /* set y limits */ + if( PIXSTART(ycen - radius) < PIXSTOP(ycen + radius) ){ + g->shapes[sno].ystart = max(g->y0,PIXSTART(ycen - radius)); + g->shapes[sno].ystop = min(g->y1,PIXSTOP(ycen + radius)); + } + else{ + g->shapes[sno].ystart = min(g->y1,PIXSTOP(ycen + radius)); + g->shapes[sno].ystop = max(g->y0,PIXSTART(ycen - radius)); + } + g->shapes[sno].scanlist = (Scan *)calloc(g->y1+1, sizeof(Scan)); + scanlist = g->shapes[sno].scanlist; + marky(g, sno, flag, type); + /* calculate start/stop values for each y line */ + for(yy=g->shapes[sno].ystart; yy<=g->shapes[sno].ystop; yy++){ + yoff = PIXCEN(yy) - ycen; + if( (dval=(radius * radius) - (yoff * yoff))>=0.0 ){ + xoff = sqrt(dval); + if( PIXSTART(xcen - xoff) <= PIXSTOP(xcen + xoff) ){ + rgs_mark(g, scanlist, sno, flag, type, PIXSTART(xcen - xoff), yy); + rgs_mark(g, scanlist, sno, flag, type, PIXSTOP(xcen + xoff), yy); + } + } + } +} + +int imcircle(GFilt g, int rno, int sno, int flag, int UNUSED(type), + double x, double y, + double UNUSED(xcen), double UNUSED(ycen), double radius) +{ + Scan scan; + + if( radius == 0 ){ + return(!flag); + } + if( g->evsect ){ + if( g->usebinsiz ){ + x = (int)((x - g->tlminx)/g->binsizx + 1.0); + y = (int)((y - g->tlminy)/g->binsizy + 1.0); + } + else{ + x = (int)((x - g->tlminx) + 1.0); + y = (int)((y - g->tlminy) + 1.0); + } + x = (int)((x - g->xmin)/g->block + 1.0); + y = (int)((y - g->ymin)/g->block + 1.0); + if(y < g->y0) return 0; + if(y > g->y1) return 0; + if(x < g->x0) return 0; + if(x > g->x1) return 0; + } + if( flag ){ + if(y < g->shapes[sno].ystart ) return 0; + if(y > g->shapes[sno].ystop ) return 0; + } + scan = g->shapes[sno].scanlist[(int)y]; + if( (scan && + ((y>=g->shapes[sno].ystart) && (y<=g->shapes[sno].ystop)) && + ((x >= scan->x) && (x <= (scan->next)->x))) == flag ){ + if( rno && flag ) g->rid = rno; + return 1; + } + else{ + return 0; + } +} + +void imellipsei(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, double xrad, double yrad, + double angle) +{ + int yy; + int nr, nc; + double yhi; + double yoff; + double xboff, xfoff; + double angl; + double sinangl, cosangl; + double cossq, sinsq, xradsq, yradsq; + double a, b_partial, c_partial; + double b, c; + Scan *scanlist; + + /* NB: do not use x and y variables, they have bogus values */ + + if( xrad == yrad ){ + imcirclei(g, rno, sno, flag, type, x, y, xcen, ycen, xrad); + return; + } + /* divide by block factor to get "real" parameters */ + xcen = (xcen - g->xmin)/g->block + 1.0; + ycen = (ycen - g->ymin)/g->block + 1.0; + xrad /= (double)g->block; + yrad /= (double)g->block; + /* set worst case limits (xrad axis parallel to vertical axis) */ +#if USE_ASTRO_ANGLE + /* convert to a Cartesian angle; save "angle" for use by other routines */ + angl = angle + 90.0; +#else + angl = angle; +#endif + while( angl >= 360.0 ) + angl = angl - 360.0; + /* convert to radians */ + angl = (angl / 180.0) * M_PI; + sinangl = sin(angl); + cosangl = cos(angl); + /* calculate approximate y limits */ + /* choose lesser of containing rotbox and circle */ + FPU_DOUBLE +#if USE_ASTRO_ANGLE + yhi = fabs(sinangl * yrad) + fabs(cosangl * xrad); +#else + yhi = fabs(sinangl * xrad) + fabs(cosangl * yrad); +#endif + yhi = min(yhi, max(yrad, xrad)); + /* set y limits */ + if( PIXSTART(ycen - yhi) < PIXSTOP(ycen + yhi) ){ + g->shapes[sno].ystart = max(g->y0,PIXSTART(ycen - yhi)); + g->shapes[sno].ystop = min(g->y1,PIXSTOP(ycen + yhi)); + } + else{ + g->shapes[sno].ystart = min(g->y1,PIXSTOP(ycen + yhi)); + g->shapes[sno].ystop = max(g->y0,PIXSTART(ycen - yhi)); + } + FPU_RESTORE + g->shapes[sno].scanlist = (Scan *)calloc(g->y1+1, sizeof(Scan)); + scanlist = g->shapes[sno].scanlist; + marky(g, sno, flag, type); + /* prepare partials for quadratic equation solutions to coordinates */ + cossq = cosangl * cosangl; + sinsq = sinangl * sinangl; +#if USE_ASTRO_ANGLE + /* because we rotate by 90.0 degrees to get from astro angle to */ + /* cartesian, we also need to switch the x and y axes. we do this */ + /* secretly so that the display will turn out right, by doing it in */ + /* the sq terms */ + xradsq = yrad * yrad; + yradsq = xrad * xrad; +#else + xradsq = xrad * xrad; + yradsq = yrad * yrad; +#endif + /* fill in as much of a,b,c as we can */ + a = (cossq / xradsq) + (sinsq / yradsq); + b_partial = (2.0 * sinangl) * ((cosangl / xradsq) - (cosangl / yradsq)); + c_partial = (sinsq / xradsq) + (cossq / yradsq); + /* calculate start/stop values for each y line */ + for(yy=g->shapes[sno].ystart; yy<=g->shapes[sno].ystop; yy++){ + yoff = yy - ycen; + b = b_partial * yoff; + c = (c_partial * yoff * yoff) - 1.0; + /* solve quadratic */ + quadeq (a, b, c, &xboff, &xfoff, &nr, &nc); + /* if real roots */ + if( nr != 0 ) { + /* translate x coordinates */ + rgs_mark(g, scanlist, sno, flag, type, PIXSTART(xcen + xboff), yy); + rgs_mark(g, scanlist, sno, flag, type, PIXSTOP(xcen + xfoff), yy); + } + } +} + +int imellipse(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, double xrad, double yrad, + double UNUSED(angle)) +{ + Scan scan; + + if( xrad == yrad ){ + return(imcircle(g, rno, sno, flag, type, x, y, xcen, ycen, xrad)); + } + if( g->evsect ){ + if( g->usebinsiz ){ + x = (int)((x - g->tlminx)/g->binsizx + 1.0); + y = (int)((y - g->tlminy)/g->binsizy + 1.0); + } + else{ + x = (int)((x - g->tlminx) + 1.0); + y = (int)((y - g->tlminy) + 1.0); + } + x = (int)((x - g->xmin)/g->block + 1.0); + y = (int)((y - g->ymin)/g->block + 1.0); + if(y < g->y0) return 0; + if(y > g->y1) return 0; + if(x < g->x0) return 0; + if(x > g->x1) return 0; + } + if( flag ){ + if(y < g->shapes[sno].ystart ) return 0; + if(y > g->shapes[sno].ystop ) return 0; + } + scan = g->shapes[sno].scanlist[(int)y]; + FPU_DOUBLE + if( (scan && + ((y>=g->shapes[sno].ystart) && (y<=g->shapes[sno].ystop)) && + ((x >= scan->x) && (x <= (scan->next)->x))) == flag ){ + if( rno && flag ) g->rid = rno; + FPU_RESTORE + return 1; + } + else{ + FPU_RESTORE + return 0; + } +} + +void imfieldi(GFilt g, int UNUSED(rno), int sno, int flag, int type, + double UNUSED(x), double UNUSED(y)) +{ + int yy; + Scan *scanlist; + + /* NB: do not use x and y variables, they have bogus values */ + g->shapes[sno].ystart = g->y0; + g->shapes[sno].ystop = g->y1; + g->shapes[sno].scanlist = (Scan *)calloc(g->y1+1, sizeof(Scan)); + scanlist = g->shapes[sno].scanlist; + marky(g, sno, flag, type); + /* calculate start/stop values for each y line */ + for(yy=g->shapes[sno].ystart; yy<=g->shapes[sno].ystop; yy++){ + rgs_mark(g, scanlist, sno, flag, type, g->x0, yy); + rgs_mark(g, scanlist, sno, flag, type, g->x1, yy); + } +} + +int imfield(GFilt g, int rno, int UNUSED(sno), int flag, int UNUSED(type), + double UNUSED(x), double UNUSED(y)) +{ + if( flag ){ + if( rno && flag ) g->rid = rno; + return 1; + } + else{ + return 0; + } +} + +void imlinei(GFilt g, int UNUSED(rno), int sno, int flag, int type, + double UNUSED(x), double UNUSED(y), + double x1, double y1, double x2, double y2) +{ + double vx[2]; + double vy[2]; + int xval, yval; + double invslope, xoffset; + + /* NB: do not use x and y variables, they have bogus values */ + /* divide by block factor to get "real" parameters */ + x1 = (x1 - g->xmin)/g->block + 1.0; + y1 = (y1 - g->ymin)/g->block + 1.0; + x2 = (x2 - g->xmin)/g->block + 1.0; + y2 = (y2 - g->ymin)/g->block + 1.0; + /* order by increasing y */ + if( y1 < y2 ){ + vx[0] = x1; + vy[0] = y1; + vx[1] = x2; + vy[1] = y2; + } + else{ + vx[0] = x2; + vy[0] = y2; + vx[1] = x1; + vy[1] = y1; + } + /* set y limits */ + g->shapes[sno].ystart = PIXNUM(vy[0]); + g->shapes[sno].ystop = PIXNUM(vy[1]); + g->shapes[sno].scanlist = (Scan *)calloc(g->y1+1, sizeof(Scan)); + marky(g, sno, flag, type); + if( feq(vy[0],vy[1]) ){ + rgs_mark(g, g->shapes[sno].scanlist, sno, flag, type, + (int)min(vx[0],vx[1]), (int)vy[0]); + rgs_mark(g, g->shapes[sno].scanlist, sno, flag, type, + (int)max(vx[0],vx[1]), (int)vy[0]); + } + else{ + /* mark all horizontal segment crossings */ + invslope = (vx[0] - vx[1]) / (vy[0] - vy[1]); + xoffset = vx[0]; + for(yval=vy[0]; yval<=vy[1]; yval++){ + xval = xoffset; + rgs_mark(g, g->shapes[sno].scanlist, sno, flag, type, xval, yval); + xoffset = xoffset + invslope; + } + } +} + +int imline(GFilt g, int rno, int sno, int flag, int UNUSED(type), + double x, double y, + double UNUSED(x1), double UNUSED(y1), + double UNUSED(x2), double UNUSED(y2)) +{ + Scan scan; + + if( g->evsect ){ + if( g->usebinsiz ){ + x = (int)((x - g->tlminx)/g->binsizx + 1.0); + y = (int)((y - g->tlminy)/g->binsizy + 1.0); + } + else{ + x = (int)((x - g->tlminx) + 1.0); + y = (int)((y - g->tlminy) + 1.0); + } + x = (int)((x - g->xmin)/g->block + 1.0); + y = (int)((y - g->ymin)/g->block + 1.0); + if(y < g->y0) return 0; + if(y > g->y1) return 0; + if(x < g->x0) return 0; + if(x > g->x1) return 0; + } + if( flag ){ + if(y < g->shapes[sno].ystart ) return 0; + if(y > g->shapes[sno].ystop ) return 0; + } + scan = g->shapes[sno].scanlist[(int)y]; + if( (scan && + ((x==(int)scan->x) || + (scan->next&&((x>=(int)scan->x)&&(x<=(int)scan->next->x)))))==flag ) { + if( rno && flag ) g->rid = rno; + return 1; + } + else + return 0; +} + +void impiei(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, double angle1, double angle2) +{ + _impiei(g, 0, rno, sno, flag, type, x, y, xcen, ycen, angle1, angle2); +} + +int impie(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double UNUSED(xcen), double UNUSED(ycen), + double UNUSED(angle1), double UNUSED(angle2)) +{ + return impolygon(g, rno, sno, flag, type, x, y); +} + +void imqtpiei(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, double angle1, double angle2) +{ + _impiei(g, 1, rno, sno, flag, type, x, y, xcen, ycen, angle1, angle2); +} + +int imqtpie(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double UNUSED(xcen), double UNUSED(ycen), + double UNUSED(angle1), double UNUSED(angle2)) +{ + return impolygon(g, rno, sno, flag, type, x, y); +} + +void impointi(GFilt g, int UNUSED(rno), int sno, int flag, int type, + double UNUSED(x), double UNUSED(y), + double xcen, double ycen) +{ + /* NB: do not use x and y variables, they have bogus values */ + /* divide by block factor to get "real" parameters */ + xcen = (xcen - g->xmin)/g->block + 1.0; + ycen = (ycen - g->ymin)/g->block + 1.0; + /* set y limits */ + g->shapes[sno].ystart = PIXNUM(ycen); + g->shapes[sno].ystop = PIXNUM(ycen); + g->shapes[sno].scanlist = (Scan *)calloc(g->y1+1, sizeof(Scan)); + marky(g, sno, flag, type); + rgs_mark(g, g->shapes[sno].scanlist, sno, flag, type, + PIXNUM(xcen), PIXNUM(ycen)); +} + +int impoint(GFilt g, int rno, int sno, int flag, int UNUSED(type), + double x, double y, + double UNUSED(xcen), double UNUSED(ycen)) +{ + Scan scan; + + if( g->evsect ){ + if( g->usebinsiz ){ + x = (int)((x - g->tlminx)/g->binsizx + 1.0); + y = (int)((y - g->tlminy)/g->binsizy + 1.0); + } + else{ + x = (int)((x - g->tlminx) + 1.0); + y = (int)((y - g->tlminy) + 1.0); + } + x = (int)((x - g->xmin)/g->block + 1.0); + y = (int)((y - g->ymin)/g->block + 1.0); + if(y < g->y0) return 0; + if(y > g->y1) return 0; + if(x < g->x0) return 0; + if(x > g->x1) return 0; + } + if( flag ){ + if(y < g->shapes[sno].ystart ) return 0; + if(y > g->shapes[sno].ystop ) return 0; + } + scan = g->shapes[sno].scanlist[(int)y]; + if( (scan && + (y == (int)g->shapes[sno].ystart) && + (x == (int)scan->x))==flag ) { + if( rno && flag ) g->rid = rno; + return 1; + } + else + return 0; +} + +#ifdef __STDC__ +void +impolygoni(GFilt g, int rno, int sno, int flag, int type, + double UNUSED(x), double y, ...) +{ + double *vx=NULL, *vy=NULL; + int count, maxcount; + va_list args; + va_start(args, y); +#else +void impolygoni(va_alist) va_dcl +{ + GFilt g; + int rno, sno, flag, type; + double x, y; + double *vx=NULL, *vy=NULL; + int count, maxcount; + va_list args; + va_start(args); + g = va_arg(args, GFilt); + rno = va_arg(args, int); + sno = va_arg(args, int); + flag = va_arg(args, int); + type = va_arg(args, int); + x = va_arg(args, double); + y = va_arg(args, double); +#endif + /* NB: do not use x and y variables, they have bogus values */ + /* allocate space for x,y arguments */ + maxcount = MASKINC; + vx = (double *)calloc(maxcount, sizeof(double)); + vy = (double *)calloc(maxcount, sizeof(double)); + /* look for x,y arguments */ + count = 0; + while( 1 ){ + if( (count + 1) >= maxcount ){ + maxcount += MASKINC; + vx = (double *)realloc(vx, maxcount*sizeof(double)); + vy = (double *)realloc(vy, maxcount*sizeof(double)); + } + vx[count] = va_arg(args, double); + vy[count] = va_arg(args, double); + if( feq(vx[count],PSTOP) && feq(vy[count],PSTOP) ) + break; + vx[count] = (vx[count] - g->xmin)/g->block + 1.0; + vy[count] = (vy[count] - g->ymin)/g->block + 1.0; + count ++; + } + va_end(args); + /* realloc to actual size */ + vx = (double *)realloc(vx, count*sizeof(double)); + vy = (double *)realloc(vy, count*sizeof(double)); + /* call the common routine */ + _polygoni(g, 0, rno, sno, flag, type, vx, vy, count); + if( vx ) free(vx); + if( vy ) free(vy); +} + +#ifdef __STDC__ +int +impolygon(GFilt g, int rno, int sno, int flag, int UNUSED(type), + double x, double y, ...) +{ + int crossings; + Scan scan; + va_list args; + va_start(args, y); +#else +int impolygon(va_alist) va_dcl +{ + GFilt g; + int rno, sno, flag, type; + double x, y; + int crossings; + Scan scan; + va_list args; + va_start(args); + g = va_arg(args, GFilt); + rno = va_arg(args, int); + sno = va_arg(args, int); + flag = va_arg(args, int); + type = va_arg(args, int); + x = va_arg(args, double); + y = va_arg(args, double); +#endif + va_end(args); + if( g->evsect ){ + if( g->usebinsiz ){ + x = (int)((x - g->tlminx)/g->binsizx + 1.0); + y = (int)((y - g->tlminy)/g->binsizy + 1.0); + } + else{ + x = (int)((x - g->tlminx) + 1.0); + y = (int)((y - g->tlminy) + 1.0); + } + x = (int)((x - g->xmin)/g->block + 1.0); + y = (int)((y - g->ymin)/g->block + 1.0); + if(y < g->y0) return 0; + if(y > g->y1) return 0; + if(x < g->x0) return 0; + if(x > g->x1) return 0; + } + if( flag ){ + if(y < g->shapes[sno].ystart ) return 0; + if(y > g->shapes[sno].ystop ) return 0; + } + /* no initialization of x for this row, just jump right in */ + if( (y>=g->shapes[sno].ystart)&&(y<=g->shapes[sno].ystop) ){ + crossings = 0; + for(scan=g->shapes[sno].scanlist[(int)y]; scan; scan=scan->next){ + if( x >= scan->x ) + crossings++; + else + break; + } + if( (crossings%2) == flag ){ + if( rno && flag ) g->rid = rno; + return 1; + } + else{ + return 0; + } + } + else{ + return !flag; + } +} + +void imnannulusi(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, + double lo, double hi, int n) +{ + int i; + int xsno; + double dinc; + + /* NB: do not use x and y variables, they have bogus values */ + + /* get limits */ + dinc = (hi - lo)/n; + xsno = (g->nshapes+1)+((sno-1)*XSNO); + /* init all shapes */ + imannulusi(g, 0, xsno, flag, type, x, y, xcen, ycen, lo, hi); + for(i=0; inshapes+1)+((sno-1)*XSNO); + /* init all shapes */ + imboxi(g, 0, xsno, flag, type, x, y, xcen, ycen, hix, hiy, ang); + imboxi(g, 0, xsno+1, flag, type, x, y, xcen, ycen, lox, loy, ang); + for(i=0; inshapes+1)+((sno-1)*XSNO); + /* init all shapes */ + imellipsei(g, 0, xsno, flag, type, x, y, xcen, ycen, hix, hiy, ang); + imellipsei(g, 0, xsno+1, flag, type, x, y, xcen, ycen, lox, loy, ang); + for(i=0; i hi ) lo -= 360.0; + dinc = (hi - lo)/n; + xsno = (g->nshapes+1)+((sno-1)*XSNO); + /* init all shapes */ + impiei(g, 0, xsno, flag, type, x, y, xcen, ycen, lo, hi); + for(i=0; i anghi ) anglo -= 360.0; + ainc = (anghi - anglo)/angn; + ahi = (int)angn; + rinc = (radhi - radlo)/radn; + rhi = (int)radn; + xsno = (g->nshapes+1)+((sno-1)*XSNO); + /* init pies and annuli */ + imannulusi(g, 0, xsno, flag, type, x, y, xcen, ycen, radlo, radhi); + imqtpiei(g, 0, xsno+1, flag, type, x, y, xcen, ycen, anglo, anghi); + for(a=0; a anghi ) anglo -= 360.0; + ainc = (anghi - anglo)/angn; + ahi = (int)angn; + xinc = (xhi - xlo)/radn; + yinc = (yhi - ylo)/radn; + rhi = (int)radn; + xsno = (g->nshapes+1)+((sno-1)*XSNO); + /* init pies and ellipses */ + imboxi(g, 0, xsno, flag, type, x, y, xcen, ycen, xhi, yhi, ang); + imqtpiei(g, 0, xsno+1, flag, type, x, y, xcen, ycen, anglo, anghi); + imboxi(g, 0, xsno+2, flag, type, x, y, xcen, ycen, xlo, ylo, ang); + for(a=0; a anghi ) anglo -= 360.0; + ainc = (anghi - anglo)/angn; + ahi = (int)angn; + xinc = (xhi - xlo)/radn; + yinc = (yhi - ylo)/radn; + rhi = (int)radn; + xsno = (g->nshapes+1)+((sno-1)*XSNO); + /* init pies and ellipses */ + imellipsei(g, 0, xsno, flag, type, x, y, xcen, ycen, xhi, yhi, ang); + imqtpiei(g, 0, xsno+1, flag, type, x, y, xcen, ycen, anglo, anghi); + imellipsei(g, 0, xsno+2, flag, type, x, y, xcen, ycen, xlo, ylo, ang); + for(a=0; anshapes+1)+((sno-1)*XSNO); + if( flag ){ + /* if its not somewhere inside the entire region we lose ... */ + if( !imannulus(g, 0, xsno, flag, type, x, y, xcen, ycen, lo, hi) ){ + return(0); + } + /* look through all of them to find the right one */ + for(i=0; inshapes+1)+((sno-1)*XSNO); + if( flag ){ + /* if its not somewhere inside the entire region we lose ... */ + if( !imbox(g, 0, xsno, flag, type, x, y, xcen, ycen, hix, hiy, ang) ){ + return(0); + } + /* if its in the inner region we lose */ + if( imbox(g, 0, xsno+1, flag, type, x, y, xcen, ycen, lox, loy, ang) ){ + return(0); + } + /* look through all of them to find the right one */ + for(i=0; inshapes+1)+((sno-1)*XSNO); + if( flag ){ + /* if its not somewhere inside the entire region we lose ... */ + if( !imellipse(g, 0, xsno, flag, type, x, y, xcen, ycen, hix, hiy, ang) ){ + return(0); + } + /* if its in the inner region we lose */ + if( imellipse(g, 0, xsno+1, flag, type, x, y, xcen, ycen, lox, loy, ang) ){ + return(0); + } + /* look through all of them to find the right one */ + for(i=0; i hi ) lo -= 360.0; + dinc = (hi - lo)/n; + xsno = (g->nshapes+1)+((sno-1)*XSNO); + if( flag ){ + /* check limits */ + if( !impie(g, 0, xsno, flag, type, x, y, xcen, ycen, lo, hi) ){ + return(0); + } + /* look through all of them to find the right one */ + for(i=0; i anghi ) anglo -= 360.0; + ainc = (anghi - anglo)/angn; + ahi = (int)angn; + rinc = (radhi - radlo)/radn; + rhi = (int)radn; + xsno = (g->nshapes+1)+((sno-1)*XSNO); + if( flag ){ + /* if its not somewhere inside the entire region we lose ... */ + if( !imannulus(g, 0, xsno, flag, type, x, y, xcen, ycen, radlo, radhi) || + !impie(g, 0, xsno+1, flag, type, x, y, xcen, ycen, anglo, anghi) ){ + return(0); + } + /* look through all of them to find the right one */ + for(a=1; a<=ahi; a++){ + for(r=1; r<=rhi; r++){ + if( imannulus(g, rno+n, sno+(2*n), flag, type, x, y, + xcen, ycen, radlo+((r-1)*rinc), radlo+(r*rinc)) && + impie(g, rno+n, sno+(2*n+1), flag, type, x, y, + xcen, ycen, anglo+((a-1)*ainc), anglo+(a*ainc)) ){ + return(1); + } + n++; + } + } + return(0); + } + else{ + /* if its not somewhere inside the entire region we win ... */ + if( !imannulus(g, 0, xsno, 1, type, x, y, xcen, ycen, radlo, radhi) ) + return(1); + else if( !impie(g, 0, xsno+1, 1, type, x, y, xcen, ycen, anglo, anghi) ){ + return(1); + } + else{ + return(0); + } + } +} + +int imbpanda(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, + double anglo, double anghi, double angn, + double xlo, double ylo, double xhi, double yhi, double radn, + double ang) +{ + + int a, r; + int ahi, rhi; + int xsno; + int n=0; + double ainc, xinc, yinc; + + /* get limits */ + anglo += ang; + anghi += ang; + while( anglo > anghi ) anglo -= 360.0; + ainc = (anghi - anglo)/angn; + ahi = (int)angn; + xinc = (xhi - xlo)/radn; + yinc = (yhi - ylo)/radn; + rhi = (int)radn; + xsno = (g->nshapes+1)+((sno-1)*XSNO); + if( flag ){ + /* if its not somewhere inside the entire region we lose ... */ + if( !imbox(g, 0, xsno, flag, type, x, y, xcen, ycen, xhi, yhi, + ang) ){ + return(0); + } + /* but if its in the inner region we lose */ + else if( imbox(g, 0, xsno+2, flag, type, x, y, xcen, ycen, xlo, ylo, + ang) ){ + return(0); + } + /* its in the box .. must also be in the pie */ + else if( !impie(g, 0, xsno+1, flag, type, x, y, xcen, ycen, anglo, anghi)){ + return(0); + } + /* look through all of them to find the right one */ + for(a=0; a anghi ) anglo -= 360.0; + ainc = (anghi - anglo)/angn; + ahi = (int)angn; + xinc = (xhi - xlo)/radn; + yinc = (yhi - ylo)/radn; + rhi = (int)radn; + xsno = (g->nshapes+1)+((sno-1)*XSNO); + if( flag ){ + /* if its not somewhere inside the entire region we lose ... */ + if( !imellipse(g, 0, xsno, flag, type, x, y, xcen, ycen, xhi, yhi, + ang) ){ + return(0); + } + /* but if its in the inner region we lose */ + else if( imellipse(g, 0, xsno+2, flag, type, x, y, xcen, ycen, xlo, ylo, + ang) ){ + return(0); + } + /* its in the ellipse .. must also be in the pie */ + else if( !impie(g, 0, xsno+1, flag, type, x, y, xcen, ycen, anglo, anghi)){ + return(0); + } + /* look through all of them to find the right one */ + for(a=0; anshapes+1)+((sno-1)*XSNO); + if( !g->shapes[xsno].xv ){ + maxpts = MASKINC; + g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double)); + g->shapes[xsno].nv = 0; + while( 1 ){ + if( g->shapes[xsno].nv >= maxpts ){ + maxpts += MASKINC; + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + maxpts*sizeof(double)); + } + g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double); + if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) && + feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){ + g->shapes[xsno].nv--; + break; + } + g->shapes[xsno].nv++; + } + va_end(args); + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + g->shapes[xsno].nv*sizeof(double)); + } + n = g->shapes[xsno].nv; + xv = g->shapes[xsno].xv; + /* this should be impossible ... */ + if( n == 2 ){ + imannulusi(g, rno, sno, flag, type, x, y, xcen, ycen, xv[0], xv[1]); + return; + } + imannulusi(g, 0, xsno, flag, type, x, y, xcen, ycen, xv[0], xv[n-1]); + for(i=0; i<(n-1); i++){ + imannulusi(g, rno+i, sno+i, flag, type, x, y, xcen, ycen, xv[i], xv[i+1]); + } +} + +#ifdef __STDC__ +void +imvboxi(GFilt g, int rno, int sno, int flag, int type, + double x, double y, double xcen, double ycen, ...) +{ + int i, j, n; + int maxpts; + int xsno; + double ang; + double *xv; + va_list args; + va_start(args, ycen); +#else +int imvboxi(va_alist) va_dcl +{ + GFilt g; + int rno, sno, flag, type; + double x, y; + double xcen, ycen; + double ang; + double *xv; + int i, j, n; + int maxpts; + int xsno; + va_list args; + va_start(args); + g = va_arg(args, GFilt); + rno = va_arg(args, int); + sno = va_arg(args, int); + flag = va_arg(args, int); + type = va_arg(args, int); + x = va_arg(args, double); + y = va_arg(args, double); + xcen = va_arg(args, double); + ycen = va_arg(args, double); +#endif + xsno = (g->nshapes+1)+((sno-1)*XSNO); + if( !g->shapes[xsno].xv ){ + maxpts = MASKINC; + g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double)); + g->shapes[xsno].nv = 0; + while( 1 ){ + if( g->shapes[xsno].nv >= maxpts ){ + maxpts += MASKINC; + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + maxpts*sizeof(double)); + } + g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double); + if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) && + feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){ + g->shapes[xsno].nv--; + break; + } + g->shapes[xsno].nv++; + } + va_end(args); + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + g->shapes[xsno].nv*sizeof(double)); + } + n = g->shapes[xsno].nv; + xv = g->shapes[xsno].xv; + ang = xv[--n]; + /* this should be impossible ... */ + if( n == 2 ){ + imboxi(g, rno, sno, flag, type, x, y, xcen, ycen, xv[0], xv[1], ang); + return; + } + imboxi(g, 0, xsno, flag, type, x, y, xcen, ycen, xv[n-2], xv[n-1], ang); + imboxi(g, 0, xsno+1, flag, type, x, y, xcen, ycen, xv[0], xv[1], ang); + for(i=2, j=0; inshapes+1)+((sno-1)*XSNO); + if( !g->shapes[xsno].xv ){ + maxpts = MASKINC; + g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double)); + g->shapes[xsno].nv = 0; + while( 1 ){ + if( g->shapes[xsno].nv >= maxpts ){ + maxpts += MASKINC; + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + maxpts*sizeof(double)); + } + g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double); + if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) && + feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){ + g->shapes[xsno].nv--; + break; + } + g->shapes[xsno].nv++; + } + va_end(args); + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + g->shapes[xsno].nv*sizeof(double)); + } + n = g->shapes[xsno].nv; + xv = g->shapes[xsno].xv; + ang = xv[--n]; + /* this should be impossible ... */ + if( n == 2 ){ + imellipsei(g, rno, sno, flag, type, x, y, xcen, ycen, xv[0], xv[1], ang); + return; + } + imellipsei(g, 0, xsno, flag, type, x, y, xcen, ycen, xv[n-2], xv[n-1], ang); + imellipsei(g, 0, xsno+1, flag, type, x, y, xcen, ycen, xv[0], xv[1], ang); + for(i=2, j=0; inshapes+1)+((sno-1)*XSNO); + if( !g->shapes[xsno].xv ){ + maxpts = MASKINC; + g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double)); + g->shapes[xsno].nv = 0; + while( 1 ){ + if( g->shapes[xsno].nv >= maxpts ){ + maxpts += MASKINC; + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + maxpts*sizeof(double)); + } + g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double); + if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) && + feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){ + g->shapes[xsno].nv--; + break; + } + g->shapes[xsno].nv++; + } + va_end(args); + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + g->shapes[xsno].nv*sizeof(double)); + } + n = g->shapes[xsno].nv; + xv = g->shapes[xsno].xv; + /* this should be impossible ... */ + if( n == 2 ){ + impiei(g, rno, sno, flag, type, x, y, xcen, ycen, xv[0], xv[1]); + return; + } + impiei(g, 0, xsno, flag, type, x, y, xcen, ycen, xv[0], xv[n-1]); + for(i=0; i<(n-1); i++){ + impiei(g, rno+i, sno+i, flag, type, x, y, xcen, ycen, xv[i], xv[i+1]); + } +} + +#ifdef __STDC__ +void +imvpointi(GFilt g, int rno, int sno, int flag, int type, + double x, double y, ...) +{ + int i, j, n; + int maxpts; + int xsno; + double *xv; + va_list args; + va_start(args, y); +#else +int imvpointi(va_alist) va_dcl +{ + GFilt g; + int rno, sno, flag, type; + double x, y; + double *xv; + int i, j, n; + int maxpts; + int xsno; + va_list args; + va_start(args); + g = va_arg(args, GFilt); + rno = va_arg(args, int); + sno = va_arg(args, int); + flag = va_arg(args, int); + type = va_arg(args, int); + x = va_arg(args, double); + y = va_arg(args, double); +#endif + xsno = (g->nshapes+1)+((sno-1)*XSNO); + if( !g->shapes[xsno].xv ){ + maxpts = MASKINC; + g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double)); + g->shapes[xsno].nv = 0; + while( 1 ){ + if( g->shapes[xsno].nv >= maxpts ){ + maxpts += MASKINC; + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + maxpts*sizeof(double)); + } + g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double); + if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) && + feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){ + g->shapes[xsno].nv--; + break; + } + g->shapes[xsno].nv++; + } + va_end(args); + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + g->shapes[xsno].nv*sizeof(double)); + } + n = g->shapes[xsno].nv; + xv = g->shapes[xsno].xv; + for(i=0, j=0; inshapes+1)+((sno-1)*XSNO); + if( !g->shapes[xsno].xv ){ + maxpts = MASKINC; + g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double)); + g->shapes[xsno].nv = 0; + while( 1 ){ + if( g->shapes[xsno].nv >= maxpts ){ + maxpts += MASKINC; + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + maxpts*sizeof(double)); + } + g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double); + if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) && + feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){ + g->shapes[xsno].nv--; + break; + } + g->shapes[xsno].nv++; + } + va_end(args); + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + g->shapes[xsno].nv*sizeof(double)); + } + n = g->shapes[xsno].nv; + xv = g->shapes[xsno].xv; + /* this should be impossible ... */ + if( n == 2 ){ + return(imannulus(g, rno, sno, flag, type, x, y, xcen, ycen, xv[0], xv[1])); + } + if( flag ){ + /* if its not somewhere inside the entire region we lose ... */ + if( !imannulus(g, 0, xsno, flag, type, x, y, xcen, ycen, xv[0], xv[n-1]) ){ + return(0); + } + /* look through all of them to find the right one */ + for(i=0; inshapes+1)+((sno-1)*XSNO); + if( !g->shapes[xsno].xv ){ + maxpts = MASKINC; + g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double)); + g->shapes[xsno].nv = 0; + while( 1 ){ + if( g->shapes[xsno].nv >= maxpts ){ + maxpts += MASKINC; + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + maxpts*sizeof(double)); + } + g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double); + if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) && + feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){ + g->shapes[xsno].nv--; + break; + } + g->shapes[xsno].nv++; + } + va_end(args); + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + g->shapes[xsno].nv*sizeof(double)); + } + n = g->shapes[xsno].nv; + xv = g->shapes[xsno].xv; + ang = xv[--n]; + /* this should be impossible ... */ + if( n == 2 ){ + return(imbox(g, rno, sno, flag, type, x, y, + xcen, ycen, xv[0], xv[1], ang)); + } + if( flag ){ + /* if its not somewhere inside the entire region we lose ... */ + if( !imbox(g, 0, xsno, flag, type, x, y, xcen, ycen, xv[n-2], xv[n-1], + ang) ){ + return(0); + } + /* if its in the inner region we lose */ + if( imbox(g, 0, xsno+1, flag, type, x, y, xcen, ycen, xv[0], xv[1], ang) ){ + return(0); + } + /* look through all of them to find the right one */ + for(i=2, j=0; inshapes+1)+((sno-1)*XSNO); + if( !g->shapes[xsno].xv ){ + maxpts = MASKINC; + g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double)); + g->shapes[xsno].nv = 0; + while( 1 ){ + if( g->shapes[xsno].nv >= maxpts ){ + maxpts += MASKINC; + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + maxpts*sizeof(double)); + } + g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double); + if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) && + feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){ + g->shapes[xsno].nv--; + break; + } + g->shapes[xsno].nv++; + } + va_end(args); + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + g->shapes[xsno].nv*sizeof(double)); + } + n = g->shapes[xsno].nv; + xv = g->shapes[xsno].xv; + ang = xv[--n]; + /* this should be impossible ... */ + if( n == 2 ){ + return(imellipse(g, rno, sno, flag, type, x, y, + xcen, ycen, xv[0], xv[1], ang)); + } + if( flag ){ + /* if its not somewhere inside the entire region we lose ... */ + if( !imellipse(g, 0, xsno, flag, type, x, y, xcen, ycen, xv[n-2], xv[n-1], + ang) ){ + return(0); + } + /* if its in the inner region we lose */ + if( imellipse(g, 0, xsno+1, flag, type, x, y, xcen, ycen, xv[0], xv[1], + ang) ){ + return(0); + } + /* look through all of them to find the right one */ + for(i=2, j=0; inshapes+1)+((sno-1)*XSNO); + if( !g->shapes[xsno].xv ){ + maxpts = MASKINC; + g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double)); + g->shapes[xsno].nv = 0; + while( 1 ){ + if( g->shapes[xsno].nv >= maxpts ){ + maxpts += MASKINC; + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + maxpts*sizeof(double)); + } + g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double); + if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) && + feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){ + g->shapes[xsno].nv--; + break; + } + g->shapes[xsno].nv++; + } + va_end(args); + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + g->shapes[xsno].nv*sizeof(double)); + } + n = g->shapes[xsno].nv; + xv = g->shapes[xsno].xv; + /* this should be impossible ... */ + if( n == 2 ){ + return(impie(g, rno, sno, flag, type, x, y, + xcen, ycen, xv[0], xv[1])); + } + if( flag ){ + /* if its not somewhere inside the entire region we lose ... */ + if( !impie(g, 0, xsno, flag, type, x, y, xcen, ycen, xv[0], xv[n-1]) ){ + return(0); + } + /* look through all of them to find the right one */ + for(i=0; inshapes+1)+((sno-1)*XSNO); + if( !g->shapes[xsno].xv ){ + maxpts = MASKINC; + g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double)); + g->shapes[xsno].nv = 0; + while( 1 ){ + if( g->shapes[xsno].nv >= maxpts ){ + maxpts += MASKINC; + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + maxpts*sizeof(double)); + } + g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double); + if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) && + feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){ + g->shapes[xsno].nv--; + break; + } + g->shapes[xsno].nv++; + } + va_end(args); + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + g->shapes[xsno].nv*sizeof(double)); + } + n = g->shapes[xsno].nv; + xv = g->shapes[xsno].xv; + /* look through all of them to find the right one */ + for(i=0, j=0; ixmax - g->xmin + 1)/g->block)/(double)g->maskdim) + 0.5); + if( mblock < 1 ){ + g->masks = NULL; + g->nmask = 0; + } + /* copy all masks and translate x,y positions as needed */ + fsize = g->nmask * sizeof(FilterMaskRec) * mblock; + xmasks = (FilterMask)calloc(1, fsize); + for(got=0, i=0; inmask; i++){ + xmasks[got].region = g->masks[i].region; + xmasks[got].y = (g->masks[i].y - 1.0) * mblock + 1.0; + xmasks[got].xstart = (g->masks[i].xstart - 1.0) * mblock + 1.0; + xmasks[got].xstop = (g->masks[i].xstop - 1.0) * mblock + 1.0; + /* replicate the segment up to the block factor */ + for(j=1; jmasks ) free(g->masks); */ + /* set up new mask records */ + g->masks = xmasks; + g->nmask = got; + + /* now mark each y line that has a y mask value */ + for(i=0; iybuf[g->masks[i].y] ) + g->ybuf[g->masks[i].y] = i+1; + } +} + +int imimagemask(GFilt g, int UNUSED(rno), int UNUSED(sno), + int UNUSED(flag), int UNUSED(type), + double x, double y) +{ + int i; + int ix, iy; + + if( g->nmask == 0 ) + return(0); + if( g->evsect ){ + if( g->usebinsiz ){ + x = (int)((x - g->tlminx)/g->binsizx + 1.0); + y = (int)((y - g->tlminy)/g->binsizy + 1.0); + } + else{ + x = (int)((x - g->tlminx) + 1.0); + y = (int)((y - g->tlminy) + 1.0); + } + x = (int)((x - g->xmin)/g->block + 1.0); + y = (int)((y - g->ymin)/g->block + 1.0); + if(y < g->y0) return 0; + if(y > g->y1) return 0; + if(x < g->x0) return 0; + if(x > g->x1) return 0; + } + ix = (int)x; + iy = (int)y; + /* look for mask segment containing ix, iy */ + i = g->ybuf[iy]; + /* ybuf contains offset+1 of first mask record containing iy */ + if( i != 0 ){ + i--; + for(; inmask; i++){ + if( g->masks[i].y > iy ){ + return(0); + } + if( (ix >= g->masks[i].xstart) && (ix <= g->masks[i].xstop) ){ + g->rid = g->masks[i].region; + return(1); + } + } + } + return(0); +} + diff --git a/filter/imregions_c.h b/filter/imregions_c.h new file mode 100644 index 0000000..bb6cdc0 --- /dev/null +++ b/filter/imregions_c.h @@ -0,0 +1 @@ +static char *IMREGIONS_C="\n/*\n NB: MAKE SURE YOU EDIT THE TEMPLATE FILE!!!!\n*/\n\n#ifndef FILTER_PTYPE\n#include \n#endif\n\n#ifndef UNUSED\n#ifdef __GNUC__\n# define UNUSED(x) UNUSED_ ## x __attribute__((__unused__))\n#else\n# define UNUSED(x) UNUSED_ ## x\n#endif\n#endif\n\n\n#define USE_ASTRO_ANGLE 0\n\n\n#define USE_FPU_DOUBLE 0\n#if USE_FPU_DOUBLE\n#include \nstatic fpu_control_t _cw;\n#define FPU_DOUBLE {fpu_control_t _cw2; _FPU_GETCW(_cw); _cw2 = _cw & ~_FPU_EXTENDED; _cw2 |= _FPU_DOUBLE; _FPU_SETCW(_cw2);}\n#define FPU_RESTORE {_FPU_SETCW(_cw);}\n#else\n#define FPU_DOUBLE\n#define FPU_RESTORE\n#endif\n\n\nstatic int imregno=0;\nvoid initimregions(void)\n{\n imregno++;\n return;\n}\n\nstatic void markx(GFilt g, int UNUSED(sno), int flag, int type, int x, int y)\n{\n \n if( type == TOK_EREG )\n return;\n \n if( flag ){\n if( x <= g->x0s[y] )\n g->x0s[y] = max(x,g->x0);\n if( x >= g->x1s[y] )\n g->x1s[y] = min(x,g->x1);\n }\n \n else{\n g->x0s[y] = g->x0;\n g->x1s[y] = g->x1;\n }\n}\n\nstatic void marky(GFilt g, int sno, int flag, int type)\n{\n int i;\n \n if( type == TOK_EREG )\n return;\n \n if( flag ){\n for(i=max(g->y0,g->shapes[sno].ystart);\n i<=min(g->y1,g->shapes[sno].ystop);\n i++)\n g->ybuf[i] = 1;\n }\n \n else{\n for(i=g->y0; i<=g->shapes[sno].ystart-1; i++)\n g->ybuf[i] = 1;\n for(i=g->shapes[sno].ystop+1; i<=g->y1; i++)\n g->ybuf[i] = 1;\n }\n}\n\nstatic int\nimagemaskcmp(const void *s1, const void *s2)\n{\n FilterMask f1 = (FilterMask)s1;\n FilterMask f2 = (FilterMask)s2;\n \n if( f1->y < f2->y ){\n return -1;\n }\n else if( f1->y > f2->y ){\n return 1;\n }\n else{\n if( f1->xstart < f2->xstart ){\n return -1;\n }\n else{\n return 1;\n }\n }\n}\n\n\n\nstatic void quadeq(double a, double b, double c,\n double *x1, double *x2, int *nr, int *nc)\n{\n double dis, q;\n if( feq(a,0.0) ){\n *nc = 0;\n if( feq(b,0.0) ){\n *nr = 0; *x1 = 0.0;\n }\n else{\n *nr = 1; *x1 = -c / b;\n }\n *x2 = *x1;\n }\n else{\n dis = b*b - 4.0 * a * c;\n if( dis > 0.0 ){\n *nr = 2; *nc = 0;\n dis = sqrt(dis);\n if( b < 0.0 ) dis = -dis;\n q = -0.5 * (b + dis);\n *x1 = q/a; *x2 = c/q;\n if(*x1 > *x2){\n q = *x1; *x1 = *x2; *x2 = q;\n }\n } \n else if( feq(dis,0.0) ){\n *nr = 1; *nc = 0; *x1 = - 0.5 * b / a; *x2 = *x1;\n }\n else{\n *nr = 0; *nc = 2; *x1 = - 0.5 * b / a; *x2 = 0.5 * sqrt(-dis) / a;\n }\n }\n}\n\nstatic void rgs_mark(GFilt g, Scan *scanlist,\n int sno, int flag, int type, int xval, int yval )\n{\n Scan scanmark, mark;\n \n if(yval < g->y0) yval = g->y0;\n if(yval > g->y1) yval = g->y1;\n mark = (Scan)calloc(1, sizeof(ScanRec));\n mark->x = xval;\n \n if( !scanlist ) return;\n \n if( !scanlist[yval] || ((scanlist[yval])->x > xval) ){\n mark->next = scanlist[yval];\n scanlist[yval] = mark;\n } else {\n scanmark = scanlist[yval];\n while( scanmark->next && ((scanmark->next)->x < xval) )\n scanmark = scanmark->next;\n mark->next = scanmark->next;\n scanmark->next = mark;\n }\n markx(g, sno, flag, type, xval, yval);\n}\n\nstatic void rgs_segment(GFilt g, Scan *scanlist, int width, int height,\n int sno, int flag, int type,\n double x1, double y1, double x2, double y2)\n{\n int ystart, ystop, yval, xval;\n double invslope, xoffset;\n\n ystart = PIXINCL(y1);\n if( ystart < 1 ) ystart = 1;\n \n ystop = PIXINCL(y2) - 1;\n if( ystop > height ) ystop = height;\n \n if( (ystart > ystop) || (ystop < 1) )\n return;\n \n invslope = (x1 - x2) / (y1 - y2);\n xoffset = x1 + ((ystart - y1) * invslope);\n for(yval=ystart; yval<=ystop; yval++){\n xval = PIXINCL(xoffset);\n \n if(xval < 1) xval = 1;\n if(xval > width) xval = width + 1;\n rgs_mark(g, scanlist, sno, flag, type, xval, yval);\n xoffset = xoffset + invslope;\n }\n}\n\nstatic void _polygoni(GFilt g, int qt, int UNUSED(rno), int sno, int flag,\n int type, double *vx, double *vy, int count)\n{\n int i, j;\n double xlo, xhi;\n double ylo, yhi;\n\n#ifdef ALREADY_DONE\n \n for(i=0; ixmin)/g->block + 1.0;\n vy[i] = (vy[i] - g->ymin)/g->block + 1.0;\n }\n#endif\n \n xlo = vx[0];\n xhi = xlo;\n ylo = vy[0];\n yhi = ylo;\n for(i=0; i xhi) xhi = vx[i];\n if(vx[i] < xlo) xlo = vx[i];\n if(vy[i] > yhi) yhi = vy[i];\n if(vy[i] < ylo) ylo = vy[i];\n }\n if( qt && (sno > 1) ){\n g->shapes[sno].ystart = g->shapes[sno-1].ystart;\n g->shapes[sno].ystop = g->shapes[sno-1].ystop;\n }\n else{\n g->shapes[sno].ystart = max(g->y0,PIXINCL(ylo));\n g->shapes[sno].ystop = min(g->y1,PIXINCL(yhi) - 1);\n }\n g->shapes[sno].scanlist = (Scan *)calloc(g->y1+1, sizeof(Scan));\n marky(g, sno, flag, type);\n\n \n \n j = count-1;\n for(i=0; i vy[j]){\n rgs_segment(g, g->shapes[sno].scanlist, g->x1, g->y1,\n sno, flag, type, vx[j], vy[j], vx[i], vy[i]);\n }\n else{\n rgs_segment(g, g->shapes[sno].scanlist, g->x1, g->y1,\n sno, flag, type, vx[i], vy[i], vx[j], vy[j]);\n }\n j = i;\n }\n}\n\nstatic int corner_vertex(int index, int width, int height,\n double *x, double *y)\n{\n switch (index) {\n case 1:\n *x = 0.0;\n *y = height + 1;\n break;\n case 2:\n *x = 0.0;\n *y = 0.0;\n break;\n case 3:\n *x = width + 1;\n *y = 0.0;\n break;\n case 4:\n *x = width + 1;\n *y = height + 1;\n default:\n break;\n }\n index = index + 1;\n if(index > 4) index = 1;\n return(index);\n}\n\nstatic int pie_intercept(int width, int height, double xcen, double ycen,\n double angle, double *xcept, double *ycept)\n{\n double angl, slope; \n angl = angle;\n \n while (angl < 0.0)\n angl = angl + 360.0;\n while (angl >= 360.0)\n angl = angl - 360.0;\n \n#if USE_ASTRO_ANGLE\n if(fabs(angl - 90.0) < SMALL_NUMBER) {\n#else\n if(fabs(angl - 180.0) < SMALL_NUMBER) {\n#endif\n *xcept = 0.0;\n *ycept = ycen;\n return(2);\n }\n#if USE_ASTRO_ANGLE\n if(fabs(angl - 270.0) < SMALL_NUMBER) {\n#else\n if(fabs(angl - 0.0) < SMALL_NUMBER) {\n#endif\n *xcept = width + 1;\n *ycept = ycen;\n return(4);\n }\n#if USE_ASTRO_ANGLE\n \n angl = angl + 90.0;\n#endif\n if(angl >= 360.0)\n angl = angl - 360.0;\n if(angl < 180.0) {\n *ycept = height + 1;\n \n if(fabs(angl - 90.0) < SMALL_NUMBER) {\n *xcept = xcen;\n return(1);\n }\n } else {\n *ycept = 0.0;\n \n if(fabs(angl - 270.0) < SMALL_NUMBER) {\n *xcept = xcen;\n return(3);\n }\n }\n \n angl = (angl / 180.0) * M_PI;\n \n slope = tan(angl);\n \n *xcept = xcen + ((*ycept - ycen) / slope);\n if(*xcept < 0) {\n *ycept = (ycen - (xcen * slope));\n *xcept = 0.0;\n return(2);\n } else if(*xcept > (width + 1)) {\n *ycept = (ycen + ((width + 1 - xcen) * slope));\n *xcept = width + 1;\n return(4);\n } else {\n if(*ycept < height)\n return(3);\n else\n return(1);\n }\n}\n\nvoid _impiei(GFilt g, int qt, int rno, int sno, int flag, int type,\n double UNUSED(x), double UNUSED(y),\n double xcen, double ycen, double angle1, double angle2)\n{\n int width, height; \n double sweep; \n double vx[7], vy[7]; \n int count; \n int intrcpt1, intrcpt2; \n double x2, y2; \n\n \n \n xcen = (xcen - g->xmin)/g->block + 1.0;\n ycen = (ycen - g->ymin)/g->block + 1.0;\n \n width = g->x1;\n height = g->y1;\n \n vx[0] = xcen;\n vy[0] = ycen;\n sweep = angle2 - angle1;\n \n if(fabs(sweep) < SMALL_NUMBER)\n return;\n if (sweep < 0.0) sweep = sweep + 360.0;\n intrcpt1 = pie_intercept(width, height, xcen, ycen, angle1,\n &(vx[1]), &(vy[1]));\n intrcpt2 = pie_intercept(width, height, xcen, ycen, angle2,\n &x2, &y2);\n count = 2;\n \n \n if((intrcpt1 != intrcpt2) || (sweep > 180.0)){\n do{\n intrcpt1 = corner_vertex(intrcpt1, width, height, \n &(vx[count]), &(vy[count]));\n count = count + 1;\n }while(intrcpt1 != intrcpt2);\n }\n vx[count] = x2;\n vy[count] = y2;\n count++;\n _polygoni(g, qt, rno, sno, flag, type, vx, vy, count);\n}\n\n\n\nvoid imannulusi(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double xcen, double ycen, double iradius, double oradius)\n{\n int yy;\n double dval;\n double xoff, yoff;\n Scan *scanlist;\n\n \n\n if( iradius == 0 ){\n imcirclei(g, rno, sno, flag, type, x, y, xcen, ycen, oradius);\n return;\n }\n \n xcen = (xcen - g->xmin)/g->block + 1.0;\n ycen = (ycen - g->ymin)/g->block + 1.0;\n iradius /= (double)g->block;\n oradius /= (double)g->block;\n \n if( PIXSTART(ycen - oradius) < PIXSTOP(ycen + oradius) ){\n g->shapes[sno].ystart = max(g->y0,PIXSTART(ycen - oradius));\n g->shapes[sno].ystop = min(g->y1,PIXSTOP(ycen + oradius));\n }\n else{\n g->shapes[sno].ystart = min(g->y1,PIXSTOP(ycen + oradius));\n g->shapes[sno].ystop = max(g->y0,PIXSTART(ycen - oradius));\n }\n g->shapes[sno].scanlist = (Scan *)calloc(g->y1+1, sizeof(Scan));\n scanlist = g->shapes[sno].scanlist;\n marky(g, sno, flag, type);\n \n for(yy=g->shapes[sno].ystart; yy<=g->shapes[sno].ystop; yy++){\n yoff = PIXCEN(yy) - ycen;\n if( (dval=(oradius * oradius) - (yoff * yoff)) > 0.0 ){\n xoff = sqrt(dval);\n if( PIXSTART(xcen - xoff) <= PIXSTOP(xcen + xoff) ){\n rgs_mark(g, scanlist, sno, flag, type, PIXSTART(xcen - xoff), yy);\n rgs_mark(g, scanlist, sno, flag, type, PIXSTOP(xcen + xoff), yy);\n }\n if( (dval=(iradius * iradius) - (yoff * yoff)) > 0.0 ){\n xoff = sqrt(dval);\n if( PIXSTART(xcen - xoff) <= PIXSTOP(xcen + xoff) ){\n rgs_mark(g, scanlist, sno, flag, type, PIXSTART(xcen - xoff), yy);\n rgs_mark(g, scanlist, sno, flag, type, PIXSTOP(xcen + xoff), yy);\n }\n }\n }\n }\n}\n\nint imannulus(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double xcen, double ycen, double iradius, double oradius)\n{\n Scan scan;\n\n if( iradius == 0 ){\n return(imcircle(g, rno, sno, flag, type, x, y, xcen, ycen, oradius));\n }\n if( g->evsect ){\n if( g->usebinsiz ){\n x = (int)((x - g->tlminx)/g->binsizx + 1.0);\n y = (int)((y - g->tlminy)/g->binsizy + 1.0);\n }\n else{\n x = (int)((x - g->tlminx) + 1.0);\n y = (int)((y - g->tlminy) + 1.0);\n }\n x = (int)((x - g->xmin)/g->block + 1.0);\n y = (int)((y - g->ymin)/g->block + 1.0);\n if(y < g->y0) return 0;\n if(y > g->y1) return 0;\n if(x < g->x0) return 0;\n if(x > g->x1) return 0;\n }\n if( flag ){\n if(y < g->shapes[sno].ystart ) return 0;\n if(y > g->shapes[sno].ystop ) return 0;\n }\n scan = g->shapes[sno].scanlist[(int)y];\n if( (scan && \n ((y >= g->shapes[sno].ystart) && (y <= g->shapes[sno].ystop)) &&\n (scan->next->next ?\n (((x >= scan->x) && (x <= scan->next->next->next->x)) &&\n !((x >= scan->next->x) && (x <= scan->next->next->x))) :\n ((x >= scan->x) && (x <= scan->next->x))))\n ==flag ){\n if( rno && flag ) g->rid = rno;\n return 1;\n }\n else\n return 0;\n}\n\nvoid imboxi(GFilt g, int rno, int sno, int flag, int type,\n double UNUSED(x), double UNUSED(y),\n double xcen, double ycen, double xwidth, double yheight,\n double angle)\n{\n double angl; \n double half_width, half_height;\n double cosangl, sinangl; \n double hw_cos, hw_sin; \n double hh_cos, hh_sin; \n double cornerx[4], cornery[4]; \n\n \n if( (xwidth == 0) && (yheight==0) ){\n return;\n }\n \n xcen = (xcen - g->xmin)/g->block + 1.0;\n ycen = (ycen - g->ymin)/g->block + 1.0;\n xwidth /= (double)g->block;\n yheight /= (double)g->block;\n#if USE_ASTRO_ANGLE\n \n angl = angle + 90.0;\n#else\n angl = angle;\n#endif\n while (angl >= 360.0) angl = angl - 360.0;\n \n angl = (angl / 180.0) * M_PI;\n sinangl = sin (angl);\n cosangl = cos (angl);\n#if USE_ASTRO_ANGLE\n \n \n \n half_width = yheight / 2.0;\n half_height = xwidth / 2.0;\n#else\n half_width = xwidth / 2.0;\n half_height = yheight / 2.0;\n#endif\n hw_cos = half_width * cosangl;\n hw_sin = half_width * sinangl;\n hh_cos = half_height * cosangl;\n hh_sin = half_height * sinangl;\n#if USE_ASTRO_ANGLE\n cornerx[0] = xcen - hw_cos - hh_sin;\n cornery[0] = ycen - hw_sin + hh_cos;\n cornerx[1] = xcen + hw_cos - hh_sin;\n cornery[1] = ycen + hw_sin + hh_cos;\n cornerx[2] = xcen + hw_cos + hh_sin;\n cornery[2] = ycen + hw_sin - hh_cos;\n cornerx[3] = xcen - hw_cos + hh_sin;\n cornery[3] = ycen - hw_sin - hh_cos;\n#else\n cornerx[0] = xcen - hw_cos + hh_sin;\n cornery[0] = ycen - hh_cos - hw_sin;\n cornerx[1] = xcen - hw_cos - hh_sin;\n cornery[1] = ycen + hh_cos - hw_sin;\n cornerx[2] = xcen + hw_cos - hh_sin;\n cornery[2] = ycen + hh_cos + hw_sin;\n cornerx[3] = xcen + hw_cos + hh_sin;\n cornery[3] = ycen - hh_cos + hw_sin;\n#endif\n _polygoni(g, 0, rno, sno, flag, type, cornerx, cornery, 4);\n}\n\nint imbox(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double UNUSED(xcen), double UNUSED(ycen),\n double xwidth, double yheight,\n double UNUSED(angle))\n{\n if( (xwidth == 0) && (yheight==0) ){\n return(!flag);\n }\n return impolygon(g, rno, sno, flag, type, x, y);\n}\n\nvoid imcirclei(GFilt g, int UNUSED(rno), int sno, int flag, int type,\n double UNUSED(x), double UNUSED(y),\n double xcen, double ycen, double radius)\n{\n int yy;\n double dval;\n double xoff, yoff;\n Scan *scanlist;\n\n \n if( radius == 0 ){\n return;\n }\n \n xcen = (xcen - g->xmin)/g->block + 1.0;\n ycen = (ycen - g->ymin)/g->block + 1.0;\n radius /= (double)g->block;\n \n if( PIXSTART(ycen - radius) < PIXSTOP(ycen + radius) ){\n g->shapes[sno].ystart = max(g->y0,PIXSTART(ycen - radius));\n g->shapes[sno].ystop = min(g->y1,PIXSTOP(ycen + radius));\n }\n else{\n g->shapes[sno].ystart = min(g->y1,PIXSTOP(ycen + radius));\n g->shapes[sno].ystop = max(g->y0,PIXSTART(ycen - radius));\n }\n g->shapes[sno].scanlist = (Scan *)calloc(g->y1+1, sizeof(Scan));\n scanlist = g->shapes[sno].scanlist;\n marky(g, sno, flag, type);\n \n for(yy=g->shapes[sno].ystart; yy<=g->shapes[sno].ystop; yy++){\n yoff = PIXCEN(yy) - ycen;\n if( (dval=(radius * radius) - (yoff * yoff))>=0.0 ){\n xoff = sqrt(dval);\n if( PIXSTART(xcen - xoff) <= PIXSTOP(xcen + xoff) ){\n rgs_mark(g, scanlist, sno, flag, type, PIXSTART(xcen - xoff), yy);\n rgs_mark(g, scanlist, sno, flag, type, PIXSTOP(xcen + xoff), yy);\n }\n }\n }\n}\n\nint imcircle(GFilt g, int rno, int sno, int flag, int UNUSED(type),\n double x, double y,\n double UNUSED(xcen), double UNUSED(ycen), double radius)\n{\n Scan scan;\n\n if( radius == 0 ){\n return(!flag);\n }\n if( g->evsect ){\n if( g->usebinsiz ){\n x = (int)((x - g->tlminx)/g->binsizx + 1.0);\n y = (int)((y - g->tlminy)/g->binsizy + 1.0);\n }\n else{\n x = (int)((x - g->tlminx) + 1.0);\n y = (int)((y - g->tlminy) + 1.0);\n }\n x = (int)((x - g->xmin)/g->block + 1.0);\n y = (int)((y - g->ymin)/g->block + 1.0);\n if(y < g->y0) return 0;\n if(y > g->y1) return 0;\n if(x < g->x0) return 0;\n if(x > g->x1) return 0;\n }\n if( flag ){\n if(y < g->shapes[sno].ystart ) return 0;\n if(y > g->shapes[sno].ystop ) return 0;\n }\n scan = g->shapes[sno].scanlist[(int)y];\n if( (scan && \n ((y>=g->shapes[sno].ystart) && (y<=g->shapes[sno].ystop)) &&\n ((x >= scan->x) && (x <= (scan->next)->x))) == flag ){\n if( rno && flag ) g->rid = rno;\n return 1;\n }\n else{\n return 0;\n }\n}\n\nvoid imellipsei(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double xcen, double ycen, double xrad, double yrad,\n double angle)\n{\n int yy;\n int nr, nc;\n double yhi;\n double yoff;\n double xboff, xfoff;\n double angl;\n double sinangl, cosangl;\n double cossq, sinsq, xradsq, yradsq;\n double a, b_partial, c_partial;\n double b, c;\n Scan *scanlist;\n\n \n\n if( xrad == yrad ){\n imcirclei(g, rno, sno, flag, type, x, y, xcen, ycen, xrad);\n return;\n }\n \n xcen = (xcen - g->xmin)/g->block + 1.0;\n ycen = (ycen - g->ymin)/g->block + 1.0;\n xrad /= (double)g->block;\n yrad /= (double)g->block;\n \n#if USE_ASTRO_ANGLE\n \n angl = angle + 90.0;\n#else\n angl = angle;\n#endif\n while( angl >= 360.0 )\n angl = angl - 360.0;\n \n angl = (angl / 180.0) * M_PI;\n sinangl = sin(angl);\n cosangl = cos(angl);\n \n \n FPU_DOUBLE\n#if USE_ASTRO_ANGLE\n yhi = fabs(sinangl * yrad) + fabs(cosangl * xrad);\n#else\n yhi = fabs(sinangl * xrad) + fabs(cosangl * yrad);\n#endif\n yhi = min(yhi, max(yrad, xrad));\n \n if( PIXSTART(ycen - yhi) < PIXSTOP(ycen + yhi) ){\n g->shapes[sno].ystart = max(g->y0,PIXSTART(ycen - yhi));\n g->shapes[sno].ystop = min(g->y1,PIXSTOP(ycen + yhi));\n }\n else{\n g->shapes[sno].ystart = min(g->y1,PIXSTOP(ycen + yhi));\n g->shapes[sno].ystop = max(g->y0,PIXSTART(ycen - yhi));\n }\n FPU_RESTORE\n g->shapes[sno].scanlist = (Scan *)calloc(g->y1+1, sizeof(Scan));\n scanlist = g->shapes[sno].scanlist;\n marky(g, sno, flag, type);\n \n cossq = cosangl * cosangl;\n sinsq = sinangl * sinangl;\n#if USE_ASTRO_ANGLE\n \n \n \n \n xradsq = yrad * yrad;\n yradsq = xrad * xrad;\n#else\n xradsq = xrad * xrad;\n yradsq = yrad * yrad;\n#endif\n \n a = (cossq / xradsq) + (sinsq / yradsq);\n b_partial = (2.0 * sinangl) * ((cosangl / xradsq) - (cosangl / yradsq));\n c_partial = (sinsq / xradsq) + (cossq / yradsq);\n \n for(yy=g->shapes[sno].ystart; yy<=g->shapes[sno].ystop; yy++){\n yoff = yy - ycen;\n b = b_partial * yoff;\n c = (c_partial * yoff * yoff) - 1.0;\n \n quadeq (a, b, c, &xboff, &xfoff, &nr, &nc);\n \n if( nr != 0 ) {\n \n rgs_mark(g, scanlist, sno, flag, type, PIXSTART(xcen + xboff), yy);\n rgs_mark(g, scanlist, sno, flag, type, PIXSTOP(xcen + xfoff), yy);\n }\n }\n}\n\nint imellipse(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double xcen, double ycen, double xrad, double yrad,\n double UNUSED(angle))\n{\n Scan scan;\n\n if( xrad == yrad ){\n return(imcircle(g, rno, sno, flag, type, x, y, xcen, ycen, xrad));\n }\n if( g->evsect ){\n if( g->usebinsiz ){\n x = (int)((x - g->tlminx)/g->binsizx + 1.0);\n y = (int)((y - g->tlminy)/g->binsizy + 1.0);\n }\n else{\n x = (int)((x - g->tlminx) + 1.0);\n y = (int)((y - g->tlminy) + 1.0);\n }\n x = (int)((x - g->xmin)/g->block + 1.0);\n y = (int)((y - g->ymin)/g->block + 1.0);\n if(y < g->y0) return 0;\n if(y > g->y1) return 0;\n if(x < g->x0) return 0;\n if(x > g->x1) return 0;\n }\n if( flag ){\n if(y < g->shapes[sno].ystart ) return 0;\n if(y > g->shapes[sno].ystop ) return 0;\n }\n scan = g->shapes[sno].scanlist[(int)y];\n FPU_DOUBLE\n if( (scan && \n ((y>=g->shapes[sno].ystart) && (y<=g->shapes[sno].ystop)) &&\n ((x >= scan->x) && (x <= (scan->next)->x))) == flag ){\n if( rno && flag ) g->rid = rno;\n FPU_RESTORE\n return 1;\n }\n else{\n FPU_RESTORE\n return 0;\n }\n}\n\nvoid imfieldi(GFilt g, int UNUSED(rno), int sno, int flag, int type,\n double UNUSED(x), double UNUSED(y))\n{\n int yy;\n Scan *scanlist;\n\n \n g->shapes[sno].ystart = g->y0;\n g->shapes[sno].ystop = g->y1;\n g->shapes[sno].scanlist = (Scan *)calloc(g->y1+1, sizeof(Scan));\n scanlist = g->shapes[sno].scanlist;\n marky(g, sno, flag, type);\n \n for(yy=g->shapes[sno].ystart; yy<=g->shapes[sno].ystop; yy++){\n rgs_mark(g, scanlist, sno, flag, type, g->x0, yy);\n rgs_mark(g, scanlist, sno, flag, type, g->x1, yy);\n }\n}\n\nint imfield(GFilt g, int rno, int UNUSED(sno), int flag, int UNUSED(type),\n double UNUSED(x), double UNUSED(y))\n{\n if( flag ){\n if( rno && flag ) g->rid = rno;\n return 1;\n }\n else{\n return 0;\n }\n}\n\nvoid imlinei(GFilt g, int UNUSED(rno), int sno, int flag, int type,\n double UNUSED(x), double UNUSED(y),\n double x1, double y1, double x2, double y2)\n{\n double vx[2];\n double vy[2];\n int xval, yval;\n double invslope, xoffset;\n\n \n \n x1 = (x1 - g->xmin)/g->block + 1.0;\n y1 = (y1 - g->ymin)/g->block + 1.0;\n x2 = (x2 - g->xmin)/g->block + 1.0;\n y2 = (y2 - g->ymin)/g->block + 1.0;\n \n if( y1 < y2 ){\n vx[0] = x1;\n vy[0] = y1;\n vx[1] = x2;\n vy[1] = y2;\n }\n else{\n vx[0] = x2;\n vy[0] = y2;\n vx[1] = x1;\n vy[1] = y1;\n }\n \n g->shapes[sno].ystart = PIXNUM(vy[0]);\n g->shapes[sno].ystop = PIXNUM(vy[1]);\n g->shapes[sno].scanlist = (Scan *)calloc(g->y1+1, sizeof(Scan));\n marky(g, sno, flag, type);\n if( feq(vy[0],vy[1]) ){\n rgs_mark(g, g->shapes[sno].scanlist, sno, flag, type,\n (int)min(vx[0],vx[1]), (int)vy[0]);\n rgs_mark(g, g->shapes[sno].scanlist, sno, flag, type,\n (int)max(vx[0],vx[1]), (int)vy[0]);\n }\n else{\n \n invslope = (vx[0] - vx[1]) / (vy[0] - vy[1]);\n xoffset = vx[0];\n for(yval=vy[0]; yval<=vy[1]; yval++){\n xval = xoffset;\n rgs_mark(g, g->shapes[sno].scanlist, sno, flag, type, xval, yval);\n xoffset = xoffset + invslope;\n }\n }\n}\n\nint imline(GFilt g, int rno, int sno, int flag, int UNUSED(type),\n double x, double y,\n double UNUSED(x1), double UNUSED(y1),\n double UNUSED(x2), double UNUSED(y2))\n{\n Scan scan;\n\n if( g->evsect ){\n if( g->usebinsiz ){\n x = (int)((x - g->tlminx)/g->binsizx + 1.0);\n y = (int)((y - g->tlminy)/g->binsizy + 1.0);\n }\n else{\n x = (int)((x - g->tlminx) + 1.0);\n y = (int)((y - g->tlminy) + 1.0);\n }\n x = (int)((x - g->xmin)/g->block + 1.0);\n y = (int)((y - g->ymin)/g->block + 1.0);\n if(y < g->y0) return 0;\n if(y > g->y1) return 0;\n if(x < g->x0) return 0;\n if(x > g->x1) return 0;\n }\n if( flag ){\n if(y < g->shapes[sno].ystart ) return 0;\n if(y > g->shapes[sno].ystop ) return 0;\n }\n scan = g->shapes[sno].scanlist[(int)y];\n if( (scan &&\n ((x==(int)scan->x) ||\n (scan->next&&((x>=(int)scan->x)&&(x<=(int)scan->next->x)))))==flag ) {\n if( rno && flag ) g->rid = rno;\n return 1;\n }\n else\n return 0;\n}\n\nvoid impiei(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double xcen, double ycen, double angle1, double angle2)\n{\n _impiei(g, 0, rno, sno, flag, type, x, y, xcen, ycen, angle1, angle2);\n}\n\nint impie(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double UNUSED(xcen), double UNUSED(ycen),\n double UNUSED(angle1), double UNUSED(angle2))\n{\n return impolygon(g, rno, sno, flag, type, x, y);\n}\n\nvoid imqtpiei(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double xcen, double ycen, double angle1, double angle2)\n{\n _impiei(g, 1, rno, sno, flag, type, x, y, xcen, ycen, angle1, angle2);\n}\n\nint imqtpie(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double UNUSED(xcen), double UNUSED(ycen),\n double UNUSED(angle1), double UNUSED(angle2))\n{\n return impolygon(g, rno, sno, flag, type, x, y);\n}\n\nvoid impointi(GFilt g, int UNUSED(rno), int sno, int flag, int type,\n double UNUSED(x), double UNUSED(y),\n double xcen, double ycen)\n{\n \n \n xcen = (xcen - g->xmin)/g->block + 1.0;\n ycen = (ycen - g->ymin)/g->block + 1.0;\n \n g->shapes[sno].ystart = PIXNUM(ycen);\n g->shapes[sno].ystop = PIXNUM(ycen);\n g->shapes[sno].scanlist = (Scan *)calloc(g->y1+1, sizeof(Scan));\n marky(g, sno, flag, type);\n rgs_mark(g, g->shapes[sno].scanlist, sno, flag, type,\n PIXNUM(xcen), PIXNUM(ycen));\n}\n\nint impoint(GFilt g, int rno, int sno, int flag, int UNUSED(type),\n double x, double y,\n double UNUSED(xcen), double UNUSED(ycen))\n{\n Scan scan;\n\n if( g->evsect ){\n if( g->usebinsiz ){\n x = (int)((x - g->tlminx)/g->binsizx + 1.0);\n y = (int)((y - g->tlminy)/g->binsizy + 1.0);\n }\n else{\n x = (int)((x - g->tlminx) + 1.0);\n y = (int)((y - g->tlminy) + 1.0);\n }\n x = (int)((x - g->xmin)/g->block + 1.0);\n y = (int)((y - g->ymin)/g->block + 1.0);\n if(y < g->y0) return 0;\n if(y > g->y1) return 0;\n if(x < g->x0) return 0;\n if(x > g->x1) return 0;\n }\n if( flag ){\n if(y < g->shapes[sno].ystart ) return 0;\n if(y > g->shapes[sno].ystop ) return 0;\n }\n scan = g->shapes[sno].scanlist[(int)y];\n if( (scan &&\n (y == (int)g->shapes[sno].ystart) && \n (x == (int)scan->x))==flag ) {\n if( rno && flag ) g->rid = rno;\n return 1;\n }\n else\n return 0;\n}\n\n#ifdef __STDC__\nvoid\nimpolygoni(GFilt g, int rno, int sno, int flag, int type,\n double UNUSED(x), double y, ...)\n{\n double *vx=NULL, *vy=NULL;\n int count, maxcount;\n va_list args;\n va_start(args, y);\n#else\nvoid impolygoni(va_alist) va_dcl\n{\n GFilt g;\n int rno, sno, flag, type;\n double x, y;\n double *vx=NULL, *vy=NULL;\n int count, maxcount;\n va_list args;\n va_start(args);\n g = va_arg(args, GFilt);\n rno = va_arg(args, int);\n sno = va_arg(args, int);\n flag = va_arg(args, int);\n type = va_arg(args, int);\n x = va_arg(args, double);\n y = va_arg(args, double);\n#endif\n \n \n maxcount = MASKINC;\n vx = (double *)calloc(maxcount, sizeof(double));\n vy = (double *)calloc(maxcount, sizeof(double));\n \n count = 0;\n while( 1 ){\n if( (count + 1) >= maxcount ){\n maxcount += MASKINC;\n vx = (double *)realloc(vx, maxcount*sizeof(double));\n vy = (double *)realloc(vy, maxcount*sizeof(double));\n }\n vx[count] = va_arg(args, double);\n vy[count] = va_arg(args, double);\n if( feq(vx[count],PSTOP) && feq(vy[count],PSTOP) )\n break;\n vx[count] = (vx[count] - g->xmin)/g->block + 1.0;\n vy[count] = (vy[count] - g->ymin)/g->block + 1.0;\n count ++;\n }\n va_end(args);\n \n vx = (double *)realloc(vx, count*sizeof(double));\n vy = (double *)realloc(vy, count*sizeof(double));\n \n _polygoni(g, 0, rno, sno, flag, type, vx, vy, count);\n if( vx ) free(vx);\n if( vy ) free(vy);\n}\n\n#ifdef __STDC__\nint\nimpolygon(GFilt g, int rno, int sno, int flag, int UNUSED(type),\n double x, double y, ...)\n{\n int crossings;\n Scan scan;\n va_list args;\n va_start(args, y);\n#else\nint impolygon(va_alist) va_dcl\n{\n GFilt g;\n int rno, sno, flag, type;\n double x, y;\n int crossings;\n Scan scan;\n va_list args;\n va_start(args);\n g = va_arg(args, GFilt);\n rno = va_arg(args, int);\n sno = va_arg(args, int);\n flag = va_arg(args, int);\n type = va_arg(args, int);\n x = va_arg(args, double);\n y = va_arg(args, double);\n#endif\n va_end(args);\n if( g->evsect ){\n if( g->usebinsiz ){\n x = (int)((x - g->tlminx)/g->binsizx + 1.0);\n y = (int)((y - g->tlminy)/g->binsizy + 1.0);\n }\n else{\n x = (int)((x - g->tlminx) + 1.0);\n y = (int)((y - g->tlminy) + 1.0);\n }\n x = (int)((x - g->xmin)/g->block + 1.0);\n y = (int)((y - g->ymin)/g->block + 1.0);\n if(y < g->y0) return 0;\n if(y > g->y1) return 0;\n if(x < g->x0) return 0;\n if(x > g->x1) return 0;\n }\n if( flag ){\n if(y < g->shapes[sno].ystart ) return 0;\n if(y > g->shapes[sno].ystop ) return 0;\n }\n \n if( (y>=g->shapes[sno].ystart)&&(y<=g->shapes[sno].ystop) ){\n crossings = 0;\n for(scan=g->shapes[sno].scanlist[(int)y]; scan; scan=scan->next){\n if( x >= scan->x )\n crossings++;\n else\n break;\n }\n if( (crossings%2) == flag ){\n if( rno && flag ) g->rid = rno;\n return 1;\n }\n else{\n return 0;\n }\n }\n else{\n return !flag;\n }\n}\n\nvoid imnannulusi(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double xcen, double ycen,\n double lo, double hi, int n)\n{\n int i;\n int xsno;\n double dinc;\n\n \n\n \n dinc = (hi - lo)/n;\n xsno = (g->nshapes+1)+((sno-1)*XSNO);\n \n imannulusi(g, 0, xsno, flag, type, x, y, xcen, ycen, lo, hi);\n for(i=0; inshapes+1)+((sno-1)*XSNO);\n \n imboxi(g, 0, xsno, flag, type, x, y, xcen, ycen, hix, hiy, ang);\n imboxi(g, 0, xsno+1, flag, type, x, y, xcen, ycen, lox, loy, ang);\n for(i=0; inshapes+1)+((sno-1)*XSNO);\n \n imellipsei(g, 0, xsno, flag, type, x, y, xcen, ycen, hix, hiy, ang);\n imellipsei(g, 0, xsno+1, flag, type, x, y, xcen, ycen, lox, loy, ang);\n for(i=0; i hi ) lo -= 360.0;\n dinc = (hi - lo)/n;\n xsno = (g->nshapes+1)+((sno-1)*XSNO);\n \n impiei(g, 0, xsno, flag, type, x, y, xcen, ycen, lo, hi);\n for(i=0; i anghi ) anglo -= 360.0;\n ainc = (anghi - anglo)/angn;\n ahi = (int)angn;\n rinc = (radhi - radlo)/radn;\n rhi = (int)radn;\n xsno = (g->nshapes+1)+((sno-1)*XSNO);\n \n imannulusi(g, 0, xsno, flag, type, x, y, xcen, ycen, radlo, radhi);\n imqtpiei(g, 0, xsno+1, flag, type, x, y, xcen, ycen, anglo, anghi);\n for(a=0; a anghi ) anglo -= 360.0;\n ainc = (anghi - anglo)/angn;\n ahi = (int)angn;\n xinc = (xhi - xlo)/radn;\n yinc = (yhi - ylo)/radn;\n rhi = (int)radn;\n xsno = (g->nshapes+1)+((sno-1)*XSNO);\n \n imboxi(g, 0, xsno, flag, type, x, y, xcen, ycen, xhi, yhi, ang);\n imqtpiei(g, 0, xsno+1, flag, type, x, y, xcen, ycen, anglo, anghi);\n imboxi(g, 0, xsno+2, flag, type, x, y, xcen, ycen, xlo, ylo, ang);\n for(a=0; a anghi ) anglo -= 360.0;\n ainc = (anghi - anglo)/angn;\n ahi = (int)angn;\n xinc = (xhi - xlo)/radn;\n yinc = (yhi - ylo)/radn;\n rhi = (int)radn;\n xsno = (g->nshapes+1)+((sno-1)*XSNO);\n \n imellipsei(g, 0, xsno, flag, type, x, y, xcen, ycen, xhi, yhi, ang);\n imqtpiei(g, 0, xsno+1, flag, type, x, y, xcen, ycen, anglo, anghi);\n imellipsei(g, 0, xsno+2, flag, type, x, y, xcen, ycen, xlo, ylo, ang);\n for(a=0; anshapes+1)+((sno-1)*XSNO);\n if( flag ){\n \n if( !imannulus(g, 0, xsno, flag, type, x, y, xcen, ycen, lo, hi) ){\n return(0);\n }\n \n for(i=0; inshapes+1)+((sno-1)*XSNO);\n if( flag ){\n \n if( !imbox(g, 0, xsno, flag, type, x, y, xcen, ycen, hix, hiy, ang) ){\n return(0);\n }\n \n if( imbox(g, 0, xsno+1, flag, type, x, y, xcen, ycen, lox, loy, ang) ){\n return(0);\n }\n \n for(i=0; inshapes+1)+((sno-1)*XSNO);\n if( flag ){\n \n if( !imellipse(g, 0, xsno, flag, type, x, y, xcen, ycen, hix, hiy, ang) ){\n return(0);\n }\n \n if( imellipse(g, 0, xsno+1, flag, type, x, y, xcen, ycen, lox, loy, ang) ){\n return(0);\n }\n \n for(i=0; i hi ) lo -= 360.0;\n dinc = (hi - lo)/n;\n xsno = (g->nshapes+1)+((sno-1)*XSNO);\n if( flag ){\n \n if( !impie(g, 0, xsno, flag, type, x, y, xcen, ycen, lo, hi) ){\n return(0);\n }\n \n for(i=0; i anghi ) anglo -= 360.0;\n ainc = (anghi - anglo)/angn;\n ahi = (int)angn;\n rinc = (radhi - radlo)/radn;\n rhi = (int)radn;\n xsno = (g->nshapes+1)+((sno-1)*XSNO);\n if( flag ){\n \n if( !imannulus(g, 0, xsno, flag, type, x, y, xcen, ycen, radlo, radhi) ||\n !impie(g, 0, xsno+1, flag, type, x, y, xcen, ycen, anglo, anghi) ){\n return(0);\n }\n \n for(a=1; a<=ahi; a++){\n for(r=1; r<=rhi; r++){\n if( imannulus(g, rno+n, sno+(2*n), flag, type, x, y,\n xcen, ycen, radlo+((r-1)*rinc), radlo+(r*rinc)) &&\n impie(g, rno+n, sno+(2*n+1), flag, type, x, y,\n xcen, ycen, anglo+((a-1)*ainc), anglo+(a*ainc)) ){\n return(1);\n }\n n++;\n }\n }\n return(0);\n }\n else{\n \n if( !imannulus(g, 0, xsno, 1, type, x, y, xcen, ycen, radlo, radhi) )\n return(1);\n else if( !impie(g, 0, xsno+1, 1, type, x, y, xcen, ycen, anglo, anghi) ){\n return(1);\n }\n else{\n return(0);\n }\n }\n}\n\nint imbpanda(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double xcen, double ycen,\n double anglo, double anghi, double angn,\n double xlo, double ylo, double xhi, double yhi, double radn,\n double ang)\n{\n \n int a, r;\n int ahi, rhi;\n int xsno;\n int n=0;\n double ainc, xinc, yinc;\n\n \n anglo += ang;\n anghi += ang;\n while( anglo > anghi ) anglo -= 360.0;\n ainc = (anghi - anglo)/angn;\n ahi = (int)angn;\n xinc = (xhi - xlo)/radn;\n yinc = (yhi - ylo)/radn;\n rhi = (int)radn;\n xsno = (g->nshapes+1)+((sno-1)*XSNO);\n if( flag ){\n \n if( !imbox(g, 0, xsno, flag, type, x, y, xcen, ycen, xhi, yhi,\n ang) ){\n return(0);\n }\n \n else if( imbox(g, 0, xsno+2, flag, type, x, y, xcen, ycen, xlo, ylo,\n ang) ){\n return(0);\n }\n \n else if( !impie(g, 0, xsno+1, flag, type, x, y, xcen, ycen, anglo, anghi)){\n return(0);\n }\n \n for(a=0; a anghi ) anglo -= 360.0;\n ainc = (anghi - anglo)/angn;\n ahi = (int)angn;\n xinc = (xhi - xlo)/radn;\n yinc = (yhi - ylo)/radn;\n rhi = (int)radn;\n xsno = (g->nshapes+1)+((sno-1)*XSNO);\n if( flag ){\n \n if( !imellipse(g, 0, xsno, flag, type, x, y, xcen, ycen, xhi, yhi,\n ang) ){\n return(0);\n }\n \n else if( imellipse(g, 0, xsno+2, flag, type, x, y, xcen, ycen, xlo, ylo,\n ang) ){\n return(0);\n }\n \n else if( !impie(g, 0, xsno+1, flag, type, x, y, xcen, ycen, anglo, anghi)){\n return(0);\n }\n \n for(a=0; anshapes+1)+((sno-1)*XSNO);\n if( !g->shapes[xsno].xv ){\n maxpts = MASKINC;\n g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double));\n g->shapes[xsno].nv = 0;\n while( 1 ){\n if( g->shapes[xsno].nv >= maxpts ){\n maxpts += MASKINC;\n g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv,\n maxpts*sizeof(double));\n }\n g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double);\n if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) &&\n feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){\n g->shapes[xsno].nv--;\n break;\n }\n g->shapes[xsno].nv++;\n }\n va_end(args);\n g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv,\n g->shapes[xsno].nv*sizeof(double));\n }\n n = g->shapes[xsno].nv;\n xv = g->shapes[xsno].xv;\n \n if( n == 2 ){\n imannulusi(g, rno, sno, flag, type, x, y, xcen, ycen, xv[0], xv[1]);\n return;\n }\n imannulusi(g, 0, xsno, flag, type, x, y, xcen, ycen, xv[0], xv[n-1]);\n for(i=0; i<(n-1); i++){\n imannulusi(g, rno+i, sno+i, flag, type, x, y, xcen, ycen, xv[i], xv[i+1]);\n }\n}\n\n#ifdef __STDC__\nvoid\nimvboxi(GFilt g, int rno, int sno, int flag, int type,\n double x, double y, double xcen, double ycen, ...)\n{\n int i, j, n;\n int maxpts;\n int xsno;\n double ang;\n double *xv;\n va_list args;\n va_start(args, ycen);\n#else\nint imvboxi(va_alist) va_dcl\n{\n GFilt g;\n int rno, sno, flag, type;\n double x, y;\n double xcen, ycen;\n double ang;\n double *xv;\n int i, j, n;\n int maxpts;\n int xsno;\n va_list args;\n va_start(args);\n g = va_arg(args, GFilt);\n rno = va_arg(args, int);\n sno = va_arg(args, int);\n flag = va_arg(args, int);\n type = va_arg(args, int);\n x = va_arg(args, double);\n y = va_arg(args, double);\n xcen = va_arg(args, double);\n ycen = va_arg(args, double);\n#endif\n xsno = (g->nshapes+1)+((sno-1)*XSNO);\n if( !g->shapes[xsno].xv ){\n maxpts = MASKINC;\n g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double));\n g->shapes[xsno].nv = 0;\n while( 1 ){\n if( g->shapes[xsno].nv >= maxpts ){\n maxpts += MASKINC;\n g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv,\n maxpts*sizeof(double));\n }\n g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double);\n if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) &&\n feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){\n g->shapes[xsno].nv--;\n break;\n }\n g->shapes[xsno].nv++;\n }\n va_end(args);\n g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv,\n g->shapes[xsno].nv*sizeof(double));\n }\n n = g->shapes[xsno].nv;\n xv = g->shapes[xsno].xv;\n ang = xv[--n];\n \n if( n == 2 ){\n imboxi(g, rno, sno, flag, type, x, y, xcen, ycen, xv[0], xv[1], ang);\n return;\n }\n imboxi(g, 0, xsno, flag, type, x, y, xcen, ycen, xv[n-2], xv[n-1], ang);\n imboxi(g, 0, xsno+1, flag, type, x, y, xcen, ycen, xv[0], xv[1], ang);\n for(i=2, j=0; inshapes+1)+((sno-1)*XSNO);\n if( !g->shapes[xsno].xv ){\n maxpts = MASKINC;\n g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double));\n g->shapes[xsno].nv = 0;\n while( 1 ){\n if( g->shapes[xsno].nv >= maxpts ){\n maxpts += MASKINC;\n g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv,\n maxpts*sizeof(double));\n }\n g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double);\n if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) &&\n feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){\n g->shapes[xsno].nv--;\n break;\n }\n g->shapes[xsno].nv++;\n }\n va_end(args);\n g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv,\n g->shapes[xsno].nv*sizeof(double));\n }\n n = g->shapes[xsno].nv;\n xv = g->shapes[xsno].xv;\n ang = xv[--n];\n \n if( n == 2 ){\n imellipsei(g, rno, sno, flag, type, x, y, xcen, ycen, xv[0], xv[1], ang);\n return;\n }\n imellipsei(g, 0, xsno, flag, type, x, y, xcen, ycen, xv[n-2], xv[n-1], ang);\n imellipsei(g, 0, xsno+1, flag, type, x, y, xcen, ycen, xv[0], xv[1], ang);\n for(i=2, j=0; inshapes+1)+((sno-1)*XSNO);\n if( !g->shapes[xsno].xv ){\n maxpts = MASKINC;\n g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double));\n g->shapes[xsno].nv = 0;\n while( 1 ){\n if( g->shapes[xsno].nv >= maxpts ){\n maxpts += MASKINC;\n g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv,\n maxpts*sizeof(double));\n }\n g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double);\n if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) &&\n feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){\n g->shapes[xsno].nv--;\n break;\n }\n g->shapes[xsno].nv++;\n }\n va_end(args);\n g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv,\n g->shapes[xsno].nv*sizeof(double));\n }\n n = g->shapes[xsno].nv;\n xv = g->shapes[xsno].xv;\n \n if( n == 2 ){\n impiei(g, rno, sno, flag, type, x, y, xcen, ycen, xv[0], xv[1]);\n return;\n }\n impiei(g, 0, xsno, flag, type, x, y, xcen, ycen, xv[0], xv[n-1]);\n for(i=0; i<(n-1); i++){\n impiei(g, rno+i, sno+i, flag, type, x, y, xcen, ycen, xv[i], xv[i+1]);\n }\n}\n\n#ifdef __STDC__\nvoid\nimvpointi(GFilt g, int rno, int sno, int flag, int type,\n double x, double y, ...)\n{\n int i, j, n;\n int maxpts;\n int xsno;\n double *xv;\n va_list args;\n va_start(args, y);\n#else\nint imvpointi(va_alist) va_dcl\n{\n GFilt g;\n int rno, sno, flag, type;\n double x, y;\n double *xv;\n int i, j, n;\n int maxpts;\n int xsno;\n va_list args;\n va_start(args);\n g = va_arg(args, GFilt);\n rno = va_arg(args, int);\n sno = va_arg(args, int);\n flag = va_arg(args, int);\n type = va_arg(args, int);\n x = va_arg(args, double);\n y = va_arg(args, double);\n#endif\n xsno = (g->nshapes+1)+((sno-1)*XSNO);\n if( !g->shapes[xsno].xv ){\n maxpts = MASKINC;\n g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double));\n g->shapes[xsno].nv = 0;\n while( 1 ){\n if( g->shapes[xsno].nv >= maxpts ){\n maxpts += MASKINC;\n g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv,\n maxpts*sizeof(double));\n }\n g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double);\n if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) &&\n feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){\n g->shapes[xsno].nv--;\n break;\n }\n g->shapes[xsno].nv++;\n }\n va_end(args);\n g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv,\n g->shapes[xsno].nv*sizeof(double));\n }\n n = g->shapes[xsno].nv;\n xv = g->shapes[xsno].xv;\n for(i=0, j=0; inshapes+1)+((sno-1)*XSNO);\n if( !g->shapes[xsno].xv ){\n maxpts = MASKINC;\n g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double));\n g->shapes[xsno].nv = 0;\n while( 1 ){\n if( g->shapes[xsno].nv >= maxpts ){\n maxpts += MASKINC;\n g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv,\n maxpts*sizeof(double));\n }\n g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double);\n if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) &&\n feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){\n g->shapes[xsno].nv--;\n break;\n }\n g->shapes[xsno].nv++;\n }\n va_end(args);\n g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv,\n g->shapes[xsno].nv*sizeof(double));\n }\n n = g->shapes[xsno].nv;\n xv = g->shapes[xsno].xv;\n \n if( n == 2 ){\n return(imannulus(g, rno, sno, flag, type, x, y, xcen, ycen, xv[0], xv[1]));\n }\n if( flag ){\n \n if( !imannulus(g, 0, xsno, flag, type, x, y, xcen, ycen, xv[0], xv[n-1]) ){\n return(0);\n }\n \n for(i=0; inshapes+1)+((sno-1)*XSNO);\n if( !g->shapes[xsno].xv ){\n maxpts = MASKINC;\n g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double));\n g->shapes[xsno].nv = 0;\n while( 1 ){\n if( g->shapes[xsno].nv >= maxpts ){\n maxpts += MASKINC;\n g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv,\n maxpts*sizeof(double));\n }\n g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double);\n if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) &&\n feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){\n g->shapes[xsno].nv--;\n break;\n }\n g->shapes[xsno].nv++;\n }\n va_end(args);\n g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv,\n g->shapes[xsno].nv*sizeof(double));\n }\n n = g->shapes[xsno].nv;\n xv = g->shapes[xsno].xv;\n ang = xv[--n];\n \n if( n == 2 ){\n return(imbox(g, rno, sno, flag, type, x, y,\n xcen, ycen, xv[0], xv[1], ang));\n }\n if( flag ){\n \n if( !imbox(g, 0, xsno, flag, type, x, y, xcen, ycen, xv[n-2], xv[n-1],\n ang) ){\n return(0);\n }\n \n if( imbox(g, 0, xsno+1, flag, type, x, y, xcen, ycen, xv[0], xv[1], ang) ){\n return(0);\n }\n \n for(i=2, j=0; inshapes+1)+((sno-1)*XSNO);\n if( !g->shapes[xsno].xv ){\n maxpts = MASKINC;\n g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double));\n g->shapes[xsno].nv = 0;\n while( 1 ){\n if( g->shapes[xsno].nv >= maxpts ){\n maxpts += MASKINC;\n g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv,\n maxpts*sizeof(double));\n }\n g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double);\n if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) &&\n feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){\n g->shapes[xsno].nv--;\n break;\n }\n g->shapes[xsno].nv++;\n }\n va_end(args);\n g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv,\n g->shapes[xsno].nv*sizeof(double));\n }\n n = g->shapes[xsno].nv;\n xv = g->shapes[xsno].xv;\n ang = xv[--n];\n \n if( n == 2 ){\n return(imellipse(g, rno, sno, flag, type, x, y,\n xcen, ycen, xv[0], xv[1], ang));\n }\n if( flag ){\n \n if( !imellipse(g, 0, xsno, flag, type, x, y, xcen, ycen, xv[n-2], xv[n-1],\n ang) ){\n return(0);\n }\n \n if( imellipse(g, 0, xsno+1, flag, type, x, y, xcen, ycen, xv[0], xv[1],\n ang) ){\n return(0);\n }\n \n for(i=2, j=0; inshapes+1)+((sno-1)*XSNO);\n if( !g->shapes[xsno].xv ){\n maxpts = MASKINC;\n g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double));\n g->shapes[xsno].nv = 0;\n while( 1 ){\n if( g->shapes[xsno].nv >= maxpts ){\n maxpts += MASKINC;\n g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv,\n maxpts*sizeof(double));\n }\n g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double);\n if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) &&\n feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){\n g->shapes[xsno].nv--;\n break;\n }\n g->shapes[xsno].nv++;\n }\n va_end(args);\n g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv,\n g->shapes[xsno].nv*sizeof(double));\n }\n n = g->shapes[xsno].nv;\n xv = g->shapes[xsno].xv;\n \n if( n == 2 ){\n return(impie(g, rno, sno, flag, type, x, y,\n xcen, ycen, xv[0], xv[1]));\n }\n if( flag ){\n \n if( !impie(g, 0, xsno, flag, type, x, y, xcen, ycen, xv[0], xv[n-1]) ){\n return(0);\n }\n \n for(i=0; inshapes+1)+((sno-1)*XSNO);\n if( !g->shapes[xsno].xv ){\n maxpts = MASKINC;\n g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double));\n g->shapes[xsno].nv = 0;\n while( 1 ){\n if( g->shapes[xsno].nv >= maxpts ){\n maxpts += MASKINC;\n g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv,\n maxpts*sizeof(double));\n }\n g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double);\n if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) &&\n feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){\n g->shapes[xsno].nv--;\n break;\n }\n g->shapes[xsno].nv++;\n }\n va_end(args);\n g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv,\n g->shapes[xsno].nv*sizeof(double));\n }\n n = g->shapes[xsno].nv;\n xv = g->shapes[xsno].xv;\n \n for(i=0, j=0; ixmax - g->xmin + 1)/g->block)/(double)g->maskdim) + 0.5);\n if( mblock < 1 ){\n g->masks = NULL;\n g->nmask = 0;\n }\n \n fsize = g->nmask * sizeof(FilterMaskRec) * mblock;\n xmasks = (FilterMask)calloc(1, fsize);\n for(got=0, i=0; inmask; i++){\n xmasks[got].region = g->masks[i].region;\n xmasks[got].y = (g->masks[i].y - 1.0) * mblock + 1.0;\n xmasks[got].xstart = (g->masks[i].xstart - 1.0) * mblock + 1.0;\n xmasks[got].xstop = (g->masks[i].xstop - 1.0) * mblock + 1.0;\n \n for(j=1; jmasks = xmasks;\n g->nmask = got;\n\n \n for(i=0; iybuf[g->masks[i].y] )\n g->ybuf[g->masks[i].y] = i+1;\n }\n}\n\nint imimagemask(GFilt g, int UNUSED(rno), int UNUSED(sno),\n int UNUSED(flag), int UNUSED(type),\n double x, double y)\n{\n int i;\n int ix, iy;\n\n if( g->nmask == 0 )\n return(0);\n if( g->evsect ){\n if( g->usebinsiz ){\n x = (int)((x - g->tlminx)/g->binsizx + 1.0);\n y = (int)((y - g->tlminy)/g->binsizy + 1.0);\n }\n else{\n x = (int)((x - g->tlminx) + 1.0);\n y = (int)((y - g->tlminy) + 1.0);\n }\n x = (int)((x - g->xmin)/g->block + 1.0);\n y = (int)((y - g->ymin)/g->block + 1.0);\n if(y < g->y0) return 0;\n if(y > g->y1) return 0;\n if(x < g->x0) return 0;\n if(x > g->x1) return 0;\n }\n ix = (int)x;\n iy = (int)y;\n \n i = g->ybuf[iy];\n \n if( i != 0 ){\n i--;\n for(; inmask; i++){\n if( g->masks[i].y > iy ){\n return(0);\n }\n if( (ix >= g->masks[i].xstart) && (ix <= g->masks[i].xstop) ){\n g->rid = g->masks[i].region;\n return(1);\n }\n }\n }\n return(0);\n}\n\n"; diff --git a/filter/imregions_c.tmpl b/filter/imregions_c.tmpl new file mode 100644 index 0000000..639fefc --- /dev/null +++ b/filter/imregions_c.tmpl @@ -0,0 +1,2585 @@ +/* + NB: MAKE SURE YOU EDIT THE TEMPLATE FILE!!!! +*/ + +#ifndef FILTER_PTYPE +#include +#endif + +#ifndef UNUSED +#ifdef __GNUC__ +# define UNUSED(x) UNUSED_ ## x __attribute__((__unused__)) +#else +# define UNUSED(x) UNUSED_ ## x +#endif +#endif + +/* panda and pie incorrectly used astronomical angles. fixed 4/2004 */ +#define USE_ASTRO_ANGLE 0 + +/* we might want to avoid (x86) extended precision problems */ +#define USE_FPU_DOUBLE _FPUDBL_ +#if USE_FPU_DOUBLE +#include +static fpu_control_t _cw; +#define FPU_DOUBLE {fpu_control_t _cw2; _FPU_GETCW(_cw); _cw2 = _cw & ~_FPU_EXTENDED; _cw2 |= _FPU_DOUBLE; _FPU_SETCW(_cw2);} +#define FPU_RESTORE {_FPU_SETCW(_cw);} +#else +#define FPU_DOUBLE +#define FPU_RESTORE +#endif + +/* add to FilterOpen to cause this module to be loaded for dynamic linking */ +static int imregno=0; +void initimregions(void) +{ + imregno++; + return; +} + +static void markx(GFilt g, int UNUSED(sno), int flag, int type, int x, int y) +{ + /* don't mark exclude regions */ + if( type == TOK_EREG ) + return; + /* for include, we might extend the x limits */ + if( flag ){ + if( x <= g->x0s[y] ) + g->x0s[y] = max(x,g->x0); + if( x >= g->x1s[y] ) + g->x1s[y] = min(x,g->x1); + } + /* for exclude, we have to look at the full line */ + else{ + g->x0s[y] = g->x0; + g->x1s[y] = g->x1; + } +} + +static void marky(GFilt g, int sno, int flag, int type) +{ + int i; + /* don't mark exclude regions */ + if( type == TOK_EREG ) + return; + /* mark include shape */ + if( flag ){ + for(i=max(g->y0,g->shapes[sno].ystart); + i<=min(g->y1,g->shapes[sno].ystop); + i++) + g->ybuf[i] = 1; + } + /* mark exclude shape */ + else{ + for(i=g->y0; i<=g->shapes[sno].ystart-1; i++) + g->ybuf[i] = 1; + for(i=g->shapes[sno].ystop+1; i<=g->y1; i++) + g->ybuf[i] = 1; + } +} + +static int +imagemaskcmp(const void *s1, const void *s2) +{ + FilterMask f1 = (FilterMask)s1; + FilterMask f2 = (FilterMask)s2; + + if( f1->y < f2->y ){ + return -1; + } + else if( f1->y > f2->y ){ + return 1; + } + else{ + if( f1->xstart < f2->xstart ){ + return -1; + } + else{ + return 1; + } + } +} + +/* ***************************** shape support ***************************** */ + +static void quadeq(double a, double b, double c, + double *x1, double *x2, int *nr, int *nc) +{ + double dis, q; + if( feq(a,0.0) ){ + *nc = 0; + if( feq(b,0.0) ){ + *nr = 0; *x1 = 0.0; + } + else{ + *nr = 1; *x1 = -c / b; + } + *x2 = *x1; + } + else{ + dis = b*b - 4.0 * a * c; + if( dis > 0.0 ){ + *nr = 2; *nc = 0; + dis = sqrt(dis); + if( b < 0.0 ) dis = -dis; + q = -0.5 * (b + dis); + *x1 = q/a; *x2 = c/q; + if(*x1 > *x2){ + q = *x1; *x1 = *x2; *x2 = q; + } + } + else if( feq(dis,0.0) ){ + *nr = 1; *nc = 0; *x1 = - 0.5 * b / a; *x2 = *x1; + } + else{ + *nr = 0; *nc = 2; *x1 = - 0.5 * b / a; *x2 = 0.5 * sqrt(-dis) / a; + } + } +} + +static void rgs_mark(GFilt g, Scan *scanlist, + int sno, int flag, int type, int xval, int yval ) +{ + Scan scanmark, mark; + /* since yval is used as an index, make sure its within limits */ + if(yval < g->y0) yval = g->y0; + if(yval > g->y1) yval = g->y1; + mark = (Scan)calloc(1, sizeof(ScanRec)); + mark->x = xval; + /* sanity check */ + if( !scanlist ) return; + /* starts are installed at back of list for given x */ + if( !scanlist[yval] || ((scanlist[yval])->x > xval) ){ + mark->next = scanlist[yval]; + scanlist[yval] = mark; + } else { + scanmark = scanlist[yval]; + while( scanmark->next && ((scanmark->next)->x < xval) ) + scanmark = scanmark->next; + mark->next = scanmark->next; + scanmark->next = mark; + } + markx(g, sno, flag, type, xval, yval); +} + +static void rgs_segment(GFilt g, Scan *scanlist, int width, int height, + int sno, int flag, int type, + double x1, double y1, double x2, double y2) +{ + int ystart, ystop, yval, xval; + double invslope, xoffset; + + ystart = PIXINCL(y1); + if( ystart < 1 ) ystart = 1; + /* note: PIXINCL(stop) is 1st pixel not counted */ + ystop = PIXINCL(y2) - 1; + if( ystop > height ) ystop = height; + /* ignore segment if there is no positive slope in integer coords */ + if( (ystart > ystop) || (ystop < 1) ) + return; + /* use inverse slope (run/rise) to get x given y with a multiply */ + invslope = (x1 - x2) / (y1 - y2); + xoffset = x1 + ((ystart - y1) * invslope); + for(yval=ystart; yval<=ystop; yval++){ + xval = PIXINCL(xoffset); + /* clip line to edges of image area (actually bend line) */ + if(xval < 1) xval = 1; + if(xval > width) xval = width + 1; + rgs_mark(g, scanlist, sno, flag, type, xval, yval); + xoffset = xoffset + invslope; + } +} + +static void _polygoni(GFilt g, int qt, int UNUSED(rno), int sno, int flag, + int type, double *vx, double *vy, int count) +{ + int i, j; + double xlo, xhi; + double ylo, yhi; + +#ifdef ALREADY_DONE + /* divide by block factor to get real endpoints */ + for(i=0; ixmin)/g->block + 1.0; + vy[i] = (vy[i] - g->ymin)/g->block + 1.0; + } +#endif + /* find the limits */ + xlo = vx[0]; + xhi = xlo; + ylo = vy[0]; + yhi = ylo; + for(i=0; i xhi) xhi = vx[i]; + if(vx[i] < xlo) xlo = vx[i]; + if(vy[i] > yhi) yhi = vy[i]; + if(vy[i] < ylo) ylo = vy[i]; + } + if( qt && (sno > 1) ){ + g->shapes[sno].ystart = g->shapes[sno-1].ystart; + g->shapes[sno].ystop = g->shapes[sno-1].ystop; + } + else{ + g->shapes[sno].ystart = max(g->y0,PIXINCL(ylo)); + g->shapes[sno].ystop = min(g->y1,PIXINCL(yhi) - 1); + } + g->shapes[sno].scanlist = (Scan *)calloc(g->y1+1, sizeof(Scan)); + marky(g, sno, flag, type); + + /* mark all horizontal segment crossings */ + /* start with segment between last and first point */ + j = count-1; + for(i=0; i vy[j]){ + rgs_segment(g, g->shapes[sno].scanlist, g->x1, g->y1, + sno, flag, type, vx[j], vy[j], vx[i], vy[i]); + } + else{ + rgs_segment(g, g->shapes[sno].scanlist, g->x1, g->y1, + sno, flag, type, vx[i], vy[i], vx[j], vy[j]); + } + j = i; + } +} + +static int corner_vertex(int index, int width, int height, + double *x, double *y) +{ + switch (index) { + case 1: + *x = 0.0; + *y = height + 1; + break; + case 2: + *x = 0.0; + *y = 0.0; + break; + case 3: + *x = width + 1; + *y = 0.0; + break; + case 4: + *x = width + 1; + *y = height + 1; + default: + break; + } + index = index + 1; + if(index > 4) index = 1; + return(index); +} + +static int pie_intercept(int width, int height, double xcen, double ycen, + double angle, double *xcept, double *ycept) +{ + double angl, slope; /* l: angle and slope of ray */ + angl = angle; + /* put angles in normal range */ + while (angl < 0.0) + angl = angl + 360.0; + while (angl >= 360.0) + angl = angl - 360.0; + /* check for a horizontal angle */ +#if USE_ASTRO_ANGLE + if(fabs(angl - 90.0) < SMALL_NUMBER) { +#else + if(fabs(angl - 180.0) < SMALL_NUMBER) { +#endif + *xcept = 0.0; + *ycept = ycen; + return(2); + } +#if USE_ASTRO_ANGLE + if(fabs(angl - 270.0) < SMALL_NUMBER) { +#else + if(fabs(angl - 0.0) < SMALL_NUMBER) { +#endif + *xcept = width + 1; + *ycept = ycen; + return(4); + } +#if USE_ASTRO_ANGLE + /* convert to a Cartesian angle */ + angl = angl + 90.0; +#endif + if(angl >= 360.0) + angl = angl - 360.0; + if(angl < 180.0) { + *ycept = height + 1; + /* rule out vertical line */ + if(fabs(angl - 90.0) < SMALL_NUMBER) { + *xcept = xcen; + return(1); + } + } else { + *ycept = 0.0; + /* rule out vertical line */ + if(fabs(angl - 270.0) < SMALL_NUMBER) { + *xcept = xcen; + return(3); + } + } + /* convert to radians */ + angl = (angl / 180.0) * M_PI; + /* calculate slope */ + slope = tan(angl); + /* calculate intercept with designated y edge */ + *xcept = xcen + ((*ycept - ycen) / slope); + if(*xcept < 0) { + *ycept = (ycen - (xcen * slope)); + *xcept = 0.0; + return(2); + } else if(*xcept > (width + 1)) { + *ycept = (ycen + ((width + 1 - xcen) * slope)); + *xcept = width + 1; + return(4); + } else { + if(*ycept < height) + return(3); + else + return(1); + } +} + +void _impiei(GFilt g, int qt, int rno, int sno, int flag, int type, + double UNUSED(x), double UNUSED(y), + double xcen, double ycen, double angle1, double angle2) +{ + int width, height; /* l: image mask width and height */ + double sweep; /* l: sweep between cut angles */ + double vx[7], vy[7]; /* l: arrays of vertices for polygon */ + int count; /* l: number of polygon vertices */ + int intrcpt1, intrcpt2; /* l: side intercepted by each cut */ + double x2, y2; /* l: coordinates of second intercept */ + + /* NB: do not use x and y variables, they have bogus values */ + /* divide by block factor to get "real" parameters */ + xcen = (xcen - g->xmin)/g->block + 1.0; + ycen = (ycen - g->ymin)/g->block + 1.0; + /* temps */ + width = g->x1; + height = g->y1; + /* start listing vertices of polygon */ + vx[0] = xcen; + vy[0] = ycen; + sweep = angle2 - angle1; + /* if sweep is too small to be noticed, don't bother */ + if(fabs(sweep) < SMALL_NUMBER) + return; + if (sweep < 0.0) sweep = sweep + 360.0; + intrcpt1 = pie_intercept(width, height, xcen, ycen, angle1, + &(vx[1]), &(vy[1])); + intrcpt2 = pie_intercept(width, height, xcen, ycen, angle2, + &x2, &y2); + count = 2; + /* if angles intercept same side and slice is between them, no corners */ + /* else, mark corners until reaching side with second angle intercept */ + if((intrcpt1 != intrcpt2) || (sweep > 180.0)){ + do{ + intrcpt1 = corner_vertex(intrcpt1, width, height, + &(vx[count]), &(vy[count])); + count = count + 1; + }while(intrcpt1 != intrcpt2); + } + vx[count] = x2; + vy[count] = y2; + count++; + _polygoni(g, qt, rno, sno, flag, type, vx, vy, count); +} + +/* ***************************** shapes ********************************** */ + +void imannulusi(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, double iradius, double oradius) +{ + int yy; + double dval; + double xoff, yoff; + Scan *scanlist; + + /* NB: do not use x and y variables, they have bogus values */ + + if( iradius == 0 ){ + imcirclei(g, rno, sno, flag, type, x, y, xcen, ycen, oradius); + return; + } + /* divide by block factor to get "real" parameters */ + xcen = (xcen - g->xmin)/g->block + 1.0; + ycen = (ycen - g->ymin)/g->block + 1.0; + iradius /= (double)g->block; + oradius /= (double)g->block; + /* set y limits */ + if( PIXSTART(ycen - oradius) < PIXSTOP(ycen + oradius) ){ + g->shapes[sno].ystart = max(g->y0,PIXSTART(ycen - oradius)); + g->shapes[sno].ystop = min(g->y1,PIXSTOP(ycen + oradius)); + } + else{ + g->shapes[sno].ystart = min(g->y1,PIXSTOP(ycen + oradius)); + g->shapes[sno].ystop = max(g->y0,PIXSTART(ycen - oradius)); + } + g->shapes[sno].scanlist = (Scan *)calloc(g->y1+1, sizeof(Scan)); + scanlist = g->shapes[sno].scanlist; + marky(g, sno, flag, type); + /* calculate start/stop values for each y line */ + for(yy=g->shapes[sno].ystart; yy<=g->shapes[sno].ystop; yy++){ + yoff = PIXCEN(yy) - ycen; + if( (dval=(oradius * oradius) - (yoff * yoff)) > 0.0 ){ + xoff = sqrt(dval); + if( PIXSTART(xcen - xoff) <= PIXSTOP(xcen + xoff) ){ + rgs_mark(g, scanlist, sno, flag, type, PIXSTART(xcen - xoff), yy); + rgs_mark(g, scanlist, sno, flag, type, PIXSTOP(xcen + xoff), yy); + } + if( (dval=(iradius * iradius) - (yoff * yoff)) > 0.0 ){ + xoff = sqrt(dval); + if( PIXSTART(xcen - xoff) <= PIXSTOP(xcen + xoff) ){ + rgs_mark(g, scanlist, sno, flag, type, PIXSTART(xcen - xoff), yy); + rgs_mark(g, scanlist, sno, flag, type, PIXSTOP(xcen + xoff), yy); + } + } + } + } +} + +int imannulus(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, double iradius, double oradius) +{ + Scan scan; + + if( iradius == 0 ){ + return(imcircle(g, rno, sno, flag, type, x, y, xcen, ycen, oradius)); + } + if( g->evsect ){ + if( g->usebinsiz ){ + x = (int)((x - g->tlminx)/g->binsizx + 1.0); + y = (int)((y - g->tlminy)/g->binsizy + 1.0); + } + else{ + x = (int)((x - g->tlminx) + 1.0); + y = (int)((y - g->tlminy) + 1.0); + } + x = (int)((x - g->xmin)/g->block + 1.0); + y = (int)((y - g->ymin)/g->block + 1.0); + if(y < g->y0) return 0; + if(y > g->y1) return 0; + if(x < g->x0) return 0; + if(x > g->x1) return 0; + } + if( flag ){ + if(y < g->shapes[sno].ystart ) return 0; + if(y > g->shapes[sno].ystop ) return 0; + } + scan = g->shapes[sno].scanlist[(int)y]; + if( (scan && + ((y >= g->shapes[sno].ystart) && (y <= g->shapes[sno].ystop)) && + (scan->next->next ? + (((x >= scan->x) && (x <= scan->next->next->next->x)) && + !((x >= scan->next->x) && (x <= scan->next->next->x))) : + ((x >= scan->x) && (x <= scan->next->x)))) + ==flag ){ + if( rno && flag ) g->rid = rno; + return 1; + } + else + return 0; +} + +void imboxi(GFilt g, int rno, int sno, int flag, int type, + double UNUSED(x), double UNUSED(y), + double xcen, double ycen, double xwidth, double yheight, + double angle) +{ + double angl; /* l: Cartesian angle in radians */ + double half_width, half_height;/* l: radii (1/2 width and height) */ + double cosangl, sinangl; /* l: sine, cosine of the Cartesian angle */ + double hw_cos, hw_sin; /* l: products of half_width with sin, cos */ + double hh_cos, hh_sin; /* l: products of half_height with sin, cos */ + double cornerx[4], cornery[4]; /* l: arrays of x and y coords of 4 corners */ + + /* NB: do not use x and y variables, they have bogus values */ + if( (xwidth == 0) && (yheight==0) ){ + return; + } + /* divide by block factor to get "real" parameters */ + xcen = (xcen - g->xmin)/g->block + 1.0; + ycen = (ycen - g->ymin)/g->block + 1.0; + xwidth /= (double)g->block; + yheight /= (double)g->block; +#if USE_ASTRO_ANGLE + /* convert to a Cartesian angle; save angle for use in multi or slices */ + angl = angle + 90.0; +#else + angl = angle; +#endif + while (angl >= 360.0) angl = angl - 360.0; + /* convert to radians */ + angl = (angl / 180.0) * M_PI; + sinangl = sin (angl); + cosangl = cos (angl); +#if USE_ASTRO_ANGLE + /* since we rotate by 90.0 degrees to get from astro angle to cartesian, */ + /* we also need to switch the width and height. we do this secretly so */ + /* that the display will turn out right, by doing it in the half terms */ + half_width = yheight / 2.0; + half_height = xwidth / 2.0; +#else + half_width = xwidth / 2.0; + half_height = yheight / 2.0; +#endif + hw_cos = half_width * cosangl; + hw_sin = half_width * sinangl; + hh_cos = half_height * cosangl; + hh_sin = half_height * sinangl; +#if USE_ASTRO_ANGLE + cornerx[0] = xcen - hw_cos - hh_sin; + cornery[0] = ycen - hw_sin + hh_cos; + cornerx[1] = xcen + hw_cos - hh_sin; + cornery[1] = ycen + hw_sin + hh_cos; + cornerx[2] = xcen + hw_cos + hh_sin; + cornery[2] = ycen + hw_sin - hh_cos; + cornerx[3] = xcen - hw_cos + hh_sin; + cornery[3] = ycen - hw_sin - hh_cos; +#else + cornerx[0] = xcen - hw_cos + hh_sin; + cornery[0] = ycen - hh_cos - hw_sin; + cornerx[1] = xcen - hw_cos - hh_sin; + cornery[1] = ycen + hh_cos - hw_sin; + cornerx[2] = xcen + hw_cos - hh_sin; + cornery[2] = ycen + hh_cos + hw_sin; + cornerx[3] = xcen + hw_cos + hh_sin; + cornery[3] = ycen - hh_cos + hw_sin; +#endif + _polygoni(g, 0, rno, sno, flag, type, cornerx, cornery, 4); +} + +int imbox(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double UNUSED(xcen), double UNUSED(ycen), + double xwidth, double yheight, + double UNUSED(angle)) +{ + if( (xwidth == 0) && (yheight==0) ){ + return(!flag); + } + return impolygon(g, rno, sno, flag, type, x, y); +} + +void imcirclei(GFilt g, int UNUSED(rno), int sno, int flag, int type, + double UNUSED(x), double UNUSED(y), + double xcen, double ycen, double radius) +{ + int yy; + double dval; + double xoff, yoff; + Scan *scanlist; + + /* NB: do not use x and y variables, they have bogus values */ + if( radius == 0 ){ + return; + } + /* divide by block factor to get "real" parameters */ + xcen = (xcen - g->xmin)/g->block + 1.0; + ycen = (ycen - g->ymin)/g->block + 1.0; + radius /= (double)g->block; + /* set y limits */ + if( PIXSTART(ycen - radius) < PIXSTOP(ycen + radius) ){ + g->shapes[sno].ystart = max(g->y0,PIXSTART(ycen - radius)); + g->shapes[sno].ystop = min(g->y1,PIXSTOP(ycen + radius)); + } + else{ + g->shapes[sno].ystart = min(g->y1,PIXSTOP(ycen + radius)); + g->shapes[sno].ystop = max(g->y0,PIXSTART(ycen - radius)); + } + g->shapes[sno].scanlist = (Scan *)calloc(g->y1+1, sizeof(Scan)); + scanlist = g->shapes[sno].scanlist; + marky(g, sno, flag, type); + /* calculate start/stop values for each y line */ + for(yy=g->shapes[sno].ystart; yy<=g->shapes[sno].ystop; yy++){ + yoff = PIXCEN(yy) - ycen; + if( (dval=(radius * radius) - (yoff * yoff))>=0.0 ){ + xoff = sqrt(dval); + if( PIXSTART(xcen - xoff) <= PIXSTOP(xcen + xoff) ){ + rgs_mark(g, scanlist, sno, flag, type, PIXSTART(xcen - xoff), yy); + rgs_mark(g, scanlist, sno, flag, type, PIXSTOP(xcen + xoff), yy); + } + } + } +} + +int imcircle(GFilt g, int rno, int sno, int flag, int UNUSED(type), + double x, double y, + double UNUSED(xcen), double UNUSED(ycen), double radius) +{ + Scan scan; + + if( radius == 0 ){ + return(!flag); + } + if( g->evsect ){ + if( g->usebinsiz ){ + x = (int)((x - g->tlminx)/g->binsizx + 1.0); + y = (int)((y - g->tlminy)/g->binsizy + 1.0); + } + else{ + x = (int)((x - g->tlminx) + 1.0); + y = (int)((y - g->tlminy) + 1.0); + } + x = (int)((x - g->xmin)/g->block + 1.0); + y = (int)((y - g->ymin)/g->block + 1.0); + if(y < g->y0) return 0; + if(y > g->y1) return 0; + if(x < g->x0) return 0; + if(x > g->x1) return 0; + } + if( flag ){ + if(y < g->shapes[sno].ystart ) return 0; + if(y > g->shapes[sno].ystop ) return 0; + } + scan = g->shapes[sno].scanlist[(int)y]; + if( (scan && + ((y>=g->shapes[sno].ystart) && (y<=g->shapes[sno].ystop)) && + ((x >= scan->x) && (x <= (scan->next)->x))) == flag ){ + if( rno && flag ) g->rid = rno; + return 1; + } + else{ + return 0; + } +} + +void imellipsei(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, double xrad, double yrad, + double angle) +{ + int yy; + int nr, nc; + double yhi; + double yoff; + double xboff, xfoff; + double angl; + double sinangl, cosangl; + double cossq, sinsq, xradsq, yradsq; + double a, b_partial, c_partial; + double b, c; + Scan *scanlist; + + /* NB: do not use x and y variables, they have bogus values */ + + if( xrad == yrad ){ + imcirclei(g, rno, sno, flag, type, x, y, xcen, ycen, xrad); + return; + } + /* divide by block factor to get "real" parameters */ + xcen = (xcen - g->xmin)/g->block + 1.0; + ycen = (ycen - g->ymin)/g->block + 1.0; + xrad /= (double)g->block; + yrad /= (double)g->block; + /* set worst case limits (xrad axis parallel to vertical axis) */ +#if USE_ASTRO_ANGLE + /* convert to a Cartesian angle; save "angle" for use by other routines */ + angl = angle + 90.0; +#else + angl = angle; +#endif + while( angl >= 360.0 ) + angl = angl - 360.0; + /* convert to radians */ + angl = (angl / 180.0) * M_PI; + sinangl = sin(angl); + cosangl = cos(angl); + /* calculate approximate y limits */ + /* choose lesser of containing rotbox and circle */ + FPU_DOUBLE +#if USE_ASTRO_ANGLE + yhi = fabs(sinangl * yrad) + fabs(cosangl * xrad); +#else + yhi = fabs(sinangl * xrad) + fabs(cosangl * yrad); +#endif + yhi = min(yhi, max(yrad, xrad)); + /* set y limits */ + if( PIXSTART(ycen - yhi) < PIXSTOP(ycen + yhi) ){ + g->shapes[sno].ystart = max(g->y0,PIXSTART(ycen - yhi)); + g->shapes[sno].ystop = min(g->y1,PIXSTOP(ycen + yhi)); + } + else{ + g->shapes[sno].ystart = min(g->y1,PIXSTOP(ycen + yhi)); + g->shapes[sno].ystop = max(g->y0,PIXSTART(ycen - yhi)); + } + FPU_RESTORE + g->shapes[sno].scanlist = (Scan *)calloc(g->y1+1, sizeof(Scan)); + scanlist = g->shapes[sno].scanlist; + marky(g, sno, flag, type); + /* prepare partials for quadratic equation solutions to coordinates */ + cossq = cosangl * cosangl; + sinsq = sinangl * sinangl; +#if USE_ASTRO_ANGLE + /* because we rotate by 90.0 degrees to get from astro angle to */ + /* cartesian, we also need to switch the x and y axes. we do this */ + /* secretly so that the display will turn out right, by doing it in */ + /* the sq terms */ + xradsq = yrad * yrad; + yradsq = xrad * xrad; +#else + xradsq = xrad * xrad; + yradsq = yrad * yrad; +#endif + /* fill in as much of a,b,c as we can */ + a = (cossq / xradsq) + (sinsq / yradsq); + b_partial = (2.0 * sinangl) * ((cosangl / xradsq) - (cosangl / yradsq)); + c_partial = (sinsq / xradsq) + (cossq / yradsq); + /* calculate start/stop values for each y line */ + for(yy=g->shapes[sno].ystart; yy<=g->shapes[sno].ystop; yy++){ + yoff = yy - ycen; + b = b_partial * yoff; + c = (c_partial * yoff * yoff) - 1.0; + /* solve quadratic */ + quadeq (a, b, c, &xboff, &xfoff, &nr, &nc); + /* if real roots */ + if( nr != 0 ) { + /* translate x coordinates */ + rgs_mark(g, scanlist, sno, flag, type, PIXSTART(xcen + xboff), yy); + rgs_mark(g, scanlist, sno, flag, type, PIXSTOP(xcen + xfoff), yy); + } + } +} + +int imellipse(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, double xrad, double yrad, + double UNUSED(angle)) +{ + Scan scan; + + if( xrad == yrad ){ + return(imcircle(g, rno, sno, flag, type, x, y, xcen, ycen, xrad)); + } + if( g->evsect ){ + if( g->usebinsiz ){ + x = (int)((x - g->tlminx)/g->binsizx + 1.0); + y = (int)((y - g->tlminy)/g->binsizy + 1.0); + } + else{ + x = (int)((x - g->tlminx) + 1.0); + y = (int)((y - g->tlminy) + 1.0); + } + x = (int)((x - g->xmin)/g->block + 1.0); + y = (int)((y - g->ymin)/g->block + 1.0); + if(y < g->y0) return 0; + if(y > g->y1) return 0; + if(x < g->x0) return 0; + if(x > g->x1) return 0; + } + if( flag ){ + if(y < g->shapes[sno].ystart ) return 0; + if(y > g->shapes[sno].ystop ) return 0; + } + scan = g->shapes[sno].scanlist[(int)y]; + FPU_DOUBLE + if( (scan && + ((y>=g->shapes[sno].ystart) && (y<=g->shapes[sno].ystop)) && + ((x >= scan->x) && (x <= (scan->next)->x))) == flag ){ + if( rno && flag ) g->rid = rno; + FPU_RESTORE + return 1; + } + else{ + FPU_RESTORE + return 0; + } +} + +void imfieldi(GFilt g, int UNUSED(rno), int sno, int flag, int type, + double UNUSED(x), double UNUSED(y)) +{ + int yy; + Scan *scanlist; + + /* NB: do not use x and y variables, they have bogus values */ + g->shapes[sno].ystart = g->y0; + g->shapes[sno].ystop = g->y1; + g->shapes[sno].scanlist = (Scan *)calloc(g->y1+1, sizeof(Scan)); + scanlist = g->shapes[sno].scanlist; + marky(g, sno, flag, type); + /* calculate start/stop values for each y line */ + for(yy=g->shapes[sno].ystart; yy<=g->shapes[sno].ystop; yy++){ + rgs_mark(g, scanlist, sno, flag, type, g->x0, yy); + rgs_mark(g, scanlist, sno, flag, type, g->x1, yy); + } +} + +int imfield(GFilt g, int rno, int UNUSED(sno), int flag, int UNUSED(type), + double UNUSED(x), double UNUSED(y)) +{ + if( flag ){ + if( rno && flag ) g->rid = rno; + return 1; + } + else{ + return 0; + } +} + +void imlinei(GFilt g, int UNUSED(rno), int sno, int flag, int type, + double UNUSED(x), double UNUSED(y), + double x1, double y1, double x2, double y2) +{ + double vx[2]; + double vy[2]; + int xval, yval; + double invslope, xoffset; + + /* NB: do not use x and y variables, they have bogus values */ + /* divide by block factor to get "real" parameters */ + x1 = (x1 - g->xmin)/g->block + 1.0; + y1 = (y1 - g->ymin)/g->block + 1.0; + x2 = (x2 - g->xmin)/g->block + 1.0; + y2 = (y2 - g->ymin)/g->block + 1.0; + /* order by increasing y */ + if( y1 < y2 ){ + vx[0] = x1; + vy[0] = y1; + vx[1] = x2; + vy[1] = y2; + } + else{ + vx[0] = x2; + vy[0] = y2; + vx[1] = x1; + vy[1] = y1; + } + /* set y limits */ + g->shapes[sno].ystart = PIXNUM(vy[0]); + g->shapes[sno].ystop = PIXNUM(vy[1]); + g->shapes[sno].scanlist = (Scan *)calloc(g->y1+1, sizeof(Scan)); + marky(g, sno, flag, type); + if( feq(vy[0],vy[1]) ){ + rgs_mark(g, g->shapes[sno].scanlist, sno, flag, type, + (int)min(vx[0],vx[1]), (int)vy[0]); + rgs_mark(g, g->shapes[sno].scanlist, sno, flag, type, + (int)max(vx[0],vx[1]), (int)vy[0]); + } + else{ + /* mark all horizontal segment crossings */ + invslope = (vx[0] - vx[1]) / (vy[0] - vy[1]); + xoffset = vx[0]; + for(yval=vy[0]; yval<=vy[1]; yval++){ + xval = xoffset; + rgs_mark(g, g->shapes[sno].scanlist, sno, flag, type, xval, yval); + xoffset = xoffset + invslope; + } + } +} + +int imline(GFilt g, int rno, int sno, int flag, int UNUSED(type), + double x, double y, + double UNUSED(x1), double UNUSED(y1), + double UNUSED(x2), double UNUSED(y2)) +{ + Scan scan; + + if( g->evsect ){ + if( g->usebinsiz ){ + x = (int)((x - g->tlminx)/g->binsizx + 1.0); + y = (int)((y - g->tlminy)/g->binsizy + 1.0); + } + else{ + x = (int)((x - g->tlminx) + 1.0); + y = (int)((y - g->tlminy) + 1.0); + } + x = (int)((x - g->xmin)/g->block + 1.0); + y = (int)((y - g->ymin)/g->block + 1.0); + if(y < g->y0) return 0; + if(y > g->y1) return 0; + if(x < g->x0) return 0; + if(x > g->x1) return 0; + } + if( flag ){ + if(y < g->shapes[sno].ystart ) return 0; + if(y > g->shapes[sno].ystop ) return 0; + } + scan = g->shapes[sno].scanlist[(int)y]; + if( (scan && + ((x==(int)scan->x) || + (scan->next&&((x>=(int)scan->x)&&(x<=(int)scan->next->x)))))==flag ) { + if( rno && flag ) g->rid = rno; + return 1; + } + else + return 0; +} + +void impiei(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, double angle1, double angle2) +{ + _impiei(g, 0, rno, sno, flag, type, x, y, xcen, ycen, angle1, angle2); +} + +int impie(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double UNUSED(xcen), double UNUSED(ycen), + double UNUSED(angle1), double UNUSED(angle2)) +{ + return impolygon(g, rno, sno, flag, type, x, y); +} + +void imqtpiei(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, double angle1, double angle2) +{ + _impiei(g, 1, rno, sno, flag, type, x, y, xcen, ycen, angle1, angle2); +} + +int imqtpie(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double UNUSED(xcen), double UNUSED(ycen), + double UNUSED(angle1), double UNUSED(angle2)) +{ + return impolygon(g, rno, sno, flag, type, x, y); +} + +void impointi(GFilt g, int UNUSED(rno), int sno, int flag, int type, + double UNUSED(x), double UNUSED(y), + double xcen, double ycen) +{ + /* NB: do not use x and y variables, they have bogus values */ + /* divide by block factor to get "real" parameters */ + xcen = (xcen - g->xmin)/g->block + 1.0; + ycen = (ycen - g->ymin)/g->block + 1.0; + /* set y limits */ + g->shapes[sno].ystart = PIXNUM(ycen); + g->shapes[sno].ystop = PIXNUM(ycen); + g->shapes[sno].scanlist = (Scan *)calloc(g->y1+1, sizeof(Scan)); + marky(g, sno, flag, type); + rgs_mark(g, g->shapes[sno].scanlist, sno, flag, type, + PIXNUM(xcen), PIXNUM(ycen)); +} + +int impoint(GFilt g, int rno, int sno, int flag, int UNUSED(type), + double x, double y, + double UNUSED(xcen), double UNUSED(ycen)) +{ + Scan scan; + + if( g->evsect ){ + if( g->usebinsiz ){ + x = (int)((x - g->tlminx)/g->binsizx + 1.0); + y = (int)((y - g->tlminy)/g->binsizy + 1.0); + } + else{ + x = (int)((x - g->tlminx) + 1.0); + y = (int)((y - g->tlminy) + 1.0); + } + x = (int)((x - g->xmin)/g->block + 1.0); + y = (int)((y - g->ymin)/g->block + 1.0); + if(y < g->y0) return 0; + if(y > g->y1) return 0; + if(x < g->x0) return 0; + if(x > g->x1) return 0; + } + if( flag ){ + if(y < g->shapes[sno].ystart ) return 0; + if(y > g->shapes[sno].ystop ) return 0; + } + scan = g->shapes[sno].scanlist[(int)y]; + if( (scan && + (y == (int)g->shapes[sno].ystart) && + (x == (int)scan->x))==flag ) { + if( rno && flag ) g->rid = rno; + return 1; + } + else + return 0; +} + +#ifdef __STDC__ +void +impolygoni(GFilt g, int rno, int sno, int flag, int type, + double UNUSED(x), double y, ...) +{ + double *vx=NULL, *vy=NULL; + int count, maxcount; + va_list args; + va_start(args, y); +#else +void impolygoni(va_alist) va_dcl +{ + GFilt g; + int rno, sno, flag, type; + double x, y; + double *vx=NULL, *vy=NULL; + int count, maxcount; + va_list args; + va_start(args); + g = va_arg(args, GFilt); + rno = va_arg(args, int); + sno = va_arg(args, int); + flag = va_arg(args, int); + type = va_arg(args, int); + x = va_arg(args, double); + y = va_arg(args, double); +#endif + /* NB: do not use x and y variables, they have bogus values */ + /* allocate space for x,y arguments */ + maxcount = MASKINC; + vx = (double *)calloc(maxcount, sizeof(double)); + vy = (double *)calloc(maxcount, sizeof(double)); + /* look for x,y arguments */ + count = 0; + while( 1 ){ + if( (count + 1) >= maxcount ){ + maxcount += MASKINC; + vx = (double *)realloc(vx, maxcount*sizeof(double)); + vy = (double *)realloc(vy, maxcount*sizeof(double)); + } + vx[count] = va_arg(args, double); + vy[count] = va_arg(args, double); + if( feq(vx[count],PSTOP) && feq(vy[count],PSTOP) ) + break; + vx[count] = (vx[count] - g->xmin)/g->block + 1.0; + vy[count] = (vy[count] - g->ymin)/g->block + 1.0; + count ++; + } + va_end(args); + /* realloc to actual size */ + vx = (double *)realloc(vx, count*sizeof(double)); + vy = (double *)realloc(vy, count*sizeof(double)); + /* call the common routine */ + _polygoni(g, 0, rno, sno, flag, type, vx, vy, count); + if( vx ) free(vx); + if( vy ) free(vy); +} + +#ifdef __STDC__ +int +impolygon(GFilt g, int rno, int sno, int flag, int UNUSED(type), + double x, double y, ...) +{ + int crossings; + Scan scan; + va_list args; + va_start(args, y); +#else +int impolygon(va_alist) va_dcl +{ + GFilt g; + int rno, sno, flag, type; + double x, y; + int crossings; + Scan scan; + va_list args; + va_start(args); + g = va_arg(args, GFilt); + rno = va_arg(args, int); + sno = va_arg(args, int); + flag = va_arg(args, int); + type = va_arg(args, int); + x = va_arg(args, double); + y = va_arg(args, double); +#endif + va_end(args); + if( g->evsect ){ + if( g->usebinsiz ){ + x = (int)((x - g->tlminx)/g->binsizx + 1.0); + y = (int)((y - g->tlminy)/g->binsizy + 1.0); + } + else{ + x = (int)((x - g->tlminx) + 1.0); + y = (int)((y - g->tlminy) + 1.0); + } + x = (int)((x - g->xmin)/g->block + 1.0); + y = (int)((y - g->ymin)/g->block + 1.0); + if(y < g->y0) return 0; + if(y > g->y1) return 0; + if(x < g->x0) return 0; + if(x > g->x1) return 0; + } + if( flag ){ + if(y < g->shapes[sno].ystart ) return 0; + if(y > g->shapes[sno].ystop ) return 0; + } + /* no initialization of x for this row, just jump right in */ + if( (y>=g->shapes[sno].ystart)&&(y<=g->shapes[sno].ystop) ){ + crossings = 0; + for(scan=g->shapes[sno].scanlist[(int)y]; scan; scan=scan->next){ + if( x >= scan->x ) + crossings++; + else + break; + } + if( (crossings%2) == flag ){ + if( rno && flag ) g->rid = rno; + return 1; + } + else{ + return 0; + } + } + else{ + return !flag; + } +} + +void imnannulusi(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, + double lo, double hi, int n) +{ + int i; + int xsno; + double dinc; + + /* NB: do not use x and y variables, they have bogus values */ + + /* get limits */ + dinc = (hi - lo)/n; + xsno = (g->nshapes+1)+((sno-1)*XSNO); + /* init all shapes */ + imannulusi(g, 0, xsno, flag, type, x, y, xcen, ycen, lo, hi); + for(i=0; inshapes+1)+((sno-1)*XSNO); + /* init all shapes */ + imboxi(g, 0, xsno, flag, type, x, y, xcen, ycen, hix, hiy, ang); + imboxi(g, 0, xsno+1, flag, type, x, y, xcen, ycen, lox, loy, ang); + for(i=0; inshapes+1)+((sno-1)*XSNO); + /* init all shapes */ + imellipsei(g, 0, xsno, flag, type, x, y, xcen, ycen, hix, hiy, ang); + imellipsei(g, 0, xsno+1, flag, type, x, y, xcen, ycen, lox, loy, ang); + for(i=0; i hi ) lo -= 360.0; + dinc = (hi - lo)/n; + xsno = (g->nshapes+1)+((sno-1)*XSNO); + /* init all shapes */ + impiei(g, 0, xsno, flag, type, x, y, xcen, ycen, lo, hi); + for(i=0; i anghi ) anglo -= 360.0; + ainc = (anghi - anglo)/angn; + ahi = (int)angn; + rinc = (radhi - radlo)/radn; + rhi = (int)radn; + xsno = (g->nshapes+1)+((sno-1)*XSNO); + /* init pies and annuli */ + imannulusi(g, 0, xsno, flag, type, x, y, xcen, ycen, radlo, radhi); + imqtpiei(g, 0, xsno+1, flag, type, x, y, xcen, ycen, anglo, anghi); + for(a=0; a anghi ) anglo -= 360.0; + ainc = (anghi - anglo)/angn; + ahi = (int)angn; + xinc = (xhi - xlo)/radn; + yinc = (yhi - ylo)/radn; + rhi = (int)radn; + xsno = (g->nshapes+1)+((sno-1)*XSNO); + /* init pies and ellipses */ + imboxi(g, 0, xsno, flag, type, x, y, xcen, ycen, xhi, yhi, ang); + imqtpiei(g, 0, xsno+1, flag, type, x, y, xcen, ycen, anglo, anghi); + imboxi(g, 0, xsno+2, flag, type, x, y, xcen, ycen, xlo, ylo, ang); + for(a=0; a anghi ) anglo -= 360.0; + ainc = (anghi - anglo)/angn; + ahi = (int)angn; + xinc = (xhi - xlo)/radn; + yinc = (yhi - ylo)/radn; + rhi = (int)radn; + xsno = (g->nshapes+1)+((sno-1)*XSNO); + /* init pies and ellipses */ + imellipsei(g, 0, xsno, flag, type, x, y, xcen, ycen, xhi, yhi, ang); + imqtpiei(g, 0, xsno+1, flag, type, x, y, xcen, ycen, anglo, anghi); + imellipsei(g, 0, xsno+2, flag, type, x, y, xcen, ycen, xlo, ylo, ang); + for(a=0; anshapes+1)+((sno-1)*XSNO); + if( flag ){ + /* if its not somewhere inside the entire region we lose ... */ + if( !imannulus(g, 0, xsno, flag, type, x, y, xcen, ycen, lo, hi) ){ + return(0); + } + /* look through all of them to find the right one */ + for(i=0; inshapes+1)+((sno-1)*XSNO); + if( flag ){ + /* if its not somewhere inside the entire region we lose ... */ + if( !imbox(g, 0, xsno, flag, type, x, y, xcen, ycen, hix, hiy, ang) ){ + return(0); + } + /* if its in the inner region we lose */ + if( imbox(g, 0, xsno+1, flag, type, x, y, xcen, ycen, lox, loy, ang) ){ + return(0); + } + /* look through all of them to find the right one */ + for(i=0; inshapes+1)+((sno-1)*XSNO); + if( flag ){ + /* if its not somewhere inside the entire region we lose ... */ + if( !imellipse(g, 0, xsno, flag, type, x, y, xcen, ycen, hix, hiy, ang) ){ + return(0); + } + /* if its in the inner region we lose */ + if( imellipse(g, 0, xsno+1, flag, type, x, y, xcen, ycen, lox, loy, ang) ){ + return(0); + } + /* look through all of them to find the right one */ + for(i=0; i hi ) lo -= 360.0; + dinc = (hi - lo)/n; + xsno = (g->nshapes+1)+((sno-1)*XSNO); + if( flag ){ + /* check limits */ + if( !impie(g, 0, xsno, flag, type, x, y, xcen, ycen, lo, hi) ){ + return(0); + } + /* look through all of them to find the right one */ + for(i=0; i anghi ) anglo -= 360.0; + ainc = (anghi - anglo)/angn; + ahi = (int)angn; + rinc = (radhi - radlo)/radn; + rhi = (int)radn; + xsno = (g->nshapes+1)+((sno-1)*XSNO); + if( flag ){ + /* if its not somewhere inside the entire region we lose ... */ + if( !imannulus(g, 0, xsno, flag, type, x, y, xcen, ycen, radlo, radhi) || + !impie(g, 0, xsno+1, flag, type, x, y, xcen, ycen, anglo, anghi) ){ + return(0); + } + /* look through all of them to find the right one */ + for(a=1; a<=ahi; a++){ + for(r=1; r<=rhi; r++){ + if( imannulus(g, rno+n, sno+(2*n), flag, type, x, y, + xcen, ycen, radlo+((r-1)*rinc), radlo+(r*rinc)) && + impie(g, rno+n, sno+(2*n+1), flag, type, x, y, + xcen, ycen, anglo+((a-1)*ainc), anglo+(a*ainc)) ){ + return(1); + } + n++; + } + } + return(0); + } + else{ + /* if its not somewhere inside the entire region we win ... */ + if( !imannulus(g, 0, xsno, 1, type, x, y, xcen, ycen, radlo, radhi) ) + return(1); + else if( !impie(g, 0, xsno+1, 1, type, x, y, xcen, ycen, anglo, anghi) ){ + return(1); + } + else{ + return(0); + } + } +} + +int imbpanda(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, + double anglo, double anghi, double angn, + double xlo, double ylo, double xhi, double yhi, double radn, + double ang) +{ + + int a, r; + int ahi, rhi; + int xsno; + int n=0; + double ainc, xinc, yinc; + + /* get limits */ + anglo += ang; + anghi += ang; + while( anglo > anghi ) anglo -= 360.0; + ainc = (anghi - anglo)/angn; + ahi = (int)angn; + xinc = (xhi - xlo)/radn; + yinc = (yhi - ylo)/radn; + rhi = (int)radn; + xsno = (g->nshapes+1)+((sno-1)*XSNO); + if( flag ){ + /* if its not somewhere inside the entire region we lose ... */ + if( !imbox(g, 0, xsno, flag, type, x, y, xcen, ycen, xhi, yhi, + ang) ){ + return(0); + } + /* but if its in the inner region we lose */ + else if( imbox(g, 0, xsno+2, flag, type, x, y, xcen, ycen, xlo, ylo, + ang) ){ + return(0); + } + /* its in the box .. must also be in the pie */ + else if( !impie(g, 0, xsno+1, flag, type, x, y, xcen, ycen, anglo, anghi)){ + return(0); + } + /* look through all of them to find the right one */ + for(a=0; a anghi ) anglo -= 360.0; + ainc = (anghi - anglo)/angn; + ahi = (int)angn; + xinc = (xhi - xlo)/radn; + yinc = (yhi - ylo)/radn; + rhi = (int)radn; + xsno = (g->nshapes+1)+((sno-1)*XSNO); + if( flag ){ + /* if its not somewhere inside the entire region we lose ... */ + if( !imellipse(g, 0, xsno, flag, type, x, y, xcen, ycen, xhi, yhi, + ang) ){ + return(0); + } + /* but if its in the inner region we lose */ + else if( imellipse(g, 0, xsno+2, flag, type, x, y, xcen, ycen, xlo, ylo, + ang) ){ + return(0); + } + /* its in the ellipse .. must also be in the pie */ + else if( !impie(g, 0, xsno+1, flag, type, x, y, xcen, ycen, anglo, anghi)){ + return(0); + } + /* look through all of them to find the right one */ + for(a=0; anshapes+1)+((sno-1)*XSNO); + if( !g->shapes[xsno].xv ){ + maxpts = MASKINC; + g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double)); + g->shapes[xsno].nv = 0; + while( 1 ){ + if( g->shapes[xsno].nv >= maxpts ){ + maxpts += MASKINC; + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + maxpts*sizeof(double)); + } + g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double); + if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) && + feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){ + g->shapes[xsno].nv--; + break; + } + g->shapes[xsno].nv++; + } + va_end(args); + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + g->shapes[xsno].nv*sizeof(double)); + } + n = g->shapes[xsno].nv; + xv = g->shapes[xsno].xv; + /* this should be impossible ... */ + if( n == 2 ){ + imannulusi(g, rno, sno, flag, type, x, y, xcen, ycen, xv[0], xv[1]); + return; + } + imannulusi(g, 0, xsno, flag, type, x, y, xcen, ycen, xv[0], xv[n-1]); + for(i=0; i<(n-1); i++){ + imannulusi(g, rno+i, sno+i, flag, type, x, y, xcen, ycen, xv[i], xv[i+1]); + } +} + +#ifdef __STDC__ +void +imvboxi(GFilt g, int rno, int sno, int flag, int type, + double x, double y, double xcen, double ycen, ...) +{ + int i, j, n; + int maxpts; + int xsno; + double ang; + double *xv; + va_list args; + va_start(args, ycen); +#else +int imvboxi(va_alist) va_dcl +{ + GFilt g; + int rno, sno, flag, type; + double x, y; + double xcen, ycen; + double ang; + double *xv; + int i, j, n; + int maxpts; + int xsno; + va_list args; + va_start(args); + g = va_arg(args, GFilt); + rno = va_arg(args, int); + sno = va_arg(args, int); + flag = va_arg(args, int); + type = va_arg(args, int); + x = va_arg(args, double); + y = va_arg(args, double); + xcen = va_arg(args, double); + ycen = va_arg(args, double); +#endif + xsno = (g->nshapes+1)+((sno-1)*XSNO); + if( !g->shapes[xsno].xv ){ + maxpts = MASKINC; + g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double)); + g->shapes[xsno].nv = 0; + while( 1 ){ + if( g->shapes[xsno].nv >= maxpts ){ + maxpts += MASKINC; + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + maxpts*sizeof(double)); + } + g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double); + if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) && + feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){ + g->shapes[xsno].nv--; + break; + } + g->shapes[xsno].nv++; + } + va_end(args); + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + g->shapes[xsno].nv*sizeof(double)); + } + n = g->shapes[xsno].nv; + xv = g->shapes[xsno].xv; + ang = xv[--n]; + /* this should be impossible ... */ + if( n == 2 ){ + imboxi(g, rno, sno, flag, type, x, y, xcen, ycen, xv[0], xv[1], ang); + return; + } + imboxi(g, 0, xsno, flag, type, x, y, xcen, ycen, xv[n-2], xv[n-1], ang); + imboxi(g, 0, xsno+1, flag, type, x, y, xcen, ycen, xv[0], xv[1], ang); + for(i=2, j=0; inshapes+1)+((sno-1)*XSNO); + if( !g->shapes[xsno].xv ){ + maxpts = MASKINC; + g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double)); + g->shapes[xsno].nv = 0; + while( 1 ){ + if( g->shapes[xsno].nv >= maxpts ){ + maxpts += MASKINC; + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + maxpts*sizeof(double)); + } + g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double); + if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) && + feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){ + g->shapes[xsno].nv--; + break; + } + g->shapes[xsno].nv++; + } + va_end(args); + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + g->shapes[xsno].nv*sizeof(double)); + } + n = g->shapes[xsno].nv; + xv = g->shapes[xsno].xv; + ang = xv[--n]; + /* this should be impossible ... */ + if( n == 2 ){ + imellipsei(g, rno, sno, flag, type, x, y, xcen, ycen, xv[0], xv[1], ang); + return; + } + imellipsei(g, 0, xsno, flag, type, x, y, xcen, ycen, xv[n-2], xv[n-1], ang); + imellipsei(g, 0, xsno+1, flag, type, x, y, xcen, ycen, xv[0], xv[1], ang); + for(i=2, j=0; inshapes+1)+((sno-1)*XSNO); + if( !g->shapes[xsno].xv ){ + maxpts = MASKINC; + g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double)); + g->shapes[xsno].nv = 0; + while( 1 ){ + if( g->shapes[xsno].nv >= maxpts ){ + maxpts += MASKINC; + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + maxpts*sizeof(double)); + } + g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double); + if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) && + feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){ + g->shapes[xsno].nv--; + break; + } + g->shapes[xsno].nv++; + } + va_end(args); + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + g->shapes[xsno].nv*sizeof(double)); + } + n = g->shapes[xsno].nv; + xv = g->shapes[xsno].xv; + /* this should be impossible ... */ + if( n == 2 ){ + impiei(g, rno, sno, flag, type, x, y, xcen, ycen, xv[0], xv[1]); + return; + } + impiei(g, 0, xsno, flag, type, x, y, xcen, ycen, xv[0], xv[n-1]); + for(i=0; i<(n-1); i++){ + impiei(g, rno+i, sno+i, flag, type, x, y, xcen, ycen, xv[i], xv[i+1]); + } +} + +#ifdef __STDC__ +void +imvpointi(GFilt g, int rno, int sno, int flag, int type, + double x, double y, ...) +{ + int i, j, n; + int maxpts; + int xsno; + double *xv; + va_list args; + va_start(args, y); +#else +int imvpointi(va_alist) va_dcl +{ + GFilt g; + int rno, sno, flag, type; + double x, y; + double *xv; + int i, j, n; + int maxpts; + int xsno; + va_list args; + va_start(args); + g = va_arg(args, GFilt); + rno = va_arg(args, int); + sno = va_arg(args, int); + flag = va_arg(args, int); + type = va_arg(args, int); + x = va_arg(args, double); + y = va_arg(args, double); +#endif + xsno = (g->nshapes+1)+((sno-1)*XSNO); + if( !g->shapes[xsno].xv ){ + maxpts = MASKINC; + g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double)); + g->shapes[xsno].nv = 0; + while( 1 ){ + if( g->shapes[xsno].nv >= maxpts ){ + maxpts += MASKINC; + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + maxpts*sizeof(double)); + } + g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double); + if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) && + feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){ + g->shapes[xsno].nv--; + break; + } + g->shapes[xsno].nv++; + } + va_end(args); + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + g->shapes[xsno].nv*sizeof(double)); + } + n = g->shapes[xsno].nv; + xv = g->shapes[xsno].xv; + for(i=0, j=0; inshapes+1)+((sno-1)*XSNO); + if( !g->shapes[xsno].xv ){ + maxpts = MASKINC; + g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double)); + g->shapes[xsno].nv = 0; + while( 1 ){ + if( g->shapes[xsno].nv >= maxpts ){ + maxpts += MASKINC; + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + maxpts*sizeof(double)); + } + g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double); + if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) && + feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){ + g->shapes[xsno].nv--; + break; + } + g->shapes[xsno].nv++; + } + va_end(args); + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + g->shapes[xsno].nv*sizeof(double)); + } + n = g->shapes[xsno].nv; + xv = g->shapes[xsno].xv; + /* this should be impossible ... */ + if( n == 2 ){ + return(imannulus(g, rno, sno, flag, type, x, y, xcen, ycen, xv[0], xv[1])); + } + if( flag ){ + /* if its not somewhere inside the entire region we lose ... */ + if( !imannulus(g, 0, xsno, flag, type, x, y, xcen, ycen, xv[0], xv[n-1]) ){ + return(0); + } + /* look through all of them to find the right one */ + for(i=0; inshapes+1)+((sno-1)*XSNO); + if( !g->shapes[xsno].xv ){ + maxpts = MASKINC; + g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double)); + g->shapes[xsno].nv = 0; + while( 1 ){ + if( g->shapes[xsno].nv >= maxpts ){ + maxpts += MASKINC; + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + maxpts*sizeof(double)); + } + g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double); + if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) && + feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){ + g->shapes[xsno].nv--; + break; + } + g->shapes[xsno].nv++; + } + va_end(args); + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + g->shapes[xsno].nv*sizeof(double)); + } + n = g->shapes[xsno].nv; + xv = g->shapes[xsno].xv; + ang = xv[--n]; + /* this should be impossible ... */ + if( n == 2 ){ + return(imbox(g, rno, sno, flag, type, x, y, + xcen, ycen, xv[0], xv[1], ang)); + } + if( flag ){ + /* if its not somewhere inside the entire region we lose ... */ + if( !imbox(g, 0, xsno, flag, type, x, y, xcen, ycen, xv[n-2], xv[n-1], + ang) ){ + return(0); + } + /* if its in the inner region we lose */ + if( imbox(g, 0, xsno+1, flag, type, x, y, xcen, ycen, xv[0], xv[1], ang) ){ + return(0); + } + /* look through all of them to find the right one */ + for(i=2, j=0; inshapes+1)+((sno-1)*XSNO); + if( !g->shapes[xsno].xv ){ + maxpts = MASKINC; + g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double)); + g->shapes[xsno].nv = 0; + while( 1 ){ + if( g->shapes[xsno].nv >= maxpts ){ + maxpts += MASKINC; + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + maxpts*sizeof(double)); + } + g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double); + if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) && + feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){ + g->shapes[xsno].nv--; + break; + } + g->shapes[xsno].nv++; + } + va_end(args); + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + g->shapes[xsno].nv*sizeof(double)); + } + n = g->shapes[xsno].nv; + xv = g->shapes[xsno].xv; + ang = xv[--n]; + /* this should be impossible ... */ + if( n == 2 ){ + return(imellipse(g, rno, sno, flag, type, x, y, + xcen, ycen, xv[0], xv[1], ang)); + } + if( flag ){ + /* if its not somewhere inside the entire region we lose ... */ + if( !imellipse(g, 0, xsno, flag, type, x, y, xcen, ycen, xv[n-2], xv[n-1], + ang) ){ + return(0); + } + /* if its in the inner region we lose */ + if( imellipse(g, 0, xsno+1, flag, type, x, y, xcen, ycen, xv[0], xv[1], + ang) ){ + return(0); + } + /* look through all of them to find the right one */ + for(i=2, j=0; inshapes+1)+((sno-1)*XSNO); + if( !g->shapes[xsno].xv ){ + maxpts = MASKINC; + g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double)); + g->shapes[xsno].nv = 0; + while( 1 ){ + if( g->shapes[xsno].nv >= maxpts ){ + maxpts += MASKINC; + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + maxpts*sizeof(double)); + } + g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double); + if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) && + feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){ + g->shapes[xsno].nv--; + break; + } + g->shapes[xsno].nv++; + } + va_end(args); + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + g->shapes[xsno].nv*sizeof(double)); + } + n = g->shapes[xsno].nv; + xv = g->shapes[xsno].xv; + /* this should be impossible ... */ + if( n == 2 ){ + return(impie(g, rno, sno, flag, type, x, y, + xcen, ycen, xv[0], xv[1])); + } + if( flag ){ + /* if its not somewhere inside the entire region we lose ... */ + if( !impie(g, 0, xsno, flag, type, x, y, xcen, ycen, xv[0], xv[n-1]) ){ + return(0); + } + /* look through all of them to find the right one */ + for(i=0; inshapes+1)+((sno-1)*XSNO); + if( !g->shapes[xsno].xv ){ + maxpts = MASKINC; + g->shapes[xsno].xv = (double *)calloc(maxpts, sizeof(double)); + g->shapes[xsno].nv = 0; + while( 1 ){ + if( g->shapes[xsno].nv >= maxpts ){ + maxpts += MASKINC; + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + maxpts*sizeof(double)); + } + g->shapes[xsno].xv[g->shapes[xsno].nv] = va_arg(args, double); + if( feq(g->shapes[xsno].xv[g->shapes[xsno].nv],PSTOP) && + feq(g->shapes[xsno].xv[g->shapes[xsno].nv-1],PSTOP) ){ + g->shapes[xsno].nv--; + break; + } + g->shapes[xsno].nv++; + } + va_end(args); + g->shapes[xsno].xv = (double *)realloc(g->shapes[xsno].xv, + g->shapes[xsno].nv*sizeof(double)); + } + n = g->shapes[xsno].nv; + xv = g->shapes[xsno].xv; + /* look through all of them to find the right one */ + for(i=0, j=0; ixmax - g->xmin + 1)/g->block)/(double)g->maskdim) + 0.5); + if( mblock < 1 ){ + g->masks = NULL; + g->nmask = 0; + } + /* copy all masks and translate x,y positions as needed */ + fsize = g->nmask * sizeof(FilterMaskRec) * mblock; + xmasks = (FilterMask)calloc(1, fsize); + for(got=0, i=0; inmask; i++){ + xmasks[got].region = g->masks[i].region; + xmasks[got].y = (g->masks[i].y - 1.0) * mblock + 1.0; + xmasks[got].xstart = (g->masks[i].xstart - 1.0) * mblock + 1.0; + xmasks[got].xstop = (g->masks[i].xstop - 1.0) * mblock + 1.0; + /* replicate the segment up to the block factor */ + for(j=1; jmasks ) free(g->masks); */ + /* set up new mask records */ + g->masks = xmasks; + g->nmask = got; + + /* now mark each y line that has a y mask value */ + for(i=0; iybuf[g->masks[i].y] ) + g->ybuf[g->masks[i].y] = i+1; + } +} + +int imimagemask(GFilt g, int UNUSED(rno), int UNUSED(sno), + int UNUSED(flag), int UNUSED(type), + double x, double y) +{ + int i; + int ix, iy; + + if( g->nmask == 0 ) + return(0); + if( g->evsect ){ + if( g->usebinsiz ){ + x = (int)((x - g->tlminx)/g->binsizx + 1.0); + y = (int)((y - g->tlminy)/g->binsizy + 1.0); + } + else{ + x = (int)((x - g->tlminx) + 1.0); + y = (int)((y - g->tlminy) + 1.0); + } + x = (int)((x - g->xmin)/g->block + 1.0); + y = (int)((y - g->ymin)/g->block + 1.0); + if(y < g->y0) return 0; + if(y > g->y1) return 0; + if(x < g->x0) return 0; + if(x > g->x1) return 0; + } + ix = (int)x; + iy = (int)y; + /* look for mask segment containing ix, iy */ + i = g->ybuf[iy]; + /* ybuf contains offset+1 of first mask record containing iy */ + if( i != 0 ){ + i--; + for(; inmask; i++){ + if( g->masks[i].y > iy ){ + return(0); + } + if( (ix >= g->masks[i].xstart) && (ix <= g->masks[i].xstop) ){ + g->rid = g->masks[i].region; + return(1); + } + } + } + return(0); +} + diff --git a/filter/inc.sed b/filter/inc.sed new file mode 100755 index 0000000..5318ca2 --- /dev/null +++ b/filter/inc.sed @@ -0,0 +1,13 @@ +: +NAME="$1" +sed ' +1i\ +static char *XXXX="\\n + +s#/\*.*\*/##g +s/"/\\"/g +s/\\n/\\\\n/g +s/$/\\n/ +$a\ +\" +' | sed "s/XXXX/$NAME/" | awk '{printf("%s", $0)};END{printf(";\n")}' diff --git a/filter/install-sh b/filter/install-sh new file mode 100755 index 0000000..36f96f3 --- /dev/null +++ b/filter/install-sh @@ -0,0 +1,276 @@ +#!/bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd=$cpprog + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd=$stripprog + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "$0: no input file specified" >&2 + exit 1 +else + : +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d "$dst" ]; then + instcmd=: + chmodcmd="" + else + instcmd=$mkdirprog + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f "$src" ] || [ -d "$src" ] + then + : + else + echo "$0: $src does not exist" >&2 + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "$0: no destination specified" >&2 + exit 1 + else + : + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d "$dst" ] + then + dst=$dst/`basename "$src"` + else + : + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' + ' +IFS="${IFS-$defaultIFS}" + +oIFS=$IFS +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS=$oIFS + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp=$pathcomp$1 + shift + + if [ ! -d "$pathcomp" ] ; + then + $mkdirprog "$pathcomp" + else + : + fi + + pathcomp=$pathcomp/ +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd "$dst" && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename "$dst"` + else + dstfile=`basename "$dst" $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename "$dst"` + else + : + fi + +# Make a couple of temp file names in the proper directory. + + dsttmp=$dstdir/#inst.$$# + rmtmp=$dstdir/#rm.$$# + +# Trap to clean up temp files at exit. + + trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0 + trap '(exit $?); exit' 1 2 13 15 + +# Move or copy the file name to the temp name + + $doit $instcmd "$src" "$dsttmp" && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi && + +# Now remove or move aside any old file at destination location. We try this +# two ways since rm can't unlink itself on some systems and the destination +# file might be busy for other reasons. In this case, the final cleanup +# might fail but the new file should still install successfully. + +{ + if [ -f "$dstdir/$dstfile" ] + then + $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null || + $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null || + { + echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 + (exit 1); exit + } + else + : + fi +} && + +# Now rename the file to the real destination. + + $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" + +fi && + +# The final little trick to "correctly" pass the exit status to the exit trap. + +{ + (exit 0); exit +} diff --git a/filter/lex.filt.c b/filter/lex.filt.c new file mode 100644 index 0000000..95c561a --- /dev/null +++ b/filter/lex.filt.c @@ -0,0 +1,8941 @@ +#define yy_create_buffer filt_create_buffer +#define yy_delete_buffer filt_delete_buffer +#define yy_scan_buffer filt_scan_buffer +#define yy_scan_string filt_scan_string +#define yy_scan_bytes filt_scan_bytes +#define yy_flex_debug filt_flex_debug +#define yy_init_buffer filt_init_buffer +#define yy_flush_buffer filt_flush_buffer +#define yy_load_buffer_state filt_load_buffer_state +#define yy_switch_to_buffer filt_switch_to_buffer +#define yyin filtin +#define yyleng filtleng +#define yylex filtlex +#define yyout filtout +#define yyrestart filtrestart +#define yytext filttext +#define yywrap filtwrap + +/* A lexical scanner generated by flex*/ + +/* Scanner skeleton version: + * $Header: /home/daffy/u0/vern/flex/RCS/flex.skl,v 2.91 96/09/10 16:58:48 vern Exp $ + */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 + +#include +#include + + +/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ +#ifdef c_plusplus +#ifndef __cplusplus +#define __cplusplus +#endif +#endif + + +#ifdef __cplusplus + +#include + +/* Use prototypes in function declarations. */ +#define YY_USE_PROTOS + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +#if __STDC__ + +#define YY_USE_PROTOS +#define YY_USE_CONST + +#endif /* __STDC__ */ +#endif /* ! __cplusplus */ + +#ifdef __TURBOC__ + #pragma warn -rch + #pragma warn -use +#include +#include +#define YY_USE_CONST +#define YY_USE_PROTOS +#endif + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + + +#ifdef YY_USE_PROTOS +#define YY_PROTO(proto) proto +#else +#define YY_PROTO(proto) () +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN yy_start = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START ((yy_start - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart( yyin ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#define YY_BUF_SIZE 16384 + +typedef struct yy_buffer_state *YY_BUFFER_STATE; + +extern int yyleng; +extern FILE *yyin, *yyout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + +/* The funky do-while in the following #define is used to turn the definition + * int a single C statement (which needs a semi-colon terminator). This + * avoids problems with code like: + * + * if ( condition_holds ) + * yyless( 5 ); + * else + * do_something_else(); + * + * Prior to using the do-while the compiler would get upset at the + * "else" because it interpreted the "if" statement as being all + * done when it reached the ';' after the yyless() call. + */ + +/* Return all but the first 'n' matched characters back to the input stream. */ + +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + *yy_cp = yy_hold_char; \ + YY_RESTORE_YY_MORE_OFFSET \ + yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, filttext_ptr ) + +/* Some routines like yy_flex_realloc() are emitted as static but are + not called by all lexers. This generates warnings in some compilers, + notably GCC. Arrange to suppress these. */ +#ifdef __GNUC__ +#define YY_MAY_BE_UNUSED __attribute__((unused)) +#else +#define YY_MAY_BE_UNUSED +#endif + +/* The following is because we cannot portably get our hands on size_t + * (without autoconf's help, which isn't available because we want + * flex-generated scanners to compile on their own). + */ +typedef unsigned int yy_size_t; + + +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + }; + +static YY_BUFFER_STATE yy_current_buffer = 0; + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + */ +#define YY_CURRENT_BUFFER yy_current_buffer + + +/* yy_hold_char holds the character lost when yytext is formed. */ +static char yy_hold_char; + +static int yy_n_chars; /* number of characters read into yy_ch_buf */ + + +int yyleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = (char *) 0; +static int yy_init = 1; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void yyrestart YY_PROTO(( FILE *input_file )); + +void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer )); +void yy_load_buffer_state YY_PROTO(( void )); +YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size )); +void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b )); +void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file )); +void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b )); +#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer ) + +YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size )); +YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str )); +YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len )); + +static void *yy_flex_alloc YY_PROTO(( yy_size_t )); +static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t )) YY_MAY_BE_UNUSED; +static void yy_flex_free YY_PROTO(( void * )); + +#define yy_new_buffer yy_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! yy_current_buffer ) \ + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ + yy_current_buffer->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! yy_current_buffer ) \ + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ + yy_current_buffer->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (yy_current_buffer->yy_at_bol) + + +#define YY_USES_REJECT +typedef unsigned char YY_CHAR; +FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; +typedef int yy_state_type; +extern char yytext[]; + + +static yy_state_type yy_get_previous_state YY_PROTO(( void )); +static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state )); +static int yy_get_next_buffer YY_PROTO(( void )); +static void yy_fatal_error YY_PROTO(( yyconst char msg[] )); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + filttext_ptr = yy_bp; \ + yyleng = (int) (yy_cp - yy_bp); \ + yy_hold_char = *yy_cp; \ + *yy_cp = '\0'; \ + if ( yyleng >= YYLMAX ) \ + YY_FATAL_ERROR( "token too large, exceeds YYLMAX" ); \ + yy_flex_strncpy( yytext, filttext_ptr, yyleng + 1 ); \ + yy_c_buf_p = yy_cp; + +#define YY_NUM_RULES 68 +#define YY_END_OF_BUFFER 69 +static yyconst short int yy_acclist[1847] = + { 0, + 60, 60, 60, 60, 60, 60, 60, 60, 69, 67, + 68, 60, 67, 68, 66, 68, 67, 68, 67, 68, + 6, 67, 68, 63, 67, 68, 63, 67, 68, 67, + 68, 64, 67, 68, 65, 67, 68, 63, 67, 68, + 66, 67, 68, 67, 68, 62, 67, 68, 62, 67, + 68, 63, 67, 68, 63, 67, 68, 63, 67, 68, + 58, 67, 68, 67, 68, 59, 67, 68,16425,16426, + 59, 67, 68,16425,16426, 59, 67, 68,16425,16426, + 59, 67, 68,16425,16426, 59, 67, 68,16425,16426, + 59, 67, 68,16425,16426, 59, 67, 68,16425,16426, + + 59, 67, 68,16425,16426, 59, 67, 68,16425,16426, + 59, 67, 68,16425,16426, 59, 67, 68,16425,16426, + 59, 67, 68,16425,16426, 59, 67, 68,16425,16426, + 59, 67, 68,16425,16426, 59, 67, 68,16425,16426, + 59, 67, 68,16425,16426, 63, 67, 68, 53, 66, + 68,16433,16434, 67, 68, 52, 63, 67, 68, 52, + 63, 67, 68, 51, 65, 67, 68, 52, 63, 67, + 68, 48, 66, 67, 68,16433,16434, 67, 68, 46, + 62, 67, 68, 46, 62, 67, 68, 67, 68, 53, + 66, 67, 68,16433,16434, 52, 63, 67, 68, 47, + + 52, 63, 67, 68, 52, 63, 67, 68, 67, 68, + 52, 63, 67, 68, 56, 64, 67, 68, 57, 65, + 67, 68, 55, 66, 67, 68, 60, 67, 68, 40, + 66, 68, 67, 68, 39, 63, 67, 68, 39, 63, + 67, 68, 36, 64, 67, 68, 38, 65, 67, 68, + 39, 63, 67, 68, 34, 66, 67, 68, 67, 68, + 23, 62, 67, 68,16416, 23, 62, 67, 68,16416, + 40, 66, 67, 68, 39, 63, 67, 68, 39, 63, + 67, 68, 39, 63, 67, 68, 33, 58, 67, 68, + 67, 68, 59, 67, 68,16425,16426, 59, 67, 68, + + 16425,16426, 59, 67, 68,16425,16426, 59, 67, 68, + 16425,16426, 59, 67, 68,16425,16426, 59, 67, 68, + 16425,16426, 59, 67, 68,16425,16426, 59, 67, 68, + 16425,16426, 59, 67, 68,16425,16426, 59, 67, 68, + 16425,16426, 59, 67, 68,16425,16426, 59, 67, 68, + 16425,16426, 59, 67, 68,16425,16426, 59, 67, 68, + 16425,16426, 59, 67, 68,16425,16426, 59, 67, 68, + 16425,16426, 59, 67, 68,16425,16426, 67, 68, 39, + 63, 67, 68, 68, 17, 68, 18, 68, 16, 68, + 19, 68, 15, 68, 9, 68, 7, 68, 9, 68, + + 60, 63, 61, 62, 62, 62, 62, 62, 58, 66, + 16425,16426, 54, 59,16425,16426, 59,16425,16426, 59, + 16425,16426, 59,16425,16426, 59,16425,16426, 59,16425, + 16426, 59,16425,16426, 59,16425,16426, 59,16425,16426, + 59,16425,16426, 59,16425,16426, 59,16425,16426, 59, + 16425,16426, 59,16425,16426, 59,16425,16426, 59,16425, + 16426, 59,16425,16426, 59,16425,16426, 59,16425,16426, + 59,16425,16426, 59,16425,16426, 59,16425,16426, 59, + 16425,16426, 59,16425,16426, 59,16425,16426, 59,16425, + 16426, 59,16425,16426, 59,16425,16426, 59,16425,16426, + + 59,16425,16426, 59,16425,16426,16433,16434, 8242, 8242, + 8242, 8242, 8242, 8242, 8242, 8242, 8242, 8242, 52, 63, + 46, 62, 46, 62, 46, 62, 46, 62, 45, 46, + 62, 44, 44, 53, 66,16433,16434, 60, 39, 63, + 23, 62,16416, 23, 62,16416, 23, 62,16416, 30, + 8224, 8224, 29, 23, 62,16416, 8224, 8224, 8224, 27, + 24, 23, 62,16416, 25, 28, 8224, 33, 58, 40, + 66, 33, 33, 59,16425,16426, 33, 33, 33, 33, + 33, 59,16425,16426,16425,16426, 33, 59,16425,16426, + 59,16425,16426, 59,16425,16426, 59,16425,16426, 59, + + 16425,16426, 59,16425,16426, 59,16425,16426, 59,16425, + 16426, 59,16425,16426, 59,16425,16426, 59,16425,16426, + 59,16425,16426, 59,16425,16426, 59,16425,16426, 59, + 16425,16426, 59,16425,16426, 59,16425,16426, 59,16425, + 16426, 59,16425,16426, 59,16425,16426, 59,16425,16426, + 59,16425,16426, 59,16425,16426, 59,16425,16426, 59, + 16425,16426, 59,16425,16426, 59,16425,16426, 59,16425, + 16426, 59,16425,16426, 59,16425,16426, 15, 8, 62, + 62, 62, 58, 8234, 8234, 8233, 59,16425,16426, 59, + 16425,16426, 59,16425,16426, 59,16425,16426, 59,16425, + + 16426, 59,16425,16426, 59,16425,16426, 59,16425,16426, + 59,16425,16426, 59,16425,16426, 59,16425,16426, 59, + 16425,16426, 59,16425,16426, 59,16425,16426, 2, 59, + 16425,16426, 59,16425,16426, 59,16425,16426, 59,16425, + 16426, 59,16425,16426, 59,16425,16426, 59,16425,16426, + 59,16425,16426, 59,16425,16426, 59,16425,16426, 59, + 16425,16426, 59,16425,16426, 59,16425,16426, 59,16425, + 16426, 59,16425,16426, 59,16425,16426, 59,16425,16426, + 8242, 8241, 8242, 8242, 8242, 8242, 8241, 8242, 8242, 8242, + 8242, 8242, 8242, 8242, 8242, 8242, 8242, 8242, 8242, 8242, + + 8242, 8242, 8242, 43, 43, 46, 62, 46, 62, 46, + 62, 44, 44, 44, 44, 27, 23, 62,16416, 23, + 62,16416, 23, 62,16416, 33, 58, 59,16425,16426, + 31, 8234, 31, 8234, 59,16425,16426, 59,16425,16426, + 59,16425,16426, 59,16425,16426, 59,16425,16426, 59, + 16425,16426, 59,16425,16426, 59,16425,16426, 59,16425, + 16426, 59,16425,16426, 59,16425,16426, 59,16425,16426, + 59,16425,16426, 2, 59,16425,16426, 59,16425,16426, + 59,16425,16426, 59,16425,16426, 59,16425,16426, 59, + 16425,16426, 59,16425,16426, 59,16425,16426, 59,16425, + + 16426, 59,16425,16426, 59,16425,16426, 59,16425,16426, + 59,16425,16426, 59,16425,16426, 59,16425,16426, 59, + 16425,16426, 59,16425,16426, 35, 15, 62, 62, 8234, + 8234, 8234, 8234, 8234, 8234, 8233, 8233,16425,16426, 54, + 59,16425,16426,16405,16406,16425,16426, 54,16405,16406, + 59,16425,16426, 59,16425,16426, 59,16425,16426, 59, + 16425,16426, 59,16425,16426, 59,16425,16426, 59,16425, + 16426, 59,16425,16426, 59,16425,16426, 59,16425,16426, + 59,16425,16426, 2, 59,16425,16426, 59,16425,16426, + 59,16425,16426, 59,16425,16426, 59,16425,16426, 59, + + 16425,16426, 59,16425,16426, 59,16425,16426, 59,16425, + 16426, 59,16425,16426, 59,16425,16426, 59,16425,16426, + 59,16425,16426, 4, 59,16425,16426, 59,16425,16426, + 8242, 8242, 8241, 8242, 8241, 8241, 8242, 8242, 8242, 8242, + 8242, 8242, 8242, 8242, 8242, 8242, 8242, 8242, 8242, 8242, + 8242, 46, 62, 43, 43, 43, 43, 46, 62, 44, + 44, 44, 37, 23, 62,16416, 23, 27, 62,16416, + 23, 62,16416,16425,16426, 33, 33, 54, 33, 33, + 33, 33, 31, 8234, 31, 8234, 31, 31, 8234, 31, + 8234, 59,16425,16426, 59,16425,16426, 59,16425,16426, + + 59,16425,16426, 59,16425,16426, 59,16425,16426, 59, + 16425,16426, 59,16425,16426, 59,16425,16426, 59,16425, + 16426, 59,16425,16426, 59,16425,16426, 59,16425,16426, + 59,16425,16426, 59,16425,16426, 59,16425,16426, 59, + 16425,16426, 59,16425,16426, 59,16425,16426, 59,16425, + 16426, 59,16425,16426, 59,16425,16426, 59,16425,16426, + 59,16425,16426, 59,16425,16426, 4, 59,16425,16426, + 59,16425,16426,16405,16406,16405,16406, 1, 8234, 8234, + 8234, 8234, 8234, 8234, 8234, 8233, 8233, 8234, 8234, 8233, + 59,16425,16426, 8213, 8213, 8214,16405,16406, 59,16425, + + 16426, 59,16425,16426, 59,16425,16426, 59,16425,16426, + 59,16425,16426, 59,16425,16426, 59,16425,16426, 59, + 16425,16426, 59,16425,16426, 20, 59,16425,16426, 59, + 16425,16426, 59,16425,16426, 59,16425,16426, 59,16425, + 16426, 59,16425,16426, 59,16425,16426, 59,16425,16426, + 16425,16426, 54, 59,16425,16426, 8242, 8242, 8242, 8242, + 8242, 8242, 8242, 8242, 8242, 8242, 8242, 8242, 8242, 8241, + 8242, 8242, 8242, 8242, 8242, 8242, 8242, 8242, 8242, 8242, + 8242, 43, 43, 43, 44, 44, 26, 26, 26, 26, + 26, 26, 8224, 23, 62,16416, 23, 62,16416, 8234, + + 8234, 8233, 31, 8234, 31, 8234, 31, 8234, 59,16425, + 16426, 59,16425,16426, 59,16425,16426, 59,16425,16426, + 59,16425,16426, 59,16425,16426, 59,16425,16426, 59, + 16425,16426, 59,16425,16426, 59,16425,16426, 20, 59, + 16425,16426, 59,16425,16426, 59,16425,16426, 59,16425, + 16426, 59,16425,16426, 59,16425,16426, 59,16425,16426, + 59,16425,16426, 59,16425,16426, 20, 8234, 8234, 8234, + 8234, 8234, 8233, 8234, 8234, 8234, 8234, 8234, 8234, 8233, + 8233, 59,16425,16426, 8213, 8213, 8213, 8213, 8214, 59, + 16425,16426, 59,16425,16426, 59,16425,16426, 59,16425, + + 16426, 59,16425,16426, 20,16405,16406,16425,16426, 20, + 54,16405,16406, 59,16425,16426, 3, 59,16425,16426, + 59,16425,16426, 59,16425,16426, 59,16425,16426,16425, + 16426, 54,16425,16426, 10, 54, 59,16425,16426, 8242, + 8242, 8242, 8242, 8242, 8242, 8242, 43, 43, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 23, 62,16416, 8234, 8234, + 8234, 8234, 8234, 8234, 8233, 8233, 31, 8234, 31, 8234, + 59,16425,16426, 59,16425,16426, 59,16425,16426, 59, + 16425,16426, 59,16425,16426, 59,16425,16426, 59,16425, + + 16426, 3, 59,16425,16426, 59,16425,16426, 59,16425, + 16426, 59,16425,16426, 59,16425,16426, 20,16405,16406, + 20,16405,16406, 8234, 8234, 8234, 8234, 8234, 8234, 8234, + 8234, 8234, 8233, 59,16425,16426, 8213, 8213, 8213, 8214, + 5, 59,16425,16426, 59,16425,16426, 59,16425,16426, + 20,16405,16406, 59,16425,16426, 59,16425,16426, 59, + 16425,16426,16425,16426, 12, 54, 8234, 8234, 8233, 10, + 16425,16426, 54, 8242, 8242, 8242, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 8234, 8234, 8234, + 8234, 8234, 8234, 8234, 8233, 59,16425,16426, 5, 59, + + 16425,16426, 59,16425,16426, 59,16425,16426, 59,16425, + 16426, 59,16425,16426, 59,16425,16426, 8234, 8234, 8234, + 8234, 8234, 59,16425,16426, 8213, 8213, 59,16425,16426, + 8234, 8234, 8233, 12, 8234, 8234, 8234, 8234, 8234, 8234, + 8233, 8233,16425,16426, 11, 54, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 8234, 8234, 8234, 8234, 8234, + 59,16425,16426, 59,16425,16426, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 8234, + 8234, 59,16425,16426, 8234, 8234, 8234, 8234, 8234, 8234, + 8233, 8233, 8234, 8234, 8234, 8234, 8234, 8234, 8234, 8233, + + 10, 8233, 8234, 8234, 8233, 11, 26, 8234, 8234, 59, + 16425,16426, 59,16425,16426, 8234, 8234, 8234, 8234, 8234, + 8234, 8234, 8233, 12, 8233, 8234, 8234, 8234, 8234, 8234, + 10, 8233, 10, 8234, 8234, 8234, 8234, 8234, 8234, 8233, + 8233, 26, 59,16425,16426, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14,16425,16426, 54, 8234, 8234, 8234, 8234, 8234, 12, + 8233, 12, 8234, 8234, 10, 8234, 8234, 8234, 8234, 8234, + 8234, 8234, 8233, 11, 8233,16425,16426, 13, 54, 8234, + + 8234, 12, 8234, 8234, 8234, 8234, 8234, 11, 8233, 11, + 8234, 8234, 8233, 13, 8234, 8234, 11, 8234, 8234, 8234, + 8234, 8234, 8234, 8233, 8233, 8234, 8234, 8234, 8234, 8234, + 8234, 8234, 8233, 13, 8233, 8234, 8234, 8234, 8234, 8234, + 13, 8233, 13, 8234, 8234, 13 + } ; + +static yyconst short int yy_accept[1689] = + { 0, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, + 9, 9, 9, 9, 9, 10, 12, 15, 17, 19, + 21, 24, 27, 30, 32, 35, 38, 41, 44, 46, + 49, 52, 55, 58, 61, 64, 66, 71, 76, 81, + 86, 91, 96, 101, 106, 111, 116, 121, 126, 131, + 136, 141, 146, 149, 154, 156, 160, 164, 168, 172, + 178, 180, 184, 188, 190, 196, 200, 205, 209, 211, + 215, 219, 223, 227, 230, 233, 235, 239, 243, 247, + 251, 255, 259, 261, 266, 271, 275, 279, 283, 287, + 291, 293, 298, 303, 308, 313, 318, 323, 328, 333, + + 338, 343, 348, 353, 358, 363, 368, 373, 378, 380, + 384, 385, 387, 389, 391, 393, 395, 397, 399, 401, + 402, 403, 403, 403, 403, 403, 403, 403, 403, 403, + 403, 404, 404, 404, 404, 404, 404, 404, 404, 404, + 404, 404, 405, 406, 406, 406, 406, 406, 406, 407, + 408, 408, 408, 409, 409, 410, 410, 411, 413, 414, + 417, 417, 417, 420, 423, 426, 429, 432, 435, 438, + 441, 444, 447, 450, 453, 456, 459, 462, 465, 468, + 471, 474, 477, 480, 483, 486, 489, 492, 495, 498, + 501, 504, 507, 509, 509, 509, 509, 509, 509, 509, + + 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, + 521, 521, 523, 525, 527, 527, 529, 530, 530, 530, + 532, 532, 532, 532, 532, 533, 534, 538, 539, 539, + 541, 541, 541, 541, 544, 547, 550, 550, 550, 551, + 552, 553, 554, 557, 557, 558, 559, 560, 560, 561, + 561, 561, 562, 565, 566, 567, 567, 568, 570, 570, + 572, 572, 573, 574, 577, 578, 579, 580, 580, 581, + 585, 587, 588, 591, 594, 597, 600, 603, 606, 609, + 612, 615, 618, 621, 624, 627, 630, 633, 636, 639, + 642, 645, 648, 651, 654, 657, 660, 663, 666, 669, + + 672, 675, 678, 678, 678, 678, 679, 679, 680, 680, + 680, 680, 680, 680, 680, 680, 680, 680, 680, 680, + 680, 680, 680, 680, 680, 680, 680, 680, 680, 680, + 680, 680, 680, 680, 680, 680, 680, 680, 681, 681, + 682, 683, 683, 684, 684, 684, 684, 684, 685, 686, + 686, 687, 687, 690, 693, 696, 699, 702, 705, 708, + 711, 714, 717, 720, 723, 726, 729, 733, 736, 739, + 742, 745, 748, 751, 754, 757, 760, 763, 766, 769, + 772, 775, 778, 781, 781, 781, 781, 781, 781, 781, + 781, 781, 781, 781, 781, 781, 781, 781, 781, 781, + + 782, 784, 784, 784, 785, 786, 787, 787, 787, 787, + 787, 789, 790, 790, 791, 791, 792, 793, 794, 795, + 796, 797, 798, 799, 800, 801, 802, 803, 804, 804, + 804, 804, 804, 805, 806, 808, 808, 810, 812, 813, + 814, 815, 815, 815, 816, 816, 816, 816, 816, 817, + 817, 817, 817, 817, 817, 817, 820, 820, 820, 820, + 820, 820, 823, 823, 823, 823, 823, 826, 826, 828, + 828, 831, 831, 831, 831, 831, 833, 835, 838, 841, + 844, 847, 850, 853, 856, 859, 862, 865, 868, 871, + 874, 878, 881, 884, 887, 890, 893, 896, 899, 902, + + 905, 908, 911, 914, 917, 920, 923, 926, 926, 926, + 927, 927, 928, 928, 928, 928, 928, 928, 928, 928, + 928, 928, 928, 928, 928, 928, 928, 928, 928, 928, + 928, 928, 928, 928, 928, 928, 928, 928, 928, 928, + 928, 928, 929, 930, 931, 932, 933, 933, 933, 934, + 934, 934, 934, 935, 936, 937, 938, 938, 940, 941, + 941, 944, 948, 951, 954, 957, 960, 963, 966, 969, + 972, 975, 978, 981, 984, 985, 988, 991, 994, 997, + 1000, 1003, 1006, 1009, 1012, 1015, 1018, 1021, 1024, 1028, + 1031, 1031, 1031, 1031, 1031, 1031, 1031, 1031, 1031, 1031, + + 1031, 1031, 1031, 1031, 1031, 1031, 1032, 1032, 1032, 1032, + 1032, 1032, 1033, 1033, 1035, 1036, 1037, 1037, 1037, 1037, + 1037, 1037, 1038, 1038, 1039, 1040, 1041, 1042, 1043, 1044, + 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1052, 1054, + 1055, 1056, 1057, 1057, 1057, 1058, 1058, 1060, 1060, 1061, + 1061, 1062, 1063, 1063, 1063, 1064, 1064, 1067, 1067, 1067, + 1067, 1067, 1067, 1067, 1067, 1067, 1067, 1067, 1067, 1067, + 1071, 1074, 1076, 1076, 1077, 1078, 1079, 1080, 1081, 1082, + 1083, 1085, 1087, 1088, 1090, 1090, 1090, 1092, 1092, 1095, + 1098, 1101, 1104, 1107, 1110, 1113, 1116, 1119, 1122, 1125, + + 1128, 1131, 1134, 1137, 1140, 1143, 1146, 1149, 1152, 1155, + 1158, 1161, 1164, 1167, 1171, 1174, 1174, 1176, 1178, 1178, + 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, + 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1179, 1179, 1179, + 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1180, 1180, 1181, + 1182, 1183, 1184, 1185, 1185, 1185, 1186, 1186, 1187, 1187, + 1187, 1188, 1188, 1188, 1188, 1188, 1189, 1190, 1190, 1191, + 1194, 1194, 1194, 1195, 1196, 1197, 1199, 1202, 1205, 1208, + 1211, 1214, 1217, 1220, 1223, 1226, 1230, 1233, 1236, 1239, + 1242, 1245, 1248, 1251, 1253, 1254, 1257, 1258, 1259, 1260, + + 1261, 1262, 1263, 1264, 1265, 1266, 1267, 1268, 1269, 1270, + 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1271, 1271, 1272, + 1273, 1274, 1275, 1276, 1277, 1278, 1279, 1280, 1281, 1282, + 1282, 1283, 1283, 1284, 1285, 1285, 1286, 1287, 1287, 1287, + 1287, 1287, 1288, 1289, 1289, 1289, 1289, 1289, 1290, 1291, + 1291, 1291, 1291, 1291, 1292, 1293, 1293, 1293, 1294, 1297, + 1300, 1300, 1300, 1300, 1300, 1300, 1301, 1302, 1302, 1303, + 1303, 1305, 1305, 1307, 1309, 1312, 1315, 1318, 1321, 1324, + 1327, 1330, 1333, 1336, 1339, 1343, 1346, 1349, 1352, 1355, + 1358, 1361, 1364, 1367, 1367, 1367, 1367, 1367, 1367, 1367, + + 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367, + 1367, 1367, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1369, + 1370, 1370, 1371, 1371, 1372, 1373, 1373, 1374, 1375, 1376, + 1377, 1377, 1377, 1378, 1378, 1378, 1378, 1379, 1380, 1381, + 1382, 1385, 1386, 1387, 1388, 1388, 1388, 1389, 1389, 1390, + 1390, 1393, 1396, 1399, 1402, 1405, 1410, 1414, 1417, 1421, + 1424, 1427, 1430, 1432, 1433, 1433, 1435, 1436, 1437, 1437, + 1437, 1437, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, + 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1441, 1442, 1443, + 1444, 1445, 1446, 1447, 1447, 1448, 1449, 1449, 1450, 1451, + + 1452, 1453, 1453, 1453, 1454, 1455, 1455, 1455, 1456, 1457, + 1458, 1459, 1459, 1459, 1460, 1460, 1460, 1461, 1462, 1463, + 1464, 1464, 1464, 1465, 1466, 1466, 1466, 1466, 1466, 1469, + 1470, 1471, 1472, 1472, 1472, 1473, 1473, 1473, 1473, 1474, + 1475, 1476, 1477, 1477, 1479, 1481, 1484, 1487, 1490, 1493, + 1496, 1499, 1502, 1506, 1509, 1512, 1515, 1518, 1518, 1518, + 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, + 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1518, 1521, 1524, + 1524, 1524, 1524, 1524, 1524, 1524, 1524, 1525, 1526, 1526, + 1527, 1527, 1528, 1529, 1530, 1531, 1532, 1532, 1532, 1533, + + 1533, 1534, 1537, 1537, 1538, 1538, 1539, 1540, 1540, 1541, + 1545, 1548, 1551, 1554, 1557, 1560, 1563, 1563, 1565, 1566, + 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1567, 1568, 1569, + 1569, 1570, 1571, 1573, 1574, 1574, 1574, 1574, 1574, 1574, + 1574, 1574, 1575, 1576, 1577, 1577, 1578, 1578, 1579, 1580, + 1580, 1581, 1581, 1582, 1583, 1583, 1584, 1584, 1585, 1586, + 1586, 1586, 1587, 1588, 1588, 1589, 1589, 1590, 1591, 1592, + 1593, 1594, 1594, 1594, 1595, 1595, 1596, 1599, 1603, 1606, + 1609, 1612, 1615, 1618, 1618, 1618, 1618, 1618, 1618, 1618, + 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, + + 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, + 1619, 1620, 1620, 1621, 1621, 1622, 1623, 1626, 1626, 1627, + 1628, 1631, 1631, 1631, 1631, 1631, 1632, 1633, 1633, 1634, + 1635, 1636, 1637, 1638, 1638, 1638, 1639, 1639, 1639, 1639, + 1640, 1641, 1642, 1643, 1643, 1643, 1645, 1646, 1647, 1647, + 1647, 1647, 1647, 1647, 1647, 1647, 1648, 1649, 1649, 1650, + 1651, 1651, 1652, 1653, 1654, 1655, 1656, 1656, 1656, 1657, + 1658, 1658, 1659, 1659, 1660, 1661, 1664, 1667, 1668, 1669, + 1670, 1671, 1672, 1673, 1674, 1675, 1676, 1677, 1678, 1679, + 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, + + 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, + 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1681, 1682, + 1685, 1686, 1687, 1688, 1688, 1688, 1689, 1689, 1689, 1689, + 1690, 1691, 1692, 1693, 1693, 1693, 1694, 1694, 1695, 1696, + 1697, 1698, 1699, 1699, 1699, 1700, 1700, 1701, 1701, 1701, + 1702, 1702, 1703, 1703, 1703, 1703, 1703, 1704, 1705, 1705, + 1706, 1707, 1708, 1708, 1709, 1710, 1713, 1713, 1713, 1713, + 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, + 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, + 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, + + 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, + 1713, 1716, 1716, 1717, 1717, 1718, 1719, 1720, 1721, 1722, + 1722, 1722, 1723, 1723, 1724, 1724, 1724, 1725, 1725, 1726, + 1726, 1727, 1728, 1728, 1729, 1729, 1730, 1731, 1731, 1732, + 1732, 1733, 1734, 1735, 1736, 1737, 1737, 1737, 1738, 1738, + 1738, 1738, 1739, 1740, 1741, 1742, 1742, 1743, 1746, 1746, + 1746, 1746, 1746, 1746, 1746, 1746, 1747, 1748, 1749, 1750, + 1751, 1752, 1753, 1754, 1755, 1756, 1757, 1758, 1759, 1760, + 1761, 1762, 1763, 1764, 1765, 1766, 1767, 1768, 1769, 1770, + 1771, 1772, 1772, 1772, 1772, 1772, 1772, 1774, 1775, 1775, + + 1776, 1777, 1777, 1778, 1778, 1779, 1780, 1780, 1781, 1781, + 1782, 1783, 1783, 1784, 1785, 1786, 1786, 1787, 1787, 1788, + 1789, 1790, 1791, 1792, 1792, 1792, 1793, 1793, 1794, 1794, + 1794, 1795, 1795, 1796, 1796, 1796, 1796, 1796, 1796, 1796, + 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, + 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, + 1796, 1796, 1796, 1796, 1796, 1796, 1798, 1799, 1800, 1800, + 1800, 1800, 1800, 1801, 1802, 1803, 1803, 1804, 1805, 1805, + 1806, 1806, 1807, 1808, 1808, 1809, 1809, 1810, 1811, 1811, + 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, + + 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811, + 1811, 1811, 1811, 1812, 1813, 1813, 1814, 1815, 1815, 1816, + 1817, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, + 1818, 1819, 1820, 1821, 1821, 1821, 1822, 1822, 1822, 1822, + 1823, 1824, 1825, 1826, 1826, 1826, 1826, 1826, 1827, 1827, + 1828, 1829, 1830, 1831, 1832, 1832, 1832, 1833, 1833, 1834, + 1834, 1834, 1835, 1835, 1836, 1836, 1836, 1836, 1837, 1838, + 1838, 1839, 1839, 1840, 1841, 1841, 1842, 1842, 1843, 1844, + 1844, 1844, 1844, 1845, 1846, 1847, 1847, 1847 + } ; + +static yyconst int yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 4, 5, 6, 1, 7, 8, 9, 10, + 11, 7, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 20, 20, 20, 23, 24, 25, 26, + 27, 28, 1, 29, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 56, + 30, 31, 32, 7, 33, 1, 34, 35, 36, 37, + + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 56, 59, 60, 61, 62, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static yyconst int yy_meta[63] = + { 0, + 1, 2, 3, 4, 1, 1, 4, 4, 1, 5, + 6, 7, 8, 9, 10, 11, 12, 12, 12, 12, + 12, 12, 12, 13, 1, 4, 14, 4, 1, 15, + 1, 1, 16, 17, 17, 17, 17, 18, 17, 16, + 16, 16, 16, 16, 19, 20, 16, 16, 16, 16, + 16, 21, 16, 16, 16, 16, 22, 16, 1, 4, + 23, 24 + } ; + +static yyconst short int yy_base[1846] = + { 0, + 0, 0, 60, 0, 79, 83, 122, 0, 184, 0, + 237, 0, 66, 67, 7752,14226, 7745,14226, 68, 7741, + 14226,14226, 7737, 7735, 215,14226, 281,14226, 288, 322, + 64, 39, 7716, 73, 7712, 7693, 319, 323, 345, 354, + 378, 385, 356, 380, 399, 409, 421, 430, 431, 440, + 463, 472, 7552, 509, 541,14226, 7603,14226, 577, 0, + 584, 606, 278, 662, 0, 82, 7579, 83, 7558, 7544, + 595,14226,14226, 253,14226, 621,14226, 7593, 0, 259, + 594,14226, 669, 691, 316,14226, 88, 7567, 231, 7559, + 7540, 752, 813, 406, 449, 276, 430, 441, 331, 216, + + 391, 461, 371, 742, 315, 345, 536, 468, 780, 7526, + 14226,14226,14226,14226,14226, 7543,14226,14226, 7523, 7564, + 14226, 7518, 217, 63, 204, 7520, 7514, 470, 7501, 7547, + 14226, 7532, 341, 479, 487, 605, 456, 606, 632, 691, + 752, 7504, 0, 7496, 627, 7474, 7489, 7488, 788, 813, + 310, 835,14226, 0, 7495, 7491,14226, 583,14226, 714, + 874, 7473, 836, 720, 860, 872, 898, 903, 904, 908, + 909, 910, 914, 941, 725, 943, 947, 956, 970, 979, + 985, 980, 989, 1001, 1012, 1016, 1022, 1027, 1038, 1045, + 1054, 1061, 0, 1051, 1101, 1110, 1087, 1159, 317, 7465, + + 7464, 359, 492, 355, 539, 226, 414, 873, 390,14226, + 1117, 7450, 411, 699, 618, 826, 1220, 516, 1188, 641, + 0, 0, 1208, 1227, 1236, 611, 0, 457, 1265,14226, + 579, 1277, 1243, 7439, 637, 1297, 1036, 7446,14226,14226, + 7455,14226, 7423, 1139, 510, 7433, 543, 555, 1140, 1333, + 1181,14226, 1358,14226,14226, 0, 7399, 7428, 7425,14226, + 7419,14226, 7435, 1419, 626, 1480, 718, 7409, 7377, 1506, + 899, 1567, 7387, 7381, 7395, 7355, 7374, 7354, 7345, 7355, + 7331, 7334, 7331, 7341, 7331, 736, 7323, 7314, 7310, 7320, + 7318, 7286, 7284, 7260, 7275, 74, 7263, 7261, 7243, 7226, + + 7229, 7229, 1309, 704, 1358, 7234, 7230,14226, 7145, 7131, + 7153, 7135, 7151, 7107, 7117, 7112, 7094, 7093, 7096, 689, + 7084, 0, 609, 7098, 831, 783, 774, 948, 1004, 975, + 933, 7075, 7060, 7062, 7042, 7038, 1394, 768, 1370, 1419, + 7018, 7026, 7023, 7025, 1162, 1433, 1440, 1576, 810, 1622, + 7014, 7009, 1186, 1466, 1513, 1515, 1331, 1517, 1519, 1395, + 1529, 1590, 1605, 1621, 1599, 1628, 1548, 1647, 1652, 1550, + 1658, 1659, 1665, 1670, 1681, 1691, 1692, 1702, 1704, 1713, + 1714, 1725, 1726, 6990, 770, 829, 694, 6978, 6975, 1032, + 6954, 1765, 1452, 1814, 912, 1875, 1936, 1997, 6971,14226, + + 6987, 985, 6954, 842, 6962, 852, 905, 1466, 1022, 0, + 6928, 6957, 6954, 6819, 6814, 937, 267, 747, 308, 761, + 417, 847, 786, 978, 1032, 918, 1120, 930, 1752, 2058, + 1774, 1843, 2067, 941, 1319, 1887, 1949, 1145, 1265, 1904, + 1959, 1075, 1971,14226, 0, 1997, 1467, 2010,14226, 2022, + 1610, 1745, 2029, 2123, 6788, 2177, 1836, 2044, 2238, 6782, + 2074, 2096, 1855, 2109, 2294, 6781, 2350, 6802, 6800, 6799, + 2411, 2472, 2495, 2133, 2116, 2518, 1060, 2574, 2635, 1552, + 6762, 1137, 666, 1758, 1145, 2000, 1707, 999, 1170, 613, + 2162, 2156, 1845, 2147, 2157, 2161, 1040, 1089, 2190, 1221, + + 1215, 2210, 1161, 2196, 2215, 2211, 2220, 6754, 0,14226, + 6782, 6781, 2221, 1210, 1561, 1392, 1603, 1422, 1796, 1608, + 1807, 1528, 1809, 1668, 1654, 1203, 6779, 1336, 1707, 1277, + 1899, 1814, 1838, 1898, 1700, 1871, 6764, 6768, 6749, 6747, + 2259, 2268,14226, 2209, 2281, 2303, 1094, 2315,14226, 0, + 2327, 2385, 2683, 1235, 6769, 6767, 6750, 2414, 6742, 2740, + 2418, 2801, 2827, 2420, 2432, 2442, 2453, 2451, 2520, 2498, + 2519, 2521, 2542, 2581, 1962, 2585, 2583, 2595, 2597, 2596, + 2630, 2642, 2646, 2648, 2644, 2681, 2683, 2705, 2804, 2825, + 6725, 6713, 6726, 6704, 6720, 6708, 6716, 6516, 6505, 6489, + + 6480, 1356, 6465, 2872, 2933, 6504, 6470, 1448, 2839, 2994, + 0, 6446, 2901,14226, 6495, 6438, 2556, 2846, 2884, 3055, + 6463, 6443, 6438, 6437, 818, 6438, 1479, 1242, 1523, 1341, + 1718, 990, 1366, 1511, 1828, 667, 1574, 2945, 2955, 2679, + 2965, 2994, 1488, 3016,14226, 0, 1340, 3028, 1648, 3084, + 3091, 6391, 6367, 0,14226, 3101, 3121, 1800, 3182, 1915, + 0, 2172, 3204, 2205, 0, 2246, 3226, 2307, 0, 3248, + 3309, 2906, 1678, 6395, 1244, 6393, 1904, 3371, 1749, 1639, + 3432, 3157, 6414, 3169, 1867, 3284, 6411, 0, 3488, 3549, + 1901, 1768, 6366, 1538, 1958, 1398, 1295, 1324, 1963, 2061, + + 1976, 1900, 1614, 1990, 2430, 1992, 1778, 2054, 1874, 2063, + 2065, 1574, 2261, 6349, 2008, 1053, 3610, 2160, 6346, 6352, + 6266, 6273, 6260, 6270, 6263, 6265, 6245, 6257, 6258, 925, + 1930, 6256, 3637, 2222, 2352, 2513,14226, 2387, 3155, 2796, + 6248, 6246, 6232, 2236, 6234, 3345, 2051, 3133, 3192, 6235, + 3216, 3309, 3418, 2103, 3445,14226, 0, 6232, 6224, 6223, + 6220, 3699, 2295, 3461, 3321, 3747, 1500, 3804, 3866, 3058, + 3488, 3502, 3914, 1949, 6213, 2373, 3537, 2997, 3542, 3544, + 3556, 3568, 3583, 3928, 3761, 3587, 3937, 3938, 3943, 3952, + 3959, 3974, 3770, 3771, 2665, 3975, 6186,14226, 6184, 6194, + + 6174, 6177, 6170, 6166, 6166, 6165, 6152, 6139, 6154, 3514, + 4025, 3582, 3994, 4086, 4001, 4141,14226, 2669, 1709, 2074, + 1809, 2146, 2130, 2172, 2206, 2143, 1014, 1128, 2428, 4042, + 2105, 4027, 4049, 6141, 4056, 4115,14226, 2013, 4200, 4150, + 4122, 4222, 4278, 2924, 4329, 4159, 4166, 4351, 4407, 3041, + 4458, 4175, 4186, 4480, 4536, 3234, 4587, 4208, 4627, 6128, + 4689, 0, 2466, 4231, 4285, 4737, 2210, 4794, 4856, 4264, + 2486, 4292, 4316, 2388, 4917, 4978, 1376, 2256, 535, 2154, + 2254, 2307, 2276, 2360, 2823, 2326, 2055, 2342, 1754, 1636, + 1834, 2828, 2400, 6122, 6116, 6126, 6120, 6122, 6102, 6117, + + 6102, 2354, 5039, 5989, 2261, 5089, 2590, 2547, 2679, 2901, + 2979, 2552, 5984, 2710, 3941, 3972, 5968, 4337, 4358,14226, + 4393, 2418, 4414, 4421, 5964, 5975, 5973, 5137, 4488, 4544, + 2705, 5183, 5970, 5199, 4598, 4744, 5224, 2374, 5281, 5343, + 3998, 3277, 4445, 4522, 2439, 4573,14226, 0, 5966, 5939, + 4028, 4444, 4520, 4570, 4089, 5404, 5430, 4924, 4245, 4459, + 4928, 4930, 4263, 4126, 2628, 4392,14226, 4231, 5457, 2994, + 4233, 4391, 5910, 5917, 5907, 5914, 5901, 5911, 5902, 5899, + 5879, 5882, 5882, 4766, 5518, 5579, 1437, 2472, 2695, 2525, + 2447, 2531, 2497, 4950, 4978,14226, 5854, 5640, 487, 2540, + + 2873, 2713, 4995, 2627,14226, 0, 2934, 5696, 3093, 2664, + 3094, 2721, 5007, 2876, 0, 3196, 5752, 3257, 2894, 3318, + 2787, 5038, 2937,14226, 0, 3467, 4490, 5808, 5830, 5878, + 5047, 5145, 2853, 5924, 5882, 5940, 5532, 5167, 5965, 2775, + 6022, 6084, 5190, 5253, 5911, 6145, 6206, 5842, 2760, 2459, + 2189, 2939, 5839, 2537, 2953, 3000, 3571, 5830, 5842, 5831, + 6267, 4914, 5830, 3031, 3085, 2945, 5831, 5828, 3507, 5813, + 3292, 3485, 6317, 3221, 4522, 4071, 4352, 6378, 6400, 5802, + 4657, 4488, 5405, 4546, 3155, 5206, 5231,14226, 6412, 3426, + 5539, 5579, 6428, 6459, 5595, 5602, 3428, 6505, 5813, 6521, + + 6560, 5230, 5631, 3081, 5647, 5654, 5798, 5809, 5808, 5151, + 5677, 5407, 0, 5693, 5679, 5700, 3537, 5563,14226, 4654, + 6622, 5167, 5008, 6684, 3159, 6744, 6773, 6802, 3125, 6859, + 6921, 3557, 5730, 5408, 5779, 5790, 5783, 5784, 5756, 5771, + 5751, 3187, 3199, 2608, 5764, 3939, 5794, 5866, 4275, 5907, + 4985, 5830, 5947, 4340, 5994, 5029, 5842, 6146, 4404, 6982, + 6159, 7004, 3243, 7050, 3454, 5885, 5972, 7066, 7097, 6171, + 6206, 3456, 7143, 5766, 7159, 7198, 7259, 7320, 5744, 5756, + 5727, 5715, 5683, 5665, 5644, 5665, 5645, 5659, 5646, 5656, + 5645, 5635, 5609, 5609, 2425, 5597, 4004, 7381, 4485, 7430, + + 3605, 5736, 5766, 5594, 5410, 5601, 5733, 5606, 6228, 6255, + 5603, 7469, 3758, 6272, 6420, 5584, 5729, 6364, 6386,14226, + 5678, 0, 3582, 7499, 7528, 7557, 3440, 7614, 7676, 4086, + 5575, 7736, 7772, 5017, 7808, 4207, 7837, 7874, 7903, 7920, + 7963, 8020, 0, 5545, 4649, 6482,14226, 5719, 8082, 5906, + 5909, 5540, 5551, 5538, 6436, 6766, 3782, 6512, 6991, 3940, + 6528, 7013, 3944, 5549, 6160, 6213, 0, 7058, 7074, 5510, + 8133, 3769, 7104, 7126, 5486, 5477, 5408, 5401,14226, 5407, + 5393, 5381, 5238, 5231, 5221, 5192, 5159, 5133, 5025, 5020, + 0, 4257, 1868, 3745, 4355, 4593, 3249, 3313, 5596, 2877, + + 0, 4766, 2379, 4313, 4537, 4626, 3757, 3918, 5652, 2991, + 2870, 4963, 6799, 4988, 6746, 6239, 7151, 7259, 4949, 5971, + 4943, 8163, 8199, 6236, 8235, 5051, 8264, 8301, 8330, 8347, + 8390, 8447, 0, 6283, 8507, 6469, 8536, 8565, 4894, 8582, + 8637, 8673, 6825, 8709, 6232, 8724, 0, 6458, 6748, 4792, + 7269, 6823, 0, 3624, 8761, 8790, 8819, 3952, 8876, 8938, + 6468, 7014, 7285, 7320, 4749, 4672, 4625, 4596, 4581, 4566, + 4535, 4533, 4448, 4357, 4311, 4284, 4254, 2562, 2972, 2910, + 3410, 3130, 872, 3201, 2603, 3023, 3495, 3026, 4287, 3946, + 4049, 3231, 3320, 3555, 3467, 2682, 3511, 3135, 4063, 4083, + + 3961, 4595, 3949, 3483, 5527, 7126, 5789, 7342, 7282, 4079, + 5735, 8998, 7342, 9027, 9056, 4052, 9073, 9128, 9164, 7346, + 9200, 6778, 9215, 0, 7015, 7326, 4051, 7367, 7371, 9252, + 9281, 6805, 9310, 7404, 9339, 9368, 3989, 7408, 3931, 7420, + 7424, 7468, 3768, 9397, 9433, 7479, 9469, 7026, 9498, 9535, + 9564, 9581, 9624, 9681, 0, 7481, 7107, 4145, 3675, 3633, + 3570, 3414, 3349, 3315, 3264, 4003, 3245, 4293, 3583, 4351, + 4124, 4352, 3316, 4054, 3746, 4551, 2785, 4415, 4121, 3198, + 4745, 4118, 4888, 4416, 4890, 4168, 4290, 4179, 4914, 4721, + 4452, 3152, 3037, 3013, 2977, 4189, 7530, 7363, 9741, 9770, + + 7107, 9799, 7566, 9828, 9857, 2882, 7504, 2865, 7738, 7512, + 7568, 9886, 9915, 7265, 7578, 9944, 7747, 9973,10002, 2838, + 10019,10074,10110, 7781,10146, 7267,10161, 0, 7777, 7811, + 2808, 7820, 7877, 2718, 2643, 2623, 4484, 4289, 4489, 4418, + 4741, 4491, 4541, 4236, 4335, 4582, 4645, 4891, 4649, 4896, + 4952, 4742, 5012, 5139, 4257, 4570, 5031, 5048, 2498, 2290, + 2185, 2113, 7942, 7422, 7375, 7944,14226, 7565,10200, 7757, + 7746,10260,10289, 7445, 7885,10318,10347, 7582,10376, 7945, + 10405,10434, 2038, 7963, 1990, 8143, 7984, 7987, 4492, 4419, + 5141, 5140, 3084, 5159, 2548, 4739, 5229, 5226, 5233, 4368, + + 5245, 4456, 1935, 1767, 1685, 1552, 8167, 7813, 0, 5436, + 10463,10492,10521, 4988,10578,10640, 7748,10700,10729, 7793, + 8175, 4910, 5489, 5040, 5491, 5536, 5535, 1466, 1225, 1285, + 1273,10758,10794, 8208,10830, 7887,10859,10896,10925,10942, + 10985,11042, 0, 8210, 1154, 4980,11102, 8245,11131,11160, + 1024,11177,11232,11268, 8247,11304, 7926,11319, 0, 8243, + 8304, 962, 8312, 8368, 789, 586,11356,11385, 7928,11414, + 8355,11443,11472, 404, 8371, 390, 8391, 8411, 8414, 3527, + 295,11501,11530, 7971, 8510, 5522,14226,11561,11585,11609, + 11618,11632,11655,11671,11694,11707,11724, 5734,11748,11771, + + 11793,11809,11822,11845, 5776,11862,11873,11884, 5789,11888, + 11912,11935,11959,11972,11984,12008,12017,12032,12056,12069, + 12088,12106,12117,12141,12164, 5857,12180,12204,12217,12241, + 12264,12274, 6183,12285,12307,12318,12329,12341,12365,12388, + 12409, 6484,12433,12452,12476,12493,12508, 6493,12519,12532, + 12556,12580,12603,12626, 6503,12648,12672,12685,12700, 6740, + 12711, 6840, 6973, 7036, 7172,12730, 7297,12753,12766,12784, + 12808,12827,12840,12850, 7308,12861,12885,12909,12933,12956, + 12969,12993,13006,13019,13027,13049,13068,13087,13107,13130, + 13148,13172,13189,13213,13226,13245,13269,13292,13307, 7369, + + 13318,13342,13365,13387,13400,13423, 7392,13443, 7460,13463, + 7491,13484,13507,13531,13555,13574,13597,13619,13643,13667, + 13690,13703,13722,13746,13759,13782,13802,13822,13843,13866, + 13890,13914,13937,13961, 7546,13985,14009,14033,14057,14081, + 14105,14129,14153,14177,14201 + } ; + +static yyconst short int yy_def[1846] = + { 0, + 1687, 1, 1, 3, 1, 1, 1687, 7, 1687, 9, + 9, 11, 1688, 1688, 1687, 1687, 1687, 1687, 1687, 1689, + 1687, 1687, 1687, 1690, 1691, 1687, 1687, 1687, 1687, 1687, + 30, 1687, 1687, 1687, 1692, 1687, 1693, 1693, 1693, 1693, + 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, + 1693, 1693, 1687, 1687, 1687, 1687, 1687, 1687, 27, 54, + 1687, 1687, 62, 1687, 54, 1687, 1687, 1687, 1687, 1687, + 1691, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 71, 1687, + 27, 1687, 1687, 1687, 84, 1687, 1687, 1687, 1687, 1694, + 1687, 1695, 1695, 93, 93, 93, 93, 93, 93, 93, + + 93, 93, 93, 93, 93, 93, 93, 93, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1696, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1689, + 1687, 1690, 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697, + 1687, 30, 31, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1698, 1692, 1699, 1687, 1687, 1687, 1693, + 1700, 1701, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, + 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, + 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1693, + 1693, 1693, 54, 1687, 54, 1687, 1687, 1687, 198, 1702, + + 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1703, 1687, + 1687, 62, 62, 1704, 1687, 1704, 1687, 1687, 1687, 1687, + 1705, 64, 1687, 1687, 1687, 225, 54, 1687, 1687, 1687, + 1687, 1687, 1687, 84, 84, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 236, 1706, 1687, 1687, 1687, 1687, 1707, 1687, + 1708, 1687, 1687, 1687, 1687, 1709, 1687, 1710, 1711, 1687, + 1687, 1687, 1687, 1712, 1687, 1700, 1687, 1713, 1687, 1712, + 1687, 266, 270, 270, 270, 270, 270, 270, 270, 270, + 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, + 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, + + 270, 270, 1687, 1714, 1687, 1715, 1716, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1717, 1718, 1719, 1718, 1718, 1718, 1718, 1718, 1718, + 1718, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1720, 1721, 1721, 266, 266, 1687, 1687, 1687, 348, 1722, + 1723, 1724, 1724, 1725, 1725, 1725, 1725, 1725, 1725, 1725, + 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, + 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, 1725, + 1725, 1725, 1725, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 394, 1687, 1687, 1687, 1687, 1687, + + 1687, 1687, 397, 1687, 1687, 1687, 1687, 1687, 398, 1726, + 1687, 1727, 1728, 1729, 1730, 1729, 1729, 1729, 1729, 1729, + 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1687, 1687, + 1687, 1687, 1687, 433, 1687, 1687, 1687, 1731, 1732, 1687, + 1687, 1687, 1687, 1687, 1733, 1687, 1734, 1687, 1687, 1687, + 1735, 1736, 1687, 1687, 454, 1687, 1735, 1687, 1687, 459, + 1687, 456, 1737, 1687, 1687, 465, 1687, 1738, 1738, 1739, + 1739, 1740, 1740, 1687, 1687, 1687, 476, 1741, 1741, 479, + 479, 479, 479, 479, 479, 479, 479, 479, 479, 479, + 479, 479, 479, 479, 479, 479, 479, 479, 479, 479, + + 479, 479, 479, 479, 479, 479, 479, 1687, 1742, 1687, + 1743, 1743, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1744, 1745, 1745, 1746, 1746, + 1746, 1746, 1746, 1746, 1746, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1747, 1687, 1687, 1687, 1687, 1687, 1748, + 1687, 1687, 1687, 553, 1749, 1750, 1751, 1752, 1752, 1687, + 1753, 1754, 1754, 1753, 1753, 1753, 1753, 1753, 1753, 1753, + 1753, 1753, 1753, 1753, 1687, 1753, 1753, 1753, 1753, 1753, + 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + + 1687, 1687, 1687, 1687, 1687, 1687, 605, 1687, 1687, 1687, + 1755, 1687, 1687, 1687, 1687, 1687, 610, 1687, 617, 1687, + 1756, 1756, 1757, 1757, 1758, 1758, 1758, 1758, 1758, 1758, + 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1687, 1687, 1759, + 1687, 1687, 1687, 1687, 1687, 1760, 1687, 1687, 1687, 1687, + 1687, 1761, 1687, 1762, 1687, 1687, 1687, 1687, 1687, 1687, + 1763, 1687, 1687, 1687, 1764, 1687, 1687, 1687, 1765, 1687, + 1687, 1766, 1766, 1766, 1766, 1766, 1766, 1687, 1766, 1766, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1767, 1768, 1768, + 690, 690, 690, 690, 690, 690, 690, 690, 690, 690, + + 690, 690, 690, 690, 690, 690, 690, 690, 690, 690, + 690, 690, 690, 690, 690, 1769, 1754, 717, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1770, 1771, 1687, 1772, 1772, 1772, 1687, 1772, 1772, 1772, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1773, + 1774, 1687, 1687, 1687, 1687, 1687, 1775, 1776, 1777, 1778, + 1778, 1687, 762, 1779, 1779, 1779, 766, 1687, 1687, 1780, + 1687, 1687, 1687, 773, 1781, 717, 1780, 1780, 1780, 1780, + 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, + 1780, 1780, 1780, 1782, 1782, 1780, 1687, 1687, 1687, 1687, + + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 811, 1687, 1687, 811, 1687, 811, 1783, 1783, + 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1687, + 1687, 1687, 1687, 1784, 1687, 1687, 1687, 1785, 1687, 1687, + 1687, 1687, 1687, 1786, 1687, 1687, 1687, 1687, 1687, 1787, + 1687, 1687, 1687, 1687, 1687, 1788, 1687, 1687, 1687, 859, + 1687, 861, 861, 1789, 1789, 1789, 866, 1687, 1687, 1687, + 1687, 1687, 1687, 1790, 1791, 1791, 876, 876, 876, 876, + 876, 876, 876, 876, 876, 876, 876, 876, 876, 876, + 876, 876, 876, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + + 1687, 1687, 1687, 1792, 1792, 1687, 1793, 1793, 1793, 1793, + 1793, 1687, 1687, 1687, 1794, 1794, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1795, 1796, 1796, 1797, 1797, 1797, + 1797, 1797, 1797, 1797, 1797, 1797, 1797, 937, 1687, 1687, + 1798, 1799, 1687, 1687, 1687, 1687, 1687, 1800, 1801, 1802, + 1798, 1798, 1798, 1798, 1798, 1803, 1803, 1798, 1798, 1798, + 1798, 1798, 1804, 1804, 1794, 1794, 1687, 1794, 1687, 1794, + 1794, 1798, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1805, 1805, 1805, 1805, + 1805, 1805, 1805, 1687, 1687, 1687, 1687, 1687, 1806, 1687, + + 1806, 1687, 1687, 1687, 1687, 1807, 1687, 1687, 1808, 1687, + 1808, 1687, 1687, 1687, 1809, 1687, 1687, 1810, 1687, 1810, + 1687, 1687, 1687, 1687, 1811, 1687, 1687, 1687, 1687, 1812, + 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1039, + 1687, 1687, 1687, 1687, 1687, 1813, 1813, 1047, 1047, 1047, + 1047, 1047, 1047, 1047, 1047, 1047, 1047, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1814, 1815, 1687, 1816, 1816, 1816, 1816, 1817, 1817, 1687, + 1818, 1818, 1819, 1819, 1687, 1687, 1687, 1687, 1820, 1820, + 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, + + 1687, 1821, 1687, 1687, 1687, 1687, 1822, 1823, 1823, 1821, + 1821, 1821, 1079, 1821, 1821, 1821, 1818, 1818, 1687, 1818, + 1687, 1818, 1818, 1687, 1124, 1819, 1819, 1819, 1128, 1687, + 1687, 1819, 1824, 1824, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1825, 1825, 1825, 1687, 1687, 1687, 1687, 1826, 1687, + 1687, 1687, 1687, 1827, 1687, 1687, 1687, 1687, 1828, 1687, + 1687, 1687, 1162, 1829, 1829, 1829, 1829, 1829, 1829, 1829, + 1829, 1829, 1829, 1829, 1829, 1687, 1830, 1830, 1178, 1178, + 1178, 1178, 1178, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1831, 1831, 1832, 1832, + + 1833, 1833, 1833, 1687, 1818, 1818, 1824, 1824, 1820, 1820, + 1820, 1820, 1820, 1820, 1820, 1100, 1821, 1687, 1687, 1687, + 1821, 1121, 1121, 1818, 1818, 1818, 1226, 1687, 1687, 1818, + 1128, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1128, + 1128, 1687, 1131, 1834, 1824, 1824, 1687, 1824, 1687, 1824, + 1824, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1162, 1687, 1687, 1835, 1829, 1829, 1829, + 1829, 1829, 1829, 1829, 1175, 1178, 1178, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1198, 1198, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, + + 1200, 1200, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, + 1687, 1833, 1833, 1687, 1824, 1824, 1820, 1820, 1820, 1821, + 1226, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1226, + 1226, 1687, 1229, 1836, 1819, 1819, 1819, 1819, 1237, 1128, + 1819, 1819, 1819, 1819, 1819, 1237, 1242, 1837, 1834, 1838, + 1834, 1834, 1249, 1249, 1824, 1824, 1824, 1357, 1687, 1687, + 1824, 1835, 1829, 1829, 1829, 1178, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1831, 1831, 1831, + 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, + 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, + + 1832, 1832, 1832, 1687, 1687, 1833, 1833, 1833, 1833, 1687, + 1821, 1818, 1818, 1818, 1818, 1327, 1226, 1818, 1818, 1818, + 1818, 1818, 1327, 1332, 1839, 1836, 1838, 1836, 1836, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1346, 1837, 1840, 1837, + 1837, 1834, 1357, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1357, 1357, 1687, 1360, 1841, 1687, 1178, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1831, 1831, 1831, 1831, 1831, + 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1832, 1832, + 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, + 1832, 1687, 1687, 1687, 1687, 1687, 1842, 1842, 1818, 1818, + + 1818, 1818, 1818, 1818, 1818, 1423, 1839, 1840, 1839, 1839, + 1836, 1819, 1819, 1819, 1837, 1824, 1824, 1824, 1824, 1449, + 1357, 1824, 1824, 1824, 1824, 1824, 1449, 1454, 1843, 1841, + 1838, 1841, 1841, 1687, 1687, 1687, 1831, 1831, 1831, 1831, + 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1832, 1832, 1832, + 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1687, 1687, + 1687, 1687, 1842, 1842, 1842, 1842, 1687, 1842, 1687, 1842, + 1842, 1818, 1818, 1818, 1839, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1527, 1843, 1840, 1843, 1843, 1841, 1831, 1831, + 1831, 1831, 1831, 1831, 1831, 1832, 1832, 1832, 1832, 1832, + + 1832, 1832, 1687, 1687, 1687, 1687, 1842, 1842, 1569, 1569, + 1842, 1842, 1842, 1613, 1687, 1687, 1842, 1824, 1824, 1824, + 1843, 1831, 1831, 1831, 1832, 1832, 1832, 1687, 1687, 1687, + 1613, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1613, + 1613, 1687, 1616, 1844, 1687, 1687, 1842, 1842, 1842, 1842, + 1637, 1613, 1842, 1842, 1842, 1842, 1842, 1637, 1642, 1845, + 1844, 1838, 1844, 1844, 1687, 1687, 1842, 1842, 1842, 1842, + 1842, 1842, 1842, 1658, 1845, 1840, 1845, 1845, 1844, 1687, + 1687, 1842, 1842, 1842, 1845, 1687, 0, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687 + } ; + +static yyconst short int yy_nxt[14289] = + { 0, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 27, 29, 22, 30, 31, 31, 31, + 31, 31, 31, 16, 28, 32, 33, 34, 35, 16, + 36, 16, 37, 38, 39, 40, 41, 42, 43, 44, + 37, 45, 46, 37, 47, 37, 37, 37, 48, 49, + 50, 37, 51, 37, 52, 37, 37, 37, 16, 53, + 16, 22, 54, 55, 121, 121, 56, 57, 118, 118, + 58, 59, 60, 59, 61, 56, 62, 63, 63, 63, + 63, 63, 63, 64, 65, 66, 67, 68, 71, 72, + 69, 73, 71, 72, 121, 73, 119, 119, 1687, 121, + + 121, 122, 123, 124, 312, 125, 126, 210, 210, 210, + 210, 313, 127, 230, 230, 500, 128, 129, 501, 70, + 1687, 56, 16, 74, 75, 76, 20, 21, 77, 78, + 24, 79, 80, 81, 82, 81, 83, 77, 84, 85, + 85, 85, 85, 85, 85, 16, 86, 87, 88, 89, + 90, 16, 91, 16, 92, 93, 94, 95, 96, 97, + 98, 99, 100, 101, 102, 100, 103, 100, 100, 100, + 104, 105, 106, 100, 107, 100, 108, 100, 100, 100, + 109, 110, 16, 77, 111, 111, 111, 111, 111, 111, + 111, 111, 111, 112, 113, 111, 114, 111, 111, 111, + + 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, + 115, 111, 111, 111, 111, 111, 116, 116, 116, 116, + 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, + 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, + 116, 116, 111, 111, 111, 111, 111, 111, 314, 111, + 134, 135, 315, 136, 228, 415, 137, 230, 230, 138, + 231, 264, 264, 111, 310, 311, 139, 423, 140, 111, + 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, + 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, + 111, 111, 111, 111, 111, 141, 415, 142, 143, 143, + + 143, 143, 143, 143, 149, 149, 149, 149, 149, 149, + 149, 229, 1687, 281, 122, 123, 124, 232, 125, 144, + 158, 264, 264, 626, 158, 127, 338, 338, 159, 145, + 129, 146, 159, 147, 1687, 148, 150, 415, 143, 143, + 143, 143, 143, 143, 143, 161, 158, 1686, 162, 161, + 1687, 1687, 162, 322, 159, 158, 151, 158, 628, 152, + 264, 264, 165, 159, 287, 159, 153, 298, 163, 164, + 324, 161, 1687, 1687, 162, 288, 264, 264, 154, 158, + 161, 158, 161, 162, 415, 162, 158, 159, 415, 159, + 264, 264, 166, 167, 159, 168, 419, 175, 299, 176, + + 158, 169, 170, 420, 161, 416, 161, 162, 159, 162, + 158, 161, 292, 177, 162, 171, 264, 264, 159, 415, + 172, 927, 158, 275, 178, 161, 289, 181, 162, 173, + 159, 158, 158, 174, 179, 161, 290, 264, 162, 159, + 159, 158, 428, 415, 180, 1687, 415, 161, 1684, 159, + 162, 264, 264, 276, 277, 424, 161, 161, 228, 162, + 162, 630, 182, 183, 158, 282, 161, 1687, 322, 162, + 184, 185, 159, 158, 283, 264, 264, 186, 284, 291, + 187, 159, 285, 188, 286, 324, 264, 264, 1000, 161, + 278, 322, 162, 189, 264, 264, 279, 280, 161, 322, + + 190, 162, 328, 318, 191, 302, 264, 264, 324, 192, + 193, 319, 194, 264, 264, 229, 324, 320, 195, 325, + 196, 415, 196, 197, 1145, 198, 199, 199, 199, 199, + 199, 199, 435, 435, 326, 240, 240, 200, 1005, 417, + 418, 201, 202, 203, 204, 201, 205, 206, 201, 201, + 201, 201, 201, 207, 201, 201, 201, 208, 209, 201, + 201, 201, 201, 201, 201, 201, 201, 210, 415, 240, + 240, 456, 456, 300, 122, 123, 124, 301, 125, 126, + 231, 264, 264, 421, 158, 127, 1048, 422, 264, 128, + 129, 211, 159, 212, 213, 213, 213, 213, 213, 213, + + 214, 214, 214, 214, 214, 214, 214, 215, 233, 161, + 234, 235, 235, 235, 235, 235, 235, 322, 322, 215, + 216, 322, 213, 213, 213, 213, 213, 213, 213, 217, + 134, 135, 1681, 136, 324, 324, 137, 232, 324, 138, + 218, 217, 215, 219, 322, 1687, 139, 230, 140, 327, + 220, 262, 262, 329, 122, 123, 124, 700, 125, 126, + 318, 324, 221, 222, 217, 127, 264, 1687, 319, 128, + 129, 1687, 330, 223, 320, 223, 224, 333, 225, 226, + 226, 226, 226, 226, 226, 236, 236, 236, 236, 236, + 236, 236, 237, 1687, 238, 239, 415, 240, 241, 242, + + 215, 693, 240, 322, 240, 243, 240, 235, 235, 235, + 235, 235, 235, 235, 244, 158, 245, 246, 247, 264, + 324, 158, 217, 159, 828, 248, 158, 249, 250, 159, + 523, 251, 252, 524, 159, 253, 429, 331, 596, 254, + 161, 255, 597, 162, 262, 262, 161, 256, 508, 162, + 257, 161, 240, 158, 162, 261, 491, 491, 262, 263, + 509, 159, 366, 262, 510, 262, 355, 262, 149, 149, + 149, 149, 149, 149, 149, 293, 415, 265, 266, 267, + 627, 268, 294, 295, 338, 338, 322, 264, 264, 296, + 415, 303, 297, 303, 629, 322, 304, 305, 305, 305, + + 305, 305, 305, 324, 149, 149, 149, 149, 149, 149, + 149, 269, 324, 270, 271, 415, 261, 592, 593, 262, + 263, 531, 159, 632, 262, 337, 262, 215, 262, 149, + 149, 149, 149, 149, 149, 149, 530, 158, 265, 272, + 267, 1680, 268, 322, 1687, 159, 339, 415, 339, 217, + 152, 340, 340, 340, 340, 340, 340, 340, 273, 274, + 324, 158, 161, 219, 529, 162, 1687, 400, 400, 159, + 594, 819, 269, 158, 270, 344, 415, 595, 400, 400, + 631, 159, 356, 345, 354, 346, 161, 346, 347, 162, + 348, 349, 349, 349, 349, 349, 349, 350, 161, 158, + + 271, 162, 415, 905, 158, 158, 425, 159, 159, 158, + 158, 158, 159, 159, 426, 158, 1471, 159, 159, 159, + 427, 617, 617, 159, 161, 472, 902, 162, 357, 161, + 161, 358, 162, 162, 161, 161, 161, 162, 162, 162, + 161, 361, 158, 162, 158, 322, 1687, 415, 158, 360, + 159, 903, 159, 359, 363, 626, 159, 158, 364, 415, + 322, 362, 324, 367, 367, 159, 415, 161, 1687, 161, + 162, 158, 162, 161, 365, 1687, 162, 324, 637, 159, + 158, 158, 161, 625, 535, 162, 158, 322, 159, 159, + 158, 368, 615, 761, 159, 402, 161, 1687, 159, 162, + + 532, 372, 158, 369, 324, 161, 161, 415, 162, 162, + 159, 161, 371, 158, 162, 161, 322, 158, 162, 415, + 370, 159, 534, 158, 633, 159, 373, 161, 158, 401, + 162, 159, 402, 324, 825, 374, 159, 237, 161, 158, + 698, 162, 161, 415, 616, 162, 158, 159, 161, 357, + 533, 162, 264, 161, 159, 158, 162, 376, 375, 244, + 377, 415, 158, 159, 161, 600, 626, 162, 1669, 378, + 159, 161, 451, 601, 162, 379, 251, 705, 634, 602, + 161, 411, 380, 162, 384, 385, 386, 161, 387, 388, + 162, 649, 649, 264, 1687, 389, 383, 894, 382, 390, + + 391, 381, 1687, 397, 397, 397, 397, 397, 397, 397, + 747, 747, 392, 510, 392, 393, 1687, 394, 395, 395, + 395, 395, 395, 395, 197, 706, 396, 199, 199, 199, + 199, 199, 199, 214, 214, 214, 214, 214, 214, 214, + 452, 457, 264, 384, 385, 386, 215, 387, 388, 415, + 453, 458, 453, 458, 389, 454, 459, 415, 390, 391, + 398, 635, 399, 1687, 636, 400, 401, 993, 217, 402, + 400, 1687, 400, 403, 400, 199, 199, 199, 199, 199, + 199, 199, 463, 692, 404, 405, 406, 558, 1687, 647, + 264, 695, 464, 407, 464, 559, 408, 465, 264, 436, + + 1665, 436, 711, 409, 437, 437, 437, 437, 437, 437, + 437, 717, 560, 730, 264, 410, 699, 353, 411, 718, + 400, 430, 224, 264, 439, 226, 226, 226, 226, 226, + 226, 431, 732, 431, 432, 737, 433, 434, 434, 434, + 434, 434, 434, 440, 440, 440, 440, 440, 440, 440, + 441, 674, 226, 226, 226, 226, 226, 226, 226, 236, + 236, 236, 236, 236, 236, 236, 1645, 708, 264, 1687, + 442, 415, 709, 443, 264, 471, 303, 821, 303, 441, + 444, 304, 305, 305, 305, 305, 305, 305, 446, 322, + 446, 1687, 445, 447, 448, 448, 448, 448, 448, 448, + + 238, 239, 443, 240, 241, 242, 324, 1565, 240, 444, + 240, 735, 240, 236, 236, 236, 236, 236, 236, 236, + 215, 445, 245, 246, 247, 304, 305, 305, 305, 305, + 305, 305, 562, 449, 450, 435, 435, 1646, 252, 264, + 563, 215, 217, 882, 461, 254, 461, 255, 733, 462, + 462, 462, 462, 462, 462, 462, 257, 161, 240, 237, + 162, 238, 239, 217, 240, 241, 242, 528, 264, 240, + 415, 240, 883, 240, 305, 305, 305, 305, 305, 305, + 305, 244, 823, 245, 246, 247, 340, 340, 340, 340, + 340, 340, 340, 717, 249, 415, 158, 807, 251, 252, + + 808, 718, 508, 626, 159, 541, 254, 541, 255, 481, + 542, 542, 542, 542, 542, 542, 542, 257, 510, 240, + 158, 161, 261, 717, 162, 262, 263, 721, 159, 264, + 262, 718, 262, 881, 262, 340, 340, 340, 340, 340, + 340, 340, 264, 568, 265, 266, 267, 347, 268, 544, + 349, 349, 349, 349, 349, 349, 545, 545, 545, 545, + 545, 545, 545, 723, 811, 811, 415, 158, 605, 605, + 605, 605, 605, 605, 605, 159, 737, 618, 269, 618, + 270, 344, 619, 619, 619, 619, 619, 619, 619, 345, + 1142, 346, 161, 346, 347, 162, 348, 349, 349, 349, + + 349, 349, 349, 350, 831, 831, 262, 158, 415, 261, + 561, 653, 262, 263, 562, 159, 158, 262, 562, 262, + 562, 262, 563, 654, 159, 820, 563, 655, 563, 717, + 562, 265, 266, 267, 352, 268, 565, 718, 563, 161, + 415, 161, 162, 161, 162, 161, 162, 826, 162, 158, + 575, 158, 415, 158, 567, 161, 352, 159, 162, 159, + 575, 159, 717, 566, 726, 269, 564, 270, 473, 822, + 718, 879, 575, 691, 161, 569, 161, 162, 474, 162, + 474, 475, 264, 476, 477, 477, 477, 477, 477, 477, + 546, 158, 349, 349, 349, 349, 349, 349, 349, 159, + + 562, 367, 1630, 415, 717, 264, 158, 720, 563, 717, + 547, 457, 718, 548, 159, 829, 161, 718, 264, 162, + 549, 458, 562, 458, 892, 161, 459, 570, 162, 562, + 563, 161, 550, 551, 162, 551, 552, 563, 553, 554, + 554, 554, 554, 554, 554, 573, 571, 161, 158, 722, + 162, 491, 725, 158, 161, 717, 159, 162, 264, 158, + 158, 159, 572, 718, 649, 649, 562, 159, 159, 717, + 471, 562, 574, 161, 563, 579, 162, 718, 161, 563, + 576, 162, 158, 1055, 161, 161, 577, 162, 162, 264, + 159, 161, 562, 562, 162, 729, 161, 578, 674, 162, + + 563, 563, 580, 158, 674, 562, 581, 161, 158, 471, + 162, 159, 322, 563, 158, 158, 159, 161, 161, 322, + 162, 162, 159, 159, 1629, 728, 158, 158, 161, 324, + 161, 162, 582, 162, 159, 159, 324, 583, 415, 161, + 161, 740, 162, 162, 585, 586, 452, 415, 697, 584, + 587, 161, 161, 987, 162, 162, 453, 734, 453, 158, + 264, 454, 589, 638, 824, 638, 588, 159, 639, 639, + 639, 639, 639, 639, 639, 674, 674, 737, 590, 393, + 471, 604, 395, 395, 395, 395, 395, 395, 432, 1054, + 640, 434, 434, 434, 434, 434, 434, 717, 384, 385, + + 386, 658, 387, 388, 877, 718, 694, 264, 717, 389, + 717, 264, 264, 390, 391, 398, 718, 399, 718, 889, + 400, 606, 264, 659, 737, 400, 322, 400, 607, 400, + 395, 395, 395, 395, 395, 395, 395, 457, 415, 404, + 405, 406, 724, 324, 514, 659, 158, 458, 608, 458, + 322, 609, 459, 989, 159, 727, 463, 415, 610, 641, + 641, 641, 641, 641, 641, 641, 464, 324, 464, 1056, + 611, 465, 717, 612, 827, 400, 398, 738, 399, 702, + 718, 400, 401, 871, 871, 402, 400, 264, 400, 403, + 400, 199, 199, 199, 199, 199, 199, 199, 264, 905, + + 404, 405, 406, 437, 437, 437, 437, 437, 437, 437, + 322, 322, 408, 890, 1378, 741, 658, 491, 264, 409, + 440, 440, 440, 440, 440, 440, 440, 324, 324, 674, + 674, 410, 736, 887, 411, 471, 400, 398, 659, 399, + 730, 648, 400, 401, 264, 264, 402, 400, 739, 400, + 215, 400, 397, 397, 397, 397, 397, 397, 397, 732, + 659, 404, 405, 406, 575, 437, 437, 437, 437, 437, + 437, 437, 217, 613, 575, 440, 440, 440, 440, 440, + 440, 440, 650, 1687, 650, 1628, 575, 651, 651, 651, + 651, 651, 651, 651, 880, 411, 443, 400, 398, 884, + + 399, 158, 264, 400, 606, 1687, 491, 264, 400, 159, + 400, 886, 400, 447, 448, 448, 448, 448, 448, 448, + 264, 927, 404, 405, 406, 481, 448, 448, 448, 448, + 448, 448, 448, 656, 264, 656, 264, 696, 657, 657, + 657, 657, 657, 657, 657, 454, 455, 455, 455, 455, + 455, 455, 264, 264, 653, 893, 612, 997, 400, 430, + 459, 460, 460, 460, 460, 460, 460, 747, 747, 431, + 655, 431, 432, 655, 433, 434, 434, 434, 434, 434, + 434, 642, 1620, 434, 434, 434, 434, 434, 434, 434, + 462, 462, 462, 462, 462, 462, 462, 885, 264, 1053, + + 891, 643, 481, 415, 644, 264, 481, 264, 264, 264, + 988, 645, 462, 462, 462, 462, 462, 462, 462, 922, + 922, 831, 831, 646, 658, 465, 466, 466, 466, 466, + 466, 466, 682, 682, 682, 682, 682, 682, 682, 455, + 455, 455, 455, 455, 455, 455, 659, 475, 158, 681, + 477, 477, 477, 477, 477, 477, 159, 158, 158, 415, + 1606, 776, 158, 158, 575, 159, 159, 660, 659, 1687, + 159, 159, 415, 662, 575, 415, 626, 704, 991, 661, + 238, 239, 990, 240, 241, 242, 575, 481, 240, 701, + 240, 158, 240, 456, 456, 663, 703, 158, 491, 159, + + 264, 415, 245, 246, 247, 159, 662, 264, 992, 264, + 264, 158, 158, 449, 264, 264, 158, 663, 252, 159, + 159, 158, 717, 546, 159, 254, 481, 255, 663, 159, + 718, 1605, 737, 712, 322, 415, 257, 915, 240, 662, + 264, 707, 626, 264, 470, 916, 548, 666, 714, 264, + 663, 324, 710, 549, 460, 460, 460, 460, 460, 460, + 460, 663, 794, 264, 264, 550, 470, 713, 264, 667, + 795, 1071, 715, 264, 719, 542, 542, 542, 542, 542, + 542, 542, 664, 663, 542, 542, 542, 542, 542, 542, + 542, 667, 905, 481, 665, 666, 352, 545, 545, 545, + + 545, 545, 545, 545, 352, 264, 1049, 264, 666, 264, + 466, 466, 466, 466, 466, 466, 466, 667, 746, 545, + 545, 545, 545, 545, 545, 545, 748, 1051, 748, 264, + 667, 749, 749, 749, 749, 749, 749, 749, 668, 667, + 548, 552, 1604, 751, 554, 554, 554, 554, 554, 554, + 669, 237, 667, 238, 239, 902, 240, 241, 242, 1050, + 264, 240, 1687, 240, 322, 240, 467, 467, 467, 467, + 467, 467, 467, 244, 776, 245, 246, 247, 1052, 264, + 903, 324, 1687, 467, 467, 467, 670, 467, 467, 683, + 251, 252, 491, 481, 671, 264, 907, 737, 254, 322, + + 255, 752, 752, 752, 752, 752, 752, 752, 352, 257, + 528, 240, 672, 264, 673, 558, 324, 674, 675, 158, + 676, 158, 674, 559, 674, 1391, 674, 159, 909, 159, + 352, 562, 1045, 158, 922, 922, 677, 678, 679, 563, + 560, 159, 471, 158, 161, 353, 161, 162, 367, 162, + 1057, 159, 158, 264, 158, 1104, 1104, 415, 161, 770, + 159, 162, 159, 888, 777, 626, 1288, 470, 161, 1289, + 680, 162, 674, 473, 264, 470, 415, 161, 778, 161, + 162, 345, 162, 474, 780, 474, 475, 683, 476, 477, + 477, 477, 477, 477, 477, 350, 473, 779, 1143, 158, + + 1180, 415, 871, 871, 345, 626, 474, 159, 474, 475, + 264, 476, 477, 477, 477, 477, 477, 477, 350, 683, + 158, 158, 158, 1687, 161, 322, 415, 162, 159, 159, + 159, 1603, 684, 782, 477, 477, 477, 477, 477, 477, + 477, 1000, 324, 158, 1144, 161, 161, 161, 162, 162, + 162, 159, 685, 1078, 415, 686, 781, 737, 626, 322, + 415, 1079, 687, 401, 626, 908, 402, 783, 161, 784, + 1182, 162, 617, 617, 688, 158, 324, 261, 785, 905, + 262, 263, 158, 159, 158, 262, 158, 262, 264, 262, + 159, 1005, 159, 905, 159, 1624, 158, 562, 158, 265, + + 266, 267, 322, 268, 159, 563, 159, 161, 1466, 161, + 162, 161, 162, 367, 162, 411, 788, 786, 689, 324, + 787, 161, 161, 161, 162, 162, 162, 1074, 1000, 789, + 967, 158, 367, 269, 905, 270, 562, 415, 261, 159, + 1473, 262, 263, 158, 563, 158, 262, 158, 262, 158, + 262, 159, 967, 159, 626, 159, 161, 159, 970, 162, + 265, 266, 267, 357, 268, 1010, 971, 967, 161, 1279, + 161, 162, 161, 162, 161, 162, 401, 162, 1005, 402, + 1279, 792, 158, 790, 158, 1687, 1687, 791, 690, 967, + 159, 322, 159, 642, 269, 970, 270, 753, 357, 554, + + 554, 554, 554, 554, 554, 554, 794, 161, 324, 161, + 162, 1081, 162, 528, 795, 1005, 644, 754, 357, 1082, + 755, 1090, 1090, 645, 415, 1075, 1484, 756, 411, 1146, + 1146, 161, 626, 793, 162, 646, 353, 1151, 1151, 757, + 352, 762, 352, 352, 352, 352, 352, 352, 352, 763, + 352, 764, 352, 764, 765, 352, 766, 767, 767, 767, + 767, 767, 767, 768, 352, 352, 352, 352, 352, 1279, + 352, 353, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 352, 352, + + 352, 352, 562, 1156, 1156, 158, 1687, 1179, 322, 470, + 563, 264, 771, 159, 771, 772, 905, 773, 774, 774, + 774, 774, 774, 774, 956, 324, 158, 161, 776, 963, + 161, 470, 957, 162, 159, 911, 1687, 964, 771, 761, + 771, 772, 1546, 773, 774, 774, 774, 774, 774, 774, + 812, 161, 812, 1687, 162, 813, 813, 813, 813, 813, + 813, 813, 619, 619, 619, 619, 619, 619, 619, 1165, + 1165, 1311, 796, 398, 1000, 399, 264, 1010, 400, 606, + 737, 264, 1578, 400, 471, 400, 607, 400, 395, 395, + 395, 395, 395, 395, 395, 1019, 927, 404, 405, 406, + + 619, 619, 619, 619, 619, 619, 619, 672, 905, 609, + 1003, 737, 815, 322, 815, 676, 610, 816, 816, 816, + 816, 816, 816, 816, 1005, 658, 1574, 1005, 611, 1390, + 324, 612, 861, 400, 398, 658, 399, 471, 1019, 400, + 606, 905, 1076, 1468, 400, 1024, 400, 659, 400, 605, + 605, 605, 605, 605, 605, 605, 215, 659, 404, 405, + 406, 639, 639, 639, 639, 639, 639, 639, 1007, 659, + 810, 639, 639, 639, 639, 639, 639, 639, 217, 659, + 1181, 641, 641, 641, 641, 641, 641, 641, 1024, 1189, + 264, 322, 612, 1190, 400, 398, 967, 399, 158, 481, + + 400, 606, 830, 905, 264, 400, 159, 400, 324, 400, + 641, 641, 641, 641, 641, 641, 641, 1562, 967, 404, + 405, 406, 528, 161, 970, 1077, 162, 832, 1467, 832, + 357, 644, 833, 833, 833, 833, 833, 833, 833, 835, + 1132, 835, 662, 1403, 836, 836, 836, 836, 836, 836, + 836, 264, 1183, 612, 905, 400, 398, 905, 399, 158, + 1561, 400, 401, 1467, 663, 402, 400, 159, 400, 1474, + 400, 620, 620, 620, 620, 620, 620, 620, 1185, 1186, + 404, 405, 406, 1560, 161, 1016, 663, 162, 620, 620, + 620, 620, 620, 620, 1010, 1010, 941, 1104, 1104, 818, + + 651, 651, 651, 651, 651, 651, 651, 651, 651, 651, + 651, 651, 651, 651, 411, 905, 400, 657, 657, 657, + 657, 657, 657, 657, 238, 239, 1187, 240, 241, 242, + 1150, 1013, 240, 1188, 240, 1623, 240, 657, 657, 657, + 657, 657, 657, 657, 1005, 1005, 245, 246, 247, 749, + 749, 749, 749, 749, 749, 749, 1207, 449, 683, 965, + 965, 905, 252, 1470, 1208, 1687, 528, 322, 965, 254, + 683, 255, 1486, 682, 682, 682, 682, 682, 682, 682, + 257, 965, 240, 839, 324, 682, 682, 682, 682, 682, + 682, 682, 1559, 840, 870, 840, 841, 662, 842, 843, + + 843, 843, 843, 843, 843, 845, 686, 910, 749, 749, + 749, 749, 749, 749, 749, 846, 415, 846, 847, 663, + 848, 849, 849, 849, 849, 849, 849, 851, 415, 528, + 753, 737, 905, 322, 1472, 666, 626, 852, 626, 852, + 853, 663, 854, 855, 855, 855, 855, 855, 855, 857, + 324, 238, 239, 755, 240, 241, 242, 667, 1019, 858, + 756, 858, 528, 240, 859, 860, 860, 860, 860, 860, + 860, 244, 757, 245, 246, 247, 905, 1687, 1026, 667, + 905, 467, 467, 467, 670, 467, 467, 1480, 251, 252, + 1385, 944, 671, 1197, 1155, 872, 254, 872, 255, 1687, + + 873, 873, 873, 873, 873, 873, 873, 257, 1024, 240, + 237, 1536, 238, 239, 946, 240, 241, 242, 1198, 1019, + 240, 947, 240, 905, 240, 752, 752, 752, 752, 752, + 752, 752, 244, 948, 245, 246, 247, 929, 929, 929, + 929, 929, 929, 929, 905, 249, 921, 905, 1279, 251, + 252, 528, 353, 1481, 1386, 1022, 918, 254, 918, 255, + 1543, 919, 919, 919, 919, 919, 919, 919, 257, 1024, + 240, 470, 862, 470, 470, 470, 470, 470, 470, 470, + 863, 470, 864, 470, 864, 865, 470, 866, 867, 867, + 867, 867, 867, 867, 868, 470, 470, 674, 470, 470, + + 1535, 470, 471, 869, 869, 869, 869, 869, 869, 869, + 869, 869, 869, 869, 869, 869, 869, 869, 869, 869, + 869, 869, 869, 869, 869, 869, 869, 869, 869, 470, + 470, 470, 470, 683, 752, 752, 752, 752, 752, 752, + 752, 905, 1090, 1090, 1213, 1213, 684, 1279, 477, 477, + 477, 477, 477, 477, 477, 755, 923, 353, 923, 353, + 1469, 924, 924, 924, 924, 924, 924, 924, 666, 686, + 1165, 1165, 1272, 1272, 1117, 765, 687, 928, 767, 767, + 767, 767, 767, 767, 1404, 471, 1199, 471, 688, 158, + 667, 261, 353, 737, 262, 263, 1117, 159, 528, 262, + + 1483, 262, 772, 262, 942, 774, 774, 774, 774, 774, + 774, 1200, 667, 265, 266, 267, 528, 268, 943, 943, + 943, 943, 943, 943, 943, 984, 905, 984, 1311, 875, + 985, 985, 985, 985, 985, 985, 985, 737, 158, 1119, + 1193, 1475, 528, 158, 1485, 158, 159, 269, 1194, 270, + 158, 159, 261, 159, 1195, 262, 263, 158, 159, 967, + 262, 1119, 262, 161, 262, 159, 162, 1122, 161, 158, + 161, 162, 1133, 162, 265, 266, 267, 159, 268, 357, + 1134, 967, 161, 1117, 158, 162, 528, 970, 956, 357, + 951, 1117, 159, 876, 161, 952, 957, 162, 813, 813, + + 813, 813, 813, 813, 813, 1482, 1311, 1279, 269, 161, + 270, 717, 162, 161, 905, 737, 162, 322, 1539, 718, + 953, 771, 264, 771, 772, 1245, 773, 774, 774, 774, + 774, 774, 774, 1245, 324, 954, 1687, 527, 527, 527, + 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, + 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, + 527, 527, 527, 527, 527, 527, 1279, 527, 528, 906, + 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, + 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, + 906, 906, 906, 906, 906, 527, 527, 527, 527, 352, + + 762, 352, 352, 352, 352, 352, 352, 352, 763, 352, + 764, 352, 764, 765, 352, 766, 767, 767, 767, 767, + 767, 767, 768, 352, 352, 352, 352, 352, 1534, 352, + 353, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 352, 352, 352, + 352, 930, 158, 767, 767, 767, 767, 767, 767, 767, + 159, 963, 966, 967, 1213, 1213, 905, 905, 353, 964, + 968, 931, 1544, 1000, 932, 1272, 1272, 161, 528, 353, + 162, 933, 1379, 1380, 357, 967, 161, 969, 1398, 162, + + 471, 970, 1245, 934, 352, 352, 352, 352, 352, 352, + 352, 352, 352, 352, 352, 935, 352, 935, 936, 352, + 937, 938, 938, 938, 938, 938, 938, 352, 352, 352, + 352, 352, 352, 1005, 352, 353, 939, 939, 939, 939, + 939, 939, 939, 939, 939, 939, 939, 939, 939, 939, + 939, 939, 939, 939, 939, 939, 939, 939, 939, 939, + 939, 939, 352, 352, 352, 352, 352, 352, 352, 352, + 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, + 352, 352, 940, 940, 940, 940, 940, 940, 940, 352, + 352, 352, 352, 352, 352, 557, 352, 353, 940, 940, + + 940, 940, 940, 940, 940, 940, 940, 940, 940, 940, + 940, 940, 940, 940, 940, 940, 940, 940, 940, 940, + 940, 940, 940, 940, 352, 352, 352, 940, 944, 158, + 774, 774, 774, 774, 774, 774, 774, 159, 158, 158, + 1000, 1010, 1083, 967, 158, 1019, 159, 159, 945, 528, + 1084, 946, 159, 158, 161, 1146, 1146, 162, 947, 1399, + 158, 159, 927, 161, 161, 967, 162, 162, 159, 161, + 948, 970, 162, 971, 967, 158, 158, 905, 161, 955, + 528, 162, 959, 159, 159, 161, 1245, 960, 162, 958, + 1005, 1005, 528, 367, 1478, 1024, 967, 1491, 1480, 158, + + 161, 161, 970, 162, 162, 1197, 961, 159, 1245, 962, + 813, 813, 813, 813, 813, 813, 813, 816, 816, 816, + 816, 816, 816, 816, 161, 972, 398, 162, 399, 158, + 1198, 400, 606, 1514, 905, 905, 400, 159, 400, 1102, + 400, 811, 811, 833, 833, 833, 833, 833, 833, 833, + 404, 405, 406, 994, 161, 994, 1537, 162, 995, 995, + 995, 995, 995, 995, 995, 833, 833, 833, 833, 833, + 833, 833, 836, 836, 836, 836, 836, 836, 836, 357, + 528, 1687, 761, 322, 612, 905, 400, 398, 1119, 399, + 158, 1467, 400, 606, 528, 1479, 1501, 400, 159, 400, + + 324, 400, 814, 814, 814, 814, 814, 814, 814, 1487, + 1119, 404, 405, 406, 528, 161, 1122, 1202, 162, 814, + 814, 814, 814, 814, 814, 1496, 357, 1123, 1119, 1488, + 986, 836, 836, 836, 836, 836, 836, 836, 999, 999, + 999, 999, 999, 999, 999, 612, 1497, 400, 401, 528, + 1119, 402, 528, 1550, 1498, 905, 1122, 816, 816, 816, + 816, 816, 816, 816, 841, 1541, 998, 843, 843, 843, + 843, 843, 843, 847, 1548, 1008, 849, 849, 849, 849, + 849, 849, 1009, 1009, 1009, 1009, 1009, 1009, 1009, 853, + 1563, 1017, 855, 855, 855, 855, 855, 855, 1564, 528, + + 411, 839, 1018, 1018, 1018, 1018, 1018, 1018, 1018, 967, + 528, 840, 1554, 840, 841, 1555, 842, 843, 843, 843, + 843, 843, 843, 1000, 459, 460, 460, 460, 460, 460, + 460, 967, 971, 967, 971, 967, 1001, 970, 843, 843, + 843, 843, 843, 843, 843, 865, 158, 1030, 867, 867, + 867, 867, 867, 867, 159, 967, 1002, 967, 904, 1003, + 904, 970, 471, 970, 1118, 1119, 1004, 905, 904, 1467, + 904, 161, 1120, 1005, 162, 1043, 1000, 1043, 1006, 1000, + 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1119, 528, 1121, + 1480, 1279, 1001, 1122, 843, 843, 843, 843, 843, 843, + + 843, 1031, 1031, 1031, 1031, 1031, 1031, 1031, 873, 873, + 873, 873, 873, 873, 873, 1003, 471, 683, 905, 1257, + 905, 528, 1004, 1465, 905, 1590, 1005, 1480, 1476, 1005, + 845, 1477, 873, 873, 873, 873, 873, 873, 873, 1538, + 846, 1010, 846, 847, 528, 848, 849, 849, 849, 849, + 849, 849, 1010, 919, 919, 919, 919, 919, 919, 919, + 1392, 1393, 1687, 1279, 322, 1011, 905, 849, 849, 849, + 849, 849, 849, 849, 919, 919, 919, 919, 919, 919, + 919, 324, 905, 905, 1260, 1012, 905, 1467, 1013, 1203, + 1279, 1005, 1133, 966, 967, 1014, 1381, 1540, 1542, 528, + + 1134, 968, 1005, 1382, 1086, 1019, 1086, 1015, 1010, 1087, + 1087, 1087, 1087, 1087, 1087, 1087, 967, 161, 969, 1626, + 162, 1011, 970, 849, 849, 849, 849, 849, 849, 849, + 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, + 924, 924, 924, 924, 1013, 158, 905, 528, 1263, 905, + 905, 1014, 1467, 159, 1592, 1024, 1547, 1552, 1005, 851, + 158, 943, 943, 943, 943, 943, 943, 943, 159, 852, + 161, 852, 853, 162, 854, 855, 855, 855, 855, 855, + 855, 1019, 1103, 528, 1279, 161, 1199, 528, 162, 1123, + 1119, 1027, 1115, 1558, 1020, 1110, 855, 855, 855, 855, + + 855, 855, 855, 1627, 929, 929, 929, 929, 929, 929, + 929, 1200, 1119, 1028, 1021, 905, 528, 1022, 1122, 353, + 905, 158, 905, 905, 1023, 1089, 451, 1594, 1589, 159, + 251, 1024, 1687, 1591, 322, 663, 1025, 1019, 943, 943, + 943, 943, 943, 943, 943, 1622, 161, 971, 967, 162, + 1020, 324, 855, 855, 855, 855, 855, 855, 855, 946, + 929, 929, 929, 929, 929, 929, 929, 1111, 528, 1464, + 967, 158, 905, 1022, 1201, 353, 970, 1467, 1394, 159, + 1023, 932, 905, 1463, 1105, 1395, 1105, 1024, 857, 1106, + 1106, 1106, 1106, 1106, 1106, 1106, 161, 1545, 458, 162, + + 458, 528, 1462, 459, 460, 460, 460, 460, 460, 460, + 244, 1112, 936, 905, 1094, 938, 938, 938, 938, 938, + 938, 1595, 1480, 451, 905, 1461, 528, 251, 1027, 353, + 238, 239, 1460, 240, 241, 242, 1489, 1383, 240, 1490, + 240, 1384, 240, 860, 860, 860, 860, 860, 860, 860, + 1028, 1247, 245, 246, 247, 1123, 1119, 528, 1205, 1119, + 467, 467, 467, 670, 467, 467, 1206, 251, 252, 1459, + 1396, 1029, 663, 1247, 1397, 254, 905, 255, 1119, 1250, + 528, 1119, 1467, 665, 1122, 1597, 257, 1122, 240, 470, + 862, 470, 470, 470, 470, 470, 470, 470, 863, 470, + + 864, 470, 864, 865, 470, 866, 867, 867, 867, 867, + 867, 867, 868, 470, 470, 470, 470, 470, 1458, 470, + 471, 869, 869, 869, 869, 869, 869, 869, 869, 869, + 869, 869, 869, 869, 869, 869, 869, 869, 869, 869, + 869, 869, 869, 869, 869, 869, 869, 470, 470, 470, + 470, 1032, 528, 867, 867, 867, 867, 867, 867, 867, + 1095, 1095, 1095, 1095, 1095, 1095, 1095, 527, 471, 527, + 528, 1033, 905, 528, 1034, 353, 528, 527, 1557, 527, + 471, 1035, 985, 985, 985, 985, 985, 985, 985, 1593, + 1600, 1549, 1625, 1036, 470, 470, 470, 470, 470, 470, + + 470, 470, 470, 470, 470, 1037, 470, 1037, 1038, 470, + 1039, 1040, 1040, 1040, 1040, 1040, 1040, 470, 470, 470, + 470, 470, 470, 761, 470, 471, 1041, 1041, 1041, 1041, + 1041, 1041, 1041, 1041, 1041, 1041, 1041, 1041, 1041, 1041, + 1041, 1041, 1041, 1041, 1041, 1041, 1041, 1041, 1041, 1041, + 1041, 1041, 470, 470, 470, 470, 470, 470, 470, 470, + 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, + 470, 470, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 470, + 470, 470, 470, 470, 470, 557, 470, 471, 1042, 1042, + 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, + + 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, + 1042, 1042, 1042, 1042, 470, 470, 470, 1042, 158, 528, + 261, 528, 528, 262, 263, 158, 159, 528, 262, 158, + 262, 158, 262, 159, 1551, 1596, 1553, 159, 1432, 159, + 1598, 905, 265, 266, 267, 528, 268, 1063, 1064, 1065, + 161, 1066, 1067, 162, 161, 1046, 161, 162, 1068, 162, + 1556, 1467, 1069, 1070, 1404, 1114, 995, 995, 995, 995, + 995, 995, 995, 737, 357, 322, 269, 1117, 270, 158, + 353, 261, 1116, 528, 262, 263, 1010, 159, 1599, 262, + 737, 262, 324, 262, 995, 995, 995, 995, 995, 995, + + 995, 1151, 1151, 265, 266, 267, 1147, 268, 1147, 1123, + 1119, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1152, 967, + 1152, 1666, 1565, 1153, 1153, 1153, 1153, 1153, 1153, 1153, + 1019, 1047, 1119, 1336, 1336, 1410, 1005, 269, 1122, 270, + 1061, 967, 1062, 528, 1565, 1156, 1156, 970, 1601, 1157, + 1062, 1157, 1062, 1119, 1158, 1158, 1158, 1158, 1158, 1158, + 1158, 1377, 528, 1031, 1031, 1031, 1031, 1031, 1031, 1031, + 1602, 905, 1063, 1064, 1065, 1119, 1066, 1067, 471, 528, + 1024, 1122, 1376, 1068, 1164, 1480, 1467, 1069, 1070, 527, + 527, 527, 527, 527, 527, 527, 527, 527, 527, 1072, + + 527, 527, 527, 527, 527, 1073, 1073, 1073, 1073, 1073, + 1073, 1073, 527, 527, 527, 527, 527, 527, 732, 527, + 528, 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, + 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, + 1073, 1073, 1073, 1073, 1073, 1073, 1073, 527, 527, 527, + 1073, 930, 158, 767, 767, 767, 767, 767, 767, 767, + 159, 1031, 1031, 1031, 1031, 1031, 1031, 1031, 353, 1119, + 528, 905, 905, 1467, 932, 1480, 471, 161, 1467, 1375, + 162, 933, 1034, 1170, 1170, 1170, 1170, 1170, 1170, 1170, + 905, 1119, 1467, 934, 1091, 1374, 1091, 1122, 471, 1092, + + 1092, 1092, 1092, 1092, 1092, 1092, 1044, 1044, 1044, 1044, + 1044, 1044, 1044, 1230, 353, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1087, 1087, 1087, 1087, 1087, 1087, 1087, 1279, + 353, 158, 1093, 1093, 1093, 1093, 1093, 1093, 1096, 159, + 938, 938, 938, 938, 938, 938, 938, 1087, 1087, 1087, + 1087, 1087, 1087, 1087, 683, 353, 161, 528, 1097, 162, + 528, 1098, 1480, 1480, 528, 1373, 1480, 1217, 1099, 1044, + 1044, 1044, 1044, 1044, 1044, 1044, 528, 1372, 1480, 1371, + 1100, 352, 352, 352, 352, 352, 352, 352, 352, 352, + 352, 352, 352, 352, 352, 352, 352, 1101, 1101, 1101, + + 1101, 1101, 1101, 1101, 352, 352, 352, 352, 352, 352, + 759, 352, 353, 1101, 1101, 1101, 1101, 1101, 1101, 1101, + 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, + 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 352, + 352, 352, 1101, 352, 352, 352, 352, 352, 352, 352, + 352, 352, 352, 352, 352, 352, 352, 352, 352, 940, + 940, 940, 940, 940, 940, 940, 352, 352, 352, 352, + 352, 352, 557, 352, 353, 940, 940, 940, 940, 940, + 940, 940, 940, 940, 940, 940, 940, 940, 940, 940, + 940, 940, 940, 940, 940, 940, 940, 940, 940, 940, + + 940, 352, 352, 352, 940, 956, 1083, 967, 158, 1251, + 1247, 1205, 1119, 957, 1084, 771, 159, 771, 772, 1206, + 773, 774, 774, 774, 774, 774, 774, 1370, 1369, 967, + 161, 1113, 1247, 161, 1119, 970, 162, 1565, 1250, 1687, + 1122, 771, 367, 771, 772, 1565, 773, 774, 774, 774, + 774, 774, 774, 1368, 1367, 1366, 1687, 965, 1124, 967, + 965, 965, 965, 965, 965, 965, 1125, 965, 1126, 965, + 1126, 1127, 965, 1128, 1129, 1129, 1129, 1129, 1129, 1129, + 1130, 967, 965, 965, 965, 965, 965, 970, 965, 1131, + 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, + + 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, + 1131, 1131, 1131, 1131, 1131, 965, 965, 965, 965, 398, + 905, 399, 528, 1404, 400, 606, 1467, 491, 1405, 400, + 1365, 400, 737, 400, 985, 985, 985, 985, 985, 985, + 985, 471, 1480, 404, 405, 406, 1038, 1350, 1169, 1040, + 1040, 1040, 1040, 1040, 1040, 1092, 1092, 1092, 1092, 1092, + 1092, 1092, 1492, 471, 1118, 1119, 528, 528, 1493, 1350, + 353, 1494, 1120, 1480, 965, 1351, 1352, 612, 1495, 400, + 398, 1480, 399, 1687, 798, 400, 606, 1119, 798, 1121, + 400, 798, 400, 1122, 400, 1092, 1092, 1092, 1092, 1092, + + 1092, 1092, 1123, 1119, 404, 405, 406, 1251, 1247, 965, + 353, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, + 1095, 1095, 1095, 1095, 1095, 1119, 353, 905, 1319, 1387, + 1247, 1122, 1212, 353, 353, 1314, 1250, 1388, 612, 1098, + 400, 1000, 1218, 1389, 1218, 1290, 1279, 1219, 1219, 1219, + 1219, 1219, 1219, 1219, 1001, 1287, 843, 843, 843, 843, + 843, 843, 843, 1106, 1106, 1106, 1106, 1106, 1106, 1106, + 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1003, 158, 158, + 158, 1286, 1285, 528, 1004, 1400, 159, 159, 159, 1284, + 1283, 1005, 1282, 1401, 158, 1281, 1006, 1010, 1280, 1402, + + 1279, 158, 159, 161, 161, 161, 162, 162, 162, 159, + 1011, 1278, 849, 849, 849, 849, 849, 849, 849, 161, + 1251, 1247, 162, 367, 1277, 1320, 161, 367, 367, 162, + 158, 1246, 1247, 1013, 1315, 1247, 1497, 1687, 159, 1248, + 1014, 1221, 1316, 1247, 1498, 341, 1687, 1005, 322, 1250, + 341, 341, 1015, 1019, 1247, 161, 1249, 1247, 162, 491, + 1250, 161, 491, 1250, 162, 324, 1020, 1687, 855, 855, + 855, 855, 855, 855, 855, 1255, 1687, 1255, 322, 367, + 1256, 1256, 1256, 1256, 1256, 1256, 1256, 438, 1312, 1022, + 1687, 491, 438, 438, 491, 324, 1023, 471, 1254, 1687, + + 467, 322, 1313, 1024, 798, 467, 467, 1253, 1025, 1160, + 1148, 1148, 1148, 1148, 1148, 1148, 1148, 798, 324, 1161, + 798, 1161, 847, 798, 1162, 1163, 1163, 1163, 1163, 1163, + 1163, 1027, 1252, 238, 239, 328, 240, 241, 242, 1109, + 1109, 240, 1220, 240, 353, 240, 1153, 1153, 1153, 1153, + 1153, 1153, 1153, 1028, 1204, 245, 246, 247, 1158, 1158, + 1158, 1158, 1158, 1158, 1158, 1196, 249, 1000, 620, 1192, + 251, 252, 1191, 620, 620, 663, 1184, 514, 254, 514, + 255, 514, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 257, + 264, 240, 1032, 1178, 867, 867, 867, 867, 867, 867, + + 867, 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1247, 471, + 1251, 1247, 683, 471, 655, 1034, 471, 1005, 1258, 798, + 1258, 1141, 1035, 1259, 1259, 1259, 1259, 1259, 1259, 1259, + 1247, 798, 798, 1247, 1036, 1166, 1250, 1166, 798, 1250, + 1167, 1167, 1167, 1167, 1167, 1167, 1167, 1140, 1010, 1139, + 1138, 1137, 1361, 1136, 1135, 471, 1168, 1168, 1168, 1168, + 1168, 1168, 1168, 1153, 1153, 1153, 1153, 1153, 1153, 1153, + 1109, 471, 158, 1168, 1168, 1168, 1168, 1168, 1168, 1171, + 159, 1040, 1040, 1040, 1040, 1040, 1040, 1040, 1167, 1167, + 1167, 1167, 1167, 1167, 1167, 950, 471, 161, 1005, 1172, + + 162, 353, 1173, 471, 927, 1261, 927, 1261, 1088, 1174, + 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1411, 1085, 1080, + 905, 1175, 470, 470, 470, 470, 470, 470, 470, 470, + 470, 470, 470, 470, 470, 470, 470, 470, 1176, 1176, + 1176, 1176, 1176, 1176, 1176, 470, 470, 470, 470, 470, + 470, 759, 470, 471, 1176, 1176, 1176, 1176, 1176, 1176, + 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, + 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, + 470, 470, 470, 1176, 470, 470, 470, 470, 470, 470, + 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, + + 1042, 1042, 1042, 1042, 1042, 1042, 1042, 470, 470, 470, + 470, 470, 470, 557, 470, 471, 1042, 1042, 1042, 1042, + 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, + 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, + 1042, 1042, 470, 470, 470, 1042, 158, 1019, 261, 1060, + 514, 262, 263, 1059, 159, 514, 262, 514, 262, 514, + 262, 1265, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1058, + 265, 266, 267, 847, 268, 1264, 1163, 1163, 1163, 1163, + 1163, 1163, 510, 659, 1687, 996, 1177, 1170, 1170, 1170, + 1170, 1170, 1170, 1170, 652, 983, 982, 1024, 981, 652, + + 652, 980, 471, 798, 269, 659, 270, 158, 1271, 261, + 979, 1005, 262, 263, 1265, 159, 978, 262, 977, 262, + 976, 262, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 975, + 974, 265, 266, 267, 967, 268, 659, 471, 1119, 973, + 1251, 1247, 950, 1173, 1210, 1210, 1210, 1210, 1210, 1210, + 1210, 761, 1413, 1413, 761, 927, 967, 481, 659, 353, + 1119, 759, 970, 1247, 1005, 269, 1122, 270, 1061, 1250, + 1062, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1062, 920, + 1062, 917, 914, 913, 912, 1427, 353, 905, 1215, 1215, + 1215, 1215, 1215, 1215, 1215, 514, 901, 514, 514, 514, + + 1063, 1064, 1065, 353, 1066, 1067, 900, 1427, 899, 898, + 897, 1068, 1117, 1428, 1429, 1069, 1070, 527, 527, 527, + 527, 527, 527, 527, 527, 527, 527, 1072, 527, 527, + 527, 527, 527, 1073, 1073, 1073, 1073, 1073, 1073, 1073, + 527, 527, 527, 527, 527, 527, 732, 527, 528, 1073, + 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, + 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, + 1073, 1073, 1073, 1073, 1073, 527, 527, 527, 1073, 1078, + 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1079, 896, 771, + 895, 771, 772, 264, 773, 774, 774, 774, 774, 774, + + 774, 1113, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1687, + 878, 771, 683, 771, 772, 683, 773, 774, 774, 774, + 774, 774, 774, 1209, 471, 1209, 471, 655, 1210, 1210, + 1210, 1210, 1210, 1210, 1210, 837, 1215, 1215, 1215, 1215, + 1215, 1215, 1215, 353, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 353, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 353, + 1439, 1093, 1093, 1093, 1093, 1093, 1093, 415, 624, 624, + 1247, 967, 1211, 1096, 622, 938, 938, 938, 938, 938, + 938, 938, 1439, 1246, 1247, 1336, 1336, 965, 1440, 1441, + 353, 1248, 1247, 967, 622, 716, 1098, 817, 1250, 970, + + 716, 716, 817, 1099, 750, 400, 1247, 609, 1249, 750, + 750, 400, 1250, 809, 814, 1100, 1214, 798, 1214, 814, + 814, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1259, 1259, + 1259, 1259, 1259, 1259, 1259, 806, 353, 1216, 1216, 1216, + 1216, 1216, 1216, 1216, 1262, 1262, 1262, 1262, 1262, 1262, + 1262, 805, 353, 804, 1216, 1216, 1216, 1216, 1216, 1216, + 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, + 352, 352, 352, 352, 352, 352, 1101, 1101, 1101, 1101, + 1101, 1101, 1101, 352, 352, 352, 352, 352, 352, 759, + 352, 353, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, + + 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, + 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 352, 352, + 352, 1101, 1117, 1222, 1119, 1117, 1117, 1117, 1117, 1117, + 1117, 1223, 1117, 1224, 1117, 1224, 1225, 1117, 1226, 1227, + 1227, 1227, 1227, 1227, 1227, 1228, 1119, 1117, 1117, 1117, + 1117, 1117, 1122, 1117, 1229, 1229, 1229, 1229, 1229, 1229, + 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, + 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, + 1117, 1117, 1117, 1117, 965, 1124, 967, 965, 965, 965, + 965, 965, 965, 1125, 965, 1126, 965, 1126, 1127, 965, + + 1128, 1129, 1129, 1129, 1129, 1129, 1129, 1130, 967, 965, + 965, 965, 965, 965, 970, 965, 1131, 1131, 1131, 1131, + 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, + 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, + 1131, 1131, 965, 965, 965, 965, 967, 1315, 1247, 803, + 1350, 834, 802, 801, 800, 1316, 834, 834, 1127, 799, + 1231, 1129, 1129, 1129, 1129, 1129, 1129, 1000, 967, 798, + 1247, 797, 1350, 353, 970, 967, 1250, 965, 1351, 1352, + 1119, 761, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1232, + 1232, 1232, 1232, 1232, 1232, 1232, 557, 967, 759, 745, + + 1405, 744, 1119, 970, 967, 743, 742, 967, 1122, 1687, + 528, 322, 512, 512, 510, 264, 1233, 1005, 1129, 1129, + 1129, 1129, 1129, 1129, 1129, 1350, 967, 967, 324, 967, + 471, 469, 970, 469, 1406, 970, 1234, 1687, 1687, 1235, + 1407, 1434, 1434, 1408, 1687, 624, 1236, 1350, 415, 967, + 1409, 838, 965, 1351, 1352, 970, 838, 838, 1237, 965, + 965, 967, 965, 965, 965, 965, 965, 965, 965, 965, + 1238, 965, 1238, 1239, 965, 1240, 1241, 1241, 1241, 1241, + 1241, 1241, 965, 967, 965, 965, 965, 965, 965, 970, + 965, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, + + 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, + 1242, 1242, 1242, 1242, 1242, 1242, 1242, 965, 965, 965, + 965, 965, 965, 967, 965, 965, 965, 965, 965, 965, + 965, 965, 965, 965, 965, 965, 965, 1243, 1243, 1243, + 1243, 1243, 1243, 1243, 965, 967, 965, 965, 965, 965, + 1244, 970, 965, 1243, 1243, 1243, 1243, 1243, 1243, 1243, + 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, + 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 1243, 965, + 965, 965, 1243, 1160, 844, 622, 413, 614, 400, 844, + 844, 408, 1010, 1161, 614, 1161, 847, 400, 1162, 1163, + + 1163, 1163, 1163, 1163, 1163, 1265, 603, 1259, 1259, 1259, + 1259, 1259, 1259, 1259, 1019, 1265, 599, 1508, 1011, 598, + 1163, 1163, 1163, 1163, 1163, 1163, 1163, 659, 1247, 1262, + 1262, 1262, 1262, 1262, 1262, 1262, 591, 659, 1012, 1508, + 353, 1013, 1005, 557, 1117, 1509, 1510, 850, 1266, 659, + 1247, 1687, 850, 850, 343, 1005, 1250, 343, 1457, 659, + 1267, 1268, 543, 1268, 1024, 1005, 1269, 1269, 1269, 1269, + 1269, 1269, 1269, 540, 1269, 1269, 1269, 1269, 1269, 1269, + 1269, 471, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 471, + 1269, 1269, 1269, 1269, 1269, 1269, 1269, 471, 539, 1168, + + 1168, 1168, 1168, 1168, 1168, 471, 538, 537, 1265, 1119, + 1270, 1171, 536, 1040, 1040, 1040, 1040, 1040, 1040, 1040, + 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1687, 471, 528, + 659, 1119, 525, 514, 1173, 471, 1687, 1122, 322, 522, + 521, 1174, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 520, + 519, 518, 659, 1175, 1273, 324, 1273, 471, 1005, 1274, + 1274, 1274, 1274, 1274, 1274, 1274, 325, 1318, 1318, 1318, + 1318, 1318, 1318, 1318, 471, 1275, 1275, 1275, 1275, 1275, + 1275, 1275, 353, 856, 517, 516, 515, 514, 856, 856, + 471, 513, 1275, 1275, 1275, 1275, 1275, 1275, 470, 470, + + 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, + 470, 470, 470, 470, 1176, 1176, 1176, 1176, 1176, 1176, + 1176, 470, 470, 470, 470, 470, 470, 759, 470, 471, + 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, + 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, + 1176, 1176, 1176, 1176, 1176, 1176, 470, 470, 470, 1176, + 158, 512, 261, 307, 507, 262, 263, 967, 159, 1247, + 262, 1350, 262, 506, 262, 1318, 1318, 1318, 1318, 1318, + 1318, 1318, 505, 1687, 265, 266, 267, 504, 268, 967, + 353, 1247, 1687, 1350, 322, 970, 1276, 1250, 965, 1351, + + 1352, 1364, 1364, 1364, 1364, 1364, 1364, 1364, 874, 503, + 502, 324, 481, 874, 874, 1442, 471, 499, 269, 925, + 270, 158, 330, 261, 925, 925, 262, 263, 1427, 159, + 498, 262, 497, 262, 496, 262, 1364, 1364, 1364, 1364, + 1364, 1364, 1364, 1687, 1119, 265, 266, 267, 1119, 268, + 1427, 471, 1687, 495, 322, 1117, 1428, 1429, 1413, 1413, + 494, 493, 1503, 1503, 1571, 1567, 1119, 492, 490, 1427, + 1119, 324, 1122, 1427, 489, 488, 1122, 1567, 487, 269, + 1107, 270, 1291, 486, 1292, 1107, 1107, 1567, 485, 329, + 484, 1427, 1292, 1570, 1292, 1427, 1117, 1428, 1429, 1567, + + 1117, 1428, 1429, 1149, 483, 1570, 967, 482, 1149, 1149, + 1439, 481, 905, 1511, 1293, 1294, 1295, 480, 1296, 1297, + 1434, 1434, 1439, 1571, 1567, 1298, 1439, 479, 967, 1299, + 1300, 1301, 1439, 1302, 970, 478, 262, 965, 1440, 1441, + 471, 1302, 262, 1302, 1439, 262, 1567, 1119, 1439, 965, + 1440, 1441, 1570, 965, 1440, 1441, 469, 259, 240, 240, + 250, 528, 240, 1303, 1304, 1305, 1515, 1306, 1307, 1119, + 1350, 1154, 240, 1687, 1308, 1122, 1154, 1154, 1309, 1310, + 1317, 1247, 1317, 1531, 1687, 1318, 1318, 1318, 1318, 1318, + 1318, 1318, 1350, 415, 413, 1517, 1517, 965, 1351, 1352, + + 353, 1119, 1159, 1247, 353, 1531, 1508, 1159, 1159, 1250, + 1245, 1532, 1533, 1225, 1508, 1321, 1227, 1227, 1227, 1227, + 1227, 1227, 343, 1119, 156, 336, 335, 334, 1508, 1122, + 1119, 1566, 1567, 1117, 1509, 1510, 1508, 332, 1687, 1568, + 131, 1117, 1509, 1510, 1322, 1322, 1322, 1322, 1322, 1322, + 1322, 131, 1119, 321, 1567, 317, 1569, 1362, 1122, 1119, + 1570, 316, 1362, 1362, 309, 120, 1571, 1567, 1119, 308, + 1427, 1323, 307, 1227, 1227, 1227, 1227, 1227, 1227, 1227, + 1439, 1119, 1503, 1503, 1247, 230, 260, 1122, 259, 1567, + 1119, 1324, 1427, 230, 1325, 1570, 1122, 1117, 1428, 1429, + + 230, 1326, 1439, 210, 227, 210, 1247, 965, 1440, 1441, + 210, 121, 1250, 1327, 1117, 1117, 1119, 1117, 1117, 1117, + 1117, 1117, 1117, 1117, 1117, 1328, 1117, 1328, 1329, 1117, + 1330, 1331, 1331, 1331, 1331, 1331, 1331, 1117, 1119, 1117, + 1117, 1117, 1117, 1117, 1122, 1117, 1332, 1332, 1332, 1332, + 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, + 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, + 1332, 1332, 1117, 1117, 1117, 1117, 1117, 1117, 1119, 1117, + 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, + 1117, 1117, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1117, + + 1119, 1117, 1117, 1117, 1117, 1334, 1122, 1117, 1333, 1333, + 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, + 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, 1333, + 1333, 1333, 1333, 1333, 1117, 1117, 1117, 1333, 967, 157, + 1508, 156, 121, 131, 121, 131, 120, 1571, 1567, 1247, + 1567, 1687, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1567, + 967, 1687, 1508, 1517, 1517, 1687, 970, 1117, 1509, 1510, + 1567, 1247, 1567, 1335, 967, 1687, 1570, 1250, 1570, 1585, + 1687, 1567, 1687, 1247, 1575, 1687, 1687, 1570, 1232, 1232, + 1232, 1232, 1232, 1232, 1232, 1247, 967, 1580, 1580, 1687, + + 1687, 1585, 970, 1617, 1687, 1247, 1245, 1586, 1587, 1235, + 967, 1250, 1687, 1531, 1571, 1567, 1687, 1247, 1687, 1337, + 1687, 1337, 1531, 1250, 1338, 1338, 1338, 1338, 1338, 1338, + 1338, 1687, 967, 1687, 1687, 1531, 1687, 1567, 970, 967, + 1245, 1532, 1533, 1570, 1531, 1687, 1687, 1687, 1687, 1245, + 1532, 1533, 1687, 1339, 1339, 1339, 1339, 1339, 1339, 1339, + 1687, 967, 1687, 1687, 1687, 1687, 1588, 970, 1687, 1687, + 1339, 1339, 1339, 1339, 1339, 1339, 967, 1687, 1687, 1531, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1508, 1239, 1567, + 1340, 1241, 1241, 1241, 1241, 1241, 1241, 1687, 967, 1687, + + 1687, 1531, 1687, 1687, 970, 967, 1245, 1532, 1533, 1508, + 1687, 1567, 1687, 1687, 1117, 1509, 1510, 1570, 1687, 1341, + 1341, 1341, 1341, 1341, 1341, 1341, 1687, 967, 1567, 1687, + 1567, 1687, 1687, 970, 1342, 1687, 1241, 1241, 1241, 1241, + 1241, 1241, 1241, 1607, 1567, 1566, 1567, 1247, 1687, 1687, + 1567, 1608, 1567, 1568, 1343, 1687, 1570, 1344, 1570, 1687, + 1687, 1580, 1580, 1687, 1345, 1585, 1567, 1687, 1567, 1247, + 1569, 1687, 1570, 1567, 1570, 1250, 1346, 1342, 1687, 1241, + 1241, 1241, 1241, 1241, 1241, 1241, 1585, 1585, 1687, 1531, + 1687, 1687, 1245, 1586, 1587, 1567, 1687, 965, 1687, 1687, + + 1344, 1570, 1687, 1687, 1687, 1687, 1687, 1345, 1585, 1687, + 1687, 1531, 1687, 1245, 1586, 1587, 1245, 1532, 1533, 965, + 965, 965, 967, 965, 965, 965, 965, 965, 965, 965, + 965, 965, 965, 965, 965, 965, 1347, 1347, 1347, 1347, + 1347, 1347, 1347, 965, 967, 965, 965, 965, 965, 1348, + 970, 965, 1347, 1347, 1347, 1347, 1347, 1347, 1347, 1347, + 1347, 1347, 1347, 1347, 1347, 1347, 1347, 1347, 1347, 1347, + 1347, 1347, 1347, 1347, 1347, 1347, 1347, 1347, 965, 965, + 965, 1347, 1245, 1353, 1247, 1245, 1245, 1245, 1245, 1245, + 1245, 1354, 1245, 1355, 1245, 1355, 1356, 1245, 1357, 1358, + + 1358, 1358, 1358, 1358, 1358, 1359, 1247, 1245, 1245, 1245, + 1245, 1245, 1250, 1245, 1360, 1360, 1360, 1360, 1360, 1360, + 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, + 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, + 1245, 1245, 1245, 1245, 1363, 1585, 1363, 1687, 1687, 1364, + 1364, 1364, 1364, 1364, 1364, 1364, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 471, 1119, 1687, 1585, 1607, 1567, + 1687, 1687, 1245, 1586, 1587, 1687, 1608, 1585, 1687, 1322, + 1322, 1322, 1322, 1322, 1322, 1322, 1687, 1119, 1687, 1621, + 1687, 1567, 1687, 1122, 1687, 1687, 1687, 1570, 1687, 1585, + + 1412, 1119, 1687, 1687, 1245, 1586, 1587, 1687, 1687, 1687, + 1567, 1687, 1662, 1687, 1687, 1322, 1322, 1322, 1322, 1322, + 1322, 1322, 1687, 1119, 1648, 1648, 1687, 1687, 1687, 1122, + 1687, 1687, 1567, 1687, 1662, 1687, 1325, 1119, 1570, 1565, + 1663, 1664, 1687, 1687, 1687, 1676, 1414, 1567, 1414, 1567, + 1687, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1687, 1119, + 1687, 1648, 1648, 1671, 1671, 1122, 1119, 1676, 1687, 1567, + 1687, 1567, 1565, 1677, 1678, 1570, 1687, 1570, 1687, 1687, + 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1687, 1119, 1687, + 1687, 1687, 1687, 1687, 1122, 1687, 1687, 1416, 1416, 1416, + + 1416, 1416, 1416, 1119, 1687, 1687, 1662, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1662, 1329, 1687, 1417, 1331, 1331, + 1331, 1331, 1331, 1331, 1687, 1119, 1687, 1687, 1662, 1687, + 1687, 1122, 1119, 1565, 1663, 1664, 1662, 1687, 1687, 1687, + 1687, 1565, 1663, 1664, 1687, 1687, 1418, 1418, 1418, 1418, + 1418, 1418, 1418, 1687, 1119, 1687, 1687, 1567, 1679, 1687, + 1122, 1419, 1687, 1331, 1331, 1331, 1331, 1331, 1331, 1331, + 1662, 1671, 1671, 1676, 1687, 1687, 1687, 1687, 1687, 1567, + 1687, 1420, 1687, 1687, 1421, 1570, 1687, 1687, 1687, 1687, + 1687, 1422, 1662, 1676, 1687, 1676, 1687, 1565, 1663, 1664, + + 1565, 1677, 1678, 1423, 1419, 1687, 1331, 1331, 1331, 1331, + 1331, 1331, 1331, 1676, 1687, 1676, 1662, 1687, 1687, 1687, + 1565, 1677, 1678, 1687, 1117, 1687, 1687, 1421, 1687, 1687, + 1687, 1687, 1687, 1687, 1422, 1676, 1687, 1685, 1662, 1687, + 1565, 1677, 1678, 1565, 1663, 1664, 1117, 1117, 1117, 1119, + 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, + 1117, 1117, 1117, 1424, 1424, 1424, 1424, 1424, 1424, 1424, + 1117, 1119, 1117, 1117, 1117, 1117, 1425, 1122, 1117, 1424, + 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, + 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, + + 1424, 1424, 1424, 1424, 1424, 1117, 1117, 1117, 1424, 967, + 1687, 1687, 1676, 1687, 1687, 1687, 1687, 1687, 1430, 1687, + 1430, 1687, 1687, 1431, 1431, 1431, 1431, 1431, 1431, 1431, + 1687, 967, 1687, 1687, 1676, 1687, 1687, 970, 967, 1565, + 1677, 1678, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1687, + 967, 1687, 1687, 1687, 1687, 1687, 970, 967, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1687, 967, + 1687, 1687, 1687, 1687, 1687, 970, 1342, 1687, 1241, 1241, + + 1241, 1241, 1241, 1241, 1241, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 965, 1687, 1687, 1344, + 1687, 1687, 1687, 1687, 1687, 1687, 1345, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1346, 967, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1341, 1341, 1341, 1341, 1341, 1341, 1341, + 1687, 967, 1687, 1687, 1687, 1687, 1687, 970, 1687, 1687, + 1687, 1687, 1687, 1687, 1433, 967, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1341, + 1341, 1341, 1341, 1341, 1341, 1341, 1687, 967, 1687, 1687, + + 1687, 1687, 1687, 970, 1687, 1687, 1687, 1687, 1687, 1687, + 1344, 967, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1435, 1687, 1435, 1687, 1687, 1436, 1436, 1436, 1436, 1436, + 1436, 1436, 1687, 967, 1687, 1687, 1687, 1687, 1687, 970, + 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1437, 1437, 1437, + 1437, 1437, 1437, 1247, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1356, 1687, 1443, 1358, 1358, + 1358, 1358, 1358, 1358, 1687, 1247, 1687, 1687, 1687, 1687, + 1687, 1250, 1247, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + + 1687, 1687, 1687, 1687, 1687, 1687, 1444, 1444, 1444, 1444, + 1444, 1444, 1444, 1687, 1247, 1687, 1687, 1687, 1687, 1687, + 1250, 1247, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1445, 1687, 1358, 1358, 1358, 1358, 1358, + 1358, 1358, 1687, 1247, 1687, 1687, 1687, 1687, 1687, 1250, + 1687, 1687, 1687, 1446, 1687, 1687, 1447, 1687, 1687, 1687, + 1687, 1687, 1687, 1448, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1449, 1245, 1245, 1247, 1245, + 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1450, 1245, 1450, + 1451, 1245, 1452, 1453, 1453, 1453, 1453, 1453, 1453, 1245, + + 1247, 1245, 1245, 1245, 1245, 1245, 1250, 1245, 1454, 1454, + 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, + 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, + 1454, 1454, 1454, 1454, 1245, 1245, 1245, 1245, 1245, 1245, + 1247, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, + 1245, 1245, 1245, 1245, 1455, 1455, 1455, 1455, 1455, 1455, + 1455, 1245, 1247, 1245, 1245, 1245, 1245, 1456, 1250, 1245, + 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, + 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, + 1455, 1455, 1455, 1455, 1455, 1455, 1245, 1245, 1245, 1455, + + 1119, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1499, + 1687, 1499, 1687, 1687, 1500, 1500, 1500, 1500, 1500, 1500, + 1500, 1687, 1119, 1687, 1687, 1687, 1687, 1687, 1122, 1119, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1415, 1415, 1415, 1415, 1415, 1415, 1415, + 1687, 1119, 1687, 1687, 1687, 1687, 1687, 1122, 1119, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 1687, + 1119, 1687, 1687, 1687, 1687, 1687, 1122, 1419, 1687, 1331, + 1331, 1331, 1331, 1331, 1331, 1331, 1687, 1687, 1687, 1687, + + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1117, 1687, 1687, + 1421, 1687, 1687, 1687, 1687, 1687, 1687, 1422, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1423, + 1119, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1418, 1418, 1418, 1418, 1418, 1418, + 1418, 1687, 1119, 1687, 1687, 1687, 1687, 1687, 1122, 1687, + 1687, 1687, 1687, 1687, 1687, 1502, 1119, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1687, 1119, 1687, + 1687, 1687, 1687, 1687, 1122, 1687, 1687, 1687, 1687, 1687, + + 1687, 1421, 1119, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1504, 1687, 1504, 1687, 1687, 1505, 1505, 1505, 1505, + 1505, 1505, 1505, 1687, 1119, 1687, 1687, 1687, 1687, 1687, + 1122, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1506, 1506, + 1506, 1506, 1506, 1506, 967, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1431, 1431, + 1431, 1431, 1431, 1431, 1431, 1687, 967, 1687, 1687, 1687, + 1687, 1687, 970, 967, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1431, 1431, 1431, + + 1431, 1431, 1431, 1431, 1687, 967, 1687, 1687, 1687, 1687, + 1687, 970, 967, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1512, 1687, 1512, 1687, 1687, 1513, 1513, 1513, 1513, + 1513, 1513, 1513, 1687, 967, 1687, 1687, 1687, 1687, 1687, + 970, 967, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1436, 1436, 1436, 1436, 1436, + 1436, 1436, 1687, 967, 1687, 1687, 1687, 1687, 1687, 970, + 967, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1436, 1436, 1436, 1436, 1436, 1436, + 1436, 1687, 967, 1687, 1687, 1687, 1687, 1687, 970, 1247, + + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1444, 1444, 1444, 1444, 1444, 1444, 1444, + 1687, 1247, 1687, 1687, 1687, 1687, 1687, 1250, 1687, 1687, + 1687, 1687, 1687, 1687, 1516, 1247, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1444, + 1444, 1444, 1444, 1444, 1444, 1444, 1687, 1247, 1687, 1687, + 1687, 1687, 1687, 1250, 1687, 1687, 1687, 1687, 1687, 1687, + 1447, 1247, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1518, 1687, 1518, 1687, 1687, 1519, 1519, 1519, 1519, 1519, + 1519, 1519, 1687, 1247, 1687, 1687, 1687, 1687, 1687, 1250, + + 1247, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1520, 1520, 1520, 1520, 1520, 1520, + 1520, 1687, 1247, 1687, 1687, 1687, 1687, 1687, 1250, 1687, + 1687, 1520, 1520, 1520, 1520, 1520, 1520, 1247, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1451, + 1687, 1521, 1453, 1453, 1453, 1453, 1453, 1453, 1687, 1247, + 1687, 1687, 1687, 1687, 1687, 1250, 1247, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1687, 1247, 1687, + 1687, 1687, 1687, 1687, 1250, 1523, 1687, 1453, 1453, 1453, + + 1453, 1453, 1453, 1453, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1524, 1687, 1687, 1525, 1687, + 1687, 1687, 1687, 1687, 1687, 1526, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1527, 1523, 1687, + 1453, 1453, 1453, 1453, 1453, 1453, 1453, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1245, 1687, + 1687, 1525, 1687, 1687, 1687, 1687, 1687, 1687, 1526, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1245, 1245, 1245, 1247, 1245, 1245, 1245, 1245, 1245, 1245, + 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1528, 1528, 1528, + + 1528, 1528, 1528, 1528, 1245, 1247, 1245, 1245, 1245, 1245, + 1529, 1250, 1245, 1528, 1528, 1528, 1528, 1528, 1528, 1528, + 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, + 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1245, + 1245, 1245, 1528, 1119, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1500, 1500, 1500, + 1500, 1500, 1500, 1500, 1687, 1119, 1687, 1687, 1687, 1687, + 1687, 1122, 1119, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1500, 1500, 1500, 1500, + 1500, 1500, 1500, 1687, 1119, 1687, 1687, 1687, 1687, 1687, + + 1122, 1119, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1572, 1687, 1572, 1687, 1687, 1573, 1573, 1573, 1573, 1573, + 1573, 1573, 1687, 1119, 1687, 1687, 1687, 1687, 1687, 1122, + 1119, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1505, 1505, 1505, 1505, 1505, 1505, + 1505, 1687, 1119, 1687, 1687, 1687, 1687, 1687, 1122, 1119, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1505, 1505, 1505, 1505, 1505, 1505, 1505, + 1687, 1119, 1687, 1687, 1687, 1687, 1687, 1122, 967, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + + 1687, 1687, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1687, + 967, 1687, 1687, 1687, 1687, 1687, 970, 967, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1687, 967, + 1687, 1687, 1687, 1687, 1687, 970, 1247, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1576, 1687, 1576, 1687, 1687, + 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1687, 1247, 1687, + 1687, 1687, 1687, 1687, 1250, 1247, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1519, + 1519, 1519, 1519, 1519, 1519, 1519, 1687, 1247, 1687, 1687, + + 1687, 1687, 1687, 1250, 1247, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1519, 1519, + 1519, 1519, 1519, 1519, 1519, 1687, 1247, 1687, 1687, 1687, + 1687, 1687, 1250, 1523, 1687, 1453, 1453, 1453, 1453, 1453, + 1453, 1453, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1245, 1687, 1687, 1525, 1687, 1687, 1687, + 1687, 1687, 1687, 1526, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1527, 1247, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1522, 1522, 1522, 1522, 1522, 1522, 1522, 1687, 1247, 1687, + + 1687, 1687, 1687, 1687, 1250, 1687, 1687, 1687, 1687, 1687, + 1687, 1579, 1247, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1522, 1522, 1522, 1522, + 1522, 1522, 1522, 1687, 1247, 1687, 1687, 1687, 1687, 1687, + 1250, 1687, 1687, 1687, 1687, 1687, 1687, 1525, 1247, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1581, 1687, 1581, + 1687, 1687, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1687, + 1247, 1687, 1687, 1687, 1687, 1687, 1250, 1583, 1583, 1583, + 1583, 1583, 1583, 1583, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1583, 1583, 1583, 1583, 1583, 1583, + + 1565, 1609, 1567, 1565, 1565, 1565, 1565, 1565, 1565, 1610, + 1565, 1611, 1565, 1611, 1612, 1565, 1613, 1614, 1614, 1614, + 1614, 1614, 1614, 1615, 1567, 1565, 1565, 1565, 1565, 1565, + 1570, 1565, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, + 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, + 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1565, 1565, + 1565, 1565, 1119, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1573, 1573, 1573, 1573, + 1573, 1573, 1573, 1687, 1119, 1687, 1687, 1687, 1687, 1687, + 1122, 1119, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + + 1687, 1687, 1687, 1687, 1687, 1573, 1573, 1573, 1573, 1573, + 1573, 1573, 1687, 1119, 1687, 1687, 1687, 1687, 1687, 1122, + 1247, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1577, 1577, 1577, 1577, 1577, 1577, + 1577, 1687, 1247, 1687, 1687, 1687, 1687, 1687, 1250, 1247, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1577, 1577, 1577, 1577, 1577, 1577, 1577, + 1687, 1247, 1687, 1687, 1687, 1687, 1687, 1250, 1247, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1618, 1687, 1618, + 1687, 1687, 1619, 1619, 1619, 1619, 1619, 1619, 1619, 1687, + + 1247, 1687, 1687, 1687, 1687, 1687, 1250, 1247, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1687, 1247, + 1687, 1687, 1687, 1687, 1687, 1250, 1247, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1687, 1247, 1687, + 1687, 1687, 1687, 1687, 1250, 1567, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1612, 1687, 1631, + 1614, 1614, 1614, 1614, 1614, 1614, 1687, 1567, 1687, 1687, + 1687, 1687, 1687, 1570, 1567, 1687, 1687, 1687, 1687, 1687, + + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1632, 1632, + 1632, 1632, 1632, 1632, 1632, 1687, 1567, 1687, 1687, 1687, + 1687, 1687, 1570, 1567, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1633, 1687, 1614, 1614, 1614, + 1614, 1614, 1614, 1614, 1687, 1567, 1687, 1687, 1687, 1687, + 1687, 1570, 1687, 1687, 1687, 1634, 1687, 1687, 1635, 1687, + 1687, 1687, 1687, 1687, 1687, 1636, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1637, 1565, 1565, + 1567, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1638, + 1565, 1638, 1639, 1565, 1640, 1641, 1641, 1641, 1641, 1641, + + 1641, 1565, 1567, 1565, 1565, 1565, 1565, 1565, 1570, 1565, + 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, + 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, + 1642, 1642, 1642, 1642, 1642, 1642, 1565, 1565, 1565, 1565, + 1565, 1565, 1567, 1565, 1565, 1565, 1565, 1565, 1565, 1565, + 1565, 1565, 1565, 1565, 1565, 1565, 1643, 1643, 1643, 1643, + 1643, 1643, 1643, 1565, 1567, 1565, 1565, 1565, 1565, 1644, + 1570, 1565, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, + 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, + 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1565, 1565, + + 1565, 1643, 1247, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1619, 1619, 1619, 1619, + 1619, 1619, 1619, 1687, 1247, 1687, 1687, 1687, 1687, 1687, + 1250, 1247, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1619, 1619, 1619, 1619, 1619, + 1619, 1619, 1687, 1247, 1687, 1687, 1687, 1687, 1687, 1250, + 1567, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1632, 1632, 1632, 1632, 1632, 1632, + 1632, 1687, 1567, 1687, 1687, 1687, 1687, 1687, 1570, 1687, + 1687, 1687, 1687, 1687, 1687, 1647, 1567, 1687, 1687, 1687, + + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1687, 1567, 1687, + 1687, 1687, 1687, 1687, 1570, 1687, 1687, 1687, 1687, 1687, + 1687, 1635, 1567, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1649, 1687, 1649, 1687, 1687, 1650, 1650, 1650, 1650, + 1650, 1650, 1650, 1687, 1567, 1687, 1687, 1687, 1687, 1687, + 1570, 1567, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1651, 1651, 1651, 1651, 1651, + 1651, 1651, 1687, 1567, 1687, 1687, 1687, 1687, 1687, 1570, + 1687, 1687, 1651, 1651, 1651, 1651, 1651, 1651, 1567, 1687, + + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1639, 1687, 1652, 1641, 1641, 1641, 1641, 1641, 1641, 1687, + 1567, 1687, 1687, 1687, 1687, 1687, 1570, 1567, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1687, 1567, + 1687, 1687, 1687, 1687, 1687, 1570, 1654, 1687, 1641, 1641, + 1641, 1641, 1641, 1641, 1641, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1655, 1687, 1687, 1656, + 1687, 1687, 1687, 1687, 1687, 1687, 1657, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1658, 1654, + + 1687, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1565, + 1687, 1687, 1656, 1687, 1687, 1687, 1687, 1687, 1687, 1657, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1565, 1565, 1565, 1567, 1565, 1565, 1565, 1565, 1565, + 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1659, 1659, + 1659, 1659, 1659, 1659, 1659, 1565, 1567, 1565, 1565, 1565, + 1565, 1660, 1570, 1565, 1659, 1659, 1659, 1659, 1659, 1659, + 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, + 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659, + + 1565, 1565, 1565, 1659, 1567, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1667, 1687, 1667, 1687, 1687, 1668, 1668, + 1668, 1668, 1668, 1668, 1668, 1687, 1567, 1687, 1687, 1687, + 1687, 1687, 1570, 1567, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1650, 1650, 1650, + 1650, 1650, 1650, 1650, 1687, 1567, 1687, 1687, 1687, 1687, + 1687, 1570, 1567, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1650, 1650, 1650, 1650, + 1650, 1650, 1650, 1687, 1567, 1687, 1687, 1687, 1687, 1687, + 1570, 1654, 1687, 1641, 1641, 1641, 1641, 1641, 1641, 1641, + + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1565, 1687, 1687, 1656, 1687, 1687, 1687, 1687, 1687, + 1687, 1657, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1658, 1567, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1653, 1653, + 1653, 1653, 1653, 1653, 1653, 1687, 1567, 1687, 1687, 1687, + 1687, 1687, 1570, 1687, 1687, 1687, 1687, 1687, 1687, 1670, + 1567, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1653, 1653, 1653, 1653, 1653, 1653, + 1653, 1687, 1567, 1687, 1687, 1687, 1687, 1687, 1570, 1687, + + 1687, 1687, 1687, 1687, 1687, 1656, 1567, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1672, 1687, 1672, 1687, 1687, + 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1687, 1567, 1687, + 1687, 1687, 1687, 1687, 1570, 1674, 1674, 1674, 1674, 1674, + 1674, 1674, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1674, 1674, 1674, 1674, 1674, 1674, 1567, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1687, + 1567, 1687, 1687, 1687, 1687, 1687, 1570, 1567, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + + 1687, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 1687, 1567, + 1687, 1687, 1687, 1687, 1687, 1570, 1567, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1682, 1687, 1682, 1687, 1687, + 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1687, 1567, 1687, + 1687, 1687, 1687, 1687, 1570, 1567, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1673, + 1673, 1673, 1673, 1673, 1673, 1673, 1687, 1567, 1687, 1687, + 1687, 1687, 1687, 1570, 1567, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1673, 1673, + 1673, 1673, 1673, 1673, 1673, 1687, 1567, 1687, 1687, 1687, + + 1687, 1687, 1570, 1567, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1683, 1683, 1683, + 1683, 1683, 1683, 1683, 1687, 1567, 1687, 1687, 1687, 1687, + 1687, 1570, 1567, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1683, 1683, 1683, 1683, + 1683, 1683, 1683, 1687, 1567, 1687, 1687, 1687, 1687, 1687, + 1570, 117, 117, 117, 117, 117, 117, 117, 117, 117, + 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, + 117, 117, 117, 117, 117, 130, 130, 130, 130, 130, + 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, + + 130, 130, 130, 130, 130, 130, 130, 130, 130, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 133, 133, 133, 133, 133, 133, 133, + 155, 155, 155, 155, 1687, 1687, 155, 155, 155, 155, + 155, 155, 155, 155, 1687, 155, 160, 1687, 1687, 160, + 1687, 1687, 1687, 1687, 1687, 1687, 160, 1687, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 1687, 160, 258, + 258, 258, 258, 1687, 1687, 258, 258, 258, 258, 258, + 258, 258, 258, 1687, 258, 264, 1687, 264, 264, 1687, + + 264, 1687, 264, 1687, 264, 264, 1687, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 1687, 264, 306, 1687, + 1687, 306, 306, 306, 306, 306, 306, 306, 306, 1687, + 306, 323, 1687, 1687, 1687, 323, 1687, 1687, 323, 323, + 323, 323, 323, 323, 323, 323, 1687, 323, 342, 342, + 1687, 342, 342, 342, 342, 342, 342, 342, 342, 342, + 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, + 342, 342, 351, 1687, 1687, 351, 1687, 351, 1687, 351, + 351, 1687, 351, 351, 1687, 1687, 351, 351, 351, 351, + 351, 351, 351, 352, 352, 352, 352, 352, 352, 352, + + 352, 352, 352, 352, 352, 352, 352, 1687, 352, 352, + 352, 352, 352, 352, 352, 352, 352, 412, 412, 412, + 412, 1687, 1687, 412, 412, 412, 412, 412, 412, 412, + 412, 1687, 412, 414, 1687, 1687, 414, 414, 414, 414, + 414, 414, 414, 414, 1687, 414, 214, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 214, 214, 1687, 1687, + 1687, 1687, 214, 455, 1687, 1687, 1687, 1687, 455, 1687, + 455, 1687, 1687, 455, 460, 1687, 1687, 1687, 1687, 460, + 1687, 460, 1687, 1687, 460, 466, 1687, 1687, 1687, 1687, + 466, 1687, 466, 1687, 1687, 466, 258, 258, 258, 258, + + 1687, 1687, 258, 258, 258, 258, 258, 258, 258, 258, + 1687, 258, 468, 468, 1687, 468, 468, 468, 468, 468, + 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, + 468, 468, 468, 468, 468, 468, 264, 1687, 264, 264, + 1687, 264, 1687, 264, 1687, 264, 264, 1687, 264, 264, + 264, 264, 264, 264, 264, 264, 264, 1687, 264, 470, + 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, + 470, 470, 470, 1687, 470, 470, 470, 470, 470, 470, + 470, 470, 470, 305, 1687, 1687, 1687, 1687, 1687, 1687, + 305, 1687, 1687, 305, 305, 306, 1687, 1687, 306, 306, + + 306, 306, 306, 306, 306, 306, 1687, 306, 511, 511, + 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, + 511, 511, 1687, 511, 511, 511, 511, 511, 511, 511, + 511, 511, 526, 526, 526, 526, 526, 526, 526, 323, + 1687, 1687, 1687, 323, 1687, 1687, 323, 323, 323, 323, + 323, 323, 323, 323, 1687, 323, 527, 527, 527, 527, + 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, + 1687, 527, 527, 527, 527, 527, 527, 527, 527, 527, + 341, 1687, 1687, 1687, 1687, 341, 341, 341, 342, 342, + 1687, 342, 342, 342, 342, 342, 342, 342, 342, 342, + + 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, + 342, 342, 555, 1687, 555, 555, 1687, 555, 1687, 1687, + 1687, 555, 555, 555, 555, 555, 555, 555, 556, 1687, + 1687, 556, 556, 556, 556, 556, 556, 556, 556, 1687, + 556, 352, 352, 352, 352, 352, 352, 352, 352, 352, + 352, 352, 352, 352, 352, 1687, 352, 352, 352, 352, + 352, 352, 352, 352, 352, 160, 1687, 1687, 160, 1687, + 1687, 1687, 1687, 1687, 1687, 160, 1687, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 1687, 160, 412, 412, + 412, 412, 1687, 1687, 412, 412, 412, 412, 412, 412, + + 412, 412, 1687, 412, 621, 621, 1687, 621, 621, 621, + 621, 621, 621, 621, 621, 621, 621, 621, 621, 621, + 621, 621, 621, 621, 621, 621, 621, 621, 414, 1687, + 1687, 414, 414, 414, 414, 414, 414, 414, 414, 1687, + 414, 623, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 1687, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 438, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 438, 438, 1687, 1687, 1687, + 438, 438, 438, 226, 1687, 226, 1687, 1687, 1687, 1687, + 1687, 226, 226, 1687, 1687, 226, 448, 1687, 1687, 1687, + + 1687, 1687, 1687, 448, 1687, 1687, 448, 448, 460, 1687, + 1687, 1687, 1687, 460, 1687, 460, 1687, 1687, 460, 455, + 1687, 1687, 1687, 1687, 455, 1687, 455, 1687, 1687, 455, + 466, 1687, 1687, 1687, 1687, 466, 1687, 466, 1687, 1687, + 466, 468, 468, 1687, 468, 468, 468, 468, 468, 468, + 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, + 468, 468, 468, 468, 468, 470, 470, 470, 470, 470, + 470, 470, 470, 470, 470, 470, 470, 470, 470, 1687, + 470, 470, 470, 470, 470, 470, 470, 470, 470, 351, + 1687, 1687, 351, 1687, 351, 1687, 351, 351, 1687, 351, + + 351, 1687, 1687, 351, 351, 351, 351, 351, 351, 351, + 264, 1687, 264, 264, 1687, 264, 1687, 264, 1687, 264, + 264, 1687, 264, 264, 264, 264, 264, 264, 264, 264, + 264, 1687, 264, 511, 511, 511, 511, 511, 511, 511, + 511, 511, 511, 511, 511, 511, 511, 1687, 511, 511, + 511, 511, 511, 511, 511, 511, 511, 731, 1687, 1687, + 1687, 1687, 1687, 731, 1687, 1687, 731, 731, 731, 731, + 731, 731, 731, 731, 1687, 731, 527, 527, 527, 527, + 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, + 1687, 527, 527, 527, 527, 527, 527, 527, 527, 527, + + 323, 1687, 1687, 1687, 323, 1687, 1687, 323, 323, 323, + 323, 323, 323, 323, 323, 1687, 323, 349, 1687, 349, + 1687, 1687, 1687, 1687, 1687, 349, 349, 1687, 1687, 349, + 758, 1687, 1687, 758, 758, 758, 758, 758, 758, 758, + 758, 1687, 758, 556, 1687, 1687, 556, 556, 556, 556, + 556, 556, 556, 556, 1687, 556, 760, 760, 760, 760, + 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, + 1687, 760, 760, 760, 760, 760, 760, 760, 760, 760, + 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, + 352, 352, 352, 352, 1687, 352, 352, 352, 352, 352, + + 352, 352, 352, 352, 160, 1687, 1687, 160, 1687, 1687, + 1687, 1687, 1687, 1687, 160, 1687, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 1687, 160, 775, 1687, 1687, + 775, 1687, 775, 1687, 775, 775, 1687, 775, 1687, 775, + 1687, 775, 775, 775, 775, 775, 775, 775, 621, 621, + 1687, 621, 621, 621, 621, 621, 621, 621, 621, 621, + 621, 621, 621, 621, 621, 621, 621, 621, 621, 621, + 621, 621, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 1687, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 414, 1687, 1687, 414, + + 414, 414, 414, 414, 414, 414, 414, 1687, 414, 434, + 1687, 434, 1687, 1687, 1687, 1687, 1687, 434, 434, 1687, + 1687, 434, 652, 1687, 1687, 1687, 1687, 652, 652, 652, + 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, + 470, 470, 470, 470, 1687, 470, 470, 470, 470, 470, + 470, 470, 470, 470, 264, 1687, 264, 264, 1687, 264, + 1687, 264, 1687, 264, 264, 1687, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 1687, 264, 716, 1687, 1687, + 1687, 1687, 716, 716, 716, 1687, 1687, 1687, 716, 731, + 1687, 1687, 1687, 1687, 1687, 731, 1687, 1687, 731, 731, + + 731, 731, 731, 731, 731, 731, 1687, 731, 904, 904, + 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, + 904, 904, 1687, 904, 904, 904, 904, 904, 904, 904, + 904, 904, 323, 1687, 323, 1687, 1687, 1687, 323, 1687, + 1687, 323, 323, 323, 323, 323, 323, 323, 323, 1687, + 323, 750, 1687, 1687, 1687, 1687, 750, 750, 750, 554, + 1687, 554, 1687, 1687, 1687, 1687, 1687, 554, 554, 1687, + 1687, 554, 758, 1687, 1687, 758, 758, 758, 758, 758, + 758, 758, 758, 1687, 758, 926, 926, 926, 926, 926, + 926, 926, 926, 926, 926, 926, 926, 926, 926, 1687, + + 926, 926, 926, 926, 926, 926, 926, 926, 926, 760, + 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, + 760, 760, 760, 1687, 760, 760, 760, 760, 760, 760, + 760, 760, 760, 352, 352, 352, 352, 352, 352, 352, + 352, 352, 352, 352, 352, 352, 352, 1687, 352, 352, + 352, 352, 352, 352, 352, 352, 352, 160, 1687, 1687, + 160, 1687, 1687, 1687, 1687, 1687, 1687, 160, 1687, 160, + 160, 160, 160, 160, 160, 160, 160, 160, 1687, 160, + 949, 1687, 1687, 949, 949, 949, 949, 949, 949, 949, + 949, 1687, 949, 965, 965, 965, 965, 965, 965, 965, + + 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, + 965, 965, 965, 965, 965, 965, 965, 414, 1687, 1687, + 414, 414, 414, 414, 414, 414, 414, 414, 1687, 414, + 834, 1687, 1687, 1687, 1687, 834, 834, 834, 838, 1687, + 1687, 1687, 1687, 838, 838, 838, 1687, 1687, 1687, 838, + 844, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 844, 844, 1687, 1687, 1687, 844, 844, 844, 844, 850, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 850, + 850, 1687, 1687, 1687, 850, 850, 850, 850, 856, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 856, 856, + + 1687, 1687, 1687, 856, 856, 856, 856, 470, 470, 470, + 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, + 470, 1687, 470, 470, 470, 470, 470, 470, 470, 470, + 470, 874, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 874, 1687, 1687, 1687, 1687, 874, 874, 874, 264, + 1687, 264, 264, 1687, 264, 1687, 264, 1687, 264, 264, + 1687, 264, 264, 264, 264, 264, 264, 264, 264, 264, + 1687, 264, 904, 904, 904, 904, 904, 904, 904, 904, + 904, 904, 904, 904, 904, 904, 1687, 904, 904, 904, + 904, 904, 904, 904, 904, 904, 323, 1687, 1687, 1687, + + 323, 1687, 1687, 323, 323, 323, 323, 323, 323, 323, + 323, 1687, 323, 965, 965, 965, 965, 965, 965, 965, + 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, + 965, 965, 965, 965, 965, 965, 965, 925, 1687, 1687, + 1687, 1687, 925, 925, 925, 926, 926, 926, 926, 926, + 926, 926, 926, 926, 926, 926, 926, 926, 926, 1687, + 926, 926, 926, 926, 926, 926, 926, 926, 926, 352, + 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, + 352, 352, 352, 1687, 352, 352, 352, 352, 352, 352, + 352, 352, 352, 160, 1687, 1687, 160, 1687, 1687, 1687, + + 1687, 1687, 1687, 160, 1687, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 1687, 160, 774, 1687, 774, 1687, + 1687, 1687, 1687, 1687, 774, 774, 1687, 1687, 774, 949, + 1687, 1687, 949, 949, 949, 949, 949, 949, 949, 949, + 1687, 949, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, + 1108, 1108, 1108, 1108, 1108, 1108, 1687, 1108, 1108, 1108, + 1108, 1108, 1108, 1108, 1108, 1108, 775, 1687, 1687, 775, + 1687, 775, 1687, 775, 775, 1687, 775, 1687, 775, 1687, + 775, 775, 775, 775, 775, 775, 775, 1117, 1117, 1117, + 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, + + 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, + 1117, 414, 1687, 1687, 414, 414, 414, 414, 414, 414, + 414, 414, 1687, 414, 999, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 999, 1687, 1687, 1687, 1687, 1687, + 999, 1687, 1687, 999, 1009, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1009, 1687, 1687, 1687, 1687, 1687, + 1009, 1687, 1687, 1009, 1018, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1018, 1687, 1687, 1687, 1687, 1687, + 1018, 1687, 1687, 1018, 470, 470, 470, 470, 470, 470, + 470, 470, 470, 470, 470, 470, 470, 470, 1687, 470, + + 470, 470, 470, 470, 470, 470, 470, 470, 264, 1687, + 264, 264, 1687, 264, 1687, 264, 1687, 264, 264, 1687, + 264, 264, 264, 264, 264, 264, 264, 264, 264, 1687, + 264, 904, 904, 904, 904, 904, 904, 904, 904, 904, + 904, 904, 904, 904, 904, 1687, 904, 904, 904, 904, + 904, 904, 904, 904, 904, 527, 527, 527, 527, 527, + 527, 527, 527, 527, 527, 527, 527, 527, 527, 1687, + 527, 527, 527, 527, 527, 527, 527, 527, 527, 323, + 1687, 323, 1687, 1687, 1687, 323, 1687, 1687, 323, 323, + 323, 323, 323, 323, 323, 323, 1687, 323, 775, 1687, + + 1687, 775, 1687, 775, 1687, 775, 775, 1687, 775, 1687, + 1687, 1687, 775, 775, 775, 775, 775, 775, 775, 1117, + 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, + 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, + 1117, 1117, 1117, 965, 965, 965, 965, 965, 965, 965, + 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, + 965, 965, 965, 965, 965, 965, 965, 352, 352, 352, + 352, 352, 352, 352, 352, 352, 352, 352, 352, 352, + 352, 1687, 352, 352, 352, 352, 352, 352, 352, 352, + 352, 160, 1687, 1687, 160, 1687, 1687, 1687, 1687, 1687, + + 1687, 160, 1687, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 1687, 160, 1107, 1687, 1687, 1687, 1687, 1107, + 1107, 1107, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, + 1108, 1108, 1108, 1108, 1108, 1108, 1687, 1108, 1108, 1108, + 1108, 1108, 1108, 1108, 1108, 1108, 1245, 1245, 1245, 1245, + 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, + 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, + 414, 1687, 1687, 414, 414, 414, 414, 414, 414, 414, + 414, 1687, 414, 1149, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1149, 1687, 1687, 1687, 1687, 1149, 1149, + + 1149, 1687, 1149, 1154, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1154, 1687, 1687, 1687, 1687, 1154, 1154, + 1154, 1687, 1154, 1159, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1159, 1687, 1687, 1687, 1687, 1159, 1159, + 1159, 1687, 1159, 470, 470, 470, 470, 470, 470, 470, + 470, 470, 470, 470, 470, 470, 470, 1687, 470, 470, + 470, 470, 470, 470, 470, 470, 470, 264, 1687, 264, + 264, 1687, 264, 1687, 264, 1687, 264, 264, 1687, 264, + 264, 264, 264, 264, 264, 264, 264, 264, 1687, 264, + 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, + + 904, 904, 904, 904, 1687, 904, 904, 904, 904, 904, + 904, 904, 904, 904, 527, 527, 527, 527, 527, 527, + 527, 527, 527, 527, 527, 527, 527, 527, 1687, 527, + 527, 527, 527, 527, 527, 527, 527, 527, 323, 1687, + 1687, 1687, 323, 1687, 323, 1687, 1687, 1687, 323, 1687, + 1687, 323, 323, 323, 323, 323, 323, 323, 323, 1687, + 323, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, + 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, + 1349, 1349, 1349, 1349, 1349, 1426, 1426, 1426, 1426, 1426, + 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, + + 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1438, + 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, + 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, 1438, + 1438, 1438, 1438, 760, 760, 760, 760, 760, 760, 760, + 760, 760, 760, 760, 760, 760, 760, 1687, 760, 760, + 760, 760, 760, 760, 760, 760, 760, 1507, 1507, 1507, + 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, + 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507, + 1507, 926, 926, 926, 926, 926, 926, 926, 926, 926, + 926, 926, 926, 926, 926, 1687, 926, 926, 926, 926, + + 926, 926, 926, 926, 926, 1530, 1530, 1530, 1530, 1530, + 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, + 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1565, + 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, + 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, 1565, + 1565, 1565, 1565, 1584, 1584, 1584, 1584, 1584, 1584, 1584, + 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1584, + 1584, 1584, 1584, 1584, 1584, 1584, 1584, 1661, 1661, 1661, + 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, + 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, + + 1661, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, + 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, + 1675, 1675, 1675, 1675, 1675, 15, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687 + } ; + +static yyconst short int yy_chk[14289] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 3, 3, 32, 32, 3, 3, 13, 14, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 5, 5, + 3, 5, 6, 6, 19, 6, 13, 14, 31, 34, + + 34, 19, 19, 19, 124, 19, 19, 66, 66, 68, + 68, 124, 19, 87, 87, 296, 19, 19, 296, 3, + 31, 3, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 11, 11, 125, 11, + 25, 25, 125, 25, 74, 206, 25, 89, 89, 25, + 80, 100, 100, 11, 123, 123, 25, 206, 25, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 27, 417, 27, 27, 27, + + 27, 27, 27, 27, 29, 29, 29, 29, 29, 29, + 29, 74, 63, 96, 27, 27, 27, 80, 27, 27, + 37, 96, 96, 417, 38, 27, 151, 151, 37, 27, + 27, 27, 38, 27, 63, 27, 30, 419, 30, 30, + 30, 30, 30, 30, 30, 37, 39, 1681, 37, 38, + 85, 199, 38, 133, 39, 40, 30, 43, 419, 30, + 105, 105, 39, 40, 99, 43, 30, 105, 38, 38, + 133, 39, 85, 199, 39, 99, 99, 99, 30, 41, + 40, 44, 43, 40, 204, 43, 42, 41, 202, 44, + 106, 106, 39, 39, 42, 40, 204, 43, 106, 43, + + 45, 40, 40, 204, 41, 202, 44, 41, 45, 44, + 46, 42, 103, 44, 42, 41, 103, 103, 46, 209, + 42, 1676, 47, 94, 44, 45, 101, 46, 45, 42, + 47, 48, 49, 42, 45, 46, 101, 101, 46, 48, + 49, 50, 209, 207, 45, 213, 421, 47, 1674, 50, + 47, 94, 94, 94, 94, 207, 48, 49, 228, 48, + 49, 421, 47, 48, 51, 97, 50, 213, 137, 50, + 48, 48, 51, 52, 97, 97, 97, 48, 97, 102, + 48, 52, 98, 49, 98, 137, 98, 98, 999, 51, + 95, 134, 51, 50, 95, 95, 95, 95, 52, 135, + + 51, 52, 137, 128, 51, 108, 102, 102, 134, 52, + 54, 128, 54, 108, 108, 228, 135, 128, 54, 134, + 54, 203, 54, 54, 999, 54, 54, 54, 54, 54, + 54, 54, 218, 218, 135, 245, 245, 54, 999, 203, + 203, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 55, 205, 247, + 247, 248, 248, 107, 55, 55, 55, 107, 55, 55, + 231, 107, 107, 205, 158, 55, 879, 205, 879, 55, + 55, 59, 158, 59, 59, 59, 59, 59, 59, 59, + + 61, 61, 61, 61, 61, 61, 61, 62, 81, 158, + 81, 81, 81, 81, 81, 81, 81, 136, 138, 215, + 62, 323, 62, 62, 62, 62, 62, 62, 62, 62, + 71, 71, 1666, 71, 136, 138, 71, 231, 323, 71, + 62, 215, 220, 62, 139, 226, 71, 76, 71, 136, + 62, 265, 265, 138, 76, 76, 76, 490, 76, 76, + 145, 139, 62, 64, 220, 76, 490, 226, 145, 76, + 76, 235, 139, 64, 145, 64, 64, 145, 64, 64, + 64, 64, 64, 64, 64, 83, 83, 83, 83, 83, + 83, 83, 84, 235, 84, 84, 636, 84, 84, 84, + + 214, 483, 84, 140, 84, 84, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 160, 84, 84, 84, 483, + 140, 164, 214, 160, 636, 84, 175, 84, 84, 164, + 320, 84, 84, 320, 175, 84, 214, 140, 387, 84, + 160, 84, 387, 160, 267, 267, 164, 84, 304, 164, + 84, 175, 84, 92, 175, 92, 286, 286, 92, 92, + 304, 92, 175, 92, 304, 92, 164, 92, 141, 141, + 141, 141, 141, 141, 141, 104, 418, 92, 92, 92, + 418, 92, 104, 104, 338, 338, 327, 104, 104, 104, + 420, 109, 104, 109, 420, 326, 109, 109, 109, 109, + + 109, 109, 109, 327, 149, 149, 149, 149, 149, 149, + 149, 92, 326, 92, 93, 423, 93, 385, 385, 93, + 93, 327, 93, 423, 93, 149, 93, 216, 93, 150, + 150, 150, 150, 150, 150, 150, 326, 163, 93, 93, + 93, 1665, 93, 325, 349, 163, 152, 625, 152, 216, + 150, 152, 152, 152, 152, 152, 152, 152, 93, 93, + 325, 165, 163, 216, 325, 163, 349, 404, 404, 165, + 386, 625, 93, 166, 93, 161, 422, 386, 406, 406, + 422, 166, 165, 161, 163, 161, 165, 161, 161, 165, + 161, 161, 161, 161, 161, 161, 161, 161, 166, 167, + + 271, 166, 208, 1383, 168, 169, 208, 167, 271, 170, + 171, 172, 168, 169, 208, 173, 1383, 170, 171, 172, + 208, 407, 407, 173, 167, 271, 730, 167, 166, 168, + 169, 167, 168, 169, 170, 171, 172, 170, 171, 172, + 173, 170, 174, 173, 176, 331, 395, 426, 177, 169, + 174, 730, 176, 168, 172, 426, 177, 178, 173, 428, + 328, 171, 331, 176, 176, 178, 416, 174, 395, 176, + 174, 179, 176, 177, 174, 434, 177, 328, 428, 179, + 180, 182, 178, 416, 331, 178, 181, 330, 180, 182, + 183, 177, 402, 1662, 181, 402, 179, 434, 183, 179, + + 328, 181, 184, 178, 330, 180, 182, 424, 180, 182, + 184, 181, 180, 185, 181, 183, 329, 186, 183, 632, + 179, 185, 330, 187, 424, 186, 182, 184, 188, 409, + 184, 187, 409, 329, 632, 183, 188, 237, 185, 189, + 488, 185, 186, 827, 402, 186, 190, 189, 187, 185, + 329, 187, 488, 188, 190, 191, 188, 186, 184, 237, + 186, 425, 192, 191, 189, 390, 827, 189, 1651, 187, + 192, 190, 237, 390, 190, 188, 237, 497, 425, 390, + 191, 409, 189, 191, 194, 194, 194, 192, 194, 194, + 192, 442, 442, 497, 477, 194, 192, 716, 191, 194, + + 194, 190, 195, 197, 197, 197, 197, 197, 197, 197, + 547, 547, 195, 716, 195, 195, 477, 195, 195, 195, + 195, 195, 195, 195, 196, 498, 196, 196, 196, 196, + 196, 196, 196, 211, 211, 211, 211, 211, 211, 211, + 244, 249, 498, 196, 196, 196, 438, 196, 196, 427, + 244, 249, 244, 249, 196, 244, 249, 828, 196, 196, + 198, 427, 198, 345, 427, 198, 198, 828, 438, 198, + 198, 345, 198, 198, 198, 198, 198, 198, 198, 198, + 198, 198, 251, 482, 198, 198, 198, 353, 345, 438, + 482, 485, 251, 198, 251, 353, 198, 251, 485, 219, + + 1645, 219, 503, 198, 219, 219, 219, 219, 219, 219, + 219, 514, 353, 526, 503, 198, 489, 353, 198, 514, + 198, 217, 223, 489, 223, 223, 223, 223, 223, 223, + 223, 217, 526, 217, 217, 1629, 217, 217, 217, 217, + 217, 217, 217, 224, 224, 224, 224, 224, 224, 224, + 225, 675, 225, 225, 225, 225, 225, 225, 225, 233, + 233, 233, 233, 233, 233, 233, 1629, 500, 501, 554, + 225, 628, 501, 225, 500, 675, 229, 628, 229, 439, + 225, 229, 229, 229, 229, 229, 229, 229, 232, 530, + 232, 554, 225, 232, 232, 232, 232, 232, 232, 232, + + 236, 236, 439, 236, 236, 236, 530, 1631, 236, 439, + 236, 530, 236, 236, 236, 236, 236, 236, 236, 236, + 435, 439, 236, 236, 236, 303, 303, 303, 303, 303, + 303, 303, 357, 236, 236, 435, 435, 1630, 236, 697, + 357, 647, 435, 697, 250, 236, 250, 236, 528, 250, + 250, 250, 250, 250, 250, 250, 236, 357, 236, 253, + 357, 253, 253, 647, 253, 253, 253, 528, 698, 253, + 630, 253, 698, 253, 305, 305, 305, 305, 305, 305, + 305, 253, 630, 253, 253, 253, 339, 339, 339, 339, + 339, 339, 339, 516, 253, 633, 360, 602, 253, 253, + + 602, 516, 305, 633, 360, 337, 253, 337, 253, 877, + 337, 337, 337, 337, 337, 337, 337, 253, 305, 253, + 264, 360, 264, 518, 360, 264, 264, 516, 264, 877, + 264, 518, 264, 696, 264, 340, 340, 340, 340, 340, + 340, 340, 696, 360, 264, 264, 264, 346, 264, 346, + 346, 346, 346, 346, 346, 346, 347, 347, 347, 347, + 347, 347, 347, 518, 608, 608, 987, 354, 393, 393, + 393, 393, 393, 393, 393, 354, 1628, 408, 264, 408, + 264, 266, 408, 408, 408, 408, 408, 408, 408, 266, + 987, 266, 354, 266, 266, 354, 266, 266, 266, 266, + + 266, 266, 266, 266, 643, 643, 266, 270, 627, 270, + 354, 447, 270, 270, 355, 270, 356, 270, 358, 270, + 359, 270, 355, 447, 356, 627, 358, 447, 359, 522, + 361, 270, 270, 270, 767, 270, 356, 522, 361, 355, + 634, 356, 355, 358, 356, 359, 358, 634, 359, 367, + 367, 370, 629, 480, 359, 361, 767, 367, 361, 370, + 367, 480, 515, 358, 522, 270, 355, 270, 272, 629, + 515, 694, 367, 480, 367, 361, 370, 367, 272, 370, + 272, 272, 694, 272, 272, 272, 272, 272, 272, 272, + 348, 362, 348, 348, 348, 348, 348, 348, 348, 362, + + 365, 370, 1606, 637, 517, 480, 363, 515, 365, 520, + 348, 451, 517, 348, 363, 637, 362, 520, 712, 362, + 348, 451, 364, 451, 712, 365, 451, 362, 365, 366, + 364, 363, 348, 350, 363, 350, 350, 366, 350, 350, + 350, 350, 350, 350, 350, 365, 363, 364, 368, 517, + 364, 703, 520, 369, 366, 525, 368, 366, 703, 371, + 372, 369, 364, 525, 649, 649, 373, 371, 372, 524, + 680, 374, 366, 368, 373, 372, 368, 524, 369, 374, + 368, 369, 375, 890, 371, 372, 369, 371, 372, 890, + 375, 373, 376, 377, 373, 525, 374, 371, 680, 374, + + 376, 377, 373, 378, 673, 379, 374, 375, 487, 673, + 375, 378, 535, 379, 380, 381, 487, 376, 377, 529, + 376, 377, 380, 381, 1605, 524, 382, 383, 378, 535, + 379, 378, 375, 379, 382, 383, 529, 376, 819, 380, + 381, 535, 380, 381, 378, 379, 452, 631, 487, 377, + 380, 382, 383, 819, 382, 383, 452, 529, 452, 484, + 487, 452, 382, 429, 631, 429, 381, 484, 429, 429, + 429, 429, 429, 429, 429, 679, 679, 1604, 383, 392, + 679, 392, 392, 392, 392, 392, 392, 392, 431, 889, + 431, 431, 431, 431, 431, 431, 431, 519, 392, 392, + + 392, 658, 392, 392, 692, 519, 484, 889, 521, 392, + 523, 484, 692, 392, 392, 394, 521, 394, 523, 707, + 394, 394, 707, 658, 532, 394, 532, 394, 394, 394, + 394, 394, 394, 394, 394, 394, 394, 457, 821, 394, + 394, 394, 519, 532, 521, 658, 493, 457, 394, 457, + 533, 394, 457, 821, 493, 523, 463, 635, 394, 432, + 432, 432, 432, 432, 432, 432, 463, 533, 463, 891, + 394, 463, 536, 394, 635, 394, 396, 533, 396, 493, + 536, 396, 396, 685, 685, 396, 396, 891, 396, 396, + 396, 396, 396, 396, 396, 396, 396, 396, 493, 1293, + + 396, 396, 396, 436, 436, 436, 436, 436, 436, 436, + 534, 531, 396, 709, 1293, 536, 660, 691, 709, 396, + 440, 440, 440, 440, 440, 440, 440, 534, 531, 677, + 677, 396, 531, 702, 396, 677, 396, 397, 660, 397, + 731, 440, 397, 397, 702, 691, 397, 397, 534, 397, + 437, 397, 397, 397, 397, 397, 397, 397, 397, 731, + 660, 397, 397, 397, 575, 437, 437, 437, 437, 437, + 437, 437, 437, 397, 575, 441, 441, 441, 441, 441, + 441, 441, 443, 774, 443, 1603, 575, 443, 443, 443, + 443, 443, 443, 443, 695, 397, 441, 397, 398, 699, + + 398, 486, 695, 398, 398, 774, 704, 699, 398, 486, + 398, 701, 398, 446, 446, 446, 446, 446, 446, 446, + 701, 1585, 398, 398, 398, 706, 448, 448, 448, 448, + 448, 448, 448, 450, 704, 450, 706, 486, 450, 450, + 450, 450, 450, 450, 450, 453, 453, 453, 453, 453, + 453, 453, 715, 486, 448, 715, 398, 838, 398, 430, + 458, 458, 458, 458, 458, 458, 458, 747, 747, 430, + 448, 430, 430, 838, 430, 430, 430, 430, 430, 430, + 430, 433, 1583, 433, 433, 433, 433, 433, 433, 433, + 461, 461, 461, 461, 461, 461, 461, 700, 708, 887, + + 710, 433, 711, 820, 433, 700, 708, 710, 887, 711, + 820, 433, 462, 462, 462, 462, 462, 462, 462, 754, + 754, 831, 831, 433, 454, 464, 464, 464, 464, 464, + 464, 464, 475, 475, 475, 475, 475, 475, 475, 454, + 454, 454, 454, 454, 454, 454, 454, 474, 494, 474, + 474, 474, 474, 474, 474, 474, 494, 492, 495, 823, + 1562, 718, 496, 491, 491, 492, 495, 454, 454, 718, + 496, 491, 826, 662, 491, 822, 826, 496, 823, 454, + 456, 456, 822, 456, 456, 456, 491, 880, 456, 492, + 456, 499, 456, 456, 456, 662, 495, 504, 494, 499, + + 494, 824, 456, 456, 456, 504, 664, 880, 824, 492, + 495, 502, 506, 456, 496, 491, 505, 662, 456, 502, + 506, 507, 513, 544, 505, 456, 1051, 456, 664, 507, + 513, 1561, 734, 504, 734, 825, 456, 744, 456, 459, + 1051, 499, 825, 499, 867, 744, 544, 666, 506, 504, + 664, 734, 502, 544, 459, 459, 459, 459, 459, 459, + 459, 459, 713, 502, 506, 544, 867, 505, 505, 666, + 713, 905, 507, 507, 513, 541, 541, 541, 541, 541, + 541, 541, 459, 459, 542, 542, 542, 542, 542, 542, + 542, 666, 905, 878, 459, 465, 763, 545, 545, 545, + + 545, 545, 545, 545, 763, 713, 881, 881, 668, 878, + 465, 465, 465, 465, 465, 465, 465, 465, 545, 546, + 546, 546, 546, 546, 546, 546, 548, 883, 548, 883, + 668, 548, 548, 548, 548, 548, 548, 548, 465, 465, + 546, 551, 1560, 551, 551, 551, 551, 551, 551, 551, + 465, 467, 668, 467, 467, 902, 467, 467, 467, 882, + 882, 467, 735, 467, 735, 467, 467, 467, 467, 467, + 467, 467, 467, 467, 776, 467, 467, 467, 886, 886, + 902, 735, 776, 467, 467, 467, 467, 467, 467, 874, + 467, 467, 888, 884, 467, 888, 735, 738, 467, 738, + + 467, 552, 552, 552, 552, 552, 552, 552, 938, 467, + 1303, 467, 471, 884, 471, 558, 738, 471, 471, 561, + 471, 564, 471, 558, 471, 1303, 471, 561, 738, 564, + 938, 705, 874, 565, 922, 922, 471, 471, 471, 705, + 558, 565, 471, 566, 561, 558, 564, 561, 565, 564, + 893, 566, 568, 893, 567, 945, 945, 829, 565, 561, + 568, 565, 567, 705, 564, 829, 1195, 863, 566, 1195, + 471, 566, 471, 472, 705, 863, 991, 568, 566, 567, + 568, 472, 567, 472, 568, 472, 472, 871, 472, 472, + 472, 472, 472, 472, 472, 472, 473, 567, 991, 570, + + 1050, 988, 871, 871, 473, 988, 473, 570, 473, 473, + 1050, 473, 473, 473, 473, 473, 473, 473, 473, 476, + 571, 569, 572, 736, 570, 736, 993, 570, 571, 569, + 572, 1559, 476, 570, 476, 476, 476, 476, 476, 476, + 476, 1000, 736, 573, 993, 571, 569, 572, 571, 569, + 572, 573, 476, 912, 990, 476, 569, 908, 990, 908, + 992, 912, 476, 617, 992, 736, 617, 571, 573, 572, + 1054, 573, 617, 617, 476, 478, 908, 478, 573, 1595, + 478, 478, 574, 478, 577, 478, 576, 478, 1054, 478, + 574, 1000, 577, 1378, 576, 1595, 578, 580, 579, 478, + + 478, 478, 907, 478, 578, 580, 579, 574, 1378, 577, + 574, 576, 577, 579, 576, 617, 577, 574, 478, 907, + 576, 578, 580, 579, 578, 580, 579, 907, 1004, 580, + 965, 581, 578, 478, 1385, 478, 479, 1144, 479, 581, + 1385, 479, 479, 582, 479, 585, 479, 583, 479, 584, + 479, 582, 965, 585, 1144, 583, 581, 584, 965, 581, + 479, 479, 479, 581, 479, 1010, 795, 795, 582, 1536, + 585, 582, 583, 585, 584, 583, 818, 584, 1004, 818, + 1535, 585, 586, 582, 587, 818, 818, 584, 479, 795, + 586, 909, 587, 640, 479, 795, 479, 553, 583, 553, + + 553, 553, 553, 553, 553, 553, 588, 586, 909, 587, + 586, 914, 587, 1396, 588, 1010, 640, 553, 586, 914, + 553, 931, 931, 640, 989, 909, 1396, 553, 818, 1002, + 1002, 588, 989, 587, 588, 640, 931, 1012, 1012, 553, + 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, + 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, + 560, 560, 560, 560, 560, 560, 560, 560, 560, 1534, + 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, + 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, + 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, + + 560, 560, 562, 1021, 1021, 589, 740, 1049, 740, 1040, + 562, 1049, 562, 589, 562, 562, 1477, 562, 562, 562, + 562, 562, 562, 562, 885, 740, 590, 562, 563, 892, + 589, 1040, 885, 589, 590, 740, 563, 892, 563, 1531, + 563, 563, 1477, 563, 563, 563, 563, 563, 563, 563, + 609, 590, 609, 563, 590, 609, 609, 609, 609, 609, + 609, 609, 618, 618, 618, 618, 618, 618, 618, 1033, + 1033, 1311, 590, 604, 1001, 604, 885, 1014, 604, 604, + 1311, 892, 1520, 604, 1033, 604, 604, 604, 604, 604, + 604, 604, 604, 604, 604, 1019, 1508, 604, 604, 604, + + 619, 619, 619, 619, 619, 619, 619, 672, 1300, 604, + 1001, 910, 613, 910, 613, 672, 604, 613, 613, 613, + 613, 613, 613, 613, 1001, 844, 1506, 1014, 604, 1300, + 910, 604, 672, 604, 605, 1007, 605, 672, 1023, 605, + 605, 1380, 910, 1380, 605, 1019, 605, 844, 605, 605, + 605, 605, 605, 605, 605, 605, 639, 1007, 605, 605, + 605, 638, 638, 638, 638, 638, 638, 638, 844, 844, + 605, 639, 639, 639, 639, 639, 639, 639, 639, 1007, + 1052, 641, 641, 641, 641, 641, 641, 641, 1023, 1066, + 1052, 911, 605, 1066, 605, 610, 970, 610, 778, 1055, + + 610, 610, 641, 1379, 1055, 610, 778, 610, 911, 610, + 642, 642, 642, 642, 642, 642, 642, 1495, 970, 610, + 610, 610, 1310, 778, 970, 911, 778, 644, 1379, 644, + 778, 642, 644, 644, 644, 644, 644, 644, 644, 648, + 970, 648, 850, 1310, 648, 648, 648, 648, 648, 648, + 648, 1056, 1056, 610, 1386, 610, 620, 1388, 620, 770, + 1494, 620, 620, 1388, 850, 620, 620, 770, 620, 1386, + 620, 620, 620, 620, 620, 620, 620, 620, 1064, 1064, + 620, 620, 620, 1493, 770, 850, 850, 770, 620, 620, + 620, 620, 620, 620, 1009, 1011, 770, 1104, 1104, 620, + + 650, 650, 650, 650, 650, 650, 650, 651, 651, 651, + 651, 651, 651, 651, 620, 1593, 620, 656, 656, 656, + 656, 656, 656, 656, 657, 657, 1065, 657, 657, 657, + 1009, 1011, 657, 1065, 657, 1593, 657, 657, 657, 657, + 657, 657, 657, 657, 1009, 1011, 657, 657, 657, 748, + 748, 748, 748, 748, 748, 748, 1085, 657, 682, 1129, + 1125, 1382, 657, 1382, 1085, 739, 1398, 739, 1125, 657, + 684, 657, 1398, 682, 682, 682, 682, 682, 682, 682, + 657, 1129, 657, 659, 739, 684, 684, 684, 684, 684, + 684, 684, 1492, 659, 682, 659, 659, 1016, 659, 659, + + 659, 659, 659, 659, 659, 663, 684, 739, 749, 749, + 749, 749, 749, 749, 749, 663, 1142, 663, 663, 1016, + 663, 663, 663, 663, 663, 663, 663, 667, 1143, 1480, + 751, 1074, 1384, 1074, 1384, 856, 1143, 667, 1142, 667, + 667, 1016, 667, 667, 667, 667, 667, 667, 667, 670, + 1074, 670, 670, 751, 670, 670, 670, 856, 1018, 670, + 751, 670, 1392, 670, 670, 670, 670, 670, 670, 670, + 670, 670, 751, 670, 670, 670, 1467, 1163, 856, 856, + 1297, 670, 670, 670, 670, 670, 670, 1392, 670, 670, + 1297, 942, 670, 1071, 1018, 686, 670, 686, 670, 1163, + + 686, 686, 686, 686, 686, 686, 686, 670, 1018, 670, + 671, 1465, 671, 671, 942, 671, 671, 671, 1071, 1020, + 671, 942, 671, 1071, 671, 752, 752, 752, 752, 752, + 752, 752, 671, 942, 671, 671, 671, 765, 765, 765, + 765, 765, 765, 765, 1298, 671, 752, 1473, 1464, 671, + 671, 1393, 765, 1393, 1298, 1020, 746, 671, 746, 671, + 1473, 746, 746, 746, 746, 746, 746, 746, 671, 1020, + 671, 678, 678, 678, 678, 678, 678, 678, 678, 678, + 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, + 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, + + 1463, 678, 678, 678, 678, 678, 678, 678, 678, 678, + 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, + 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, + 678, 678, 678, 681, 753, 753, 753, 753, 753, 753, + 753, 1381, 1090, 1090, 1097, 1097, 681, 1462, 681, 681, + 681, 681, 681, 681, 681, 753, 755, 1090, 755, 1097, + 1381, 755, 755, 755, 755, 755, 755, 755, 1026, 681, + 1165, 1165, 1172, 1172, 1227, 764, 681, 764, 764, 764, + 764, 764, 764, 764, 1404, 1165, 1072, 1172, 681, 689, + 1026, 689, 764, 1404, 689, 689, 1227, 689, 1395, 689, + + 1395, 689, 771, 689, 771, 771, 771, 771, 771, 771, + 771, 1072, 1026, 689, 689, 689, 1072, 689, 772, 772, + 772, 772, 772, 772, 772, 810, 1387, 810, 1680, 689, + 810, 810, 810, 810, 810, 810, 810, 1680, 777, 1117, + 1069, 1387, 1397, 779, 1397, 780, 777, 689, 1069, 689, + 690, 779, 690, 780, 1069, 690, 690, 781, 690, 1132, + 690, 1117, 690, 777, 690, 781, 777, 1117, 779, 782, + 780, 779, 1057, 780, 690, 690, 690, 782, 690, 779, + 1057, 1132, 781, 1223, 783, 781, 1394, 1132, 786, 781, + 777, 1223, 783, 690, 782, 780, 786, 782, 812, 812, + + 812, 812, 812, 812, 812, 1394, 1201, 1461, 690, 783, + 690, 717, 783, 786, 1469, 1201, 786, 1201, 1469, 717, + 782, 717, 1057, 717, 717, 1354, 717, 717, 717, 717, + 717, 717, 717, 1354, 1201, 783, 717, 733, 733, 733, + 733, 733, 733, 733, 733, 733, 733, 733, 733, 733, + 733, 733, 733, 733, 733, 733, 733, 733, 733, 733, + 733, 733, 733, 733, 733, 733, 1460, 733, 733, 733, + 733, 733, 733, 733, 733, 733, 733, 733, 733, 733, + 733, 733, 733, 733, 733, 733, 733, 733, 733, 733, + 733, 733, 733, 733, 733, 733, 733, 733, 733, 762, + + 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, + 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, + 762, 762, 762, 762, 762, 762, 762, 762, 1459, 762, + 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, + 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, + 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, + 762, 766, 785, 766, 766, 766, 766, 766, 766, 766, + 785, 793, 794, 794, 1213, 1213, 1294, 1475, 766, 793, + 794, 766, 1475, 1257, 766, 1272, 1272, 785, 1307, 1213, + 785, 766, 1294, 1294, 785, 794, 793, 794, 1307, 793, + + 1272, 794, 1443, 766, 768, 768, 768, 768, 768, 768, + 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, + 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, + 768, 768, 768, 1257, 768, 768, 768, 768, 768, 768, + 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, + 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, + 768, 768, 768, 768, 768, 768, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 773, 784, + 773, 773, 773, 773, 773, 773, 773, 784, 787, 788, + 1146, 1260, 915, 915, 789, 1263, 787, 788, 773, 1308, + 915, 773, 789, 790, 784, 1146, 1146, 784, 773, 1308, + 791, 790, 1439, 787, 788, 915, 787, 788, 791, 789, + 773, 915, 789, 916, 916, 792, 796, 1390, 790, 784, + 1403, 790, 788, 792, 796, 791, 1358, 790, 791, 787, + 1146, 1260, 1401, 789, 1390, 1263, 916, 1403, 1401, 941, + + 792, 796, 916, 792, 796, 1197, 791, 941, 1358, 792, + 813, 813, 813, 813, 813, 813, 813, 815, 815, 815, + 815, 815, 815, 815, 941, 796, 811, 941, 811, 951, + 1197, 811, 811, 1437, 1466, 1197, 811, 951, 811, 941, + 811, 811, 811, 832, 832, 832, 832, 832, 832, 832, + 811, 811, 811, 830, 951, 830, 1466, 951, 830, 830, + 830, 830, 830, 830, 830, 833, 833, 833, 833, 833, + 833, 833, 835, 835, 835, 835, 835, 835, 835, 951, + 1391, 1076, 1427, 1076, 811, 1474, 811, 814, 1230, 814, + 955, 1474, 814, 814, 1399, 1391, 1416, 814, 955, 814, + + 1076, 814, 814, 814, 814, 814, 814, 814, 814, 1399, + 1230, 814, 814, 814, 1400, 955, 1230, 1076, 955, 814, + 814, 814, 814, 814, 814, 1410, 955, 964, 964, 1400, + 814, 836, 836, 836, 836, 836, 836, 836, 841, 841, + 841, 841, 841, 841, 841, 814, 1458, 814, 816, 1482, + 964, 816, 1479, 1482, 1458, 1471, 964, 816, 816, 816, + 816, 816, 816, 816, 840, 1471, 840, 840, 840, 840, + 840, 840, 840, 846, 1479, 846, 846, 846, 846, 846, + 846, 846, 847, 847, 847, 847, 847, 847, 847, 852, + 1496, 852, 852, 852, 852, 852, 852, 852, 1496, 1486, + + 816, 839, 853, 853, 853, 853, 853, 853, 853, 1236, + 1488, 839, 1486, 839, 839, 1488, 839, 839, 839, 839, + 839, 839, 839, 842, 858, 858, 858, 858, 858, 858, + 858, 1236, 968, 968, 971, 971, 842, 1236, 842, 842, + 842, 842, 842, 842, 842, 864, 959, 864, 864, 864, + 864, 864, 864, 864, 959, 968, 842, 971, 1292, 842, + 1292, 968, 864, 971, 963, 963, 842, 1544, 1292, 1544, + 1292, 959, 963, 842, 959, 870, 1149, 870, 842, 843, + 870, 870, 870, 870, 870, 870, 870, 963, 1555, 963, + 1555, 1377, 843, 963, 843, 843, 843, 843, 843, 843, + + 843, 865, 865, 865, 865, 865, 865, 865, 872, 872, + 872, 872, 872, 872, 872, 843, 865, 873, 1389, 1149, + 1538, 1487, 843, 1376, 1468, 1538, 1149, 1487, 1389, 843, + 845, 1389, 873, 873, 873, 873, 873, 873, 873, 1468, + 845, 1154, 845, 845, 1304, 845, 845, 845, 845, 845, + 845, 845, 848, 918, 918, 918, 918, 918, 918, 918, + 1304, 1304, 1077, 1375, 1077, 848, 1545, 848, 848, 848, + 848, 848, 848, 848, 919, 919, 919, 919, 919, 919, + 919, 1077, 1470, 1472, 1154, 848, 1295, 1545, 848, 1077, + 1374, 1154, 972, 966, 966, 848, 1295, 1470, 1472, 1600, + + 972, 966, 848, 1295, 921, 1159, 921, 848, 849, 921, + 921, 921, 921, 921, 921, 921, 966, 972, 966, 1600, + 972, 849, 966, 849, 849, 849, 849, 849, 849, 849, + 923, 923, 923, 923, 923, 923, 923, 924, 924, 924, + 924, 924, 924, 924, 849, 952, 1478, 1484, 1159, 1540, + 1590, 849, 1590, 952, 1540, 1159, 1478, 1484, 849, 851, + 960, 943, 943, 943, 943, 943, 943, 943, 960, 851, + 952, 851, 851, 952, 851, 851, 851, 851, 851, 851, + 851, 854, 943, 1491, 1373, 960, 1199, 1602, 960, 1082, + 1082, 1027, 960, 1491, 854, 952, 854, 854, 854, 854, + + 854, 854, 854, 1602, 929, 929, 929, 929, 929, 929, + 929, 1199, 1082, 1027, 854, 1537, 1199, 854, 1082, 929, + 1539, 953, 1542, 1589, 854, 929, 1027, 1542, 1537, 953, + 1027, 854, 1075, 1539, 1075, 1027, 854, 855, 944, 944, + 944, 944, 944, 944, 944, 1589, 953, 1084, 1084, 953, + 855, 1075, 855, 855, 855, 855, 855, 855, 855, 944, + 930, 930, 930, 930, 930, 930, 930, 953, 1305, 1372, + 1084, 954, 1543, 855, 1075, 930, 1084, 1543, 1305, 954, + 855, 930, 1476, 1371, 946, 1305, 946, 855, 857, 946, + 946, 946, 946, 946, 946, 946, 954, 1476, 857, 954, + + 857, 1556, 1370, 857, 857, 857, 857, 857, 857, 857, + 857, 954, 935, 1546, 935, 935, 935, 935, 935, 935, + 935, 1546, 1556, 857, 1296, 1369, 1402, 857, 859, 935, + 859, 859, 1368, 859, 859, 859, 1402, 1296, 859, 1402, + 859, 1296, 859, 859, 859, 859, 859, 859, 859, 859, + 859, 1245, 859, 859, 859, 1120, 1120, 1306, 1081, 1081, + 859, 859, 859, 859, 859, 859, 1081, 859, 859, 1367, + 1306, 859, 859, 1245, 1306, 859, 1547, 859, 1120, 1245, + 1549, 1081, 1547, 859, 1120, 1549, 859, 1081, 859, 861, + 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, + + 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, + 861, 861, 861, 861, 861, 861, 861, 861, 1366, 861, + 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, + 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, + 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, + 861, 866, 1490, 866, 866, 866, 866, 866, 866, 866, + 936, 936, 936, 936, 936, 936, 936, 1302, 866, 1302, + 1596, 866, 1541, 1552, 866, 936, 1481, 1302, 1490, 1302, + 1365, 866, 984, 984, 984, 984, 984, 984, 984, 1541, + 1552, 1481, 1596, 866, 868, 868, 868, 868, 868, 868, + + 868, 868, 868, 868, 868, 868, 868, 868, 868, 868, + 868, 868, 868, 868, 868, 868, 868, 868, 868, 868, + 868, 868, 868, 1350, 868, 868, 868, 868, 868, 868, + 868, 868, 868, 868, 868, 868, 868, 868, 868, 868, + 868, 868, 868, 868, 868, 868, 868, 868, 868, 868, + 868, 868, 868, 868, 868, 868, 869, 869, 869, 869, + 869, 869, 869, 869, 869, 869, 869, 869, 869, 869, + 869, 869, 869, 869, 869, 869, 869, 869, 869, 869, + 869, 869, 869, 869, 869, 869, 869, 869, 869, 869, + 869, 869, 869, 869, 869, 869, 869, 869, 869, 869, + + 869, 869, 869, 869, 869, 869, 869, 869, 869, 869, + 869, 869, 869, 869, 869, 869, 869, 869, 875, 1483, + 875, 1485, 1548, 875, 875, 958, 875, 1550, 875, 961, + 875, 962, 875, 958, 1483, 1548, 1485, 961, 1339, 962, + 1550, 1622, 875, 875, 875, 1489, 875, 1062, 1062, 1062, + 958, 1062, 1062, 958, 961, 875, 962, 961, 1062, 962, + 1489, 1622, 1062, 1062, 1312, 958, 994, 994, 994, 994, + 994, 994, 994, 1312, 961, 1312, 875, 1321, 875, 876, + 1319, 876, 962, 1551, 876, 876, 1151, 876, 1551, 876, + 1646, 876, 1312, 876, 995, 995, 995, 995, 995, 995, + + 995, 1151, 1151, 876, 876, 876, 1003, 876, 1003, 1123, + 1123, 1003, 1003, 1003, 1003, 1003, 1003, 1003, 1013, 1234, + 1013, 1646, 1614, 1013, 1013, 1013, 1013, 1013, 1013, 1013, + 1156, 876, 1123, 1234, 1234, 1314, 1151, 876, 1123, 876, + 903, 1234, 903, 1553, 1614, 1156, 1156, 1234, 1553, 1022, + 903, 1022, 903, 1326, 1022, 1022, 1022, 1022, 1022, 1022, + 1022, 1290, 1557, 1031, 1031, 1031, 1031, 1031, 1031, 1031, + 1557, 1624, 903, 903, 903, 1326, 903, 903, 1031, 1558, + 1156, 1326, 1289, 903, 1031, 1558, 1624, 903, 903, 906, + 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, + + 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, + 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, + 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, + 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, + 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, + 906, 928, 1110, 928, 928, 928, 928, 928, 928, 928, + 1110, 1032, 1032, 1032, 1032, 1032, 1032, 1032, 928, 1122, + 1554, 1592, 1591, 1592, 928, 1554, 1032, 1110, 1591, 1288, + 1110, 928, 1032, 1038, 1038, 1038, 1038, 1038, 1038, 1038, + 1594, 1122, 1594, 928, 932, 1287, 932, 1122, 1038, 932, + + 932, 932, 932, 932, 932, 932, 1043, 1043, 1043, 1043, + 1043, 1043, 1043, 1122, 932, 934, 934, 934, 934, 934, + 934, 934, 1086, 1086, 1086, 1086, 1086, 1086, 1086, 1286, + 934, 1102, 934, 934, 934, 934, 934, 934, 937, 1102, + 937, 937, 937, 937, 937, 937, 937, 1087, 1087, 1087, + 1087, 1087, 1087, 1087, 1044, 937, 1102, 1598, 937, 1102, + 1597, 937, 1597, 1598, 1599, 1285, 1599, 1102, 937, 1044, + 1044, 1044, 1044, 1044, 1044, 1044, 1601, 1284, 1601, 1283, + 937, 939, 939, 939, 939, 939, 939, 939, 939, 939, + 939, 939, 939, 939, 939, 939, 939, 939, 939, 939, + + 939, 939, 939, 939, 939, 939, 939, 939, 939, 939, + 939, 939, 939, 939, 939, 939, 939, 939, 939, 939, + 939, 939, 939, 939, 939, 939, 939, 939, 939, 939, + 939, 939, 939, 939, 939, 939, 939, 939, 939, 939, + 939, 939, 939, 940, 940, 940, 940, 940, 940, 940, + 940, 940, 940, 940, 940, 940, 940, 940, 940, 940, + 940, 940, 940, 940, 940, 940, 940, 940, 940, 940, + 940, 940, 940, 940, 940, 940, 940, 940, 940, 940, + 940, 940, 940, 940, 940, 940, 940, 940, 940, 940, + 940, 940, 940, 940, 940, 940, 940, 940, 940, 940, + + 940, 940, 940, 940, 940, 956, 1083, 1083, 1112, 1134, + 1134, 1205, 1205, 956, 1083, 956, 1112, 956, 956, 1205, + 956, 956, 956, 956, 956, 956, 956, 1282, 1281, 1083, + 956, 957, 1134, 1112, 1205, 1083, 1112, 1610, 1134, 957, + 1205, 957, 1112, 957, 957, 1610, 957, 957, 957, 957, + 957, 957, 957, 1280, 1278, 1277, 957, 969, 969, 969, + 969, 969, 969, 969, 969, 969, 969, 969, 969, 969, + 969, 969, 969, 969, 969, 969, 969, 969, 969, 969, + 969, 969, 969, 969, 969, 969, 969, 969, 969, 969, + 969, 969, 969, 969, 969, 969, 969, 969, 969, 969, + + 969, 969, 969, 969, 969, 969, 969, 969, 969, 969, + 969, 969, 969, 969, 969, 969, 969, 969, 969, 985, + 1623, 985, 1625, 1686, 985, 985, 1623, 1276, 1405, 985, + 1275, 985, 1686, 985, 985, 985, 985, 985, 985, 985, + 985, 1270, 1625, 985, 985, 985, 1037, 1244, 1037, 1037, + 1037, 1037, 1037, 1037, 1037, 1091, 1091, 1091, 1091, 1091, + 1091, 1091, 1405, 1037, 1118, 1118, 1627, 1626, 1405, 1244, + 1091, 1405, 1118, 1626, 1244, 1244, 1244, 985, 1405, 985, + 986, 1627, 986, 1264, 1254, 986, 986, 1118, 1253, 1118, + 986, 1252, 986, 1118, 986, 1092, 1092, 1092, 1092, 1092, + + 1092, 1092, 1206, 1206, 986, 986, 986, 1208, 1208, 1231, + 1092, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1096, 1096, + 1096, 1096, 1096, 1096, 1096, 1206, 1095, 1299, 1216, 1299, + 1208, 1206, 1095, 1096, 1211, 1204, 1208, 1299, 986, 1096, + 986, 998, 1103, 1299, 1103, 1196, 1194, 1103, 1103, 1103, + 1103, 1103, 1103, 1103, 998, 1193, 998, 998, 998, 998, + 998, 998, 998, 1105, 1105, 1105, 1105, 1105, 1105, 1105, + 1106, 1106, 1106, 1106, 1106, 1106, 1106, 998, 1111, 1221, + 1115, 1192, 1191, 1309, 998, 1309, 1111, 1221, 1115, 1190, + 1189, 998, 1188, 1309, 1114, 1187, 998, 1008, 1186, 1309, + + 1185, 1116, 1114, 1111, 1221, 1115, 1111, 1221, 1115, 1116, + 1008, 1184, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1114, + 1248, 1248, 1114, 1115, 1183, 1221, 1116, 1111, 1114, 1116, + 1217, 1133, 1133, 1008, 1207, 1207, 1411, 1202, 1217, 1133, + 1008, 1116, 1207, 1248, 1411, 1698, 1202, 1008, 1202, 1248, + 1698, 1698, 1008, 1017, 1133, 1217, 1133, 1207, 1217, 1182, + 1133, 1411, 1181, 1207, 1411, 1202, 1017, 1203, 1017, 1017, + 1017, 1017, 1017, 1017, 1017, 1145, 1203, 1145, 1203, 1217, + 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1705, 1202, 1017, + 1407, 1180, 1705, 1705, 1179, 1203, 1017, 1174, 1141, 1407, + + 1709, 1407, 1203, 1017, 1140, 1709, 1709, 1139, 1017, 1028, + 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1138, 1407, 1028, + 1137, 1028, 1028, 1136, 1028, 1028, 1028, 1028, 1028, 1028, + 1028, 1029, 1135, 1029, 1029, 1407, 1029, 1029, 1029, 1109, + 1108, 1029, 1107, 1029, 1099, 1029, 1152, 1152, 1152, 1152, + 1152, 1152, 1152, 1029, 1080, 1029, 1029, 1029, 1157, 1157, + 1157, 1157, 1157, 1157, 1157, 1070, 1029, 1148, 1726, 1068, + 1029, 1029, 1067, 1726, 1726, 1029, 1063, 1060, 1029, 1059, + 1029, 1058, 1148, 1148, 1148, 1148, 1148, 1148, 1148, 1029, + 1053, 1029, 1030, 1048, 1030, 1030, 1030, 1030, 1030, 1030, + + 1030, 1166, 1166, 1166, 1166, 1166, 1166, 1166, 1250, 1030, + 1251, 1251, 1045, 1035, 997, 1030, 1166, 1148, 1150, 983, + 1150, 982, 1030, 1150, 1150, 1150, 1150, 1150, 1150, 1150, + 1250, 981, 980, 1251, 1030, 1034, 1250, 1034, 979, 1251, + 1034, 1034, 1034, 1034, 1034, 1034, 1034, 978, 1153, 977, + 976, 975, 1250, 974, 973, 1034, 1036, 1036, 1036, 1036, + 1036, 1036, 1036, 1153, 1153, 1153, 1153, 1153, 1153, 1153, + 950, 1036, 1320, 1036, 1036, 1036, 1036, 1036, 1036, 1039, + 1320, 1039, 1039, 1039, 1039, 1039, 1039, 1039, 1167, 1167, + 1167, 1167, 1167, 1167, 1167, 949, 1039, 1320, 1153, 1039, + + 1320, 933, 1039, 1167, 927, 1155, 926, 1155, 925, 1039, + 1155, 1155, 1155, 1155, 1155, 1155, 1155, 1320, 917, 913, + 904, 1039, 1041, 1041, 1041, 1041, 1041, 1041, 1041, 1041, + 1041, 1041, 1041, 1041, 1041, 1041, 1041, 1041, 1041, 1041, + 1041, 1041, 1041, 1041, 1041, 1041, 1041, 1041, 1041, 1041, + 1041, 1041, 1041, 1041, 1041, 1041, 1041, 1041, 1041, 1041, + 1041, 1041, 1041, 1041, 1041, 1041, 1041, 1041, 1041, 1041, + 1041, 1041, 1041, 1041, 1041, 1041, 1041, 1041, 1041, 1041, + 1041, 1041, 1041, 1041, 1042, 1042, 1042, 1042, 1042, 1042, + 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, + + 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, + 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, + 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, + 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, + 1042, 1042, 1042, 1042, 1042, 1042, 1046, 1158, 1046, 901, + 900, 1046, 1046, 899, 1046, 898, 1046, 897, 1046, 896, + 1046, 1265, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 895, + 1046, 1046, 1046, 1161, 1046, 1161, 1161, 1161, 1161, 1161, + 1161, 1161, 894, 1265, 860, 834, 1046, 1170, 1170, 1170, + 1170, 1170, 1170, 1170, 1733, 809, 808, 1158, 807, 1733, + + 1733, 806, 1170, 805, 1046, 1265, 1046, 1047, 1170, 1047, + 804, 1265, 1047, 1047, 1266, 1047, 803, 1047, 802, 1047, + 801, 1047, 1171, 1171, 1171, 1171, 1171, 1171, 1171, 800, + 799, 1047, 1047, 1047, 1345, 1047, 1266, 1171, 1324, 797, + 1316, 1316, 775, 1171, 1209, 1209, 1209, 1209, 1209, 1209, + 1209, 761, 1324, 1324, 760, 759, 1345, 1047, 1266, 1209, + 1324, 758, 1345, 1316, 1266, 1047, 1324, 1047, 1061, 1316, + 1061, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1061, 750, + 1061, 745, 743, 742, 741, 1334, 1210, 732, 1214, 1214, + 1214, 1214, 1214, 1214, 1214, 729, 728, 727, 726, 725, + + 1061, 1061, 1061, 1214, 1061, 1061, 724, 1334, 723, 722, + 721, 1061, 1334, 1334, 1334, 1061, 1061, 1073, 1073, 1073, + 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, + 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, + 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, + 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, + 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, + 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1078, + 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1078, 720, 1078, + 719, 1078, 1078, 714, 1078, 1078, 1078, 1078, 1078, 1078, + + 1078, 1079, 1219, 1219, 1219, 1219, 1219, 1219, 1219, 1079, + 693, 1079, 687, 1079, 1079, 683, 1079, 1079, 1079, 1079, + 1079, 1079, 1079, 1089, 676, 1089, 674, 653, 1089, 1089, + 1089, 1089, 1089, 1089, 1089, 652, 1215, 1215, 1215, 1215, + 1215, 1215, 1215, 1089, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1215, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1093, + 1348, 1093, 1093, 1093, 1093, 1093, 1093, 626, 624, 623, + 1361, 1336, 1093, 1094, 622, 1094, 1094, 1094, 1094, 1094, + 1094, 1094, 1348, 1246, 1246, 1336, 1336, 1348, 1348, 1348, + 1094, 1246, 1361, 1336, 621, 1742, 1094, 616, 1361, 1336, + + 1742, 1742, 615, 1094, 1748, 612, 1246, 607, 1246, 1748, + 1748, 606, 1246, 603, 1755, 1094, 1098, 601, 1098, 1755, + 1755, 1098, 1098, 1098, 1098, 1098, 1098, 1098, 1258, 1258, + 1258, 1258, 1258, 1258, 1258, 600, 1098, 1100, 1100, 1100, + 1100, 1100, 1100, 1100, 1261, 1261, 1261, 1261, 1261, 1261, + 1261, 599, 1100, 598, 1100, 1100, 1100, 1100, 1100, 1100, + 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, + 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, + 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, + 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, + + 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, + 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, + 1101, 1101, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, + 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, + 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, + 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, + 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, + 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, + 1121, 1121, 1121, 1121, 1124, 1124, 1124, 1124, 1124, 1124, + 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, + + 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, + 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, + 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, + 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, + 1124, 1124, 1124, 1124, 1124, 1124, 1126, 1315, 1315, 597, + 1349, 1760, 596, 595, 594, 1315, 1760, 1760, 1126, 593, + 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1256, 1126, 592, + 1315, 591, 1349, 559, 1126, 1127, 1315, 1349, 1349, 1349, + 1422, 557, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1127, + 1127, 1127, 1127, 1127, 1127, 1127, 556, 1127, 555, 540, + + 1313, 539, 1422, 1127, 1128, 538, 537, 1432, 1422, 1313, + 527, 1313, 512, 511, 508, 481, 1128, 1256, 1128, 1128, + 1128, 1128, 1128, 1128, 1128, 1352, 1128, 1343, 1313, 1432, + 470, 469, 1128, 468, 1313, 1432, 1128, 466, 460, 1128, + 1313, 1343, 1343, 1313, 455, 415, 1128, 1352, 414, 1343, + 1313, 1762, 1352, 1352, 1352, 1343, 1762, 1762, 1128, 1130, + 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, + 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, + 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, + 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, + + 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, + 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, + 1130, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, + 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, + 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, + 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, + 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, + 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, + 1131, 1131, 1131, 1160, 1763, 413, 412, 411, 405, 1763, + 1763, 403, 1259, 1160, 401, 1160, 1160, 399, 1160, 1160, + + 1160, 1160, 1160, 1160, 1160, 1162, 391, 1259, 1259, 1259, + 1259, 1259, 1259, 1259, 1262, 1362, 389, 1425, 1162, 388, + 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1448, 1262, + 1262, 1262, 1262, 1262, 1262, 1262, 384, 1362, 1162, 1425, + 352, 1162, 1259, 351, 1425, 1425, 1425, 1764, 1162, 1162, + 1448, 344, 1764, 1764, 343, 1162, 1448, 342, 1362, 1362, + 1162, 1164, 341, 1164, 1262, 1362, 1164, 1164, 1164, 1164, + 1164, 1164, 1164, 336, 1268, 1268, 1268, 1268, 1268, 1268, + 1268, 1164, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1268, + 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1168, 335, 1168, + + 1168, 1168, 1168, 1168, 1168, 1269, 334, 333, 1457, 1501, + 1168, 1169, 332, 1169, 1169, 1169, 1169, 1169, 1169, 1169, + 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1406, 1169, 324, + 1457, 1501, 321, 319, 1169, 1273, 1406, 1501, 1406, 318, + 317, 1169, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 316, + 315, 314, 1457, 1169, 1173, 1406, 1173, 1274, 1457, 1173, + 1173, 1173, 1173, 1173, 1173, 1173, 1406, 1317, 1317, 1317, + 1317, 1317, 1317, 1317, 1173, 1175, 1175, 1175, 1175, 1175, + 1175, 1175, 1317, 1765, 313, 312, 311, 310, 1765, 1765, + 1175, 309, 1175, 1175, 1175, 1175, 1175, 1175, 1176, 1176, + + 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, + 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, + 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, + 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, + 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, + 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1176, + 1177, 307, 1177, 306, 302, 1177, 1177, 1514, 1177, 1526, + 1177, 1351, 1177, 301, 1177, 1318, 1318, 1318, 1318, 1318, + 1318, 1318, 300, 1409, 1177, 1177, 1177, 299, 1177, 1514, + 1318, 1526, 1409, 1351, 1409, 1514, 1177, 1526, 1351, 1351, + + 1351, 1363, 1363, 1363, 1363, 1363, 1363, 1363, 1767, 298, + 297, 1409, 295, 1767, 1767, 1351, 1363, 294, 1177, 1775, + 1177, 1178, 1409, 1178, 1775, 1775, 1178, 1178, 1426, 1178, + 293, 1178, 292, 1178, 291, 1178, 1364, 1364, 1364, 1364, + 1364, 1364, 1364, 1408, 1413, 1178, 1178, 1178, 1420, 1178, + 1426, 1364, 1408, 290, 1408, 1426, 1426, 1426, 1413, 1413, + 289, 288, 1420, 1420, 1498, 1498, 1413, 287, 285, 1428, + 1420, 1408, 1413, 1429, 284, 283, 1420, 1565, 282, 1178, + 1800, 1178, 1198, 281, 1198, 1800, 1800, 1498, 280, 1408, + 279, 1428, 1198, 1498, 1198, 1429, 1428, 1428, 1428, 1565, + + 1429, 1429, 1429, 1807, 278, 1565, 1434, 277, 1807, 1807, + 1438, 276, 1198, 1428, 1198, 1198, 1198, 275, 1198, 1198, + 1434, 1434, 1440, 1564, 1564, 1198, 1441, 274, 1434, 1198, + 1198, 1200, 1438, 1200, 1434, 273, 269, 1438, 1438, 1438, + 268, 1200, 263, 1200, 1440, 261, 1564, 1574, 1441, 1440, + 1440, 1440, 1564, 1441, 1441, 1441, 259, 258, 257, 246, + 243, 1200, 241, 1200, 1200, 1200, 1440, 1200, 1200, 1574, + 1442, 1809, 238, 234, 1200, 1574, 1809, 1809, 1200, 1200, + 1212, 1446, 1212, 1456, 212, 1212, 1212, 1212, 1212, 1212, + 1212, 1212, 1442, 201, 200, 1446, 1446, 1442, 1442, 1442, + + 1212, 1224, 1811, 1446, 162, 1456, 1507, 1811, 1811, 1446, + 1456, 1456, 1456, 1224, 1510, 1224, 1224, 1224, 1224, 1224, + 1224, 1224, 156, 1224, 155, 148, 147, 146, 1507, 1224, + 1225, 1497, 1497, 1507, 1507, 1507, 1510, 144, 142, 1497, + 132, 1510, 1510, 1510, 1225, 1225, 1225, 1225, 1225, 1225, + 1225, 130, 1225, 129, 1497, 127, 1497, 1835, 1225, 1226, + 1497, 126, 1835, 1835, 122, 120, 1568, 1568, 1503, 119, + 1511, 1226, 116, 1226, 1226, 1226, 1226, 1226, 1226, 1226, + 1515, 1226, 1503, 1503, 1578, 110, 91, 1226, 90, 1568, + 1503, 1226, 1511, 88, 1226, 1568, 1503, 1511, 1511, 1511, + + 78, 1226, 1515, 70, 69, 67, 1578, 1515, 1515, 1515, + 57, 53, 1578, 1226, 1228, 1228, 1228, 1228, 1228, 1228, + 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, + 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, + 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, + 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, + 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, + 1228, 1228, 1228, 1228, 1228, 1228, 1229, 1229, 1229, 1229, + 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, + 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, + + 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, + 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, + 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, + 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1232, 36, + 1509, 35, 33, 24, 23, 20, 17, 1571, 1571, 1517, + 1617, 15, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1570, + 1232, 0, 1509, 1517, 1517, 0, 1232, 1509, 1509, 1509, + 1571, 1517, 1617, 1232, 1233, 0, 1571, 1517, 1617, 1529, + 0, 1570, 0, 1524, 1509, 0, 0, 1570, 1233, 1233, + 1233, 1233, 1233, 1233, 1233, 1620, 1233, 1524, 1524, 0, + + 0, 1529, 1233, 1570, 0, 1524, 1529, 1529, 1529, 1233, + 1235, 1524, 0, 1530, 1608, 1608, 0, 1620, 0, 1235, + 0, 1235, 1532, 1620, 1235, 1235, 1235, 1235, 1235, 1235, + 1235, 0, 1235, 0, 0, 1530, 0, 1608, 1235, 1237, + 1530, 1530, 1530, 1608, 1532, 0, 0, 0, 0, 1532, + 1532, 1532, 0, 1237, 1237, 1237, 1237, 1237, 1237, 1237, + 0, 1237, 0, 0, 0, 0, 1532, 1237, 0, 0, + 1237, 1237, 1237, 1237, 1237, 1237, 1238, 0, 0, 1533, + 0, 0, 0, 0, 0, 0, 0, 1575, 1238, 1636, + 1238, 1238, 1238, 1238, 1238, 1238, 1238, 0, 1238, 0, + + 0, 1533, 0, 0, 1238, 1239, 1533, 1533, 1533, 1575, + 0, 1636, 0, 0, 1575, 1575, 1575, 1636, 0, 1239, + 1239, 1239, 1239, 1239, 1239, 1239, 0, 1239, 1657, 0, + 1669, 0, 0, 1239, 1240, 0, 1240, 1240, 1240, 1240, + 1240, 1240, 1240, 1563, 1563, 1566, 1566, 1580, 0, 0, + 1657, 1563, 1669, 1566, 1240, 0, 1657, 1240, 1669, 0, + 0, 1580, 1580, 0, 1240, 1584, 1563, 0, 1566, 1580, + 1566, 0, 1563, 1684, 1566, 1580, 1240, 1241, 0, 1241, + 1241, 1241, 1241, 1241, 1241, 1241, 1587, 1584, 0, 1588, + 0, 0, 1584, 1584, 1584, 1684, 0, 1241, 0, 0, + + 1241, 1684, 0, 0, 0, 0, 0, 1241, 1587, 0, + 0, 1588, 0, 1587, 1587, 1587, 1588, 1588, 1588, 1241, + 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, + 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, + 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, + 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, + 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, + 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, + 1242, 1242, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, + 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, + + 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, + 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, + 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, + 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, + 1249, 1249, 1249, 1249, 1271, 1586, 1271, 0, 0, 1271, + 1271, 1271, 1271, 1271, 1271, 1271, 0, 0, 0, 0, + 0, 0, 0, 0, 1271, 1322, 0, 1586, 1607, 1607, + 0, 0, 1586, 1586, 1586, 0, 1607, 1621, 0, 1322, + 1322, 1322, 1322, 1322, 1322, 1322, 0, 1322, 0, 1586, + 0, 1607, 0, 1322, 0, 0, 0, 1607, 0, 1621, + + 1322, 1323, 0, 0, 1621, 1621, 1621, 0, 0, 0, + 1634, 0, 1644, 0, 0, 1323, 1323, 1323, 1323, 1323, + 1323, 1323, 0, 1323, 1634, 1634, 0, 0, 0, 1323, + 0, 0, 1634, 0, 1644, 0, 1323, 1325, 1634, 1644, + 1644, 1644, 0, 0, 0, 1660, 1325, 1648, 1325, 1655, + 0, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 0, 1325, + 0, 1648, 1648, 1655, 1655, 1325, 1327, 1660, 0, 1648, + 0, 1655, 1660, 1660, 1660, 1648, 0, 1655, 0, 0, + 1327, 1327, 1327, 1327, 1327, 1327, 1327, 0, 1327, 0, + 0, 0, 0, 0, 1327, 0, 0, 1327, 1327, 1327, + + 1327, 1327, 1327, 1328, 0, 0, 1661, 0, 0, 0, + 0, 0, 0, 0, 1663, 1328, 0, 1328, 1328, 1328, + 1328, 1328, 1328, 1328, 0, 1328, 0, 0, 1661, 0, + 0, 1328, 1329, 1661, 1661, 1661, 1663, 0, 0, 0, + 0, 1663, 1663, 1663, 0, 0, 1329, 1329, 1329, 1329, + 1329, 1329, 1329, 0, 1329, 0, 0, 1671, 1663, 0, + 1329, 1330, 0, 1330, 1330, 1330, 1330, 1330, 1330, 1330, + 1664, 1671, 1671, 1675, 0, 0, 0, 0, 0, 1671, + 0, 1330, 0, 0, 1330, 1671, 0, 0, 0, 0, + 0, 1330, 1664, 1677, 0, 1675, 0, 1664, 1664, 1664, + + 1675, 1675, 1675, 1330, 1331, 0, 1331, 1331, 1331, 1331, + 1331, 1331, 1331, 1678, 0, 1677, 1679, 0, 0, 0, + 1677, 1677, 1677, 0, 1331, 0, 0, 1331, 0, 0, + 0, 0, 0, 0, 1331, 1678, 0, 1677, 1679, 0, + 1678, 1678, 1678, 1679, 1679, 1679, 1331, 1332, 1332, 1332, + 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, + 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, + 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, + 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, + 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, + + 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1335, + 0, 0, 1685, 0, 0, 0, 0, 0, 1335, 0, + 1335, 0, 0, 1335, 1335, 1335, 1335, 1335, 1335, 1335, + 0, 1335, 0, 0, 1685, 0, 0, 1335, 1337, 1685, + 1685, 1685, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1337, 1337, 1337, 1337, 1337, 1337, 1337, 0, + 1337, 0, 0, 0, 0, 0, 1337, 1338, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1338, 1338, 1338, 1338, 1338, 1338, 1338, 0, 1338, + 0, 0, 0, 0, 0, 1338, 1340, 0, 1340, 1340, + + 1340, 1340, 1340, 1340, 1340, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1340, 0, 0, 1340, + 0, 0, 0, 0, 0, 0, 1340, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1340, 1341, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1341, 1341, 1341, 1341, 1341, 1341, 1341, + 0, 1341, 0, 0, 0, 0, 0, 1341, 0, 0, + 0, 0, 0, 0, 1341, 1342, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1342, + 1342, 1342, 1342, 1342, 1342, 1342, 0, 1342, 0, 0, + + 0, 0, 0, 1342, 0, 0, 0, 0, 0, 0, + 1342, 1344, 0, 0, 0, 0, 0, 0, 0, 0, + 1344, 0, 1344, 0, 0, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 0, 1344, 0, 0, 0, 0, 0, 1344, + 1346, 1346, 1346, 1346, 1346, 1346, 1346, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1346, 1346, 1346, + 1346, 1346, 1346, 1355, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1355, 0, 1355, 1355, 1355, + 1355, 1355, 1355, 1355, 0, 1355, 0, 0, 0, 0, + 0, 1355, 1356, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 1356, 1356, 1356, 1356, + 1356, 1356, 1356, 0, 1356, 0, 0, 0, 0, 0, + 1356, 1357, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1357, 0, 1357, 1357, 1357, 1357, 1357, + 1357, 1357, 0, 1357, 0, 0, 0, 0, 0, 1357, + 0, 0, 0, 1357, 0, 0, 1357, 0, 0, 0, + 0, 0, 0, 1357, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1357, 1359, 1359, 1359, 1359, + 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, + 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, + + 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, + 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, + 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, + 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1359, 1360, 1360, + 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, + 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, + 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, + 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, + 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, + 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, + + 1412, 0, 0, 0, 0, 0, 0, 0, 0, 1412, + 0, 1412, 0, 0, 1412, 1412, 1412, 1412, 1412, 1412, + 1412, 0, 1412, 0, 0, 0, 0, 0, 1412, 1414, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1414, 1414, 1414, 1414, 1414, 1414, 1414, + 0, 1414, 0, 0, 0, 0, 0, 1414, 1415, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1415, 1415, 1415, 1415, 1415, 1415, 1415, 0, + 1415, 0, 0, 0, 0, 0, 1415, 1417, 0, 1417, + 1417, 1417, 1417, 1417, 1417, 1417, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 1417, 0, 0, + 1417, 0, 0, 0, 0, 0, 0, 1417, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1417, + 1418, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1418, 1418, 1418, 1418, 1418, 1418, + 1418, 0, 1418, 0, 0, 0, 0, 0, 1418, 0, + 0, 0, 0, 0, 0, 1418, 1419, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1419, 1419, 1419, 1419, 1419, 1419, 1419, 0, 1419, 0, + 0, 0, 0, 0, 1419, 0, 0, 0, 0, 0, + + 0, 1419, 1421, 0, 0, 0, 0, 0, 0, 0, + 0, 1421, 0, 1421, 0, 0, 1421, 1421, 1421, 1421, + 1421, 1421, 1421, 0, 1421, 0, 0, 0, 0, 0, + 1421, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1423, 1423, + 1423, 1423, 1423, 1423, 1430, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1430, 1430, + 1430, 1430, 1430, 1430, 1430, 0, 1430, 0, 0, 0, + 0, 0, 1430, 1431, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1431, 1431, 1431, + + 1431, 1431, 1431, 1431, 0, 1431, 0, 0, 0, 0, + 0, 1431, 1433, 0, 0, 0, 0, 0, 0, 0, + 0, 1433, 0, 1433, 0, 0, 1433, 1433, 1433, 1433, + 1433, 1433, 1433, 0, 1433, 0, 0, 0, 0, 0, + 1433, 1435, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1435, 1435, 1435, 1435, 1435, + 1435, 1435, 0, 1435, 0, 0, 0, 0, 0, 1435, + 1436, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1436, 1436, 1436, 1436, 1436, 1436, + 1436, 0, 1436, 0, 0, 0, 0, 0, 1436, 1444, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1444, 1444, 1444, 1444, 1444, 1444, 1444, + 0, 1444, 0, 0, 0, 0, 0, 1444, 0, 0, + 0, 0, 0, 0, 1444, 1445, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1445, + 1445, 1445, 1445, 1445, 1445, 1445, 0, 1445, 0, 0, + 0, 0, 0, 1445, 0, 0, 0, 0, 0, 0, + 1445, 1447, 0, 0, 0, 0, 0, 0, 0, 0, + 1447, 0, 1447, 0, 0, 1447, 1447, 1447, 1447, 1447, + 1447, 1447, 0, 1447, 0, 0, 0, 0, 0, 1447, + + 1449, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1449, 1449, 1449, 1449, 1449, 1449, + 1449, 0, 1449, 0, 0, 0, 0, 0, 1449, 0, + 0, 1449, 1449, 1449, 1449, 1449, 1449, 1450, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1450, + 0, 1450, 1450, 1450, 1450, 1450, 1450, 1450, 0, 1450, + 0, 0, 0, 0, 0, 1450, 1451, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1451, 1451, 1451, 1451, 1451, 1451, 1451, 0, 1451, 0, + 0, 0, 0, 0, 1451, 1452, 0, 1452, 1452, 1452, + + 1452, 1452, 1452, 1452, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1452, 0, 0, 1452, 0, + 0, 0, 0, 0, 0, 1452, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1452, 1453, 0, + 1453, 1453, 1453, 1453, 1453, 1453, 1453, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1453, 0, + 0, 1453, 0, 0, 0, 0, 0, 0, 1453, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1453, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, + 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, + + 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, + 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, + 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, + 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, + 1454, 1454, 1454, 1499, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1499, 1499, 1499, + 1499, 1499, 1499, 1499, 0, 1499, 0, 0, 0, 0, + 0, 1499, 1500, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1500, 1500, 1500, 1500, + 1500, 1500, 1500, 0, 1500, 0, 0, 0, 0, 0, + + 1500, 1502, 0, 0, 0, 0, 0, 0, 0, 0, + 1502, 0, 1502, 0, 0, 1502, 1502, 1502, 1502, 1502, + 1502, 1502, 0, 1502, 0, 0, 0, 0, 0, 1502, + 1504, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1504, 1504, 1504, 1504, 1504, 1504, + 1504, 0, 1504, 0, 0, 0, 0, 0, 1504, 1505, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1505, 1505, 1505, 1505, 1505, 1505, 1505, + 0, 1505, 0, 0, 0, 0, 0, 1505, 1512, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 1512, 1512, 1512, 1512, 1512, 1512, 1512, 0, + 1512, 0, 0, 0, 0, 0, 1512, 1513, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 0, 1513, + 0, 0, 0, 0, 0, 1513, 1516, 0, 0, 0, + 0, 0, 0, 0, 0, 1516, 0, 1516, 0, 0, + 1516, 1516, 1516, 1516, 1516, 1516, 1516, 0, 1516, 0, + 0, 0, 0, 0, 1516, 1518, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1518, + 1518, 1518, 1518, 1518, 1518, 1518, 0, 1518, 0, 0, + + 0, 0, 0, 1518, 1519, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1519, 1519, + 1519, 1519, 1519, 1519, 1519, 0, 1519, 0, 0, 0, + 0, 0, 1519, 1521, 0, 1521, 1521, 1521, 1521, 1521, + 1521, 1521, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1521, 0, 0, 1521, 0, 0, 0, + 0, 0, 0, 1521, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1521, 1522, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1522, 1522, 1522, 1522, 1522, 1522, 1522, 0, 1522, 0, + + 0, 0, 0, 0, 1522, 0, 0, 0, 0, 0, + 0, 1522, 1523, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1523, 1523, 1523, 1523, + 1523, 1523, 1523, 0, 1523, 0, 0, 0, 0, 0, + 1523, 0, 0, 0, 0, 0, 0, 1523, 1525, 0, + 0, 0, 0, 0, 0, 0, 0, 1525, 0, 1525, + 0, 0, 1525, 1525, 1525, 1525, 1525, 1525, 1525, 0, + 1525, 0, 0, 0, 0, 0, 1525, 1527, 1527, 1527, + 1527, 1527, 1527, 1527, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1527, 1527, 1527, 1527, 1527, 1527, + + 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, + 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, + 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, + 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, + 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, + 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, 1569, + 1569, 1569, 1572, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1572, 1572, 1572, 1572, + 1572, 1572, 1572, 0, 1572, 0, 0, 0, 0, 0, + 1572, 1573, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 1573, 1573, 1573, 1573, 1573, + 1573, 1573, 0, 1573, 0, 0, 0, 0, 0, 1573, + 1576, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1576, 1576, 1576, 1576, 1576, 1576, + 1576, 0, 1576, 0, 0, 0, 0, 0, 1576, 1577, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1577, 1577, 1577, 1577, 1577, 1577, 1577, + 0, 1577, 0, 0, 0, 0, 0, 1577, 1579, 0, + 0, 0, 0, 0, 0, 0, 0, 1579, 0, 1579, + 0, 0, 1579, 1579, 1579, 1579, 1579, 1579, 1579, 0, + + 1579, 0, 0, 0, 0, 0, 1579, 1581, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1581, 1581, 1581, 1581, 1581, 1581, 1581, 0, 1581, + 0, 0, 0, 0, 0, 1581, 1582, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1582, 1582, 1582, 1582, 1582, 1582, 1582, 0, 1582, 0, + 0, 0, 0, 0, 1582, 1611, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1611, 0, 1611, + 1611, 1611, 1611, 1611, 1611, 1611, 0, 1611, 0, 0, + 0, 0, 0, 1611, 1612, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 1612, 1612, + 1612, 1612, 1612, 1612, 1612, 0, 1612, 0, 0, 0, + 0, 0, 1612, 1613, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1613, 0, 1613, 1613, 1613, + 1613, 1613, 1613, 1613, 0, 1613, 0, 0, 0, 0, + 0, 1613, 0, 0, 0, 1613, 0, 0, 1613, 0, + 0, 0, 0, 0, 0, 1613, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1613, 1615, 1615, + 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, + 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, + + 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, + 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, + 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, + 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, + 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, + 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, + 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, + 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, + 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, + 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, + + 1616, 1616, 1618, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1618, 1618, 1618, 1618, + 1618, 1618, 1618, 0, 1618, 0, 0, 0, 0, 0, + 1618, 1619, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1619, 1619, 1619, 1619, 1619, + 1619, 1619, 0, 1619, 0, 0, 0, 0, 0, 1619, + 1632, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1632, 1632, 1632, 1632, 1632, 1632, + 1632, 0, 1632, 0, 0, 0, 0, 0, 1632, 0, + 0, 0, 0, 0, 0, 1632, 1633, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1633, 1633, 1633, 1633, 1633, 1633, 1633, 0, 1633, 0, + 0, 0, 0, 0, 1633, 0, 0, 0, 0, 0, + 0, 1633, 1635, 0, 0, 0, 0, 0, 0, 0, + 0, 1635, 0, 1635, 0, 0, 1635, 1635, 1635, 1635, + 1635, 1635, 1635, 0, 1635, 0, 0, 0, 0, 0, + 1635, 1637, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1637, 1637, 1637, 1637, 1637, + 1637, 1637, 0, 1637, 0, 0, 0, 0, 0, 1637, + 0, 0, 1637, 1637, 1637, 1637, 1637, 1637, 1638, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1638, 0, 1638, 1638, 1638, 1638, 1638, 1638, 1638, 0, + 1638, 0, 0, 0, 0, 0, 1638, 1639, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 0, 1639, + 0, 0, 0, 0, 0, 1639, 1640, 0, 1640, 1640, + 1640, 1640, 1640, 1640, 1640, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1640, 0, 0, 1640, + 0, 0, 0, 0, 0, 0, 1640, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1640, 1641, + + 0, 1641, 1641, 1641, 1641, 1641, 1641, 1641, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1641, + 0, 0, 1641, 0, 0, 0, 0, 0, 0, 1641, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1641, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, + 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, + 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, + 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, + 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, + 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, + + 1642, 1642, 1642, 1642, 1647, 0, 0, 0, 0, 0, + 0, 0, 0, 1647, 0, 1647, 0, 0, 1647, 1647, + 1647, 1647, 1647, 1647, 1647, 0, 1647, 0, 0, 0, + 0, 0, 1647, 1649, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1649, 1649, 1649, + 1649, 1649, 1649, 1649, 0, 1649, 0, 0, 0, 0, + 0, 1649, 1650, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1650, 1650, 1650, 1650, + 1650, 1650, 1650, 0, 1650, 0, 0, 0, 0, 0, + 1650, 1652, 0, 1652, 1652, 1652, 1652, 1652, 1652, 1652, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1652, 0, 0, 1652, 0, 0, 0, 0, 0, + 0, 1652, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1652, 1653, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1653, 1653, + 1653, 1653, 1653, 1653, 1653, 0, 1653, 0, 0, 0, + 0, 0, 1653, 0, 0, 0, 0, 0, 0, 1653, + 1654, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1654, 1654, 1654, 1654, 1654, 1654, + 1654, 0, 1654, 0, 0, 0, 0, 0, 1654, 0, + + 0, 0, 0, 0, 0, 1654, 1656, 0, 0, 0, + 0, 0, 0, 0, 0, 1656, 0, 1656, 0, 0, + 1656, 1656, 1656, 1656, 1656, 1656, 1656, 0, 1656, 0, + 0, 0, 0, 0, 1656, 1658, 1658, 1658, 1658, 1658, + 1658, 1658, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1658, 1658, 1658, 1658, 1658, 1658, 1667, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 0, + 1667, 0, 0, 0, 0, 0, 1667, 1668, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 1668, 1668, 1668, 1668, 1668, 1668, 1668, 0, 1668, + 0, 0, 0, 0, 0, 1668, 1670, 0, 0, 0, + 0, 0, 0, 0, 0, 1670, 0, 1670, 0, 0, + 1670, 1670, 1670, 1670, 1670, 1670, 1670, 0, 1670, 0, + 0, 0, 0, 0, 1670, 1672, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1672, + 1672, 1672, 1672, 1672, 1672, 1672, 0, 1672, 0, 0, + 0, 0, 0, 1672, 1673, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1673, 1673, + 1673, 1673, 1673, 1673, 1673, 0, 1673, 0, 0, 0, + + 0, 0, 1673, 1682, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1682, 1682, 1682, + 1682, 1682, 1682, 1682, 0, 1682, 0, 0, 0, 0, + 0, 1682, 1683, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1683, 1683, 1683, 1683, + 1683, 1683, 1683, 0, 1683, 0, 0, 0, 0, 0, + 1683, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, + 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, 1688, + 1688, 1688, 1688, 1688, 1688, 1689, 1689, 1689, 1689, 1689, + 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, + + 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1689, 1690, + 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, + 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, 1690, + 1690, 1690, 1690, 1691, 1691, 1691, 1691, 1691, 1691, 1691, + 1692, 1692, 1692, 1692, 0, 0, 1692, 1692, 1692, 1692, + 1692, 1692, 1692, 1692, 0, 1692, 1693, 0, 0, 1693, + 0, 0, 0, 0, 0, 0, 1693, 0, 1693, 1693, + 1693, 1693, 1693, 1693, 1693, 1693, 1693, 0, 1693, 1694, + 1694, 1694, 1694, 0, 0, 1694, 1694, 1694, 1694, 1694, + 1694, 1694, 1694, 0, 1694, 1695, 0, 1695, 1695, 0, + + 1695, 0, 1695, 0, 1695, 1695, 0, 1695, 1695, 1695, + 1695, 1695, 1695, 1695, 1695, 1695, 0, 1695, 1696, 0, + 0, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696, 0, + 1696, 1697, 0, 0, 0, 1697, 0, 0, 1697, 1697, + 1697, 1697, 1697, 1697, 1697, 1697, 0, 1697, 1699, 1699, + 0, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, + 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, + 1699, 1699, 1700, 0, 0, 1700, 0, 1700, 0, 1700, + 1700, 0, 1700, 1700, 0, 0, 1700, 1700, 1700, 1700, + 1700, 1700, 1700, 1701, 1701, 1701, 1701, 1701, 1701, 1701, + + 1701, 1701, 1701, 1701, 1701, 1701, 1701, 0, 1701, 1701, + 1701, 1701, 1701, 1701, 1701, 1701, 1701, 1702, 1702, 1702, + 1702, 0, 0, 1702, 1702, 1702, 1702, 1702, 1702, 1702, + 1702, 0, 1702, 1703, 0, 0, 1703, 1703, 1703, 1703, + 1703, 1703, 1703, 1703, 0, 1703, 1704, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1704, 1704, 0, 0, + 0, 0, 1704, 1706, 0, 0, 0, 0, 1706, 0, + 1706, 0, 0, 1706, 1707, 0, 0, 0, 0, 1707, + 0, 1707, 0, 0, 1707, 1708, 0, 0, 0, 0, + 1708, 0, 1708, 0, 0, 1708, 1710, 1710, 1710, 1710, + + 0, 0, 1710, 1710, 1710, 1710, 1710, 1710, 1710, 1710, + 0, 1710, 1711, 1711, 0, 1711, 1711, 1711, 1711, 1711, + 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, + 1711, 1711, 1711, 1711, 1711, 1711, 1712, 0, 1712, 1712, + 0, 1712, 0, 1712, 0, 1712, 1712, 0, 1712, 1712, + 1712, 1712, 1712, 1712, 1712, 1712, 1712, 0, 1712, 1713, + 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, + 1713, 1713, 1713, 0, 1713, 1713, 1713, 1713, 1713, 1713, + 1713, 1713, 1713, 1714, 0, 0, 0, 0, 0, 0, + 1714, 0, 0, 1714, 1714, 1715, 0, 0, 1715, 1715, + + 1715, 1715, 1715, 1715, 1715, 1715, 0, 1715, 1716, 1716, + 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, 1716, + 1716, 1716, 0, 1716, 1716, 1716, 1716, 1716, 1716, 1716, + 1716, 1716, 1717, 1717, 1717, 1717, 1717, 1717, 1717, 1718, + 0, 0, 0, 1718, 0, 0, 1718, 1718, 1718, 1718, + 1718, 1718, 1718, 1718, 0, 1718, 1719, 1719, 1719, 1719, + 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, + 0, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, 1719, + 1720, 0, 0, 0, 0, 1720, 1720, 1720, 1721, 1721, + 0, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, + + 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, + 1721, 1721, 1722, 0, 1722, 1722, 0, 1722, 0, 0, + 0, 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1723, 0, + 0, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 0, + 1723, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1724, + 1724, 1724, 1724, 1724, 1724, 0, 1724, 1724, 1724, 1724, + 1724, 1724, 1724, 1724, 1724, 1725, 0, 0, 1725, 0, + 0, 0, 0, 0, 0, 1725, 0, 1725, 1725, 1725, + 1725, 1725, 1725, 1725, 1725, 1725, 0, 1725, 1727, 1727, + 1727, 1727, 0, 0, 1727, 1727, 1727, 1727, 1727, 1727, + + 1727, 1727, 0, 1727, 1728, 1728, 0, 1728, 1728, 1728, + 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, + 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1729, 0, + 0, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 1729, 0, + 1729, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730, + 1730, 1730, 1730, 1730, 1730, 0, 1730, 1730, 1730, 1730, + 1730, 1730, 1730, 1730, 1730, 1731, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1731, 1731, 0, 0, 0, + 1731, 1731, 1731, 1732, 0, 1732, 0, 0, 0, 0, + 0, 1732, 1732, 0, 0, 1732, 1734, 0, 0, 0, + + 0, 0, 0, 1734, 0, 0, 1734, 1734, 1735, 0, + 0, 0, 0, 1735, 0, 1735, 0, 0, 1735, 1736, + 0, 0, 0, 0, 1736, 0, 1736, 0, 0, 1736, + 1737, 0, 0, 0, 0, 1737, 0, 1737, 0, 0, + 1737, 1738, 1738, 0, 1738, 1738, 1738, 1738, 1738, 1738, + 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, 1738, + 1738, 1738, 1738, 1738, 1738, 1739, 1739, 1739, 1739, 1739, + 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 0, + 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1739, 1740, + 0, 0, 1740, 0, 1740, 0, 1740, 1740, 0, 1740, + + 1740, 0, 0, 1740, 1740, 1740, 1740, 1740, 1740, 1740, + 1741, 0, 1741, 1741, 0, 1741, 0, 1741, 0, 1741, + 1741, 0, 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741, + 1741, 0, 1741, 1743, 1743, 1743, 1743, 1743, 1743, 1743, + 1743, 1743, 1743, 1743, 1743, 1743, 1743, 0, 1743, 1743, + 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1744, 0, 0, + 0, 0, 0, 1744, 0, 0, 1744, 1744, 1744, 1744, + 1744, 1744, 1744, 1744, 0, 1744, 1745, 1745, 1745, 1745, + 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, + 0, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745, + + 1746, 0, 0, 0, 1746, 0, 0, 1746, 1746, 1746, + 1746, 1746, 1746, 1746, 1746, 0, 1746, 1747, 0, 1747, + 0, 0, 0, 0, 0, 1747, 1747, 0, 0, 1747, + 1749, 0, 0, 1749, 1749, 1749, 1749, 1749, 1749, 1749, + 1749, 0, 1749, 1750, 0, 0, 1750, 1750, 1750, 1750, + 1750, 1750, 1750, 1750, 0, 1750, 1751, 1751, 1751, 1751, + 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, + 0, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, + 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752, + 1752, 1752, 1752, 1752, 0, 1752, 1752, 1752, 1752, 1752, + + 1752, 1752, 1752, 1752, 1753, 0, 0, 1753, 0, 0, + 0, 0, 0, 0, 1753, 0, 1753, 1753, 1753, 1753, + 1753, 1753, 1753, 1753, 1753, 0, 1753, 1754, 0, 0, + 1754, 0, 1754, 0, 1754, 1754, 0, 1754, 0, 1754, + 0, 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1756, 1756, + 0, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, + 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756, + 1756, 1756, 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757, + 1757, 1757, 1757, 1757, 1757, 1757, 0, 1757, 1757, 1757, + 1757, 1757, 1757, 1757, 1757, 1757, 1758, 0, 0, 1758, + + 1758, 1758, 1758, 1758, 1758, 1758, 1758, 0, 1758, 1759, + 0, 1759, 0, 0, 0, 0, 0, 1759, 1759, 0, + 0, 1759, 1761, 0, 0, 0, 0, 1761, 1761, 1761, + 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, + 1766, 1766, 1766, 1766, 0, 1766, 1766, 1766, 1766, 1766, + 1766, 1766, 1766, 1766, 1768, 0, 1768, 1768, 0, 1768, + 0, 1768, 0, 1768, 1768, 0, 1768, 1768, 1768, 1768, + 1768, 1768, 1768, 1768, 1768, 0, 1768, 1769, 0, 0, + 0, 0, 1769, 1769, 1769, 0, 0, 0, 1769, 1770, + 0, 0, 0, 0, 0, 1770, 0, 0, 1770, 1770, + + 1770, 1770, 1770, 1770, 1770, 1770, 0, 1770, 1771, 1771, + 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771, + 1771, 1771, 0, 1771, 1771, 1771, 1771, 1771, 1771, 1771, + 1771, 1771, 1772, 0, 1772, 0, 0, 0, 1772, 0, + 0, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 0, + 1772, 1773, 0, 0, 0, 0, 1773, 1773, 1773, 1774, + 0, 1774, 0, 0, 0, 0, 0, 1774, 1774, 0, + 0, 1774, 1776, 0, 0, 1776, 1776, 1776, 1776, 1776, + 1776, 1776, 1776, 0, 1776, 1777, 1777, 1777, 1777, 1777, + 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 0, + + 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1777, 1778, + 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778, + 1778, 1778, 1778, 0, 1778, 1778, 1778, 1778, 1778, 1778, + 1778, 1778, 1778, 1779, 1779, 1779, 1779, 1779, 1779, 1779, + 1779, 1779, 1779, 1779, 1779, 1779, 1779, 0, 1779, 1779, + 1779, 1779, 1779, 1779, 1779, 1779, 1779, 1780, 0, 0, + 1780, 0, 0, 0, 0, 0, 0, 1780, 0, 1780, + 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780, 0, 1780, + 1781, 0, 0, 1781, 1781, 1781, 1781, 1781, 1781, 1781, + 1781, 0, 1781, 1782, 1782, 1782, 1782, 1782, 1782, 1782, + + 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, + 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1783, 0, 0, + 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 0, 1783, + 1784, 0, 0, 0, 0, 1784, 1784, 1784, 1785, 0, + 0, 0, 0, 1785, 1785, 1785, 0, 0, 0, 1785, + 1786, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1786, 1786, 0, 0, 0, 1786, 1786, 1786, 1786, 1787, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1787, + 1787, 0, 0, 0, 1787, 1787, 1787, 1787, 1788, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1788, 1788, + + 0, 0, 0, 1788, 1788, 1788, 1788, 1789, 1789, 1789, + 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, + 1789, 0, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, + 1789, 1790, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1790, 0, 0, 0, 0, 1790, 1790, 1790, 1791, + 0, 1791, 1791, 0, 1791, 0, 1791, 0, 1791, 1791, + 0, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, 1791, + 0, 1791, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, + 1792, 1792, 1792, 1792, 1792, 1792, 0, 1792, 1792, 1792, + 1792, 1792, 1792, 1792, 1792, 1792, 1793, 0, 0, 0, + + 1793, 0, 0, 1793, 1793, 1793, 1793, 1793, 1793, 1793, + 1793, 0, 1793, 1794, 1794, 1794, 1794, 1794, 1794, 1794, + 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794, + 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1795, 0, 0, + 0, 0, 1795, 1795, 1795, 1796, 1796, 1796, 1796, 1796, + 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 0, + 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1797, + 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, + 1797, 1797, 1797, 0, 1797, 1797, 1797, 1797, 1797, 1797, + 1797, 1797, 1797, 1798, 0, 0, 1798, 0, 0, 0, + + 0, 0, 0, 1798, 0, 1798, 1798, 1798, 1798, 1798, + 1798, 1798, 1798, 1798, 0, 1798, 1799, 0, 1799, 0, + 0, 0, 0, 0, 1799, 1799, 0, 0, 1799, 1801, + 0, 0, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, + 0, 1801, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, + 1802, 1802, 1802, 1802, 1802, 1802, 0, 1802, 1802, 1802, + 1802, 1802, 1802, 1802, 1802, 1802, 1803, 0, 0, 1803, + 0, 1803, 0, 1803, 1803, 0, 1803, 0, 1803, 0, + 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1804, 1804, 1804, + 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, + + 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, + 1804, 1805, 0, 0, 1805, 1805, 1805, 1805, 1805, 1805, + 1805, 1805, 0, 1805, 1806, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1806, 0, 0, 0, 0, 0, + 1806, 0, 0, 1806, 1808, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1808, 0, 0, 0, 0, 0, + 1808, 0, 0, 1808, 1810, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1810, 0, 0, 0, 0, 0, + 1810, 0, 0, 1810, 1812, 1812, 1812, 1812, 1812, 1812, + 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 0, 1812, + + 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1812, 1813, 0, + 1813, 1813, 0, 1813, 0, 1813, 0, 1813, 1813, 0, + 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813, 0, + 1813, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, 1814, + 1814, 1814, 1814, 1814, 1814, 0, 1814, 1814, 1814, 1814, + 1814, 1814, 1814, 1814, 1814, 1815, 1815, 1815, 1815, 1815, + 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 0, + 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1816, + 0, 1816, 0, 0, 0, 1816, 0, 0, 1816, 1816, + 1816, 1816, 1816, 1816, 1816, 1816, 0, 1816, 1817, 0, + + 0, 1817, 0, 1817, 0, 1817, 1817, 0, 1817, 0, + 0, 0, 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1818, + 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, + 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818, + 1818, 1818, 1818, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1820, 1820, 1820, + 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, + 1820, 0, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, + 1820, 1821, 0, 0, 1821, 0, 0, 0, 0, 0, + + 0, 1821, 0, 1821, 1821, 1821, 1821, 1821, 1821, 1821, + 1821, 1821, 0, 1821, 1822, 0, 0, 0, 0, 1822, + 1822, 1822, 1823, 1823, 1823, 1823, 1823, 1823, 1823, 1823, + 1823, 1823, 1823, 1823, 1823, 1823, 0, 1823, 1823, 1823, + 1823, 1823, 1823, 1823, 1823, 1823, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1825, 0, 0, 1825, 1825, 1825, 1825, 1825, 1825, 1825, + 1825, 0, 1825, 1826, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1826, 0, 0, 0, 0, 1826, 1826, + + 1826, 0, 1826, 1827, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1827, 0, 0, 0, 0, 1827, 1827, + 1827, 0, 1827, 1828, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1828, 0, 0, 0, 0, 1828, 1828, + 1828, 0, 1828, 1829, 1829, 1829, 1829, 1829, 1829, 1829, + 1829, 1829, 1829, 1829, 1829, 1829, 1829, 0, 1829, 1829, + 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1830, 0, 1830, + 1830, 0, 1830, 0, 1830, 0, 1830, 1830, 0, 1830, + 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830, 0, 1830, + 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831, + + 1831, 1831, 1831, 1831, 0, 1831, 1831, 1831, 1831, 1831, + 1831, 1831, 1831, 1831, 1832, 1832, 1832, 1832, 1832, 1832, + 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 0, 1832, + 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1833, 0, + 0, 0, 1833, 0, 1833, 0, 0, 0, 1833, 0, + 0, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833, 0, + 1833, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, + 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834, + 1834, 1834, 1834, 1834, 1834, 1836, 1836, 1836, 1836, 1836, + 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, + + 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1836, 1837, + 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, + 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, + 1837, 1837, 1837, 1838, 1838, 1838, 1838, 1838, 1838, 1838, + 1838, 1838, 1838, 1838, 1838, 1838, 1838, 0, 1838, 1838, + 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1839, 1839, 1839, + 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, + 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, + 1839, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, + 1840, 1840, 1840, 1840, 1840, 0, 1840, 1840, 1840, 1840, + + 1840, 1840, 1840, 1840, 1840, 1841, 1841, 1841, 1841, 1841, + 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, + 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1842, + 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, + 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, 1842, + 1842, 1842, 1842, 1843, 1843, 1843, 1843, 1843, 1843, 1843, + 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1843, + 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1844, 1844, 1844, + 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, + 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844, + + 1844, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, + 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, 1845, + 1845, 1845, 1845, 1845, 1845, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687 + } ; + +static yy_state_type yy_state_buf[YY_BUF_SIZE + 2], *yy_state_ptr; +static char *yy_full_match; +static int yy_lp; +static int yy_looking_for_trail_begin = 0; +static int yy_full_lp; +static int *yy_full_state; +#define YY_TRAILING_MASK 0x2000 +#define YY_TRAILING_HEAD_MASK 0x4000 +#define REJECT \ +{ \ +*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ \ +yy_cp = yy_full_match; /* restore poss. backed-over text */ \ +yy_lp = yy_full_lp; /* restore orig. accepting pos. */ \ +yy_state_ptr = yy_full_state; /* restore orig. state */ \ +yy_current_state = *yy_state_ptr; /* restore curr. state */ \ +++yy_lp; \ +goto find_rule; \ +} +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +#ifndef YYLMAX +#define YYLMAX 8192 +#endif + +char yytext[YYLMAX]; +char *filttext_ptr; +#line 1 "filt.l" +#define INITIAL 0 +#line 5 "filt.l" + +#include +#ifdef HAVE_MALLOC_H +#include +#endif +#ifdef HAVE_STDLIB_H +#include +#endif +#include +#include +#include +#include + +#define MAX_INCLUDE_DEPTH 100 +#define SEGINC 1024 +#define MASKINC 1024 + +#define LARGE_NUMBER 65536 + +/* must match regions.h */ +#define PSTOP -142857.142857 + +/* stolen from fitsy/xos.h */ +#define X__PI 3.14159265358979323846 +#define X_2PI ( 2 * X__PI ) +#define X_R2D (X_2PI / 360.0) +#define X_R2H (X_2PI / 24.0) +#define X_H2D (360.0 / 24.0) + +#define r2h(r) ( (r) / X_R2H ) +#define h2r(d) ( (d) * X_R2H ) +#define r2d(r) ( (r) / X_R2D ) +#define d2r(d) ( (d) * X_R2D ) +#define h2d(r) ( (r) * X_H2D ) +#define d2h(d) ( (d) / X_H2D ) + +/* region types */ +#define TY_ANNULUS 1 +#define TY_BOX 2 +#define TY_CIRCLE 3 +#define TY_ELLIPSE 4 +#define TY_FIELD 5 +#define TY_LINE 6 +#define TY_PANDA 7 +#define TY_BPANDA 8 +#define TY_CPANDA 9 +#define TY_EPANDA 10 +#define TY_PIE 11 +#define TY_QTPIE 11 +#define TY_POINT 12 +#define TY_POLYGON 13 +#define TY_IMAGEMASK 14 + +/* oft-used checks on argument and coord types */ +#define XARG ((narg % 2) == 1) +#define YARG ((narg % 2) == 0) +#define POSARG ((regid == TY_POLYGON) || (regid == TY_LINE) || (narg<=2)) +#define ANGARG (((regid == TY_PANDA) && (narg==3)) || \ + ((regid == TY_PANDA) && (narg==4)) || \ + ((regid == TY_BPANDA) && (narg==3)) || \ + ((regid == TY_BPANDA) && (narg==4)) || \ + ((regid == TY_CPANDA) && (narg==3)) || \ + ((regid == TY_CPANDA) && (narg==4)) || \ + ((regid == TY_EPANDA) && (narg==3)) || \ + ((regid == TY_EPANDA) && (narg==4)) || \ + ((regid == TY_PIE) && (narg>=3)) ) + +#define NUMARG (((regid == TY_PANDA) && (narg==5)) || \ + ((regid == TY_PANDA) && (narg==8)) || \ + ((regid == TY_BPANDA) && (narg==5)) || \ + ((regid == TY_BPANDA) && (narg==10)) || \ + ((regid == TY_CPANDA) && (narg==5)) || \ + ((regid == TY_CPANDA) && (narg==8)) || \ + ((regid == TY_EPANDA) && (narg==5)) || \ + ((regid == TY_EPANDA) && (narg==10)) ) + +#define SAVEANG ((regid == TY_BOX) || (regid == TY_ELLIPSE)) + +#define USEPHYS (filt->fhd->table && \ + (filt->type == TYPE_EVENTS) && !filt->evsect) + +#define USEWCS (gcoordsys && \ + strcmp(gcoordsys, "image") && strcmp(gcoordsys, "physical")) + +#define IMFLIP (USEWCS && wcs->imflip) + +#define WCSSIZE (iswcs(wcs) && (cdelt1!=0) && (cdelt2!=0)) + +/* format statements */ +#define DFMT1 ",%f" +#define DFMT2 ",%f,%f" +#define DFMT4 ",%f,%f,%f,%f" +#define SFMT1 ",%s" +#define IFMT1 ",%d" + +/* flex is not thread-safe, so we did not put any effort into avoiding + globals, i.e. by putting read-write variables below into a struct */ + +static YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH]; +static int include_stack_ptr = 0; +static int parse_error = 0; + +static int colargs; +static int filtlen; +static int radanglen; +static int initbindefs; +static int regtype; +static int regid; +static int laststart; +static int maxfiltseg; +static int setargs; +static int inexpr; +static int macropass; +static int narg; +static int nparen; +static int nsparen; +static int nrparen; +static int nfiltseg; +static int nrange; +static int nroutine; +static int nshape; +static int nregion; +static int nmask; +static int got; +static int offscl; +static int xtype, ytype; +static int tltyp[2]; + +static double lastd1; +static double lastd2; +static double xpos, ypos; +static double xpix, ypix; +static double cdelt1, cdelt2, crot; +static double dval, dval2; +static double tlmin[2]; +static double tlmax[2]; +static double binsiz[2]; + +static char lastarg[SZ_LINE]; +static char regname[SZ_LINE]; +static char colnames[2][SZ_LINE]; +static char wcsnames[2][SZ_LINE]; +static char macrobuf[SZ_LINE]; +static char rangename[SZ_LINE]; +static char sbuf[SZ_LINE]; +static char saveang[SZ_LINE]; + +static char *fcoordsys=NULL; +static char *gcoordsys=NULL; +static char *filter=NULL; +static char *radang=NULL; + +static struct WorldCoor *wcs=NULL; +static FiltSeg *filtseg=NULL; +static Filter filt=NULL; + +/* these are read-only */ +static char *rnames[] = {"annulus", "box", "circle", "ellipse", + "line", "panda", "pie", "qtpie", "point", + "polygon", "field", "bpanda", "cpanda", "epanda", + "imagemask", NULL}; +static int rargs[] = {4, 5, 3, 5, + 4, 8, 4, 4, 2, + 6, 0, 11, 8, 11, + 0, 0}; +static int vargs[] = {'y', 'o', 'y', 'o', + 'n', 'n', 'y', 'n', 'e', + 'e', 'n', 'n', 'n', 'n', + 'n', '\0'}; + +static int _FiltLexTypeCmp(const void *s1, const void *s2); +static int _FiltLexTypeMatch(int ftype, int ttype); +static int _FiltLexAccel _PRx((int n)); +static int _FiltLexRegionPanda _PRx((void)); +static int _FiltLexLcx _PRx((void)); +static int _FiltLexArgCheck _PRx((char *name, int args)); +static int _FiltLexNeedOp _PRx((int i, char *s)); +static void _FiltLexOp _PRx((char *s)); +static void _FiltLexTypeSet _PRx((int type)); +static void _FiltLexNew _PRx((void)); +static void _FiltLexParen _PRx((char *s)); +static void _FiltLexCat _PRx((char *s)); +static void _FiltLexRegionStart _PRx((int docols)); +static void _FiltLexRegionVal _PRx((char *s)); +static void _FiltLexRegionEnd _PRx((void)); +static void _FiltLexRangeAdd _PRx((char *xname, char *str, int type, int n, int maxlen)); +static void _FiltLexArgSave _PRx((double dval)); +static void _FiltLexSetWcs _PRx((char *s)); +static void _FiltLexWcsCols _PRx((FITSHead header, char *name1, char *name2)); +static void _FiltLexNum _PRx((int lcx)); +static void _FiltLexEnd _PRx((void)); +static void _FiltLexMake _PRx((void)); +static char *_FiltLexGetWcs _PRx((void)); +static int _FiltIncMask(FilterMask masks, int maxmask, int nmask); +static int _FiltFitsMask(char *filename, FilterMask *rmasks, FITSHead *rhead, int *nreg); +static void bin2num(char *d, char *s, int maxlen); + +int _filterror _PRx((char *msg)); +#define RLIST 1 + +#define RTINE 2 + +#define REG 3 + +#define AREG 4 + +#define INCLUDE 5 + +#define COMM 6 + +#line 4563 "lex.filt.c" + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap YY_PROTO(( void )); +#else +extern int yywrap YY_PROTO(( void )); +#endif +#endif + +#ifndef YY_NO_UNPUT +static void yyunput YY_PROTO(( int c, char *buf_ptr )); +#endif + +#ifndef filttext_ptr +static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int )); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen YY_PROTO(( yyconst char * )); +#endif + +#ifndef YY_NO_INPUT +#ifdef __cplusplus +static int yyinput YY_PROTO(( void )); +#else +static int input YY_PROTO(( void )); +#endif +#endif + +#if YY_STACK_USED +static int yy_start_stack_ptr = 0; +static int yy_start_stack_depth = 0; +static int *yy_start_stack = 0; +#ifndef YY_NO_PUSH_STATE +static void yy_push_state YY_PROTO(( int new_state )); +#endif +#ifndef YY_NO_POP_STATE +static void yy_pop_state YY_PROTO(( void )); +#endif +#ifndef YY_NO_TOP_STATE +static int yy_top_state YY_PROTO(( void )); +#endif + +#else +#define YY_NO_PUSH_STATE 1 +#define YY_NO_POP_STATE 1 +#define YY_NO_TOP_STATE 1 +#endif + +#ifdef YY_MALLOC_DECL +YY_MALLOC_DECL +#else +#if __STDC__ +#ifndef __cplusplus +#include +#endif +#else +/* Just try to get by without declaring the routines. This will fail + * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int) + * or sizeof(void*) != sizeof(int). + */ +#endif +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ + +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( yy_current_buffer->yy_is_interactive ) \ + { \ + int c = '*', n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \ + && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL int yylex YY_PROTO(( void )) +#endif + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +YY_DECL + { + register yy_state_type yy_current_state; + register char *yy_cp = NULL, *yy_bp = NULL; + register int yy_act; + +#line 247 "filt.l" + + +#line 4717 "lex.filt.c" + + if ( yy_init ) + { + yy_init = 0; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! yy_start ) + yy_start = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! yy_current_buffer ) + yy_current_buffer = + yy_create_buffer( yyin, YY_BUF_SIZE ); + + yy_load_buffer_state(); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = yy_c_buf_p; + + /* Support of yytext. */ + *yy_cp = yy_hold_char; + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = yy_start; + yy_state_ptr = yy_state_buf; + *yy_state_ptr++ = yy_current_state; +yy_match: + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 1688 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + *yy_state_ptr++ = yy_current_state; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 14226 ); + +yy_find_action: + yy_current_state = *--yy_state_ptr; + yy_lp = yy_accept[yy_current_state]; +find_rule: /* we branch to this label when backing up */ + for ( ; ; ) /* until we find what rule we matched */ + { + if ( yy_lp && yy_lp < yy_accept[yy_current_state + 1] ) + { + yy_act = yy_acclist[yy_lp]; + if ( yy_act & YY_TRAILING_HEAD_MASK || + yy_looking_for_trail_begin ) + { + if ( yy_act == yy_looking_for_trail_begin ) + { + yy_looking_for_trail_begin = 0; + yy_act &= ~YY_TRAILING_HEAD_MASK; + break; + } + } + else if ( yy_act & YY_TRAILING_MASK ) + { + yy_looking_for_trail_begin = yy_act & ~YY_TRAILING_MASK; + yy_looking_for_trail_begin |= YY_TRAILING_HEAD_MASK; + } + else + { + yy_full_match = yy_cp; + yy_full_state = yy_state_ptr; + yy_full_lp = yy_lp; + break; + } + ++yy_lp; + goto find_rule; + } + --yy_cp; + yy_current_state = *--yy_state_ptr; + yy_lp = yy_accept[yy_current_state]; + } + + YY_DO_BEFORE_ACTION; + + +do_action: /* This label is used only to access EOF actions. */ + + + switch ( yy_act ) + { /* beginning of action switch */ +case 1: +YY_RULE_SETUP +#line 249 "filt.l" +{ _FiltLexCat(yytext); } + YY_BREAK +case 2: +YY_RULE_SETUP +#line 251 "filt.l" +{ _FiltLexSetWcs(yytext); } + YY_BREAK +case 3: +YY_RULE_SETUP +#line 253 "filt.l" +{ BEGIN COMM; } + YY_BREAK +case 4: +YY_RULE_SETUP +#line 254 "filt.l" +{ BEGIN COMM; } + YY_BREAK +case 5: +YY_RULE_SETUP +#line 255 "filt.l" +{ BEGIN COMM; } + YY_BREAK +case 6: +YY_RULE_SETUP +#line 256 "filt.l" +{ + /* comment acts like EOL */ + if( YY_START == REG ){ + _FiltLexRegionEnd(); + _FiltLexNew(); + } + else if( YY_START == RLIST ){ + _FiltLexParen(")"); + _FiltLexNew(); + } + else{ + _FiltLexNew(); + } + BEGIN COMM; +} + YY_BREAK +case 7: +YY_RULE_SETUP +#line 271 "filt.l" +{ BEGIN INITIAL; } + YY_BREAK +case 8: +YY_RULE_SETUP +#line 272 "filt.l" +{ BEGIN INITIAL; } + YY_BREAK +case 9: +YY_RULE_SETUP +#line 273 "filt.l" +{ /* ignore comments up to eol */ ; } + YY_BREAK +case 10: +YY_RULE_SETUP +#line 275 "filt.l" +{ ; /* ignore */ } + YY_BREAK +case 11: +YY_RULE_SETUP +#line 276 "filt.l" +{ ; /* ignore */ } + YY_BREAK +case 12: +YY_RULE_SETUP +#line 277 "filt.l" +{ ; /* ignore */ } + YY_BREAK +case 13: +YY_RULE_SETUP +#line 278 "filt.l" +{ ; /* ignore */ } + YY_BREAK +case 14: +*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ +yy_c_buf_p = yy_cp = yy_bp + 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 280 "filt.l" +{ + if( YY_START == REG ){ + _FiltLexRegionEnd(); + _FiltLexNew(); + } + /* Found an asc-style region */ + colargs = 0; + laststart = YY_START; + BEGIN AREG; +} + YY_BREAK +case 15: +YY_RULE_SETUP +#line 290 "filt.l" +{ + if( colargs > 2 ) + _filterror("illegal Chandra region (too many column args)"); + if( !FilterSymbolEnter(filt, yytext, &got) ){ + switch(got){ + case -1: + _filterror("missing column or header parameter"); + break; + case -2: + _filterror("column is not an array"); + break; + case -3: + _filterror("internal error while processing column"); + break; + } + } + strcpy(colnames[colargs],yytext); + colargs++; +} + YY_BREAK +case 16: +YY_RULE_SETUP +#line 309 "filt.l" +{ ; } + YY_BREAK +case 17: +YY_RULE_SETUP +#line 310 "filt.l" +{ ; } + YY_BREAK +case 18: +YY_RULE_SETUP +#line 311 "filt.l" +{ ; } + YY_BREAK +case 19: +YY_RULE_SETUP +#line 312 "filt.l" +{ + /* end of asc part of region */ + if( colargs != 2 ) + _filterror("illegal Chandra region (wrong number of cols)"); + BEGIN INITIAL; +} + YY_BREAK +case 20: +#line 320 "filt.l" +case 21: +YY_RULE_SETUP +#line 320 "filt.l" +{ + /* finish off previous */ + if( YY_START == REG ){ + _FiltLexRegionEnd(); + _FiltLexNew(); + } + /* Found a region */ + BEGIN REG; + if( filt->type == TYPE_EVENTS ){ + /* if asc-style, re-do wcs for specified columns */ + if( colargs == 2 ){ + _FiltLexRegionStart(2); + _FiltLexWcsCols(filt->fhd, colnames[0], colnames[1]); + } + /* set up default columns */ + else{ + _FiltLexRegionStart(1); + } + } + /* its an image */ + else{ + _FiltLexRegionStart(0); + } +} + YY_BREAK +case 22: +YY_RULE_SETUP +#line 344 "filt.l" +{ + /* can't happen */ + _filterror("invalid characters following the region name"); +} + YY_BREAK +case 23: +YY_RULE_SETUP +#line 348 "filt.l" +{ + narg++; + /* process this pure number in the current coord system */ + _FiltLexNum(_FiltLexLcx()); +} + YY_BREAK +case 24: +YY_RULE_SETUP +#line 353 "filt.l" +{ + narg++; + /* remove trailing unit character */ + yytext[strlen(yytext)-1] = '\0'; + /* process this as a pure number in image coord sys */ + _FiltLexNum(LCX_IMAGE); +} + YY_BREAK +case 25: +YY_RULE_SETUP +#line 360 "filt.l" +{ + narg++; + /* remove trailing unit character */ + yytext[strlen(yytext)-1] = '\0'; + /* process this as a pure number in physical coord sys */ + _FiltLexNum(LCX_PHYS); +} + YY_BREAK +case 26: +YY_RULE_SETUP +#line 367 "filt.l" +{ + char *coordsys; + if( nowcs(wcs) ) + _filterror("no WCS information in file"); + narg++; + /* save x value for processing with y next time */ + if( XARG ){ + xpos = SAOstrtod(yytext,NULL); + xtype = SAOdtype; + if( (xtype !=0) && (xtype != '.') && (xtype != 'd') ){ + coordsys = _FiltLexGetWcs(); + /* arg1 coords are hms, but ecliptic, galactic are deg */ + if( !coordsys || + (strncasecmp(coordsys, "ecl", 3) && + strncasecmp(coordsys, "gal", 3)) ){ + xpos = h2d(xpos); + } + } + } + else{ + ypos = SAOstrtod(yytext,NULL); + ytype = SAOdtype; + /* convert wcs to image pixels */ + wcsc2pix(wcs, xpos,ypos, _FiltLexGetWcs(), &xpix,&ypix, + &offscl); + /* convert to physical for single event filtering */ + if( USEPHYS ){ + xpix = tli2p(xpix, tlmin[0], binsiz[0], tltyp[0]); + ypix = tli2p(ypix, tlmin[1], binsiz[1], tltyp[1]); + } + snprintf(sbuf, SZ_LINE, DFMT2, xpix, ypix); + _FiltLexCat(sbuf); + } +} + YY_BREAK +case 27: +YY_RULE_SETUP +#line 401 "filt.l" +{ + narg++; + /* handle position arguments */ + if( POSARG ){ + if( nowcs(wcs) ) + _filterror("no WCS information in file"); + /* save x value for processing with y next time */ + if( XARG ){ + xpos = strtod(yytext,NULL); + } + else{ + ypos = strtod(yytext,NULL); + /* convert wcs to image pixels */ + wcsc2pix(wcs, xpos, ypos, _FiltLexGetWcs(), + &xpix, &ypix, &offscl); + /* convert to physical for single event filtering */ + if( USEPHYS ){ + xpix = tli2p(xpix, tlmin[0], binsiz[0], tltyp[0]); + ypix = tli2p(ypix, tlmin[1], binsiz[1], tltyp[1]); + } + snprintf(sbuf, SZ_LINE, DFMT2, xpix, ypix); + _FiltLexCat(sbuf); + } + } + /* angle arguments are just passed along, with updated crot */ + else if( ANGARG ){ + dval = strtod(yytext,NULL); + if( USEWCS ) dval += crot; + if( IMFLIP ) dval = -dval; + snprintf(sbuf, SZ_LINE, DFMT1, dval); + _FiltLexCat(sbuf); + } + /* panda numeric args are just passed along */ + else if( NUMARG ){ + dval = strtod(yytext,NULL); + snprintf(sbuf, SZ_LINE, DFMT1, dval); + _FiltLexCat(sbuf); + } + /* handle size arguments */ + else{ + if( !WCSSIZE ) + _filterror("no WCS (or CDELT) information in file"); + if( SAVEANG ){ + dval = strtod(yytext,NULL); + if( USEWCS ) dval += crot; + if( IMFLIP ) dval = -dval; + snprintf(saveang, SZ_LINE, DFMT1, dval); + } + /* arg 1 is ra, arg2 is dec */ + if( XARG ) + dval = ABS(strtod(yytext,NULL)/cdelt1); + else + dval = ABS(strtod(yytext,NULL)/cdelt2); + snprintf(sbuf, SZ_LINE, DFMT1, dval); + _FiltLexCat(sbuf); + _FiltLexArgSave(dval); + } +} + YY_BREAK +case 28: +YY_RULE_SETUP +#line 459 "filt.l" +{ + narg++; + /* handle position arguments */ + if( POSARG ){ + if( nowcs(wcs) ) + _filterror("no WCS information in file"); + /* save x value for processing with y next time */ + if( XARG ){ + xpos = r2d(strtod(yytext,NULL)); + } + else{ + ypos = r2d(strtod(yytext,NULL)); + /* convert wcs to image pixels */ + wcsc2pix(wcs, xpos, ypos, _FiltLexGetWcs(), + &xpix, &ypix, &offscl); + /* convert to physical for single event filtering */ + if( USEPHYS ){ + xpix = tli2p(xpix, tlmin[0], binsiz[0], tltyp[0]); + ypix = tli2p(ypix, tlmin[1], binsiz[1], tltyp[1]); + } + snprintf(sbuf, SZ_LINE, DFMT2, xpix, ypix); + _FiltLexCat(sbuf); + } + } + /* angle arguments are just passed along, with updated crot */ + else if( ANGARG ){ + dval = r2d(strtod(yytext,NULL)); + if( USEWCS ) dval += crot; + if( IMFLIP ) dval = -dval; + snprintf(sbuf, SZ_LINE, DFMT1, dval); + _FiltLexCat(sbuf); + } + /* panda numeric args are just passed along */ + else if( NUMARG ){ + dval = strtod(yytext,NULL); + snprintf(sbuf, SZ_LINE, DFMT1, dval); + _FiltLexCat(sbuf); + } + /* handle size arguments */ + else{ + if( !WCSSIZE ) + _filterror("no WCS (or CDELT) information in file"); + if( SAVEANG ){ + dval = r2d(strtod(yytext,NULL)); + if( USEWCS ) dval += crot; + if( IMFLIP ) dval = -dval; + snprintf(saveang, SZ_LINE, DFMT1, dval); + } + /* arg 1 is ra, arg2 is dec */ + if( XARG ) + dval = r2d(ABS(strtod(yytext,NULL)/cdelt1)); + else + dval = r2d(ABS(strtod(yytext,NULL)/cdelt2)); + snprintf(sbuf, SZ_LINE, DFMT1, dval); + _FiltLexCat(sbuf); + _FiltLexArgSave(dval); + } +} + YY_BREAK +case 29: +YY_RULE_SETUP +#line 517 "filt.l" +{ + if( !WCSSIZE ) + _filterror("no WCS (or CDELT) information in file"); + narg++; + /* arg 1 is ra, arg2 is dec */ + if( XARG ) + dval = ABS(strtod(yytext,NULL)/(cdelt1*60.0)); + else + dval = ABS(strtod(yytext,NULL)/(cdelt2*60.0)); + snprintf(sbuf, SZ_LINE, DFMT1, dval); + _FiltLexCat(sbuf); + _FiltLexArgSave(dval); +} + YY_BREAK +case 30: +YY_RULE_SETUP +#line 530 "filt.l" +{ + if( !WCSSIZE ) + _filterror("no WCS (or CDELT) information in file"); + narg++; + /* arg 1 is ra, arg2 is dec */ + if( XARG ) + dval = ABS(strtod(yytext,NULL)/(cdelt1*3600.0)); + else + dval = ABS(strtod(yytext,NULL)/(cdelt2*3600.0)); + snprintf(sbuf, SZ_LINE, DFMT1, dval); + _FiltLexCat(sbuf); + _FiltLexArgSave(dval); +} + YY_BREAK +case 31: +YY_RULE_SETUP +#line 543 "filt.l" +{ + int n; + n = strtol(strchr(yytext, '=')+1, NULL, 10); + if( n <=0 ){ + _filterror("invalid region accelerator"); + } + else{ + if( !_FiltLexAccel(n) ){ + _filterror("invalid region accelerator"); + } + } +} + YY_BREAK +case 32: +YY_RULE_SETUP +#line 555 "filt.l" +{ + if( _FiltLexArgCheck(regname, narg) == 0 ){ + /* new expression without an expression separator ... sigh */ + _FiltLexRegionEnd(); + _FiltLexNew(); + BEGIN INITIAL; + yyless(0); + } else { + narg++; + /* process this pure number in the current coord system */ + _FiltLexNum(_FiltLexLcx()); + } +} + YY_BREAK +case 33: +YY_RULE_SETUP +#line 568 "filt.l" +{ + /* new expression without an expression separator ... sigh */ + _FiltLexRegionEnd(); + _FiltLexNew(); + BEGIN INITIAL; + yyless(0); +} + YY_BREAK +case 34: +YY_RULE_SETUP +#line 575 "filt.l" +{ + /* explicit rule avoids the _FiltLexNew of general rule */ + ; +} + YY_BREAK +case 35: +YY_RULE_SETUP +#line 579 "filt.l" +{ + _FiltLexRegionVal(yytext); + if( !nsparen ){ + _FiltLexRegionEnd(); + BEGIN INITIAL; + } +} + YY_BREAK +case 36: +YY_RULE_SETUP +#line 586 "filt.l" +{ + nsparen++; +} + YY_BREAK +case 37: +YY_RULE_SETUP +#line 589 "filt.l" +{ + _FiltLexRegionVal(yytext+1); + if( nsparen ){ + nsparen--; + if( !nsparen ){ + _FiltLexRegionEnd(); + BEGIN INITIAL; + } + } else { + _FiltLexRegionEnd(); + BEGIN INITIAL; + /* REJECT; */ + /* explicit execution of general rule instead of REJECT */ + nparen--; + _FiltLexNew(); + _FiltLexCat(")"); + _FiltLexNew(); + } +} + YY_BREAK +case 38: +YY_RULE_SETUP +#line 608 "filt.l" +{ + if( nsparen ){ + nsparen--; + if( !nsparen ){ + _FiltLexRegionEnd(); + BEGIN INITIAL; + } + } else { + _FiltLexRegionEnd(); + BEGIN INITIAL; + /* REJECT; */ + /* explicit execution of general rule instead of REJECT */ + nparen--; + _FiltLexNew(); + _FiltLexCat(")"); + _FiltLexNew(); + } +} + YY_BREAK +case 39: +YY_RULE_SETUP +#line 626 "filt.l" +{ + _FiltLexRegionEnd(); + _FiltLexOp(yytext); + BEGIN INITIAL; +} + YY_BREAK +case 40: +YY_RULE_SETUP +#line 631 "filt.l" +{ + _FiltLexRegionEnd(); + _FiltLexNew(); + BEGIN INITIAL; +} + YY_BREAK +case 41: +YY_RULE_SETUP +#line 637 "filt.l" +{ + _filterror("you must use == to compare two columns,"); +} + YY_BREAK +case 42: +YY_RULE_SETUP +#line 641 "filt.l" +{ + if( YY_START == REG ){ + _FiltLexRegionEnd(); + } + _FiltLexParen("("); + BEGIN RLIST; + narg = 0; + _FiltLexTypeSet(TOK_RLIST); + nrange = 0; + if( !FilterSymbolEnter(filt, yytext, &got) ){ + switch(got){ + case -1: + _filterror("missing column or header parameter"); + break; + case -2: + _filterror("column is not an array"); + break; + case -3: + _filterror("internal error while processing column"); + break; + } + } + strncpy(rangename, yytext, SZ_LINE-1); +} + YY_BREAK +case 43: +YY_RULE_SETUP +#line 665 "filt.l" +{ + _FiltLexRangeAdd(rangename, yytext, 3, nrange++, SZ_LINE); +} + YY_BREAK +case 44: +YY_RULE_SETUP +#line 668 "filt.l" +{ + _FiltLexRangeAdd(rangename, yytext, 1, nrange++, SZ_LINE); +} + YY_BREAK +case 45: +YY_RULE_SETUP +#line 671 "filt.l" +{ + _FiltLexRangeAdd(rangename, yytext, 4, nrange++, SZ_LINE); +} + YY_BREAK +case 46: +YY_RULE_SETUP +#line 674 "filt.l" +{ + _FiltLexRangeAdd(rangename, yytext, 2, nrange++, SZ_LINE); +} + YY_BREAK +case 47: +YY_RULE_SETUP +#line 677 "filt.l" +{ ; } + YY_BREAK +case 48: +YY_RULE_SETUP +#line 678 "filt.l" +{ ; } + YY_BREAK +case 49: +YY_RULE_SETUP +#line 679 "filt.l" +{ ; } + YY_BREAK +case 50: +YY_RULE_SETUP +#line 680 "filt.l" +{ + _FiltLexParen(")"); + _FiltLexNew(); + BEGIN INITIAL; +} + YY_BREAK +case 51: +YY_RULE_SETUP +#line 685 "filt.l" +{ + _FiltLexParen(")"); + _FiltLexNew(); + _FiltLexParen(")"); + _FiltLexNew(); + BEGIN INITIAL; +} + YY_BREAK +case 52: +YY_RULE_SETUP +#line 692 "filt.l" +{ + _FiltLexParen(")"); + _FiltLexOp(yytext); + BEGIN INITIAL; +} + YY_BREAK +case 53: +YY_RULE_SETUP +#line 697 "filt.l" +{ + _FiltLexParen(")"); + _FiltLexNew(); + BEGIN INITIAL; +} + YY_BREAK +case 54: +*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ +yy_c_buf_p = yy_cp -= 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 703 "filt.l" +{ + /* Found a routine */ + laststart = YY_START; + BEGIN RTINE; + narg = 0; + nrparen = 0; + _FiltLexTypeSet(TOK_RTINE); + _FiltLexCat(FilterLexRoutine1(filt, yytext)); + nroutine++; +} + YY_BREAK +case 55: +YY_RULE_SETUP +#line 713 "filt.l" +{ + /* explicit rule avoids the _FiltLexNew of general rule */ + _FiltLexCat(","); +} + YY_BREAK +case 56: +YY_RULE_SETUP +#line 717 "filt.l" +{ + nrparen++; + _FiltLexCat("("); +} + YY_BREAK +case 57: +YY_RULE_SETUP +#line 721 "filt.l" +{ + nrparen--; + if( nrparen ){ + _FiltLexCat(")"); + } + else{ + /* end of routine */ + BEGIN laststart; + _FiltLexCat(FilterLexRoutine2(filt, ")")); + } +} + YY_BREAK +case 58: +YY_RULE_SETUP +#line 733 "filt.l" +{ + /* Found an include file */ + char *s, *t; + if( YY_START == REG ){ + _FiltLexRegionEnd(); + _FiltLexNew(); + } + /* handle FITS mask file specially */ + filt->nmask = _FiltFitsMask(yytext+1, + &(filt->masks), + &(filt->maskhd), + &(filt->nmaskreg)); + /* filt->nmask == -1 => its not a FITS file */ + if( filt->nmask != -1 ){ + switch(filt->nmask){ + case -2: + _filterror("FITS image mask must be image data -"); + break; + case -3: + _filterror("Invalid dimensions for FITS image mask -"); + break; + case -4: + _filterror("FITS image mask cannot contain negative values -"); + break; + default: + if( (filt->type != TYPE_IMAGE) && !filt->evsect ){ + _filterror("FITS image mask is valid for image filtering only -"); + } + else{ + if( nmask ) + _filterror("only one FITS image mask allowed at a time -"); + else + nmask++; + } + break; + } + } + else{ + if ( include_stack_ptr >= MAX_INCLUDE_DEPTH ) { + _filterror("include files are nested too deeply"); + } + if( (s = (char *)FileContents(yytext+1, 0, NULL)) == NULL ){ + _filterror("can't access include file"); + } + /* ignore empty include file */ + else if( *s == '\0' ){ + ; + } + else { + t = FilterClip(s); + xfree(s); + if( t && *t ){ + include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER; + _FiltLexNew(); + _FiltLexParen("("); + FiltScanString(t); + xfree(t); + } + } + } +} + YY_BREAK +case 59: +YY_RULE_SETUP +#line 795 "filt.l" +{ + if( !FilterSymbolEnter(filt, yytext, &got) ){ + switch(got){ + case -1: + _filterror("missing column or header parameter"); + break; + case -2: + _filterror("column is not an array"); + break; + case -3: + _filterror("internal error while processing column"); + break; + } + } + else{ + narg++; + /* add if initial condition (not region, routine, etc.) */ + if( YY_START == INITIAL ) _FiltLexTypeSet(TOK_NAME); + _FiltLexCat(FilterLexName(filt,yytext)); + } +} + YY_BREAK +case 60: +YY_RULE_SETUP +#line 817 "filt.l" +{ ; /* ignore white space */ } + YY_BREAK +case 61: +YY_RULE_SETUP +#line 819 "filt.l" +{ narg++; _FiltLexCat(yytext); } + YY_BREAK +case 62: +YY_RULE_SETUP +#line 821 "filt.l" +{ + char tbuf[SZ_LINE]; + bin2num(tbuf, yytext, SZ_LINE-1); + narg++; + _FiltLexCat(tbuf); + } + YY_BREAK +case 63: +YY_RULE_SETUP +#line 828 "filt.l" +{ + _FiltLexOp(yytext); + if( YY_START != RTINE ) BEGIN INITIAL; +} + YY_BREAK +case 64: +YY_RULE_SETUP +#line 833 "filt.l" +{ + nparen++; + _FiltLexNew(); + _FiltLexCat(yytext); + _FiltLexNew(); +} + YY_BREAK +case 65: +YY_RULE_SETUP +#line 839 "filt.l" +{ + nparen--; + _FiltLexNew(); + _FiltLexCat(yytext); + _FiltLexNew(); +} + YY_BREAK +case 66: +YY_RULE_SETUP +#line 845 "filt.l" +{ + _FiltLexNew(); + BEGIN INITIAL; +} + YY_BREAK +case 67: +YY_RULE_SETUP +#line 850 "filt.l" +{ _FiltLexCat(yytext); } + YY_BREAK +case YY_STATE_EOF(INITIAL): +case YY_STATE_EOF(RLIST): +case YY_STATE_EOF(RTINE): +case YY_STATE_EOF(REG): +case YY_STATE_EOF(AREG): +case YY_STATE_EOF(INCLUDE): +case YY_STATE_EOF(COMM): +#line 852 "filt.l" +{ + if ( --include_stack_ptr < 0 ){ + _FiltLexMake(); + yy_delete_buffer( YY_CURRENT_BUFFER ); + yyterminate(); + } else { + _FiltLexParen(")"); + _FiltLexNew(); + yy_delete_buffer( YY_CURRENT_BUFFER ); + yy_switch_to_buffer(include_stack[include_stack_ptr] ); + } +} + YY_BREAK +case 68: +YY_RULE_SETUP +#line 865 "filt.l" +ECHO; + YY_BREAK +#line 5704 "lex.filt.c" + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - filttext_ptr) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = yy_hold_char; + YY_RESTORE_YY_MORE_OFFSET + + if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between yy_current_buffer and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + yy_n_chars = yy_current_buffer->yy_n_chars; + yy_current_buffer->yy_input_file = yyin; + yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + yy_c_buf_p = filttext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state(); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = filttext_ptr + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++yy_c_buf_p; + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = yy_c_buf_p; + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer() ) + { + case EOB_ACT_END_OF_FILE: + { + yy_did_buffer_switch_on_eof = 0; + + if ( yywrap() ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + yy_c_buf_p = filttext_ptr + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = + filttext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state(); + + yy_cp = yy_c_buf_p; + yy_bp = filttext_ptr + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + yy_c_buf_p = + &yy_current_buffer->yy_ch_buf[yy_n_chars]; + + yy_current_state = yy_get_previous_state(); + + yy_cp = yy_c_buf_p; + yy_bp = filttext_ptr + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ + } /* end of yylex */ + + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ + +static int yy_get_next_buffer() + { + register char *dest = yy_current_buffer->yy_ch_buf; + register char *source = filttext_ptr; + register int number_to_move, i; + int ret_val; + + if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( yy_current_buffer->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( yy_c_buf_p - filttext_ptr - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) (yy_c_buf_p - filttext_ptr) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + yy_current_buffer->yy_n_chars = yy_n_chars = 0; + + else + { + int num_to_read = + yy_current_buffer->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ +#ifdef YY_USES_REJECT + YY_FATAL_ERROR( +"input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); +#else + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = yy_current_buffer; + + int yy_c_buf_p_offset = + (int) (yy_c_buf_p - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yy_flex_realloc( (void *) b->yy_ch_buf, + b->yy_buf_size + 2 ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = yy_current_buffer->yy_buf_size - + number_to_move - 1; +#endif + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), + yy_n_chars, num_to_read ); + + yy_current_buffer->yy_n_chars = yy_n_chars; + } + + if ( yy_n_chars == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart( yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + yy_current_buffer->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + yy_n_chars += number_to_move; + yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; + yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; + + filttext_ptr = &yy_current_buffer->yy_ch_buf[0]; + + return ret_val; + } + + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + +static yy_state_type yy_get_previous_state() + { + register yy_state_type yy_current_state; + register char *yy_cp; + + yy_current_state = yy_start; + yy_state_ptr = yy_state_buf; + *yy_state_ptr++ = yy_current_state; + + for ( yy_cp = filttext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 1688 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + *yy_state_ptr++ = yy_current_state; + } + + return yy_current_state; + } + + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + +#ifdef YY_USE_PROTOS +static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state ) +#else +static yy_state_type yy_try_NUL_trans( yy_current_state ) +yy_state_type yy_current_state; +#endif + { + register int yy_is_jam; + + register YY_CHAR yy_c = 1; + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 1688 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 1687); + if ( ! yy_is_jam ) + *yy_state_ptr++ = yy_current_state; + + return yy_is_jam ? 0 : yy_current_state; + } + + +#ifndef YY_NO_UNPUT +#ifdef YY_USE_PROTOS +static void yyunput( int c, register char *yy_bp ) +#else +static void yyunput( c, yy_bp ) +int c; +register char *yy_bp; +#endif + { + register char *yy_cp = yy_c_buf_p; + + /* undo effects of setting up yytext */ + *yy_cp = yy_hold_char; + + if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register int number_to_move = yy_n_chars + 2; + register char *dest = &yy_current_buffer->yy_ch_buf[ + yy_current_buffer->yy_buf_size + 2]; + register char *source = + &yy_current_buffer->yy_ch_buf[number_to_move]; + + while ( source > yy_current_buffer->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + yy_current_buffer->yy_n_chars = + yy_n_chars = yy_current_buffer->yy_buf_size; + + if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + + + filttext_ptr = yy_bp; + yy_hold_char = *yy_cp; + yy_c_buf_p = yy_cp; + } +#endif /* ifndef YY_NO_UNPUT */ + + +#ifndef YY_NO_INPUT +#ifdef __cplusplus +static int yyinput() +#else +static int input() +#endif + { + int c; + + *yy_c_buf_p = yy_hold_char; + + if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + /* This was really a NUL. */ + *yy_c_buf_p = '\0'; + + else + { /* need more input */ + int offset = yy_c_buf_p - filttext_ptr; + ++yy_c_buf_p; + + switch ( yy_get_next_buffer() ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart( yyin ); + + /* fall through */ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap() ) + return EOF; + + if ( ! yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = filttext_ptr + offset; + break; + } + } + } + + c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */ + *yy_c_buf_p = '\0'; /* preserve yytext */ + yy_hold_char = *++yy_c_buf_p; + + + return c; + } +#endif /* YY_NO_INPUT */ + +#ifdef YY_USE_PROTOS +void yyrestart( FILE *input_file ) +#else +void yyrestart( input_file ) +FILE *input_file; +#endif + { + if ( ! yy_current_buffer ) + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); + + yy_init_buffer( yy_current_buffer, input_file ); + yy_load_buffer_state(); + } + + +#ifdef YY_USE_PROTOS +void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) +#else +void yy_switch_to_buffer( new_buffer ) +YY_BUFFER_STATE new_buffer; +#endif + { + if ( yy_current_buffer == new_buffer ) + return; + + if ( yy_current_buffer ) + { + /* Flush out information for old buffer. */ + *yy_c_buf_p = yy_hold_char; + yy_current_buffer->yy_buf_pos = yy_c_buf_p; + yy_current_buffer->yy_n_chars = yy_n_chars; + } + + yy_current_buffer = new_buffer; + yy_load_buffer_state(); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + yy_did_buffer_switch_on_eof = 1; + } + + +#ifdef YY_USE_PROTOS +void yy_load_buffer_state( void ) +#else +void yy_load_buffer_state() +#endif + { + yy_n_chars = yy_current_buffer->yy_n_chars; + filttext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos; + yyin = yy_current_buffer->yy_input_file; + yy_hold_char = *yy_c_buf_p; + } + + +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_create_buffer( FILE *file, int size ) +#else +YY_BUFFER_STATE yy_create_buffer( file, size ) +FILE *file; +int size; +#endif + { + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer( b, file ); + + return b; + } + + +#ifdef YY_USE_PROTOS +void yy_delete_buffer( YY_BUFFER_STATE b ) +#else +void yy_delete_buffer( b ) +YY_BUFFER_STATE b; +#endif + { + if ( ! b ) + return; + + if ( b == yy_current_buffer ) + yy_current_buffer = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yy_flex_free( (void *) b->yy_ch_buf ); + + yy_flex_free( (void *) b ); + } + + + +#ifdef YY_USE_PROTOS +void yy_init_buffer( YY_BUFFER_STATE b, FILE *file ) +#else +void yy_init_buffer( b, file ) +YY_BUFFER_STATE b; +FILE *file; +#endif + + + { + yy_flush_buffer( b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + +#if YY_ALWAYS_INTERACTIVE + b->yy_is_interactive = 1; +#else +#if YY_NEVER_INTERACTIVE + b->yy_is_interactive = 0; +#else + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; +#endif +#endif + } + + +#ifdef YY_USE_PROTOS +void yy_flush_buffer( YY_BUFFER_STATE b ) +#else +void yy_flush_buffer( b ) +YY_BUFFER_STATE b; +#endif + + { + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == yy_current_buffer ) + yy_load_buffer_state(); + } + + +#ifndef YY_NO_SCAN_BUFFER +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size ) +#else +YY_BUFFER_STATE yy_scan_buffer( base, size ) +char *base; +yy_size_t size; +#endif + { + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer( b ); + + return b; + } +#endif + + +#ifndef YY_NO_SCAN_STRING +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str ) +#else +YY_BUFFER_STATE yy_scan_string( yy_str ) +yyconst char *yy_str; +#endif + { + int len; + for ( len = 0; yy_str[len]; ++len ) + ; + + return yy_scan_bytes( yy_str, len ); + } +#endif + + +#ifndef YY_NO_SCAN_BYTES +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len ) +#else +YY_BUFFER_STATE yy_scan_bytes( bytes, len ) +yyconst char *bytes; +int len; +#endif + { + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = len + 2; + buf = (char *) yy_flex_alloc( n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < len; ++i ) + buf[i] = bytes[i]; + + buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer( buf, n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; + } +#endif + + +#ifndef YY_NO_PUSH_STATE +#ifdef YY_USE_PROTOS +static void yy_push_state( int new_state ) +#else +static void yy_push_state( new_state ) +int new_state; +#endif + { + if ( yy_start_stack_ptr >= yy_start_stack_depth ) + { + yy_size_t new_size; + + yy_start_stack_depth += YY_START_STACK_INCR; + new_size = yy_start_stack_depth * sizeof( int ); + + if ( ! yy_start_stack ) + yy_start_stack = (int *) yy_flex_alloc( new_size ); + + else + yy_start_stack = (int *) yy_flex_realloc( + (void *) yy_start_stack, new_size ); + + if ( ! yy_start_stack ) + YY_FATAL_ERROR( + "out of memory expanding start-condition stack" ); + } + + yy_start_stack[yy_start_stack_ptr++] = YY_START; + + BEGIN(new_state); + } +#endif + + +#ifndef YY_NO_POP_STATE +static void yy_pop_state() + { + if ( --yy_start_stack_ptr < 0 ) + YY_FATAL_ERROR( "start-condition stack underflow" ); + + BEGIN(yy_start_stack[yy_start_stack_ptr]); + } +#endif + + +#ifndef YY_NO_TOP_STATE +static int yy_top_state() + { + return yy_start_stack[yy_start_stack_ptr - 1]; + } +#endif + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +#ifdef YY_USE_PROTOS +static void yy_fatal_error( yyconst char msg[] ) +#else +static void yy_fatal_error( msg ) +char msg[]; +#endif + { + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); + } + + + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + yytext[yyleng] = yy_hold_char; \ + yy_c_buf_p = yytext + n; \ + yy_hold_char = *yy_c_buf_p; \ + *yy_c_buf_p = '\0'; \ + yyleng = n; \ + } \ + while ( 0 ) + + +/* Internal utility routines. */ + +#ifndef filttext_ptr +#ifdef YY_USE_PROTOS +static void yy_flex_strncpy( char *s1, yyconst char *s2, int n ) +#else +static void yy_flex_strncpy( s1, s2, n ) +char *s1; +yyconst char *s2; +int n; +#endif + { + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; + } +#endif + +#ifdef YY_NEED_STRLEN +#ifdef YY_USE_PROTOS +static int yy_flex_strlen( yyconst char *s ) +#else +static int yy_flex_strlen( s ) +yyconst char *s; +#endif + { + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; + } +#endif + + +#ifdef YY_USE_PROTOS +static void *yy_flex_alloc( yy_size_t size ) +#else +static void *yy_flex_alloc( size ) +yy_size_t size; +#endif + { + return (void *) malloc( size ); + } + +#ifdef YY_USE_PROTOS +static void *yy_flex_realloc( void *ptr, yy_size_t size ) +#else +static void *yy_flex_realloc( ptr, size ) +void *ptr; +yy_size_t size; +#endif + { + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); + } + +#ifdef YY_USE_PROTOS +static void yy_flex_free( void *ptr ) +#else +static void yy_flex_free( ptr ) +void *ptr; +#endif + { + free( ptr ); + } + +#if YY_MAIN +int main() + { + yylex(); + return 0; + } +#endif +#line 865 "filt.l" + + +/* + * + * Private Routines + * + * + */ + + +#ifdef YY_USE_PROTOS +static void floatprefix(void) +#else +static void floatprefix() +#endif +{ + if( filt->method == METHOD_C ) + _FiltLexCat("(double)"); +} + +#ifdef YY_USE_PROTOS +static void floatsuffix(void) +#else +static void floatsuffix() +#endif +{ + return; +} + +#ifdef YY_USE_PROTOS +static void +bin2num(char *d, char *s, int maxlen) +#else +static void +bin2num(d, s, maxlen) + char *d; + char *s; + int maxlen; +#endif +{ + unsigned long bits; + char *p=NULL; + + if( strlen(s) < 2 ){ + if( d != s ) strncpy(d, s, maxlen-1); + } + else{ + if( (*s=='0') && (*(s+1)=='b') ){ + bits = strtoul(s+2, &p, 2); + if( *p != '\0' ) _filterror("invalid binary value"); + snprintf(d, maxlen, "%lx", bits); + if( (strlen(d) <2) || (*d!='0') || ((*(d+1)!='x')&&((*(d+1)!='X'))) ){ + snprintf(d, maxlen, "0x%lx", bits); + } + } + else{ + if( d != s ) strncpy(d, s, maxlen-1); + } + } +} + +/* + * + * _FiltLexNew -- finish last start and set up new filter segment + * + */ +#ifdef YY_USE_PROTOS +static void +_FiltLexNew(void) +#else +static void _FiltLexNew() +#endif +{ + int i; + int last; + + if( nfiltseg >= maxfiltseg ){ + last = maxfiltseg; + if( maxfiltseg == 0 ){ + maxfiltseg = SEGINC; + filtseg = (FiltSeg *)xmalloc(maxfiltseg * sizeof(FiltSeg)); + } + else{ + maxfiltseg += SEGINC; + filtseg = (FiltSeg *)xrealloc(filtseg, maxfiltseg * sizeof(FiltSeg)); + } + /* clear the unused records */ + for(i=last; is) ){ + filtseg[nfiltseg] = (FiltSeg)xcalloc(1, sizeof(FiltSegRec)); + nfiltseg++; + } + filtseg[nfiltseg-1]->n = nfiltseg-1; + filtseg[nfiltseg-1]->nregion = 0; +} + +/* + * + * _FiltLexParen -- add a paren to the filter string buffer + * + */ +#ifdef YY_USE_PROTOS +static void +_FiltLexParen(char *str) +#else +static void _FiltLexParen(str) + char *str; +#endif +{ + /* _FiltLexNew(); */ + _FiltLexCat(str); + /* _FiltLexNew(); */ +} + +/* + * + * __FiltLexCat -- add a string to the filter string buffer + * + */ +#ifdef YY_USE_PROTOS +static void +__FiltLexCat(char *str, char **ostr, int *olen) +#else +static void __FiltLexCat(str, ostr, olen) + char *str; + char **ostr; + int *olen; +#endif +{ + int blen; + int slen; + + if( (str == NULL) || (*str == '\0') ) + return; + else + slen = strlen(str) + 1; + + if( (*ostr == NULL) || (**ostr == '\0') ) + blen = 0; + else + blen = strlen(*ostr); + + while( (blen + slen) >= *olen ){ + *olen += SEGINC; + } + if( blen == 0 ) + *ostr = (char *)xcalloc(*olen, sizeof(char)); + else + *ostr = (char *)xrealloc(*ostr, *olen); + strcat(*ostr, str); +} + +/* + * + * _FiltLexCat -- add a string to the filter string buffer + * + */ +#ifdef YY_USE_PROTOS +static void +_FiltLexCat(char *str) +#else +static void _FiltLexCat(str) + char *str; +#endif +{ + char *s; + if( !str || !*str ) + return; + if( nfiltseg ==0 ) + _FiltLexNew(); + s = xmalloc(strlen(str)+1); + nowhite(str, s); + __FiltLexCat(s, &(filtseg[nfiltseg-1]->s), &(filtseg[nfiltseg-1]->len)); + if( s ) xfree(s); +} + +/* + * + * _FiltLexArgSave -- save a radius or angle value to the temp string: + * this is a special hack for funcnts + * + */ +#ifdef YY_USE_PROTOS +static void +_FiltLexArgSave(double dval) +#else +static void _FiltLexArgSave(dval) + double dval; +#endif +{ + char tbuf[SZ_LINE]; + + if( narg < 3 ) + return; + snprintf(tbuf, SZ_LINE, DFMT1, dval); + if( narg == 3 ){ + *lastarg = '\0'; + lastd1 = 0.0; + lastd2 = 0.0; + if( filtseg[nfiltseg-1]->radang ){ + xfree(filtseg[nfiltseg-1]->radang); + filtseg[nfiltseg-1]->radang = NULL; + filtseg[nfiltseg-1]->ralen = 0; + } + } + switch(regid){ + case TY_ANNULUS: + case TY_CIRCLE: + if( *lastarg ){ + __FiltLexCat(lastarg, &(filtseg[nfiltseg-1]->radang), + &(filtseg[nfiltseg-1]->ralen)); + } + __FiltLexCat(tbuf, &(filtseg[nfiltseg-1]->radang), + &(filtseg[nfiltseg-1]->ralen)); + if( narg > 3 ){ + __FiltLexCat(",NA,NA\n", &(filtseg[nfiltseg-1]->radang), + &(filtseg[nfiltseg-1]->ralen)); + strcpy(lastarg, tbuf); + } + lastd1 = lastd2; + lastd2 = dval; + break; + + case TY_BOX: + case TY_ELLIPSE: + if( (narg%2) == 1 ){ + if( *lastarg ){ + __FiltLexCat(lastarg, &(filtseg[nfiltseg-1]->radang), + &(filtseg[nfiltseg-1]->ralen)); + } + __FiltLexCat(tbuf, &(filtseg[nfiltseg-1]->radang), + &(filtseg[nfiltseg-1]->ralen)); + if( narg > 3 ){ + __FiltLexCat(",NA,NA\n", &(filtseg[nfiltseg-1]->radang), + &(filtseg[nfiltseg-1]->ralen)); + strcpy(lastarg, tbuf); + } + lastd1 = lastd2; + lastd2 = dval; + } + break; + + case TY_PIE: + if( narg == 3 ){ + __FiltLexCat("NA,NA", &(filtseg[nfiltseg-1]->radang), + &(filtseg[nfiltseg-1]->ralen)); + } + else if( *lastarg ){ + __FiltLexCat("NA,NA,", &(filtseg[nfiltseg-1]->radang), + &(filtseg[nfiltseg-1]->ralen)); + __FiltLexCat(lastarg, &(filtseg[nfiltseg-1]->radang), + &(filtseg[nfiltseg-1]->ralen)); + } + __FiltLexCat(tbuf, &(filtseg[nfiltseg-1]->radang), + &(filtseg[nfiltseg-1]->ralen)); + if( narg > 3 ){ + __FiltLexCat("\n", &(filtseg[nfiltseg-1]->radang), + &(filtseg[nfiltseg-1]->ralen)); + strcpy(lastarg, tbuf); + } + lastd1 = lastd2; + lastd2 = dval; + break; + + case TY_POINT: + /* we have to process this here if its is a varargs */ + /* so, for the 3rd arg, we add a line for initial x, y pair */ + if( narg == 3 ){ + __FiltLexCat("NA,NA,NA,NA\n", &(filtseg[nfiltseg-1]->radang), + &(filtseg[nfiltseg-1]->ralen)); + } + /* and for every even arg, add a line for the preceeding x,y pair */ + else if( (narg % 2) == 0 ){ + __FiltLexCat("NA,NA,NA,NA\n", &(filtseg[nfiltseg-1]->radang), + &(filtseg[nfiltseg-1]->ralen)); + } + break; + default: + return; + } +} + +/* + * + * _FiltLexAccel -- appply acceleration to a segment + * + */ +#ifdef YY_USE_PROTOS +static int +_FiltLexAccel(int n) +#else +static int _FiltLexAccel(n) + int n; +#endif +{ + int i; + char tbuf[SZ_LINE]; + char *s; + double dinc; + + /* check region type */ + switch(regid){ + case TY_ANNULUS: + break; + case TY_BOX: + narg -= 2; + break; + case TY_CIRCLE: + narg -= 1; + break; + case TY_ELLIPSE: + narg -= 2; + break; + case TY_PIE: + break; + default: + _filterror("annulus, box, circle, ellipse, pie accelerators only - "); + break; + } + /* add the argument */ + snprintf(tbuf, SZ_LINE, IFMT1, n); + _FiltLexCat(tbuf); + /* change the name of the routine we will call */ + if( filtseg[nfiltseg-1]->s0 ){ + if( (s = xstrdup(&filtseg[nfiltseg-1]->s[filtseg[nfiltseg-1]->s0])) ){ + filtseg[nfiltseg-1]->s[filtseg[nfiltseg-1]->s0] = '\0'; + _FiltLexCat("n"); + _FiltLexCat(s); + snprintf(tbuf, SZ_LINE, "%d ", n); + __FiltLexCat(tbuf, &(filtseg[nfiltseg-1]->regions), + &(filtseg[nfiltseg-1]->nr)); + __FiltLexCat(tbuf, &(filtseg[nfiltseg-1]->shapes), + &(filtseg[nfiltseg-1]->ns)); + setargs = 1; + free (s); + } + if( filtseg[nfiltseg-1]->radang ){ + xfree(filtseg[nfiltseg-1]->radang); + filtseg[nfiltseg-1]->radang = NULL; + filtseg[nfiltseg-1]->ralen = 0; + } + switch(regid){ + case TY_ANNULUS: + case TY_BOX: + case TY_CIRCLE: + case TY_ELLIPSE: + dinc = (lastd2 - lastd1)/n; + for(i=1; i<=n; i++){ + snprintf(tbuf, SZ_LINE, DFMT2, lastd1+((i-1)*dinc), lastd1+(i*dinc)); + __FiltLexCat(tbuf, &(filtseg[nfiltseg-1]->radang), + &(filtseg[nfiltseg-1]->ralen)); + __FiltLexCat(",NA,NA", &(filtseg[nfiltseg-1]->radang), + &(filtseg[nfiltseg-1]->ralen)); + __FiltLexCat("\n", &(filtseg[nfiltseg-1]->radang), + &(filtseg[nfiltseg-1]->ralen)); + } + break; + case TY_PIE: + dinc = (lastd2 - lastd1)/n; + for(i=1; i<=n; i++){ + snprintf(tbuf, SZ_LINE, DFMT2, lastd1+((i-1)*dinc), lastd1+(i*dinc)); + __FiltLexCat("NA,NA", &(filtseg[nfiltseg-1]->radang), + &(filtseg[nfiltseg-1]->ralen)); + __FiltLexCat(tbuf, &(filtseg[nfiltseg-1]->radang), + &(filtseg[nfiltseg-1]->ralen)); + __FiltLexCat("\n", &(filtseg[nfiltseg-1]->radang), + &(filtseg[nfiltseg-1]->ralen)); + } + break; + default: + _filterror("annulus, box, circle, ellipse, pie accelerators only - "); + break; + } + _FiltLexTypeSet(TOK_ACCEL); + } + else{ + _filterror("misplaced accelerator"); + } + return(n); +} + +/* + * + * _FiltLexTypeSet -- add type info to the filter segment record + * + */ +#ifdef YY_USE_PROTOS +static void +_FiltLexTypeSet(int type) +#else +static void _FiltLexTypeSet(type) + int type; +#endif +{ + if( nfiltseg ==0 ) + _FiltLexNew(); + filtseg[nfiltseg-1]->type |= type; +} + +/* + * + * _FiltLexOp -- add an operator to the filter segment record + * + */ +#ifdef YY_USE_PROTOS +static void +_FiltLexOp(char *op) +#else +static void _FiltLexOp(op) + char *op; +#endif +{ + _FiltLexCat(op); + filtseg[nfiltseg-1]->ops += 1; +} + +#ifdef YY_USE_PROTOS +static void +_FiltLexRegionStart(int docols) +#else +static void _FiltLexRegionStart(docols) + int docols; +#endif +{ + char *s, *t; + char tbuf[SZ_LINE]; + + /* sanity check -- 1D images do not support regions */ + if( (filt->type == TYPE_IMAGE) && (ft_naxes(filt->fhd)==1) ){ + _filterror("2D region filters invalid for 1D images"); + } + narg = 0; + setargs=0; + s = xmalloc(strlen(yytext)+1); + nowhite(yytext, s); + if( *s == '+' ){ + regtype = TOK_IREG; + strcpy(regname, s+1); + } + else if( *s == '-' ){ + regtype = TOK_EREG; + strcpy(regname, s+1); + } + else if( *s == '!' ){ + regtype = TOK_NREG; + strcpy(regname, s+1); + } + else{ + regtype = TOK_IREG; + strcpy(regname, s); + } + _FiltLexTypeSet(regtype); + if( !(t=strchr(regname, '(')) ){ + nsparen=0; + } + /* remove the paren from the regname string -- we will explicitly add it */ + else{ + *t = '\0'; + nsparen=1; + } + /* convert to lower case, remove white space */ + culc(regname); + nowhite(regname, s); + strcpy(regname, s); + /* convert abbrev to region */ + if( !strncmp(regname, "ann", 3) ){ + strcpy(regname, "annulus"); + regid = TY_ANNULUS; + } + else if( !strncmp(regname, "box", 3) ){ + strcpy(regname, "box"); + regid = TY_BOX; + } + else if( !strncmp(regname, "cir", 3) ){ + strcpy(regname, "circle"); + regid = TY_CIRCLE; + } + else if( !strncmp(regname, "ell", 3) ){ + strcpy(regname, "ellipse"); + regid = TY_ELLIPSE; + } + else if( !strncmp(regname, "fie", 3) ){ + strcpy(regname, "field"); + regid = TY_FIELD; + } + else if( !strncmp(regname, "lin", 3) ){ + strcpy(regname, "line"); + regid = TY_LINE; + } + else if( !strncmp(regname, "pan", 3) ){ + strcpy(regname, "panda"); + regid = TY_PANDA; + } + else if( !strncmp(regname, "bpa", 3) ){ + strcpy(regname, "bpanda"); + regid = TY_BPANDA; + } + else if( !strncmp(regname, "cpa", 3) ){ + strcpy(regname, "cpanda"); + regid = TY_CPANDA; + } + else if( !strncmp(regname, "epa", 3) ){ + strcpy(regname, "epanda"); + regid = TY_EPANDA; + } + else if( !strncmp(regname, "pie", 3) ){ + strcpy(regname, "pie"); + regid = TY_PIE; + } + else if( !strncmp(regname, "qtp", 3) ){ + strcpy(regname, "qtpie"); + regid = TY_PIE; + } + else if( !strncmp(regname, "poi", 3) ){ + strcpy(regname, "point"); + regid = TY_POINT; + } + else if( !strncmp(regname, "pol", 3) ){ + strcpy(regname, "polygon"); + regid = TY_POLYGON; + } + else if( !strcmp(regname, "imagemask") ){ + regid = TY_IMAGEMASK; + } + /* append filter-type prefix */ + switch( filt->type ){ + case TYPE_EVENTS: + /* normally, we filter rows analytically using evregions.o */ + if( !filt->evsect ) + _FiltLexCat("ev"); + /* if evsect=xxx is specified, we filter by image pixels */ + else + _FiltLexCat("im"); + break; + case TYPE_IMAGE: + /* image are filtered by image pixels */ + _FiltLexCat("im"); + break; + } + /* no region value to start */ + filtseg[nfiltseg-1]->regval = 0; + /* save size of current string so we can get back to the region string */ + filtseg[nfiltseg-1]->s0 = strlen(filtseg[nfiltseg-1]->s); + /* append region */ + _FiltLexCat(FilterLexRegion1(filt,regname)); + /* append standard args */ + _FiltLexCat("(g,$RS,"); + /* add include/exclude and whether we mark y lines for this region + (we don't mark y on excludes as an optimization) */ + switch(regtype){ + case TOK_IREG: + snprintf(tbuf, SZ_LINE, "1,%d", TOK_IREG); + _FiltLexCat(tbuf); + break; + case TOK_NREG: + snprintf(tbuf, SZ_LINE, "0,%d", TOK_NREG); + _FiltLexCat(tbuf); + break; + case TOK_EREG: + snprintf(tbuf, SZ_LINE, "0,%d", TOK_EREG); + _FiltLexCat(tbuf); + break; + } + switch(docols){ + case 0: + /* initialize default columns for tables -- but don't enter symbols yet */ + FilterSymbolDefaults(filt, 0); + /* initialize wcs for default image case */ + _FiltLexWcsCols(filt->fhd, filt->xbin, filt->ybin); + _FiltLexCat(","); + floatprefix(); + _FiltLexCat("x"); + floatsuffix(); + _FiltLexCat(","); + floatprefix(); + _FiltLexCat("y"); + floatsuffix(); + break; + case 1: + if( !initbindefs ){ + /* initialize default columns for tables and enter symbols */ + FilterSymbolDefaults(filt, 1); + /* initialize wcs for default table case */ + _FiltLexWcsCols(filt->fhd, filt->xbin, filt->ybin); + initbindefs++; + } + if( !filt->xbin || !filt->ybin ){ + _filterror("two binning columns are required for regions"); + } + _FiltLexCat(","); + floatprefix(); + _FiltLexCat(filt->xbin); + floatsuffix(); + _FiltLexCat(","); + floatprefix(); + _FiltLexCat(filt->ybin); + floatsuffix(); + break; + case 2: + _FiltLexCat(","); + floatprefix(); + _FiltLexCat(colnames[0]); + floatsuffix(); + _FiltLexCat(","); + floatprefix(); + _FiltLexCat(colnames[1]); + floatsuffix(); + break; + } + if( s ) xfree(s); +} + +#ifdef YY_USE_PROTOS +static void +_FiltLexRegionVal(char *s) +#else +static void +_FiltLexRegionVal(s) + char *s; +#endif +{ + char *t=NULL; + if( (t=strchr(s, '{')) ){ + t++; + } + else{ + t = s; + } + filtseg[nfiltseg-1]->regval = atoi(t); +} + +#ifdef YY_USE_PROTOS +static void +_FiltLexRegionEnd(void) +#else +static void +_FiltLexRegionEnd() +#endif +{ + int n; + char *s; + char ebuf[SZ_LINE]; + char tbuf[SZ_LINE]; + + /* add final arguments as required */ + switch( regid ){ + case TY_BOX: + if( (narg%2) == 0 ){ + _FiltLexCat(",0.0"); narg++; + } + else{ + /* if we saved an angle arg, we need to replace the last position arg */ + if( *saveang ){ + if( (s=strrchr(filtseg[nfiltseg-1]->s, ',')) ){ + *s = '\0'; + _FiltLexCat(saveang); + } + } + } + break; + case TY_ELLIPSE: + if( (narg%2) == 0 ){ + _FiltLexCat(",0.0"); narg++; + } + else{ + /* if we saved an angle arg, we need to replace the last position arg */ + if( *saveang ){ + if( (s=strrchr(filtseg[nfiltseg-1]->s, ',')) ){ + *s = '\0'; + _FiltLexCat(saveang); + } + } + } + break; + case TY_BPANDA: + case TY_EPANDA: + if( (narg%2) == 0 ){ + _FiltLexCat(",0.0"); narg++; + } + /* drop through here to process panda */ + case TY_PANDA: + case TY_CPANDA: + _FiltLexRegionPanda(); + setargs = 1; + break; + default: + break; + } + + /* argument check */ + if( (n=_FiltLexArgCheck(regname, narg)) > 0 ){ + /* don't bother printing where we are in region */ + *yytext = '\0'; + switch( vargs[n-1] ){ + case 'n': + snprintf(ebuf, SZ_LINE, "'%s' requires %d args (%d found)", + rnames[n-1], rargs[n-1], narg); + break; + case 'e': + snprintf(ebuf, SZ_LINE, + "'%s' requires at least %d (even) args (%d found)", + rnames[n-1], rargs[n-1], narg); + break; + case 'o': + snprintf(ebuf, SZ_LINE, + "'%s' requires at least %d (odd) args (%d found)", + rnames[n-1], rargs[n-1], narg); + break; + case 'y': + default: + snprintf(ebuf, SZ_LINE, "'%s' requires %d args (%d found)", + rnames[n-1], rargs[n-1], narg); + break; + } + _filterror(ebuf); + } + + /* process varargs */ + if( (n < 0) || (regid == TY_POLYGON) ){ + if( filtseg[nfiltseg-1]->type & TOK_ACCEL ){ + _filterror("n= and variable arglist cannot be combined -"); + } + /* if its a varargs, we need to end with PSTOP values */ + snprintf(sbuf, SZ_LINE, DFMT2, PSTOP, PSTOP); + _FiltLexCat(sbuf); + /* change the name of the routine we will call */ + if( regid != TY_POLYGON ){ + if( filtseg[nfiltseg-1]->s0 ){ + if((s = xstrdup(&filtseg[nfiltseg-1]->s[filtseg[nfiltseg-1]->s0]))){ + filtseg[nfiltseg-1]->s[filtseg[nfiltseg-1]->s0] = '\0'; + _FiltLexCat("v"); + _FiltLexCat(s); + switch(regid){ + case TY_ANNULUS: + n = narg - 3; + break; + case TY_BOX: + n = (narg - 5)/2; + break; + case TY_CIRCLE: + n = narg - 3; + break; + case TY_ELLIPSE: + n = (narg - 5)/2; + break; + case TY_PIE: + n = narg - 3; + break; + case TY_POINT: + n = narg/2; + break; + default: + _filterror("varargs: annulus, box, circle, ellipse, pie, point;"); + break; + } + snprintf(tbuf, SZ_LINE, "%d ", n); + __FiltLexCat(tbuf, &(filtseg[nfiltseg-1]->regions), + &(filtseg[nfiltseg-1]->nr)); + __FiltLexCat(tbuf, &(filtseg[nfiltseg-1]->shapes), + &(filtseg[nfiltseg-1]->ns)); + setargs = 1; + free (s); + } + _FiltLexTypeSet(TOK_VARARGS); + } + else{ + _filterror("invalid varargs"); + } + } + } + + + /* set number of regions and shapes, if not already done */ + if( !setargs ){ + snprintf(tbuf, SZ_LINE, "%d ", 1); + __FiltLexCat(tbuf, &(filtseg[nfiltseg-1]->regions), + &(filtseg[nfiltseg-1]->nr)); + __FiltLexCat(tbuf, &(filtseg[nfiltseg-1]->shapes), + &(filtseg[nfiltseg-1]->ns)); + } + + /* finish off region string */ + _FiltLexCat(FilterLexRegion2(filt,")")); + + /* no column arguments */ + colargs = 0; + /* arguments are not set */ + setargs = 0; + /* save angle not set */ + *saveang = 0; +} + +#ifdef YY_USE_PROTOS +static int +_FiltLexRegionPanda(void) +#else +static int +_FiltLexRegionPanda() +#endif +{ + int i; + int n=0; + int got=0; + int a, r; + int ahi=0, rhi=0; + int hi=0; + double d[11]; + double ainc=0.0, rinc=0.0; + char tbuf[SZ_LINE]; + char *s=NULL; + char *t, *u; + + switch(regid){ + case TY_PANDA: + case TY_CPANDA: + hi = 7; + break; + case TY_BPANDA: + case TY_EPANDA: + hi = 10; + break; + default: + _filterror("unknown panda type -- contact saord@cfa.harvard.edu"); + break; + } + s = xstrdup(filtseg[nfiltseg-1]->s); + for(i=hi; i>=0; i--){ + /* look for last comma */ + t = strrchr(s, ','); + if( !t ) goto done; + /* null it out from base string */ + *t = '\0'; + /* point past comma and get double value */ + t++; + d[i] = strtod(t, &u); + if( t == u ) goto done; + } + + switch(regid){ + case TY_PANDA: + case TY_CPANDA: + ainc = (d[3] - d[2])/d[4]; + ahi = (int)d[4]; + rinc = (d[6] - d[5])/d[7]; + rhi = (int)d[7]; + break; + case TY_BPANDA: + case TY_EPANDA: + ainc = (d[3] - d[2])/d[4]; + ahi = (int)d[4]; + rinc = (d[7] - d[5])/d[9]; + rhi = (int)d[9]; + break; + default: + _filterror("unknown panda type -- contact saord@cfa.harvard.edu"); + break; + } + /* process limits arguments */ + for(a=1; a<=ahi; a++){ + for(r=1; r<=rhi; r++){ + snprintf(tbuf, SZ_LINE, DFMT4, + d[5]+((r-1)*rinc), d[5]+(r*rinc), + d[2]+((a-1)*ainc), d[2]+(a*ainc)); + __FiltLexCat(tbuf, &(filtseg[nfiltseg-1]->radang), + &(filtseg[nfiltseg-1]->ralen)); + __FiltLexCat("\n", &(filtseg[nfiltseg-1]->radang), + &(filtseg[nfiltseg-1]->ralen)); + n++; + } + } + + /* adjust region and shape count */ + snprintf(tbuf, SZ_LINE, "%d ", n); + __FiltLexCat(tbuf, &(filtseg[nfiltseg-1]->regions), + &(filtseg[nfiltseg-1]->nr)); + snprintf(tbuf, SZ_LINE, "%d ", 2*n); + __FiltLexCat(tbuf, &(filtseg[nfiltseg-1]->shapes), + &(filtseg[nfiltseg-1]->ns)); + _FiltLexTypeSet(TOK_ACCEL); + /* success */ + got = 1; + +done: + if( s ) xfree(s); + return got; +} + +/* + * + * _FiltLexRangeAdd -- add a rangelist string to the filter string buffer + * + */ +#ifdef YY_USE_PROTOS +static void +_FiltLexRangeAdd(char *xname, char *str, int type, int n, int maxlen) +#else +static void _FiltLexRangeAdd(xname, str, type, n, maxlen) + char *xname; + char *str; + int type; + int n; + int maxlen; +#endif +{ + char tbuf[SZ_LINE]; + char tbuf2[SZ_LINE]; + char *s; + char *t; + char *t2; + char *name; + + /* get "in-expression" name for current technique */ + name = FilterLexName(filt, xname); + + /* initialize pointers */ + s = str; + t = tbuf; + + /* clear working buffer */ + memset(t, 0, SZ_LINE); + + /* if this is not the beginning, we first need to OR with prev */ + if( n != 0 ) strncat(t, "||", maxlen-1); + + /* put in parens for safety */ + strncat(t, "(", maxlen-1); + + /* add the name */ + strncat(t, name, maxlen-1); + + /* add the rangelist */ + switch(type){ + case 1: + strncat(t, "<=", maxlen-1); + /* skip past : */ + s++; + /* append value */ + t2 = tbuf2; + while( *s ){ + *t2++ = *s++; + } + *t2 = '\0'; + bin2num(tbuf2, tbuf2, maxlen-1); + strncat(t, tbuf2, maxlen-1); + break; + case 2: + strncat(t, "==", maxlen-1); + /* append upper value */ + t2 = tbuf2; + while( *s ){ + *t2++ = *s++; + } + *t2 = '\0'; + bin2num(tbuf2, tbuf2, maxlen-1); + strncat(t, tbuf2, maxlen-1); + break; + case 3: + strncat(t, ">=", maxlen-1); + /* append lower value */ + t2 = tbuf2; + while( *s && (*s != ':') ){ + *t2++ = *s++; + } + *t2 = '\0'; + bin2num(tbuf2, tbuf2, maxlen-1); + strncat(t, tbuf2, maxlen-1); + /* skip past : */ + s++; + strncat(t, "&&", maxlen-1); + strncat(t, name, maxlen-1); + strncat(t, "<=", maxlen-1); + /* append upper value */ + t2 = tbuf2; + while( *s ){ + *t2++ = *s++; + } + *t2 = '\0'; + bin2num(tbuf2, tbuf2, maxlen-1); + strncat(t, tbuf2, maxlen-1); + break; + case 4: + strncat(t, ">=", maxlen-1); + /* append lower value */ + t2 = tbuf2; + while( *s && (*s != ':') ){ + *t2++ = *s++; + } + *t2 = '\0'; + bin2num(tbuf2, tbuf2, maxlen-1); + strncat(t, tbuf2, maxlen-1); + break; + } + strncat(t, ")", maxlen-1); + _FiltLexCat(tbuf); +} + +/* + * + * _FiltLexTypeCmp -- compare routine for qsort + * + */ +#ifdef YY_USE_PROTOS +static int +_FiltLexTypeCmp(const void *s1, const void *s2) +#else +static int _FiltLexTypeCmp(s1, s2) + const void *s1; + const void *s2; +#endif +{ + FiltSeg *f1 = (FiltSeg *)s1; + FiltSeg *f2 = (FiltSeg *)s2; + + /* check for broken qsort */ + if( !*f1 || !*f2 ){ + _filterror("qsort is broken -- contact saord@cfa.harvard.edu"); + /* will not happen */ + return 0; + } + + /* make sure null string is at the end */ + if( !(*f1)->s && !(*f2)->s ) return 0; + else if( !(*f1)->s ) return 1; + else if( !(*f2)->s ) return -1; + + /* paint: reverse order and make excludes local */ + if( filt->paint ){ + /* if both are regions, reverse order */ + if( ((*f1)->type & TOK_REG) && ((*f2)->type & TOK_REG) ){ + if( (*f1)->n < (*f2)->n ) return 1; + else if( (*f1)->n > (*f2)->n ) return -1; + else return 0; + } + /* keep same order */ + else{ + if( (*f1)->n < (*f2)->n ) return -1; + else if( (*f1)->n > (*f2)->n ) return 1; + else return 0; + } + } + else{ + /* if both or neither are eregions, keep them in the same order */ + if( ((*f1)->type & TOK_EREG) == ((*f2)->type & TOK_EREG) ){ + if( (*f1)->n < (*f2)->n ) return -1; + else if( (*f1)->n > (*f2)->n ) return 1; + else return 0; + } + /* exactly one is an eregion -- and we want eregions last */ + else{ + if( (*f1)->type & TOK_EREG ) return 1; + else if( (*f2)->type & TOK_EREG ) return -1; + /* should not happen */ + else return 0; + } + } +} + +/* + * + * _FiltLexTypeMatch -- see if the type of filtering we are doing + * matches the type of token we have + * + */ +#ifdef YY_USE_PROTOS +int +_FiltLexTypeMatch(int ftype, int ttype) +#else +int _FiltLexTypeMatch(ftype, ttype) + int ftype; + int ttype; +#endif +{ + switch(ftype){ + case TYPE_IMAGE: + /* we don't allow range list and col names in image filters */ + if( (ttype & TOK_RLIST) || (ttype & TOK_NAME) ) + return 0; + /* everything else is fine */ + else + return 1; + case TYPE_EVENTS: + return 1; + default: + return 1; + } +} + +#ifdef YY_USE_PROTOS +static int +_FiltLexArgCheck(char *name, int args) +#else +static int _FiltLexArgCheck(name, args) + char *name; + int args; +#endif +{ + int i; + + for(i=0; rnames[i]; i++){ + if( !strcmp(name, rnames[i]) ){ + if( args == rargs[i] ){ + return(0); + } + else{ + /* less than required min */ + if( args < rargs[i] ) + return(i+1); + /* more than min args -- could be varargs */ + else{ + /* check args allowed in varargs */ + switch(vargs[i]){ + case 'e': + if( (args%2) == 0 ) + return(-1); + else + return(i+1); + case 'o': + if( (args%2) == 1 ) + return(-1); + else + return(i+1); + case 'y': + return(-1); + default: + return(i+1); + } + } + } + } + } + return(0); +} + +#ifdef YY_USE_PROTOS +static void +_FiltLexSetWcs(char *s) +#else +static void _FiltLexSetWcs(s) + char *s; +#endif +{ + char name[SZ_LINE]; + int ip=0; + + newdtable(",=;"); + /* get name of global coordsys */ + if( word(s, name, &ip) ){ + if( gcoordsys ) xfree(gcoordsys); + gcoordsys = xstrdup(name); + culc(gcoordsys); + } + /* restore old delim table */ + freedtable(); +} + +#ifdef YY_USE_PROTOS +static char * +_FiltLexCB(char *name, void *client_data) +#else +static char *_FiltLexCB(name, client_data) + char *name; + void *client_data; +#endif +{ + FiltSeg f=(FiltSeg)client_data; + int ip=0; + int nr=0; + int ns=0; + char *s; + char tbuf[SZ_LINE]; + + if( !strcmp(name, "RS") ){ + /* exclude regions get no region value first time around */ + if( (macropass==0) && (f->type & TOK_EREG) ){ + return NULL; + } + /* get next region value and remove from string */ + if( word(f->regions, tbuf, &ip) ){ + nr = atoi(tbuf); + s = xstrdup(&(f->regions[ip])); + xfree(f->regions); + f->regions = s; + } + else{ + _filterror("internal error: no region string specified"); + return(NULL); + } + if( !inexpr || (f->type & (TOK_ACCEL|TOK_VARARGS)) ){ + if( f->regval ){ + snprintf(macrobuf, SZ_LINE, "%d,", f->regval); + } + else{ + snprintf(macrobuf, SZ_LINE, "%d,", nregion+1); + } + nregion += nr; + f->nregion += nr; + inexpr = 1; + } + else{ + if( f->regval ){ + snprintf(macrobuf, SZ_LINE, "%d,", f->regval); + } + else{ + snprintf(macrobuf, SZ_LINE, "%d,", nregion); + } + } + + /* get next shape value and remove from string */ + ip = 0; + if( word(f->shapes, tbuf, &ip) ){ + ns = atoi(tbuf); + s = xstrdup(&(f->shapes[ip])); + xfree(f->shapes); + f->shapes = s; + } + else{ + _filterror("internal error: no shape string specified"); + return(NULL); + } + /* concat shape value */ + nshape++; + snprintf(tbuf, SZ_LINE, "%d", nshape); + strcat(macrobuf, tbuf); + /* set new shape value */ + nshape += (ns-1); + + /* return macro value */ + return(macrobuf); + } + else{ + return NULL; + } +} + +/* + * + * _FiltLexNeedOp -- determine if we add a connecting operator for this segment + * + */ +#ifdef YY_USE_PROTOS +static int +_FiltLexNeedOp(int i, char *s) +#else +static int _FiltLexNeedOp(i, s) + int i; + char *s; +#endif +{ + int c; + /* check for operator in current string */ + if( s && *s ){ + c = *s; + switch(c){ + case '&': + case '|': + case '=': + case '!': + case '<': + case '>': + return 0; + default: + break; + } + } + /* not in this string check for operator in previous */ + for(i=i-1; i>=0; i--){ + if( !filtseg[i] || !filtseg[i]->s ) continue; + if( strcmp(filtseg[i]->s, "(") && strcmp(filtseg[i]->s, ")") ) + break; + } + if( i >= 0 ){ + c = filtseg[i]->s[strlen(filtseg[i]->s)-1]; + switch(c){ + case '&': + case '|': + case '=': + case '!': + case '<': + case '>': + return 0; + default: + return 1; + } + } + else{ + return 0; + } +} + +/* + * + * _FiltLexMake -- generate filter from filter segments + * + */ +#ifdef YY_USE_PROTOS +static void +_FiltLexMake(void) +#else +static void _FiltLexMake() +#endif +{ + int i, j, k, l; + int x, xtot; + int type=0; + int ltype=0; + int opar=0; + char *s; + + /* debugging */ + if( filt->debug ){ + for(i=0; is ) + fprintf(stderr, "unsorted #%d %s\n", filtseg[i]->n, filtseg[i]->s); + else + fprintf(stderr, "unsorted #%d %d is empty\n", i, filtseg[i]->n); + } + } + /* look for bad region expressions and determine how many regions we have */ + for(i=0, j=0, k=0, l=0; is ) continue; + type = filtseg[i]->type; + /* make sure we want the type being offered */ + if( !_FiltLexTypeMatch(filt->type, type) ){ + _filterror("column filters not permitted in an image filter expression"); + } + /* look for bad combinations */ + if( (type & TOK_NREG) && !(type & TOK_IREG) ) + _filterror("!region must be combined with another region (e.g., field()&&!region)"); + if( (type & TOK_EREG) && (type & TOK_IREG) ) + _filterror("-region must not be combined with another region (use !region instead)"); + if( (type & TOK_EREG) && (type & TOK_NAME) ) + _filterror("-region must not be combined with filters (use !region instead)"); + if( (type & TOK_EREG) && (type & TOK_RLIST) ) + _filterror("-region must not be combined with range lists (use !region instead)"); + if( (type & TOK_EREG) && (type & TOK_RTINE) ) + _filterror("-region must not be combined with routines (use !region instead)"); + /* count region types */ + if( filtseg[i]->type & TOK_IREG ) j++; + if( filtseg[i]->type & TOK_NREG ) k++; + if( filtseg[i]->type & TOK_EREG ) l++; + } + /* check for fits image mask and process specially */ + if( filt->masks ){ + /* can't have fits mask and ascii regions */ + if( j || k || l ){ + _filterror("FITS image masks cannot be combined with ASCII regions"); + } + /* image filtering of events uses a imagemask special routine */ + if( (filt->type == TYPE_EVENTS) && filt->evsect ){ + strcpy(yytext, "imagemask"); + _FiltLexRegionStart(1); + _FiltLexRegionEnd(); + } + else{ + __FiltLexCat("imagemask", &filter, &filtlen); + nregion = filt->nmaskreg; + return; + } + } + /* if we have only exclude regions, add field */ + if( !j && !k && l ){ + strcpy(yytext, "field"); + if( filt->type == TYPE_EVENTS ) + _FiltLexRegionStart(1); + else + _FiltLexRegionStart(0); + _FiltLexRegionEnd(); + } + + /* reset region and shape counts */ + nregion=0; + nshape=0; + + /* expand macro before reordering, to maintain region numbers in sequence */ + for(i=0; is ){ + if( _FiltLexNeedOp(i, NULL) ) inexpr=0; + macropass=0; + s = ExpandMacro(filtseg[i]->s, NULL, NULL, 0, _FiltLexCB, filtseg[i]); + xfree(filtseg[i]->s); + filtseg[i]->s = s; + } + } + + /* we want descending order so that eregions are last in the expression */ + qsort(filtseg, nfiltseg, sizeof(FiltSeg), _FiltLexTypeCmp); + + if( filt->debug ){ + for(i=0; is ) + fprintf(stderr, "sorted #%d %s\n", filtseg[i]->n, filtseg[i]->s); + else + fprintf(stderr, "sorted #%d %d is empty\n", i, filtseg[i]->n); + } + } + + /* add open paren and mark that we did it */ + __FiltLexCat("(", &filter, &filtlen); + opar = 1; + + /* run through segments, inserting proper boolean connectors */ + ltype = 0; + for(i=0; is ){ + /* no type probably means its a paren, so just add it and jump out */ + if( !filtseg[i]->type ){ + __FiltLexCat(filtseg[i]->s, &filter, &filtlen); + /* remove empty parens, if we just make them */ + x = strlen(filter); + if( (filter[x-2] == '(') && (filter[x-1] == ')') ) + filter[x-2] = '\0'; + i++; + continue; + } + type = filtseg[i]->type; + if( _FiltLexNeedOp(i, NULL) ) inexpr=0; + macropass=1; + s = ExpandMacro(filtseg[i]->s, NULL, NULL, 0, _FiltLexCB, filtseg[i]); + if( _FiltLexNeedOp(i, s) ){ + /* remove trailing open parens from prev. segment (add back later) */ + for(xtot=0, x=strlen(filter)-1; x>=0; x--){ + if( filter[x] != '(' ) break; + filter[x] = '\0'; + xtot++; + } + if( (ltype & TOK_IREG) && (type & TOK_IREG) ){ + __FiltLexCat("||", &filter, &filtlen); + } + else if( (ltype & TOK_IREG) && (type & TOK_EREG) ){ + if( opar > 0 ){ + __FiltLexCat(")", &filter, &filtlen); + opar--; + } + if( filt->paint ){ + if( opar > 0 ){ + __FiltLexCat(")", &filter, &filtlen); + opar --; + } + __FiltLexCat("||", &filter, &filtlen); + } + else{ + __FiltLexCat("&&", &filter, &filtlen); + } + __FiltLexCat("(", &filter, &filtlen); + opar++; + } + else if( (ltype & TOK_EREG) && (type & TOK_EREG) ){ + __FiltLexCat("&&", &filter, &filtlen); + } + else if( (ltype & TOK_EREG) && (type & TOK_IREG) ){ + if( filt->paint && (opar > 0) ){ + __FiltLexCat(")", &filter, &filtlen); + opar --; + } + __FiltLexCat("&&", &filter, &filtlen); + __FiltLexCat("(", &filter, &filtlen); + opar ++; + if( filt->paint ){ + __FiltLexCat("(", &filter, &filtlen); + opar++; + } + } + /* otherwise implied operator is AND */ + else{ + __FiltLexCat("&&", &filter, &filtlen); + } + /* add back parens */ + for(x=0; xpaint && (i==0) ){ + __FiltLexCat("((", &filter, &filtlen); + opar +=2; + } + } + __FiltLexCat(s, &filter, &filtlen); + if( s ) xfree(s); + if( filtseg[i]->radang ){ + if( *filtseg[i]->radang == ',' ) + __FiltLexCat(filtseg[i]->radang+1, &radang, &radanglen); + else + __FiltLexCat(filtseg[i]->radang, &radang, &radanglen); + } + else{ + __FiltLexCat("NA,NA,NA,NA\n", &radang, &radanglen); + } + i++; + for(; (itype==type); ){ + if( _FiltLexNeedOp(i, NULL) ) inexpr=0; + s = ExpandMacro(filtseg[i]->s, NULL, NULL, 0, _FiltLexCB, filtseg[i]); + if( _FiltLexNeedOp(i, s) ){ + for(xtot=0, x=strlen(filter)-1; x>=0; x--){ + if( filter[x] != '(' ) break; + filter[x] = '\0'; + xtot++; + } + /* if lhs and rhs are regions, implied operator is OR */ + if( type & TOK_IREG ) + __FiltLexCat("||", &filter, &filtlen); + /* otherwise implied operator is AND */ + else + __FiltLexCat("&&", &filter, &filtlen); + for(x=0; xradang ){ + if( *filtseg[i]->radang == ',' ) + __FiltLexCat(filtseg[i]->radang+1, &radang, &radanglen); + else + __FiltLexCat(filtseg[i]->radang, &radang, &radanglen); + } + else{ + __FiltLexCat("NA,NA,NA,NA\n", &radang, &radanglen); + } + i++; + } + } + /* ignore invalid arguments */ + else{ + i++; + } + /* save last type */ + ltype = type; + } + + /* if last segment was an exclude and we are in paint mode, ignore it */ + if( filt->paint && (ltype & TOK_EREG) ){ + __FiltLexCat("&&0", &filter, &filtlen); + } + + /* close off open parens (lots could be needed in paint mode) */ + while( opar-- ){ + __FiltLexCat(")", &filter, &filtlen); + } + + /* check for even number of parens */ + l = strlen(filter); + for(i=0, j=0; idebug ) fprintf(stderr, "paren error %d: %s\n", j, filter); + _filterror("unbalanced parentheses"); + } + if( filt->debug ) fprintf(stderr, "filter: %s\n", filter); +} + +/* + * + * _FiltLexEnd -- cleanup from parsing regions + * + */ +#ifdef YY_USE_PROTOS +static void +_FiltLexEnd(void) +#else +static void _FiltLexEnd() +#endif +{ + int i; + + /* reset state variables */ + colargs = 0; + initbindefs = 0; + include_stack_ptr = 0; + nroutine = 0; + nshape = 0; + nmask = 0; + nparen = 0; + parse_error = 0; + filtlen = 0; + radanglen = 0; + regid = 0; + regtype = 0; + inexpr = 0; + *regname = '\0'; + *saveang = 0; + *(wcsnames[0]) = '\0'; + *(wcsnames[1]) = '\0'; + binsiz[0] = 1; + binsiz[1] = 1; + /* free up previous filter */ + if( filter ){ + xfree(filter); + filter = NULL; + } + /* free up previous radang string */ + if( radang ){ + xfree(radang); + radang = NULL; + } + /* free up wcs */ + if( wcs ){ + wcsfree (wcs); + wcs = NULL; + } + /* no segments */ + if( filtseg ){ + for(i=0; is ) xfree(filtseg[i]->s); + if( filtseg[i]->regions ) xfree(filtseg[i]->regions); + if( filtseg[i]->shapes ) xfree(filtseg[i]->shapes); + if( filtseg[i]->radang ) xfree(filtseg[i]->radang); + xfree(filtseg[i]); + } + } + xfree(filtseg); + filtseg = NULL; + } + maxfiltseg = 0; + nfiltseg = 0; + if( gcoordsys ){ + xfree(gcoordsys); + gcoordsys = NULL; + } + if( fcoordsys ){ + xfree(fcoordsys); + fcoordsys = NULL; + } + cdelt1 = 0.0; + cdelt2 = 0.0; + crot = 0.0; +} + +/* + * + * _FiltLexGetWcs -- determine the WCS coord system to use for wcsc translation + * + */ +#ifdef YY_USE_PROTOS +static char * +_FiltLexGetWcs(void) +#else +static char *_FiltLexGetWcs() +#endif +{ + if( gcoordsys && + strcmp(gcoordsys, "image") && strcmp(gcoordsys, "physical") ) + return gcoordsys; + if( fcoordsys && + strcmp(fcoordsys, "image") && strcmp(fcoordsys, "physical") ) + return fcoordsys; + return NULL; +} + +/* + * + * _FiltLexWcsCols -- reset WCS for these columns + * + */ +#ifdef YY_USE_PROTOS +static void +_FiltLexWcsCols(FITSHead iheader, char *name0, char *name1) +#else +static void _FiltLexWcsCols(iheader, name0, name1) + FITSHead iheader; + char *name0; + char *name1; +#endif +{ + int i, which, ival; + int simple=1; + double dval, dval2; + char *s; + FITSHead oheader; + FITSCard card; + + /* make sure we have something to process */ + if( !iheader ) + return; + + if( filt->fhd->image ){ + /* free up old wcs */ + if( wcs ) wcsfree (wcs); + /* init new wcs */ + hlength(ft_cards(filt->fhd),0); + wcs = wcsinit(ft_cards(filt->fhd)); + tltyp[0] = 0; + tltyp[1] = 0; + } + /* for tables, we can init wcs only the specified columns */ + else if( name0 && *name0 && name1 && *name1 ){ + /* see if these are the same as the last set of columns */ + if( (*(wcsnames[0]) && !strcasecmp(name0,wcsnames[0])) && + (*(wcsnames[1]) && !strcasecmp(name1,wcsnames[1])) && wcs ){ + return; + } + + /* gather up important tl info about the binning columns */ + for(i=1; i<=iheader->table->tfields; i++){ + /* determine which bincol we are processing */ + if( !strcasecmp(iheader->table->col[i-1].name, name0) ) + which = 0; + else if( !strcasecmp(iheader->table->col[i-1].name, name1) ) + which = 1; + else + continue; + /* set tlinfo values for this column */ + tlmin[which] = ft_headgetr(iheader, "TLMIN", i, 1.0, &card); + tlmax[which] = ft_headgetr(iheader, "TLMAX", i, 1.0, &card); + binsiz[which] = ft_headgetr(iheader, "TDBIN", i, 1.0, &card); + tltyp[which] = iheader->table->col[i-1].type; + } + + /* free up old wcs */ + if( wcs ) wcsfree (wcs); + /* make a copy of the header */ + oheader = ft_headcopy(iheader); + + /* make sure this is a primary FITS file */ + ft_cardfmt((FITSCard)oheader->cards, + "SIMPLE", 0, FT_LOGICAL, &simple, 0, "Standard FITS"); + /* set dimension info, used by wcs code */ + ft_headseti(oheader, "NAXIS", 0, 2, "number of axes", 1); + /* set dimension info */ + for(i=0; i<=1; i++){ + ival = (int)tldim(tlmin[i], tlmax[i], binsiz[i], tltyp[i]); + ft_headseti(oheader, "NAXIS", i+1, ival, "axis dimension", 1); + } + /* set bitpix */ + ft_headseti(oheader, "BITPIX", 0, 32, "bits/pixel", 1); + /* synchronize the header and the cards after any changes */ + ft_syncdata(oheader); + + /* transform WCS cards for the specified columns, if we have such */ + for(i=1; i<=iheader->table->tfields; i++){ + /* determine which bincol we are processing */ + if( !strcasecmp(iheader->table->col[i-1].name, name0) ) + which = 0; + else if( !strcasecmp(iheader->table->col[i-1].name, name1) ) + which = 1; + else + continue; + /* convert event wcs header info image wcs info */ + if( (s=ft_headgets(iheader, "TCTYP", i, NULL, &card)) && card ){ + ft_headapps(oheader, "CTYPE", which+1, s, NULL); + xfree(s); + } + if( (s=ft_headgets(iheader, "TCRVL", i, NULL, &card)) && card ){ + ft_headappv(oheader, "CRVAL", which+1, s, NULL); + xfree(s); + } + if( (s=ft_headgets(iheader, "TCDLT", i, NULL, &card)) && card ){ + ft_headappv(oheader, "CDELT", which+1, s, NULL); + xfree(s); + } + if( (s=ft_headgets(iheader, "TCROT", i, NULL, &card)) && card ){ + ft_headappv(oheader, "CROTA", which+1, s, NULL); + xfree(s); + } + /* this value gets converted from physical to image */ + if( (dval=ft_headgetr(iheader, "TCRPX", i, 0.0, &card)) && card ){ + dval2 = tlp2i(dval, tlmin[which], binsiz[which], tltyp[which]); + ft_headsetr(oheader, "CRPIX", which+1, dval2, 7, NULL, 1); + } + } + + /* init new wcs */ + hlength(ft_cards(oheader),0); + wcs = wcsinit(ft_cards(oheader)); + ft_headfree(oheader, 1); + /* save names for next time */ + strcpy(wcsnames[0], name0); + strcpy(wcsnames[1], name1); + } + + /* set some extra wcs parameters */ + if( wcs && iswcs(wcs) ){ + if( fcoordsys ) xfree(fcoordsys); + fcoordsys = xstrdup(wcs->radecin); + culc(fcoordsys); + if( !wcs->coorflip ){ + cdelt1 = wcs->cdelt[0]; + cdelt2 = wcs->cdelt[1]; + } + else{ + cdelt1 = wcs->cdelt[1]; + cdelt2 = wcs->cdelt[0]; + } + if ( wcs->imflip ) { + crot = -wcs->rot; + } else { + crot = wcs->rot; + } + } + else{ + cdelt1 = 0.0; + cdelt2 = 0.0; + crot = 0.0; + } + /* set global coord system first time through */ + if( !gcoordsys ){ + if( (gcoordsys=xstrdup(getenv("COORDSYS"))) == NULL ) + gcoordsys = xstrdup(DEFAULT_COORDSYS); + } +} + +/* + * + * _FiltLexLcx -- determine if we have a linear-type WCS + * + */ +#ifdef YY_USE_PROTOS +static int +_FiltLexLcx(void) +#else +static int _FiltLexLcx() +#endif +{ + char *coordsys; + coordsys = gcoordsys; + if( !coordsys || !*coordsys ) + return 0; + if( !strcasecmp(coordsys, "image") ) return LCX_IMAGE; + if( !strcasecmp(coordsys, "physical") ) return LCX_PHYS; + if( !strcasecmp(coordsys, "amplifier") ) return LCX_AMP; + if( !strcasecmp(coordsys, "detector") ) return LCX_DET; + return 0; +} + +#ifdef YY_USE_PROTOS +static void +_FiltLexNum(int lcx) +#else +static void _FiltLexNum(lcx) + int lcx; +#endif +{ + char tbuf[SZ_LINE]; + + /* process binary number, if necessary */ + bin2num(tbuf, yytext, SZ_LINE); + + /* for linear coordinate systems (physical, amps, etc.), + we have to convert to image coords or physical coords, + depending on the type of data and type of filtering */ + if( lcx ){ + /* data is in a table: we can use image or physical coords */ + if( filt->fhd->table ){ + /* if we want to use physical coordinates ... */ + if( USEPHYS ){ + /* convert image positions to physical coords */ + if( lcx == LCX_IMAGE ){ + if( POSARG ){ + dval = tli2p(strtod(tbuf,NULL), + tlmin[(narg+1)%2], binsiz[(narg+1)%2], tltyp[(narg+1)%2]); + snprintf(sbuf, SZ_LINE, DFMT1, dval); + _FiltLexCat(sbuf); + _FiltLexArgSave(dval); + } + /* angle arguments are just passed along */ + else if( ANGARG ){ + dval = strtod(tbuf,NULL); + snprintf(sbuf, SZ_LINE, DFMT1, dval); + _FiltLexCat(sbuf); + _FiltLexArgSave(dval); + } + /* panda numeric args are just passed along */ + else if( NUMARG ){ + dval = strtod(tbuf,NULL); + snprintf(sbuf, SZ_LINE, DFMT1, dval); + _FiltLexCat(sbuf); + } + /* size arguments have to be converted using the binsize */ + else{ + if( SAVEANG ){ + dval = strtod(tbuf,NULL); + snprintf(saveang, SZ_LINE, DFMT1, dval); + } + dval = strtod(tbuf,NULL) * binsiz[(narg+1)%2]; + snprintf(sbuf, SZ_LINE, DFMT1, dval); + _FiltLexCat(sbuf); + _FiltLexArgSave(dval); + } + } + /* already in physical -- just pass along args */ + else{ + dval = strtod(tbuf,NULL); + snprintf(sbuf, SZ_LINE, DFMT1, dval); + _FiltLexCat(sbuf); + _FiltLexArgSave(dval); + } + } + /* we are using image coords (image-style filtering) */ + else{ + /* convert non-image positions to image coords */ + if( lcx != LCX_IMAGE ){ + if( POSARG ){ + dval = tlp2i(strtod(tbuf,NULL), + tlmin[(narg+1)%2], binsiz[(narg+1)%2], tltyp[(narg+1)%2]); + snprintf(sbuf, SZ_LINE, DFMT1, dval); + _FiltLexCat(sbuf); + _FiltLexArgSave(dval); + } + /* angle arguments are just passed along */ + else if( ANGARG ){ + dval = strtod(tbuf,NULL); + snprintf(sbuf, SZ_LINE, DFMT1, dval); + _FiltLexCat(sbuf); + _FiltLexArgSave(dval); + } + /* panda numeric args are just passed along */ + else if( NUMARG ){ + dval = strtod(tbuf,NULL); + snprintf(sbuf, SZ_LINE, DFMT1, dval); + _FiltLexCat(sbuf); + } + /* size arguments have to be converted using the binsize */ + else{ + if( SAVEANG ){ + dval = strtod(tbuf,NULL); + snprintf(saveang, SZ_LINE, DFMT1, dval); + } + dval = strtod(tbuf,NULL) / binsiz[(narg+1)%2]; + snprintf(sbuf, SZ_LINE, DFMT1, dval); + _FiltLexCat(sbuf); + _FiltLexArgSave(dval); + } + } + /* already in image -- just pass along args */ + else{ + dval = strtod(tbuf,NULL); + snprintf(sbuf, SZ_LINE, DFMT1, dval); + _FiltLexCat(sbuf); + _FiltLexArgSave(dval); + } + } + } + /* data is in an image: we use image coords */ + else{ + /* convert positional arguments to image */ + if( POSARG ){ + /* save x value for processing with y next time */ + if( XARG ){ + xpos = SAOstrtod(tbuf,NULL); + } + else{ + ypos = SAOstrtod(tbuf,NULL); + switch(lcx){ + case LCX_IMAGE: + xpix = xpos; + ypix = ypos; + break; + case LCX_PHYS: + ft_phy2img(filt->fhd, xpos, ypos, &xpix, &ypix); + break; + case LCX_AMP: + ft_amp2phy(filt->fhd, xpos, ypos, &dval, &dval2); + ft_phy2img(filt->fhd, dval, dval2, &xpix, &ypix); + break; + case LCX_DET: + ft_det2phy(filt->fhd, xpos, ypos, &dval, &dval2); + ft_phy2img(filt->fhd, dval, dval2, &xpix, &ypix); + break; + } + snprintf(sbuf, SZ_LINE, DFMT2, xpix, ypix); + _FiltLexCat(sbuf); + } + } + /* angle arguments are just passed along, with updated crot */ + else if( ANGARG ){ + dval = strtod(tbuf,NULL); + if( USEWCS ) dval += crot; + if( IMFLIP ) dval = -dval; + snprintf(sbuf, SZ_LINE, DFMT1, dval); + _FiltLexCat(sbuf); + } + /* panda numeric args are just passed along */ + else if( NUMARG ){ + dval = strtod(tbuf,NULL); + snprintf(sbuf, SZ_LINE, DFMT1, dval); + _FiltLexCat(sbuf); + } + /* convert size args, which may or may not be in pairs */ + else{ + if( SAVEANG ){ + dval = strtod(tbuf,NULL); + if( USEWCS ) dval += crot; + if( IMFLIP ) dval = -dval; + snprintf(saveang, SZ_LINE, DFMT1, dval); + } + /* arg 1 is associated with ra, arg2 with dec */ + if( XARG ){ + xpos = ABS(strtod(tbuf,NULL)); + ypos = 0.0; + switch(lcx){ + case LCX_IMAGE: + xpix = xpos; + break; + case LCX_PHYS: + ft_phy2img_size(filt->fhd, xpos, ypos, &xpix, &ypix); + break; + case LCX_AMP: + ft_amp2phy_size(filt->fhd, xpos,ypos, &dval,&dval2); + ft_phy2img_size(filt->fhd, dval,dval2, &xpix,&ypix); + break; + case LCX_DET: + ft_det2phy_size(filt->fhd, xpos,ypos, &dval,&dval2); + ft_phy2img_size(filt->fhd, dval,dval2, &xpix,&ypix); + break; + } + snprintf(sbuf, SZ_LINE, DFMT1, xpix); + _FiltLexArgSave(xpix); + } + else{ + xpos = 0.0; + ypos = ABS(strtod(tbuf,NULL)); + switch(lcx){ + case LCX_IMAGE: + ypix = ypos; + break; + case LCX_PHYS: + ft_phy2img_size(filt->fhd, xpos, ypos, &xpix, &ypix); + break; + case LCX_AMP: + ft_amp2phy_size(filt->fhd, xpos,ypos, &dval,&dval2); + ft_phy2img_size(filt->fhd, dval,dval2, &xpix,&ypix); + break; + case LCX_DET: + ft_det2phy_size(filt->fhd, xpos,ypos, &dval,&dval2); + ft_phy2img_size(filt->fhd, dval,dval2, &xpix,&ypix); + break; + } + snprintf(sbuf, SZ_LINE, DFMT1, ypix); + _FiltLexArgSave(ypix); + } + _FiltLexCat(sbuf); + } + } + } + /* not lcx -- angle arguments are just passed along with updated crot */ + else if( ANGARG ){ + dval = strtod(tbuf,NULL); + if( USEWCS ) dval += crot; + if( IMFLIP ) dval = -dval; + snprintf(sbuf, SZ_LINE, DFMT1, dval); + _FiltLexCat(sbuf); + } + /* panda numeric args are just passed along */ + else if( NUMARG ){ + dval = strtod(tbuf,NULL); + snprintf(sbuf, SZ_LINE, DFMT1, dval); + _FiltLexCat(sbuf); + } + /* not lcx -- everything else is assumed to be in units of "degrees" + in the default system. add 'd' and put back for reparsing */ + else{ + int i; + char *yycopy = xstrdup(tbuf); + unput('d'); + for(i=yyleng-1; i>=0; --i) + unput(yycopy[i]); + xfree(yycopy); + narg--; + } +} + +#ifdef YY_USE_PROTOS +static int +_FiltIncMask(FilterMask masks, int maxmask, int nmask) +#else +static int _FiltIncMask(masks, maxmask, nmask) + FilterMask masks; + int maxmask; + int nmask; +#endif +{ + int omax; + nmask++; + if( nmask >= maxmask ){ + omax = maxmask; + maxmask += MASKINC; + masks = (FilterMask)xrealloc(masks, maxmask*sizeof(FilterMaskRec)); + memset(masks+omax, 0, (maxmask-omax)*sizeof(FilterMaskRec)); + } + return nmask; +} + +#ifdef YY_USE_PROTOS +static int +_FiltFitsMask(char *filename, FilterMask *rmasks, FITSHead *rhead, int *nreg) +#else +static int _FiltFitsMask(filename, rmasks, rhead, nreg) + char *filename; + FilterMask *rmasks; + FITSHead *rhead; + int *nreg; +#endif +{ + short *dptr; + short *data=NULL; + int x, y; + int maxreg=-1; + int maxmask; /* max masks allocated thus far */ + int nmask=0; /* number of mask segments */ + FilterMask masks=NULL; /* array valid region masks for one row */ + FITSHead head=NULL; + + /* read fits image */ + if( !ft_simpleimageread(filename, &head, (void *)&data, NULL, 16) ){ + return(-1); + } + if( !head->image ){ + if( data ) xfree(data); + if( head ) ft_headfree(head, 1); + return(-2); + } + if( !ft_naxes(head) || !ft_naxis(head, 1) || !ft_naxis(head, 2) ){ + if( data ) xfree(data); + if( head ) ft_headfree(head, 1); + return(-3); + } + + /* allocate an array of masks, which will be returned to caller */ + maxmask = MASKINC; + masks = (FilterMask)xcalloc(maxmask, sizeof(FilterMaskRec)); + /* seed the first region mask value */ + masks[nmask].region = 0; + /* loop through y rows */ + for(y=1; y<=ft_naxis(head, 2); y++){ + dptr = data + ((y-1) * ft_naxis(head, 1)); + /* to start this line, we make a seed mask with no region */ + if( masks[nmask].region ){ + nmask = _FiltIncMask(masks, maxmask, nmask); + masks[nmask].region = 0; + } + /* process each pixel in the row */ + for(x=1; x<=ft_naxis(head, 1); x++, dptr++){ + /* we do not allow negative values */ + if( *dptr < 0 ){ + if( data ) xfree(data); + if( head ) ft_headfree(head, 1); + if( masks ) xfree(masks); + return(-4); + } + /* set max region as needed */ + if( *dptr > maxreg ) + maxreg = *dptr; + /* look for a change in the mask */ + if( *dptr != masks[nmask].region ){ + /* if previous was non-zero region, finish it and bump to next */ + if( masks[nmask].region ){ + masks[nmask].xstop = x - 1; + nmask = _FiltIncMask(masks, maxmask, nmask); + } + masks[nmask].y = y; + masks[nmask].region = *dptr; + masks[nmask].xstart = x; + } + } + /* finish last non-zero segment, inc number of mask segs */ + if( masks[nmask].region ){ + masks[nmask].xstop = x; + nmask = _FiltIncMask(masks, maxmask, nmask); + } + } + + /* free up data space */ + if( data ) xfree(data); + /* allocate just enough mask space */ + masks = (FilterMask)xrealloc(masks, nmask*sizeof(FilterMaskRec)); + if( rmasks ) + *rmasks = masks; + else + xfree(masks); + if( rhead ) + *rhead = head; + else + ft_headfree(head, 1); + if( nreg ) + *nreg = maxreg; + + return(nmask); +} + +/* + * + * Semi-public Routines + * + * + */ + +/* + * + * _FilterString -- return output filter from lexer + * + */ +#ifdef YY_USE_PROTOS +char * +_FilterString(void) +#else +char *_FilterString() +#endif +{ + if( filtlen <= 0 ) + _FiltLexMake(); + return(filter); +} + +#ifdef YY_USE_PROTOS +int +FilterRoutineCount(void) +#else +int FilterRoutineCount() +#endif +{ + return(nroutine); +} + +#ifdef YY_USE_PROTOS +int +FilterShapeCount(void) +#else +int FilterShapeCount() +#endif +{ + return(nshape); +} + +#ifdef YY_USE_PROTOS +int +FilterRegionCount(int type) +#else +int FilterRegionCount(type) + int type; +#endif +{ + int i, j; + + /* handle fits image masks specially */ + if( nmask ){ + if( type & TOK_IREG ) + return(nregion); + else + return(0); + } + + /* normal regions */ + for(i=0, j=0; itype & type ){ + j += filtseg[i]->nregion; + } + } + return(j); +} + +#ifdef YY_USE_PROTOS +char * +FilterRadAng(void) +#else +char *FilterRadAng() +#endif +{ + return(radang); +} + +#ifdef YY_USE_PROTOS +int +FilterParseError(void) +#else +int FilterParseError() +#endif +{ + return(parse_error); +} + +#ifdef YY_USE_PROTOS +int +FilterTlInfo(double *tlmins, double *binsizs, int *tltyps) +#else +int FilterTlInfo(tlmins, binsizs, tltyps) + double *tlmins; + double *binsizs; + int *tltyps; +#endif +{ + tlmins[0] = tlmin[0]; + tlmins[1] = tlmin[1]; + binsizs[0] = binsiz[0]; + binsizs[1] = binsiz[1]; + tltyps[0] = tltyp[0]; + tltyps[1] = tltyp[1]; + return 1; +} + +#ifdef YY_USE_PROTOS +void +FiltInitParser(void) +#else +void FiltInitParser() +#endif +{ + static int parser = 0; + /* make sure we free'd up all space from last time */ + _FiltLexEnd(); + /* set up some convenience variables */ + filt = FilterDefault(); +/* + if( parser ) + yyrestart(NULL); +*/ + BEGIN INITIAL; + parser++; + laststart=INITIAL; +} + +#ifdef YY_USE_PROTOS +void +FiltScanString(char *s) +#else +void FiltScanString(s) + char *s; +#endif +{ + int i; + char *t; + /* make sure there is an explicit delim at end so we are done before + lex finds EOF -- otherwise panda shapes don't get processed */ + i = strlen(s); + t = xmalloc(i+2); + strcpy(t, s); + if( (t[i-1] != ';') && (t[i-1] != '\n') ) + strcat(t, "\n"); + yy_scan_string(t); + if( t ) xfree(t); +} + +/* yyerror -- renamed to _filterror because flex -P does not change this */ +#ifdef YY_USE_PROTOS +int +_filterror(char *msg) +#else +int _filterror(msg) + char *msg; +#endif +{ + if( *yytext ) + gerror(stderr, "%s while parsing filter at: %s\n", + msg ? msg : "filterr", yytext); + else + gerror(stderr, "%s\n", msg ? msg : "filterr"); + YY_FLUSH_BUFFER; + parse_error = 1; + yyterminate(); +} + +#ifdef YY_USE_PROTOS +int yywrap(void) +#else +int yywrap() +#endif +{ + return 1; +} diff --git a/filter/lex.idx.c b/filter/lex.idx.c new file mode 100644 index 0000000..cfceac7 --- /dev/null +++ b/filter/lex.idx.c @@ -0,0 +1,2829 @@ +#define yy_create_buffer idx_create_buffer +#define yy_delete_buffer idx_delete_buffer +#define yy_scan_buffer idx_scan_buffer +#define yy_scan_string idx_scan_string +#define yy_scan_bytes idx_scan_bytes +#define yy_flex_debug idx_flex_debug +#define yy_init_buffer idx_init_buffer +#define yy_flush_buffer idx_flush_buffer +#define yy_load_buffer_state idx_load_buffer_state +#define yy_switch_to_buffer idx_switch_to_buffer +#define yyin idxin +#define yyleng idxleng +#define yylex idxlex +#define yyout idxout +#define yyrestart idxrestart +#define yytext idxtext +#define yywrap idxwrap + +/* A lexical scanner generated by flex */ + +/* Scanner skeleton version: + * $Header: /home/daffy/u0/vern/flex/RCS/flex.skl,v 2.91 96/09/10 16:58:48 vern Exp $ + */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 + +#include + + +/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ +#ifdef c_plusplus +#ifndef __cplusplus +#define __cplusplus +#endif +#endif + + +#ifdef __cplusplus + +#include +#include + +/* Use prototypes in function declarations. */ +#define YY_USE_PROTOS + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +#if __STDC__ + +#define YY_USE_PROTOS +#define YY_USE_CONST + +#endif /* __STDC__ */ +#endif /* ! __cplusplus */ + +#ifdef __TURBOC__ + #pragma warn -rch + #pragma warn -use +#include +#include +#define YY_USE_CONST +#define YY_USE_PROTOS +#endif + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + + +#ifdef YY_USE_PROTOS +#define YY_PROTO(proto) proto +#else +#define YY_PROTO(proto) () +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN yy_start = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START ((yy_start - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart( yyin ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#define YY_BUF_SIZE 16384 + +typedef struct yy_buffer_state *YY_BUFFER_STATE; + +extern int yyleng; +extern FILE *yyin, *yyout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + +/* The funky do-while in the following #define is used to turn the definition + * int a single C statement (which needs a semi-colon terminator). This + * avoids problems with code like: + * + * if ( condition_holds ) + * yyless( 5 ); + * else + * do_something_else(); + * + * Prior to using the do-while the compiler would get upset at the + * "else" because it interpreted the "if" statement as being all + * done when it reached the ';' after the yyless() call. + */ + +/* Return all but the first 'n' matched characters back to the input stream. */ + +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + *yy_cp = yy_hold_char; \ + YY_RESTORE_YY_MORE_OFFSET \ + yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, idxtext_ptr ) + +/* The following is because we cannot portably get our hands on size_t + * (without autoconf's help, which isn't available because we want + * flex-generated scanners to compile on their own). + */ +typedef unsigned int yy_size_t; + + +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + }; + +static YY_BUFFER_STATE yy_current_buffer = 0; + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + */ +#define YY_CURRENT_BUFFER yy_current_buffer + + +/* yy_hold_char holds the character lost when yytext is formed. */ +static char yy_hold_char; + +static int yy_n_chars; /* number of characters read into yy_ch_buf */ + + +int yyleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = (char *) 0; +static int yy_init = 1; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void yyrestart YY_PROTO(( FILE *input_file )); + +void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer )); +void yy_load_buffer_state YY_PROTO(( void )); +YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size )); +void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b )); +void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file )); +void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b )); +#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer ) + +YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size )); +YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str )); +YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len )); + +static void *yy_flex_alloc YY_PROTO(( yy_size_t )); +static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t )); +static void yy_flex_free YY_PROTO(( void * )); + +#define yy_new_buffer yy_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! yy_current_buffer ) \ + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ + yy_current_buffer->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! yy_current_buffer ) \ + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ + yy_current_buffer->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (yy_current_buffer->yy_at_bol) + +typedef unsigned char YY_CHAR; +FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; +typedef int yy_state_type; +extern char yytext[]; + + +static yy_state_type yy_get_previous_state YY_PROTO(( void )); +static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state )); +static int yy_get_next_buffer YY_PROTO(( void )); +static void yy_fatal_error YY_PROTO(( yyconst char msg[] )); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + idxtext_ptr = yy_bp; \ + yyleng = (int) (yy_cp - yy_bp); \ + yy_hold_char = *yy_cp; \ + *yy_cp = '\0'; \ + if ( yyleng >= YYLMAX ) \ + YY_FATAL_ERROR( "token too large, exceeds YYLMAX" ); \ + yy_flex_strncpy( yytext, idxtext_ptr, yyleng + 1 ); \ + yy_c_buf_p = yy_cp; + +#define YY_NUM_RULES 15 +#define YY_END_OF_BUFFER 16 +static yyconst short int yy_accept[570] = + { 0, + 0, 0, 16, 14, 13, 15, 14, 14, 14, 14, + 1, 1, 14, 14, 14, 6, 6, 6, 14, 10, + 8, 0, 2, 2, 1, 0, 1, 0, 11, 9, + 12, 0, 6, 0, 6, 6, 7, 0, 0, 0, + 2, 1, 0, 0, 5, 0, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 0, 0, 2, + 1, 0, 0, 0, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 0, 0, + 0, 5, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 0, 0, 0, + + 6, 0, 6, 0, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 0, 0, 5, 0, 6, + 6, 0, 6, 6, 6, 6, 6, 6, 6, 0, + 5, 6, 0, 6, 0, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, + 0, 0, 0, 0, 0, 4, 0, 0, 3, 0, + 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, + 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, + 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0 + } ; + +static yyconst int yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 4, 1, 1, 1, 1, 5, 1, 6, + 7, 1, 8, 9, 10, 11, 1, 12, 13, 14, + 15, 16, 17, 15, 18, 19, 15, 1, 1, 20, + 21, 22, 1, 1, 26, 27, 28, 29, 30, 31, + 32, 25, 33, 25, 25, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 25, 45, 46, 25, + 23, 1, 24, 1, 25, 1, 26, 27, 28, 29, + + 30, 31, 32, 25, 33, 25, 25, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 25, 45, + 46, 25, 1, 47, 1, 48, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static yyconst int yy_meta[49] = + { 0, + 1, 1, 2, 1, 1, 3, 4, 5, 6, 5, + 7, 8, 8, 8, 8, 8, 8, 8, 8, 1, + 1, 1, 9, 1, 10, 11, 11, 11, 11, 12, + 11, 10, 10, 13, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 13, 10, 1, 14 + } ; + +static yyconst short int yy_base[607] = + { 0, + 0, 0, 2154, 2377, 2377, 2377, 2132, 2119, 2056, 0, + 38, 39, 2040, 2015, 2014, 47, 48, 51, 1979, 2377, + 2377, 2009, 1994, 1993, 0, 48, 2377, 0, 2377, 2377, + 2377, 45, 53, 1995, 87, 1987, 2377, 2003, 52, 53, + 0, 1979, 58, 2005, 2377, 1987, 61, 71, 74, 96, + 82, 73, 75, 51, 116, 118, 121, 1991, 81, 0, + 2377, 2002, 93, 139, 129, 124, 132, 127, 145, 150, + 151, 153, 155, 158, 166, 164, 169, 176, 1991, 179, + 194, 1983, 198, 187, 189, 202, 203, 205, 209, 210, + 213, 214, 228, 217, 229, 233, 237, 1988, 255, 243, + + 257, 262, 242, 252, 264, 249, 267, 268, 271, 276, + 286, 291, 292, 295, 297, 0, 304, 310, 97, 315, + 307, 334, 323, 325, 330, 296, 336, 329, 338, 1992, + 130, 341, 377, 348, 366, 345, 1987, 354, 367, 351, + 1983, 390, 404, 402, 422, 1977, 433, 1922, 179, 470, + 1915, 1942, 504, 416, 512, 447, 532, 451, 540, 1939, + 563, 1910, 220, 600, 1899, 298, 2377, 634, 455, 642, + 459, 662, 463, 670, 467, 693, 1898, 336, 730, 1896, + 378, 173, 484, 764, 488, 784, 492, 792, 496, 448, + 462, 815, 1895, 466, 360, 500, 282, 504, 849, 526, + + 420, 452, 503, 48, 527, 554, 94, 437, 102, 358, + 1926, 555, 567, 136, 377, 1925, 1924, 575, 1904, 579, + 1858, 1862, 299, 578, 1847, 221, 1864, 579, 1836, 1815, + 345, 1828, 1829, 581, 1813, 559, 1799, 586, 1795, 400, + 1784, 570, 1790, 353, 1785, 567, 1796, 190, 1758, 579, + 0, 484, 1760, 596, 584, 604, 1781, 597, 616, 616, + 1752, 857, 0, 576, 622, 1762, 0, 633, 1750, 694, + 903, 706, 697, 1748, 1744, 684, 2377, 1717, 627, 943, + 960, 984, 2377, 710, 1722, 1008, 1729, 1723, 628, 654, + 658, 682, 712, 1043, 743, 716, 722, 1056, 758, 1699, + + 748, 1080, 1708, 1699, 726, 749, 746, 828, 1121, 1682, + 1652, 1144, 747, 843, 1162, 1645, 1637, 1185, 1631, 1202, + 1630, 1219, 1243, 1622, 1622, 124, 908, 1283, 753, 777, + 707, 922, 1295, 804, 833, 805, 861, 1303, 933, 837, + 956, 1316, 989, 1609, 1590, 802, 1086, 838, 938, 925, + 1099, 847, 973, 988, 1262, 1334, 1581, 1551, 1357, 989, + 1352, 1376, 1556, 1548, 1399, 1534, 1417, 990, 1114, 991, + 1251, 801, 1430, 1453, 862, 1013, 904, 1443, 1466, 927, + 1017, 0, 1528, 1527, 1104, 998, 1500, 1133, 1075, 1276, + 1096, 1479, 1052, 1484, 1008, 1140, 1118, 1491, 1055, 1157, + + 1495, 1480, 1461, 1442, 1164, 1519, 1165, 1547, 1166, 1565, + 1172, 1576, 1432, 1429, 1413, 1411, 1184, 1102, 1160, 1390, + 1140, 1581, 1215, 1389, 1252, 1181, 1198, 1342, 1142, 1589, + 1395, 1325, 1265, 1497, 1320, 1537, 1258, 1238, 1237, 1222, + 1095, 1509, 1224, 1370, 1264, 1605, 1082, 1389, 1318, 1633, + 1321, 1661, 1061, 1047, 1013, 1012, 1342, 1623, 1003, 1615, + 1396, 1651, 989, 1679, 1301, 1432, 1435, 952, 1193, 1687, + 1544, 921, 1398, 1451, 1499, 908, 1212, 1694, 1594, 843, + 771, 756, 744, 723, 1255, 1701, 709, 1706, 1505, 1719, + 697, 1725, 1585, 1732, 679, 1743, 1604, 1747, 678, 1757, + + 1070, 0, 0, 0, 1425, 1761, 649, 1772, 1438, 1776, + 624, 1787, 1555, 1791, 615, 1800, 1603, 1808, 581, 1816, + 1586, 1824, 547, 1837, 1819, 1841, 518, 1854, 1619, 1858, + 473, 1866, 1647, 1871, 407, 1884, 1712, 1888, 0, 1897, + 1804, 1901, 0, 1906, 1666, 1912, 287, 1917, 1675, 1928, + 278, 1939, 1865, 1943, 172, 1956, 1944, 1968, 72, 1962, + 1832, 1974, 0, 1980, 1893, 1984, 0, 1992, 2377, 70, + 2008, 2019, 732, 2026, 2038, 2052, 1318, 2066, 2080, 2094, + 2108, 2122, 2136, 2148, 2156, 2170, 2182, 2190, 2204, 2209, + 2217, 2227, 2235, 2240, 58, 2253, 2264, 1349, 2278, 1379, + + 2292, 2306, 2320, 2334, 2348, 2362 + } ; + +static yyconst short int yy_def[607] = + { 0, + 569, 1, 569, 569, 569, 569, 569, 569, 569, 570, + 571, 571, 569, 569, 569, 572, 572, 572, 569, 569, + 569, 569, 570, 570, 12, 573, 569, 574, 569, 569, + 569, 575, 572, 576, 572, 35, 569, 569, 577, 573, + 40, 574, 575, 578, 569, 576, 576, 572, 572, 572, + 572, 572, 572, 35, 572, 572, 572, 569, 577, 59, + 569, 578, 569, 579, 572, 572, 572, 572, 572, 572, + 572, 572, 572, 572, 572, 572, 572, 572, 569, 579, + 580, 576, 579, 572, 572, 572, 572, 572, 572, 572, + 572, 572, 572, 572, 572, 572, 572, 569, 580, 576, + + 580, 581, 572, 575, 572, 572, 572, 572, 572, 572, + 572, 572, 572, 572, 572, 582, 581, 576, 583, 581, + 572, 575, 572, 572, 572, 572, 572, 572, 572, 569, + 569, 572, 575, 572, 575, 572, 569, 133, 133, 575, + 569, 133, 575, 133, 133, 569, 133, 147, 144, 147, + 150, 569, 133, 575, 133, 575, 133, 575, 133, 569, + 133, 161, 155, 161, 164, 159, 569, 133, 575, 133, + 575, 133, 575, 133, 575, 133, 176, 170, 176, 179, + 174, 575, 575, 174, 575, 133, 575, 133, 575, 578, + 184, 133, 192, 188, 578, 575, 575, 575, 188, 575, + + 578, 578, 199, 578, 578, 575, 578, 578, 578, 578, + 578, 578, 584, 578, 585, 578, 569, 585, 586, 587, + 569, 586, 586, 588, 569, 586, 569, 588, 589, 569, + 586, 569, 589, 589, 569, 586, 569, 589, 569, 586, + 569, 589, 569, 586, 569, 589, 569, 586, 569, 589, + 590, 586, 569, 589, 591, 586, 569, 589, 592, 591, + 593, 586, 594, 589, 592, 265, 595, 265, 593, 593, + 596, 597, 589, 569, 268, 595, 569, 276, 598, 593, + 586, 596, 569, 597, 599, 589, 569, 268, 600, 598, + 290, 280, 280, 593, 280, 281, 281, 586, 281, 599, + + 599, 601, 569, 268, 600, 305, 593, 280, 593, 593, + 309, 593, 586, 281, 586, 586, 315, 586, 599, 599, + 589, 589, 601, 569, 268, 593, 280, 312, 312, 312, + 586, 281, 318, 318, 318, 320, 320, 599, 320, 322, + 322, 589, 322, 569, 268, 593, 280, 328, 328, 586, + 281, 333, 333, 599, 320, 599, 599, 356, 599, 589, + 322, 589, 589, 362, 589, 569, 602, 593, 280, 586, + 281, 599, 320, 359, 359, 359, 589, 322, 365, 365, + 365, 602, 569, 569, 265, 276, 268, 290, 593, 280, + 586, 281, 599, 320, 374, 374, 589, 322, 379, 379, + + 569, 268, 276, 291, 593, 603, 586, 604, 599, 320, + 589, 322, 569, 268, 276, 291, 603, 593, 593, 280, + 309, 280, 593, 312, 604, 586, 586, 281, 315, 281, + 586, 318, 599, 320, 589, 322, 569, 268, 276, 291, + 593, 280, 309, 312, 586, 281, 315, 318, 599, 605, + 589, 606, 569, 268, 276, 291, 593, 280, 309, 312, + 586, 281, 315, 318, 605, 599, 599, 320, 356, 320, + 599, 359, 606, 589, 589, 322, 362, 322, 589, 365, + 569, 268, 276, 291, 593, 280, 309, 312, 586, 281, + 315, 318, 599, 320, 356, 359, 589, 322, 362, 365, + + 569, 268, 276, 291, 593, 280, 309, 312, 586, 281, + 315, 318, 599, 320, 356, 359, 589, 322, 362, 365, + 593, 280, 309, 312, 586, 281, 315, 318, 599, 320, + 356, 359, 589, 322, 362, 365, 593, 280, 309, 312, + 586, 281, 315, 318, 599, 320, 356, 359, 589, 322, + 362, 365, 599, 320, 356, 359, 589, 322, 362, 365, + 599, 320, 356, 359, 589, 322, 362, 365, 0, 569, + 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, + 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, + 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, + + 569, 569, 569, 569, 569, 569 + } ; + +static yyconst short int yy_nxt[2426] = + { 0, + 4, 5, 6, 7, 8, 4, 4, 4, 4, 9, + 10, 11, 12, 12, 12, 12, 12, 12, 12, 13, + 14, 15, 4, 4, 16, 16, 16, 16, 16, 17, + 16, 16, 18, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 19, 4, 24, 24, + 44, 45, 32, 32, 63, 40, 32, 40, 32, 59, + 569, 59, 569, 44, 45, 276, 64, 26, 26, 34, + 34, 27, 27, 34, 207, 34, 32, 23, 32, 32, + 32, 57, 28, 569, 47, 36, 33, 32, 569, 567, + 569, 35, 32, 34, 33, 34, 34, 34, 44, 45, + + 63, 32, 44, 131, 34, 72, 65, 73, 63, 34, + 66, 67, 48, 49, 50, 70, 51, 52, 34, 71, + 53, 32, 54, 32, 55, 56, 32, 209, 68, 32, + 54, 211, 32, 69, 32, 44, 45, 32, 34, 346, + 34, 74, 63, 34, 81, 82, 34, 270, 75, 34, + 32, 34, 76, 78, 34, 32, 32, 86, 32, 77, + 32, 43, 83, 32, 84, 216, 87, 34, 85, 32, + 88, 32, 34, 34, 32, 34, 90, 34, 190, 45, + 34, 32, 91, 89, 81, 82, 34, 142, 34, 563, + 92, 34, 32, 93, 104, 85, 94, 95, 34, 46, + + 100, 43, 83, 102, 82, 97, 96, 32, 32, 34, + 32, 34, 156, 223, 32, 32, 62, 101, 32, 32, + 43, 83, 32, 252, 34, 34, 231, 34, 153, 103, + 106, 34, 34, 32, 32, 34, 34, 105, 32, 34, + 107, 108, 32, 85, 223, 109, 110, 32, 81, 82, + 34, 34, 112, 171, 32, 34, 111, 44, 45, 34, + 46, 100, 64, 100, 34, 114, 47, 81, 118, 32, + 115, 34, 32, 32, 113, 121, 32, 62, 101, 62, + 101, 32, 124, 122, 119, 120, 34, 202, 45, 34, + 34, 32, 123, 34, 559, 125, 32, 32, 34, 127, + + 32, 32, 32, 555, 128, 126, 157, 226, 34, 81, + 118, 85, 32, 34, 34, 81, 82, 34, 34, 34, + 102, 118, 223, 129, 85, 85, 119, 120, 32, 34, + 32, 175, 85, 47, 135, 32, 134, 119, 120, 44, + 45, 32, 133, 32, 168, 34, 32, 34, 85, 132, + 32, 34, 34, 32, 85, 85, 44, 45, 34, 145, + 34, 85, 142, 34, 63, 139, 63, 34, 223, 185, + 34, 44, 45, 236, 136, 142, 223, 85, 139, 248, + 85, 85, 44, 45, 212, 217, 172, 143, 138, 139, + 139, 139, 139, 139, 139, 139, 201, 140, 144, 219, + + 143, 147, 148, 148, 148, 148, 148, 148, 148, 44, + 45, 189, 142, 149, 149, 149, 149, 149, 149, 149, + 149, 44, 45, 223, 153, 551, 63, 149, 149, 149, + 149, 149, 149, 150, 151, 151, 151, 151, 151, 151, + 151, 153, 244, 63, 148, 148, 148, 148, 148, 148, + 148, 148, 44, 45, 63, 142, 44, 45, 63, 157, + 44, 45, 204, 168, 44, 45, 154, 153, 44, 45, + 182, 172, 44, 45, 186, 157, 195, 155, 157, 210, + 205, 151, 151, 151, 151, 151, 151, 151, 151, 44, + 45, 547, 182, 44, 45, 196, 168, 44, 45, 200, + + 186, 44, 45, 158, 172, 44, 45, 223, 182, 44, + 45, 197, 197, 256, 159, 161, 162, 162, 162, 162, + 162, 162, 162, 163, 163, 163, 163, 163, 163, 163, + 163, 44, 45, 63, 186, 543, 206, 163, 163, 163, + 163, 163, 163, 164, 165, 165, 165, 165, 165, 165, + 165, 166, 166, 166, 166, 166, 166, 166, 166, 44, + 45, 63, 197, 208, 539, 166, 166, 166, 166, 166, + 166, 168, 44, 45, 162, 162, 162, 162, 162, 162, + 162, 162, 223, 217, 44, 45, 227, 227, 214, 238, + 234, 242, 259, 234, 535, 240, 169, 219, 246, 234, + + 229, 229, 234, 250, 234, 273, 261, 170, 172, 234, + 262, 165, 165, 165, 165, 165, 165, 165, 165, 234, + 234, 254, 258, 265, 259, 266, 267, 223, 531, 569, + 264, 274, 267, 173, 290, 305, 290, 305, 261, 277, + 527, 259, 569, 278, 174, 176, 177, 177, 177, 177, + 177, 177, 177, 178, 178, 178, 178, 178, 178, 178, + 178, 569, 279, 569, 277, 523, 259, 178, 178, 178, + 178, 178, 178, 179, 180, 180, 180, 180, 180, 180, + 180, 181, 181, 181, 181, 181, 181, 181, 181, 269, + 277, 307, 259, 519, 515, 181, 181, 181, 181, 181, + + 181, 182, 280, 286, 177, 177, 177, 177, 177, 177, + 177, 177, 283, 289, 259, 511, 283, 270, 259, 269, + 234, 307, 350, 222, 308, 313, 183, 507, 285, 222, + 223, 313, 285, 569, 314, 569, 41, 184, 186, 41, + 504, 180, 180, 180, 180, 180, 180, 180, 180, 310, + 269, 280, 269, 311, 319, 277, 320, 259, 326, 331, + 269, 503, 269, 187, 316, 222, 281, 222, 317, 270, + 223, 301, 312, 502, 188, 191, 191, 191, 191, 191, + 191, 191, 191, 310, 269, 280, 269, 318, 501, 191, + 191, 191, 191, 191, 191, 192, 193, 193, 193, 193, + + 193, 193, 193, 194, 194, 194, 194, 194, 194, 194, + 194, 222, 300, 222, 354, 368, 393, 194, 194, 194, + 194, 194, 194, 197, 301, 270, 193, 193, 193, 193, + 193, 193, 193, 193, 310, 269, 280, 269, 311, 316, + 222, 281, 222, 327, 233, 269, 360, 269, 198, 316, + 222, 281, 222, 317, 222, 500, 222, 312, 332, 199, + 203, 203, 203, 203, 203, 203, 203, 203, 300, 300, + 354, 300, 318, 355, 203, 203, 203, 203, 203, 203, + 223, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, + + 271, 271, 271, 222, 222, 222, 222, 222, 222, 222, + 222, 281, 222, 222, 310, 269, 280, 269, 311, 397, + 498, 347, 222, 222, 222, 261, 223, 234, 316, 222, + 281, 222, 317, 496, 233, 351, 233, 312, 370, 357, + 300, 320, 300, 358, 310, 269, 280, 269, 223, 222, + 292, 318, 293, 294, 295, 295, 295, 295, 295, 295, + 295, 295, 359, 233, 494, 360, 270, 296, 361, 297, + 298, 299, 299, 299, 299, 299, 299, 299, 299, 316, + 222, 281, 222, 223, 222, 222, 222, 222, 222, 222, + 222, 222, 281, 222, 222, 363, 233, 322, 233, 364, + + 372, 377, 491, 222, 222, 222, 261, 223, 389, 391, + 403, 301, 234, 270, 223, 300, 487, 300, 365, 357, + 300, 320, 300, 363, 233, 322, 233, 279, 484, 483, + 222, 234, 302, 302, 302, 302, 302, 302, 302, 302, + 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, + 302, 302, 302, 302, 309, 309, 309, 309, 309, 309, + 309, 309, 233, 482, 233, 409, 270, 315, 315, 315, + 315, 315, 315, 315, 315, 301, 277, 481, 259, 223, + 233, 233, 233, 233, 233, 233, 321, 233, 322, 233, + 233, 405, 310, 269, 280, 269, 311, 463, 270, 233, + + 233, 233, 285, 234, 369, 316, 222, 281, 222, 317, + 457, 265, 407, 266, 441, 312, 402, 371, 270, 223, + 310, 269, 280, 269, 311, 270, 233, 310, 318, 280, + 390, 411, 309, 309, 309, 309, 309, 309, 309, 309, + 290, 234, 290, 312, 270, 404, 357, 300, 320, 300, + 328, 329, 443, 329, 447, 330, 330, 330, 330, 330, + 330, 330, 330, 363, 233, 322, 233, 270, 316, 312, + 281, 318, 441, 315, 315, 315, 315, 315, 315, 315, + 315, 417, 425, 270, 433, 223, 269, 270, 223, 301, + 435, 333, 334, 445, 334, 234, 335, 335, 335, 335, + + 335, 335, 335, 335, 223, 495, 383, 423, 223, 336, + 445, 337, 338, 339, 339, 339, 339, 339, 339, 339, + 339, 223, 359, 280, 499, 301, 340, 441, 341, 342, + 343, 343, 343, 343, 343, 343, 343, 343, 270, 459, + 456, 365, 234, 233, 233, 233, 233, 233, 233, 321, + 233, 322, 233, 233, 222, 455, 454, 316, 222, 281, + 222, 317, 233, 233, 233, 285, 234, 392, 357, 300, + 320, 300, 358, 505, 383, 431, 453, 373, 270, 461, + 318, 449, 310, 269, 280, 269, 311, 223, 301, 233, + 348, 359, 348, 406, 349, 349, 349, 349, 349, 349, + + 349, 349, 352, 300, 352, 312, 353, 353, 353, 353, + 353, 353, 353, 353, 356, 356, 356, 356, 356, 356, + 356, 356, 60, 383, 471, 60, 301, 362, 362, 362, + 362, 362, 362, 362, 362, 465, 451, 448, 473, 234, + 357, 301, 320, 234, 234, 356, 356, 356, 356, 356, + 356, 356, 356, 291, 446, 485, 291, 301, 363, 233, + 322, 233, 364, 374, 375, 270, 375, 378, 376, 376, + 376, 376, 376, 376, 376, 376, 310, 269, 280, 269, + 301, 365, 363, 306, 322, 460, 306, 362, 362, 362, + 362, 362, 362, 362, 362, 316, 222, 281, 222, 234, + + 233, 444, 442, 226, 464, 379, 380, 445, 380, 489, + 381, 381, 381, 381, 381, 381, 381, 381, 223, 223, + 383, 479, 234, 384, 440, 385, 439, 386, 387, 387, + 387, 387, 387, 387, 387, 387, 357, 300, 320, 300, + 358, 521, 438, 394, 493, 437, 388, 493, 270, 363, + 233, 322, 233, 364, 525, 301, 398, 416, 301, 359, + 395, 223, 395, 497, 396, 396, 396, 396, 396, 396, + 396, 396, 365, 399, 234, 399, 415, 400, 400, 400, + 400, 400, 400, 400, 400, 316, 222, 281, 222, 317, + 357, 300, 320, 300, 358, 414, 408, 363, 233, 322, + + 233, 364, 410, 357, 300, 320, 300, 358, 318, 412, + 413, 497, 402, 359, 450, 310, 269, 280, 269, 311, + 365, 269, 234, 509, 458, 419, 359, 420, 223, 421, + 422, 422, 422, 422, 422, 422, 422, 422, 312, 401, + 401, 383, 423, 363, 233, 322, 233, 364, 424, 222, + 319, 382, 320, 427, 452, 428, 493, 429, 430, 430, + 430, 430, 430, 430, 430, 430, 365, 301, 529, 383, + 431, 357, 300, 320, 300, 358, 432, 365, 301, 234, + 359, 434, 363, 233, 322, 233, 364, 310, 269, 280, + 269, 311, 436, 442, 359, 316, 222, 281, 222, 317, + + 513, 446, 238, 537, 301, 365, 497, 367, 301, 270, + 312, 316, 222, 281, 222, 317, 533, 234, 318, 517, + 462, 310, 269, 280, 269, 366, 234, 234, 488, 310, + 269, 280, 269, 311, 318, 300, 486, 545, 345, 467, + 344, 468, 301, 469, 470, 470, 470, 470, 470, 470, + 470, 470, 312, 234, 301, 383, 471, 316, 222, 281, + 222, 317, 472, 233, 490, 549, 318, 475, 223, 476, + 234, 477, 478, 478, 478, 478, 478, 478, 478, 478, + 318, 312, 553, 383, 479, 316, 222, 281, 222, 301, + 480, 557, 492, 357, 300, 320, 300, 358, 234, 494, + + 363, 233, 322, 233, 364, 270, 498, 310, 269, 280, + 269, 311, 310, 269, 280, 269, 359, 325, 310, 506, + 280, 324, 301, 365, 508, 316, 222, 281, 222, 317, + 312, 316, 222, 281, 222, 270, 304, 510, 357, 300, + 320, 300, 358, 512, 303, 301, 279, 514, 318, 357, + 300, 320, 300, 363, 233, 322, 233, 364, 516, 288, + 287, 359, 518, 363, 233, 322, 233, 310, 269, 280, + 269, 311, 520, 270, 275, 270, 365, 522, 310, 269, + 280, 269, 316, 222, 281, 222, 317, 263, 524, 257, + 312, 253, 526, 316, 222, 281, 222, 357, 300, 320, + + 300, 358, 251, 528, 530, 318, 357, 300, 320, 300, + 316, 249, 281, 532, 363, 233, 322, 233, 364, 247, + 359, 534, 363, 233, 322, 233, 245, 223, 243, 536, + 310, 269, 280, 269, 311, 241, 541, 365, 357, 239, + 320, 538, 223, 310, 269, 280, 269, 316, 222, 281, + 222, 317, 234, 312, 540, 301, 237, 235, 542, 234, + 316, 222, 281, 222, 357, 300, 320, 300, 358, 232, + 318, 544, 357, 300, 320, 300, 546, 363, 233, 322, + 233, 364, 561, 230, 548, 223, 225, 359, 301, 550, + 363, 233, 322, 233, 310, 269, 280, 269, 311, 363, + + 365, 322, 552, 310, 269, 280, 269, 316, 222, 281, + 222, 317, 316, 222, 281, 222, 234, 312, 357, 300, + 320, 300, 358, 357, 300, 320, 300, 223, 554, 221, + 318, 220, 213, 556, 363, 233, 322, 233, 364, 43, + 43, 359, 43, 43, 558, 363, 233, 322, 233, 357, + 300, 320, 300, 358, 43, 560, 167, 365, 160, 43, + 562, 565, 357, 300, 320, 300, 43, 234, 363, 233, + 322, 233, 359, 564, 363, 233, 322, 233, 364, 568, + 357, 300, 320, 300, 358, 566, 357, 300, 320, 300, + 363, 233, 322, 233, 364, 152, 146, 365, 363, 233, + + 322, 233, 141, 359, 137, 116, 47, 98, 63, 79, + 47, 63, 61, 365, 25, 25, 58, 57, 47, 25, + 25, 33, 26, 39, 38, 37, 33, 33, 33, 33, + 33, 33, 33, 42, 31, 30, 42, 42, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 46, 46, 46, 46, 46, 46, 46, 46, + 29, 46, 46, 46, 46, 46, 62, 62, 22, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 99, 99, 99, 99, 99, 99, + + 99, 99, 99, 99, 99, 99, 99, 99, 117, 117, + 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, + 117, 117, 130, 21, 130, 130, 130, 130, 130, 130, + 130, 130, 130, 130, 130, 130, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 215, 215, 20, 569, 569, 569, 569, 215, 215, 215, + 215, 218, 569, 218, 218, 218, 218, 218, 218, 218, + 222, 222, 222, 222, 222, 222, 222, 222, 569, 222, + 222, 222, 222, 222, 224, 224, 569, 569, 569, 569, + 569, 224, 224, 224, 224, 228, 569, 228, 228, 228, + + 228, 228, 228, 228, 233, 233, 233, 233, 233, 233, + 233, 233, 569, 233, 233, 233, 233, 233, 255, 255, + 255, 255, 260, 569, 260, 260, 260, 260, 260, 260, + 260, 268, 569, 268, 268, 269, 269, 269, 269, 269, + 269, 269, 269, 569, 269, 269, 269, 269, 269, 272, + 272, 272, 272, 282, 282, 282, 282, 282, 282, 282, + 282, 282, 282, 282, 282, 282, 282, 284, 569, 284, + 569, 284, 284, 284, 284, 284, 284, 284, 300, 300, + 300, 300, 300, 300, 300, 300, 569, 300, 300, 300, + 300, 300, 323, 323, 323, 323, 323, 323, 323, 323, + + 323, 323, 323, 323, 323, 323, 383, 569, 383, 383, + 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 426, 426, 426, 426, 426, 426, + 426, 426, 426, 426, 426, 426, 426, 426, 466, 466, + 466, 466, 466, 466, 466, 466, 466, 466, 466, 466, + 466, 466, 474, 474, 474, 474, 474, 474, 474, 474, + 474, 474, 474, 474, 474, 474, 3, 569, 569, 569, + 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, + 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, + + 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, + 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, + 569, 569, 569, 569, 569 + } ; + +static yyconst short int yy_chk[2426] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 11, 12, + 32, 32, 16, 17, 204, 26, 18, 26, 33, 39, + 40, 39, 40, 43, 43, 595, 47, 11, 12, 16, + 17, 11, 12, 18, 204, 33, 48, 570, 52, 49, + 53, 54, 11, 12, 47, 18, 54, 51, 59, 559, + 59, 17, 35, 48, 54, 52, 49, 53, 63, 63, + + 207, 50, 119, 119, 51, 52, 48, 53, 209, 35, + 49, 49, 35, 35, 35, 51, 35, 35, 50, 51, + 35, 55, 35, 56, 35, 35, 57, 207, 50, 66, + 35, 209, 68, 50, 65, 131, 131, 67, 55, 326, + 56, 55, 214, 57, 64, 64, 66, 326, 55, 68, + 69, 65, 55, 57, 67, 70, 71, 67, 72, 56, + 73, 64, 64, 74, 65, 214, 68, 69, 66, 76, + 69, 75, 70, 71, 77, 72, 71, 73, 182, 182, + 74, 78, 72, 70, 80, 80, 76, 149, 75, 555, + 73, 77, 84, 74, 85, 75, 76, 76, 78, 81, + + 81, 80, 80, 83, 83, 78, 77, 86, 87, 84, + 88, 85, 149, 248, 89, 90, 81, 81, 91, 92, + 83, 83, 94, 248, 86, 87, 226, 88, 163, 84, + 87, 89, 90, 93, 95, 91, 92, 86, 96, 94, + 88, 89, 97, 92, 226, 90, 91, 103, 100, 100, + 93, 95, 94, 163, 106, 96, 93, 104, 104, 97, + 99, 99, 101, 101, 103, 96, 100, 102, 102, 105, + 97, 106, 107, 108, 95, 103, 109, 99, 99, 101, + 101, 110, 106, 104, 102, 102, 105, 197, 197, 107, + 108, 111, 105, 109, 551, 107, 112, 113, 110, 109, + + 114, 126, 115, 547, 110, 108, 166, 223, 111, 117, + 117, 111, 121, 112, 113, 118, 118, 114, 126, 115, + 120, 120, 223, 113, 114, 115, 117, 117, 123, 121, + 124, 166, 112, 118, 128, 125, 126, 120, 120, 122, + 122, 127, 122, 129, 178, 123, 132, 124, 123, 121, + 136, 128, 125, 134, 124, 125, 140, 140, 127, 140, + 129, 127, 138, 132, 210, 138, 195, 136, 231, 178, + 134, 135, 135, 231, 129, 139, 244, 134, 139, 244, + 136, 132, 133, 133, 210, 215, 181, 138, 133, 133, + 133, 133, 133, 133, 133, 133, 195, 135, 138, 215, + + 139, 142, 142, 142, 142, 142, 142, 142, 142, 143, + 143, 181, 143, 144, 144, 144, 144, 144, 144, 144, + 144, 154, 154, 240, 154, 535, 201, 144, 144, 144, + 144, 144, 144, 145, 145, 145, 145, 145, 145, 145, + 145, 147, 240, 208, 147, 147, 147, 147, 147, 147, + 147, 147, 156, 156, 190, 156, 158, 158, 202, 158, + 169, 169, 201, 169, 171, 171, 147, 171, 173, 173, + 191, 173, 175, 175, 194, 175, 190, 147, 150, 208, + 202, 150, 150, 150, 150, 150, 150, 150, 150, 183, + 183, 531, 183, 185, 185, 191, 185, 187, 187, 194, + + 187, 189, 189, 150, 189, 196, 196, 252, 196, 198, + 198, 203, 198, 252, 150, 153, 153, 153, 153, 153, + 153, 153, 153, 155, 155, 155, 155, 155, 155, 155, + 155, 200, 200, 205, 200, 527, 203, 155, 155, 155, + 155, 155, 155, 157, 157, 157, 157, 157, 157, 157, + 157, 159, 159, 159, 159, 159, 159, 159, 159, 206, + 206, 212, 206, 205, 523, 159, 159, 159, 159, 159, + 159, 161, 213, 213, 161, 161, 161, 161, 161, 161, + 161, 161, 236, 218, 220, 220, 224, 228, 212, 234, + 246, 238, 255, 242, 519, 236, 161, 218, 242, 264, + + 224, 228, 250, 246, 234, 264, 255, 161, 164, 238, + 256, 164, 164, 164, 164, 164, 164, 164, 164, 254, + 258, 250, 254, 259, 260, 259, 259, 256, 515, 265, + 258, 265, 265, 164, 279, 289, 279, 289, 260, 268, + 511, 268, 268, 268, 164, 168, 168, 168, 168, 168, + 168, 168, 168, 170, 170, 170, 170, 170, 170, 170, + 170, 290, 268, 290, 291, 507, 291, 170, 170, 170, + 170, 170, 170, 172, 172, 172, 172, 172, 172, 172, + 172, 174, 174, 174, 174, 174, 174, 174, 174, 292, + 276, 292, 276, 499, 495, 174, 174, 174, 174, 174, + + 174, 176, 270, 273, 176, 176, 176, 176, 176, 176, + 176, 176, 272, 276, 272, 491, 284, 270, 284, 293, + 273, 293, 331, 296, 293, 296, 176, 487, 272, 297, + 331, 297, 284, 305, 297, 305, 573, 176, 179, 573, + 484, 179, 179, 179, 179, 179, 179, 179, 179, 295, + 295, 295, 295, 295, 301, 306, 301, 306, 307, 313, + 329, 483, 329, 179, 299, 299, 299, 299, 299, 307, + 313, 301, 295, 482, 179, 184, 184, 184, 184, 184, + 184, 184, 184, 330, 330, 330, 330, 299, 481, 184, + 184, 184, 184, 184, 184, 186, 186, 186, 186, 186, + + 186, 186, 186, 188, 188, 188, 188, 188, 188, 188, + 188, 334, 336, 334, 336, 346, 372, 188, 188, 188, + 188, 188, 188, 192, 372, 346, 192, 192, 192, 192, + 192, 192, 192, 192, 308, 308, 308, 308, 308, 335, + 335, 335, 335, 308, 340, 348, 340, 348, 192, 314, + 314, 314, 314, 314, 352, 480, 352, 308, 314, 192, + 199, 199, 199, 199, 199, 199, 199, 199, 337, 375, + 337, 375, 314, 337, 199, 199, 199, 199, 199, 199, + 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, + 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, + + 262, 262, 262, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 327, 327, 327, 327, 327, 377, + 476, 327, 271, 271, 271, 271, 271, 377, 332, 332, + 332, 332, 332, 472, 380, 332, 380, 327, 350, 339, + 339, 339, 339, 339, 349, 349, 349, 349, 350, 271, + 280, 332, 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 339, 341, 468, 341, 280, 281, 341, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 353, + 353, 353, 353, 281, 282, 282, 282, 282, 282, 282, + 282, 282, 282, 282, 282, 343, 343, 343, 343, 343, + + 354, 360, 463, 282, 282, 282, 282, 282, 368, 370, + 386, 354, 360, 368, 370, 395, 459, 395, 343, 376, + 376, 376, 376, 381, 381, 381, 381, 386, 456, 455, + 282, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 294, 294, 294, 294, 294, 294, + 294, 294, 399, 454, 399, 393, 294, 298, 298, 298, + 298, 298, 298, 298, 298, 393, 501, 453, 501, 298, + 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, + 302, 389, 347, 347, 347, 347, 347, 447, 389, 302, + + 302, 302, 302, 302, 347, 351, 351, 351, 351, 351, + 441, 385, 391, 385, 418, 347, 385, 351, 441, 391, + 369, 369, 369, 369, 369, 418, 302, 309, 351, 309, + 369, 397, 309, 309, 309, 309, 309, 309, 309, 309, + 388, 397, 388, 369, 309, 388, 396, 396, 396, 396, + 309, 312, 421, 312, 429, 312, 312, 312, 312, 312, + 312, 312, 312, 400, 400, 400, 400, 312, 315, 421, + 315, 429, 419, 315, 315, 315, 315, 315, 315, 315, + 315, 405, 407, 419, 409, 315, 417, 405, 407, 409, + 411, 315, 318, 426, 318, 411, 318, 318, 318, 318, + + 318, 318, 318, 318, 426, 469, 417, 417, 318, 320, + 427, 320, 320, 320, 320, 320, 320, 320, 320, 320, + 320, 427, 469, 423, 477, 320, 322, 423, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, 423, 443, + 440, 477, 322, 323, 323, 323, 323, 323, 323, 323, + 323, 323, 323, 323, 425, 439, 438, 371, 371, 371, + 371, 371, 323, 323, 323, 323, 323, 371, 355, 355, + 355, 355, 355, 485, 425, 425, 437, 355, 485, 445, + 371, 433, 390, 390, 390, 390, 390, 445, 433, 323, + 328, 355, 328, 390, 328, 328, 328, 328, 328, 328, + + 328, 328, 333, 465, 333, 390, 333, 333, 333, 333, + 333, 333, 333, 333, 338, 338, 338, 338, 338, 338, + 338, 338, 577, 465, 465, 577, 338, 342, 342, 342, + 342, 342, 342, 342, 342, 449, 435, 432, 451, 342, + 356, 449, 356, 435, 451, 356, 356, 356, 356, 356, + 356, 356, 356, 598, 428, 457, 598, 356, 361, 361, + 361, 361, 361, 356, 359, 457, 359, 361, 359, 359, + 359, 359, 359, 359, 359, 359, 444, 444, 444, 444, + 359, 361, 362, 600, 362, 444, 600, 362, 362, 362, + 362, 362, 362, 362, 362, 448, 448, 448, 448, 362, + + 473, 424, 420, 431, 448, 362, 365, 431, 365, 461, + 365, 365, 365, 365, 365, 365, 365, 365, 431, 461, + 473, 473, 365, 367, 416, 367, 415, 367, 367, 367, + 367, 367, 367, 367, 367, 367, 373, 373, 373, 373, + 373, 505, 414, 373, 466, 413, 367, 467, 505, 378, + 378, 378, 378, 378, 509, 466, 378, 404, 467, 373, + 374, 509, 374, 474, 374, 374, 374, 374, 374, 374, + 374, 374, 378, 379, 474, 379, 403, 379, 379, 379, + 379, 379, 379, 379, 379, 392, 392, 392, 392, 392, + 394, 394, 394, 394, 394, 402, 392, 398, 398, 398, + + 398, 398, 394, 434, 434, 434, 434, 434, 392, 398, + 401, 475, 387, 394, 434, 442, 442, 442, 442, 442, + 398, 406, 475, 489, 442, 406, 434, 406, 489, 406, + 406, 406, 406, 406, 406, 406, 406, 406, 442, 384, + 383, 406, 406, 436, 436, 436, 436, 436, 406, 408, + 471, 366, 471, 408, 436, 408, 471, 408, 408, 408, + 408, 408, 408, 408, 408, 408, 436, 471, 513, 408, + 408, 410, 410, 410, 410, 410, 408, 364, 513, 363, + 358, 410, 412, 412, 412, 412, 412, 422, 422, 422, + 422, 422, 412, 422, 410, 430, 430, 430, 430, 430, + + 493, 430, 479, 521, 357, 412, 479, 345, 493, 521, + 422, 446, 446, 446, 446, 446, 517, 479, 430, 497, + 446, 460, 460, 460, 460, 344, 517, 497, 460, 458, + 458, 458, 458, 458, 446, 450, 458, 529, 325, 450, + 324, 450, 529, 450, 450, 450, 450, 450, 450, 450, + 450, 450, 458, 321, 319, 450, 450, 462, 462, 462, + 462, 462, 450, 452, 462, 533, 317, 452, 316, 452, + 533, 452, 452, 452, 452, 452, 452, 452, 452, 452, + 462, 311, 545, 452, 452, 464, 464, 464, 464, 545, + 452, 549, 464, 470, 470, 470, 470, 470, 549, 470, + + 478, 478, 478, 478, 478, 310, 478, 486, 486, 486, + 486, 486, 488, 488, 488, 488, 470, 304, 537, 486, + 537, 303, 300, 478, 488, 490, 490, 490, 490, 490, + 486, 492, 492, 492, 492, 537, 288, 490, 494, 494, + 494, 494, 494, 492, 287, 285, 278, 494, 490, 496, + 496, 496, 496, 498, 498, 498, 498, 498, 496, 275, + 274, 494, 498, 500, 500, 500, 500, 506, 506, 506, + 506, 506, 500, 269, 266, 261, 498, 506, 508, 508, + 508, 508, 510, 510, 510, 510, 510, 257, 508, 253, + 506, 249, 510, 512, 512, 512, 512, 514, 514, 514, + + 514, 514, 247, 512, 514, 510, 516, 516, 516, 516, + 541, 245, 541, 516, 518, 518, 518, 518, 518, 243, + 514, 518, 520, 520, 520, 520, 241, 541, 239, 520, + 522, 522, 522, 522, 522, 237, 525, 518, 561, 235, + 561, 522, 525, 524, 524, 524, 524, 526, 526, 526, + 526, 526, 233, 522, 524, 561, 232, 230, 526, 229, + 528, 528, 528, 528, 530, 530, 530, 530, 530, 227, + 526, 528, 532, 532, 532, 532, 530, 534, 534, 534, + 534, 534, 553, 225, 532, 222, 221, 530, 553, 534, + 536, 536, 536, 536, 538, 538, 538, 538, 538, 565, + + 534, 565, 536, 540, 540, 540, 540, 542, 542, 542, + 542, 542, 544, 544, 544, 544, 565, 538, 546, 546, + 546, 546, 546, 548, 548, 548, 548, 219, 546, 217, + 542, 216, 211, 548, 550, 550, 550, 550, 550, 193, + 180, 546, 177, 165, 550, 552, 552, 552, 552, 554, + 554, 554, 554, 554, 162, 552, 160, 550, 152, 151, + 554, 557, 556, 556, 556, 556, 148, 557, 560, 560, + 560, 560, 554, 556, 558, 558, 558, 558, 558, 560, + 562, 562, 562, 562, 562, 558, 564, 564, 564, 564, + 566, 566, 566, 566, 566, 146, 141, 558, 568, 568, + + 568, 568, 137, 562, 130, 98, 82, 79, 62, 58, + 46, 44, 42, 566, 571, 571, 38, 36, 34, 571, + 571, 572, 24, 23, 22, 19, 572, 572, 572, 572, + 572, 572, 572, 574, 15, 14, 574, 574, 575, 575, + 575, 575, 575, 575, 575, 575, 575, 575, 575, 575, + 575, 575, 576, 576, 576, 576, 576, 576, 576, 576, + 13, 576, 576, 576, 576, 576, 578, 578, 9, 578, + 578, 578, 578, 578, 578, 578, 578, 578, 578, 578, + 579, 579, 579, 579, 579, 579, 579, 579, 579, 579, + 579, 579, 579, 579, 580, 580, 580, 580, 580, 580, + + 580, 580, 580, 580, 580, 580, 580, 580, 581, 581, + 581, 581, 581, 581, 581, 581, 581, 581, 581, 581, + 581, 581, 582, 8, 582, 582, 582, 582, 582, 582, + 582, 582, 582, 582, 582, 582, 583, 583, 583, 583, + 583, 583, 583, 583, 583, 583, 583, 583, 583, 583, + 584, 584, 7, 3, 0, 0, 0, 584, 584, 584, + 584, 585, 0, 585, 585, 585, 585, 585, 585, 585, + 586, 586, 586, 586, 586, 586, 586, 586, 0, 586, + 586, 586, 586, 586, 587, 587, 0, 0, 0, 0, + 0, 587, 587, 587, 587, 588, 0, 588, 588, 588, + + 588, 588, 588, 588, 589, 589, 589, 589, 589, 589, + 589, 589, 0, 589, 589, 589, 589, 589, 590, 590, + 590, 590, 591, 0, 591, 591, 591, 591, 591, 591, + 591, 592, 0, 592, 592, 593, 593, 593, 593, 593, + 593, 593, 593, 0, 593, 593, 593, 593, 593, 594, + 594, 594, 594, 596, 596, 596, 596, 596, 596, 596, + 596, 596, 596, 596, 596, 596, 596, 597, 0, 597, + 0, 597, 597, 597, 597, 597, 597, 597, 599, 599, + 599, 599, 599, 599, 599, 599, 0, 599, 599, 599, + 599, 599, 601, 601, 601, 601, 601, 601, 601, 601, + + 601, 601, 601, 601, 601, 601, 602, 0, 602, 602, + 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, + 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, + 603, 603, 603, 603, 604, 604, 604, 604, 604, 604, + 604, 604, 604, 604, 604, 604, 604, 604, 605, 605, + 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, + 605, 605, 606, 606, 606, 606, 606, 606, 606, 606, + 606, 606, 606, 606, 606, 606, 569, 569, 569, 569, + 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, + 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, + + 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, + 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, + 569, 569, 569, 569, 569 + } ; + +static yy_state_type yy_last_accepting_state; +static char *yy_last_accepting_cpos; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +#ifndef YYLMAX +#define YYLMAX 8192 +#endif + +char yytext[YYLMAX]; +char *idxtext_ptr; +#line 1 "idx.l" +#define INITIAL 0 +#line 5 "idx.l" +#include +#include +#include +#include + +extern int idx_debug; + +static int _valint(char *s, idxvalrec **v); +static int _valfloat(char *s, idxvalrec **v); +static int _valname(char *s, idxvalrec **v); +static int _valreg(char *s, idxvalrec **v); +static int _valfunc(char *s, idxvalrec **v); +/* note that negative numbers are not defined here, but in the grammar */ +/* must match regions in filt.l */ +#line 1133 "lex.idx.c" + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap YY_PROTO(( void )); +#else +extern int yywrap YY_PROTO(( void )); +#endif +#endif + +#ifndef YY_NO_UNPUT +static void yyunput YY_PROTO(( int c, char *buf_ptr )); +#endif + +#ifndef idxtext_ptr +static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int )); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen YY_PROTO(( yyconst char * )); +#endif + +#ifndef YY_NO_INPUT +#ifdef __cplusplus +static int yyinput YY_PROTO(( void )); +#else +static int input YY_PROTO(( void )); +#endif +#endif + +#if YY_STACK_USED +static int yy_start_stack_ptr = 0; +static int yy_start_stack_depth = 0; +static int *yy_start_stack = 0; +#ifndef YY_NO_PUSH_STATE +static void yy_push_state YY_PROTO(( int new_state )); +#endif +#ifndef YY_NO_POP_STATE +static void yy_pop_state YY_PROTO(( void )); +#endif +#ifndef YY_NO_TOP_STATE +static int yy_top_state YY_PROTO(( void )); +#endif + +#else +#define YY_NO_PUSH_STATE 1 +#define YY_NO_POP_STATE 1 +#define YY_NO_TOP_STATE 1 +#endif + +#ifdef YY_MALLOC_DECL +YY_MALLOC_DECL +#else +#if __STDC__ +#ifndef __cplusplus +#include +#endif +#else +/* Just try to get by without declaring the routines. This will fail + * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int) + * or sizeof(void*) != sizeof(int). + */ +#endif +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ + +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( yy_current_buffer->yy_is_interactive ) \ + { \ + int c = '*', n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \ + && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL int yylex YY_PROTO(( void )) +#endif + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +YY_DECL + { + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + +#line 35 "idx.l" + + +#line 1287 "lex.idx.c" + + if ( yy_init ) + { + yy_init = 0; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! yy_start ) + yy_start = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! yy_current_buffer ) + yy_current_buffer = + yy_create_buffer( yyin, YY_BUF_SIZE ); + + yy_load_buffer_state(); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = yy_c_buf_p; + + /* Support of yytext. */ + *yy_cp = yy_hold_char; + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = yy_start; +yy_match: + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if ( yy_accept[yy_current_state] ) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 570 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 2377 ); + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + if ( yy_act == 0 ) + { /* have to back up */ + yy_cp = yy_last_accepting_cpos; + yy_current_state = yy_last_accepting_state; + yy_act = yy_accept[yy_current_state]; + } + + YY_DO_BEFORE_ACTION; + + +do_action: /* This label is used only to access EOF actions. */ + + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = yy_hold_char; + yy_cp = yy_last_accepting_cpos; + yy_current_state = yy_last_accepting_state; + goto yy_find_action; + +case 1: +YY_RULE_SETUP +#line 37 "idx.l" +{return _valint(yytext, &(idxlval.val));} + YY_BREAK +case 2: +YY_RULE_SETUP +#line 39 "idx.l" +{return _valfloat(yytext, &(idxlval.val));} + YY_BREAK +case 3: +YY_RULE_SETUP +#line 42 "idx.l" +{ + return _valreg(yytext, &(idxlval.val)); +} + YY_BREAK +case 4: +YY_RULE_SETUP +#line 46 "idx.l" +{ + return _valreg(yytext, &(idxlval.val)); +} + YY_BREAK +case 5: +YY_RULE_SETUP +#line 50 "idx.l" +{ + /* support functions with one level of nested parens */ + return _valfunc(yytext, &(idxlval.val)); +} + YY_BREAK +case 6: +YY_RULE_SETUP +#line 55 "idx.l" +{return _valname(yytext, &(idxlval.val));} + YY_BREAK +case 7: +YY_RULE_SETUP +#line 57 "idx.l" +{return OR;} + YY_BREAK +case 8: +YY_RULE_SETUP +#line 58 "idx.l" +{return AND;} + YY_BREAK +case 9: +YY_RULE_SETUP +#line 59 "idx.l" +{return EQ;} + YY_BREAK +case 10: +YY_RULE_SETUP +#line 60 "idx.l" +{return NE;} + YY_BREAK +case 11: +YY_RULE_SETUP +#line 61 "idx.l" +{return LE;} + YY_BREAK +case 12: +YY_RULE_SETUP +#line 62 "idx.l" +{return GE;} + YY_BREAK +case 13: +YY_RULE_SETUP +#line 64 "idx.l" +{;} + YY_BREAK +case YY_STATE_EOF(INITIAL): +#line 66 "idx.l" +{ + yy_delete_buffer( YY_CURRENT_BUFFER ); + yyterminate(); + } + YY_BREAK +case 14: +YY_RULE_SETUP +#line 71 "idx.l" +{return yytext[0];} + YY_BREAK +case 15: +YY_RULE_SETUP +#line 73 "idx.l" +ECHO; + YY_BREAK +#line 1459 "lex.idx.c" + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - idxtext_ptr) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = yy_hold_char; + YY_RESTORE_YY_MORE_OFFSET + + if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between yy_current_buffer and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + yy_n_chars = yy_current_buffer->yy_n_chars; + yy_current_buffer->yy_input_file = yyin; + yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + yy_c_buf_p = idxtext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state(); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = idxtext_ptr + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++yy_c_buf_p; + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = yy_c_buf_p; + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer() ) + { + case EOB_ACT_END_OF_FILE: + { + yy_did_buffer_switch_on_eof = 0; + + if ( yywrap() ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + yy_c_buf_p = idxtext_ptr + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = + idxtext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state(); + + yy_cp = yy_c_buf_p; + yy_bp = idxtext_ptr + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + yy_c_buf_p = + &yy_current_buffer->yy_ch_buf[yy_n_chars]; + + yy_current_state = yy_get_previous_state(); + + yy_cp = yy_c_buf_p; + yy_bp = idxtext_ptr + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ + } /* end of yylex */ + + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ + +static int yy_get_next_buffer() + { + register char *dest = yy_current_buffer->yy_ch_buf; + register char *source = idxtext_ptr; + register int number_to_move, i; + int ret_val; + + if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( yy_current_buffer->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( yy_c_buf_p - idxtext_ptr - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) (yy_c_buf_p - idxtext_ptr) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + yy_current_buffer->yy_n_chars = yy_n_chars = 0; + + else + { + int num_to_read = + yy_current_buffer->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ +#ifdef YY_USES_REJECT + YY_FATAL_ERROR( +"input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); +#else + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = yy_current_buffer; + + int yy_c_buf_p_offset = + (int) (yy_c_buf_p - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yy_flex_realloc( (void *) b->yy_ch_buf, + b->yy_buf_size + 2 ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = yy_current_buffer->yy_buf_size - + number_to_move - 1; +#endif + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), + yy_n_chars, num_to_read ); + + yy_current_buffer->yy_n_chars = yy_n_chars; + } + + if ( yy_n_chars == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart( yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + yy_current_buffer->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + yy_n_chars += number_to_move; + yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; + yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; + + idxtext_ptr = &yy_current_buffer->yy_ch_buf[0]; + + return ret_val; + } + + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + +static yy_state_type yy_get_previous_state() + { + register yy_state_type yy_current_state; + register char *yy_cp; + + yy_current_state = yy_start; + + for ( yy_cp = idxtext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 570 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + } + + return yy_current_state; + } + + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + +#ifdef YY_USE_PROTOS +static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state ) +#else +static yy_state_type yy_try_NUL_trans( yy_current_state ) +yy_state_type yy_current_state; +#endif + { + register int yy_is_jam; + register char *yy_cp = yy_c_buf_p; + + register YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 570 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 569); + + return yy_is_jam ? 0 : yy_current_state; + } + + +#ifndef YY_NO_UNPUT +#ifdef YY_USE_PROTOS +static void yyunput( int c, register char *yy_bp ) +#else +static void yyunput( c, yy_bp ) +int c; +register char *yy_bp; +#endif + { + register char *yy_cp = yy_c_buf_p; + + /* undo effects of setting up yytext */ + *yy_cp = yy_hold_char; + + if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register int number_to_move = yy_n_chars + 2; + register char *dest = &yy_current_buffer->yy_ch_buf[ + yy_current_buffer->yy_buf_size + 2]; + register char *source = + &yy_current_buffer->yy_ch_buf[number_to_move]; + + while ( source > yy_current_buffer->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + yy_current_buffer->yy_n_chars = + yy_n_chars = yy_current_buffer->yy_buf_size; + + if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + + + idxtext_ptr = yy_bp; + yy_hold_char = *yy_cp; + yy_c_buf_p = yy_cp; + } +#endif /* ifndef YY_NO_UNPUT */ + + +#ifdef __cplusplus +static int yyinput() +#else +static int input() +#endif + { + int c; + + *yy_c_buf_p = yy_hold_char; + + if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + /* This was really a NUL. */ + *yy_c_buf_p = '\0'; + + else + { /* need more input */ + int offset = yy_c_buf_p - idxtext_ptr; + ++yy_c_buf_p; + + switch ( yy_get_next_buffer() ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart( yyin ); + + /* fall through */ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap() ) + return EOF; + + if ( ! yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = idxtext_ptr + offset; + break; + } + } + } + + c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */ + *yy_c_buf_p = '\0'; /* preserve yytext */ + yy_hold_char = *++yy_c_buf_p; + + + return c; + } + + +#ifdef YY_USE_PROTOS +void yyrestart( FILE *input_file ) +#else +void yyrestart( input_file ) +FILE *input_file; +#endif + { + if ( ! yy_current_buffer ) + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); + + yy_init_buffer( yy_current_buffer, input_file ); + yy_load_buffer_state(); + } + + +#ifdef YY_USE_PROTOS +void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) +#else +void yy_switch_to_buffer( new_buffer ) +YY_BUFFER_STATE new_buffer; +#endif + { + if ( yy_current_buffer == new_buffer ) + return; + + if ( yy_current_buffer ) + { + /* Flush out information for old buffer. */ + *yy_c_buf_p = yy_hold_char; + yy_current_buffer->yy_buf_pos = yy_c_buf_p; + yy_current_buffer->yy_n_chars = yy_n_chars; + } + + yy_current_buffer = new_buffer; + yy_load_buffer_state(); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + yy_did_buffer_switch_on_eof = 1; + } + + +#ifdef YY_USE_PROTOS +void yy_load_buffer_state( void ) +#else +void yy_load_buffer_state() +#endif + { + yy_n_chars = yy_current_buffer->yy_n_chars; + idxtext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos; + yyin = yy_current_buffer->yy_input_file; + yy_hold_char = *yy_c_buf_p; + } + + +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_create_buffer( FILE *file, int size ) +#else +YY_BUFFER_STATE yy_create_buffer( file, size ) +FILE *file; +int size; +#endif + { + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer( b, file ); + + return b; + } + + +#ifdef YY_USE_PROTOS +void yy_delete_buffer( YY_BUFFER_STATE b ) +#else +void yy_delete_buffer( b ) +YY_BUFFER_STATE b; +#endif + { + if ( ! b ) + return; + + if ( b == yy_current_buffer ) + yy_current_buffer = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yy_flex_free( (void *) b->yy_ch_buf ); + + yy_flex_free( (void *) b ); + } + + +#ifndef YY_ALWAYS_INTERACTIVE +#ifndef YY_NEVER_INTERACTIVE +extern int isatty YY_PROTO(( int )); +#endif +#endif + +#ifdef YY_USE_PROTOS +void yy_init_buffer( YY_BUFFER_STATE b, FILE *file ) +#else +void yy_init_buffer( b, file ) +YY_BUFFER_STATE b; +FILE *file; +#endif + + + { + yy_flush_buffer( b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + +#if YY_ALWAYS_INTERACTIVE + b->yy_is_interactive = 1; +#else +#if YY_NEVER_INTERACTIVE + b->yy_is_interactive = 0; +#else + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; +#endif +#endif + } + + +#ifdef YY_USE_PROTOS +void yy_flush_buffer( YY_BUFFER_STATE b ) +#else +void yy_flush_buffer( b ) +YY_BUFFER_STATE b; +#endif + + { + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == yy_current_buffer ) + yy_load_buffer_state(); + } + + +#ifndef YY_NO_SCAN_BUFFER +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size ) +#else +YY_BUFFER_STATE yy_scan_buffer( base, size ) +char *base; +yy_size_t size; +#endif + { + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer( b ); + + return b; + } +#endif + + +#ifndef YY_NO_SCAN_STRING +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str ) +#else +YY_BUFFER_STATE yy_scan_string( yy_str ) +yyconst char *yy_str; +#endif + { + int len; + for ( len = 0; yy_str[len]; ++len ) + ; + + return yy_scan_bytes( yy_str, len ); + } +#endif + + +#ifndef YY_NO_SCAN_BYTES +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len ) +#else +YY_BUFFER_STATE yy_scan_bytes( bytes, len ) +yyconst char *bytes; +int len; +#endif + { + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = len + 2; + buf = (char *) yy_flex_alloc( n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < len; ++i ) + buf[i] = bytes[i]; + + buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer( buf, n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; + } +#endif + + +#ifndef YY_NO_PUSH_STATE +#ifdef YY_USE_PROTOS +static void yy_push_state( int new_state ) +#else +static void yy_push_state( new_state ) +int new_state; +#endif + { + if ( yy_start_stack_ptr >= yy_start_stack_depth ) + { + yy_size_t new_size; + + yy_start_stack_depth += YY_START_STACK_INCR; + new_size = yy_start_stack_depth * sizeof( int ); + + if ( ! yy_start_stack ) + yy_start_stack = (int *) yy_flex_alloc( new_size ); + + else + yy_start_stack = (int *) yy_flex_realloc( + (void *) yy_start_stack, new_size ); + + if ( ! yy_start_stack ) + YY_FATAL_ERROR( + "out of memory expanding start-condition stack" ); + } + + yy_start_stack[yy_start_stack_ptr++] = YY_START; + + BEGIN(new_state); + } +#endif + + +#ifndef YY_NO_POP_STATE +static void yy_pop_state() + { + if ( --yy_start_stack_ptr < 0 ) + YY_FATAL_ERROR( "start-condition stack underflow" ); + + BEGIN(yy_start_stack[yy_start_stack_ptr]); + } +#endif + + +#ifndef YY_NO_TOP_STATE +static int yy_top_state() + { + return yy_start_stack[yy_start_stack_ptr - 1]; + } +#endif + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +#ifdef YY_USE_PROTOS +static void yy_fatal_error( yyconst char msg[] ) +#else +static void yy_fatal_error( msg ) +char msg[]; +#endif + { + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); + } + + + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + yytext[yyleng] = yy_hold_char; \ + yy_c_buf_p = yytext + n; \ + yy_hold_char = *yy_c_buf_p; \ + *yy_c_buf_p = '\0'; \ + yyleng = n; \ + } \ + while ( 0 ) + + +/* Internal utility routines. */ + +#ifndef idxtext_ptr +#ifdef YY_USE_PROTOS +static void yy_flex_strncpy( char *s1, yyconst char *s2, int n ) +#else +static void yy_flex_strncpy( s1, s2, n ) +char *s1; +yyconst char *s2; +int n; +#endif + { + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; + } +#endif + +#ifdef YY_NEED_STRLEN +#ifdef YY_USE_PROTOS +static int yy_flex_strlen( yyconst char *s ) +#else +static int yy_flex_strlen( s ) +yyconst char *s; +#endif + { + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; + } +#endif + + +#ifdef YY_USE_PROTOS +static void *yy_flex_alloc( yy_size_t size ) +#else +static void *yy_flex_alloc( size ) +yy_size_t size; +#endif + { + return (void *) malloc( size ); + } + +#ifdef YY_USE_PROTOS +static void *yy_flex_realloc( void *ptr, yy_size_t size ) +#else +static void *yy_flex_realloc( ptr, size ) +void *ptr; +yy_size_t size; +#endif + { + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); + } + +#ifdef YY_USE_PROTOS +static void yy_flex_free( void *ptr ) +#else +static void yy_flex_free( ptr ) +void *ptr; +#endif + { + free( ptr ); + } + +#if YY_MAIN +int main() + { + yylex(); + return 0; + } +#endif +#line 73 "idx.l" + + +#ifdef YY_USE_PROTOS +static int _valint(char *s, idxvalrec **v) +#else +static int _valint(s, v) + char *s; + idxvalrec **v; +#endif +{ + char *t; + *v = idxvalnew(s); + (*v)->ival = strtoll(s, &t, 0); + if( *t ) + idxerror("bad integer value"); + (*v)->type = NUM; + (*v)->ntype = PARSE_INTEGER; + (*v)->dval = (double)(*v)->ival; + return NUM; +} + +#ifdef YY_USE_PROTOS +static int _valfloat(char *s, idxvalrec **v) +#else +static int _valfloat(s, v) + char *s; + idxvalrec **v; +#endif +{ + char *t; + *v = idxvalnew(s); + (*v)->dval = strtod(s, &t); + if( *t ) + idxerror("bad float value"); + (*v)->type = NUM; + (*v)->ntype = PARSE_FLOAT; + return NUM; +} + +#ifdef YY_USE_PROTOS +static int _valname(char *s, idxvalrec **v) +#else +static int _valname(s, v) + char *s; + idxvalrec **v; +#endif +{ + int i; + int got; + int oflag; + int isize=0; + char *iname; + char *colname; + char tail[SZ_LINE]; + FilterSymbols sp=NULL; + idxvalrec *vv; + + *v = idxvalnew(s); + /* lookup the string */ + if( !(sp=FilterSymbolLookup(FilterDefault(), s)) ){ + idxerror("column name not found in data file"); + (*v)->type = INDEF; + return INDEF; + } + colname = idxinfo(IDX_COLNAME); + /* see what sort of symbol it is */ + switch(sp->type){ + case SYM_COL: + if( !(iname=idxindexfilename(s, &isize)) ){ + (*v)->type = INDEF; + return INDEF; + } + /* if we already have opened this index, just use the existing handle */ + if( (vv=idxlookupfilename(iname)) ){ + (*v)->igio = vv->igio; + (*v)->ifits = vv->ifits; + } + /* open index for first time and mark iname */ + else{ + oflag = setgerror(0); + (*v)->igio = ft_fitsheadopen(iname, &((*v)->ifits), tail, SZ_LINE, "r"); + setgerror(oflag); + if( !((*v)->igio) ){ + idxerror("existing index file can't be opened"); + (*v)->type = INDEF; + return INDEF; + } + else{ + (*v)->iname = xstrdup(iname); + } + } + xfree(iname); + if( (*v)->ifits ){ + for(got=0, i=0; i<(*v)->ifits->table->tfields; i++){ + if( !strcasecmp(s, (*v)->ifits->table->col[i].name) ){ + (*v)->vtype = (*v)->ifits->table->col[i].type; + (*v)->voffset = (*v)->ifits->table->col[i].offset; + (*v)->vn = (*v)->ifits->table->col[i].n; + got++; + } + if( !strcasecmp(colname, (*v)->ifits->table->col[i].name) ){ + (*v)->itype = (*v)->ifits->table->col[i].type; + (*v)->ioffset = (*v)->ifits->table->col[i].offset; + (*v)->in = (*v)->ifits->table->col[i].n; + got++; + } + } + if( got == 2 ){ +#ifdef HAVE_SYS_MMAN_H + if( !(*v)->igio->gz ){ + if(!((*v)->idata = mmap(NULL, isize, PROT_READ, MAP_PRIVATE, + fileno((*v)->igio->fp), 0)) ){ + idxerror("index file can't be mmap'ed"); + (*v)->type = INDEF; + return INDEF; + } + (*v)->ilen = isize; + } +#endif + (*v)->nrow = ft_naxis((*v)->ifits,2); + (*v)->type = COL; + return COL; + } + else{ + idxerror("column name and/or index not found in index file"); + } + } + else{ + (*v)->type = INDEF; + return INDEF; + } + case SYM_PAR: + (*v)->ntype=ParseDataType(sp->value, &(*v)->dval, &(*v)->ival); + (*v)->type = NUM; + switch((*v)->ntype){ + case PARSE_INTEGER: + case PARSE_HEXINT: + (*v)->dval = (double)(*v)->ival; + return NUM; + case PARSE_FLOAT: + return NUM; + default: + idxerror("invalid parameter type in index"); + return 0; + } + default: + idxerror("unknown symbol type in index"); + return 0; + } +} + +#ifdef YY_USE_PROTOS +static int _valreglims(idxvalrec *v, char *s) +#else +static int _valreglims(v, s) + idxvalrec *v; + char *s; +#endif +{ + int i; + int ip=0; + int nd=0, maxd=0; + double xcen, ycen; + double dval; + double *dvals; + double pts[8]; + char tbuf[SZ_LINE]; + char tbuf2[SZ_LINE]; + double angle; + double xwidth, yheight; + double angl; /* l: Cartesian angle in radians */ + double half_width, half_height;/* l: radii (1/2 width and height) */ + double cosangl, sinangl; /* l: sine, cosine of the Cartesian angle */ + double hw_cos, hw_sin; /* l: products of half_width with sin, cos */ + double hh_cos, hh_sin; /* l: products of half_height with sin, cos */ + + if( !strcmp(v->s, "circle") || !strcmp(v->s, "ncircle") || + !strcmp(v->s, "annulus") || !strcmp(v->s, "nannulus") ){ + if( !word(s, tbuf, &ip)||!word(s, tbuf2, &ip) ) return 0; + xcen = atof(tbuf); + ycen = atof(tbuf2); + dval = -1; + if( *v->s == 'n' ){ + if( !word(s, tbuf, &ip) || !word(s, tbuf, &ip) ) return 0; + dval = MAX(atof(tbuf),dval); + } + else{ + while( word(s, tbuf, &ip) && strcmp(tbuf, "-142857.142857") ){ + dval = MAX(atof(tbuf),dval); + } + } + v->rlo[0] = xcen - dval - 1; + v->rhi[0] = xcen + dval + 1; + v->rlo[1] = ycen - dval - 1; + v->rhi[1] = ycen + dval + 1; + return 1; + } + else if( !strcmp(v->s, "box") || !strcmp(v->s, "nbox") || + !strcmp(v->s, "ellipse") || !strcmp(v->s, "nellipse") ){ + if( !word(s, tbuf, &ip)||!word(s, tbuf2, &ip) ) return 0; + xcen = atof(tbuf); + ycen = atof(tbuf2); + maxd = SZ_LINE; + if( !(dvals=(double *)malloc(maxd*sizeof(double))) ) return 0; + if( *v->s == 'n' ){ + if( !word(s, tbuf, &ip) || !word(s, tbuf, &ip) ) return 0; + if( !word(s, tbuf, &ip) || !word(s, tbuf2, &ip) ) return 0; + dvals[nd++] = atof(tbuf); + dvals[nd++] = atof(tbuf2); + if( word(s, tbuf, &ip) && word(s, tbuf, &ip) ) + dvals[nd++] = atof(tbuf); + } + else{ + while( word(s, tbuf, &ip) && strcmp(tbuf, "-142857.142857") ){ + dvals[nd++] = atof(tbuf); + if( nd == maxd ){ + maxd += SZ_LINE; + if( !(dvals=(double *)realloc(dvals, maxd*sizeof(double))) ) return 0; + } + } + } +ellcom: + if( nd == 2 ){ + angle = 0.0; + xwidth = dvals[0]; + yheight = dvals[1]; + } + else{ + angle = dvals[nd-1]; + xwidth = dvals[nd-3]; + yheight = dvals[nd-2]; + } + if( dvals ) xfree(dvals); + + /* Why is this done in evfilter.c??? Doesn't seem necessary */ + /* angl = angle + 90.0; */ + angl = angle; + while (angl >= 360.0) angl = angl - 360.0; + /* convert to radians */ + angl = (angl / 180.0) * M_PI; + sinangl = sin (angl); + cosangl = cos (angl); + /* Why is this done in evfilter.c??? Doesn't seem necessary */ + /* since we rotate by 90.0 degrees to get from astro angle to cartesian, */ + /* we also need to switch the width and height. we do this secretly so */ + /* that the display will turn out right, by doing it in the half terms */ + if( !strcmp(v->s, "box") ){ + /* + half_width = yheight / 2.0; + half_height = xwidth / 2.0; + */ + half_width = xwidth / 2.0; + half_height = yheight / 2.0; + } + else{ + /* + half_width = yheight; + half_height = xwidth; + */ + half_width = xwidth; + half_height = yheight; + } + hw_cos = half_width * cosangl; + hw_sin = half_width * sinangl; + hh_cos = half_height * cosangl; + hh_sin = half_height * sinangl; + + pts[0] = xcen - hw_cos - hh_sin; + pts[1] = ycen - hw_sin + hh_cos; + pts[2] = xcen + hw_cos - hh_sin; + pts[3] = ycen + hw_sin + hh_cos; + pts[4] = xcen + hw_cos + hh_sin; + pts[5] = ycen + hw_sin - hh_cos; + pts[6] = xcen - hw_cos + hh_sin; + pts[7] = ycen - hw_sin - hh_cos; + + v->rlo[0] = pts[0]; + v->rhi[0] = pts[0]; + v->rlo[1] = pts[1]; + v->rhi[1] = pts[1]; + for(i=2; i<8; i+=2){ + v->rlo[0] = MIN(pts[i],v->rlo[0]); + v->rhi[0] = MAX(pts[i],v->rhi[0]); + v->rlo[1] = MIN(pts[i+1],v->rlo[1]); + v->rhi[1] = MAX(pts[i+1],v->rhi[1]); + } + return 1; + } + else if( !strcmp(v->s, "line") ){ + for(i=0; i<4; i++){ + if( word(s, tbuf, &ip) ){ + pts[i] = atof(tbuf); + } + } + v->rlo[0] = MIN(pts[0],pts[2]); + v->rhi[0] = MAX(pts[0],pts[2]); + v->rlo[1] = MIN(pts[1],pts[3]); + v->rhi[1] = MAX(pts[1],pts[3]); + return 1; + } + else if( !strcmp(v->s, "point") || !strcmp(v->s, "polygon") ){ + if( !word(s, tbuf, &ip)||!word(s, tbuf2, &ip) ) return 0; + xcen = atof(tbuf); + ycen = atof(tbuf2); + v->rlo[0] = xcen-1; + v->rhi[0] = xcen+1; + v->rlo[1] = ycen-1; + v->rhi[1] = ycen+1; + while( word(s, tbuf, &ip) && strcmp(tbuf, "-142857.142857") && + word(s, tbuf2, &ip) ){ + dval = atof(tbuf); + v->rlo[0] = MIN(dval-1,v->rlo[0]); + v->rhi[0] = MAX(dval+1,v->rhi[0]); + dval = atof(tbuf2); + v->rlo[1] = MIN(dval-1,v->rlo[1]); + v->rhi[1] = MAX(dval+1,v->rhi[1]); + } + return 1; + } + else if( !strcmp(v->s, "pie") || !strcmp(v->s, "qtpie") ){ + return 0; + } + else if( !strcmp(v->s, "panda") || !strcmp(v->s, "cpanda") ){ + maxd = SZ_LINE; + if( !(dvals=(double *)malloc(maxd*sizeof(double))) ) return 0; + while( word(s, tbuf, &ip) && strcmp(tbuf, "-142857.142857") ){ + dvals[nd++] = atof(tbuf); + if( nd == maxd ){ + maxd += SZ_LINE; + if( !(dvals=(double *)realloc(dvals, maxd*sizeof(double))) ) return 0; + } + } + v->rlo[0] = dvals[0] - dvals[6] - 1; + v->rhi[0] = dvals[0] + dvals[6] + 1; + v->rlo[1] = dvals[1] - dvals[6] - 1; + v->rhi[1] = dvals[1] + dvals[6] + 1; + if( dvals ) xfree(dvals); + return 1; + } + else if( !strcmp(v->s, "bpanda") || !strcmp(v->s, "epanda") ){ + maxd = 3; + if( !(dvals=(double *)malloc(maxd*sizeof(double))) ) return 0; + /* grab: xcen ycen */ + if( !word(s, tbuf, &ip)||!word(s, tbuf2, &ip) ) return 0; + xcen = atof(tbuf); + ycen = atof(tbuf2); + /* skip: ang1 ang2 nang xwlo yhlo */ + for(i=0; i<5; i++){ + if( !word(s, tbuf, &ip) ) return 0; + } + /* grab: xwhi yhhi */ + for(i=0; i<2; i++){ + if( !word(s, tbuf, &ip) ) return 0; + dvals[nd++] = atof(tbuf); + } + /* skip: nrad */ + if( !word(s, tbuf, &ip) ) return 0; + /* grab: ang */ + if( !word(s, tbuf, &ip) ) return 0; + dvals[nd++] = atof(tbuf); + /* we can now handle this with box/ellipse code */ + goto ellcom; + } + else if( !strcmp(v->s, "field") ){ + return 0; + } + else{ + return 0; + } +} + +#ifdef YY_USE_PROTOS +static int _valreg(char *s, idxvalrec **v) +#else +static int _valreg(s, v) + char *s; + idxvalrec **v; +#endif +{ + int ip=0; + char *t; + char tbuf[SZ_LINE]; + *v = idxvalnew(NULL); + newdtable("(),"); + while( *s == '(' ) s++; + if( !word(s, tbuf, &ip) ){ + (*v)->type = INDEF; + return REG; + } + if( strstr(tbuf, "field") ){ + (*v)->type = INDEF; + return REG; + } + t = tbuf+2; + if( *t == 'v' ) t++; + (*v)->s = xstrdup(t); + if( !word(s, tbuf, &ip) || !word(s, tbuf, &ip) || + !word(s, tbuf, &ip) || !word(s, tbuf, &ip) ){ + (*v)->type = INDEF; + return REG; + } + /* include/exclude */ + if( !atoi(tbuf) ){ + (*v)->type = INDEF; + return REG; + } + if( !word(s, tbuf, &ip) || !word(s, tbuf, &ip) || !word(s, tbuf, &ip) ){ + (*v)->type = INDEF; + return REG; + } + culc(tbuf); + _valname(tbuf, &(*v)->rv[0]); + if( !word(s, tbuf, &ip) || !word(s, tbuf, &ip) ){ + (*v)->type = INDEF; + return REG; + } + culc(tbuf); + _valname(tbuf, &(*v)->rv[1]); + if( !_valreglims(*v, &s[ip]) ){ + (*v)->type = INDEF; + return REG; + } + freedtable(); + (*v)->type = REG; + return REG; +} + +#ifdef YY_USE_PROTOS +static int _valfunc(char *s, idxvalrec **v) +#else +static int _valfunc(s, v) + char *s; + idxvalrec **v; +#endif +{ + *v = idxvalnew(s); + (*v)->type = FUNC; + return FUNC; +} + + +#ifdef YY_USE_PROTOS +void +idxstring(char *s) +#else +void idxstring(s) + char *s; +#endif +{ + idx_scan_string(s); +} + +#ifdef YY_USE_PROTOS +int +idxerror(char *msg) +#else +int idxerror(msg) + char *msg; +#endif +{ + Filter filter; + + YY_FLUSH_BUFFER; + /* turn indexing off */ + if( (filter=FilterDefault()) ){ + filter->doidx = -1; + } + /* output message, if necessary */ + if( idx_debug ){ + fprintf(stderr, "ERROR: %s", msg); + if( !strcmp(msg, "syntax error") ){ + fprintf(stderr, " (terminating index processing)"); + } + fprintf(stderr, "\n"); + } + yyterminate(); +} + +#ifdef YY_USE_PROTOS +int yywrap(void) +#else +int yywrap() +#endif +{ + return 1; +} + diff --git a/filter/regions.h b/filter/regions.h new file mode 100644 index 0000000..984323d --- /dev/null +++ b/filter/regions.h @@ -0,0 +1,408 @@ +#if MINIMIZE_INCLUDES +#include +int sscanf(const char *s, const char *format, ...); +typedef unsigned long size_t; +size_t strlen(); +char *strcpy(), *strdup(), *strstr(), *getenv(); +void *calloc(), *malloc(), *memset(), *memmove(); +void exit(); +#else +#include +#include +#include +#include +#include +#ifdef __STDC__ +#include +#include +#else +#include +#endif +#endif + +#if MINIMIZE_INCLUDES +/* lots of math functions from math.h */ +extern double acos(double); +extern double asin(double); +extern double atan(double); +extern double atan2(double, double); +extern double cos(double); +extern double sin(double); +extern double tan(double); +extern double acosh(double); +extern double asinh(double); +extern double atanh(double); +extern double cosh(double); +extern double sinh(double); +extern double tanh(double); +extern double exp (double); +extern double exp2 (double); +extern double expm1 (double); +extern double log (double); +extern double log10 (double); +extern double log2 (double); +extern double log1p (double); +extern double logb (double); +extern double modf (double, double *); +extern double ldexp (double, int); +extern double frexp (double, int *); +extern int ilogb (double); +extern double scalbn (double, int); +extern double scalbln (double, long int); +extern double fabs(double); +extern double cbrt(double); +extern double hypot (double, double); +extern double pow (double, double); +extern double sqrt(double); +extern double erf(double); +extern double erfc(double); +extern double lgamma(double); +extern double tgamma(double); +extern double ceil (double); +extern double floor (double); +extern double nearbyint (double); +extern double rint (double); +extern long int lrint (double); +extern double round (double); +extern long int lround (double); +extern double trunc (double); +extern double fmod (double, double); +extern double remainder (double, double); +extern double remquo (double, double, int *); +extern double copysign (double, double); +extern double nan(const char *); +extern double nextafter (double, double); +extern double fdim (double, double); +extern double fmax (double, double); +extern double fmin (double, double); +extern double fma (double, double, double); +/* and math constants */ +#define M_E 2.71828182845904523536028747135266250 /* e */ +#define M_LOG2E 1.44269504088896340735992468100189214 /* log 2e */ +#define M_LOG10E 0.434294481903251827651128918916605082 /* log 10e */ +#define M_LN2 0.693147180559945309417232121458176568 /* log e2 */ +#define M_LN10 2.30258509299404568401799145468436421 /* log e10 */ +#define M_PI 3.14159265358979323846264338327950288 /* pi */ +#define M_PI_2 1.57079632679489661923132169163975144 /* pi/2 */ +#define M_PI_4 0.785398163397448309615660845819875721 /* pi/4 */ +#define M_1_PI 0.318309886183790671537767526745028724 /* 1/pi */ +#define M_2_PI 0.636619772367581343075535053490057448 /* 2/pi */ +#define M_2_SQRTPI 1.12837916709551257389615890312154517 /* 2/sqrt(pi) */ +#define M_SQRT2 1.41421356237309504880168872420969808 /* sqrt(2) */ +#define M_SQRT1_2 0.707106781186547524400844362104849039 /* 1/sqrt(2) */ +#endif + +#define MASKINC 10000 +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif +#define SMALL_NUMBER 1.0E-24 +#define LARGE_NUMBER 65535 +#define PSTOP -142857.142857 + +#ifndef SZ_LINE +#define SZ_LINE 4096 +#endif +#ifndef min +#define min(x,y) (((x)<(y))?(x):(y)) +#endif +#ifndef max +#define max(x,y) (((x)>(y))?(x):(y)) +#endif +#ifndef abs +#define abs(x) ((x)<0?(-x):(x)) +#endif +#ifndef feq +#define feq(x,y) (fabs((double)x-(double)y)<=(double)1.0E-15) +#endif +#ifndef NULL +#define NULL (void *)0 +#endif + +#ifndef TOK_EREG +#define TOK_EREG 1 +#endif +#ifndef TOK_NREG +#define TOK_NREG 2 +#endif +#ifndef TOK_IREG +#define TOK_IREG 4 +#endif + +#define PIXCEN(a) (double)(a) +#define PIXNUM(a) (int)((a)+0.5) +#define PIXSTART(a) ((int)(a)+1) +#define PIXSTOP(a) (((int)(a))==(a)?((int)(a)-1):((int)(a))) +/* to assure that geometrically adjoining regions touch but don't overlap */ +/* when edge is exactly on a pixel center it goes to right or upper region. */ +/* used for non-radially symetric regions instead of PIXSTART, PIXSTOP */ +#define PIXINCL(a) (int)((a)+1.0) + +/* this is the filter string for field only */ +#define EVFIELDONLY "(evfield(g,1,1,1,(double)x,(double)y))" + +#define XSNO 3 + +/* NB: these MUST match the definition in filter.h */ +#ifndef __filter_h +typedef struct filtmaskrec { + int region; + int y; + int xstart, xstop; +} *FilterMask, FilterMaskRec; + +/* parameter structure for a scan entry */ +typedef struct scanrec{ + struct scanrec *next; + int x; +} *Scan, ScanRec; + +typedef struct shaperec { + int init; + double ystart, ystop; + Scan *scanlist; + /* varargs */ + int nv; + double *xv; + /* circle, annulus */ + double r1sq, r2sq; + /* ellipse */ + double angl, sinangl, cosangl; + double cossq, sinsq; + double xradsq, yradsq; + double a; + /* polygon-style shapes */ + int npt; + double *pts; + /* line */ + int xonly; + double x1, x2, y1; + double invslope; +} *Shape, ShapeRec; + +/* these are global for use with special region routines */ +typedef struct gfiltrec { + int nshapes; /* number of shapes */ + int maxshapes; /* number of shape records we allocate */ + Shape shapes; /* array holding range limits for one shape */ + int rid; /* first valid region for current pixel */ + int usebinsiz; /* whether bindizx,binsizy are used */ + char *evsect; /* value of event section */ + double tlminx, tlminy; /* tlmin for event section */ + double binsizx, binsizy; /* bin sizes for event section */ + double tloff; /* offset for quick p2i conversion */ + int xmin, xmax, ymin, ymax; /* section limits in original image coords */ + int block; /* block factor */ + int x0, x1, y0, y1; /* section limits in section coords */ + int *ybuf; /* valid y row flags */ + int *x0s; /* valid x start values */ + int *x1s; /* valid x stop values */ + int nmask; /* number of image mask record */ + int maskdim; /* size of mask image */ + FilterMask masks; /* mask records */ +} *GFilt, GFiltRec; +#endif + +/* declare image init routines */ +void imannulusi(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, double iradius, double oradius); +void imboxi(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, double xwidth, double yheight, + double angle); +void imcirclei(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, double radius); +void imellipsei(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, double xrad, double yrad, + double angle); +void imfieldi(GFilt g, int rno, int sno, int flag, int type, + double x, double y); +void imlinei(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double x0, double y0, double x1, double y1); +void impiei(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, double angle1, double angle2); +void imqtpiei(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, double angle1, double angle2); +void impointi(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen); +void impandai(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, + double anglo, double anghi, double angn, + double radlo, double radhi, double radn); +void imnannulusi(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, + double lo, double hi, int n); +void imnboxi(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, + double lox, double loy, double hix, double hiy, int n, + double angle); +void imnellipsei(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, + double lox, double loy, double hix, double hiy, int n, + double angle); +void imnpiei(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, + double lo, double hi, int n); + +#ifdef __STDC__ +void impolygoni(GFilt g, int rno, int sno, int flag, int type, + double x, double y, ...); +void imvannulusi(GFilt g, int rno, int sno, int flag, int type, + double x, double y, double xcen, double ycen, ...); +void imvboxi(GFilt g, int rno, int sno, int flag, int type, + double x, double y, double xcen, double ycen, ...); +void imvellipsei(GFilt g, int rno, int sno, int flag, int type, + double x, double y, double xcen, double ycen, ...); +void imvpiei(GFilt g, int rno, int sno, int flag, int type, + double x, double y, double xcen, double ycen, ...); +void imvpointi(GFilt g, int rno, int sno, int flag, int type, + double x, double y, ...); +#endif + + +/* declare image region routines */ +int imannulus(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, double iradius, double oradius); +int imbox(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, double xwidth, double yheight, + double angle); +int imcircle(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, double radius); +int imellipse(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, double xrad, double yrad, + double angle); +int imfield(GFilt g, int rno, int sno, int flag, int type, + double x, double y); +int imline(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double x1, double y1, double x2, double y2); +int impie(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, double angle1, double angle2); +int imqtpie(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, double angle1, double angle2); +int impoint(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen); +int impanda(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, + double anglo, double anghi, double angn, + double radlo, double radhi, double radn); +int imnannulus(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, + double lo, double hi, int n); +int imnbox(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, + double lox, double loy, double hix, double hiy, int n, + double angle); +int imnellipse(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, + double lox, double loy, double hix, double hiy, int n, + double angle); +int imnpie(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, + double lo, double hi, int n); +#ifdef __STDC__ +int impolygon(GFilt g, int rno, int sno, int flag, int type, + double x, double y, ...); +int imvannulus(GFilt g, int rno, int sno, int flag, int type, + double x, double y, double xcen, double ycen, ...); +int imvbox(GFilt g, int rno, int sno, int flag, int type, + double x, double y, double xcen, double ycen, ...); +int imvellipse(GFilt g, int rno, int sno, int flag, int type, + double x, double y, double xcen, double ycen, ...); +int imvpie(GFilt g, int rno, int sno, int flag, int type, + double x, double y, double xcen, double ycen, ...); +int imvpoint(GFilt g, int rno, int sno, int flag, int type, + double x, double y, ...); +#endif + +/* declare event region routines */ +int evannulus(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, double iradius, double oradius); +int evbox(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, double xwidth, double yheight, + double angle); +int evcircle(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, double radius); +int evellipse(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, double xrad, double yrad, + double angle); +int evfield(GFilt g, int rno, int sno, int flag, int type, + double x, double y); +int evline(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double x1, double y1, double x2, double y2); +int evpie(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, double angle1, double angle2); +int evqtpie(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, double angle1, double angle2); +int evpoint(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen); +int evnannulus(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, + double lo, double hi, int n); +int evnbox(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, + double lox, double loy, double hix, double hiy, int n, + double angle); +int evnellipse(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, + double lox, double loy, double hix, double hiy, int n, + double angle); +int evnpie(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, + double lo, double hi, int n); +int evpanda(GFilt g, int rno, int sno, int flag, int type, + double x, double y, + double xcen, double ycen, + double anglo, double anghi, double angn, + double radlo, double radhi, double radn); +#ifdef __STDC__ +int evpolygon(GFilt g, int rno, int sno, int flag, int type, + double x, double y, ...); +int evvannulus(GFilt g, int rno, int sno, int flag, int type, + double x, double y, double xcen, double ycen, ...); +int evvbox(GFilt g, int rno, int sno, int flag, int type, + double x, double y, double xcen, double ycen, ...); +int evvellipse(GFilt g, int rno, int sno, int flag, int type, + double x, double y, double xcen, double ycen, ...); +int evvpie(GFilt g, int rno, int sno, int flag, int type, + double x, double y, double xcen, double ycen, ...); +int evvpoint(GFilt g, int rno, int sno, int flag, int type, + double x, double y, ...); +#endif + diff --git a/filter/regions_h.h b/filter/regions_h.h new file mode 100644 index 0000000..bfb0d57 --- /dev/null +++ b/filter/regions_h.h @@ -0,0 +1 @@ +static char *REGIONS_H="\n#if MINIMIZE_INCLUDES\n#include \nint sscanf(const char *s, const char *format, ...);\ntypedef unsigned long size_t;\nsize_t strlen();\nchar *strcpy(), *strdup(), *strstr(), *getenv();\nvoid *calloc(), *malloc(), *memset(), *memmove();\nvoid exit();\n#else\n#include \n#include \n#include \n#include \n#include \n#ifdef __STDC__\n#include \n#include \n#else\n#include \n#endif\n#endif\n\n#if MINIMIZE_INCLUDES\n\nextern double acos(double);\nextern double asin(double);\nextern double atan(double);\nextern double atan2(double, double);\nextern double cos(double);\nextern double sin(double);\nextern double tan(double);\nextern double acosh(double);\nextern double asinh(double);\nextern double atanh(double);\nextern double cosh(double);\nextern double sinh(double);\nextern double tanh(double);\nextern double exp (double);\nextern double exp2 (double); \nextern double expm1 (double); \nextern double log (double);\nextern double log10 (double);\nextern double log2 (double);\nextern double log1p (double);\nextern double logb (double);\nextern double modf (double, double *);\nextern double ldexp (double, int);\nextern double frexp (double, int *);\nextern int ilogb (double);\nextern double scalbn (double, int);\nextern double scalbln (double, long int);\nextern double fabs(double);\nextern double cbrt(double);\nextern double hypot (double, double);\nextern double pow (double, double);\nextern double sqrt(double);\nextern double erf(double);\nextern double erfc(double);\nextern double lgamma(double);\nextern double tgamma(double);\nextern double ceil (double);\nextern double floor (double);\nextern double nearbyint (double);\nextern double rint (double);\nextern long int lrint (double);\nextern double round (double);\nextern long int lround (double);\nextern double trunc (double);\nextern double fmod (double, double);\nextern double remainder (double, double);\nextern double remquo (double, double, int *);\nextern double copysign (double, double);\nextern double nan(const char *);\nextern double nextafter (double, double);\nextern double fdim (double, double);\nextern double fmax (double, double);\nextern double fmin (double, double);\nextern double fma (double, double, double);\n\n#define M_E 2.71828182845904523536028747135266250 \n#define M_LOG2E 1.44269504088896340735992468100189214 \n#define M_LOG10E 0.434294481903251827651128918916605082 \n#define M_LN2 0.693147180559945309417232121458176568 \n#define M_LN10 2.30258509299404568401799145468436421 \n#define M_PI 3.14159265358979323846264338327950288 \n#define M_PI_2 1.57079632679489661923132169163975144 \n#define M_PI_4 0.785398163397448309615660845819875721 \n#define M_1_PI 0.318309886183790671537767526745028724 \n#define M_2_PI 0.636619772367581343075535053490057448 \n#define M_2_SQRTPI 1.12837916709551257389615890312154517 \n#define M_SQRT2 1.41421356237309504880168872420969808 \n#define M_SQRT1_2 0.707106781186547524400844362104849039 \n#endif\n\n#define MASKINC 10000\n#ifndef M_PI\n#define M_PI 3.14159265358979323846\n#endif\n#define SMALL_NUMBER 1.0E-24\n#define LARGE_NUMBER 65535\n#define PSTOP -142857.142857\n\n#ifndef SZ_LINE\n#define SZ_LINE 4096\n#endif\n#ifndef min\n#define min(x,y) (((x)<(y))?(x):(y))\n#endif\n#ifndef max\n#define max(x,y) (((x)>(y))?(x):(y))\n#endif\n#ifndef abs\n#define abs(x) ((x)<0?(-x):(x))\n#endif\n#ifndef feq\n#define feq(x,y) (fabs((double)x-(double)y)<=(double)1.0E-15)\n#endif\n#ifndef NULL\n#define NULL (void *)0\n#endif\n\n#ifndef TOK_EREG\n#define TOK_EREG 1\n#endif\n#ifndef TOK_NREG\n#define TOK_NREG 2\n#endif\n#ifndef TOK_IREG\n#define TOK_IREG 4\n#endif\n\n#define PIXCEN(a) (double)(a)\n#define PIXNUM(a) (int)((a)+0.5) \n#define PIXSTART(a) ((int)(a)+1)\n#define PIXSTOP(a) (((int)(a))==(a)?((int)(a)-1):((int)(a)))\n\n\n\n#define PIXINCL(a) (int)((a)+1.0) \n\n\n#define EVFIELDONLY \"(evfield(g,1,1,1,(double)x,(double)y))\"\n\n#define XSNO 3\n\n\n#ifndef __filter_h\ntypedef struct filtmaskrec {\n int region;\n int y;\n int xstart, xstop;\n} *FilterMask, FilterMaskRec;\n\n\ntypedef struct scanrec{\n struct scanrec *next;\n int x;\n} *Scan, ScanRec;\n\ntypedef struct shaperec {\n int init;\n double ystart, ystop;\n Scan *scanlist;\n \n int nv;\n double *xv;\n \n double r1sq, r2sq;\n \n double angl, sinangl, cosangl;\n double cossq, sinsq;\n double xradsq, yradsq;\n double a;\n \n int npt;\n double *pts;\n \n int xonly;\n double x1, x2, y1;\n double invslope;\n} *Shape, ShapeRec;\n\n\ntypedef struct gfiltrec {\n int nshapes; \n int maxshapes; \n Shape shapes; \n int rid; \n int usebinsiz; \n char *evsect; \n double tlminx, tlminy; \n double binsizx, binsizy; \n double tloff; \n int xmin, xmax, ymin, ymax; \n int block; \n int x0, x1, y0, y1; \n int *ybuf; \n int *x0s; \n int *x1s; \n int nmask; \n int maskdim; \n FilterMask masks; \n} *GFilt, GFiltRec;\n#endif\n\n\nvoid imannulusi(GFilt g, int rno, int sno, int flag, int type, \n double x, double y,\n double xcen, double ycen, double iradius, double oradius);\nvoid imboxi(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double xcen, double ycen, double xwidth, double yheight,\n double angle);\nvoid imcirclei(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double xcen, double ycen, double radius);\nvoid imellipsei(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double xcen, double ycen, double xrad, double yrad,\n double angle);\nvoid imfieldi(GFilt g, int rno, int sno, int flag, int type,\n double x, double y);\nvoid imlinei(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double x0, double y0, double x1, double y1);\nvoid impiei(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double xcen, double ycen, double angle1, double angle2);\nvoid imqtpiei(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double xcen, double ycen, double angle1, double angle2);\nvoid impointi(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double xcen, double ycen);\nvoid impandai(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double xcen, double ycen,\n double anglo, double anghi, double angn,\n double radlo, double radhi, double radn);\nvoid imnannulusi(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double xcen, double ycen,\n double lo, double hi, int n);\nvoid imnboxi(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double xcen, double ycen,\n double lox, double loy, double hix, double hiy, int n,\n double angle);\nvoid imnellipsei(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double xcen, double ycen,\n double lox, double loy, double hix, double hiy, int n,\n double angle);\nvoid imnpiei(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double xcen, double ycen,\n double lo, double hi, int n);\n\n#ifdef __STDC__\nvoid impolygoni(GFilt g, int rno, int sno, int flag, int type,\n double x, double y, ...);\nvoid imvannulusi(GFilt g, int rno, int sno, int flag, int type,\n double x, double y, double xcen, double ycen, ...);\nvoid imvboxi(GFilt g, int rno, int sno, int flag, int type,\n double x, double y, double xcen, double ycen, ...);\nvoid imvellipsei(GFilt g, int rno, int sno, int flag, int type,\n double x, double y, double xcen, double ycen, ...);\nvoid imvpiei(GFilt g, int rno, int sno, int flag, int type,\n double x, double y, double xcen, double ycen, ...);\nvoid imvpointi(GFilt g, int rno, int sno, int flag, int type, \n double x, double y, ...);\n#endif\n\n\n\nint imannulus(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double xcen, double ycen, double iradius, double oradius);\nint imbox(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double xcen, double ycen, double xwidth, double yheight,\n double angle);\nint imcircle(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double xcen, double ycen, double radius);\nint imellipse(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double xcen, double ycen, double xrad, double yrad,\n double angle);\nint imfield(GFilt g, int rno, int sno, int flag, int type,\n double x, double y);\nint imline(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double x1, double y1, double x2, double y2);\nint impie(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double xcen, double ycen, double angle1, double angle2);\nint imqtpie(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double xcen, double ycen, double angle1, double angle2);\nint impoint(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double xcen, double ycen);\nint impanda(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double xcen, double ycen,\n double anglo, double anghi, double angn,\n double radlo, double radhi, double radn);\nint imnannulus(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double xcen, double ycen,\n double lo, double hi, int n);\nint imnbox(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double xcen, double ycen,\n double lox, double loy, double hix, double hiy, int n,\n double angle);\nint imnellipse(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double xcen, double ycen,\n double lox, double loy, double hix, double hiy, int n,\n double angle);\nint imnpie(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double xcen, double ycen,\n double lo, double hi, int n);\n#ifdef __STDC__\nint impolygon(GFilt g, int rno, int sno, int flag, int type,\n double x, double y, ...);\nint imvannulus(GFilt g, int rno, int sno, int flag, int type,\n double x, double y, double xcen, double ycen, ...);\nint imvbox(GFilt g, int rno, int sno, int flag, int type,\n double x, double y, double xcen, double ycen, ...);\nint imvellipse(GFilt g, int rno, int sno, int flag, int type,\n double x, double y, double xcen, double ycen, ...);\nint imvpie(GFilt g, int rno, int sno, int flag, int type,\n double x, double y, double xcen, double ycen, ...);\nint imvpoint(GFilt g, int rno, int sno, int flag, int type,\n double x, double y, ...);\n#endif\n\n\nint evannulus(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double xcen, double ycen, double iradius, double oradius);\nint evbox(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double xcen, double ycen, double xwidth, double yheight,\n double angle);\nint evcircle(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double xcen, double ycen, double radius);\nint evellipse(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double xcen, double ycen, double xrad, double yrad,\n double angle);\nint evfield(GFilt g, int rno, int sno, int flag, int type,\n double x, double y);\nint evline(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double x1, double y1, double x2, double y2);\nint evpie(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double xcen, double ycen, double angle1, double angle2);\nint evqtpie(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double xcen, double ycen, double angle1, double angle2);\nint evpoint(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double xcen, double ycen);\nint evnannulus(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double xcen, double ycen,\n double lo, double hi, int n);\nint evnbox(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double xcen, double ycen,\n double lox, double loy, double hix, double hiy, int n,\n double angle);\nint evnellipse(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double xcen, double ycen,\n double lox, double loy, double hix, double hiy, int n,\n double angle);\nint evnpie(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double xcen, double ycen,\n double lo, double hi, int n);\nint evpanda(GFilt g, int rno, int sno, int flag, int type,\n double x, double y,\n double xcen, double ycen,\n double anglo, double anghi, double angn,\n double radlo, double radhi, double radn);\n#ifdef __STDC__\nint evpolygon(GFilt g, int rno, int sno, int flag, int type,\n double x, double y, ...);\nint evvannulus(GFilt g, int rno, int sno, int flag, int type,\n double x, double y, double xcen, double ycen, ...);\nint evvbox(GFilt g, int rno, int sno, int flag, int type,\n double x, double y, double xcen, double ycen, ...);\nint evvellipse(GFilt g, int rno, int sno, int flag, int type,\n double x, double y, double xcen, double ycen, ...);\nint evvpie(GFilt g, int rno, int sno, int flag, int type,\n double x, double y, double xcen, double ycen, ...);\nint evvpoint(GFilt g, int rno, int sno, int flag, int type,\n double x, double y, ...);\n#endif\n\n"; diff --git a/filter/sample.c b/filter/sample.c new file mode 100644 index 0000000..4cacfca --- /dev/null +++ b/filter/sample.c @@ -0,0 +1,83 @@ + +#define min(x,y) (((x)<(y))?(x):(y)) +#define max(x,y) (((x)>(y))?(x):(y)) + + +#define CONVERT 0 +#define FILTER (pha==1&&pi>3) +#define ESIZE 20 +#define GET_pha LoadColumn(eptr+4,2,1,CONVERT,&pha) +#define GET_pi LoadColumn(eptr+6,2,1,CONVERT,&pi) +#define GET GET_pha;GET_pi; +short pha; +short pi; + +#define RADIAN 57.295779513082320877 +#define RADTODEG(r) ((r)*RADIAN) +#define DEGTORAD(d) ((d)/RADIAN) +#define INSIDE(a,r1,r2) (((a)>(r1))&&((a)<=((r2)<(r1)?(r2+360.0):(r2)))) + +static double d; + +#define Annulus(X,Y,x,y,ri,ro) ((((X-x)*(X-x))+((Y-y)*(Y-y))<=(ro*ro))&& (((X-x)*(X-x))+((Y-y)*(Y-y))>(ri*ri))) +#define annulus(x,y,ri,ro) Annulus(_X_,_Y_,x,y,ri,ro) + +#define Circle(X,Y,x,y,r) (((X-x)*(X-x))+((Y-y)*(Y-y))<=(r*r)) +#define circle(x,y,r) Circle(_X_,_Y_,x,y,r) + +#define Ellipse(X,Y,x,y,a,b) (((X-x)*(X-x))/(double)(a*a))+(((Y-y)*(Y-y))/(double)(b*b))<=1.0) +#define ellipse(x,y,a,b) Ellipse(_X_,_Y_,x,y,a,b) + +#define Pie(X,Y,x,y,r1,r2) ((X==x)&&(Y==y)?1:(INSIDE(((d=RADTODEG(atan2(Y-y,X-x)))<90?d+270.0:d-90.0),r1,r2))) +#define pie(x,y,r1,r2) Pie(_X_,_Y_,x,y,r1,r2) + +#define Point(X,Y,x,y) ((X==x)&&(Y==y)) +#define point(x,y) Point(_X_,_Y_,x,y) + +#define Box(X,Y,x,y,w,h) ((X>(x-(double)(w/2)))&&(X<=(x+(double)(w/2)))&&(Y>(y-(double)(h/2)))&&(Y<=(y+(double)(h/2)))) +#define box(x,y,w,h) Box(_X_,_Y_,x,y,w,h) + +LoadColumn(eptr, bytes, iter, convert, obuf) + char *eptr; + int bytes, iter, convert; + char *obuf; +{ + char *optr=obuf; + int i, j; + for(i=0; i0 ){ + ebuf = (char *)malloc(get); + for(etop=ebuf; get>0; etop += got, get -= got){ + if( (got=read(0, etop, get)) <=0 ) + break; + } + for(rptr=ebuf, eptr=ebuf; eptr + +#define SYMINC 100 /* increment for allocating symbols */ + +static char *bincols=NULL; +static char xbin[SZ_LINE]; +static char ybin[SZ_LINE]; + +extern char *filtinchar; + +/* + * + * Public Routines + * + */ + +/* + * + * FilterSymbolInit -- init the symbol table + * + */ +#ifdef ANSI_FUNC +int +FilterSymbolInit(Filter filter) +#else +int FilterSymbolInit(filter) + Filter filter; +#endif +{ + /* make sure we are init'ed */ + if( filter == NULL ){ + gerror(stderr, "symbol table not initialized\n"); + return(0); + } + filter->symtab = (FilterSymbols)xcalloc(SYMINC, sizeof(FilterSymRec)); + filter->nsyms = 0; + filter->maxsyms = SYMINC; + return(SYMINC); +} + +/* + * + * FilterSymbolEnter -- enter a new symbol in the symbol table + * The symbol will either be a column name, or + * a parameter in the table header, or + * a parameter in the primary header + * + */ +#ifdef ANSI_FUNC +char * +FilterSymbolEnter(Filter filter, char *s, int *got) +#else +char *FilterSymbolEnter(filter, s, got) + Filter filter; + char *s; + int *got; +#endif +{ + int brack=0; + int i, j; + char *t; + FilterSymbols sp; + char name[SZ_LINE]; + FITSCard card; + FITSHead fhd; + + /* see return value */ + if( got ) *got =-3; + + /* make sure we are init'ed */ + if( filter == NULL ){ + gerror(stderr, "symbol table not initialized\n"); + return(NULL); + } + + /* make sure we are init'ed */ + if( filter->fhd == NULL ){ + gerror(stderr, "symbol table not initialized\n"); + return(NULL); + } + fhd = filter->fhd; + + /* make sure we have something */ + if( !s || !*s ) + return(NULL); + + /* this is the name of the variable in the filter program */ + nowhite(s, name); + /* but strip off brackets */ + if( (t=strchr(name, '[')) != NULL ){ + brack=1; + *t = '\0'; + } + + /* loop through the symbol table and look for existing symbol */ + for(i=0; insyms; i++){ + sp = &(filter->symtab[i]); + /* skip accidentally empty ones */ + if( (sp->name == NULL) || (*sp->name == '\0') ) + continue; + /* is this name already entered? */ + if( !strcasecmp(sp->name, name) ){ + if( got ) *got = 1; + return (char *)sp->name; + } + } + + /* make sure there is room for a new symbol */ + if( i >= filter->maxsyms ){ + filter->maxsyms += SYMINC; + filter->symtab = (FilterSymbols)xrealloc(filter->symtab, + filter->maxsyms*sizeof(FilterSymRec)); + } + + /* this is where the next symbol will be entered */ + sp = &(filter->symtab[i]); + + /* look for name in the list of columns */ + if( fhd->table ){ + for(j=0; jtable->tfields; j++){ + if( !strcasecmp(name, fhd->table->col[j].name) ){ + if( brack && (fhd->table->col[j].n==1) ){ + if( got ) *got = -2; + return(NULL); + } + sp->type = SYM_COL; + sp->name = (char *)xstrdup(name); + sp->idx = j; + filter->size += fhd->table->col[j].size; + filter->nsyms++; + if( got ) *got = 1; + return (char *)sp->name; + } + } + } + /* look for name in the table header */ + if( (t=ft_headgets(fhd, name, 0, NULL, &card)) ){ + sp->type = SYM_PAR; + sp->name = xstrdup(name); + sp->value = t; + sp->idx = -1; + filter->nsyms++; + if( got ) *got = 2; + return (char *)sp->name; + } + /* look for name in the primary header */ + else if( fhd->primary && + (t=ft_headgets(fhd->primary, name, 0, NULL, &card)) ){ + sp->type = SYM_PAR; + sp->name = xstrdup(name); + sp->value = t; + sp->idx = -1; + filter->nsyms++; + if( got ) *got = 2; + return (char *)sp->name; + } + /* did not find the symbol anywhere */ + else{ + gerror(stderr, "can't find '%s' in table\n", s); + if( got ) *got = -1; + return(NULL); + } +} /* EnterSymbol */ + + +/* + * + * FilterSymbolLookup -- lookup a symbol in the symbol table + * + */ +#ifdef ANSI_FUNC +FilterSymbols +FilterSymbolLookup(Filter filter, char *name) +#else +FilterSymbols FilterSymbolLookup(filter, name) + Filter filter; + char *s; +#endif +{ + int i; + + /* sanity check */ + if( !name || !*name ) return NULL; + + /* loop through the symbol table and look for existing symbol */ + for(i=0; insyms; i++){ + /* skip accidentally empty ones */ + if( (filter->symtab[i].name == NULL) || (*filter->symtab[i].name == '\0') ) + continue; + /* look for name */ + if( !strcasecmp(filter->symtab[i].name, name) ){ + /* return symbol table record if found */ + return &filter->symtab[i]; + } + } + return NULL; +} + +/* + * + * FilterSymbolDefaults -- enter default symbols for X and Y columns + * + */ +#ifdef ANSI_FUNC +int +FilterSymbolDefaults(Filter filter, int enter) +#else +int FilterSymbolDefaults(filter, enter) + Filter filter; + int enter; +#endif +{ + int ip=0; + char tbuf[SZ_LINE]; + char *mbuf; + char *k; + char *s; + + /* this is only for events */ + if( !filter || !filter->fhd || !filter->fhd->table ) + return 0; + + /* parse bincols variable */ + if( !bincols ){ + mbuf = xstrdup(filter->mode); + if( !keyword(mbuf, "bincols", tbuf, SZ_LINE) ) + return 0; + if( mbuf ) xfree(mbuf); + s = tbuf; + /* parse the bincols string and add the symbols */ + newdtable(",:)"); + bincols = xstrdup(s); + k = bincols; + /* point past first paren */ + if( *bincols == '(' ) + k++; + if( !word(k, xbin, &ip) || !word(k, ybin, &ip) ){ + freedtable(); + return 0; + } + freedtable(); + /* set the filter bin strings */ + if( filter->xbin ) xfree(filter->xbin); + filter->xbin = xstrdup(xbin); + if( filter->ybin ) xfree(filter->ybin); + filter->ybin = xstrdup(ybin); + } + else if( !filter->xbin || !filter->ybin ){ + /* set the filter bin strings */ + if( filter->xbin ) xfree(filter->xbin); + filter->xbin = xstrdup(xbin); + if( filter->ybin ) xfree(filter->ybin); + filter->ybin = xstrdup(ybin); + } + + /* enter symbols if necessary */ + if( enter ){ + if( !FilterSymbolEnter(filter, xbin, NULL) || + !FilterSymbolEnter(filter, ybin, NULL) ) + return 0; + } + return 1; +} + +/* + * + * FilterSymbolFree -- free space from symbol table + * + */ +#ifdef ANSI_FUNC +void +FilterSymbolFree(Filter filter) +#else +void FilterSymbolFree(filter) + Filter filter; +#endif +{ + int i; + FilterSymbols sp; + + /* if we have no symbols, just return */ + if( !filter || !filter->nsyms ) + return; + + /* loop through the symbol table and free up records */ + for(i=0; insyms; i++){ + sp = &(filter->symtab[i]); + /* skip accidentally empty ones */ + if( (sp->name == NULL) || (*sp->name == '\0') ) + continue; + /* process this type of symbol */ + switch(sp->type){ + case SYM_COL: + xfree(sp->name); + sp->name = NULL; + break; + case SYM_PAR: + xfree(sp->name); + xfree(sp->value); + sp->name = NULL; + break; + } + } + /* no symbols */ + filter->nsyms = 0; + if( bincols != NULL ){ + xfree(bincols); + bincols = NULL; + *xbin = '\0'; + *ybin = '\0'; + } +} + diff --git a/filter/tfilt.c b/filter/tfilt.c new file mode 100644 index 0000000..0eba0b1 --- /dev/null +++ b/filter/tfilt.c @@ -0,0 +1,527 @@ +/* + * Copyright (c) 1999-2003 Smithsonian Astrophysical Observatory + */ + +/* + * + * tfilt.c -- test program for filtering tables + * + */ + +#if HAVE_CONFIG_H +#include +#endif + +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_MALLOC_H +#include +#endif +#ifdef HAVE_STDLIB_H +#include +#endif +#ifdef HAVE_STRING_H +#include +#endif +#include +#include +#include +#include +#include + +extern char *optarg; +extern int optind; + +char bincols[SZ_LINE]; +int debug=0; + +#define NEVENTS 10240 + +/* from Harbison&Steele by way of GNU cinfigure ... + returns 1 for bigendian, 0 for littleendian */ +#ifdef ANSI_FUNC +int +is_bigendian(void) +#else +int is_bigendian() +#endif +{ + union + { + long l; + char c[sizeof (long)]; + } u; + u.l = 1; + return(u.c[sizeof (long) - 1] == 1); +} + +/* + * + * ListEvents -- list events in a binary table + * + */ +#ifdef ANSI_FUNC +static int +ListEvents(GIO gio, FILE *ofd, FITSHead header, char *s, int iformat, + char *mode) +#else +static int ListEvents(gio, ofd, header, s, iformat, mode) + GIO gio; /* input FITS file handle */ + FILE *ofd; /* output file handle */ + FITSHead header; /* fitsy header */ + char *s; /* filter for events */ + int iformat; /* input format of data: 0=native, 1=fits */ + char *mode /* filteropen mode */ +#endif +{ + int i, j; /* loop counters */ + int get; /* number of events to read */ + int got; /* number of events read */ + int left; /* number of events left to read */ + int total; /* total number of events in file */ + int convert; /* whether we have to convert to native */ + int nev; /* max number of events to read at once */ + int evsize; /* size of an event record */ + int ototal; /* output total events */ + int *vbuf; /* valid event flags */ + char *ebuf; /* event buffer */ + char *eptr; /* current pointer into ebuf */ + char tbuf[SZ_LINE]; /* ever-present temp buf */ + unsigned char bval; /* byte value */ + short sval; /* short value */ + unsigned short usval; /* short value */ + int ival; /* int value */ + long long lval; /* 64-bit int value */ + unsigned int uival; /* unsigned int value */ + float fval; /* float value */ + double dval; /* double value */ + int dofilt=0; /* true if we can filter */ + Filter filter=NULL; + + /* we have to convert to native if the data is not the + same as the big-endian-ness of the machine */ + convert = (iformat != is_bigendian()); + /* create the mode string */ + if( convert ) + strcpy(tbuf, "convert=true"); + else + strcpy(tbuf, "convert=false"); + strcat(tbuf, bincols); + if( debug ) + strcat(tbuf, ",debug=2"); + + /* now add the input mode */ + if( mode && *mode ){ + strcat(tbuf, ","); + strcat(tbuf, mode); + } + + /* init some convenience variables */ + evsize = header->basic->naxis[0]; + total = header->basic->naxis[1]; + ototal = 0; + + /* open the filter */ + if( (filter = FilterOpen(header, s, tbuf)) == NULL ){ + fprintf(stderr, "ERROR: tfilt could not open filter: %s\n", + s ? s : "no filter"); + return(0); + } + else if( filter == NOFILTER ){ + fprintf(stderr, "no valid filter specified\n"); + return(0); + } + + /* allocate space for a pile of event records */ + for(nev=NEVENTS; nev>0; nev /=2){ + if( ((ebuf = (char *)xmalloc(evsize*nev))!= NULL) && + ((vbuf = (int *)xmalloc(sizeof(int)*nev))!= NULL) ) + break; + } + + /* print out header */ + for(j=0; jtable->tfields; j++){ + switch(header->table->col[j].type){ + case 'B': + case 'L': + fprintf(ofd, "%6s", header->table->col[j].name); + break; + case 'I': + case 'U': + fprintf(ofd, "%6s", header->table->col[j].name); + break; + case 'J': + case 'V': + fprintf(ofd, "%11s", header->table->col[j].name); + break; + case 'K': + fprintf(ofd, "%20s", header->table->col[j].name); + break; + case 'E': + fprintf(ofd, "%11s", header->table->col[j].name); + break; + case 'D': + fprintf(ofd, "%17s", header->table->col[j].name); + break; + default: + break; + } + } + fprintf(ofd, "\n"); + + for(j=0; jtable->tfields; j++){ + switch(header->table->col[j].type){ + case 'B': + case 'L': + fprintf(ofd, " -----"); + break; + case 'I': + case 'U': + fprintf(ofd, " -----"); + break; + case 'J': + case 'V': + fprintf(ofd, " ----------"); + break; + case 'K': + fprintf(ofd, " -------------------"); + break; + case 'E': + fprintf(ofd, " ----------"); + break; + case 'D': + fprintf(ofd, " ----------------"); + break; + default: + break; + } + } + fprintf(ofd, "\n"); + + /* set the total number of events or 'read til eof' */ + left = total; + + /* read all event records */ + while( left != 0 ){ + /* figure out how many to read this time */ + get = MIN(nev, left); + /* read in a pile of events */ + got=gread(gio, ebuf, evsize, get); + /* check for eof */ + if( got != get ){ + fprintf(stderr, "Warning: events ends at %d (expected %d)\n", + total-left, total); + /* we must be done */ + left = 0; + } + else{ + left -= got; + } + /* filter the events through the co-process */ + if( filter ){ + dofilt = FilterEvents(filter, ebuf, evsize, got, vbuf); + } + /* process each event in the pile */ + for(eptr=ebuf, i=0; itable->tfields; j++){ + switch(header->table->col[j].type){ + case 'B': + case 'L': + ColumnLoad(eptr+header->table->col[j].offset, + header->table->col[j].size, 1, convert, (char *)&bval); + fprintf(ofd, "%6d", (int)bval); + break; + case 'I': + ColumnLoad(eptr+header->table->col[j].offset, + header->table->col[j].size, 1, convert, (char *)&sval); + fprintf(ofd, "%6d", (int)sval); + break; + case 'U': + ColumnLoad(eptr+header->table->col[j].offset, + header->table->col[j].size, 1, convert, (char *)&usval); + fprintf(ofd, "%6d", (int)usval); + break; + case 'J': + ColumnLoad(eptr+header->table->col[j].offset, + header->table->col[j].size, 1, convert, (char *)&ival); + fprintf(ofd, "%11d", ival); + break; + case 'V': + ColumnLoad(eptr+header->table->col[j].offset, + header->table->col[j].size, 1, convert, (char *)&uival); + fprintf(ofd, "%11d", uival); + break; + case 'K': + ColumnLoad(eptr+header->table->col[j].offset, + header->table->col[j].size, 1, convert, (char *)&lval); + fprintf(ofd, "%20lld", lval); + break; + case 'E': + ColumnLoad(eptr+header->table->col[j].offset, + header->table->col[j].size, 1, convert, (char *)&fval); + fprintf(ofd, "%11.2f", fval); + break; + case 'D': + ColumnLoad(eptr+header->table->col[j].offset, + header->table->col[j].size, 1, convert, (char *)&dval); + fprintf(ofd, "%17.4f", dval); + break; + default: + break; + } + } + fprintf(ofd, "\n"); + } + } + + /* free up allocated space */ + if( ebuf ) + xfree(ebuf); + if( vbuf ) + xfree(vbuf); + + /* done with the filter process */ + if( filter ) + FilterClose(filter); + + /* final tally */ + fprintf(ofd, "\nTotal events: %d\n", ototal); + + /* that's good news */ + return(ototal); +} + +#ifdef ANSI_FUNC +int +main (int argc, char **argv) +#else +main(argc, argv) + int argc; + char **argv; +#endif +{ + int c; + int type; + int x, y, n; + int nmask; + int x0, x1, y0, y1, block; + int listev = 0; + int dispim = 0; + int dispfilt = 1; + int doidx = 0; + char *s; + char *iname; /* input file name ptr */ + char fname[SZ_LINE]; /* input file name */ + char tail[SZ_LINE]; /* tail of file name */ + char tbuf[SZ_LINE]; /* ever-present temp buffer */ + char mode[SZ_LINE]; /* mode for FilterOpen */ + char evsect[SZ_LINE]; /* event section for image filters */ + long save_pos; /* save position in FITS file */ + GIO gio; /* input FITS file handle */ + FITSHead header; /* global fitsy header struct */ + Filter filter; + FilterMask masks; + + /* we want the args in the same order in which they arrived, and + gnu getopt sometimes changes things without this */ + putenv("POSIXLY_CORRECT=true"); + + /* assume events */ + type = 'e'; + + /* process switch arguments */ + while ((c = getopt(argc, argv, "d:efilxz")) != -1){ + switch(c){ + case 'd': + dispim = 1; + strcpy(evsect, optarg); + if(sscanf(optarg, "%d %d %d %d %d", &x0, &x1, &y0, &y1, &block)!=5){ + fprintf(stderr, "-d requires x0, x1, y0, y1, block\n"); + exit(1); + } + break; + case 'e': + type = 'e'; + break; + case 'f': + dispfilt = 1; + break; + case 'i': + type = 'i'; + break; + case 'l': + listev = 1; + break; + case 'x': + doidx = 1; + break; + case 'z': + putenv("FILTER_PAINT=true"); + break; + } + } + + if( type == 'e' ){ + strcpy(mode, "type=events"); + if( dispim ){ + snprintf(tbuf, SZ_LINE, ",evsect=\"%s\"", evsect); + strcat(mode, tbuf); + } + } + else{ + strcpy(mode, "type=image"); + } + + + /* get file name or use a default */ + if( optind >= argc ){ + iname = "../funtest/test.ev[EVENTS]"; + } + else{ + strncpy(fname, argv[optind], SZ_LINE); + if( !strchr(fname, '[') ) + strncat(fname, "[EVENTS]", SZ_LINE); + iname = fname; + optind++; + } + + /* if we do not list or display, we are in debug mode */ + if( !listev && !dispim && !dispfilt ){ + debug = 2; + } + + /* open the binary table extension */ + if( (gio=ft_fitsheadopen(iname, &header, tail, SZ_LINE, "r")) == NULL ){ + fprintf(stderr, "ERROR: can't read FITS binary table: %s\n", iname); + exit(1); + } + if( header == NULL ){ + fprintf(stderr, "ERROR: can't access FITS data: %s\n", iname); + exit(1); + } + + if( keyword(tail, "bincols", tbuf, SZ_LINE) ){ + snprintf(bincols, SZ_LINE, ",bincols=(%s)", tbuf); + strcat(mode, bincols); + } + else{ + strcpy(bincols, ",bincols=(x,y)"); + strcat(mode, bincols); + } + if( debug ) + strcat(mode, ",debug=2"); + strcat(mode, ",lexonly=1"); + if( (s=getenv("FILTER_PAINT")) ){ + if( istrue(s) ) + strcat(mode, ",paint=true"); + else if( isfalse(s) ) + strcat(mode, ",paint=false"); + } + + while( 1 ){ + *tbuf = '\0'; + if( feof(stdin) ) + break; + fgets(tbuf, SZ_LINE, stdin); + if( *tbuf == 'q' ) + exit(0); + if( *tbuf ){ + if( listev ){ + /* list out events */ + save_pos = gtell(gio); + ListEvents(gio, stdout, header, tbuf, 1, mode); + gseek(gio, save_pos, SEEK_SET); + } + if( dispim ){ + /* display image */ + if( *tbuf && (*tbuf != '\n') ){ + fprintf(stdout, "input string: %s", tbuf); + filter = FilterOpen(header, tbuf, mode); + if( !filter ) + fprintf(stderr, "Error in FilterOpen()\n"); + else if( filter == NOFILTER ) + fprintf(stderr, "No valid filter specified\n"); + else{ + nmask = FilterImage(filter, x0, x1, y0, y1, block, &masks, NULL); + if( nmask ){ + /* loop through mask segments */ + y = 1; + for(n=0; n1&&max(pi,pha)<3 +min(pi,pha)*14>x +max(pi,pha)==(pi+1) +(pi+pha)>2+log(pi)-pha +(pi<3)&&(pi==pha) +pi=3:4,(pha>1) +pha=1,100