#include "all.h"

int token_init(void);
int subscript(void);

#define true (!false)
#define false 0
#define add_tok(pp1,n) \
	(*ntok)++; \
	(*tok)[*ntok] = outbuff; \
	for (tj=0;tj<n;tj++) { \
		if (in_quote) *(outbuff+tj) = *(pp1+tj);\
		else *(outbuff+tj) = toupper(*(pp1+tj)); \
		if (*(outbuff+tj) == '"') if (*(outbuff+tj-1) != '\\') { \
			if (in_quote==true) in_quote = false; \
			else in_quote = true; \
		} \
	} \
	in_quote = false; \
	outbuff = outbuff + (n); \
	*(outbuff++) = '\0';
static char term_table1[256];
static char term_table2[256];
static char term_table3[256];
static char *term_table;
static int table_loaded;
char *find_non_term();
char *find_non_space();
char *find_term();
int in_quote;
int spmode;
/* typedef char (*(*TOKENS)[500]);  */

/*--------------------------------------------------------------------------*/

token_norm()
{
	if (table_loaded==false) token_init();
	term_table = &term_table1[0];
	spmode = false;
}
token_space()
{
	if (table_loaded==false) token_init();
	term_table = &term_table2[0];
	spmode = true;
}
token_equal()
{
	if (table_loaded==false) token_init();
	term_table = &term_table3[0];
	spmode = false;
}
token_init()
{
	int i;
	term_table = &term_table1[0];
	table_loaded = true;
	{auto char *termset=" 	,-+*)(<>=/!^@";
	for (i=0;i<=255;i++) {
		if (strchr(termset,i)!=NULL) {
			term_table1[i]=true;
		}
	}}
	{auto char *termset=" 	!";
		for (i=0;i<=255;i++) {
			if (strchr(termset,i)!=NULL) {
				term_table2[i]=true;
			}
		}
	}
	{auto char *termset=" 	,+*)(<>=/!^@";
		for (i=0;i<=255;i++) {
			if (strchr(termset,i)!=NULL) {
				term_table3[i]=true;
			}
		}
	}
}
token(char *lin,TOKENS tok,int *ntok,char *outbuff)
{
int i,j,jj;
int tj;
char *cp;
char *p2;
	*ntok = 0;
	in_quote = false;
	if (table_loaded==false) token_init();
	cp = lin;
	cp = find_non_space(cp);
	while (*cp!=0) {
		if (*cp==' ' || *cp=='	') {
			*cp = ' ';
			cp = find_non_space(cp);
		}
		if (*cp == '!') goto endofline;
		p2 = find_term(cp);
		jj = p2-cp+1;
		if (jj==0) goto endofline;
		add_tok(cp,jj);
		cp = p2 + 1 ;
		if (*ntok>280) subscript();
	}
endofline:;
	if (*ntok>0) {
		if ( (*(*tok)[*ntok])=='\n' ) (*ntok)--;
		if (strcmp((*tok)[*ntok]," ")==0) (*ntok)--;
		if (*ntok>0) p2 =  (*tok)[*ntok] + strlen((*tok)[*ntok])  - 1;
		if (*p2==10) *p2 = 0;
	}
}
/*--------------------------------------------------------------------------*/
char *find_non_space(char *cp)
{
	for ( ; *cp!=0 ; cp++ )  {
		if (*cp!=' ' && *cp!='	') break;
	}
	return cp;
}
/*--------------------------------------------------------------------------*/
char *find_term(char *cp)
{
char *start;
	start = cp;
/*	if (*cp=='"') {
		cp++;
		for (; *cp!=0 ; cp++ )  {
			if (*cp=='"') break;
		}
		return cp;
	} */
	for (; *cp!=0 ; cp++ )  {
		if (*cp == '"') {
			cp++;
			for (; *cp!=0 ; cp++ )  {
				if (*cp=='"') if (*(cp-1)!='\\') break;
			}
		}
		if (term_table[*cp]==true) break;
	}
	if (cp>start) return cp-1;
	if (*cp==' ' || *cp=='	') return cp-1;
	if (*cp==0) return cp-1;
	return cp;
}
/*--------------------------------------------------------------------------*/
int subscript(void)
{
	gprint("Subscript out of range in tokenizer (use shorter lines) \n");
}

token_data(char *lin,char *tk[],int *ntok,char *outbuff)
{
	char *s;
	s = strtok(lin," ,=\t\n\x0a\x0c\x0d");
	*ntok = 0;
	for (;s!=NULL;) {
		if (*s == '"' || *s == '!' || *s == ';') goto endofline;
		*ntok += 1;
		strcpy(outbuff,s);
		strupr(outbuff);
		tk[*ntok] = outbuff;
		outbuff = outbuff + strlen(outbuff) + 1;
		s = strtok(NULL," ,=\t\n\x0a\x0c\x0d");
	}
endofline:;

}

