[gimp] R5RS compatability fix for string->number and number->string (SF bug #3399335) Optional radix parame
- From: Kevin Cozens <kcozens src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] R5RS compatability fix for string->number and number->string (SF bug #3399335) Optional radix parame
- Date: Fri, 14 Dec 2012 22:43:23 +0000 (UTC)
commit df30fd6e682bc0453806d934a8559c9ba1cc12bd
Author: Kevin Cozens <kcozens svn gnome org>
Date: Fri Dec 14 17:36:26 2012 -0500
R5RS compatability fix for string->number and number->string (SF bug #3399335)
Optional radix parameter from SVN version 92 of official version of TinyScheme.
plug-ins/script-fu/scripts/script-fu.init | 7 +-
plug-ins/script-fu/tinyscheme/init.scm | 7 +-
plug-ins/script-fu/tinyscheme/opdefines.h | 4 +-
plug-ins/script-fu/tinyscheme/scheme.c | 120 ++++++++++++++++++++++-------
4 files changed, 103 insertions(+), 35 deletions(-)
---
diff --git a/plug-ins/script-fu/scripts/script-fu.init b/plug-ins/script-fu/scripts/script-fu.init
index 120ecc7..ba96022 100644
--- a/plug-ins/script-fu/scripts/script-fu.init
+++ b/plug-ins/script-fu/scripts/script-fu.init
@@ -142,7 +142,9 @@
(if (pred a) a
(error "string->xxx: not a xxx" a))))
-(define (string->number str) (string->anyatom str number?))
+(define (string->number str . base)
+ (let ((n (string->atom str (if (null? base) 10 (car base)))))
+ (if (number? n) n #f)))
(define (anyatom->string n pred)
(if (pred n)
@@ -150,7 +152,8 @@
(error "xxx->string: not a xxx" n)))
-(define (number->string n) (anyatom->string n number?))
+(define (number->string n . base)
+ (atom->string n (if (null? base) 10 (car base))))
(define (char-cmp? cmp a b)
(cmp (char->integer a) (char->integer b)))
diff --git a/plug-ins/script-fu/tinyscheme/init.scm b/plug-ins/script-fu/tinyscheme/init.scm
index 120ecc7..25896d3 100644
--- a/plug-ins/script-fu/tinyscheme/init.scm
+++ b/plug-ins/script-fu/tinyscheme/init.scm
@@ -142,15 +142,18 @@
(if (pred a) a
(error "string->xxx: not a xxx" a))))
-(define (string->number str) (string->anyatom str number?))
+(define (string->number str . base)
+ (let ((n (string->atom str (if (null? base) 10 (car base)))))
+ (if (number? n) n #f)))
(define (anyatom->string n pred)
(if (pred n)
(atom->string n)
(error "xxx->string: not a xxx" n)))
+(define (number->string n . base)
+ (atom->string n (if (null? base) 10 (car base))))
-(define (number->string n) (anyatom->string n number?))
(define (char-cmp? cmp a b)
(cmp (char->integer a) (char->integer b)))
diff --git a/plug-ins/script-fu/tinyscheme/opdefines.h b/plug-ins/script-fu/tinyscheme/opdefines.h
index 3101eef..ceb4d0e 100644
--- a/plug-ins/script-fu/tinyscheme/opdefines.h
+++ b/plug-ins/script-fu/tinyscheme/opdefines.h
@@ -88,9 +88,9 @@
_OP_DEF(opexe_2, "char-upcase", 1, 1, TST_CHAR, OP_CHARUPCASE )
_OP_DEF(opexe_2, "char-downcase", 1, 1, TST_CHAR, OP_CHARDNCASE )
_OP_DEF(opexe_2, "symbol->string", 1, 1, TST_SYMBOL, OP_SYM2STR )
- _OP_DEF(opexe_2, "atom->string", 1, 1, TST_ANY, OP_ATOM2STR )
+ _OP_DEF(opexe_2, "atom->string", 1, 2, TST_ANY TST_NATURAL, OP_ATOM2STR )
_OP_DEF(opexe_2, "string->symbol", 1, 1, TST_STRING, OP_STR2SYM )
- _OP_DEF(opexe_2, "string->atom", 1, 1, TST_STRING, OP_STR2ATOM )
+ _OP_DEF(opexe_2, "string->atom", 1, 2, TST_STRING TST_NATURAL, OP_STR2ATOM )
_OP_DEF(opexe_2, "make-string", 1, 2, TST_NATURAL TST_CHAR, OP_MKSTRING )
_OP_DEF(opexe_2, "string-length", 1, 1, TST_STRING, OP_STRLEN )
_OP_DEF(opexe_2, "string-ref", 2, 2, TST_STRING TST_NATURAL, OP_STRREF )
diff --git a/plug-ins/script-fu/tinyscheme/scheme.c b/plug-ins/script-fu/tinyscheme/scheme.c
index cbfdc1b..ad47dc2 100644
--- a/plug-ins/script-fu/tinyscheme/scheme.c
+++ b/plug-ins/script-fu/tinyscheme/scheme.c
@@ -1437,7 +1437,6 @@ static int file_push(scheme *sc, const char *fname) {
if(fname)
sc->load_stack[sc->file_i].rep.stdio.filename = store_string(sc, strlen(fname), fname, 0);
#endif
-
}
return fin!=0;
}
@@ -2126,17 +2125,38 @@ static void atom2str(scheme *sc, pointer l, int f, char **pp, int *plen) {
snprintf(p, STRBUFFSIZE, "#<PORT>");
} else if (is_number(l)) {
p = sc->strbuff;
- if(num_is_integer(l)) {
- snprintf(p, STRBUFFSIZE, "%ld", ivalue_unchecked(l));
+ if (f <= 1 || f == 10) /* f is the base for numbers if > 1 */ {
+ if(num_is_integer(l)) {
+ snprintf(p, STRBUFFSIZE, "%ld", ivalue_unchecked(l));
+ } else {
+ snprintf(p, STRBUFFSIZE, "%.10g", rvalue_unchecked(l));
+ /* r5rs says there must be a '.' (unless 'e'?) */
+ f = strcspn(p, ".e");
+ if (p[f] == 0) {
+ p[f] = '.'; // not found, so add '.0' at the end
+ p[f+1] = '0';
+ p[f+2] = 0;
+ }
+ }
} else {
- snprintf(p, STRBUFFSIZE, "%.10g", rvalue_unchecked(l));
- /* R5RS says there must be a '.' (unless 'e'?) */
- f = strcspn(p, ".e");
- if (p[f] == 0) {
- p[f] = '.'; // not found, so add '.0' at the end
- p[f+1] = '0';
- p[f+2] = 0;
- }
+ long v = ivalue(l);
+ if (f == 16) {
+ if (v >= 0)
+ snprintf(p, STRBUFFSIZE, "%lx", v);
+ else
+ snprintf(p, STRBUFFSIZE, "-%lx", -v);
+ } else if (f == 8) {
+ if (v >= 0)
+ snprintf(p, STRBUFFSIZE, "%lo", v);
+ else
+ snprintf(p, STRBUFFSIZE, "-%lo", -v);
+ } else if (f == 2) {
+ unsigned long b = (v < 0) ? -v : v;
+ p = &p[STRBUFFSIZE-1];
+ *p = 0;
+ do { *--p = (b&1) ? '1' : '0'; b >>= 1; } while (b != 0);
+ if (v < 0) *--p = '-';
+ }
}
} else if (is_string(l)) {
if (!f) {
@@ -2981,7 +3001,7 @@ static pointer opexe_0(scheme *sc, enum scheme_opcodes op) {
sc->code = car(sc->code);
else
sc->code = cadr(sc->code); /* (if #f 1) ==> () because
- * car(sc->NIL) = sc->NIL */
+ * car(sc->NIL) = sc->NIL */
s_goto(sc,OP_EVAL);
case OP_LET0: /* let */
@@ -3528,28 +3548,70 @@ static pointer opexe_2(scheme *sc, enum scheme_opcodes op) {
s_return(sc,mk_symbol(sc,strvalue(car(sc->args))));
case OP_STR2ATOM: /* string->atom */ {
- char *s=strvalue(car(sc->args));
- if(*s=='#') {
- s_return(sc, mk_sharp_const(sc, s+1));
- } else {
- s_return(sc, mk_atom(sc, s));
- }
- }
+ char *s=strvalue(car(sc->args));
+ long pf = 0;
+ if(cdr(sc->args)!=sc->NIL) {
+ /* we know cadr(sc->args) is a natural number */
+ /* see if it is 2, 8, 10, or 16, or error */
+ pf = ivalue_unchecked(cadr(sc->args));
+ if(pf == 16 || pf == 10 || pf == 8 || pf == 2) {
+ /* base is OK */
+ }
+ else {
+ pf = -1;
+ }
+ }
+ if (pf < 0) {
+ Error_1(sc, "string->atom: bad base:", cadr(sc->args));
+ } else if(*s=='#') /* no use of base! */ {
+ s_return(sc, mk_sharp_const(sc, s+1));
+ } else {
+ if (pf == 0 || pf == 10) {
+ s_return(sc, mk_atom(sc, s));
+ }
+ else {
+ char *ep;
+ long iv = strtol(s,&ep,(int )pf);
+ if (*ep == 0) {
+ s_return(sc, mk_integer(sc, iv));
+ }
+ else {
+ s_return(sc, sc->F);
+ }
+ }
+ }
+ }
case OP_SYM2STR: /* symbol->string */
x=mk_string(sc,symname(car(sc->args)));
setimmutable(x);
s_return(sc,x);
- case OP_ATOM2STR: /* atom->string */
- x=car(sc->args);
- if(is_number(x) || is_character(x) || is_string(x) || is_symbol(x)) {
- char *p;
- int len;
- atom2str(sc,x,0,&p,&len);
- s_return(sc,mk_counted_string(sc,p,len));
- } else {
- Error_1(sc, "atom->string: not an atom:", x);
- }
+
+ case OP_ATOM2STR: /* atom->string */ {
+ long pf = 0;
+ x=car(sc->args);
+ if(cdr(sc->args)!=sc->NIL) {
+ /* we know cadr(sc->args) is a natural number */
+ /* see if it is 2, 8, 10, or 16, or error */
+ pf = ivalue_unchecked(cadr(sc->args));
+ if(is_number(x) && (pf == 16 || pf == 10 || pf == 8 || pf == 2)) {
+ /* base is OK */
+ }
+ else {
+ pf = -1;
+ }
+ }
+ if (pf < 0) {
+ Error_1(sc, "atom->string: bad base:", cadr(sc->args));
+ } else if(is_number(x) || is_character(x) || is_string(x) || is_symbol(x)) {
+ char *p;
+ int len;
+ atom2str(sc,x,(int )pf,&p,&len);
+ s_return(sc,mk_counted_string(sc,p,len));
+ } else {
+ Error_1(sc, "atom->string: not an atom:", x);
+ }
+ }
case OP_MKSTRING: { /* make-string */
gunichar fill=' ';
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]