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);