/* @(#)tbl_usrinp.c	19.1 (ES0-DMD) 02/25/03 14:07:42 */
/*===========================================================================
  Copyright (C) 1995 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 Massachusetss Ave, Cambridge, 
  MA 02139, USA.
 
  Corresponding 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) 1993 European Southern Observatory
.IDENTifer   
.AUTHOR      R.M. van Hees IPG-ESO Garching
.KEYWORDS    3D tables
.LANGUAGE    C
.PURPOSE     Split user input into column designation, row number and items
        input: char *string
       output:       int  *type       orientation of the data in the 3D table
                                      0) sequence number
                                      1) data from a column
                                      2) data from a row
                                      3) data from a index ("depth")
                     char *column     textual designation,
                                         DEFAULT: all columns
                     int  *rownr      number of the requested row,
                                         DEFAULT: rownr = 1
                     int  *index      index in the "depth" direction,
                                         DEFAULT: index = 1
                     int  *items      number of items to be read,
                                         DEFAULT: all items

.COMMENTS    this routine does not check the contents of the input string,
             this has to be done by a high level table routine, but it does 
             a syntax check
.ENVIRONment MIDAS
             #include <midas_def.h>     Prototypes for MIDAS interfaces
             #include <plot_def.h>      Symbols used by the PLT interfaces

.VERSION     1.0     28-Jul-1993   Created by R.M. van Hees
------------------------------------------------------------*/
/*
 * Define _POSIX_SOURCE to indicate
 * that this is a POSIX program
 */
#define  _POSIX_SOURCE 1

/*
 * definition of the used functions in this module
 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <midas_def.h>

/*
 * define some macros and constants
 */
#include <plot_def.h>

/*
 * here starts the code of some private functions
 */

/*++++++++++++++++++++++++++++++
 * This function is only usefull if the user asks for data in a column
 * or data contained in a range of columns
 *   Note: before the call:  **string == '#',
 *         after: *string is move after the character sting with column numbers
 */
#ifdef __STDC__
      static void get_col( char **string, char *column )
#else
      static void get_col( string, column )
      char **string, *column;
#endif
{
char *p_end;

/*
 * where does the string with column number ends?
 */
if ( (p_end = strchr( *string, '[' )) == NULL )
   { (void) strcpy( column, *string );
     *string = p_end;
   }
else
   { (void) strncat( column, *string, (p_end - *string));
     *string = p_end;
   }
}

/*++++++++++++++++++++++++++++++
 * This function is only usefull if the user asks for data in a table 
 * having a constant row number
 *   Note: before the call:  **string == '@',
 *         after: *string is move after the character sting with the row number
 */
#ifdef __STDC__
      static void get_row( char **string, int *rownr )
#else
      static void get_row( string, rownr )
      char **string;
      int  *rownr;
#endif
{
char *crow, *p_end;

crow = calloc(12, sizeof(char));
*crow = '\0';
/*
 * where does the string with row number ends?
 */
if ( (p_end = strchr( *string, ':' )) != NULL )
   { if ( strchr( *string, '#' ) != NULL )
        p_end = MYMIN( p_end, strchr( *string, '#' ) );
     else if ( strchr( *string, '[' ) != NULL )
        p_end = MYMIN( p_end, strchr( *string, '[' ) );
   }
else if ( (p_end = strchr( *string, '#' )) != NULL )
   { if ( strchr( *string, '[' ) != NULL )
        p_end = MYMIN( p_end, strchr( *string, '[' ) );
   }
else
   p_end = strchr( *string, '[' );

(*string)++;
if ( p_end == NULL )
   { (void) strcpy( crow, *string );
     *string = p_end;
   }
else
   { (void) strncat( crow, *string, (p_end - *string));
     *string = p_end;
   }

if ( strin( crow, ".." ) )
   SCETER( 2, "***FATAL: Illegal input, check syntax" );
else
   *rownr = atoi( crow );

(void) osmmfree( crow );
return;
}

