aboutsummaryrefslogblamecommitdiffstats
path: root/irc_parse.c
blob: d7ccd034a768e3b459f908d4751871f9677257c9 (plain) (tree)































































































































                                                                                      































                                                                                         





























































































































































                                                                              
                          





                                               
#include "irc_parse.h"

/*mvar things*/
//shitty macro
#define MVAR_ALLOC_STRC(VNAME,VTYPE,VRET)\
VTYPE *VNAME;\
VNAME=malloc(sizeof(VTYPE));\
if ((VNAME)==NULL){\
VRET\
}\
memset(VNAME,0,sizeof(VTYPE));

#define MVAR_ALLOC_ARR(VNAME,VTYPE,VSZ,VRET)\
VTYPE *VNAME;\
VNAME=malloc(sizeof(VTYPE)*(VSZ));\
if ((VNAME)==NULL){\
VRET\
}\
memset(VNAME,0,sizeof(VTYPE)*(VSZ));

/**/

irc_token* token_create()
{
	MVAR_ALLOC_STRC(ret,irc_token,{
		return NULL;
	});

	ret->size = 0;
	ret->max_size = IRC_TK_MAX_SIZE; //should be enought

	MVAR_ALLOC_ARR(reg_tk_list,irc_token_el*,ret->max_size,{
		free(ret);
		return NULL;
	});

	ret->tk_list = reg_tk_list;

	return ret;
}

//? maybe return number of index?

int token_add(irc_token *tk, char *s, char *e)
{
	int ret = -1;


	//as there irc usually have no more then 512 bytes
	if ((e-s)>512)
	{
		return -1;
	}

	MVAR_ALLOC_STRC(token,irc_token_el,{
		return -1;
	});

	int sz=e-s;
	token->type = IRC_TKT_NONE;
	token->size = sz;
	token->token = malloc(sz+1); //blow
	memcpy(token->token,s,token->size);
	token->token[token->size] = 0x0;

	//dont support more tokens then original size, for now
	if (tk->size == IRC_TK_MAX_SIZE)
	{
		printf("Cant add token, no space\n");
		return -1;
	}

	tk->tk_list[tk->size] = token;
	tk->size += 1;
	ret = 0;

	return ret;
}


int token_cmp(irc_token *tk, int idx, char *str)
{
	int ret = -1;

	if ((idx>=tk->size) || (idx<0))
	{
		return -1;
	}

	if (strncmp(tk->tk_list[idx]->token,str,strlen(tk->tk_list[idx]->token)) != 0)
	{
		return 0;
	}
	ret = 1;

	return ret;
}


char* token_new_str(irc_token *tk, int idx)
{
	char *ret = NULL;

	if (tk->size < idx )
	{
		return NULL;
	}

	if (idx < 0)
	{
		return NULL;
	}

	ret = alloc_new_str_s(tk->tk_list[idx]->token,tk->tk_list[idx]->size);

	return ret;
}


int token_len(irc_token *tk)
{
	int ret = -1;

	ret = tk->size;

	return ret;
}

irc_token* token_cpy_new(irc_token *tk)
{
	int i = 0;
	irc_token *ret=NULL;

	if (tk == NULL)
	{
		return NULL;
	}

	ret = token_create();
	if (ret == NULL)
	{
		return NULL;
	}

	ret->size = tk->size;
	ret->max_size = tk->max_size;
	for (i=0;i<tk->size;i++)
	{
		irc_token_el *te = NULL;
		te = malloc(sizeof(irc_token_el));
		te->type = tk->tk_list[i]->type;
		te->size = tk->tk_list[i]->size;
		te->token = alloc_new_str_s(tk->tk_list[i]->token, tk->tk_list[i]->size);
		ret->tk_list[i] = te;
		te = NULL;
	}

	return ret;
}


