summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--irc_parse.c293
-rw-r--r--irc_parse.h51
-rw-r--r--util.c33
-rw-r--r--util.h11
4 files changed, 388 insertions, 0 deletions
diff --git a/irc_parse.c b/irc_parse.c
new file mode 100644
index 0000000..98820a3
--- /dev/null
+++ b/irc_parse.c
@@ -0,0 +1,293 @@
+#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;
+}
+
+
+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;
+} \ No newline at end of file
diff --git a/irc_parse.h b/irc_parse.h
new file mode 100644
index 0000000..4933f43
--- /dev/null
+++ b/irc_parse.h
@@ -0,0 +1,51 @@
+#ifndef __IRC_PARSE_H
+#define __IRC_PARSE_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+
+#include "util.h"
+
+//points to one token in da string
+#define IRC_TKT_NONE 0
+#define IRC_TKT_HOST 1
+#define IRC_TKT_CMD 2
+#define IRC_TKT_PARAM 3
+typedef struct irc_token_el
+{
+ int type;
+ int size;
+ char *token;
+} irc_token_el;
+
+#define IRC_TK_MAX_SIZE 100
+typedef struct irc_token
+{
+ int size; //how many tokens
+ int max_size; //allocate token spaces
+ irc_token_el **tk_list;
+} irc_token;
+
+
+
+//create default token list, with prealocated, token structures
+irc_token* token_create();
+//create new string(with extra byte that have NULL at the end), for token andd to list
+int token_add(irc_token *tk, char *s, char *e);
+//compare token by index with string
+int token_cmp(irc_token *tk, int idx, char *str);
+//return new string that could be freed
+char* token_new_str(irc_token *tk, int idx);
+//number of tokens
+int token_len(irc_token *tk);
+//clean all tokens
+void token_destroy(irc_token *tk);
+
+//return number of parse tokens
+irc_token* irc_parse(char *str, int sz);
+
+
+#endif \ No newline at end of file
diff --git a/util.c b/util.c
new file mode 100644
index 0000000..20ad6d8
--- /dev/null
+++ b/util.c
@@ -0,0 +1,33 @@
+#include "util.h"
+
+char *alloc_new_str_s(char *str, size_t size)
+{
+ char *ret = NULL;
+
+ if (str == NULL)
+ {
+ return NULL;
+ }
+
+ //1MB is enought
+ if (size > (1024*1024))
+ {
+ return NULL;
+ }
+
+ ret = malloc(size+1);
+ if (ret == NULL)
+ {
+ return NULL;
+ }
+
+ memcpy(ret, str, size);
+ ret[size] = 0;
+
+ return ret;
+}
+
+char *alloc_new_str(char *str)
+{
+ return alloc_new_str_s(str, strlen(str));
+} \ No newline at end of file
diff --git a/util.h b/util.h
new file mode 100644
index 0000000..fd6bbfd
--- /dev/null
+++ b/util.h
@@ -0,0 +1,11 @@
+#ifndef __UTIL_H
+#define __UTIL_H
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+char *alloc_new_str_s(char *str, size_t size);
+char *alloc_new_str(char *str);
+
+#endif \ No newline at end of file