#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;
}