rev 605 - in trunk: include/prothon pr/test src
SVN User <[email protected]> Sat, 12 Jun 2004 01:28:27 -0400
| Newsgroups | gmane.comp.lang.prothon.cvs |
|---|---|
| Message-ID | <[email protected]> |
Author: mark
Date: 2004-06-12 01:28:24 -0400 (Sat, 12 Jun 2004)
New Revision: 605
Modified:
trunk/include/prothon/prothon.h
trunk/pr/test/test.pr
trunk/src/builtins-string.c
Log:
added string.fmt() and string.str_(spec)
Modified: trunk/include/prothon/prothon.h
===================================================================
--- trunk/include/prothon/prothon.h 2004-06-12 00:00:35 UTC (rev 604)
+++ trunk/include/prothon/prothon.h 2004-06-12 05:28:24 UTC (rev 605)
@@ -981,8 +981,9 @@
(var) = int2i64t(ist, index > 0 ? parms[((index)-1)*2+1] : list_item(ist, parms[1], -index)); }
i64_t int2i64t(isp ist, obj_p self);
-#define STRING_PARAM(index, var) \
-{ if (!has_proto(ist, (index > 0 ? parms[((index)-1)*2+1] : list_item(ist, parms[1], -index)), OBJ(STRING_PROTO))) { \
+#define STRING_PARAM(index, var) \
+{ if (!has_proto(ist, (index > 0 ? parms[((index)-1)*2+1] : \
+ list_item(ist, parms[1], -index)), OBJ(STRING_PROTO))) { \
raise_exception(ist, OBJ(TYPE_EXC), \
"expected a string in parameter " #index); \
return NULL; \
Modified: trunk/pr/test/test.pr
===================================================================
--- trunk/pr/test/test.pr 2004-06-12 00:00:35 UTC (rev 604)
+++ trunk/pr/test/test.pr 2004-06-12 05:28:24 UTC (rev 605)
@@ -1,3 +1,3 @@
#!/usr/bin/env prothon
-print "abc" * (-1)
\ No newline at end of file
+print "{0} likes {1}".fmt('mark', 'linda')
\ No newline at end of file
Modified: trunk/src/builtins-string.c
===================================================================
--- trunk/src/builtins-string.c 2004-06-12 00:00:35 UTC (rev 604)
+++ trunk/src/builtins-string.c 2004-06-12 05:28:24 UTC (rev 605)
@@ -404,9 +404,64 @@
return OBJ(NONE);
}
-DEF(String, str_, NULL) {
+DEF(String, str_, FPARM1(spec, NEW_STRING(""))) {
+ obj_p res;
+ char *spec, *wid_p = NULL, *prec_p = NULL, *p;
+ int left_align = FALSE;
+ int zero_pad = FALSE;
+ int width, precision, i, self_len, res_len;
+ ch3_p self_ptr, res_ptr, ptr;
+
BIN_STR_CHK(String);
- return self;
+ STRING_PARAM(1, spec);
+ if (*spec == 0) return self;
+ for(p=spec; *p; p++) {
+ if (!wid_p && !prec_p && *p == '-') left_align = TRUE;
+ else if (!wid_p && !prec_p && *p == '0') zero_pad = TRUE;
+ else if (!wid_p && !prec_p && *p > '0' && *p <= '9') wid_p = p;
+ else if (!prec_p && *p == '.') { prec_p = p+1; *p = 0; }
+ else if (*p == 's' || *p == 'S') {
+ if (*(p+1) != 0) {
+ raise_exception(ist, OBJ(TYPE_EXC), "character found after s in string fmt spec");
+ return NULL;
+ }
+ *p = 0;
+ break;
+ } else if (*p < '0' || *p > '9') {
+ raise_exception(ist, OBJ(VALUE_EXC), "ivalid fmt spec in str_ parameter: \"%s\"", spec);
+ return NULL;
+ }
+ }
+ if (!wid_p && !prec_p) return self;
+ if (wid_p) width = atoi(wid_p);
+ if (prec_p) precision = atoi(prec_p);
+ self_len = pr_strlen(self);
+ self_ptr = pr_ch3ptr(self);
+ if (prec_p)
+ self_len = min(precision, self_len);
+ if (wid_p)
+ res_len = max(self_len, width);
+ else
+ res_len = self_len;
+ ptr = res_ptr = pr_malloc(res_len*3);
+ if (!left_align)
+ for (i=0; i < res_len-self_len; i++, ptr++) {
+ ptr->b0 = (u8_t) (zero_pad ? '0' : ' ');
+ ptr->b1 = 0; ptr->b2 = 0;
+ }
+ for (i=0; i < self_len; i++, ptr++, self_ptr++) {
+ ptr->b0 = self_ptr->b0;
+ ptr->b1 = self_ptr->b1;
+ ptr->b2 = self_ptr->b2;
+ }
+ if (left_align)
+ for (i=0; i < res_len-self_len; i++, ptr++) {
+ ptr->b0 = (u8_t) ' ';
+ ptr->b1 = 0; ptr->b2 = 0;
+ }
+ res = new_string_ch3_obj(ist, res_ptr, res_len);
+ pr_free(res_ptr);
+ return res;
}
DEF(String, hash_, NULL) {
@@ -548,6 +603,96 @@
return res;
}
+#define BRACE_LEFT 0x7B
+#define BRACE_RIGHT 0x7D
+
+#define CH3MOVE(src) \
+do { \
+ if (dstp == resp+res_len) { \
+ resp = pr_realloc(resp, res_len*6); \
+ dstp = resp+res_len; \
+ res_len *= 2; \
+ } \
+ dstp->b0 = src->b0; \
+ dstp->b1 = src->b1; \
+ dstp->b2 = src->b2; \
+ dstp++; \
+ src++; \
+} while (FALSE)
+
+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;
+ while (srcp < endp && ORD(srcp) != BRACE_LEFT) CH3MOVE(srcp);
+ if (srcp == endp) break;
+ srcp++;
+ if (srcp < endp && ORD(srcp) == BRACE_LEFT) {
+ 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;
+ }
+ insp = pr_ch3ptr(ins_text);
+ ins_len = pr_strlen(ins_text);
+ for(i=0; i < ins_len; i++) CH3MOVE(insp);
+ del_unlock(ins_text);
+ }
+ res = new_string_ch3_obj(ist, resp, dstp-resp);
+ pr_free(resp);
+ return res;
+}
+
DEF(String, ord, NULL) {
BIN_CONTENT_CHK(String);
if (!pr_strlen(self)) {
@@ -962,6 +1107,7 @@
MODULE_ADD_SYM(String, add_);
MODULE_ADD_SYM(String, mul_);
MODULE_ADD_SYM(String, mod_);
+ MODULE_ADD_SYM(String, fmt);
MODULE_ADD_SYM(String, iter_);
MODULE_ADD_SYM(String, join);
MODULE_ADD_SYM(String, in__QUES);