rev 606 - in trunk: . pr/test src

SVN User <[email protected]> Sat, 12 Jun 2004 03:38:05 -0400
Newsgroups gmane.comp.lang.prothon.cvs
Message-ID <[email protected]>
Author: mark
Date: 2004-06-12 03:38:02 -0400 (Sat, 12 Jun 2004)
New Revision: 606

Modified:
   trunk/STATUS.txt
   trunk/pr/test/test.pr
   trunk/src/builtins-string.c
Log:
added nested substitution in str.fmt()

Modified: trunk/STATUS.txt
===================================================================
--- trunk/STATUS.txt	2004-06-12 05:28:24 UTC (rev 605)
+++ trunk/STATUS.txt	2004-06-12 07:38:02 UTC (rev 606)
@@ -4,8 +4,7 @@
 --- unicode module
 		http://www.prothon.org/pipermail/prothon-user/2004-June/001895.html
 		
---- implement new string.fmt(): 
-		"abc{var:spec}def{0:spec}ghi".fmt('posvalue', var='kwvalue')
+--- add int.str_(spec), float.str_(spec)
 
 --- Complete File/Dir objects
 --- TextFile object

Modified: trunk/pr/test/test.pr
===================================================================
--- trunk/pr/test/test.pr	2004-06-12 05:28:24 UTC (rev 605)
+++ trunk/pr/test/test.pr	2004-06-12 07:38:02 UTC (rev 606)
@@ -1,3 +1,3 @@
 #!/usr/bin/env prothon
 
-print "{0} likes {1}".fmt('mark', 'linda')
\ No newline at end of file
+print "*{0:{1}}*".fmt("abc",10)
\ No newline at end of file

Modified: trunk/src/builtins-string.c
===================================================================
--- trunk/src/builtins-string.c	2004-06-12 05:28:24 UTC (rev 605)
+++ trunk/src/builtins-string.c	2004-06-12 07:38:02 UTC (rev 606)
@@ -620,15 +620,95 @@
 	src++;									\
 } while (FALSE)
 
