rev 399 - in trunk: include/prothon modules/Prosist src

SVN User <[email protected]> Thu, 22 Apr 2004 14:50:50 -0400
Newsgroups gmane.comp.lang.prothon.cvs
Message-ID <[email protected]>
Author: mark
Date: 2004-04-22 14:50:47 -0400 (Thu, 22 Apr 2004)
New Revision: 399

Modified:
   trunk/include/prothon/prothon.h
   trunk/include/prothon/prothon_dll.h
   trunk/modules/Prosist/Prosist.c
   trunk/src/builtins-core.c
   trunk/src/builtins-dict.c
   trunk/src/object.c
   trunk/src/object.h
Log:
Prosist can now save an object tree, code to load the
tree is half coded

Modified: trunk/include/prothon/prothon.h
===================================================================
--- trunk/include/prothon/prothon.h	2004-04-21 08:16:22 UTC (rev 398)
+++ trunk/include/prothon/prothon.h	2004-04-22 18:50:47 UTC (rev 399)
@@ -1117,6 +1117,9 @@
 int get_obj_rdacc(obj_p obj);
 int get_obj_wracc(obj_p obj);
 
+// DUMP: dump object store details to debug text file
+// Object tree starting at specified object is dumped to the debug text file.
+void dump(isp ist, char* dumpfilename, obj_p obj);
 
 #ifdef __cplusplus
 }

Modified: trunk/include/prothon/prothon_dll.h
===================================================================
--- trunk/include/prothon/prothon_dll.h	2004-04-21 08:16:22 UTC (rev 398)
+++ trunk/include/prothon/prothon_dll.h	2004-04-22 18:50:47 UTC (rev 399)
@@ -114,6 +114,7 @@
 	obj_p		(*new_dict_obj)(isp ist, int initial_size);
 	int			(*proto_len)(isp ist, obj_p obj);
 	obj_p		(*proto_item)(isp ist, obj_p obj, int i);
+	void		(*dump)(isp ist, char* dumpfilename, obj_p obj);
 
 	void*		(*pr_malloc)(size_t nbytes);
 	void*		(*pr_realloc)(void *p, size_t nbytes);
@@ -293,6 +294,7 @@
 #define set_archived	 	(*services->set_archived)
 #define clr_archived	 	(*services->clr_archived)
 #define is_archived	 		(*services->is_archived)
+#define dump		 		(*services->dump)
 
 #endif // OBJECT_H
 

