aboutsummaryrefslogtreecommitdiff
path: root/pkg/tbtables/cfitsio/eval.l
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/tbtables/cfitsio/eval.l')
-rw-r--r--pkg/tbtables/cfitsio/eval.l512
1 files changed, 512 insertions, 0 deletions
diff --git a/pkg/tbtables/cfitsio/eval.l b/pkg/tbtables/cfitsio/eval.l
new file mode 100644
index 00000000..4b9e0deb
--- /dev/null
+++ b/pkg/tbtables/cfitsio/eval.l
@@ -0,0 +1,512 @@
+%{
+/************************************************************************/
+/* */
+/* CFITSIO Lexical Parser */
+/* */
+/* This file is one of 3 files containing code which parses an */
+/* arithmetic expression and evaluates it in the context of an input */
+/* FITS file table extension. The CFITSIO lexical parser is divided */
+/* into the following 3 parts/files: the CFITSIO "front-end", */
+/* eval_f.c, contains the interface between the user/CFITSIO and the */
+/* real core of the parser; the FLEX interpreter, eval_l.c, takes the */
+/* input string and parses it into tokens and identifies the FITS */
+/* information required to evaluate the expression (ie, keywords and */
+/* columns); and, the BISON grammar and evaluation routines, eval_y.c, */
+/* receives the FLEX output and determines and performs the actual */
+/* operations. The files eval_l.c and eval_y.c are produced from */
+/* running flex and bison on the files eval.l and eval.y, respectively. */
+/* (flex and bison are available from any GNU archive: see www.gnu.org) */
+/* */
+/* The grammar rules, rather than evaluating the expression in situ, */
+/* builds a tree, or Nodal, structure mapping out the order of */
+/* operations and expression dependencies. This "compilation" process */
+/* allows for much faster processing of multiple rows. This technique */
+/* was developed by Uwe Lammers of the XMM Science Analysis System, */
+/* although the CFITSIO implementation is entirely code original. */
+/* */
+/* */
+/* Modification History: */
+/* */
+/* Kent Blackburn c1992 Original parser code developed for the */
+/* FTOOLS software package, in particular, */
+/* the fselect task. */
+/* Kent Blackburn c1995 BIT column support added */
+/* Peter D Wilson Feb 1998 Vector column support added */
+/* Peter D Wilson May 1998 Ported to CFITSIO library. User */
+/* interface routines written, in essence */
+/* making fselect, fcalc, and maketime */
+/* capabilities available to all tools */
+/* via single function calls. */
+/* Peter D Wilson Jun 1998 Major rewrite of parser core, so as to */
+/* create a run-time evaluation tree, */
+/* inspired by the work of Uwe Lammers, */
+/* resulting in a speed increase of */
+/* 10-100 times. */
+/* Peter D Wilson Jul 1998 gtifilter(a,b,c,d) function added */
+/* Peter D Wilson Aug 1998 regfilter(a,b,c,d) function added */
+/* Peter D Wilson Jul 1999 Make parser fitsfile-independent, */
+/* allowing a purely vector-based usage */
+/* */
+/************************************************************************/
+
+#include <math.h>
+#include <string.h>
+#include <ctype.h>
+#ifdef sparc
+#include <malloc.h>
+#else
+#include <stdlib.h>
+#endif
+#include "eval_defs.h"
+
+ParseData gParse; /* Global structure holding all parser information */
+
+/***** Internal functions *****/
+
+ int yyGetVariable( char *varName, YYSTYPE *varVal );
+
+static int find_variable( char *varName );
+static int expr_read( char *buf, int nbytes );
+
+/***** Definitions *****/
+
+#define YY_NO_UNPUT /* Don't include YYUNPUT function */
+#define YY_NEVER_INTERACTIVE 1
+
+#define MAXCHR 256
+#define MAXBIT 128
+
+#define OCT_0 "000"
+#define OCT_1 "001"
+#define OCT_2 "010"
+#define OCT_3 "011"
+#define OCT_4 "100"
+#define OCT_5 "101"
+#define OCT_6 "110"
+#define OCT_7 "111"
+#define OCT_X "xxx"
+
+#define HEX_0 "0000"
+#define HEX_1 "0001"
+#define HEX_2 "0010"
+#define HEX_3 "0011"
+#define HEX_4 "0100"
+#define HEX_5 "0101"
+#define HEX_6 "0110"
+#define HEX_7 "0111"
+#define HEX_8 "1000"
+#define HEX_9 "1001"
+#define HEX_A "1010"
+#define HEX_B "1011"
+#define HEX_C "1100"
+#define HEX_D "1101"
+#define HEX_E "1110"
+#define HEX_F "1111"
+#define HEX_X "xxxx"
+
+/*
+ MJT - 13 June 1996
+ read from buffer instead of stdin
+ (as per old ftools.skel)
+*/
+#undef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( (result = expr_read( (char *) buf, max_size )) < 0 ) \
+ YY_FATAL_ERROR( "read() in flex scanner failed" );
+
+%}
+bit ([bB][01xX]+)
+oct ([oO][01234567xX]+)
+hex ([hH][0123456789aAbBcCdDeEfFxX]+)
+integer [0-9]+
+boolean (t|f|T|F)
+real ([0-9]*"."[0-9]+)|([0-9]*"."*[0-9]+[eEdD][+-]?[0-9]+)|([0-9]*".")
+constant ("#"[a-zA-Z0-9_]+)|("#""$"[^\n]*"$")
+string ([\"][^\"\n]*[\"])|([\'][^\'\n]*[\'])
+variable ([a-zA-Z_][a-zA-Z0-9_]*)|("$"[^$\n]*"$")
+function [a-zA-Z][a-zA-Z0-9]+"("
+intcast ("(int)"|"(INT)")
+fltcast ("(float)"|"(FLOAT)"|"(double)"|"(DOUBLE)")
+power ("^"|"**")
+not ("!"|".not."|".NOT."|"not."|"NOT.")
+or ("||"|".or."|".OR."|"or."|"OR.")
+and ("&&"|".and."|".AND."|"and."|"AND.")
+equal ("=="|".eq."|".EQ."|"eq."|"EQ.")
+not_equal ("!="|".ne."|".NE."|"ne."|"NE.")
+greater (">"|".gt."|".GT."|"gt."|"GT.")
+lesser ("<"|".lt."|".LT."|"lt."|"LT.")
+greater_eq (">="|"=>"|".ge."|".GE."|"ge."|"GE.")
+lesser_eq ("<="|"=<"|".le."|".LE."|"le."|"LE.")
+nl \n
+
+%%
+
+[ \t]+ ;
+{bit} {
+ int len;
+ len = strlen(yytext);
+ while (yytext[len] == ' ')
+ len--;
+ len = len - 1;
+ strncpy(yylval.str,&yytext[1],len);
+ yylval.str[len] = '\0';
+ return( BITSTR );
+ }
+{oct} {
+ int len;
+ char tmpstring[256];
+ char bitstring[256];
+ len = strlen(yytext);
+ while (yytext[len] == ' ')
+ len--;
+ len = len - 1;
+ strncpy(tmpstring,&yytext[1],len);
+ tmpstring[len] = '\0';
+ bitstring[0] = '\0';
+ len = 0;
+ while ( tmpstring[len] != '\0')
+ {
+ switch ( tmpstring[len] )
+ {
+ case '0':
+ strcat(bitstring,OCT_0);
+ break;
+ case '1':
+ strcat(bitstring,OCT_1);
+ break;
+ case '2':
+ strcat(bitstring,OCT_2);
+ break;
+ case '3':
+ strcat(bitstring,OCT_3);
+ break;
+ case '4':
+ strcat(bitstring,OCT_4);
+ break;
+ case '5':
+ strcat(bitstring,OCT_5);
+ break;
+ case '6':
+ strcat(bitstring,OCT_6);
+ break;
+ case '7':
+ strcat(bitstring,OCT_7);
+ break;
+ case 'x':
+ case 'X':
+ strcat(bitstring,OCT_X);
+ break;
+ }
+ len++;
+ }
+ strcpy( yylval.str, bitstring );
+ return( BITSTR );
+ }
+{hex} {
+ int len;
+ char tmpstring[256];
+ char bitstring[256];
+ len = strlen(yytext);
+ while (yytext[len] == ' ')
+ len--;
+ len = len - 1;
+ strncpy(tmpstring,&yytext[1],len);
+ tmpstring[len] = '\0';
+ bitstring[0] = '\0';
+ len = 0;
+ while ( tmpstring[len] != '\0')
+ {
+ switch ( tmpstring[len] )
+ {
+ case '0':
+ strcat(bitstring,HEX_0);
+ break;
+ case '1':
+ strcat(bitstring,HEX_1);
+ break;
+ case '2':
+ strcat(bitstring,HEX_2);
+ break;
+ case '3':
+ strcat(bitstring,HEX_3);
+ break;
+ case '4':
+ strcat(bitstring,HEX_4);
+ break;
+ case '5':
+ strcat(bitstring,HEX_5);
+ break;
+ case '6':
+ strcat(bitstring,HEX_6);
+ break;
+ case '7':
+ strcat(bitstring,HEX_7);
+ break;
+ case '8':
+ strcat(bitstring,HEX_8);
+ break;
+ case '9':
+ strcat(bitstring,HEX_9);
+ break;
+ case 'a':
+ case 'A':
+ strcat(bitstring,HEX_A);
+ break;
+ case 'b':
+ case 'B':
+ strcat(bitstring,HEX_B);
+ break;
+ case 'c':
+ case 'C':
+ strcat(bitstring,HEX_C);
+ break;
+ case 'd':
+ case 'D':
+ strcat(bitstring,HEX_D);
+ break;
+ case 'e':
+ case 'E':
+ strcat(bitstring,HEX_E);
+ break;
+ case 'f':
+ case 'F':
+ strcat(bitstring,HEX_F);
+ break;
+ case 'x':
+ case 'X':
+ strcat(bitstring,HEX_X);
+ break;
+ }
+ len++;
+ }
+
+ strcpy( yylval.str, bitstring );
+ return( BITSTR );
+ }
+{integer} {
+ yylval.lng = atol(yytext);
+ return( LONG );
+ }
+{boolean} {
+ if ((yytext[0] == 't') || (yytext[0] == 'T'))
+ yylval.log = 1;
+ else
+ yylval.log = 0;
+ return( BOOLEAN );
+ }
+{real} {
+ yylval.dbl = atof(yytext);
+ return( DOUBLE );
+ }
+{constant} {
+ if( !strcasecmp(yytext,"#PI") ) {
+ yylval.dbl = (double)(4) * atan((double)(1));
+ return( DOUBLE );
+ } else if( !strcasecmp(yytext,"#E") ) {
+ yylval.dbl = exp((double)(1));
+ return( DOUBLE );
+ } else if( !strcasecmp(yytext,"#DEG") ) {
+ yylval.dbl = ((double)4)*atan((double)1)/((double)180);
+ return( DOUBLE );
+ } else if( !strcasecmp(yytext,"#ROW") ) {
+ return( ROWREF );
+ } else if( !strcasecmp(yytext,"#NULL") ) {
+ return( NULLREF );
+ } else if( !strcasecmp(yytext,"#SNULL") ) {
+ return( SNULLREF );
+ } else {
+ int len;
+ if (yytext[1] == '$') {
+ len = strlen(yytext) - 3;
+ yylval.str[0] = '#';
+ strncpy(yylval.str+1,&yytext[2],len);
+ yylval.str[len+1] = '\0';
+ yytext = yylval.str;
+ }
+ return( (*gParse.getData)(yytext, &yylval) );
+ }
+ }
+{string} {
+ int len;
+ len = strlen(yytext) - 2;
+ strncpy(yylval.str,&yytext[1],len);
+ yylval.str[len] = '\0';
+ return( STRING );
+ }
+{variable} {
+ int len,type;
+
+ if (yytext[0] == '$') {
+ len = strlen(yytext) - 2;
+ strncpy(yylval.str,&yytext[1],len);
+ yylval.str[len] = '\0';
+ yytext = yylval.str;
+ }
+ type = yyGetVariable(yytext, &yylval);
+ return( type );
+ }
+{function} {
+ char *fname;
+ int len=0;
+ fname = &yylval.str[0];
+ while( (fname[len]=toupper(yytext[len])) ) len++;
+
+ if( FSTRCMP(fname,"BOX(")==0
+ || FSTRCMP(fname,"CIRCLE(")==0
+ || FSTRCMP(fname,"ELLIPSE(")==0
+ || FSTRCMP(fname,"NEAR(")==0
+ || FSTRCMP(fname,"ISNULL(")==0
+ )
+ /* Return type is always boolean */
+ return( BFUNCTION );
+
+ else if( FSTRCMP(fname,"GTIFILTER(")==0 )
+ return( GTIFILTER );
+
+ else if( FSTRCMP(fname,"REGFILTER(")==0 )
+ return( REGFILTER );
+
+ else
+ return( FUNCTION );
+ }
+{intcast} { return( INTCAST ); }
+{fltcast} { return( FLTCAST ); }
+{power} { return( POWER ); }
+{not} { return( NOT ); }
+{or} { return( OR ); }
+{and} { return( AND ); }
+{equal} { return( EQ ); }
+{not_equal} { return( NE ); }
+{greater} { return( GT ); }
+{lesser} { return( LT ); }
+{greater_eq} { return( GTE ); }
+{lesser_eq} { return( LTE ); }
+{nl} { return( '\n' ); }
+. { return( yytext[0] ); }
+%%
+
+int yywrap()
+{
+ /* MJT -- 13 June 1996
+ Supplied for compatibility with
+ pre-2.5.1 versions of flex which
+ do not recognize %option noyywrap
+ */
+ return(1);
+}
+
+/*
+ expr_read is lifted from old ftools.skel.
+ Now we can use any version of flex with
+ no .skel file necessary! MJT - 13 June 1996
+
+ keep a memory of how many bytes have been
+ read previously, so that an unlimited-sized
+ buffer can be supported. PDW - 28 Feb 1998
+*/
+
+static int expr_read(char *buf, int nbytes)
+{
+ int n;
+
+ n = 0;
+ if( !gParse.is_eobuf ) {
+ do {
+ buf[n++] = gParse.expr[gParse.index++];
+ } while ((n<nbytes)&&(gParse.expr[gParse.index] != '\0'));
+ if( gParse.expr[gParse.index] == '\0' ) gParse.is_eobuf = 1;
+ }
+ buf[n] = '\0';
+ return(n);
+}
+
+int yyGetVariable( char *varName, YYSTYPE *thelval )
+{
+ int varNum, type;
+ char errMsg[MAXVARNAME+25];
+
+ varNum = find_variable( varName );
+ if( varNum<0 ) {
+ if( gParse.getData ) {
+ type = (*gParse.getData)( varName, thelval );
+ } else {
+ type = pERROR;
+ gParse.status = PARSE_SYNTAX_ERR;
+ strcpy (errMsg,"Unable to find data: ");
+ strncat(errMsg, varName, MAXVARNAME);
+ ffpmsg (errMsg);
+ }
+ } else {
+ /* Convert variable type into expression type */
+ switch( gParse.varData[ varNum ].type ) {
+ case LONG:
+ case DOUBLE: type = COLUMN; break;
+ case BOOLEAN: type = BCOLUMN; break;
+ case STRING: type = SCOLUMN; break;
+ case BITSTR: type = BITCOL; break;
+ default:
+ type = pERROR;
+ gParse.status = PARSE_SYNTAX_ERR;
+ strcpy (errMsg,"Bad datatype for data: ");
+ strncat(errMsg, varName, MAXVARNAME);
+ ffpmsg (errMsg);
+ break;
+ }
+ thelval->lng = varNum;
+ }
+ return( type );
+}
+
+static int find_variable(char *varName)
+{
+ int i;
+
+ if( gParse.nCols )
+ for( i=0; i<gParse.nCols; i++ ) {
+ if( ! strncasecmp(gParse.varData[i].name,varName,MAXVARNAME) ) {
+ return( i );
+ }
+ }
+ return( -1 );
+}
+
+#if defined(vms) || defined(__vms) || defined(WIN32) || defined(__WIN32__) || defined(macintosh)
+
+/* ================================================================== */
+/* A hack for nonunix machines, which lack strcasecmp and strncasecmp */
+/* ================================================================== */
+
+int strcasecmp(const char *s1, const char *s2)
+{
+ char c1, c2;
+
+ for (;;) {
+ c1 = toupper( *s1 );
+ c2 = toupper( *s2 );
+
+ if (c1 < c2) return(-1);
+ if (c1 > c2) return(1);
+ if (c1 == 0) return(0);
+ s1++;
+ s2++;
+ }
+}
+
+int strncasecmp(const char *s1, const char *s2, size_t n)
+{
+ char c1, c2;
+
+ for (; n-- ;) {
+ c1 = toupper( *s1 );
+ c2 = toupper( *s2 );
+
+ if (c1 < c2) return(-1);
+ if (c1 > c2) return(1);
+ if (c1 == 0) return(0);
+ s1++;
+ s2++;
+ }
+ return(0);
+}
+
+#endif