summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore4
-rw-r--r--Makefile20
-rw-r--r--ast.c0
-rw-r--r--ast.h0
-rw-r--r--darray.c335
-rw-r--r--darray.h53
-rw-r--r--debug.h69
-rw-r--r--dm.c259
-rw-r--r--dm.h16
-rw-r--r--dm_parser.c323
-rw-r--r--dm_parser.ragel95
-rw-r--r--exper.c15
-rw-r--r--mtable.c107
-rw-r--r--mtable.h36
-rw-r--r--syntax.c559
-rw-r--r--syntax.h123
-rw-r--r--test.h19
-rw-r--r--test/alleatures.dm10
-rw-r--r--test/elf32.bin1
-rw-r--r--test/elf32.md13
-rw-r--r--test/manyifs.md12
-rw-r--r--test/one_byte.dm3
-rw-r--r--test/range.md3
-rw-r--r--test/rangeif.md3
-rw-r--r--test/simpleif.md2
-rw-r--r--test/test.bin1
-rw-r--r--test/two_byte.md13
-rw-r--r--tokenizer.c141
-rw-r--r--tokenizer.h53
29 files changed, 2288 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..af4e307
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+*.o
+dm
+*.txt
+*.cc
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..11b00bd
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,20 @@
+PROJECT=dm
+CC=gcc
+CFLAGS=-std=c1x
+SOURCES=$(PROJECT)_parser.c darray.c tokenizer.c syntax.c mtable.c
+OBJECTS=$(SOURCES:.c=.o)
+
+all: clean ragel $(OBJECTS) $(PROJECT)
+
+$(PROJECT):
+ $(CC) $(CFLAGS) $(OBJECTS) $(PROJECT).c -o $(PROJECT)
+
+ragel:
+ ragel $(PROJECT)_parser.ragel
+
+%.o: %.c
+ $(CC) $(CFLAGS) -c $<
+
+clean:
+ rm -f $(PROJECT)
+ rm -f *.o
diff --git a/ast.c b/ast.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/ast.c
diff --git a/ast.h b/ast.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/ast.h
diff --git a/darray.c b/darray.c
new file mode 100644
index 0000000..eb9886f
--- /dev/null
+++ b/darray.c
@@ -0,0 +1,335 @@
+#include "darray.h"
+
+/*****************************************************************************/
+darray* darr_create(ssize_t data_size, ssize_t init_size)
+{
+ //PRINT("\n");
+ int i = 0;
+ darray *arr = NULL;
+
+ if ( init_size <= 0 )
+ {
+ printf("initial darray size should be >0\n");
+ goto error;
+ }
+
+ arr = malloc(sizeof(darray));
+ if ( arr == NULL )
+ {
+ printf("cannot allocalte mem\n");
+ goto error;
+ }
+ arr->max = init_size;
+
+ arr->data = malloc(init_size*sizeof(uint8_t *));
+ if (arr->data == NULL)
+ {
+ printf("Cannot allocate mem for data\n");
+ goto error;
+ }
+
+ for (i=0;i<init_size;i++)
+ {
+ arr->data[i] = NULL;
+ }
+
+ arr->end = 0;
+ arr->size = data_size;
+ arr->expand = DEFAULT_EXPAND_RATE;
+
+ return arr;
+
+error:
+ if ( arr != NULL )
+ {
+ free( arr );
+ arr = NULL;
+ }
+ //ERROR("\n");
+ return NULL;
+}
+
+
+/*****************************************************************************/
+void darr_destroy(darray *da)
+{
+ //PRINT("\n");
+ if(da)
+ {
+ if(da->data)
+ {
+ free(da->data);
+ }
+ free(da);
+ da = NULL;
+ }
+}
+
+
+/*****************************************************************************/
+void darr_clear(darray *da)
+{
+ //PRINT("\n");
+ int i = 0;
+ if(da->size > 0)
+ {
+ for(i = 0; i < da->max; i++)
+ {
+ if(da->data[i] != NULL)
+ {
+ free(da->data[i]);
+ }
+ }
+ }
+}
+
+/*****************************************************************************/
+void darr_clear_idx(darray *da, int idx)
+{
+ if ( idx > da->max )
+ {
+ return;
+ }
+ if (idx > da->end )
+ {
+ return;
+ }
+ if (da->data[idx] != NULL)
+ {
+ //PRINT("free=0x%08x\n", da->data[idx]);
+ free( da->data[idx] );
+ da->data[idx] = NULL;
+ }
+}
+
+/*****************************************************************************/
+int darr_expand(darray *da)
+{
+ //PRINT("\n");
+ size_t old_max = da->max;
+
+ if ( darr_resize(da, da->max + da->expand ) != 0 )
+ {
+ printf("Couldnt resize\n");
+ goto error;
+ }
+
+ memset(da->data + old_max, 0, da->expand + 1);
+ return 0;
+
+error:
+ //ERROR("\n");
+ return -1;
+}
+
+
+/*****************************************************************************/
+int darr_resize(darray *da, ssize_t size)
+{
+ //PRINT("\n");
+ int i = 0;
+ void *data = NULL;
+
+ if (size < 1)
+ {
+ printf("new size smaller then 1\n");
+ goto error;
+ }
+
+ //PRINT("max-0x%08x=new-0x%08x\n",da->max, size);
+
+ if (size < da->max)
+ {
+ i = da->max;
+ do
+ {
+ if ( da->data[i-1] != NULL )
+ {
+ free(da->data[i-1]);
+ da->data[i-1] = NULL;
+ }
+ i -= 1;
+ } while ( i-1 == size );
+ }
+
+ da->max = size;
+
+
+
+
+ data = realloc(da->data, da->max * sizeof(void *));
+ // check contents and assume realloc doesn't harm the original on error
+
+ if ( data == NULL )
+ {
+ printf("Cannot relocate data\n");
+ goto error;
+ }
+
+ da->data = data;
+
+ return 0;
+error:
+ //ERROR("\n");
+ return -1;
+}
+
+
+/*****************************************************************************/
+int darr_contract(darray *da)
+{
+ //PRINT("\n");
+ int sz = -1;
+
+ if ( da->end < da->expand )
+ {
+ sz = da->expand;
+ } else {
+ sz = da->end;
+ }
+
+ return darr_resize(da, sz + 1);
+}
+
+
+/*****************************************************************************/
+int darr_push(darray *da, void *val)
+{
+ //PRINT("\n");
+ if (da->data[da->end] != NULL)
+ {
+ //ERROR("\n");
+
+ }
+
+ da->data[da->end] = val;
+ da->end++;
+
+ if(darr_end(da) >= darr_max(da))
+ {
+ return darr_expand(da);
+ }
+
+ return 0;
+}
+
+
+/*****************************************************************************/
+void* darr_pop(darray *da)
+{
+ //PRINT("\n");
+ void *val = NULL;
+
+ if ( da->end-1 < 0 )
+ {
+ printf("Cannot pop value empty stack\n");
+ goto error;
+ }
+
+ val = darr_remove(da, da->end - 1);
+ da->end--;
+
+ if((darr_end(da) > (int)da->expand) &&
+ (darr_end(da) % da->expand))
+ {
+ darr_contract(da);
+ }
+
+ return val;
+
+error:
+ //ERROR("\n");
+ return NULL;
+}
+
+
+/*****************************************************************************/
+void darr_clear_destroy(darray *da)
+{
+ //PRINT("\n");
+ darr_clear(da);
+ darr_destroy(da);
+}
+
+
+/*****************************************************************************/
+int darr_set(darray *da, int idx, void *val)
+{
+ //PRINT("\n");
+ if ( idx >= da->max )
+ {
+ printf("setting param out of range\n");
+ goto error;
+ }
+ if(idx > da->end)
+ {
+ da->end = idx;
+ }
+
+ //PRINT("idx=%d ptr=%x\n",idx,val);
+
+ da->data[idx] = val;
+ return 0;
+error:
+ //ERROR("\n");
+ return -1;
+}
+
+
+/*****************************************************************************/
+void* darr_get(darray *da, int idx)
+{
+ //PRINT("\n");
+ if ( idx >= da->end )
+ {
+ printf("gettin value out of range\n");
+ goto error;
+ }
+ //PRINT("idx=%d\n",idx);
+ //PRINT("end=%d\n",da->end);
+ //PRINT("max=%d\n",da->max);
+ //PRINT("data=0x%x\n",da->data);
+ return da->data[idx];
+error:
+ //ERROR("\n");
+ return NULL;
+}
+
+
+/*****************************************************************************/
+void* darr_remove(darray *da, int idx)
+{
+ //PRINT("\n");
+ void *val = NULL;
+ val = da->data[idx];
+ da->data[idx] = NULL;
+ return val;
+}
+
+
+/*****************************************************************************/
+void* darr_new(darray *da)
+{
+ //PRINT("\n");
+ if ( da->size < 1 )
+ {
+ printf("data element size <1\n");
+ goto error;
+ }
+
+ return calloc(1, da->size);
+
+error:
+ //ERROR("\n");
+ return NULL;
+}
+
+/*****************************************************************************/
+int darr_isidx(darray *da, int idx)
+{
+ if ( idx < 0)
+ return 0;
+ if ( idx < da->end )
+ return 1;
+ return 0;
+}
diff --git a/darray.h b/darray.h
new file mode 100644
index 0000000..8d8f9e9
--- /dev/null
+++ b/darray.h
@@ -0,0 +1,53 @@
+/* Some thx goes to http://c.learncodethehardway.org/book/ex34.html */
+#ifndef __LIBADT_DARRAY_H
+#define __LIBADT_DARRAY_H
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+
+//#include "debug.h"
+//#include "mmm.h"
+
+#define DEFAULT_EXPAND_RATE 10
+
+typedef struct darray {
+ int end; //element amount. end <= max
+ int max; //maximal element number
+ size_t size; //single element size
+ size_t expand; //expand size
+ void **data;
+} darray;
+
+darray* darr_create(ssize_t data_size, ssize_t init_size);
+void darr_destroy(darray *da);
+void darr_clear(darray *da);
+void darr_clear_idx(darray *da, int idx);
+int darr_expand(darray *da);
+int darr_resize(darray *da, ssize_t size);
+int darr_contract(darray *da);
+int darr_push(darray *da, void *val);
+void* darr_pop(darray *da);
+void darr_clear_destroy(darray *da);
+int darr_set(darray *da, int idx, void *val);
+void* darr_get(darray *da, int idx);
+void* darr_remove(darray *da, int idx);
+void* darr_new(darray *da);
+int darr_isidx(darray *da, int idx);
+
+#define darr_last(A) ((A)->data[(A)->end - 1])
+#define darr_first(A) ((A)->data[0])
+#define darr_end(A) ((A)->end)
+#define darr_count(A) darr_end(A)
+#define darr_max(A) ((A)->max)
+#define darr_free(E) free((E))
+
+/*
+when do set it just overwrite data without checking if there is some or not
+if set more then max then no error and no resize happens
+when get element if error then NULL if value NULL then NULL how distinguish
+*/
+
+#endif
diff --git a/debug.h b/debug.h
new file mode 100644
index 0000000..fdcaf86
--- /dev/null
+++ b/debug.h
@@ -0,0 +1,69 @@
+#ifndef __RB_DEBUG_UTILS_H
+#define __RB_DEBUG_UTILS_H
+
+//what about kprintf?
+
+//config options
+#define PRINTF printf
+#define COLORIZE
+#define PRINT_LINENUM
+#define PRINT_FILENAME
+#define PRINT_DEBUG
+
+
+//use color
+#ifdef COLORIZE
+ #define D_COLOR "1;32m"
+ #define D_COLOR_S "\033[" D_COLOR
+ #define D_COLOR_E "\033[0m"
+ #define E_COLOR "1;31m"
+ #define E_COLOR_S "\033[" E_COLOR
+ #define E_COLOR_E "\033[0m"
+#else
+ #define D_COLOR
+ #define D_COLOR_S
+ #define D_COLOR_E
+ #define E_COLOR
+ #define E_COLOR_S
+ #define E_COLOR_E
+#endif
+
+//print debug line
+#ifdef PRINT_LINENUM
+ #define PRINT_LINE_F ":%03d "
+ #define PRINT_LINE_D __LINE__
+#else
+ #define PRINT_LINE_F ""
+ #define PRINT_LINE_D ""
+#endif
+
+//print
+#ifdef PRINT_FILENAME
+ #define PRINT_FILE_F "FILE:%s"
+ #define PRINT_FILE_D __FILE__
+#else
+ #define PRINT_FILE_F ""
+ #define PRINT_FILE_D ""
+#endif
+
+//print debug string
+#ifdef PRINT_DEBUG
+ #define PRINT_DEBUG_F "Debug: "
+#else
+ #define PRINT_DEBUG_F ""
+#endif
+
+#define PRINT( format, args ... ) PRINTF( D_COLOR_S PRINT_DEBUG_F \
+ PRINT_FILE_F PRINT_LINE_F format D_COLOR_E, PRINT_FILE_D, \
+ PRINT_LINE_D, ##args);
+
+#define ERROR( format, args ... ) PRINTF( E_COLOR_S PRINT_DEBUG_F \
+ PRINT_FILE_F PRINT_LINE_F format E_COLOR_E, PRINT_FILE_D, \
+ PRINT_LINE_D, ##args);
+
+#define PNL() PRINT("\n");
+
+#define ENL() ERROR("\n");
+
+
+#endif
diff --git a/dm.c b/dm.c
new file mode 100644
index 0000000..95a5763
--- /dev/null
+++ b/dm.c
@@ -0,0 +1,259 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+
+#include <sys/stat.h>
+
+#include "dm.h"
+#include "syntax.h"
+#include "mtable.h"
+
+
+/*****************************************************************************/
+int ast2tb( ast_root *ast, mt_table *mt )
+{
+ int i,j,k;
+ ast_range *arng = NULL;
+ mt_range *mrng = NULL;
+
+ for (i=0;i<ast->total_tokens;i++)
+ {
+ arng = ast->range[i];
+
+ if ((arng->val != NULL) && (arng->iff == NULL))
+ {
+ mrng = malloc(sizeof(mt_range));
+ memset(mrng,0,sizeof(mt_range));
+
+ mrng->start = arng->start;
+ mrng->end = arng->end;
+ mrng->val = arng->val->note;
+ mrng->val_sz = arng->val->size;
+
+ mt_add( mt, mrng );
+ }
+
+ if (arng->iff == NULL) continue;
+
+ for (j=0;j<arng->size_iff;j++)
+ {
+ unsigned char *cmp=NULL;
+
+ if (arng->iff[j]->expr->size_cmp > 0)
+ {
+ mrng = malloc(sizeof(mt_range));
+ memset(mrng,0,sizeof(mt_range));
+
+ //set start end positions
+ mrng->start = arng->start;
+ mrng->end = arng->end;
+
+ cmp = malloc(arng->iff[j]->expr->size_cmp);
+ for (k=0;k<arng->iff[j]->expr->size_cmp;k++)
+ cmp[k] = arng->iff[j]->expr->cmp[k]->val;
+ mrng->cmp = cmp;
+ mrng->cmp_sz = arng->iff[j]->expr->size_cmp;
+
+ if (arng->iff[j]->val != NULL)
+ {
+ mrng->val = arng->iff[j]->val->note;
+ mrng->val_sz = arng->iff[j]->val->size;
+ }
+
+ mt_add( mt, mrng );
+ }
+ }
+ }
+
+ return 0;
+}
+
+/*****************************************************************************/
+/* primitive matchin for loop, get table sorted then more advanced solution
+ * maycome */
+int match( mt_table *mt, unsigned char *buf, size_t size )
+{
+ //anonymouse function
+ int pr(char *str, int sz)
+ {
+ int i;
+ for (i=0;i<sz;i++)
+ printf("%c", str[i]);
+ }
+
+ int i;
+ mt_range *rng = NULL;
+
+ for ( i=0; i<mt_size(mt); i++ )
+ {
+ rng = mt_get(mt,i);
+ if (rng == NULL) continue;
+ if (rng->start >= 0 && rng->start < size)
+ {
+ if ( rng->cmp_sz == 0)
+ {
+ printf("Byte %d match ", rng->start);
+ pr(rng->val,rng->val_sz);
+ printf("\n");
+ } else if (rng->cmp_sz == 1)
+ {
+ if (buf[rng->start] == ((unsigned char*)rng->cmp)[0])
+ {
+ printf("Byte %d match ", rng->start);
+ pr(rng->val,rng->val_sz);
+ printf("\n");
+ }
+ } else
+ {
+ printf("Cmp %d size not yet supported\n",rng->cmp_sz);
+ }
+ }
+ }
+
+ return 0;
+}
+
+/*****************************************************************************/
+void helper( char *progname )
+{
+ printf("Usage: %s [OPTS] <filename>\n\n"
+ "-f [BINFILE]\n"
+ "-m [DATAMACHFILE]\n"
+ "Version: %s \n"
+ "Example: %s -f bin.bin -m test/one_byte.md\n"
+ , progname, __VER__, progname);
+}
+
+
+/*****************************************************************************/
+void version()
+{
+ printf("Datamatch Version: %s \n", __VER__);
+}
+
+
+/*****************************************************************************/
+int main(int argc, char **argv)
+{
+ FILE *fin = NULL;
+ FILE *fdm = NULL;
+ struct stat st;
+ token_list *tl = NULL;
+ mt_table *mt = NULL;
+ ast_root *ast = NULL;
+ int c;
+ char *input_file = NULL;
+ char *datamach_file = NULL;
+ char *buf = NULL;
+ char *binbuf = NULL;
+ ssize_t binbuf_size = 0;
+
+ /*get cmd args and set options */
+ while ( (c = getopt(argc, argv, "f:m:v")) != -1 )
+ {
+ switch(c)
+ {
+ case 'f':
+ input_file = optarg;
+ break;
+ case 'm':
+ datamach_file = optarg;
+ break;
+ case 'v':
+ version();
+ exit(1);
+ break;
+ default:
+ helper( argv[0] );
+ exit(1);
+ }
+ }
+
+ if ((datamach_file == NULL) || (input_file == NULL))
+ {
+ printf("Should be set -f and -m\n");
+ return -1;
+ }
+
+ if ( stat( datamach_file, &st) )
+ {
+ printf("Cannot stat file %s\n", datamach_file );
+ return -1;
+ }
+
+ if ( stat( input_file, &st) )
+ {
+ printf("Cannot stat file %s\n", input_file );
+ return -1;
+ }
+
+
+ tl = tl_create();
+ mt = mt_create();
+ if (mt == NULL)
+ {
+ printf("Cannot create table\n");
+ return -1;
+ }
+
+
+ fdm = fopen( datamach_file, "r+" );
+ if ( fdm )
+ {
+ fseek( fdm, 0, SEEK_SET );
+ stat( datamach_file, &st );
+ buf = malloc( st.st_size+1 ); memset( buf, 0, st.st_size+1 );
+ size_t r_size = fread( buf, 1, st.st_size, fdm );
+ if ( r_size > 0 )
+ {
+ int ret = parse_dm( tl, buf );
+ //printf("Datamatch %d %d bytes\n", ret, r_size );
+ } else
+ {
+ printf("ERR: while reading file %s [%d]\n", argv[1], r_size);
+ }
+ fclose( fdm );
+ } else
+ {
+ printf("ERR: Cannot open file\n");
+ return -1;
+ }
+
+ fin = fopen( input_file, "r+" );
+ if (fin)
+ {
+ fseek( fin, 0, SEEK_SET );
+ stat( input_file, &st );
+ binbuf = malloc( st.st_size );
+ memset( binbuf, 0, st.st_size );
+ binbuf_size = fread( binbuf, 1, st.st_size, fin );
+
+ fclose( fin );
+ } else
+ {
+ printf("ERR:Cannot open binary file\n\n");
+ return -1;
+ }
+
+ /* print tokens */
+ //printf("print token_list\n");
+ //tl_str( tl );
+ //printf("end token_list\n");
+ ast = ast_syntax( tl );
+ //printf("ast = 0x%08x\n", ast);
+
+ //print_ast( ast );
+ ast2tb( ast, mt );
+ //mt_print( mt );
+
+ match( mt, binbuf, binbuf_size );
+
+ tl_destroy( tl );
+ mt_destroy( mt );
+
+ if ( buf ) free( buf );
+ if ( binbuf ) free( binbuf );
+
+ return 0;
+} \ No newline at end of file
diff --git a/dm.h b/dm.h
new file mode 100644
index 0000000..1f27e57
--- /dev/null
+++ b/dm.h
@@ -0,0 +1,16 @@
+#ifndef __DM_H
+#define __DM_H
+
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+
+#include "darray.h"
+#include "tokenizer.h"
+
+#define __VER__ "0.3 beta"
+
+
+int parse_dm( token_list *tl, const char* );
+
+#endif \ No newline at end of file
diff --git a/dm_parser.c b/dm_parser.c
new file mode 100644
index 0000000..bfd829f
--- /dev/null
+++ b/dm_parser.c
@@ -0,0 +1,323 @@
+
+#line 1 "dm_parser.ragel"
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "dm.h"
+
+
+
+
+#define CTS(X) {if (!dm_current_tok)token_s = p; printf("%s ",#X);if (!dm_current_tok) dm_current_tok = TOK_##X;}
+#define CTE() {token_e = p;}
+#define TADD(T,S,E) {tl_add_tok(tl,T,S,E);}
+
+char *new_string( const char *start, const char *end )
+{
+ int str_s = end-start+1;
+ char *new_str=malloc( str_s+1 );
+ memcpy( new_str, start, str_s );
+ if ( new_str != NULL )
+ new_str[str_s]=0x0;
+ return new_str;
+}
+
+int print_token( char *s, char *e, int tok)
+{
+ char *p = new_string( s, e );
+ printf("t=%d,p=%s\n",tok,p);
+ free( p );
+ return 0;
+}
+
+
+
+#line 38 "dm_parser.c"
+static const char _dm_actions[] = {
+ 0, 1, 0, 1, 1, 1, 2, 1,
+ 3, 1, 4, 1, 5, 1, 6, 1,
+ 7, 1, 8, 1, 9, 1, 10, 1,
+ 11, 1, 12
+};
+
+static const char _dm_key_offsets[] = {
+ 0, 0, 8, 17, 23, 24, 36, 39,
+ 41
+};
+
+static const char _dm_trans_keys[] = {
+ 32, 39, 48, 57, 65, 90, 97, 122,
+ 32, 34, 39, 48, 57, 65, 90, 97,
+ 122, 48, 57, 65, 70, 97, 102, 102,
+ 32, 34, 38, 40, 41, 45, 48, 105,
+ 9, 10, 49, 57, 120, 48, 57, 48,
+ 57, 48, 57, 65, 70, 97, 102, 0
+};
+
+static const char _dm_single_lengths[] = {
+ 0, 2, 3, 0, 1, 8, 1, 0,
+ 0
+};
+
+static const char _dm_range_lengths[] = {
+ 0, 3, 3, 3, 0, 2, 1, 1,
+ 3
+};
+
+static const char _dm_index_offsets[] = {
+ 0, 0, 6, 13, 17, 19, 30, 33,
+ 35
+};
+
+static const char _dm_indicies[] = {
+ 0, 0, 0, 0, 0, 1, 0, 2,
+ 0, 0, 0, 0, 1, 4, 4, 4,
+ 3, 5, 1, 6, 7, 8, 9, 10,
+ 11, 12, 14, 6, 13, 1, 16, 13,
+ 15, 13, 15, 4, 4, 4, 17, 0
+};
+
+static const char _dm_trans_targs[] = {
+ 2, 0, 5, 5, 8, 5, 5, 1,
+ 5, 5, 5, 5, 6, 7, 4, 5,
+ 3, 5
+};
+
+static const char _dm_trans_actions[] = {
+ 0, 0, 9, 25, 0, 11, 7, 0,
+ 17, 13, 15, 19, 5, 0, 0, 23,
+ 0, 21
+};
+
+static const char _dm_to_state_actions[] = {
+ 0, 0, 0, 0, 0, 1, 0, 0,
+ 0
+};
+
+static const char _dm_from_state_actions[] = {
+ 0, 0, 0, 0, 0, 3, 0, 0,
+ 0
+};
+
+static const char _dm_eof_trans[] = {
+ 0, 0, 0, 4, 0, 0, 16, 16,
+ 18
+};
+
+static const int dm_start = 5;
+static const int dm_first_final = 5;
+static const int dm_error = 0;
+
+static const int dm_en_main = 5;
+
+
+#line 63 "dm_parser.ragel"
+
+
+int parse_dm( token_list *tl, const char *str )
+{
+ static uint8_t cs;
+ const int stacksize = 10;
+ int res=0, *top=0, *stack=NULL, act=0;
+ stack = malloc( sizeof(stack)*stacksize );
+ char *p=(char *)str, *pe = (char *)str + strlen( str ), *eof=NULL;
+ char *ts, *te = 0;
+
+ /*
+ variables used in state machine
+ */
+ char *token_s=NULL, *token_e=NULL;
+ char *value_s=NULL, *value_e=NULL;
+ int token_type=0;
+ int dm_current_tok = TOK_NONE;
+
+
+#line 138 "dm_parser.c"
+ {
+ cs = dm_start;
+ ts = 0;
+ te = 0;
+ act = 0;
+ }
+
+#line 83 "dm_parser.ragel"
+
+#line 148 "dm_parser.c"
+ {
+ int _klen;
+ unsigned int _trans;
+ const char *_acts;
+ unsigned int _nacts;
+ const char *_keys;
+
+ if ( p == pe )
+ goto _test_eof;
+ if ( cs == 0 )
+ goto _out;
+_resume:
+ _acts = _dm_actions + _dm_from_state_actions[cs];
+ _nacts = (unsigned int) *_acts++;
+ while ( _nacts-- > 0 ) {
+ switch ( *_acts++ ) {
+ case 1:
+#line 1 "NONE"
+ {ts = p;}
+ break;
+#line 169 "dm_parser.c"
+ }
+ }
+
+ _keys = _dm_trans_keys + _dm_key_offsets[cs];
+ _trans = _dm_index_offsets[cs];
+
+ _klen = _dm_single_lengths[cs];
+ if ( _klen > 0 ) {
+ const char *_lower = _keys;
+ const char *_mid;
+ const char *_upper = _keys + _klen - 1;
+ while (1) {
+ if ( _upper < _lower )
+ break;
+
+ _mid = _lower + ((_upper-_lower) >> 1);
+ if ( (*p) < *_mid )
+ _upper = _mid - 1;
+ else if ( (*p) > *_mid )
+ _lower = _mid + 1;
+ else {
+ _trans += (unsigned int)(_mid - _keys);
+ goto _match;
+ }
+ }
+ _keys += _klen;
+ _trans += _klen;
+ }
+
+ _klen = _dm_range_lengths[cs];
+ if ( _klen > 0 ) {
+ const char *_lower = _keys;
+ const char *_mid;
+ const char *_upper = _keys + (_klen<<1) - 2;
+ while (1) {
+ if ( _upper < _lower )
+ break;
+
+ _mid = _lower + (((_upper-_lower) >> 1) & ~1);
+ if ( (*p) < _mid[0] )
+ _upper = _mid - 2;
+ else if ( (*p) > _mid[1] )
+ _lower = _mid + 2;
+ else {
+ _trans += (unsigned int)((_mid - _keys)>>1);
+ goto _match;
+ }
+ }
+ _trans += _klen;
+ }
+
+_match:
+ _trans = _dm_indicies[_trans];
+_eof_trans:
+ cs = _dm_trans_targs[_trans];
+
+ if ( _dm_trans_actions[_trans] == 0 )
+ goto _again;
+
+ _acts = _dm_actions + _dm_trans_actions[_trans];
+ _nacts = (unsigned int) *_acts++;
+ while ( _nacts-- > 0 )
+ {
+ switch ( *_acts++ )
+ {
+ case 2:
+#line 1 "NONE"
+ {te = p+1;}
+ break;
+ case 3:
+#line 52 "dm_parser.ragel"
+ {te = p+1;}
+ break;
+ case 4:
+#line 53 "dm_parser.ragel"
+ {te = p+1;{/*printf("str = ");fwrite(ts,1,te-ts,stdout);printf("\n");*/TADD(TOK_STR,ts,te);}}
+ break;
+ case 5:
+#line 55 "dm_parser.ragel"
+ {te = p+1;{/*printf("if = ");fwrite(ts,1,te-ts,stdout);printf("\n");*/TADD(TOK_IF,ts,te);}}
+ break;
+ case 6:
+#line 56 "dm_parser.ragel"
+ {te = p+1;{/*printf("lbr = ");fwrite(ts,1,te-ts,stdout);printf("\n");*/TADD(TOK_LBR,ts,te);}}
+ break;
+ case 7:
+#line 57 "dm_parser.ragel"
+ {te = p+1;{/*printf("rbr = ");fwrite(ts,1,te-ts,stdout);printf("\n");*/TADD(TOK_RBR,ts,te);}}
+ break;
+ case 8:
+#line 58 "dm_parser.ragel"
+ {te = p+1;{/*printf("and = ");fwrite(ts,1,te-ts,stdout);printf("\n");*/TADD(TOK_EAND,ts,te);}}
+ break;
+ case 9:
+#line 59 "dm_parser.ragel"
+ {te = p+1;{/*printf("range = ");fwrite(ts,1,te-ts,stdout);printf("\n");*/TADD(TOK_RANGE,ts,te);}}
+ break;
+ case 10:
+#line 51 "dm_parser.ragel"
+ {te = p;p--;{/*printf("hex = ");fwrite(ts,1,te-ts,stdout);printf("\n");*/TADD(TOK_HEX,ts,te);}}
+ break;
+ case 11:
+#line 54 "dm_parser.ragel"
+ {te = p;p--;{/*printf("int = ");fwrite(ts,1,te-ts,stdout);printf("\n");*/TADD(TOK_INT,ts,te);}}
+ break;
+ case 12:
+#line 54 "dm_parser.ragel"
+ {{p = ((te))-1;}{/*printf("int = ");fwrite(ts,1,te-ts,stdout);printf("\n");*/TADD(TOK_INT,ts,te);}}
+ break;
+#line 279 "dm_parser.c"
+ }
+ }
+
+_again:
+ _acts = _dm_actions + _dm_to_state_actions[cs];
+ _nacts = (unsigned int) *_acts++;
+ while ( _nacts-- > 0 ) {
+ switch ( *_acts++ ) {
+ case 0:
+#line 1 "NONE"
+ {ts = 0;}
+ break;
+#line 292 "dm_parser.c"
+ }
+ }
+
+ if ( cs == 0 )
+ goto _out;
+ if ( ++p != pe )
+ goto _resume;
+ _test_eof: {}
+ if ( p == eof )
+ {
+ if ( _dm_eof_trans[cs] > 0 ) {
+ _trans = _dm_eof_trans[cs] - 1;
+ goto _eof_trans;
+ }
+ }
+
+ _out: {}
+ }
+
+#line 84 "dm_parser.ragel"
+
+ if ( cs == dm_error )
+ {
+ printf("ERR state [%d] pos[%d]:[%s]\n", res, p-str, p);
+ res = -1;
+ }
+
+ return res;
+}
+
+
+
diff --git a/dm_parser.ragel b/dm_parser.ragel
new file mode 100644
index 0000000..80c873b
--- /dev/null
+++ b/dm_parser.ragel
@@ -0,0 +1,95 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "dm.h"
+
+
+
+
+#define CTS(X) {if (!dm_current_tok)token_s = p; printf("%s ",#X);if (!dm_current_tok) dm_current_tok = TOK_##X;}
+#define CTE() {token_e = p;}
+#define TADD(T,S,E) {tl_add_tok(tl,T,S,E);}
+
+char *new_string( const char *start, const char *end )
+{
+ int str_s = end-start+1;
+ char *new_str=malloc( str_s+1 );
+ memcpy( new_str, start, str_s );
+ if ( new_str != NULL )
+ new_str[str_s]=0x0;
+ return new_str;
+}
+
+int print_token( char *s, char *e, int tok)
+{
+ char *p = new_string( s, e );
+ printf("t=%d,p=%s\n",tok,p);
+ free( p );
+ return 0;
+}
+
+
+%%{
+ machine dm;
+
+
+ hex = '0x' [a-fA-F0-9]+;
+ int = [0-9]+;
+ newline = '\n' >{CTS(NL)} @{CTE()};
+ if = 'if';
+ lbracket = '(';
+ rbracket = ')';
+ and = '&';
+ range = '-';
+ string = ('"' ([a-zA-Z0-9' '])+ '"');
+
+ sp = (' ' | '\t' | '\n');
+
+ main := |*
+ hex {/*printf("hex = ");fwrite(ts,1,te-ts,stdout);printf("\n");*/TADD(TOK_HEX,ts,te);};
+ sp {};
+ string {/*printf("str = ");fwrite(ts,1,te-ts,stdout);printf("\n");*/TADD(TOK_STR,ts,te);};
+ int {/*printf("int = ");fwrite(ts,1,te-ts,stdout);printf("\n");*/TADD(TOK_INT,ts,te);};
+ if {/*printf("if = ");fwrite(ts,1,te-ts,stdout);printf("\n");*/TADD(TOK_IF,ts,te);};
+ lbracket {/*printf("lbr = ");fwrite(ts,1,te-ts,stdout);printf("\n");*/TADD(TOK_LBR,ts,te);};
+ rbracket {/*printf("rbr = ");fwrite(ts,1,te-ts,stdout);printf("\n");*/TADD(TOK_RBR,ts,te);};
+ and {/*printf("and = ");fwrite(ts,1,te-ts,stdout);printf("\n");*/TADD(TOK_EAND,ts,te);};
+ range {/*printf("range = ");fwrite(ts,1,te-ts,stdout);printf("\n");*/TADD(TOK_RANGE,ts,te);};
+ *|;
+
+ write data;
+}%%
+
+int parse_dm( token_list *tl, const char *str )
+{
+ static uint8_t cs;
+ const int stacksize = 10;
+ int res=0, *top=0, *stack=NULL, act=0;
+ stack = malloc( sizeof(stack)*stacksize );
+ char *p=(char *)str, *pe = (char *)str + strlen( str ), *eof=NULL;
+ char *ts, *te = 0;
+
+ /*
+ variables used in state machine
+ */
+ char *token_s=NULL, *token_e=NULL;
+ char *value_s=NULL, *value_e=NULL;
+ int token_type=0;
+ int dm_current_tok = TOK_NONE;
+
+ %%write init;
+ %%write exec;
+
+ if ( cs == dm_error )
+ {
+ printf("ERR state [%d] pos[%d]:[%s]\n", res, p-str, p);
+ res = -1;
+ }
+
+ return res;
+}
+
+
+
diff --git a/exper.c b/exper.c
new file mode 100644
index 0000000..1bcf65d
--- /dev/null
+++ b/exper.c
@@ -0,0 +1,15 @@
+#define TOK_NONE 0
+#define TOK_HEX 1
+#define TOK_INT 2
+#define TOK_NL 3
+#define TOK_IF 4
+#define TOK_LBR 5
+#define TOK_RBR 6
+#define TOK_STR 7
+
+int dm_current_tok = TOK_NONE;
+
+#define CT(X) (dm_current_tok = TOK_##X;)
+
+CT(IF)
+CT(STR)
diff --git a/mtable.c b/mtable.c
new file mode 100644
index 0000000..7d705e8
--- /dev/null
+++ b/mtable.c
@@ -0,0 +1,107 @@
+#include "mtable.h"
+
+
+/*****************************************************************************/
+mt_table* mt_create()
+{
+ mt_table *mt = NULL;
+
+ mt = malloc( sizeof(mt_table) );
+ if (mt == NULL)
+ {
+ printf("Cannot allocate mem for mt_table\n");
+ return NULL;
+ }
+ memset(mt,0,sizeof(mt));
+
+ mt->table = darr_create( sizeof(mt_range), 100 );
+ if (mt->table == NULL)
+ {
+ printf("Cannot allocate ->table\n");
+ goto error;
+ }
+
+ return mt;
+
+error:
+ free( mt );
+ return NULL;
+
+}
+
+
+/*****************************************************************************/
+int mt_add( mt_table *mt, mt_range *rng )
+{
+ if (rng == NULL)
+ {
+ return -1;
+ }
+
+ if ( darr_push( mt->table, rng ) != 0 )
+ {
+ printf("Cannot add new table row\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+/*****************************************************************************/
+mt_range* mt_search( mt_table *mt, int pos )
+{
+ int i;
+ mt_range *el = NULL;
+
+ for (i=0; i<darr_end(mt->table); i++)
+ {
+ el = darr_get( mt->table, i );
+ if ((pos >= el->start) && (pos <= el->end))
+ {
+ return el;
+ }
+ }
+
+ return NULL;
+}
+
+
+/*****************************************************************************/
+int mt_print( mt_table *mt )
+{
+ int i;
+ mt_range *rng = NULL;
+
+ printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
+ printf("+ START + END + CMP + SIZE + VAL + SIZE +\n");
+ printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
+ for (i=0; i<darr_end(mt->table); i++)
+ {
+ rng = mt_get(mt,i);
+ if (rng == NULL)
+ continue;
+ printf("+ %8d + %8d + %08x + %8d + %08x + %8d +\n",
+ rng->start, rng->end, rng->cmp, rng->cmp_sz,
+ rng->val, rng->val_sz);
+ }
+ printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
+
+ return 0;
+}
+
+
+/*****************************************************************************/
+void mt_destroy( mt_table *mt )
+{
+ if ( mt == NULL )
+ {
+ return;
+ }
+
+ if ( mt->table != NULL)
+ {
+ darr_destroy( mt->table );
+ }
+
+ free( mt );
+}
diff --git a/mtable.h b/mtable.h
new file mode 100644
index 0000000..573f3e2
--- /dev/null
+++ b/mtable.h
@@ -0,0 +1,36 @@
+#ifndef __MTABLE_H
+#define __MTABLE_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#include "darray.h"
+#include "debug.h"
+
+typedef struct mt_range {
+ //range postiont start end
+ unsigned long start;
+ unsigned long end;
+ //cmp array start end
+ void *cmp;
+ int cmp_sz;
+ //note string
+ void *val;
+ int val_sz;
+} mt_range;
+
+typedef struct mt_table {
+ darray *table;
+} mt_table;
+
+mt_table* mt_create();
+int mt_add( mt_table *mt, mt_range *rng );
+mt_range* mt_search( mt_table *mt, int pos );
+int mt_print( mt_table *mt );
+void mt_destroy( mt_table *mt );
+
+#define mt_size(MT_TABLE) (darr_end((MT_TABLE)->table))
+#define mt_get(MT_TABLE,X) (darr_get((MT_TABLE)->table,X))
+
+#endif \ No newline at end of file
diff --git a/syntax.c b/syntax.c
new file mode 100644
index 0000000..510d735
--- /dev/null
+++ b/syntax.c
@@ -0,0 +1,559 @@
+#include "syntax.h"
+
+//token postion/type
+#define TP(POS) tl_tok_type(tl,(POS))
+#define TP_EQ(POS,TYPE) (tl_tok_type(tl,(POS)) == TYPE)
+#define TP_EQ2(POS,TYPE1,TYPE2) ((tl_tok_type(tl,(POS))==TYPE1)||(tl_tok_type(tl,(POS))==TYPE2))
+#define TP_NEQ(POS,TYPE) (tl_tok_type(tl,(POS)) != TYPE)
+#define TP_NEQ2(POS,TYPE1,TYPE2) ((tl_tok_type(tl,(POS))!=TYPE1)&&(tl_tok_type(tl,(POS))!=TYPE2))
+
+//check if enought tokens to parse
+#define TE(POS) (tl_size(tl) > (POS))
+
+
+/*****************************************************************************/
+ast_root* ast_syntax( token_list *tl )
+{
+ ast_root *ast_tree = NULL;
+ ast_range *rng = NULL;
+ tk_pos=0;
+
+ ast_tree = atrt_i();
+
+ while ( tk_pos < tl_size(tl) )
+ {
+ //current - INT|HEX next not RANGE
+ if (TP_EQ2(tk_pos,TOK_INT,TOK_HEX)
+ && TP_NEQ(tk_pos+1,TOK_RANGE))
+ {
+ rng = att_range( tl, tk_pos );
+ if (rng == NULL ) break;
+ atrt_a_range( &ast_tree, rng, 0 );
+ // current - INT|HEX next RANGE
+ } else if ( TP_EQ2(tk_pos,TOK_INT,TOK_HEX)
+ && TP_EQ(tk_pos+1,TOK_RANGE) )
+ {
+ rng = att_range( tl, tk_pos );
+ if (rng == NULL ) break;
+ atrt_a_range( &ast_tree, rng, 0 );
+ } else
+ {
+ printf("ERR:%d\n",tl_tok_type(tl,tk_pos));
+ printf("Syntax error\n");
+ break;
+ }
+ }
+
+ return ast_tree;
+}
+
+
+/*****************************************************************************/
+ast_if* att_if( token_list *tl, int pos )
+{
+ //PRINT("IF:pos->%d %d\n",tk_pos,pos);
+
+
+ ast_if *ret = NULL;
+ ast_expr *expr = NULL;
+ ast_value *val = NULL;
+
+ if ( TP_NEQ(pos,TOK_IF) )
+ {
+ printf("not if syntax error\n");
+ return NULL;
+ }
+ // SHOULD BE first LBR (INT|HEX) third RBR
+ if ((TP_EQ(pos+1,TOK_LBR)) &&
+ (TP_EQ2(pos+2,TOK_HEX,TOK_INT)) &&
+ (TP_EQ(pos+3,TOK_RBR)) )
+ {
+ expr = att_expr( tl, pos+1 );
+ pos = tk_pos;
+ val = att_value( tl, pos );
+ ret = ati_i();
+ ati_s_expr( &ret, expr );
+ ati_s_val( &ret, val );
+ } else
+ {
+ printf("invalid range\n");
+ return NULL;
+ }
+
+
+ return ret;
+}
+
+
+/*****************************************************************************/
+ast_range* att_range( token_list *tl, int pos )
+{
+ //PRINT("RNG:pos->%d %d\n",tk_pos,pos);
+ ast_range *ret = NULL;
+ ast_value *val = NULL;
+ ast_if *iff = NULL;
+
+
+ if ( TP_NEQ2(pos,TOK_HEX,TOK_INT) )
+ {
+ printf("range incorrect syntax\n");
+ return NULL;
+ }
+
+ //current HEX STR
+ if ( TP_EQ(pos+1,TOK_STR) )
+ {
+ ret = atrn_i();
+ atrn_s_rng0( &ret, tok2int(tl_get_tok(tl,pos)) );
+ val = att_value( tl, pos+1 );
+ if (val==NULL) return NULL;
+ atrn_s_val( &ret, val );
+ tk_pos = pos+2;
+ //current HEX IF ...
+ } else if ( TP_EQ(pos+1,TOK_IF) )
+ {
+ ret = atrn_i();
+ atrn_s_rng0( &ret, tok2int(tl_get_tok(tl,pos)));
+ iff = att_if( tl, pos+1 );
+ if (iff==NULL) return NULL;
+ atrn_a_if( &ret, iff );
+ //current HEX RNG HEX
+ } else if (TP_EQ(pos+1,TOK_RANGE) &&
+ (TP_EQ2(pos+2,TOK_HEX,TOK_INT)))
+ {
+ ret = atrn_i();
+ atrn_s_rng1( &ret, tok2int(tl_get_tok(tl,pos)), tok2int(tl_get_tok(tl,pos+2)));
+ if (TP_EQ(pos+3,TOK_STR))
+ {
+ val = att_value(tl,pos+3);
+ if (val==NULL) return NULL;
+ atrn_s_val( &ret, val );
+ tk_pos = pos+4;
+ } else if (TP_EQ(pos+3,TOK_IF))
+ {
+ iff = att_if( tl, pos+3 );
+ if (iff==NULL) return NULL;
+ atrn_a_if( &ret, iff );
+ }
+ } else
+ {
+ printf("wrong range syntax TOK=%d\n",tl_tok_type(tl,pos+1));
+ return NULL;
+ }
+
+ while (TE(tk_pos) && TP_EQ(tk_pos,TOK_IF) && (ret != NULL))
+ {
+ //PNL();
+ pos = tk_pos;
+ //PRINT("There is more ifs\n");
+ iff = att_if( tl, pos );
+ if (iff==NULL) return NULL;
+ atrn_a_if( &ret, iff );
+ //PNL();
+ }
+
+ return ret;
+}
+
+
+/*****************************************************************************/
+ast_expr* att_expr( token_list *tl, int pos )
+{
+ //PRINT("EXPR:pos->%d %d\n",tk_pos,pos);
+
+ ast_expr *ret = NULL;
+ ast_expr_cmp *cmp = NULL;
+
+ // SHOULD BE first LBR (INT|HEX) third RBR
+ if ( TP_NEQ(pos,TOK_LBR) )
+ {
+ printf("Missing ( syntax error\n");
+ return NULL;
+ }
+
+ if ( TP_NEQ(pos+2,TOK_RBR) )
+ {
+ printf("Missing ) syntax error\n");
+ return NULL;
+ }
+
+ ret = ate_i();
+ cmp = att_expr_cmp( tl, pos+1 );
+ if (cmp==NULL) return NULL;
+ ate_a_cmp( &ret, cmp );
+ tk_pos += 1;
+
+ return ret;
+}
+
+
+/*****************************************************************************/
+ast_expr_cmp* att_expr_cmp( token_list *tl, int pos )
+{
+ //PRINT("CMP:pos->%d %d\n",tk_pos,pos);
+ ast_expr_cmp *ret = NULL;
+
+ //current should be one HEX|INT
+ if (TP_EQ2(pos,TOK_HEX,TOK_INT))
+ {
+ ret = atec_i();
+ atec_s_val( &ret, tok2int(tl_get_tok(tl,pos)));
+ tk_pos = pos + 1;
+ } else
+ {
+ printf("Expression not INT not HEX\n");
+ return NULL;
+ }
+
+ return ret;
+}
+
+
+/*****************************************************************************/
+ast_expr_bit* att_expr_bit( token_list *tl, int pos )
+{
+
+}
+
+/*****************************************************************************/
+ast_value* att_value( token_list *tl, int pos )
+{
+ //PRINT("VAL:pos->%d %d\n", tk_pos, pos);
+ ast_value *val = NULL;
+ token *tok = NULL;
+
+ //current should be one STR
+ if (TP_NEQ(pos,TOK_STR))
+ {
+ printf("value incorrect syntax\n");
+ return NULL;
+ }
+
+ val = atv_i();
+ tok = tl_get_tok(tl,pos);
+ atv_s_note( &val, tok->s, (tok->e)-(tok->s) );
+ //PRINT("VAL[%.10s]\n",tok->s);
+ tk_pos = pos + 1;
+
+ return val;
+}
+
+
+/*****************************************************************************/
+ast_root* atrt_i()
+{
+ ast_root *ret = NULL;
+
+ ret = malloc( sizeof(ast_root) );
+ if (ret == NULL)
+ {
+ printf("Cannot alloc ast_root\n");
+ return NULL;
+ }
+ memset( ret, 0, sizeof(ast_root) );
+
+ return ret;
+}
+
+
+/*****************************************************************************/
+int atrt_a_range( ast_root **rt, ast_range *rng, int idx)
+{
+ //PNL();
+ (*rt)->range = realloc( (*rt)->range, sizeof(void*)*(*rt)->total_tokens+1 );
+ (*rt)->range[(*rt)->total_tokens] = rng;
+ (*rt)->total_tokens += 1;
+
+ return 0;
+}
+
+
+/*****************************************************************************/
+ast_range* atrn_i()
+{
+ ast_range *ret = NULL;
+
+ ret = malloc( sizeof(ast_range) );
+ if (ret == NULL)
+ {
+ printf("Cannot alloc ast_range\n");
+ return NULL;
+ }
+ memset( ret, 0, sizeof(ast_range) );
+
+ return ret;
+}
+
+
+/*****************************************************************************/
+int atrn_a_if( ast_range **rng, ast_if *iff )
+{
+ //PNL();
+ (*rng)->iff = realloc( (*rng)->iff, sizeof(void*)*(*rng)->size_iff+1 );
+ (*rng)->iff[(*rng)->size_iff] = iff;
+ (*rng)->size_iff += 1;
+ return 0;
+}
+
+
+/*****************************************************************************/
+int atrn_a_val( ast_range **rng, ast_value *val )
+{
+ (*rng)->val = val;
+
+ return 0;
+}
+
+
+/*****************************************************************************/
+int atrn_s_rng0( ast_range **rng, int value )
+{
+ (*rng)->range_type = 0;
+ (*rng)->start = value;
+ (*rng)->end = value;
+
+ return 0;
+}
+
+
+/*****************************************************************************/
+int atrn_s_rng1( ast_range **rng, unsigned long start, unsigned long end)
+{
+ (*rng)->range_type = 1;
+ (*rng)->start = start;
+ (*rng)->end = end;
+
+ return 0;
+}
+
+
+/*****************************************************************************/
+int atrn_s_val( ast_range **rng, ast_value *val )
+{
+ (*rng)->val = val;
+
+ return 0;
+}
+
+
+/*****************************************************************************/
+ast_if* ati_i()
+{
+ ast_if *ret = NULL;
+
+ ret = malloc( sizeof(ast_if) );
+ if (ret == NULL)
+ {
+ printf("Cannot alloc ast_if\n");
+ return NULL;
+ }
+ memset( ret, 0, sizeof(ast_if) );
+
+ return ret;
+}
+
+
+/*****************************************************************************/
+int ati_s_expr( ast_if **iff, ast_expr *expr )
+{
+ (*iff)->expr = expr;
+ return -1;
+}
+
+
+/*****************************************************************************/
+int ati_s_val( ast_if **iff, ast_value *val )
+{
+ (*iff)->val = val;
+ return -1;
+}
+
+
+/*****************************************************************************/
+ast_expr* ate_i()
+{
+ ast_expr *ret = NULL;
+
+ ret = malloc( sizeof(ast_expr) );
+ if (ret == NULL)
+ {
+ printf("Cannot alloc ast_expr\n");
+ return NULL;
+ }
+ memset( ret, 0, sizeof(ast_expr) );
+
+ return ret;
+}
+
+
+/*****************************************************************************/
+int ate_a_bit( ast_expr **expr, ast_expr_bit *bit )
+{
+ //PNL();
+ if ((*expr)->bit == NULL)
+ {
+ (*expr)->bit = malloc(sizeof(void *));
+ (*expr)->bit[0] = bit;
+ (*expr)->size_bit = 1;
+ } else
+ {
+ (*expr)->bit = realloc( (*expr)->bit, sizeof(void*)*((*expr)->size_bit+1) );
+ (*expr)->bit[(*expr)->size_bit] = bit;
+ (*expr)->size_bit += 1;
+ }
+
+ return 0;
+}
+
+
+/*****************************************************************************/
+int ate_a_cmp( ast_expr **expr, ast_expr_cmp *cmp )
+{
+ //PNL();
+ if ((*expr)->cmp == NULL)
+ {
+ (*expr)->cmp = malloc(sizeof(void *));
+ (*expr)->cmp[0] = cmp;
+ (*expr)->size_cmp = 1;
+ } else
+ {
+ (*expr)->cmp = realloc( (*expr)->cmp, sizeof(void*)*((*expr)->size_cmp+1) );
+ (*expr)->cmp[(*expr)->size_cmp] = cmp;
+ (*expr)->size_cmp += 1;
+ }
+
+ return 0;
+}
+
+
+/*****************************************************************************/
+int ate_eval( ast_expr *expr )
+{
+
+}
+
+
+/*****************************************************************************/
+ast_expr_bit* ateb_i()
+{
+ ast_expr_bit *ret = NULL;
+
+ ret = malloc( sizeof(ast_expr_bit) );
+ if (ret == NULL)
+ {
+ printf("Cannot alloc ast_expr_bit\n");
+ return NULL;
+ }
+ memset( ret, 0, sizeof(ast_expr_bit) );
+
+ return ret;
+}
+
+
+/*****************************************************************************/
+int ateb_s_mask( ast_expr_bit **expr, unsigned char mask )
+{
+ (*expr)->mask = mask;
+
+ return 0;
+}
+
+
+/*****************************************************************************/
+ast_expr_cmp* atec_i()
+{
+ ast_expr_cmp *ret = NULL;
+
+ ret = malloc( sizeof(ast_expr_cmp) );
+ if (ret == NULL)
+ {
+ printf("Cannot alloc ast_expr_cmp\n");
+ return NULL;
+ }
+ memset( ret, 0, sizeof(ast_expr_cmp) );
+
+ return ret;
+}
+
+
+/*****************************************************************************/
+int atec_s_val( ast_expr_cmp **expr, unsigned char val )
+{
+ (*expr)->val = val;
+ return 0;
+}
+
+
+/*****************************************************************************/
+ast_value* atv_i()
+{
+ ast_value *ret = NULL;
+
+ ret = malloc( sizeof(ast_value) );
+ if (ret == NULL)
+ {
+ printf("Cannot alloc ast_value\n");
+ return NULL;
+ }
+ memset( ret, 0, sizeof(ast_value) );
+
+ return ret;
+}
+
+
+/*****************************************************************************/
+int atv_s_note( ast_value **val, char *note, int size)
+{
+ (*val)->note = note;
+ (*val)->size = size;
+
+ return 0;
+}
+
+/*****************************************************************************/
+int print_ast( ast_root *root )
+{
+ int i,j,k;
+ ast_range *rng = NULL;
+
+ if ( root == NULL )
+ {
+ printf("Empty ast_root\n");
+ return -1;
+ }
+
+ for (i=0;i<root->total_tokens;i++)
+ {
+ printf("RANGE:%d\n",i );
+ rng = root->range[i];
+ if ( rng->range_type == 0 || rng->range_type == 1 )
+ {
+ printf("%d-%d:\n",rng->start, rng->end);
+ if (rng->val != NULL)
+ {
+ printf("\t[%.12s]\n",rng->val->note);
+ }
+ if (rng->iff != NULL)
+ {
+ printf("\tIF\n");
+ for (j=0;j<rng->size_iff;j++)
+ {
+ if (rng->iff[j]->expr != NULL)
+ {
+ printf("\t\tCMP:");
+ for (k=0;k<rng->iff[j]->expr->size_cmp;k++)
+ {
+ printf("0x%02x ",rng->iff[j]->expr->cmp[k]->val);
+ }
+ printf("\n");
+ }
+ if (rng->iff[j]->val != NULL)
+ {
+ printf("\t\tVAL:%.7s\n",rng->iff[j]->val->note);
+ }
+ }
+ }
+ }
+ }
+ return 0;
+} \ No newline at end of file
diff --git a/syntax.h b/syntax.h
new file mode 100644
index 0000000..9f2d224
--- /dev/null
+++ b/syntax.h
@@ -0,0 +1,123 @@
+#ifndef __SYNTAX_H
+#define __SYNTAX_H
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+
+
+#include "debug.h"
+#include "tokenizer.h"
+
+#define ALLOC_MEMSET(T,VAL) {VAL=malloc(sizeof(T));memset(VAL,0,sizeof(T));}
+
+
+typedef struct ast_range ast_range;
+typedef struct ast_if ast_if;
+typedef struct ast_value ast_value;
+typedef struct ast_expr ast_expr;
+typedef struct ast_expr_bit ast_expr_bit;
+typedef struct ast_expr_cmp ast_expr_cmp;
+
+//welcome to 90's
+//[TYPE]_[SET/GET/ADD/INIT]_[VALUE]
+//G -get
+//S -set
+//A - add
+//I - init
+//SZ-size
+//S - start
+//E - end
+
+//ATRT
+typedef struct ast_root
+{
+ int size;
+ int total_tokens;
+ ast_range **range;
+} ast_root;
+
+//ATRN
+typedef struct ast_range
+{
+ int range_type;
+ unsigned long start;
+ unsigned long end;
+ int next_type;
+ int size_iff;
+ ast_if **iff;
+ ast_value *val;
+} ast_range;
+
+//ATI
+typedef struct ast_if
+{
+ int eval;
+ ast_expr *expr;
+ ast_value *val;
+} ast_if;
+
+//ATEB
+typedef struct ast_expr_bit
+{
+ unsigned char mask;
+} ast_expr_bit;
+
+//ATEC
+typedef struct ast_expr_cmp
+{
+ unsigned char val;
+} ast_expr_cmp;
+
+//ATE
+typedef struct ast_expr
+{
+ int type;
+ int size_cmp;
+ int size_bit;
+ ast_expr_cmp **cmp;
+ ast_expr_bit **bit;
+} ast_expr;
+
+//ATV
+typedef struct ast_value
+{
+ int size;
+ char *note;
+
+} ast_value;
+
+static int tk_pos = 0;
+
+ast_root* ast_syntax( token_list *tl );
+ast_if* att_if( token_list *tl, int pos );
+ast_range* att_range( token_list *tl, int pos );
+ast_expr* att_expr( token_list *tl, int pos );
+ast_expr_cmp* att_expr_cmp( token_list *tl, int pos );
+ast_expr_bit* att_expr_bit( token_list *tl, int pos );
+ast_value* att_value( token_list *tl, int pos );
+ast_root* atrt_i();
+int atrt_a_range( ast_root **rt, ast_range *rng, int idx);
+ast_range* atrn_i();
+int atrn_a_if( ast_range **rng, ast_if *iff );
+int atrn_a_val( ast_range **rng, ast_value *val );
+int atrn_s_rng0( ast_range **rng, int value );
+int atrn_s_rng1( ast_range **rng, unsigned long start, unsigned long end);
+int atrn_s_val( ast_range **rng, ast_value *val );
+ast_if* ati_i();
+int ati_s_expr( ast_if **iff, ast_expr *expr );
+int ati_s_val( ast_if **iff, ast_value *val );
+ast_expr* ate_i();
+int ate_a_bit( ast_expr **expr, ast_expr_bit *bit );
+int ate_a_cmp( ast_expr **expr, ast_expr_cmp *cmp );
+int ate_eval( ast_expr *expr );
+ast_expr_bit* ateb_i();
+int ateb_s_mask( ast_expr_bit **expr, unsigned char mask );
+ast_expr_cmp* atec_i();
+int atec_s_val( ast_expr_cmp **expr, unsigned char val );
+ast_value* atv_i();
+int atv_s_note( ast_value **val, char *note, int size);
+int print_ast( ast_root *root );
+
+#endif \ No newline at end of file
diff --git a/test.h b/test.h
new file mode 100644
index 0000000..9364452
--- /dev/null
+++ b/test.h
@@ -0,0 +1,19 @@
+#define M(T) _Generic((T),int:12);
+
+typedef struct ast_range {int i;} ast_range;
+typedef struct ast_if ast_if;
+typedef struct ast_value ast_value;
+typedef struct ast_expr ast_expr;
+typedef struct ast_root ast_root;
+typedef struct ast_expr_cmp ast_expr_cmp;
+typedef struct ast_expr_bitwise ast_expr_bitwise;
+
+#define ALLOC_MEMSET(T,VAL) {VAL=malloc(sizeof(T));memset(VAL,0,sizeof(T));}
+
+
+
+int fun()
+{
+ char *root;
+ ALLOC_MEMSET(ast_range,root);
+} \ No newline at end of file
diff --git a/test/alleatures.dm b/test/alleatures.dm
new file mode 100644
index 0000000..ea3bda7
--- /dev/null
+++ b/test/alleatures.dm
@@ -0,0 +1,10 @@
+0x01-0x2 "Hello"
+
+0x010
+ if (0x01) "One"
+ if (0x02) "Two"
+ if (0x03) "Three"
+ if (0x40) "Forty"
+0x0aaa
+ if (&0x0001) "bit one"
+ if (&0x0112) "some more bits" \ No newline at end of file
diff --git a/test/elf32.bin b/test/elf32.bin
new file mode 100644
index 0000000..1c0b9f2
--- /dev/null
+++ b/test/elf32.bin
@@ -0,0 +1 @@
+ \ No newline at end of file
diff --git a/test/elf32.md b/test/elf32.md
new file mode 100644
index 0000000..d5ab688
--- /dev/null
+++ b/test/elf32.md
@@ -0,0 +1,13 @@
+0x0-0x3
+ "magic number"
+0x4
+ if (0x01) "32 bit elf"
+ if (0x02) "64 bit elf"
+0x5
+ if (0x01) "little endian"
+ if (0x02) "big endian"
+0x10
+ if (0x1) "relocatable ELF"
+ if (0x2) "executable ELF"
+ if (0x3) "shared ELF"
+ if (0x4) "Core ELF what that" \ No newline at end of file
diff --git a/test/manyifs.md b/test/manyifs.md
new file mode 100644
index 0000000..745d5ab
--- /dev/null
+++ b/test/manyifs.md
@@ -0,0 +1,12 @@
+0x01-0x2 "Hello"
+
+0x010
+ if (0x01) "One"
+ if (0x02) "Two"
+ if (0x03) "Three"
+ if (0x40) "Forty"
+0x012
+ if (0x01) "One"
+ if (0x02) "Two"
+ if (0x03) "Three"
+ if (0x40) "Forty" \ No newline at end of file
diff --git a/test/one_byte.dm b/test/one_byte.dm
new file mode 100644
index 0000000..deb59d8
--- /dev/null
+++ b/test/one_byte.dm
@@ -0,0 +1,3 @@
+0x000001 "first byte"
+ 0xa10f "second byte"
+ 3 "third byte" \ No newline at end of file
diff --git a/test/range.md b/test/range.md
new file mode 100644
index 0000000..fa0310f
--- /dev/null
+++ b/test/range.md
@@ -0,0 +1,3 @@
+0x1-0x2 "Header"
+0x3-0x4 "General info"
+0x3-0x5 "Hola" \ No newline at end of file
diff --git a/test/rangeif.md b/test/rangeif.md
new file mode 100644
index 0000000..82b03bd
--- /dev/null
+++ b/test/rangeif.md
@@ -0,0 +1,3 @@
+0x1-0x2 if (0x00) "Header"
+0x3-0x4 if (0x01) "General info"
+0x3-0x5 if (0x02) "Hola" \ No newline at end of file
diff --git a/test/simpleif.md b/test/simpleif.md
new file mode 100644
index 0000000..1a617c6
--- /dev/null
+++ b/test/simpleif.md
@@ -0,0 +1,2 @@
+0x12 if (0x01) "asdinfo"
+0x14 if (0x02) "hello" \ No newline at end of file
diff --git a/test/test.bin b/test/test.bin
new file mode 100644
index 0000000..8de8f43
--- /dev/null
+++ b/test/test.bin
@@ -0,0 +1 @@
+
diff --git a/test/two_byte.md b/test/two_byte.md
new file mode 100644
index 0000000..ad71609
--- /dev/null
+++ b/test/two_byte.md
@@ -0,0 +1,13 @@
+0x00 "zero byte"
+0x01 if ( 0x00 )
+ "first byte"
+0x0a "second byte"
+0x3 "third byte"
+0x04 if (0x01)
+ "array"
+
+0x2 - 0x3 if ( 0x12 )
+"if array"
+
+0x2 if ( & 0x12 )
+"if array" \ No newline at end of file
diff --git a/tokenizer.c b/tokenizer.c
new file mode 100644
index 0000000..a7c73e2
--- /dev/null
+++ b/tokenizer.c
@@ -0,0 +1,141 @@
+#include "tokenizer.h"
+
+
+/*****************************************************************************/
+token* token_create()
+{
+ token *t = NULL;
+ t = malloc(sizeof(token));
+ memset(t,0,sizeof(token));
+ return t;
+}
+
+
+/*****************************************************************************/
+int token_set( token **tok, int val, char *s, char *e )
+{
+ if ( tok == NULL )
+ {
+ printf("token is NULL\n");
+ return -1;
+ }
+
+ if ( !(TOK_IN_RANGE(val)) )
+ {
+ printf("Token value not in range\n");
+ return -1;
+ }
+
+ (*tok)->token = val;
+ (*tok)->s = s;
+ (*tok)->e = e;
+
+ return 0;
+}
+
+
+/*****************************************************************************/
+token_list* tl_create()
+{
+ token_list *tl = NULL;
+
+ tl = malloc( sizeof(token_list) );
+ if (tl == NULL)
+ {
+ printf("Cannot alloc mem\n");
+ goto error;
+ }
+ memset(tl, 0, sizeof(token_list));
+
+ tl->list = darr_create( sizeof(token), 100 );
+ if (tl->list == NULL)
+ {
+ printf("cannot create ->list\n");
+ goto error;
+ }
+
+ return tl;
+
+error:
+ return NULL;
+}
+
+
+/*****************************************************************************/
+int tl_add_tok( token_list *tl, int t, char *s, char *e )
+{
+ token *tok = NULL;
+ tok = token_create();
+ if (tok == NULL)
+ {
+ printf("Cannot add token\n");
+ return -1;
+ }
+ token_set( &tok, t, s, e );
+ darr_push( tl->list, (void *)tok );
+ return 0;
+}
+
+
+/*****************************************************************************/
+char* tl_str( token_list *tl )
+{
+ int len = 128;
+ int p = 0;
+ char *s = NULL;
+ int i = 0;
+ //s = malloc( len );
+ //s[p] = 0;
+
+
+ for (i=0; i<darr_end(tl->list); i++)
+ {
+ token *t = (token *)darr_get(tl->list, i);
+ //printf("t=0x%x\n",t);
+ if ( t != NULL )
+ {
+ printf("%02d:TOK:0x%x s:0x%08x e:0x%08x\n",i,t->token,t->s,t->e);
+ }
+ }
+
+ return s;
+error:
+ return NULL;
+}
+
+
+/*****************************************************************************/
+void tl_destroy( token_list *tl )
+{
+ if ( tl == NULL )
+ return;
+ if ( tl->list != NULL )
+ {
+ darr_clear_destroy( tl->list );
+ }
+}
+
+
+/*****************************************************************************/
+int tl_size( token_list *tl )
+{
+ return darr_end( tl->list );
+}
+
+
+int tok2int( token *tok )
+{
+ char str[128];
+ int sz = tok->e - tok->s;
+ memcpy(str,tok->s,sz);
+ str[sz] = 0;
+ //printf("!%s %d\n",str,strtol(str,NULL,16));
+ return strtol(str,NULL,16);
+}
+
+
+char *tok2str( token *tok )
+{
+
+}
+
diff --git a/tokenizer.h b/tokenizer.h
new file mode 100644
index 0000000..1d3acdb
--- /dev/null
+++ b/tokenizer.h
@@ -0,0 +1,53 @@
+#ifndef __TOKENIZER_H
+#define __TOKENIZER_H
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "darray.h"
+
+#define TOK_NONE 0
+#define TOK_HEX 1
+#define TOK_INT 2
+#define TOK_NL 3
+#define TOK_IF 4
+#define TOK_LBR 5
+#define TOK_RBR 6
+#define TOK_STR 7
+#define TOK_EAND 8
+#define TOK_RANGE 9
+
+#define TOK2STR(X) TOK_#X
+
+/*not best way how to define*/
+#define TOK_IN_RANGE(TOK) ((TOK_HEX>=0)&&(TOK_RANGE<=TOK_RANGE))
+
+typedef struct token
+{
+ int token;
+ char *s, *e;
+} token;
+
+typedef struct token_list
+{
+ darray *list;
+} token_list;
+
+token* token_create();
+int token_set( token **tok, int val, char *s, char *e );
+
+token_list* tl_create();
+int tl_add_tok( token_list *tl, int t, char *s, char *e );
+char* tl_str( token_list *tl );
+void tl_destroy( token_list *tl );
+int tl_size( token_list *tl );
+
+#define tl_tok_type(TL,IDX) (((token *)(darr_get((TL)->list,IDX)))->token)
+#define tl_get_tok(TL,IDX) ((token *)(darr_get((TL)->list,IDX)))
+
+int tok2int( token *tok );
+char *tok2str( token *tok );
+
+#endif \ No newline at end of file