Modified: trunk/modules/Prosist/Prosist.c
===================================================================
--- trunk/modules/Prosist/Prosist.c	2004-04-21 08:16:22 UTC (rev 398)
+++ trunk/modules/Prosist/Prosist.c	2004-04-22 18:50:47 UTC (rev 399)
@@ -66,6 +66,7 @@
 
 typedef struct {
 	apr_dbm_p	db;
+	apr_pool_t*	pool;
 	obj_p		root;
 	psid_t		nextid;
 	obj_p		id_to_idobj;
@@ -142,19 +143,45 @@
 #define ADD_BUF_END()   pr_free(_buf)
 
 //******************************** load_dbm_int *******************************
-i32_t load_dbm_int(char* key) {
-	return 0;
+i32_t load_dbm_int(psrec_p psrecp, char* key) {
+	apr_status_t aprerr;
+	apr_datum_t key_d, value;
+	ADD_BUF_DECLARE;
+
+	ADD_BUF_START();
+	ADD_STR(key);
+	ADD_BUF_TO_DATUM(key_d);
+
+	aprerr = apr_dbm_fetch(psrecp->db, key_d, &value);
+	IF_APR_DBM_ERR(psrecp->db, "loading int value ", key_d.dptr);
+	ADD_BUF_END();
+	return atoi(value.dptr);
 }
 
 //******************************** store_dbm_int ******************************
-void store_dbm_int(char* key, i32_t val) {
+void store_dbm_int(psrec_p psrecp, char* key, i32_t val) {
+	apr_status_t aprerr;
+	apr_datum_t key_d, value;
+	ADD_BUF_DECLARE;
 
+	ADD_BUF_START();
+	ADD_STR(key);
+	ADD_BUF_TO_DATUM(key_d);
+	ADD_BUF_START();
+	ADD_NUM(val);
+	ADD_BUF_TO_DATUM(value);
+	aprerr = apr_dbm_store(psrecp->db, key_d, value);
+	IF_APR_DBM_ERR(psrecp->db, "storing int value ", key_d.dptr);
+printf("key: %s\n", key_d.dptr);
+printf("val: %s\n\n", value.dptr);
+	ADD_BUF_END();
 }
 
 //******************************** obj_to_id ********************************
 psid_t obj_to_id(isp ist, psrec_p psrecp, obj_p obj) {
 	obj_p id_obj = dict_item(ist, psrecp->obj_to_id, obj); if_exc_return -1;
 	if (!id_obj) {
+		dump(ist, "obj-to-id.txt", obj);
 		raise_exception(ist, ProsistExc_OBJ, "obj_to_id called on obj with no id");
 		return -1;
 	}
@@ -174,6 +201,19 @@
 	return TRUE;
 }
 
+//******************************** id_registered_QUES *************************
+int id_registered_QUES(isp ist, psrec_p psrecp, obj_p id_obj) {
+	obj_p obj = dict_item(ist, psrecp->id_to_obj, id_obj);
+	if_exc_return FALSE;
+	if (!obj) {
+		obj = NEW_OBJ(NULL);
+		dict_add(ist, psrecp->obj_to_id, obj, id_obj); if_exc_return FALSE;
+		dict_add(ist, psrecp->id_to_obj, id_obj, obj); 
+		return FALSE;
+	}
+	return TRUE;
+}
+
 //******************************** apr_str ************************************
 apr_datum_t apr_str(char* str){
 	apr_datum_t apr_str;
@@ -182,8 +222,116 @@
 	return apr_str;
 }
 
-//******************************** load_object ********************************
-obj_p load_object(isp ist, psrec_p psrecp ) {
+//******************************** append_ids *********************************
+void append_ids(isp ist, psrec_p psrecp, obj_p idlist, psid_t id) {
+	apr_status_t aprerr;
+	apr_datum_t key, value;
+	char *p, *end;
+	ADD_BUF_DECLARE;
+
+	ADD_BUF_START();
+	ADD_NUM(id);
+	ADD_BUF_TO_DATUM(key);
+	ADD_BUF_START();
+	aprerr = apr_dbm_fetch(psrecp->db, key, &value);
+	IF_APR_DBM_ERR(psrecp->db, "loading obj value ", key.dptr);
+	p = value.dptr;
+	end = p + value.dsize;
+	ADD_BUF_END();
+
+	while (p < end) {
+		switch (*p) {
+			case '`': {
+				int i=0, mlen, module_flg = TRUE;
+				char *module, *name;
+				obj_p module_obj, obj, id_tuple;
+				mlen = max(8, (int) value.dsize);
+				module = pr_malloc(mlen);
+				for(p++; *p != '.'; p++) module[i++] = *p;
+				module[i] = 0;
+				if (module[0] == '*')
+					module_flg = FALSE;
+				name = pr_malloc(value.dsize - i);
+				for(i=0,p++; p < end; p++) name[i++] = *p;
+				name[i] = 0;
+				// do auto-import here XXX
+				if (module_flg)	
+					module_obj = get_attr(ist, OBJ(MODULES), sym(ist, module));
+				else
+					module_obj = OBJ(OBJECT);
+				if_exc_return;
+				obj = get_attr(ist, module_obj, sym(ist, name)); if_exc_return;
+				if (!obj) {
+					raise_exception(ist, ProsistExc_OBJ, "identity object %s not found in module %s", name, module);
+					return;
+				}
+				id_tuple = get_attr(ist, obj, SYM(__ID__)); if_exc_return;
+				if (!id_tuple) {
+					raise_exception(ist, ProsistExc_OBJ, "identity object is missing id tuple");
+					return;
+				}
+				dict_add(ist, psrecp->id_to_idobj, id_tuple, obj); if_exc_return;
+				dict_add(ist, psrecp->idobj_to_id, obj, id_tuple); if_exc_return;
+				break;
+			}
+			case 'p': {
+				obj_p id_obj;
+				psid_t n;
+				while(*p++ != ';') {
+					for(n=0; *p != ',' && *p != ';'; p++)
+						n = n*10 + *p - '0';
+					id_obj = NEW_INT(n);
+					if(!id_registered_QUES(ist, psrecp, id_obj))
+						list_append(ist, idlist, id_obj);
+				}
+				break;
+			}
+			case 'a': {
+				obj_p id_obj;
+				psid_t n;
+				while(*p++ != ';') {
+					while(*p++ != ':');
+					for(n=0; *p != ',' && *p != ';'; p++)
+						n = n*10 + *p - '0';
+					id_obj = NEW_INT(n);
+					if(!id_registered_QUES(ist, psrecp, id_obj))
+						list_append(ist, idlist, id_obj);
+				}
+				break;
+			}
+			case 'l': {
+				obj_p id_obj;
+				int n;
+				while(++p < end) {
+					for(n=0; *p != ',' && p < end; p++)
+						n = n*10 + *p - '0';
+					id_obj = NEW_INT(n);
+					if(!id_registered_QUES(ist, psrecp, id_obj))
+						list_append(ist, idlist, id_obj);
+				}
+				return;
+			}
+			case 'i':
+			case 's':
+				return;
+			default:
+				raise_exception(ist, ProsistExc_OBJ, "invalid record from db: %s", key.dptr);
+				return;
+		}
+	}
+}
+
+//******************************** load_db ************************************
+obj_p load_db(isp ist, psrec_p psrecp) {
+	int idx = 0;
+	obj_p idlist = new_list_obj(ist, 20);
+		
+	append_ids(ist, psrecp, idlist, 0); if_exc_return NULL;
+	for (; idx < (int) list_len(ist, idlist); idx++) {
+		psid_t id = (psid_t) (list_item(ist, idlist, idx)->data.i64);
+		append_ids(ist, psrecp, idlist, id); if_exc_return NULL;
+	}
+
 	return NULL;
 }
 
@@ -193,7 +341,7 @@
 	apr_datum_t key, value;
 	obj_p id_tuple, proxy_obj;
 	psid_t id;
-	int i, plen, added_attr;
+	int i, plen, added_attr = FALSE;
 	ADD_BUF_DECLARE;
 
 	id = obj_to_id(ist, psrecp, obj); if_exc_return;
@@ -215,6 +363,7 @@
 		ADD_STR(s2);
 		ADD_BUF_TO_DATUM(value);
 		aprerr = apr_dbm_store(psrecp->db, key, value);
+		IF_APR_DBM_ERR(psrecp->db, "storing id object ", value.dptr);
 
 printf("key: %s\n", key.dptr);
 printf("val: %s\n\n", value.dptr);
@@ -228,41 +377,41 @@
 		return;
 	}
 	ADD_BUF_START();
-	plen = proto_len(ist, obj);
+	plen = proto_len(ist, proxy_obj);
+	if (plen) ADD_CHR('p');
 	for(i=0; i < plen; i++) {
-		psid_t id = obj_to_id(ist, psrecp, proto_item(ist, obj, i)); if_exc_return;
-		ADD_CHR('p');
+		psid_t id = obj_to_id(ist, psrecp, proto_item(ist, proxy_obj, i)); if_exc_return;
 		ADD_NUM(id);
 		if (i < plen-1) ADD_CHR(',') 
 		else            ADD_CHR(';'); 
 	}
-	if (!obj->has_attrs) {
-		attr_key_t akey = attr_first_key(ist, obj);
+	if (!proxy_obj->has_attrs) {
+		attr_key_t akey = attr_first_key(ist, proxy_obj);
 		while(akey) {
 			ADD_CHR('a');
 			ADD_STR(key_to_symstr(ist, akey));
 			ADD_CHR(':');
-			ADD_REF(attr_value_by_key(ist, obj, akey));
+			ADD_REF(attr_value_by_key(ist, proxy_obj, akey));
 			ADD_CHR(',');
 			added_attr = TRUE;
-			akey = attr_next_key(ist, obj, akey);
+			akey = attr_next_key(ist, proxy_obj, akey);
 		}
 	}
 	if (added_attr) { _idx--; ADD_CHR(';'); }
-	if (obj->data_type == DATA_TYPE_IMMDATA) {
+	if (proxy_obj->data_type == DATA_TYPE_IMMDATA) {
 		ADD_CHR('i');
-		ADD_NUM(obj->imm_data_len);
+		ADD_NUM(proxy_obj->imm_data_len);
 		ADD_CHR(':');
-		ADD_MEM(&(obj->data), 8);
+		ADD_MEM(&(proxy_obj->data), 8);
 	}
-	if (has_proto_QUES(ist, obj, OBJ(STRING_PROTO))) {
+	if (has_proto_QUES(ist, proxy_obj, OBJ(STRING_PROTO))) {
 		ADD_CHR('s');
-		ADD_MEM(pr_strptr(obj), (int) pr_strlen(obj));
-	} else if (has_proto_QUES(ist, obj, OBJ(TUPLE_PROTO))) {
-		int llen = (int) list_len(ist, obj);
+		ADD_MEM(pr_strptr(proxy_obj), (int) pr_strlen(proxy_obj));
+	} else if (has_proto_QUES(ist, proxy_obj, OBJ(TUPLE_PROTO))) {
+		int llen = (int) list_len(ist, proxy_obj);
 		ADD_CHR('l');
 		for (i=0; i < llen; i++) {
-			ADD_REF(list_item(ist, obj, i));
+			ADD_REF(list_item(ist, proxy_obj, i));
 			if (i < llen-1) ADD_CHR(','); 
 		}
 	}
@@ -332,8 +481,8 @@
 			return;
 		}
 	}
+	(*loidx)++;
 	dict_add(ist, psrecp->proxies, obj, proxy_obj);
-	(*loidx)++;
 
 	plen = proto_len(ist, proxy_obj);
 	for(i=0; i < plen; i++) {
@@ -456,9 +605,10 @@
 	set_attr(ist, self, sym(ist, "root"),     root_obj);
 	read_lock(ist, self);
 
-	self->data_type = DATA_TYPE_DATAPTR;
-	self->data.ptr  = psrecp = pr_malloc(sizeof(psrec_t));
-	psrecp->db = db;
+	self->data_type		= DATA_TYPE_DATAPTR;
+	self->data.ptr		= psrecp = pr_malloc(sizeof(psrec_t));
+	psrecp->db			= db;
+	psrecp->pool		= cntxt;
 	psrecp->id_to_idobj = NEW_DICT(4*INITIAL_OBJ_COUNT);
 	psrecp->idobj_to_id = NEW_DICT(4*INITIAL_OBJ_COUNT);
 	psrecp->id_to_obj   = NEW_DICT(4*INITIAL_OBJ_COUNT);
@@ -466,13 +616,13 @@
 	psrecp->proxies     = NEW_DICT(4*INITIAL_OBJ_COUNT);
 
 	if (root_obj == OBJ(NONE)) {
-		psrecp->nextid = load_dbm_int("!nextid");
-		psrecp->root   = load_object(ist, psrecp);  
+		psrecp->nextid = load_dbm_int(psrecp, "!nextid");
+		psrecp->root   = load_db(ist, psrecp);
 	} else {
 		psrecp->root   = root_obj;
 		psrecp->nextid = 0;
 		store_new_db(ist, psrecp);  if_exc_return NULL; 
-		store_dbm_int("!nextid", psrecp->nextid);
+		store_dbm_int(psrecp, "!nextid", psrecp->nextid);
 	}
 	return OBJ(NONE);
 }
@@ -490,28 +640,36 @@
 		trans_commit(ist, dbdatap);
 	return self;
 }
+*/
 
-
-DEF(DB, close, NULL) { 
-	dbdata_p dbdatap = self->data.ptr;
-	if (dbdatap) {
-		trans_commit(ist, dbdatap);
-		apr_file_close(dbdatap->stream);
-		apr_pool_destroy(dbdatap->pool);
+DEF(Prosist, close, NULL) { 
+	psrec_p psrecp = self->data.ptr;
+	if (psrecp) {
+		// commit(ist, psrecp);
+		apr_dbm_close(psrecp->db);
+		apr_pool_destroy(psrecp->pool);
 		self->data.ptr = NULL;
 	}
 	return self;
 }
 
-DEF(DB, closed_QUES, NULL) { 
+DEF(Prosist, closed_QUES, NULL) { 
 	if (self->data.ptr) return OBJ(PR_FALSE);
 	else                return OBJ(PR_TRUE);
 }
-*/
+
+DEF(Prosist, __objList__, FORM_RPARAM) {
+	return parms[1];
+}
+
+
 MAIN_MODULE_INIT(Prosist)
 {
 	MODULE_SUB_INIT(Prosist);
 	MODULE_ADD_SYM(Prosist, __init__);
+	MODULE_ADD_SYM(Prosist, close);
+	MODULE_ADD_SYM(Prosist, closed_QUES);
+	MODULE_ADD_SYM(Prosist, __objList__);
 
 	check_exceptions(ist);
 }

Modified: trunk/src/builtins-core.c
===================================================================
--- trunk/src/builtins-core.c	2004-04-21 08:16:22 UTC (rev 398)
+++ trunk/src/builtins-core.c	2004-04-22 18:50:47 UTC (rev 399)
@@ -259,7 +259,9 @@
 }
 
 DEF(Object, __eq__QUES, FORM_RPARAM) {
-	obj_p cmp_obj = call_func1(ist, self, SYM(CMP), parms[1]); if_exc_return NULL;
+	obj_p cmp_obj = call_func1(ist, self, SYM(CMP), parms[1]); 
+	if(catch_exception(ist, OBJ(FUNCNOTFOUND_EXC), NULL))
+		return OBJ(PR_FALSE);
 	if (cmp_obj && *((i64_t*)(obj_data_p(cmp_obj))) == 0)
 		return OBJ(PR_TRUE);
 	else

Modified: trunk/src/builtins-dict.c
===================================================================
--- trunk/src/builtins-dict.c	2004-04-21 08:16:22 UTC (rev 398)
+++ trunk/src/builtins-dict.c	2004-04-22 18:50:47 UTC (rev 399)
@@ -131,8 +131,8 @@
 	for (i=hash_in; (key=((dp=dictptr(dict,i))->entry.key)); i++){
 		hash = dp->entry.hash;
 		if (hash < 0) { hole = dp; continue; }
-		if ( hash == hash_in && 
-			call_func(ist, key, SYM(__EQ__QUES), 2, rp, NULL) == OBJ(PR_TRUE) ) {
+		if ( hash == hash_in && ( key == key_in ||
+			call_func(ist, key, SYM(__EQ__QUES), 2, rp, NULL) == OBJ(PR_TRUE) ) ) {
 			match = PR_TRUE;
 			break;
 		}
@@ -183,8 +183,8 @@
 	if (!hash_in) hash_in++;
 	dict = (dict_p) obj_data_p(dict_obj);
 	for (i=hash_in; (key=((dp=dictptr(dict,i))->entry.key)); i++){
-		if ( dp->entry.hash == hash_in && 
-			 call_func(ist, key, SYM(__EQ__QUES), 2, rp, NULL) == OBJ(PR_TRUE) ) {
+		if ( dp->entry.hash == hash_in && ( key == key_in ||
+			 call_func(ist, key, SYM(__EQ__QUES), 2, rp, NULL) == OBJ(PR_TRUE) ) ) {
 			dict_rd_chk();
 			res = dp->entry.value;
 			read_unlock(ist, dict_obj);
@@ -411,8 +411,8 @@
 	}
 	dict = (dict_p) self->data.ptr;
 	for(i=hash_in; (key=((dp=dictptr(dict,i))->entry.key)); i++){
-		if ( dp->entry.hash == hash_in && 
-			 call_func(ist, key, SYM(__EQ__QUES), 2, rp, NULL) == OBJ(PR_TRUE) ) {
+		if ( dp->entry.hash == hash_in && ( key == key_in ||
+			 call_func(ist, key, SYM(__EQ__QUES), 2, rp, NULL) == OBJ(PR_TRUE) ) ) {
 			dp->entry.hash = ENTRY_DELETED;
 			dictlen(dict)--;
 			def_write_unlock(self);
@@ -497,6 +497,7 @@
 
 MODULE_START(DictRestore) {
 	DictRestore_OBJ = NEW_OBJ(OBJ(LIST_PROTO));
+	MODULE_ADD_TO_OBJ(DictRestore, OBJ(OBJECT), "DictRestore");
 	set_obj_id(DictRestore_OBJ, *, DictRestore);
 }
 

Modified: trunk/src/object.c
===================================================================
--- trunk/src/object.c	2004-04-21 08:16:22 UTC (rev 398)
+++ trunk/src/object.c	2004-04-22 18:50:47 UTC (rev 399)
@@ -193,8 +193,8 @@
 	dll_services.new_dict_obj	   = new_dict_obj;	  
 	dll_services.proto_len		   = proto_len;	  
 	dll_services.proto_item		   = proto_item;		 
+	dll_services.dump			   = dump;		 
 
-
 	/* Setup the core objects. Order counts here */
 	OBJ(OBJECT)             = NEW_OBJ(NULL);
 	OBJ(OBJECT)->attr_proto.proto = OBJ(OBJECT);
@@ -963,8 +963,8 @@
 clist_p object_list;
 int first_symbol, prt_flg=0;
 FILE* fout;
-void dump(isp ist, char* dumfilename, obj_p obj){
-	fout = fopen(dumfilename, "w");
+void dump(isp ist, char* dumpfilename, obj_p obj){
+	fout = fopen(dumpfilename, "w");
 	object_list = new_clist(10);
 	first_symbol = PR_TRUE;
 	fprintf(fout,"\nDumping (%lx)\n",(unsigned long)(uintptr_t)obj);

Modified: trunk/src/object.h
===================================================================
--- trunk/src/object.h	2004-04-21 08:16:22 UTC (rev 398)
+++ trunk/src/object.h	2004-04-22 18:50:47 UTC (rev 399)
@@ -140,7 +140,6 @@
 
 char* numonly(char* s, char* buf);
 
-void dump(isp ist, char* dumpfilename, obj_p obj);
 void dump_obj(isp ist, obj_p obj, int dep);
 
 obj_p arginit(isp its, int argc, char* argv[]);