/*===========================================================================
  Copyright (C) 1995,2003 European Southern Observatory (ESO)
 
  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 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., 675 Massachusetts Ave, Cambridge, 
  MA 02139, USA.
 
  Correspondence concerning ESO-MIDAS should be addressed as follows:
	Internet e-mail: midas@eso.org
	Postal address: European Southern Observatory
			Data Management Division 
			Karl-Schwarzschild-Strasse 2
			D 85748 Garching bei Muenchen 
			GERMANY
===========================================================================*/

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.COPYRIGHT  (c) 1991 European Southern Observatory
.LANGUAGE   C
.IDENT      cvbtest.c
.AUTHOR     Preben J. Grosbol [ESO/IPG]
.KEYWORDS   test routines, data conversion
.ENVIRON    UNIX
.PURPOSE    Test routine for data conversion routines
.VERSION    1.0   1990-Sep-27 : Creation,     PJG
.VERSION    1.1   1990-Feb-11 : Add conversion back again,     PJG
.VERSION    1.2   1990-Feb-12 : Add benchmark test,     PJG

 030804		last modif
------------------------------------------------------------------------*/

#include  <stdio.h>
#include  <fitsfmt.h>
#include  <fitsextvals.h>
#include  <fitscvb.h>

#define   MXBUF      2880                    /* Max. char. in buffer    */
#define   MXPARM       16                    /* Max. no. of parameter   */

static char *plist[] = {"i+:Input file",
			"v-:Verbose",
                        "b-:Benchmark",
			"x-:Export format",
			"f-:Single precision Floating Point",
			"d-:Double precision Floating Point",
			"l-:Long integer",
			"s-:Short integer", (char *) 0};

main(argc,argv)
int       argc;
char    **argv;

{
  unsigned char  v, *pb, *pv, buf[MXBUF];
  char           c, *pc, mode, *pval[MXPARM];
  char           *gvparm();
  long	         *pl;
  short          *ps;
  float          *pf;
  double         *pd;
  int            n, i, to, vrbs, from, xfmt, bmark;
  FILE           *ifp;

  dcparm(argc,argv,plist,pval);             /* decode parameter list  */
  ifp = (pc=gvparm('i',plist,pval)) ? fopen(pc,"r") : stdin;
  if (!ifp) exit(1);
  vrbs = (gvparm('v',plist,pval) != (char *) 0);
  xfmt = (gvparm('x',plist,pval) != (char *) 0);
  bmark = (gvparm('b',plist,pval) != (char *) 0);
  if (gvparm('f',plist,pval)) mode = 'f';
  else if (gvparm('d',plist,pval)) mode = 'd';
  else if (gvparm('l',plist,pval)) mode = 'l';
  else if (gvparm('s',plist,pval)) mode = 's';
  else mode = 'f';
  if (vrbs) printf("Format Mode %c\n\n",mode);

  cvinit(); to = 1; from = 0;
  if (bmark) {                  /* Benchmark test 10000 FITS records */
    n = 100000;
    if (vrbs) printf("Benchmark for %d 2880 byte FITS records\n",n);
    i = MXBUF; pb = buf;
    while (i--) *pb++ = 0xff & i;
    switch (mode) {
       case 'd' : i = MXBUF/8; pd = (double *) buf;
	          while (n--) { cvr8(pd,i,from); cvr8(pd,i,to); }
                  break;
       case 'f' : i = MXBUF/4; pf = (float *) buf;
	          while (n--) { cvr4(pf,i,from); cvr4(pf,i,to); }
                  break;
       case 'l' : i = MXBUF/4; pl = (long *) buf;
	          while (n--) 
                     {
                     if (!same_comp_i4) 
                        {
                        cvi4(pl,i,from);
                        cvi4(pl,i,to); 
                        }
                     }
                  break;
       case 's' : i = MXBUF/2; ps = (short *) buf;
	          while (n--) 
                     {
                     if (!same_comp_i2) 
                        {
                        cvi2(ps,i,from);
                        cvi2(ps,i,to); 
                        }
                     }
                  break;
       }
    exit(0);
  }

  while (fgets((char*) buf,MXBUF,ifp)) {
     if (vrbs) fputs((char*) buf,stdout);
     n = 0; pb = buf; pv = buf;
     while (c = *pb++) {
	if (c=='!') break;
	if ('0'<=c && c<='9') v = c - '0';
	else if ('A'<=c && c<='F') v = 10 + c - 'A';
	else if ('a'<=c && c<='f') v = 10 + c - 'a';
	else continue;
	if (n++ & 1) *pv++ += v; else *pv = v<<4;
      }
     switch (mode) {
	case 'd' : i = n/16; pd = (double *) buf;
	           if (!i) break;
		   printf("Double %02x%02x%02x%02x %02x%02x%02x%02x > ",
			   buf[0],buf[1],buf[2],buf[3],
			   buf[4],buf[5],buf[6],buf[7]);
		   cvr8(pd,i,from);
		   printf(" %25.17e ",*pd);
		   printf("(%02x%02x%02x%02x %02x%02x%02x%02x)\n",
			   buf[0],buf[1],buf[2],buf[3],
			   buf[4],buf[5],buf[6],buf[7]);
	           if (xfmt) {
		      cvr8(pd,i,to);
		      printf("-----> %02x%02x%02x%02x %02x%02x%02x%02x\n",
			     buf[0],buf[1],buf[2],buf[3],
			     buf[4],buf[5],buf[6],buf[7]);
		    }
		   break;
	case 'f' : i = n/8; pf = (float *) buf;
	           if (!i) break;
		   printf("Float %02x%02x%02x%02x > ",
			   buf[0],buf[1],buf[2],buf[3]);
		   cvr4(pf,i,from);
		   printf(" %16.7e ",*pf);
		   printf("(%02x%02x%02x%02x)\n",
			   buf[0],buf[1],buf[2],buf[3]);
	           if (xfmt) {
		      cvr4(pf,i,to);
		      printf("----> %02x%02x%02x%02x\n",
			     buf[0],buf[1],buf[2],buf[3]);
		    }
		   break;
	case 'l' : i = n/8; pl = (long *) buf;
	           if (!i) break;
		   printf("Long %02x%02x%02x%02x > ",
			   buf[0],buf[1],buf[2],buf[3]);
		   if (!same_comp_i4) cvi4(pl,i,from);
		   printf(" %12ld ",*pl);
		   printf("(%02x%02x%02x%02x)\n",
			   buf[0],buf[1],buf[2],buf[3]);
	           if (xfmt) {
		      if (!same_comp_i4) cvi4(pl,i,to);
		      printf("---> %02x%02x%02x%02x\n",
			     buf[0],buf[1],buf[2],buf[3]);
		    }
		   break;
	case 's' : i = n/4; ps = (short *) buf;
		   if (!i) break;
		   printf("Short %02x%02x > ",buf[0],buf[1]);
		   if (!same_comp_i2) cvi2(ps,i,from);
		   printf(" %7d ",*ps);
		   printf("(%02x%02x)\n",buf[0],buf[1]);
	           if (xfmt) {
		      if (!same_comp_i2) cvi2(ps,i,to);
		      printf("----> %02x%02x\n",buf[0],buf[1]);
		    }
		   break;
	}
   }
  exit(0);
}

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.COPYRIGHT   (c) 1990 European Southern Observatory
.LANGUAGE    C
.IDENT       dcparm.c
.AUTHOR      Preben J. Grosbol [ESO/IPG]
.KEYWORDS    parameter decoding, command line
.ENVIRON     UNIX
.VERSION     1.0   1990-Jul-12 : Creation,     PJG
.VERSION     1.1   1990-Aug-24 : Add gvparm function,     PJG
------------------------------------------------------------------------*/
static  char  *cnull = "";            /* pointer to NULL string         */