void token_destroy(irc_token *tk)
{
	if (tk != NULL)
	{
		int i;
		for (i=0;i<tk->size;i++)
		{
			free(tk->tk_list[i]->token);
			free(tk->tk_list[i]);
		}

		free(tk->tk_list);
		free(tk);
	}
}

#define IRC_P_START 1
#define IRC_P_START_WORD 2
#define IRC_P_CONTINUE 3
#define IRC_P_MESSAGE 4
#define IRC_P_END 5
irc_token* irc_parse(char *str, int sz)
{
	irc_token *ret=NULL;

	int j=-1;
	int state=IRC_P_START;
	char *iter = str;
	char *st=NULL,*en=NULL;
	int tok_cnt=0;

	if (str[0] != ':')
	{
		return NULL;
	}

	ret = token_create();
	if (ret == NULL)
	{
		printf("Cant allocate token array\n");
		return NULL;
	}

	for (j=0;j<sz;j++)
	{

		
		switch(state)
		{
		case IRC_P_START:
			//printf("S %d %02x\n",j,iter[j]);
			//if begining is just empty space continue
			if (iter[j]==' ')
			{
				break;
			}
			if (iter[j]=='\0')
			{
				//if first byte zero then nothing to do
				state = IRC_P_END;
				break;
			}
			//parse first word
			state = IRC_P_START_WORD;
			break;
		case IRC_P_START_WORD:
			//printf("W");
			//tok[tok_cnt].s = iter+j;
			st = iter+j;
			if (iter[j]==' ')
			{
				//tok[tok_cnt].e = iter+j-1;
				en = iter+j-1;
				tok_cnt += 1;
				state = IRC_P_START;
				break;
			}
			if (iter[j]=='\0')
			{
				//tok[tok_cnt].e = iter+j-1;
				en = iter+j;
				token_add(ret, st, en);
				tok_cnt += 1;
				state = IRC_P_END;
				break;
			}
			if (iter[j]==':')
			{
				//tok[tok_cnt].s = iter+j;
				st = iter+j;
				state = IRC_P_MESSAGE;
				break;
			}
			state = IRC_P_CONTINUE;
			break;
		case IRC_P_CONTINUE:
			//printf("C");
			if ((iter[j]!=' ')&&(iter[j]!='\0'))
			{
				state = IRC_P_CONTINUE;
				break;
			}
			if (iter[j]=='\0')
			{
				//tok[tok_cnt].e = iter+j-1;
				en = iter+j;
				token_add(ret,st,en);
				tok_cnt += 1;
				state = IRC_P_END;
				break;
			}
			if (iter[j]==' ')
			{
				//tok[tok_cnt].e = iter+j-1;
				en = iter+j;
				token_add(ret,st,en);
				tok_cnt += 1;
				state = IRC_P_START_WORD;
				break;
			}
			printf("Unknown state\n");
			break;
		case IRC_P_MESSAGE:
			//printf("M");
			if ((iter[j]=='\0')||(iter[j]=='\n')||(iter[j]=='\r'))
			{
				//tok[tok_cnt].e = iter+j-1;
				en = iter+j;
				token_add(ret,st,en);
				tok_cnt += 1;
				state = IRC_P_END;
				break;
			}
			state = IRC_P_MESSAGE;
			break;
		case IRC_P_END:
			//printf("E\n");
			break;
		default:
			printf("ERR STATE %d\n",state);
			return NULL;
		};
		
	}
	if ((state==IRC_P_CONTINUE)||(state==IRC_P_MESSAGE))
	{
		//tok[tok_cnt].e = iter+j-1;
		en = iter+j;
		token_add(ret,st,en);
		tok_cnt += 1;
	}
	for (j=0;j<tok_cnt;j++)
	{
		//write(0,tok[j].s,tok[j].e-tok[j].s+1);
		//*(tok[j].e+1)=0x0;
		//write(0,"]\n",2);
	}
	if (tok_cnt < 2 ) 
	{
		printf("Not enought tokens\n");
	};

	return ret;
}