rev 594 - in trunk: . src

SVN User <[email protected]> Thu, 10 Jun 2004 03:23:29 -0400
Newsgroups gmane.comp.lang.prothon.cvs
Message-ID <[email protected]>
Author: mark
Date: 2004-06-10 03:23:26 -0400 (Thu, 10 Jun 2004)
New Revision: 594

Modified:
   trunk/STATUS.txt
   trunk/src/builtins-bytes.c
   trunk/src/builtins-string.c
   trunk/src/object.h
   trunk/src/prothon.y
Log:
\x00 is legal ascii now, Bytes.str_ prints as x""

Modified: trunk/STATUS.txt
===================================================================
--- trunk/STATUS.txt	2004-06-10 05:32:33 UTC (rev 593)
+++ trunk/STATUS.txt	2004-06-10 07:23:26 UTC (rev 594)
@@ -1,8 +1,8 @@
 
 ----------------------- TO-DO (highest priority first) ------------------------
 
---- binaryObj = Bytes("Hello world", "ascii") (or "latin-1") exception to tell "latin-1"
 --- allow lists of ints in Bytes constructor
+--- allow Bytes object in String constructor with encoding param
 
 --- allow tracebacks in the constructors to exception objects or raise command
 

Modified: trunk/src/builtins-bytes.c
===================================================================
--- trunk/src/builtins-bytes.c	2004-06-10 05:32:33 UTC (rev 593)
+++ trunk/src/builtins-bytes.c	2004-06-10 07:23:26 UTC (rev 594)
@@ -128,14 +128,36 @@
 	Bytes_OBJ->imm_data_len = 0;
 }
 