int dcparm(argc,argv,plist,pval)
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.PURPOSE     Decode options and parameters on the command line using
             standard UNIX syntax.
.COMMENT     Each option/flag and parameter is defined in a string
             where the first character is the letter for the flag and
             the second indicates the type '-' for flag and '+' for
             addition string expected. After the parameter definition
             field as comment can be given starting with the delimeter ':'.
             If a parameter is not given it's value in a NULL popinter.
             When a flag without string is specified the pointer  points
             to a NULL string.
             Example:    command  -x -i name -o file
             A parameter list    plist[] = {"x-:Execute flag",
                                            "v-:Verbose flag",
                                            "i+:Input file",
                                            "o+:Output file",(char *) 0}
             would give an output pval[] = {"",(char *) 0,"name","file"}
.RETURN      Status where 0:OK, -1:Error
------------------------------------------------------------------------*/
int        argc;          /* parameter count                            */
char     **argv;          /* pointers to parameters                     */
char   *plist[];          /* pointers to parameter definitions          */
char    *pval[];          /* pointers to parameters strings             */

{
  char  c,*pc,*pl;
  int   n;

  pl = cnull;                                     /* initiate variables */
  for (n=0; plist[n]; n++) pval[n] = (char *) 0;

  argv++;                                  /* skip over command name    */
  if (--argc != 0)                         /* decode parameters         */
    while (argc--) {
       pc = *argv++;
       if (*pl=='+') { pval[n] = pc; pl = cnull; continue; }	    
       if (*pc++ == '-')
          while (c = *pc++) {
	     n = 0;
	     while ((pl=plist[n]) && *pl!=c) n++;
             if (pl++) { 
                if (*pl!='+') pval[n] = cnull;
                else { 
                  if (*pc) { pval[n] = pc; pl = cnull; }
                  break;
                }
             }
          }	     
    }
  return 0;
}

char *gvparm(opt,plist,pval)
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.PURPOSE     Retrieve parameter value for option specified
.COMMENT     The arrays 'plist' and 'pval' are the same as in
             routine cdparm().
.RETURN      Pointer to value string, NULL pointer if not available
------------------------------------------------------------------------*/
char        opt;          /* option for parameter                       */
char   *plist[];          /* pointers to parameter definitions          */
char    *pval[];          /* pointers to parameter strings              */

{
  while (*plist && **plist!=opt) plist++, pval++;

  return ((*plist) ? *pval : (char *) 0);
}

