From 7bc4e7a1a2ff299cd749ebebca146f7fee36f1ce Mon Sep 17 00:00:00 2001
From: Sven Robertz <sven@cs.lth.se>
Date: Mon, 15 Apr 2013 11:37:09 +0200
Subject: [PATCH] split parser stack into val_ and ptr_ + added
 signature_name_length to work around handling varint lengths

---
 lib/c/experimental/labcomm_sig_parser.c | 142 ++++++++++++++----------
 lib/c/experimental/labcomm_sig_parser.h |   6 +-
 2 files changed, 89 insertions(+), 59 deletions(-)

diff --git a/lib/c/experimental/labcomm_sig_parser.c b/lib/c/experimental/labcomm_sig_parser.c
index a56081f..62477d3 100644
--- a/lib/c/experimental/labcomm_sig_parser.c
+++ b/lib/c/experimental/labcomm_sig_parser.c
@@ -56,25 +56,44 @@ static int unpack_varint(unsigned char *buf, unsigned int idx, unsigned char *si
         return res;
 }
 
-void dumpStack(buffer *b) {
+void dumpValStack(buffer *b) {
 #ifdef DEBUG_STACK
 	int i;
-	printf("=== stack: ");
+	printf("=== value stack: ");
 	for(i=0; i<STACK_SIZE; i++) { //HERE BE DRAGONS
-		printf("%2.2x ", b->stack[i]);
+		printf("%2.2x ", b->val_stack[i]);
 	}
-	printf("    top==%d\n", b->top);
+	printf("    top==%d\n", b->val_top);
+#endif
+}
+void dumpPtrStack(buffer *b) {
+#ifdef DEBUG_STACK
+	int i;
+	printf("=== pointer stack: ");
+	for(i=0; i<STACK_SIZE; i++) { //HERE BE DRAGONS
+		printf("%2.2x ", b->ptr_stack[i]);
+	}
+	printf("    top==%d\n", b->ptr_top);
 #endif
 }
 
-void push(buffer *b, void* e) {
-	b->stack[b->top]=e;
-	b->top=b->top-1;
-	dumpStack(b);
+void push_val(buffer *b, unsigned int e) {
+	b->val_stack[b->val_top]=e;
+	b->val_top=b->val_top-1;
+	dumpValStack(b);
+}
+unsigned int pop_val(buffer *b) {
+	b->val_top=b->val_top+1;
+	return b->val_stack[b->val_top];
+}
+void push_ptr(buffer *b, void* e) {
+	b->ptr_stack[b->ptr_top]=e;
+	b->ptr_top=b->ptr_top-1;
+	dumpPtrStack(b);
 }
-void* pop(buffer *b) {
-	b->top=b->top+1;
-	return b->stack[b->top];
+void* pop_ptr(buffer *b) {
+	b->ptr_top=b->ptr_top+1;
+	return b->ptr_stack[b->ptr_top];
 }
 	
 int init_buffer(buffer *b, size_t size, size_t stacksize) {
@@ -83,11 +102,15 @@ int init_buffer(buffer *b, size_t size, size_t stacksize) {
 	b->size = 0;
 	b->idx = 0;
 
-	b->stack = calloc(stacksize, sizeof(b->stack));
 	b->stacksize = stacksize;
-	b->top = stacksize-1;
 
-	return b->c == NULL || b->stack == NULL;
+	b->val_stack = calloc(stacksize, sizeof(b->val_stack));
+	b->val_top = stacksize-1;
+
+	b->ptr_stack = calloc(stacksize, sizeof(b->ptr_stack));
+	b->ptr_top = stacksize-1;
+
+	return b->c == NULL || b->val_stack == NULL || b->ptr_stack == NULL;
 }
 
 int read_file(FILE *f, buffer *b) {
@@ -143,19 +166,24 @@ void getStr(buffer *b, char *dest, size_t size) {
 }
 
 unsigned int signatures_length[MAX_SIGNATURES];
+unsigned int signatures_name_length[MAX_SIGNATURES];
 unsigned char signatures_name[MAX_SIGNATURES][MAX_NAME_LEN]; //HERE BE DRAGONS: add range checks
 unsigned char signatures[MAX_SIGNATURES][MAX_SIG_LEN]; 
 
 unsigned int get_signature_len(unsigned int uid){
 	return signatures_length[uid-LABCOMM_USER];
 }
-unsigned char* get_signature_name(unsigned int uid){
-	return &signatures_name[uid-LABCOMM_USER][1];
-}
 unsigned char* get_signature(unsigned int uid){
 	return signatures[uid-LABCOMM_USER];
 }
 
+unsigned int get_signature_name_len(unsigned int uid){
+	return signatures_name_length[uid-LABCOMM_USER];
+}
+unsigned char* get_signature_name(unsigned int uid){
+	return signatures_name[uid-LABCOMM_USER];
+}
+
 labcomm_signature_t sig_ts[MAX_SIGNATURES];
 
 labcomm_signature_t *get_sig_t(unsigned int uid) 
@@ -267,17 +295,17 @@ int do_parse(buffer *d) {
 	if(type == TYPE_DECL ) {
 		advancen(d, nbytes);
 		accept_user_id(d);
-		unsigned int uid = (unsigned int) (unsigned long) pop(d);
+		unsigned int uid = pop_val(d);
 		VERBOSE_PRINTF(", name = ");
 		accept_string(d);
-		pop(d); // ignore, for now. 
+		pop_val(d); // ignore length, for now. 
 #ifdef RETURN_STRINGS
-		char *str = (char *) pop(d);
+		char *str = (char *) pop_ptr(d);
 		free(str);
 #endif
 		VERBOSE_PRINTF(" : ");
 		accept_type(d);
-		unsigned int type = (unsigned int) (unsigned long) pop(d);
+		unsigned int type = pop_val(d);
 
 		//push(d, type);
 		VERBOSE_PRINTF("\n");
@@ -288,23 +316,23 @@ int do_parse(buffer *d) {
 		VERBOSE_PRINTF("sample_decl ");
 		accept_user_id(d);
 		unsigned int nstart = d->idx;
-		unsigned int uid = (unsigned int) (unsigned long) pop(d);
+		unsigned int uid = pop_val(d);
 		labcomm_signature_t *newsig = get_sig_t(uid);
 		newsig->type = type;
 		VERBOSE_PRINTF(", name = ");
 		accept_string(d);
 		unsigned int start = d->idx;
-		unsigned int nlen = (unsigned int) (unsigned long) pop(d);
+		unsigned int nlen = pop_val(d);
 #ifdef RETURN_STRINGS
-		char *str = (char *) pop(d);
+		char *str = (char *) pop_ptr(d);
 		free(str);
 #endif
 		unsigned char lenlen = labcomm_varint_sizeof(nlen);
 		accept_type(d);
 		//printf(" : ");
 		//unsigned int dt = pop(d);
-		pop(d); // ignore type, for now
-		unsigned int enc_size = (unsigned int) (unsigned long) pop(d);
+		pop_val(d); // ignore type, for now
+		unsigned int enc_size = pop_val(d);
 		unsigned int end = d->idx;
 		unsigned int len = end-start;
 
@@ -318,8 +346,8 @@ int do_parse(buffer *d) {
 		}
 
 		if(nlen < MAX_NAME_LEN) { // leave 1 byte for terminating NULL
-			signatures_name[uid-LABCOMM_USER][0] = nlen;
-			memcpy(signatures_name[uid-LABCOMM_USER], &d->c[nstart+lenlen-1], nlen+1);
+			signatures_name_length[uid-LABCOMM_USER] = nlen;
+			memcpy(signatures_name[uid-LABCOMM_USER], &d->c[nstart+lenlen], nlen);
 			signatures_name[uid-LABCOMM_USER][nlen+1]=0;
 			newsig->name = signatures_name[uid-LABCOMM_USER];
 		} else {
@@ -355,7 +383,7 @@ static int accept_user_id(buffer *d){
 	if(uid >= LABCOMM_USER) {
 		advancen(d, nbytes);
 		VERBOSE_PRINTF("uid = %x ", uid);
-		push(d, (void *) (unsigned long) uid);
+		push_val(d, uid);
 		return TRUE;
 	} else {
 		return FALSE;
@@ -368,11 +396,11 @@ static int accept_string(buffer *d){
 	getStr(d, str, len); 
 	VERBOSE_PRINTF("%s", str);
 #ifdef RETURN_STRINGS
-	push(d, str);
+	push_ptr(d, str);
 #else
 	free(str);
 #endif
-	push(d, (void *) (unsigned long) len);
+	push_val(d, len);
 	return TRUE;
 }
 static int accept_type(buffer *d){
@@ -382,43 +410,43 @@ static int accept_type(buffer *d){
 		case TYPE_BOOLEAN :
 			VERBOSE_PRINTF("boolean");
 			advancen(d, nbytes);
-			push(d, (void *) (unsigned long) 1);
+			push_val(d, 1);
 			break;
 		case TYPE_BYTE :
 			VERBOSE_PRINTF("byte");
 			advancen(d, nbytes);
-			push(d, (void *) (unsigned long) 1);
+			push_val(d,  1);
 			break;
 		case TYPE_SHORT :
 			VERBOSE_PRINTF("short");
 			advancen(d, nbytes);
-			push(d, (void *) (unsigned long) 2);
+			push_val(d,  2);
 			break;
 		case TYPE_INTEGER :
 			VERBOSE_PRINTF("integer");
 			advancen(d, nbytes);
-			push(d, (void *) (unsigned long) 4);
+			push_val(d,  4);
 			break;
 		case TYPE_LONG :
 			VERBOSE_PRINTF("long");
 			advancen(d, nbytes);
-			push(d, (void *) (unsigned long) 8);
+			push_val(d,  8);
 			break;
 		case TYPE_FLOAT :
 			VERBOSE_PRINTF("float");
 			advancen(d, nbytes);
-			push(d, (void *) (unsigned long) 4);
+			push_val(d,  4);
 			break;
 		case TYPE_DOUBLE :
 			VERBOSE_PRINTF("double");
 			advancen(d, nbytes);
-			push(d, (void *) (unsigned long) 8);
+			push_val(d,  8);
 			break;
 		case TYPE_STRING :
 			VERBOSE_PRINTF("string");
 			advancen(d, nbytes);
 			buffer_set_varsize(d);
-			push(d, (void *) (unsigned long)0);
+			push_val(d, 0);
 			break;
 		case ARRAY_DECL :
 			accept_array_decl(d);
@@ -430,10 +458,10 @@ static int accept_type(buffer *d){
 			break;
 		default :
 			printf("accept_basic_type default (type==%x) should not happen\n", type);
-			push(d, (void *) (unsigned long)0);
+			push_val(d, 0);
 			return FALSE;
 	}
-	push(d,(void *) (unsigned long) type);
+	push_val(d, type);
 	return TRUE;
 }
 
@@ -460,24 +488,24 @@ static int accept_array_decl(buffer *d){
 		}
 		VERBOSE_PRINTF(" of ");
 		accept_type(d);
-		unsigned int et= (unsigned int) (unsigned long) pop(d); 
-		unsigned int es= (unsigned int) (unsigned long) pop(d);
+		unsigned int et= pop_val(d); 
+		unsigned int es= pop_val(d);
 #ifdef DEBUG
 		printf("accept_array_decl: et = %x\n", et);
 #endif
 		if(numVar == 0) {
 #ifdef DEBUG
-			printf("size=%d, es=%d\n", size, s);
+			printf("size=%d, es=%d\n", size, es);
 #endif
-			push(d, (void *) (unsigned long) (size*es));
+			push_val(d,  (size*es));
 		}
 		//pop(d);
-		push(d,(void *) (unsigned long) tid);
+		push_val(d, tid);
 		return TRUE;
 	} else {
 		printf("accept_array_decl: type=%x, should not happen\n",tid);
-		push(d,(void *) (unsigned long) 0);
-		push(d,(void *) (unsigned long) tid);
+		push_val(d, 0);
+		push_val(d, tid);
 		return FALSE;
 	}
 }
@@ -495,35 +523,35 @@ static int accept_struct_decl(buffer *d){
 		for(i=0; i<nf; i++) {
 			VERBOSE_PRINTF("\t");
 			accept_field(d);
-			fieldsizes += (unsigned int) (unsigned long) pop(d);
+			fieldsizes += pop_val(d);
 		}
-		push(d, (void *) (unsigned long) fieldsizes);
-//		push(d, (void *) (unsigned long)tid);
+		push_val(d, fieldsizes);
+//		push_val(d, tid);
 		return TRUE;
 	} else {
 		printf("accept_struct_decl: type=%x, should not happen\n",tid);
-		push(d, (void *) (unsigned long)0);
-		push(d, (void *) (unsigned long) tid);
+		push_val(d, 0);
+		push_val(d, tid);
 		return FALSE;
 	}
 }
 static int accept_field(buffer *d){
 	VERBOSE_PRINTF("field ");
 	accept_string(d);
-	pop(d); // ignore length, for now
+	pop_val(d); // ignore length, for now
 #ifdef RETURN_STRINGS
-		char *str = (char *) pop(d);
+		char *str = (char *) pop_ptr(d);
 		free(str);
 #endif
 	VERBOSE_PRINTF(" : ");
 	accept_type(d);
-	pop(d); // ignore type, for now
+	pop_val(d); // ignore type, for now
 	//push(d, pop(d) == NOP
 	VERBOSE_PRINTF("\n");
 }
 static int accept_sample_data(buffer *d){
 	accept_user_id(d);
-	unsigned int uid = (unsigned int) (unsigned long) pop(d);	
+	unsigned int uid = pop_val(d);	
 	printf("sample data... %x\n", uid);
 #ifdef DEBUG
 	dump_signature(uid);
diff --git a/lib/c/experimental/labcomm_sig_parser.h b/lib/c/experimental/labcomm_sig_parser.h
index d7f994f..6e51645 100644
--- a/lib/c/experimental/labcomm_sig_parser.h
+++ b/lib/c/experimental/labcomm_sig_parser.h
@@ -65,9 +65,11 @@ typedef struct {
 	size_t size;
 	size_t capacity;
 	unsigned int idx;
-	void** stack;
+	unsigned int val_top;
+	int * val_stack;
+	unsigned int ptr_top;
+	void** ptr_stack;
 	size_t stacksize;
-	unsigned int top;
 	int current_decl_is_varsize;
 } buffer;
 
-- 
GitLab