/*
 * vsscanf.c
 *
 * vsscanf(), from which the rest of the scanf()
 * family is built
 */

#include <ctype.h>
#include <stdarg.h>
#include <stddef.h>
#include <inttypes.h>
#include <string.h>
#include <limits.h>

#ifndef LONG_BIT
#define LONG_BIT (CHAR_BIT*sizeof(long))
#endif

enum flags {
  FL_SPLAT  = 0x01,		/* Drop the value, do not assign */
  FL_INV    = 0x02,		/* Character-set with inverse */
  FL_WIDTH  = 0x04,		/* Field width specified */
  FL_MINUS  = 0x08,		/* Negative number */
};

enum ranks {
  rank_char	= -2,
  rank_short	= -1,
  rank_int 	= 0,
  rank_long	= 1,
  rank_longlong	= 2,
  rank_ptr      = INT_MAX	/* Special value used for pointers */
};

#define MIN_RANK	rank_char
#define MAX_RANK	rank_longlong

#define INTMAX_RANK	rank_longlong
#define SIZE_T_RANK	rank_long
#define PTRDIFF_T_RANK	rank_long

enum bail {
  bail_none = 0,		/* No error condition */
  bail_eof,			/* Hit EOF */
  bail_err			/* Conversion mismatch */
};

static inline const char *
skipspace(const char *p)
{
  while ( isspace((unsigned char)*p) ) p++;
  return p;
}

static inline void
set_bit(unsigned long *bitmap, unsigned int bit)
{
  bitmap[bit/LONG_BIT] |= 1UL << (bit%LONG_BIT);
}

static inline int
test_bit(unsigned long *bitmap, unsigned int bit)
{
  return (int)(bitmap[bit/LONG_BIT] >> (bit%LONG_BIT)) & 1;
}