+obj_p de_spec(isp ist, ch3_p* srcp, ch3_p endp, obj_p list, obj_p dict) {
+	u32_t ch;
+	char buf[256], *p, *pend, *var, *spec;
+	obj_p value, ins_text;
+	int i, ins_len;
+	ch3_p insp;
+	for ( p = buf, pend = buf + sizeof(buf); 
+		  p < pend && *srcp < endp && (ch = ORD(*srcp)) != BRACE_RIGHT;
+		  p++, (*srcp)++ ) {
+		if (ch < 0x20 || ch > 0x7f) {
+			raise_exception(ist, OBJ(VALUE_EXC), "invalid character in formatting spec");
+			return NULL;
+		}
+		if (ch == BRACE_LEFT) {
+			(*srcp)++;
+			if (*srcp < endp && (ch = ORD(*srcp)) == BRACE_LEFT)
+				goto savech;
+			ins_text = de_spec(ist, srcp, endp, list, dict); if_exc_return NULL;
+			ins_len = pr_strlen(ins_text);
+			insp    = pr_ch3ptr(ins_text);
+			if (p+ins_len > pend) {
+				raise_exception(ist, OBJ(VALUE_EXC), "unterminated formatting spec");
+				return NULL;
+			}
+			for(i=0; i < ins_len; i++, p++, insp++) {
+				ch = ORD(insp);
+				if (ch < 0x20 || ch > 0x7f) {
+					raise_exception(ist, OBJ(VALUE_EXC), "invalid character in formatting spec");
+					return NULL;
+				}
+				*p = (char) ch;
+			}
+			del_unlock(ins_text);
+			if (p < pend && *srcp < endp && (ch = ORD(*srcp)) != BRACE_RIGHT)
+				goto savech;
+			else
+				break;
+		}
+savech:
+		*p = (char) ch;
+	}
+	*p = 0;
+	if (ch != BRACE_RIGHT) {
+		raise_exception(ist, OBJ(VALUE_EXC), "unterminated formatting spec");
+		return NULL;
+	}
+	(*srcp)++;
+	var = spec = buf;
+	for(; *spec; spec++)
+		if (*spec == ':') {
+			*spec = 0; 
+			spec++;
+			break;
+		}
+	if (*var >= '0' && *var <= '9') {
+		size_t index;
+		for (p=var+1; *p; p++)
+			if (*p < '0' || *p > '9') {
+				raise_exception(ist, OBJ(VALUE_EXC), "invalid character in fmt spec list index (%s)", var);
+				return NULL;
+			}
+		index = atoi(var);
+		if (index >= list_len(ist, list)) {
+			raise_exception(ist, OBJ(VALUE_EXC), "fmt spec list index too big (%s)", var);
+			return NULL;
+		}
+		value = list_item(ist, list, (int) index);
+	} else
+		value = dict_item(ist, dict, NEW_STRING(var));
+	if_exc_return NULL;
+	if (!value) {
+		raise_exception(ist, OBJ(VALUE_EXC), "no match in dictionary for fmt spec variable \"%s\"", var);
+		return NULL;
+	}
+	if (*spec) {
+		ins_text = call_func1(ist, value, SYM(STR_), NEW_STRING(spec)); if_exc_return NULL;
+	} else {
+		ins_text = call_func0(ist, value, SYM(STR_)); if_exc_return NULL;
+	}
+	return ins_text;
+}
+
 DEF(String, fmt, FORM_STAR3_PARAM) {
 	obj_p res, list = parms[1], dict = parms[3];
 	ch3_p srcp = pr_ch3ptr(self);
 	data_size_t src_len = pr_strlen(self), i, res_len = src_len*2, ins_len;
 	ch3_p endp = srcp+src_len, resp = pr_malloc(res_len*3), dstp=resp, insp;
 	while (srcp < endp) {
-		u32_t ch;
-		char buf[256], *p, *pend, *var, *spec;
-		obj_p value, ins_text;
+		obj_p ins_text;
 		while (srcp < endp && ORD(srcp) != BRACE_LEFT) CH3MOVE(srcp);
 		if (srcp == endp) break;
 		srcp++;
@@ -636,55 +716,9 @@
 			CH3MOVE(srcp);
 			continue;
 		}
-		for ( p = buf, pend = buf + sizeof(buf); 
-			  p < pend && srcp < endp && (ch = ORD(srcp)) != BRACE_RIGHT;
-			  p++, srcp++ ) {
-			if (ch < 0x20 || ch > 0x7f) {
-				raise_exception(ist, OBJ(VALUE_EXC), "invalid character in formatting spec");
-				return NULL;
-			}
-			*p = (char) ch;
-		}
-	    *p = 0;
-		if (ch != BRACE_RIGHT) {
-			raise_exception(ist, OBJ(VALUE_EXC), "unterminated formatting spec");
-			return NULL;
-		}
-		srcp++;
-		var = spec = buf;
-		for(; *spec; spec++)
-			if (*spec == ':') {
-				*spec = 0; 
-				spec++;
-				break;
-			}
-		if (*var >= '0' && *var <= '9') {
-			size_t index;
-			for (p=var+1; *p; p++)
-				if (*p < '0' || *p > '9') {
-					raise_exception(ist, OBJ(VALUE_EXC), "invalid character in fmt spec list index (%s)", var);
-					return NULL;
-				}
-			index = atoi(var);
-			if (index >= list_len(ist, list)) {
-				raise_exception(ist, OBJ(VALUE_EXC), "fmt spec list index too big (%s)", var);
-				return NULL;
-			}
-			value = list_item(ist, list, (int) index);
-		} else
-			value = dict_item(ist, dict, NEW_STRING(var));
-		if_exc_return NULL;
-		if (!value) {
-			raise_exception(ist, OBJ(VALUE_EXC), "no match in dictionary for fmt spec variable \"%s\"", var);
-			return NULL;
-		}
-		if (*spec) {
-			ins_text = call_func1(ist, value, SYM(STR_), NEW_STRING(spec)); if_exc_return NULL;
-		} else {
-			ins_text = call_func0(ist, value, SYM(STR_)); if_exc_return NULL;
-		}
+		ins_text = de_spec(ist, &srcp, endp, list, dict); if_exc_return NULL;
+		ins_len = pr_strlen(ins_text);
 		insp    = pr_ch3ptr(ins_text);
-		ins_len = pr_strlen(ins_text);
 		for(i=0; i < ins_len; i++) CH3MOVE(insp);
 		del_unlock(ins_text);
 	}