/*++++++++++++++++++++++++++++++
 * This function is only usefull if the user asks for data in a 3D table 
 *   Note: before the call:  **string == '[',
 *         after: *string is move after the character sting with depth numbers
 */
#ifdef __STDC__
      static void get_indx( char **string, int *index, int *items )
#else
      static void get_indx( string, index, items )
      char **string;
      int  *index, *items;
#endif
{
int  slen;
char *cindex, *citems, *p_end, *p_range; 

cindex = calloc(10, sizeof(char));
citems = calloc(10, sizeof(char));
*cindex = *citems = '\0';
/*
 * where does the string ends
 */
if ( (p_end = strchr( *string, ']' )) == NULL )
   SCETER( 3, "***FATAL: Illegal input, check syntax" );

(*string)++;
if ( (p_range = strstrs( *string, ".." )) == NULL )
   { (void) strncat( cindex, *string, (p_end - *string));
     *index = atoi( cindex );
     *items = 1;
   }
else
   { (void) strncat( cindex, *string, (p_range - *string));
     (void) strncat( citems, p_range+2, (p_end - p_range - 2));
     *index = atoi( cindex );
     *items = abs( atoi( citems ) - atoi( cindex )) + 1;
   }

slen = strlen( *string );
if ( slen > p_end - *string + 1 )
   *string = p_end + 1;
else
   *string = NULL;

(void) osmmfree( cindex );
(void) osmmfree( citems );
return;
}

/*++++++++++++++++++++++++++++++++++++++++++++++++++
 *
 * here start the code of the function
 */
void TBL_USRINP( string, type, column, rownr, index, items )
char *string, *column;
int  *type, *rownr, *index, *items;

{
int    slen;
char   *cbuff, *pntr;

/*
 * initialisation:
 *    if not specified we take: - ALL the Columns in the table,
 *                              - FIRST Row,
 *                              - FIRST Index, and ALL Items
 */
*column = '\0';
*rownr  = *index = 1;
*items  = 0;

/*
 * allocate memory for local character strings and remove trailing blanks
 */
slen = strlen( string );
pntr = cbuff = calloc(slen+1, sizeof(char));

/*
 * test if sequence number is requested
 */
(void) strcpy( cbuff, string );
(void) strtok( cbuff, " " );
if ( strncmp( cbuff, "SEQ", 3 ) == 0 || strncmp( cbuff, "seq", 3 ) == 0 )
   (void) strcpy( cbuff, "?" );

/*
 * get orientation of the requested data, or leave with an error message
 */
*type = 0;
switch( (int) *cbuff )
   { case '[':
         (*type)++;
     case '@':
         (*type)++;
     case '#':
     case ':':
         (*type)++;
         break;
     case '?':
         break;
     default :
         SCETER( 1, "***FATAL: Illegal coordinate string" );
   }
/*
 * The user is not allowed to specify a row number if the plane is not a
 *     Y-plane
 */
if ( (*type == 1 || *type == 3 ) && strchr( pntr, '@' ) != NULL )
   SCETER(2, "*** FATAL: Use SELECT/TABLE, to select one or more rows");

switch( *type )
   { case 2:
         get_row( &pntr, rownr );
     case 1:
         if ( pntr != NULL ) get_col( &pntr, column );
/* 
 * more than one column and type = 1
 */
         if ( *type == 1 )
            { if ( *column == '\0' || strin( column, ".." )
                   || strchr( column, ',' ) != NULL )
                 *type = 2;
            }
         if ( pntr != NULL ) get_indx( &pntr, index, items );
         break;
     case 3:
         get_indx( &pntr, index, items );
/* 
 * more than one item --> type = 2 
 */
         if ( *items > 1 ) *type = 2;          
         if ( pntr != NULL ) get_col( &pntr, column );
         break;
     case 0:
         (void) strcpy( column, "Sequence" );
         break;
   }

(void) osmmfree( cbuff );
return;
}

