summaryrefslogtreecommitdiffstats
path: root/funtools/tabcalc_c.h
blob: 621562c0b7d71adb1f3018c7e5d940b48da26cfa (plain)
1
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 <stdio.h>\n#include <unistd.h>\n#include <stdlib.h>\n#include <math.h>\n#include <string.h>\n#include <funtools.h>\n#include <word.h>\n#include <NaN.h>\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";