/* Copyright (C) 1996-2013 Free Software Foundation, Inc.
   This file is part of the GNU C Library.
   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, see
   <http://www.gnu.org/licenses/>.  */

#ifndef _REGEXP_H
#define _REGEXP_H	1

/* The contents of this header file was first standardized in X/Open
   System Interface and Headers Issue 2, originally coming from SysV.
   In issue 4, version 2, it is marked as TO BE WITDRAWN, and it has
   been withdrawn in SUSv3.

   This code shouldn't be used in any newly written code.  It is
   included only for compatibility reasons.  Use the POSIX definition
   in <regex.h> for portable applications and a reasonable interface.  */

#include <features.h>
#include <alloca.h>
#include <regex.h>
#include <stdlib.h>
#include <string.h>

/* The implementation provided here emulates the needed functionality
   by mapping to the POSIX regular expression matcher.  The interface
   for the here included function is weird (this really is a harmless
   word).

   The user has to provide six macros before this header file can be
   included:

   INIT		Declarations vor variables which can be used by the
		other macros.

   GETC()	Return the value of the next character in the regular
		expression pattern.  Successive calls should return
		successive characters.

   PEEKC()	Return the value of the next character in the regular
		expression pattern.  Immediately successive calls to
		PEEKC() should return the same character which should
		also be the next character returned by GETC().

   UNGETC(c)	Cause `c' to be returned by the next call to GETC() and
		PEEKC().

   RETURN(ptr)	Used for normal exit of the `compile' function.  `ptr'
		is a pointer to the character after the last character of
		the compiled regular expression.

   ERROR(val)	Used for abnormal return from `compile'.  `val' is the
		error number.  The error codes are:
		11	Range endpoint too large.
		16	Bad number.
		25	\digit out of range.
		36	Illegal or missing delimiter.
		41	No remembered search string.
		42	\( \) imbalance.
		43	Too many \(.
		44	More tan two numbers given in \{ \}.
		45	} expected after \.
		46	First number exceeds second in \{ \}.
		49	[ ] imbalance.
		50	Regular expression overflow.

  */

__BEGIN_DECLS

/* Interface variables.  They contain the results of the successful
   calls to `setp' and `advance'.  */
extern char *loc1;
extern char *loc2;

/* The use of this variable in the `advance' function is not
   supported.  */
extern char *locs;


#ifndef __DO_NOT_DEFINE_COMPILE
/* Get and compile the user supplied pattern up to end of line or
   string or until EOF is seen, whatever happens first.  The result is
   placed in the buffer starting at EXPBUF and delimited by ENDBUF.

   This function cannot be defined in the libc itself since it depends
   on the macros.  */
char *
compile (char *__restrict instring, char *__restrict expbuf,
	 const char *__restrict endbuf, int eof)
{
  char *__input_buffer = NULL;
  size_t __input_size = 0;
  size_t __current_size = 0;
  int __ch;
  int __error;
  INIT

  /* Align the expression buffer according to the needs for an object
     of type `regex_t'.  Then check for minimum size of the buffer for
     the compiled regular expression.  */
  regex_t *__expr_ptr;
# if defined __GNUC__ && __GNUC__ >= 2
  const size_t __req = __alignof__ (regex_t *);
# else
  /* How shall we find out?  We simply guess it and can change it is
     this really proofs to be wrong.  */
  const size_t __req = 8;
# endif
  expbuf += __req;
  expbuf -= (expbuf - ((char *) 0)) % __req;
  if (endbuf < expbuf + sizeof (regex_t))
    {
      ERROR (50);
    }
  __expr_ptr = (regex_t *) expbuf;
  /* The remaining space in the buffer can be used for the compiled
     pattern.  */
  __expr_ptr->__REPB_PREFIX (buffer) = expbuf + sizeof (regex_t);
  __expr_ptr->__REPB_PREFIX (allocated)
    = endbuf - (char *) __expr_ptr->__REPB_PREFIX (buffer);

  while ((__ch = (GETC ())) != eof)
    {
      if (__ch == '\0' || __ch == '\n')
	{
	  UNGETC (__ch);
	  break;
	}

      if (__current_size + 1 >= __input_size)
	{
	  size_t __new_size = __input_size ? 2 * __input_size : 128;
	  char *__new_room = (char *) alloca (__new_size);
	  /* See whether we can use the old buffer.  */
	  if (__new_room + __new_size == __input_buffer)
	    {
	      __input_size += __new_size;
	      __input_buffer = (char *) memcpy (__new_room, __input_buffer,
					       __current_size);
	    }
	  else if (__input_buffer + __input_size == __new_room)
	    __input_size += __new_size;
	  else
	    {
	      __input_size = __new_size;
	      __input_buffer = (char *) memcpy (__new_room, __input_buffer,
						__current_size);
	    }
	}
      __input_buffer[__current_size++] = __ch;
    }
  if (__current_size)
    __input_buffer[__current_size++] = '\0';
  else
    __input_buffer = "";

  /* Now compile the pattern.  */
  __error = regcomp (__expr_ptr, __input_buffer, REG_NEWLINE);
  if (__error != 0)
    /* Oh well, we have to translate POSIX error codes.  */
    switch (__error)
      {
      case REG_BADPAT:
      case REG_ECOLLATE:
      case REG_ECTYPE:
      case REG_EESCAPE:
      case REG_BADRPT:
      case REG_EEND:
      case REG_ERPAREN:
      default:
	/* There is no matching error code.  */
	RETURN (36);
      case REG_ESUBREG:
	RETURN (25);
      case REG_EBRACK:
	RETURN (49);
      case REG_EPAREN:
	RETURN (42);
      case REG_EBRACE:
	RETURN (44);
      case REG_BADBR:
	RETURN (46);
      case REG_ERANGE:
	RETURN (11);
      case REG_ESPACE:
      case REG_ESIZE:
	ERROR (50);
      }

  /* Everything is ok.  */
  RETURN ((char *) (__expr_ptr->__REPB_PREFIX (buffer)
		    + __expr_ptr->__REPB_PREFIX (used)));
}
#endif


/* Find the next match in STRING.  The compiled regular expression is
   found in the buffer starting at EXPBUF.  `loc1' will return the
   first character matched and `loc2' points to the next unmatched
   character.  */
extern int step (const char *__restrict __string,
		 const char *__restrict __expbuf) __THROW;

/* Match the beginning of STRING with the compiled regular expression
   in EXPBUF.  If the match is successful `loc2' will contain the
   position of the first unmatched character.  */
extern int advance (const char *__restrict __string,
		    const char *__restrict __expbuf) __THROW;


__END_DECLS

#endif /* regexp.h */