-DEF(Bytes, init_, FORM_RPARAM) {
-	char *s;
+DEF(Bytes, init_, FPARM2(value, NULL, encoding, NEW_STRING("ASCII"))) {
 	obj_p res = NULL;
+	size_t len;
+	byt_p obj_byt;
+
 	BIN_EMPTY_CHK();
 	if (has_proto(ist, parms[1], OBJ(STRING_PROTO))) {
-		s = pr2c_strptr(ist, parms[1]);
-		set_bytes_data(ist, self, s, strlen(s));
-		pr_free(s);
+		char* encoding_str;
+		int latin = FALSE;
+		u8_t* buf;
+
+		STRING_PARAM(2, encoding_str);
+		if (!strcmp(encoding_str, "latin-1"))
+			latin = TRUE;
+		else if (strcmp(encoding_str, "ASCII")) {
+			raise_exception(ist, OBJ(VALUE_EXC), "unknown encoding parameter: '%s'", encoding_str);
+			return NULL;
+		}
+		len = pr_strlen(parms[1]);
+		if (len <= IMM_DATA_LEN) {
+			SET_TYPE_IF_EXC(OBJ(BYTES_PROTO), self, DATA_TYPE_IMMDATA) return NULL;
+			self->imm_data_len = (int) len;
+			buf = self->data.bytes;
+		} else {
+			obj_byt = obj_malloc(ist, OBJ(BYTES_PROTO), self, sizeof(byt_t)+len); if_exc_return NULL;
+			obj_byt->len = (data_size_t) len;
+			buf = &(obj_byt->byt[0]);
+		}
+		pr_str2bytes(ist, buf, parms[1], latin);
+		self->immutable = TRUE;
 		return OBJ(NONE);
 	} else if (has_proto(ist, parms[1], OBJ(BYTES_PROTO))) {
 		return copy_object(ist, parms[1]);
@@ -146,10 +168,25 @@
 }
 
 DEF(Bytes, str_, NULL) {
-	char buf[32];
+	u8_t* self_ptr;
+	char *buf;
+	size_t i, self_len;
+	obj_p res;
+
 	BIN_STR_CHK(Bytes);
-	apr_snprintf(buf, sizeof(buf), "<Bytes:%x>", (unsigned long) (intptr_t) self);
-	return NEW_STRING(buf);
+	self_ptr = bytes_ptr(self);
+	self_len = bytes_len(self);
+	buf = pr_malloc(self_len*3+3);
+	strcpy(buf, "x\"");
+	for (i=0; i < self_len; i++) {
+		char str[8];
+		apr_snprintf(str, sizeof(str), "%02x ", *(self_ptr++));
+		strcat(buf, str);
+	}
+	*(buf+strlen(buf)-1) = '\"';
+	res = NEW_STRING(buf);
+	pr_free(buf);
+	return res;
 }
 
 DEF(Bytes, hash_, NULL) {
Modified: trunk/src/builtins-string.c
===================================================================
--- trunk/src/builtins-string.c	2004-06-10 05:32:33 UTC (rev 593)
+++ trunk/src/builtins-string.c	2004-06-10 07:23:26 UTC (rev 594)
@@ -69,6 +69,8 @@
 
 #define is_String(objid)        (has_proto(ist, objid, String_OBJ))
 
+#define ORD(ch3p)  (((u32_t)(ch3p)->b0)+((((u32_t)(ch3p)->b1)+(((u32_t)(ch3p)->b2)*256))*256))
+
 MODULE_DECLARE(String);
 MODULE_DECLARE(StringGen);
 
@@ -140,14 +142,52 @@
 	res = pr_malloc(len+1);
 	for (i=0; i < len; i++) {
 		res[i] = (char) ch3p[i].b0;
-		if (!ch3p[i].b0 || ch3p[i].b0 > 127 || ch3p[i].b1 || ch3p[i].b2) {
-			raise_exception(ist, OBJ(VALUE_EXC), "string has non-ascii value");
+		if (ch3p[i].b1 || ch3p[i].b2) {
+			raise_exception(ist, OBJ(VALUE_EXC), "bad ASCII value (0x%x), need unicode encoding", ORD(ch3p+i));
 			return "";
 		}
+		if (ch3p[i].b0 > 127) {
+			raise_exception(ist, OBJ(VALUE_EXC), "bad ASCII value (0x%02x), try 'latin-1' encoding", ch3p[i].b0);
+			return "";
+		}
 	}
 	res[i] = 0;
 	return res;
 }
+//********************************* pr_str2bytes *******************************
+void pr_str2bytes(isp ist, u8_t* buf, obj_p str_obj, int latin) {
+	str_p strp;
+	ch3_p ch3p;
+	data_size_t i, data_size, len;
+
+	if (!str_obj) {
+		raise_exception(ist, OBJ(INTERNAL_EXC), "string object missing in pr_str2bytes");
+		return;
+	}
+	if (str_obj->data_type == DATA_TYPE_IMMDATA) {
+		data_size = str_obj->imm_data_len;
+		ch3p      = str_obj->data.str;
+	} else if (str_obj->data_type == DATA_TYPE_DATAPTR) {
+		strp      = str_obj->data.ptr;
+		data_size = strp->size - sizeof(str_t);
+		ch3p      = strp->str;
+	} else {
+		raise_exception(ist, OBJ(VALUE_EXC), "string object uninitialized");
+		return;
+	}
+	len = data_size/3;
+	for (i=0; i < len; i++) {
+		buf[i] = ch3p[i].b0;
+		if (ch3p[i].b1 || ch3p[i].b2) {
+			raise_exception(ist, OBJ(VALUE_EXC), "bad char value (0x%x), need different encoding", ORD(ch3p+i));
+			return;
+		}
+		if (!latin && ch3p[i].b0 > 127) {
+			raise_exception(ist, OBJ(VALUE_EXC), "bad ASCII value (0x%02x), use 'latin-1' encoding(?)", ch3p[i].b0);
+			return;
+		}
+	}
+}
 //********************************* changeCase ********************************
 // Generic case-changer function.
 #define AT_WORD_START -1
@@ -391,7 +431,7 @@
 		ch3p = self->data.str;
 	else
 		ch3p = ((str_p)self->data.ptr)->str;
-	return NEW_INT(ch3p->b0+((ch3p->b1+(ch3p->b2*256))*256));
+	return NEW_INT(ORD(ch3p));
 }
 
 DEF(String, join, FORM_RPARAM) {

Modified: trunk/src/object.h
===================================================================
--- trunk/src/object.h	2004-06-10 05:32:33 UTC (rev 593)
+++ trunk/src/object.h	2004-06-10 07:23:26 UTC (rev 594)
@@ -150,6 +150,7 @@
 int int_is_zero(obj_p obj);
 u8_t* bytes_ptr(obj_p obj);
 size_t bytes_len(obj_p obj);
+void pr_str2bytes(isp ist, u8_t* buf, obj_p str_obj, int latin);
 
 void dict2attrs(isp ist, obj_p dict, obj_p obj);
 void list2protos(isp ist, obj_p list, obj_p obj);

Modified: trunk/src/prothon.y
===================================================================
--- trunk/src/prothon.y	2004-06-10 05:32:33 UTC (rev 593)
+++ trunk/src/prothon.y	2004-06-10 07:23:26 UTC (rev 594)
@@ -991,7 +991,10 @@
 		}
 		str_ptr[str_index++]=0;		
 		str_ptr = pr_realloc(str_ptr, str_index);
-		lvalp->str_type = new_string_n_obj((((parse_state*) yylex_param)->ist), str_ptr, str_index-1); 
+		if (x_flag)
+			lvalp->str_type = new_bytes_obj((((parse_state*) yylex_param)->ist), str_ptr, str_index-1);
+		else
+			lvalp->str_type = new_string_n_obj((((parse_state*) yylex_param)->ist), str_ptr, str_index-1); 
 #ifdef TRACE_PARSER
 	if (trace_parser){
 		fprintf(((parse_state*) yylex_param)->debug_stream, "\"%s\"\n",str_ptr);