#include <ctype.h>

#include "indexl.h"

#define SPACE 32
#define NL 10
/* #define IMPLIED_BS(a) ((a)==SPACE || (a)==NL || ispunct(a)) */
#define IMPLIED_BS(a) ((a)==SPACE || (a)==NL || ispunct(a))
#define CAP  0x01
#define CCAP 0x02
#define ACAP 0x03
#define BS   0x04

static INLINE int
issp(int m) {

  return m==SPACE;

}

static INLINE int
isnl(int m) {

  return m==NL;

}

static INLINE int
isalphaa(int m) {

  return isalpha(m) || m=='\'';

}

#define TTYPE 5
typedef int (*tfunc)(int);
static tfunc T[TTYPE]={isalphaa,isdigit,ispunct,issp,isnl};


int
str_to_token(Map *m,Gen *g) {

  char *tt,temp_flag;
  static char cur_flag,next_flag=BS,*eow,wl;
  int (*f)(int);
  unsigned i;

  temp_flag=cur_flag;
  if (!cur_flag) {

    eow=m->m;
    for (i=0;i<TTYPE && !T[i](*eow);i++);
    if (i==TTYPE) {
      err("Bad character ->%c<- %u\n",*eow,*eow);
      return 0;
    }
    f=T[i];
    
    cur_flag=next_flag;
    if (f==isalphaa) {
      cur_flag |= CCAP;
      if (isupper(*eow)) {
	cur_flag |= CAP;
	*eow=tolower(*eow);
      }
    }
    for (tt=++eow;eow<(char *)m->me && f(*eow);eow++) 
      if ((cur_flag & CCAP) && islower(*eow))
	cur_flag &= ~CCAP;
    if (cur_flag & CCAP)
      for (;tt<eow;tt++)
	*tt=tolower(*tt);

    next_flag=0;
    if (eow==(char *)m->me || !IMPLIED_BS(*eow))
      next_flag |= BS;
    
    wl=eow-(char *)m->m;
    if (eow+1<(char *)m->me && *eow==SPACE && !IMPLIED_BS(eow[1]))
      eow++;

  }

  if (temp_flag!=cur_flag) {
    g->v=&cur_flag;
    g->w=1;
  } else {
    g->v=m->m;
    g->w=wl;
    m->m=eow;
    cur_flag=0;
  }
  
  return 1;

}

#define mem_in(a,b,c) do {\
memcpy(a,b,c);\
a=(char *)a+c;\
} while (0)	       

void
token_to_str(const W *w,Map *m) {

  static char f;
  const char sp=SPACE;
  char q;
  register unsigned s,z;
  register const char *t;
  register char tt;

  t=w->c;
  s=w->u;
  tt=*t;
  z=f;

/*   if (s+1>(char *)m->me-(char *)m->m) */
/*     map_get(m,0,(char *)m->me-(char *)m->m1+s+1+m->o); */

  if (tt<SPACE && tt!=NL) {
    z|=tt;
    f=z;
    return;
  }

  if (z & BS)
    z &= ~BS;
  else 
    if (!IMPLIED_BS(tt)) 
      mem_in(m->m,&sp,sizeof(sp));

  if (!(z & ACAP)) 
    mem_in(m->m,t,s);
  else {

    if (z & CAP) {
      q=toupper(tt);
      z &= ~CAP;
    } else 
      q=tt;

    mem_in(m->m,&q,sizeof(q));
    s--;
    t++;

    if (z & CCAP) {
      for (;s--;t++) {
	q=toupper(*t);
	mem_in(m->m,&q,sizeof(q));
      }
      z &= ~CCAP;
    } else 
      mem_in(m->m,t,s);

  }

  f=z;

}