int vsscanf(const char *buffer, size_t n, const char *format, va_list ap)
{
  const char *p = format;
  char ch;
  const char *q = buffer;
  const char *qq;
  uintmax_t val = 0;
  int rank = rank_int;		/* Default rank */
  unsigned int width = UINT_MAX;
  int base;
  enum flags flags = 0;
  enum {
    st_normal,			/* Ground state */
    st_flags,			/* Special flags */
    st_width,			/* Field width */
    st_modifiers,		/* Length or conversion modifiers */
    st_match_init,		/* Initial state of %[ sequence */
    st_match,			/* Main state of %[ sequence */
    st_match_range,		/* After - in a %[ sequence */
  } state = st_normal;
  char *sarg = NULL;		/* %s %c or %[ string argument */
  enum bail bail = bail_none;
  int sign;
  int converted = 0;		/* Successful conversions */
  unsigned long matchmap[((1 << CHAR_BIT)+(LONG_BIT-1))/LONG_BIT];
  int matchinv = 0;		/* Is match map inverted? */
  unsigned char range_start = 0;

  while ( (ch = *p++) && !bail ) {
    switch ( state ) {
    case st_normal:
      if ( ch == '%' ) {
	state = st_flags;
	flags = 0; rank = rank_int; width = UINT_MAX;
      } else if ( isspace((unsigned char)ch) ) {
	q = skipspace(q);
      } else {
	if ( *q == ch )
	  q++;
	else
	  bail = bail_err;	/* Match failure */
      }
      break;

    case st_flags:
      switch ( ch ) {
      case '*':
	flags |= FL_SPLAT;
	break;
      case '0' ... '9':
	width = (ch-'0');
	state = st_width;
	flags |= FL_WIDTH;
	break;
      default:
	state = st_modifiers;
	p--;			/* Process this character again */
	break;
      }
      break;

    case st_width:
      if ( ch >= '0' && ch <= '9' ) {
	width = width*10+(ch-'0');
      } else {
	state = st_modifiers;
	p--;			/* Process this character again */
      }
      break;

    case st_modifiers:
      switch ( ch ) {
	/* Length modifiers - nonterminal sequences */
      case 'h':
	rank--;			/* Shorter rank */
	break;
      case 'l':
	rank++;			/* Longer rank */
	break;
      case 'j':
	rank = INTMAX_RANK;
	break;
      case 'z':
	rank = SIZE_T_RANK;
	break;
      case 't':
	rank = PTRDIFF_T_RANK;
	break;
      case 'L':
      case 'q':
	rank = rank_longlong;	/* long double/long long */
	break;

      default:
	/* Output modifiers - terminal sequences */
	state = st_normal;	/* Next state will be normal */
	if ( rank < MIN_RANK )	/* Canonicalize rank */
	  rank = MIN_RANK;
	else if ( rank > MAX_RANK )
	  rank = MAX_RANK;

	switch ( ch ) {
	case 'P':		/* Upper case pointer */
	case 'p':		/* Pointer */
#if 0	/* Enable this to allow null pointers by name */
	  q = skipspace(q);
	  if ( !isdigit((unsigned char)*q) ) {
	    static const char * const nullnames[] =
	    { "null", "nul", "nil", "(null)", "(nul)", "(nil)", 0 };
	    const char * const *np;

	    /* Check to see if it's a null pointer by name */
	    for ( np = nullnames ; *np ; np++ ) {
	      if ( !strncasecmp(q, *np, strlen(*np)) ) {
		val = (uintmax_t)((void *)NULL);
		goto set_integer;
	      }
	    }
	    /* Failure */
	    bail = bail_err;
	    break;
	  }
	  /* else */
#endif
	  rank = rank_ptr;
	  base = 0; sign = 0;
	  goto scan_int;

	case 'i':		/* Base-independent integer */
	  base = 0; sign = 1;
	  goto scan_int;

	case 'd':		/* Decimal integer */
	  base = 10; sign = 1;
	  goto scan_int;

	case 'o':		/* Octal integer */
	  base = 8; sign = 0;
	  goto scan_int;

	case 'u':		/* Unsigned decimal integer */
	  base = 10; sign = 0;
	  goto scan_int;
	  
	case 'x':		/* Hexadecimal integer */
	case 'X':
	  base = 16; sign = 0;
	  goto scan_int;

	case 'n':		/* Number of characters consumed */
	  val = (q-buffer);
	  goto set_integer;

	scan_int:
	  q = skipspace(q);
	  if ( !*q ) {
	    bail = bail_eof;
	    break;
	  }
	  val = strntoumax(q, (char **)&qq, base, width);
	  if ( qq == q ) {
	    bail = bail_err;
	    break;
	  }
	  converted++;
	  /* fall through */

	set_integer:
	  if ( !(flags & FL_SPLAT) ) {
	    switch(rank) {
	    case rank_char:
	      *va_arg(ap, unsigned char *) = (unsigned char)val;
	      break;
	    case rank_short:
	      *va_arg(ap, unsigned short *) = (unsigned short)val;
	      break;
	    case rank_int:
	      *va_arg(ap, unsigned int *) = (unsigned int)val;
	      break;
	    case rank_long:
	      *va_arg(ap, unsigned long *) = (unsigned long)val;
	      break;
	    case rank_longlong:
	      *va_arg(ap, unsigned long long *) = (unsigned long long)val;
	      break;
	    case rank_ptr:
	      *va_arg(ap, void **) = (void *)(uintptr_t)val;
	      break;
	    }
	  }
	  break;
	  
	case 'c':               /* Character */
          width = (flags & FL_WIDTH) ? width : 1; /* Default width == 1 */
          sarg = va_arg(ap, char *);
          while ( width-- ) {
            if ( !*q ) {
              bail = bail_eof;
              break;
            }
            *sarg++ = *q++;
          }
          if ( !bail )
            converted++;
          break;

        case 's':               /* String */
	  {
	    char *sp;
	    sp = sarg = va_arg(ap, char *);
	    while ( width-- && *q && !isspace((unsigned char)*q) ) {
	      *sp++ = *q++;
	    }
	    if ( sarg != sp ) {
	      *sp = '\0';	/* Terminate output */
	      converted++;
	    } else {
	      bail = bail_eof;
	    }
	  }
	  break;
	  
	case '[':		/* Character range */
	  sarg = va_arg(ap, char *);
	  state = st_match_init;
	  matchinv = 0;
	  memset(matchmap, 0, sizeof matchmap);
	  break;

	case '%':		/* %% sequence */
	  if ( *q == '%' )
	    q++;
	  else
	    bail = bail_err;
	  break;

	default:		/* Anything else */
	  bail = bail_err;	/* Unknown sequence */
	  break;
	}
      }
    
    case st_match_init:		/* Initial state for %[ match */
      if ( ch == '^' && !(flags & FL_INV) ) {
	matchinv = 1;
      } else {
	set_bit(matchmap, (unsigned char)ch);
	state = st_match;
      }
      break;
      
    case st_match:		/* Main state for %[ match */
      if ( ch == ']' ) {
	goto match_run;
      } else if ( ch == '-' ) {
	range_start = (unsigned char)ch;
	state = st_match_range;
      } else {
	set_bit(matchmap, (unsigned char)ch);
      }
      break;
      
    case st_match_range:		/* %[ match after - */
      if ( ch == ']' ) {
	set_bit(matchmap, (unsigned char)'-'); /* - was last character */
	goto match_run;
      } else {
	int i;
	for ( i = range_start ; i < (unsigned char)ch ; i++ )
	  set_bit(matchmap, i);
	state = st_match;
      }
      break;

    match_run:			/* Match expression finished */
      qq = q;
      while ( width && *q && test_bit(matchmap, (unsigned char)*q)^matchinv ) {
	*sarg++ = *q++;
      }
      if ( q != qq ) {
	converted++;
      } else {
	bail = *q ? bail_err : bail_eof;
      }
      break;
    }
  }

  if ( bail == bail_eof && !converted )
    converted = -1;		/* Return EOF (-1) */

  return converted;
}
