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

/*+++++++++  
.MODULE    str2.c
.AUTHOR    Francois Ochsenbein [ESO]
.LANGUAGE  C
.CATEGORY  Basic String Tokenisation

.COMMENTS
\begin{TeX}
	This module computes the length of basic tokens; 
	tokens recognized here are:
\begin{itemize}
\item 	{\bf stkid}: identifiers (starting {\em alpha}, 
	then {\em alpha}numeric, where
	{\em alpha} includes also {\bf\$} and {\bf\_}).
\item 	{\bf stkint}: integers written as (signed)digits, or {\tt 0x...} in hexadecimal,
	or {\tt 0o...} for octal.
\item 	{\bf stknum}: numbers that can match floating-point numbers (no hexadecimal facility)
\item 	{\bf stkstr}: quoted strings (the \b is used to escape the quote)
\item 	{\bf stkcomment}: comments between / *    and * /
\end{itemize}
All routines return a length which represents the matching length.
\end{TeX}

.VERSION   1.0	30-Jan-1990: Creation
.VERSION   1.1	22-Mar-1990: Renamed as stk (string token)

 090831		last modif
----------------------------------------------------------------------------*/
 
#include <osdefos.h>
#include <macrogen.h>
#include <atype.h>

#define issign(c)		((c == '+') || (c == '-'))

/*===========================================================================
 *		Identifier (starting with alphabetic)
 *===========================================================================*/

int stkid(s)
/*+++++++
.PURPOSE Reads an `identifier' (starting alphabetic, then alphanumeric)
.RETURNS Length of valid token (0 if none)
.REMARKS 
---------*/
	char 	*s;		/* IN: string to scan	*/
{
	char *p;

  p = s;
  if (isid1(*p))
  {	p++;
  	while (isid(*p))	p++;
  }
  
  return(p - s);
}

/*===========================================================================
 *		Integer (numeric as digits)
 *===========================================================================*/

int stkint(s)
/*+++++++
.PURPOSE Tokenize an `integer'; possibilities 0x (hexa), 0O (octal).
.RETURNS Length of token
.REMARKS s starts with sign or digit
---------*/
	char 	*s;		/* IN: string to scan	*/
{
	char 	*p, base;

  p = s, base = 0;
  
  if (*p == '0')			/* Look for Octal or Hexa	*/
  	p++, base = toupper(*p);
  else if (issign(*p))	p++;
  else if (isdigit(*p)) ;
  else goto FIN;
  
  if (base)			/* There is a special base character	*/
  {  	if (base == 'X')	base = _XDIGIT_;
  	else if (base == 'O')	base = _DIGIT_;
  	else goto FIN;		/* Stopped by an alphabetic	*/
  	p++;			/* Skip the base letter. 	*/
  }
  else 	base = _DIGIT_;

	/* Now span over the digits */

  while(ischar(*p, base))	p++;

  FIN: return(p-s);
}

/*===========================================================================
 *		Numeric (floating-point)
 *===========================================================================*/

int stknum(s)
/*++++++++++++++++++
.PURPOSE Match Number, written as a floating-point number (exponent expressed
		as e, E, d or D)
.RETURNS Length of token
.REMARKS s starts with sign or . or digit
---------------------*/
	char	*s;	/* IN: String to scan */
{
	char	*p, x;
	
  p = s;
  
  if    (issign(*p))	p++;
  while (isdigit(*p))	p++;
  if (*p == '.')	for (++p; isdigit(*p); p++) ;

  x = toupper(*p);	
  if ( (x == 'E') || (x == 'D'))	/* Look for Exponent */
  {	p++;
	if    (issign(*p))	p++;
	while (isdigit(*p))	p++;
  }
  return(p-s);
}

/*===========================================================================
 *		Quoted String (quote escaped with \)
 *===========================================================================*/

int stkstr(s)
/*++++++++++++++++++
.PURPOSE Match a quoted string
.RETURNS Length of quoted string, INCLUDING terminators
.REMARKS s starts with ' or " or `. The escape character is \ .
---------------------*/
	char	*s;	/* IN: String to scan */
{
	char	*p, quote;
	


  p = (char *) 0;

  quote = *s;
  
  if ((quote != '"') && (quote != '\'') && (quote != '`')) 
  	goto FIN;
  
  for (p = s+1; *p; p++)
  {		/* Find End Of String. Take care of quote escaped with \ */
  	if (*p == '\\')	{ p++; continue; }	/* Escaped char	*/
	if (*p == quote){ p++; 	break;	 }	/* Quote found.	*/
  }

  FIN: return(p-s);
}

/*===========================================================================
 *		Comment (between / *   and * /)
 *===========================================================================*/

int stkcomment(s)
/*+++++++
.PURPOSE Extracts the comment from a string
.RETURNS Length of comment, including limits / *   * /
.REMARKS String assumed to start with / * 
---------*/
	char 	*s;		/* IN: string to scan	*/
{
	char	*p;
	
  p = s;
  if (*p   != '/')	goto FIN;
  if (*++p != '*')	goto FIN;

  for (++p; *p; p++)
  {  	if (*p != '*')	continue;
	if (*(p+1) == '/')	{ p += 2; break; }
  			/* Char following the * must be a / ... */
  }

  FIN: return(p-s);
}

