/*===========================================================================
  Copyright (C) 1989-2009 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
===========================================================================*/

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.TYPE        Module
.NAME        tbadec.c
.LANGUAGE    C
.AUTHOR      IPG-ESO Garching
.CATEGORY    table utilities

.COMMENTS    Interpretation of datatypes and formats.
\begin{TeX}
The datatype can be one of the following:

\begin{itemize}
\item	R[eal], R[eal]*4   - floating point single precision.
\item	D[ouble], R[eal]*8 - floating point double precision.
\item	I[nteger], I[nteger]*4 - long integer (4 bytes).
\item	S[hort],   I[nteger]*2 - short integer (2 bytes).
\item	B[yte],    I[nteger]*1 - byte integer (1 byte).
\item	U[nsigned]*$n$ - Unisgned integer with $n = 1, 2, 4$
\item	C[haracter]*n          - character string.
\end{itemize}
\end{TeX}


.VERSION 1.0 	25-Mar-1989   Definition     J.D. Ponz
.VERSION 3.0 	05-Jul-1990   New version with column arrays   F.O.
.VERSION 3.1 	27-Nov-1990   Merge of tbdecfmt and tbdectyp
.VERSION 3.15   04-Feb-1991   length of string = length of field  M.P

 090707		last modif
------------------------------------------------------------*/

#include <tbldef.h>
#include <midas_def.h>
#include <str.h>		/* String Utilities	*/
#include <proto_tbl.h>

#include <stdio.h>
#include <stdlib.h>



int tbl_dectyp(etype,type,noelem,form)
/*++++++++++++++++++
.PURPOSE Interpret the Type (e.g. R*4) declaration
.RETURNS Status
------------------*/
 char *etype;		/* IN: Text to scan	*/
 int  *type;		/* OUT: Midas data type	*/
 int  *noelem;		/* OUT: Array size	*/
 char *form;		/* OUT: Default Format	*/
{
	int 	i, l1, alen;
	char	msg[256];

  *noelem = 1;
  alen    = 0;		/* ASCII length */
  i = strloc (etype, '(');
  if (etype[i])	{
  	l1 = atoi(etype+1+i);
  	if ((l1 < 1) || (l1 > TBL_MAXSIZ)) {
		sprintf(msg, "****Bad array size in `%s'", etype);
		SCTPUT (msg);
		return (ERR_TBLCOL);
  	}
  	*noelem = l1;
  }

  l1 = 0;				/* decode type */
  i = strloc (etype, '*');
  if (etype[i])	l1 = atoi(etype + i + 1);
  switch (etype[0]) {
    case 'd': case 'D':
    case_double:
	if (!alen)	alen = 24;
    	sprintf (form, "D%d.%d", alen, alen-7);
    	*type = D_R8_FORMAT;
    	break;
    case 'R': case 'r': 
	if (l1 == 8)	goto case_double;
	if (!alen)	alen = 12;
    	sprintf (form, "E%d.%d", alen, alen-6);
	*type = D_R4_FORMAT;
	break;
    case 'I': case 'i': 
    case_int:
	if (l1 == 1)	{ *type = D_I1_FORMAT; if (!alen)  alen = 4; }
	else if (l1==2)	{ *type = D_I2_FORMAT; if (!alen)  alen = 6; }
	else		{ *type = D_I4_FORMAT; if (!alen)  alen = 11;}
    	sprintf (form, "I%d", alen);
	break;
    case 'l': case 'L': 
    case 'u': case 'U': 
    	if (l1 == 1)	{
		l1 = *noelem; 	*noelem = 1;
		goto case_ascii;
    	}
	if (l1==2)	{ *type = D_L1_FORMAT; if (!alen)  alen = 4; }
	else		{ *type = D_L4_FORMAT; if (!alen)  alen = 8;}
    	sprintf (form, "X%d", alen);
	break;
    case 'a': case 'A': 
    case 'c': case 'C': 
    case_ascii:
/*	if (*noelem > 1) {
		sprintf(msg, "**** C*n columns can't be arrays `%s'", etype);
		SCTPUT (msg);
		return (ERR_TBLCOL);
	} */
	if (l1 == 0)	l1 = alen;
  	if ((l1 < 1) || (l1 > TBL_MAXSIZ)) {
		sprintf(msg, "**** Bad character size in `%s'", etype);
		SCTPUT (msg);
		return (ERR_TBLCOL);
  	}
	sprintf(form,"A%d",l1);
/*	*noelem = 1;  */
	*type = D_C_FORMAT;
	break;  
    case 'B': case 'b': 
    	l1 = 1;    	goto case_int;
    case 'S': 
    	l1 = 2;    	goto case_int;
    default:
	sprintf (msg, "**** Bad datatype %s", etype);
	SCTPUT  (msg);
	return (ERR_TBLCOL);
  }

  return (ERR_NORMAL);
}


