aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFreeArtMan <=>2015-12-17 20:59:18 +0000
committerFreeArtMan <=>2015-12-17 20:59:18 +0000
commita61ad1cef9ef77f9afd67230df5470b6b55525be (patch)
treed8bae5fc932865e769e4965ce0817b6d107badf2
downloaddm-a61ad1cef9ef77f9afd67230df5470b6b55525be.tar.gz
dm-a61ad1cef9ef77f9afd67230df5470b6b55525be.zip
Initial commit
-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>
+