static char *TABCALC_C="\n/*\n *\n * This program was generated automatically by the funcalc program,\n * by running the tabcalc.c template through the funcalc.l lexical analyzer.\n * On this system, it was (or can be) built a command such as:\n *\n * $COMMAND\n *\n */\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n\nextern char *optarg;\nextern int optind;\n\n/* define the types of event records we have to handle */\n#define REC_CUR 1\n#define REC_PREV 2\n#define REC_NEXT 4\n\n#define ARGC __nxarg\n#define ARGV(n) ((__xargs && (n>=0) && (n<__nxarg)) ? __xargs[n] : NULL)\n\n#define I __i\n#define NROW __nrow\n#define WRITE_ROW FunTableRowPut(ofun, (char *)cur, 1, __i, NULL)\n\n/* default number of rows to read at a time */\n#define MAXROW 8192\nint __maxrow=MAXROW;\n\n/* floating check for equality */\n#ifndef feq\n#define feq(x,y) (fabs((double)x-(double)y)<=(double)1.0E-15)\n/* avoid divide by zero */\n#ifndef div\n#define div(a,b) (feq(b,0)?(getnand()):(a/b))\n#endif\n#endif\n\ntypedef struct rowstruct{\n$MEMBERS\nint __ncol;\n} *Row, RowRec;\n\n/* global definitions and init calls go here */\n$GLOBAL\n\n/* main program */\nint main (int argc, char **argv)\n{\n int __c, __i;\n int __get, __got, __total, __rectype, __args;\n int __saved=0;\n int __del=0;\n int __nxarg=0;\n int __ip=0;\n int __nrow=-1;\n int __rawsize=0;\n char *__s;\n char *__cols=NULL;\n char *__argstr=NULL;\n char *__rawsave=NULL;\n char *__rawbuf=NULL;\n char **__xargs=NULL;\n char __tbuf[SZ_LINE];\n Row __rowbuf, __rowrptr, __rowsptr, __roweptr;\n Row cur, prev, next;\n Fun fun, ofun;\n off_t __opos;\n $AUTO\n \n /* local definitions, followed by init calls, go here */\n $LOCAL\n\n /* exit on gio errors */\n if( !getenv(\"GERROR\") )\n setgerror(2);\n\n /* avoid shared library problems by using \"process\" type for filtering */\n putenv(\"FILTER_PTYPE=process\");\n\n /* process switch arguments */\n while ((__c = getopt(argc, argv, \"a:d\")) != -1){\n switch(__c){\n case 'a':\n __argstr = xstrdup(optarg);\n break;\n case 'd':\n __del = 1;\n break;\n }\n }\n\n /* check for required arguments */\n __args = argc - optind;\n /* make sure we have minimal arguments */\n if( __args < $ARGS ){\n if( $ARGS == 1 )\n fprintf(stderr, \"usage: %s iname\\n\", argv[0]);\n else\n fprintf(stderr, \"usage: %s iname oname [cols]\\n\", argv[0]);\n goto error;\n }\n\n /* set passed arguments in __xargs array */\n if( __argstr && *__argstr ){\n __xargs = calloc(SZ_LINE, sizeof(char *));\n while( word(__argstr, __tbuf, &__ip) ){\n if( __nxarg >= SZ_LINE ){\n gerror(stderr, \"too many args passed via -a\\n\");\n goto error;\n }\n __xargs[__nxarg++] = xstrdup(__tbuf);\n }\n }\n\n /* set rectype: determine whether we need prev,next records */\n __rectype=$RECTYPE;\n\n /* get maxrow,if user-specified */\n if( (__s=(char *)getenv(\"FUN_MAXROW\")) != NULL )\n __maxrow = atoi(__s);\n /* make sure max row is large enough to handle prev, next */\n if( __rectype & (REC_PREV|REC_NEXT) )\n __maxrow = MAX(3,__maxrow);\n else\n __maxrow = MAX(1,__maxrow);\n /* this is what we read each time */\n __get = __maxrow;\n\n /* open input file */\n if( !(fun = FunOpen(argv[optind+0], \"rc\", NULL)) ){\n gerror(stderr, \"could not FunOpen input file: %s\\n\", argv[optind+0]);\n goto error;\n }\n\n /* open the output FITS image, inheriting params from input */\n if( $ARGS > 1 ){\n if( !(ofun = FunOpen(argv[optind+1], \"w\", fun)) ){\n gerror(stderr, \"could not FunOpen output file: %s\\n\", argv[optind+1]);\n goto error;\n }\n }\n\n /* select columns */\n FunColumnSelect(fun, sizeof(RowRec), \"merge=$MERGE\", \n $SELECT\n \"$N\", \"1J\", \"r\", FUN_OFFSET(Row, __ncol),\n NULL);\n\n /* activate specified columns -- these will be written to the output file */\n if( __args >= 3 ) __cols = argv[optind+2];\n FunColumnActivate(fun, __cols, NULL);\n\n /* allocate space for __rowbuf -- we will manage this buffer ourselves */\n /* NB: we need 2 extra rows for prev and next */\n __rowbuf = (Row)xcalloc(__maxrow+2, sizeof(RowRec));\n\n /* get size of raw data record and allocate a raw record */\n FunInfoGet(fun, FUN_RAWSIZE, &__rawsize, 0);\n __rawsave = (char *)xcalloc(1, __rawsize);\n\n /* no record read yet */\n __total = 0;\n\n /* any user-defined calls before we enter the row loop go here */\n $BEFORE\n\n /* main loop -- get rows and process */\n while( 1 ){\n if( !(__rectype & (REC_PREV|REC_NEXT)) ){\n /* offset of next record to process */\n __rowsptr = __rowbuf;\n __rowrptr = __rowbuf;\n }\n /* need prev record */\n else if( __rectype & REC_PREV ){\n /* no records yet: read new batch of records into start of __rowbuf */\n if( __total == 0 ){\n __rowsptr = __rowbuf+1;\n __rowrptr = __rowbuf;\n }\n /* read last processed record into start of __rowbuf, process others */\n else{\n if( __rectype & REC_NEXT ){\n memcpy(__rowbuf, __rowrptr+(__got-2), sizeof(RowRec)*2);\n __rowsptr = __rowbuf+1;\n __rowrptr = __rowbuf+2;\n /* save raw data for this unprocessed record */\n FunInfoGet(fun, FUN_RAWBUF, &__rawbuf, 0);\n memcpy(__rawsave, __rawbuf+((__got-1)*__rawsize), __rawsize);\n }\n else{\n memcpy(__rowbuf, __rowrptr+(__got-1), sizeof(RowRec));\n __rowsptr = __rowbuf+1;\n __rowrptr = __rowbuf+1;\n }\n }\n }\n /* if we did not process last record, seek to it now and start there */\n else if( __rectype & REC_NEXT ){\n /* no records yet: read new batch of records into start of __rowbuf */\n if( __total == 0 ){\n __rowsptr = __rowbuf;\n __rowrptr = __rowbuf;\n }\n /* read last processed record into first new record, process others */\n else{\n memcpy(__rowbuf, __rowrptr+(__got-1), sizeof(RowRec));\n __rowsptr = __rowbuf;\n __rowrptr = __rowbuf+1;\n /* save raw data for this unprocessed record */\n FunInfoGet(fun, FUN_RAWBUF, &__rawbuf, 0);\n memcpy(__rawsave, __rawbuf+((__got-1)*__rawsize), __rawsize);\n }\n }\n\n /* read new rows */\n if( !FunTableRowGet(fun, __rowrptr, __get, NULL, &__got) || !__got )\n break;\n\n /* last record to process */\n __roweptr = __rowrptr + __got;\n /* if we need access to next record, don't process the last one we read */\n if( __rectype & REC_NEXT ){\n __roweptr--;\n }\n\n /* make sure there are rows to process */\n if( (__roweptr-__rowsptr) <= 0 ) break;\n\n /* process all rows */\n for(cur=__rowsptr, __i=__rowsptr-__rowrptr; cur<__roweptr; cur++, __i++){\n /* save raw buffer and switch rawbuf from previous */\n if( __i == -1 ){\n FunInfoGet(fun, FUN_RAWBUF, &__rawbuf, 0);\n FunInfoPut(fun, FUN_RAWBUF, &__rawsave, 0);\n __i = 0;\n __saved = 1;\n }\n /* restore raw buffer */\n else if( __saved ){\n FunInfoPut(fun, FUN_RAWBUF, &__rawbuf, 0);\n __i = 0;\n __saved = 0;\n }\n /* finished another row */\n NROW++;\n /* set up pointer to prev and next as needed */\n if( __rectype & REC_PREV ) prev = cur - 1;\n if( __rectype & REC_NEXT ) next = cur + 1;\n /* execute the expression */\n $EXPR\n /* write out this row with the new column */\n if( $ARGS > 1 ) WRITE_ROW;\n }\n /* update total */\n __total += __got;\n }\n\n /* any user-defined calls after we finish the row loop go here */\n $AFTER\n\n /* free row data */\n if( __rowbuf ) xfree(__rowbuf);\n if( __rawsave ) xfree(__rawsave);\n\n /* free arg strings */\n if( __xargs ){\n for(__i=0; __i<__nxarg; __i++){\n if( __xargs[__i] ) xfree(__xargs[__i]);\n }\n xfree(__xargs);\n }\n\n /* clean up -- close output before input to perform flush automatically */\n if( $ARGS > 1 )\n FunClose(ofun);\n FunClose(fun);\n\n /* delete program if necessary */\n if( __del ) unlink(argv[0]);\n return(0);\n\nerror:\n /* delete program if necessary */\n if( __del ) unlink(argv[0]);\n return(1);\n}\n";