int tbl_decfmt(line,i1,i2,type,noelem,form,unit,label)
/*++++++++++++++++++
.PURPOSE Decode one line of the FMT file, which looks like
\begin{TeX}
	{\tt DEFINE/FIELD} [pos1 pos2] type [format] label [unit]
\end{TeX}
.RETURNS Status
.REMARKS If type==0 on return, we've an emtpy line (comment).
	Beware, the input line IS MODIFIED !!!
-i----------------*/
 char *line;	/* IN: Line to scan	*/
 int  *i1;	/* OUT: position (1) 	*/
 int  *i2;	/* OUT: position (2)	*/
 int  *type;	/* OUT: Element type in midas_def format	*/
 int  *noelem;	/* OUT: Size of array	*/
 char *form;	/* OUT: Format		*/
 char *unit;	/* OUT: Unit		*/
 char *label;	/* OUT: Label (column name)	*/
{
 int status, l1, l2, i,j;
 char *pf, *pl, *pu, *dtype;
 char *p,*pt,mpt[6];

  *i1   = 0;
  *i2   = 0;
  *type = 0;
  *noelem = 1;
  *form = *unit = '\0';
  l1 = l2 = 0;
  pt = mpt;

  line[strloc(line, '!')] = '\0';		/* Strip comments	*/

						/* DEFINE/KEY		*/
  p = line + strskip (line, ' ');
  if (*p != 'd' && *p != 'D') return(ERR_NORMAL);
  p += strloc (p, ' ');

						/* Get pos2  pos2	*/
  p += strskip(p, ' '); 
  if (isdigit (*p)) {
  	l1 = atoi(p); 	p += strloc(p, ' ');	p += strskip(p, ' '); 
  	l2 = atoi(p); 	p += strloc(p, ' ');
  	*i1 = l1; *i2 = l2; 
  	l2 = l2 - l1 + 1;
  }

  p += strskip(p, ' ');
  dtype = p;
  p+=strloc(p,' ' ); 
  if (*p) *(p++) = '\0'; 
  p += strskip(p, ' '); pf = p;    p += strloc(p, ' '); if (*p) *(p++) = '\0';
  p += strskip(p, ' '); pl = p;    p += strloc(p, ' '); if (*p) *(p++) = '\0';
  p += strskip(p, ' '); pu = p;    p += strloc(p, ' '); if (*p) *(p++) = '\0';
  if (! *pl)		pl = pf, pf = pu;	/* Only 1 string */
  if (*pf == ':')	p = pl, pl = pf+1, pf = p;
  if (*pu == ':')	p = pl, pl = pu+1, pu = p;
  if (*pf == '"')	p = pu, pu = pf,   pf = p;
  i = strloc(dtype,'*');
  if ((*dtype =='C' || *dtype =='c') && (!dtype[i])) sprintf(pt,"C*%d",l2); 
      else
          {
       j=0;
       while (*dtype!='\0'){
                pt[j] = *dtype++;
                j++;}
          pt[j] = '\0';
          }
 status = tbl_dectyp(pt, type, noelem, form);
 if (status) return(status);
 if (!pt[i] && (*pt =='C' || *pt =='c')) *noelem = l2;
 else if (( *pt=='C' || *pt =='c')) {
          pt +=2;
          *noelem = atoi(pt);
          }

  if (*pf)	strcpy (form, pf);
  if (*pu)	strcpy (unit, pu);


  i = (int) strlen(pl);
  if (i > TBL_LABLEN)
     {                                 /* truncate if necessary */
     (void) strncpy(label,pl,TBL_LABLEN);
     label[TBL_LABLEN] = '\0';
     (void) SCTPUT("(I/W) - column label truncated..");
     }
  else
     strcpy (label, pl);

  return(status);
}
