History

str->num: ignore leading and trailing whitespace

Sigrid Solveig Haflínudóttir committed 3 months ago

Commit fa39cec1 parent 09b46d94 files · +34 −17Browse files

Showing the changes to src (3 of 4 files). Show all

Unified · Split

3 files
  1. src/docs.sl +2 −2
  2. src/read.c +22 −14
  3. src/str.c +9 −0
src/docs.sl+2−2
@@ -482,8 +482,8 @@ · 481 unmodified lines
482(defdoc (str->num s (:base NIL))482(defdoc (str->num s (:base NIL))
483 «Return the number using the radix `base` in the string `s`.483 «Return the number using the radix `base` in the string `s`.
484 484
485 Returns `NIL` if the number could not be parsed or there were485 Returns `NIL` if the number could not be parsed. Any number of leading
486 left-over trailing characters.»486 and/or trailing whitespace runes is allowed and those will be ignored.»
487 :doc-example487 :doc-example
488 «(str->num "1.2")488 «(str->num "1.2")
489 ; ↳ 1.2»489 ; ↳ 1.2»
src/read.c+22−14
@@ -42,19 +42,19 @@ sl_read_numtok(const char *tok, sl_v *pval, int base) · 41 unmodified lines
42 s64int i64;42 s64int i64;
43 double d;43 double d;
44 44
45 if(sl_unlikely(*tok == '\0'))45 if(sl_unlikely(*tok == 0))
46 return false;46 return false;
47 if(!((tok[0] == '0' && tok[1] == 'x') || (base >= 15)) && strpbrk(tok, ".eEpP") != nil){47 if(!((tok[0] == '0' && tok[1] == 'x') || (base >= 15)) && strpbrk(tok, ".eEpP") != nil){
48 d = strtod(tok, &end);48 d = strtod(tok, &end);
49 if(sl_unlikely(*end == '\0')){49 if(sl_unlikely(*end == 0)){
50 if(pval != nil)50 if(pval != nil)
51 *pval = mk_f64(d);51 *pval = mk_f64(d);
52 return true;52 return true;
53 }53 }
54 // floats can end in f or f054 // floats can end in f or f0
55 if(end > tok && end[0] == 'f' &&55 if(end > tok && end[0] == 'f' &&
56 (end[1] == '\0' ||56 (end[1] == 0 ||
57 (end[1] == '0' && end[2] == '\0'))){57 (end[1] == '0' && end[2] == 0))){
58 if(pval != nil)58 if(pval != nil)
59 *pval = mk_f32((float)d);59 *pval = mk_f32((float)d);
60 return true;60 return true;
@@ -77,8 +77,12 @@ sl_read_numtok(const char *tok, sl_v *pval, int base) · 16 unmodified lines
77 i64 = INT64_MAX;77 i64 = INT64_MAX;
78 else{78 else{
79 i64 = strtoll(tok, &end, base);79 i64 = strtoll(tok, &end, base);
80 if(*end != '\0')80 if(*end != 0){
81 return false;81 Rune r;
82 chartorune(&r, end);
83 if(!isspacerune(r))
84 return false;
85 }
82 }86 }
83 if(sl_unlikely(pval == nil))87 if(sl_unlikely(pval == nil))
84 return true;88 return true;
@@ -89,9 +93,13 @@ sl_read_numtok(const char *tok, sl_v *pval, int base) · 4 unmodified lines
89 mpint *m = strtomp(tok, &end, base, nil);93 mpint *m = strtomp(tok, &end, base, nil);
90 if(m == nil)94 if(m == nil)
91 return false;95 return false;
92 if(end != tok+strlen(tok)){96 if(*end != 0){
93 mpfree(m);97 Rune r;
94 return false;98 chartorune(&r, end);
99 if(!isspacerune(r)){
100 mpfree(m);
101 return false;
102 }
95 }103 }
96 if(mpsignif(m) >= FIXNUM_BITS){104 if(mpsignif(m) >= FIXNUM_BITS){
97 *pval = mk_bignum(m);105 *pval = mk_bignum(m);
@@ -207,7 +215,7 @@ read_token(Rune c, bool digits) · 109 unmodified lines
207 if(sl_unlikely(nc == 0))215 if(sl_unlikely(nc == 0))
208 cthrow(parse_error("unexpected char: #x%"PRIx32, c), c);216 cthrow(parse_error("unexpected char: #x%"PRIx32, c), c);
209terminate:217terminate:
210 RS->buf[i++] = '\0';218 RS->buf[i++] = 0;
211 return issym;219 return issym;
212}220}
213 221
@@ -357,7 +365,7 @@ again: · 143 unmodified lines
357 }else365 }else
358 cthrow(parse_error( "invalid label: #%s%c", RS->buf, ch), dummy);366 cthrow(parse_error( "invalid label: #%s%c", RS->buf, ch), dummy);
359 x = strtoll(RS->buf, &end, 10);367 x = strtoll(RS->buf, &end, 10);
360 if(*end != '\0')368 if(*end != 0)
361 cthrow(parse_error("invalid label: #%s%c", RS->buf, ch), dummy);369 cthrow(parse_error("invalid label: #%s%c", RS->buf, ch), dummy);
362 RS->tokval = fixnum(x);370 RS->tokval = fixnum(x);
363 }else if(sl_unlikely(c == '!')){371 }else if(sl_unlikely(c == '!')){
@@ -410,7 +418,7 @@ again: · 46 unmodified lines
410 RS->tokval = mk_sym(RS->buf, true);418 RS->tokval = mk_sym(RS->buf, true);
411 }else{419 }else{
412 x = strtol(RS->buf, &end, 10);420 x = strtol(RS->buf, &end, 10);
413 if(*end != '\0' || RS->buf[0] == '\0')421 if(*end != 0 || RS->buf[0] == 0)
414 cthrow(parse_error("invalid gensym label: #%s", RS->buf), dummy);422 cthrow(parse_error("invalid gensym label: #%s", RS->buf), dummy);
415 RS->tokval = fixnum(x);423 RS->tokval = fixnum(x);
416 }424 }
@@ -636,7 +644,7 @@ read_str(int dummy) · 219 unmodified lines
636 break;644 break;
637 ios_getc(IO);645 ios_getc(IO);
638 }646 }
639 eseq[j] = '\0';647 eseq[j] = 0;
640 r = strtol(eseq, nil, 8);648 r = strtol(eseq, nil, 8);
641 // \DDD and \xXX read bytes, not runes649 // \DDD and \xXX read bytes, not runes
642 buf[i++] = r;650 buf[i++] = r;
@@ -648,7 +656,7 @@ read_str(int dummy) · 5 unmodified lines
648 eseq[j++] = c;656 eseq[j++] = c;
649 ios_getc(IO);657 ios_getc(IO);
650 }658 }
651 eseq[j] = '\0';659 eseq[j] = 0;
652 if(j)660 if(j)
653 r = strtol(eseq, nil, 16);661 r = strtol(eseq, nil, 16);
654 if(!j || r > Runemax){662 if(!j || r > Runemax){
src/str.c+9−0
@@ -724,6 +724,15 @@ BUILTIN("str->num", str_2_num) · 723 unmodified lines
724 if(nargs != 1)724 if(nargs != 1)
725 argcount(1);725 argcount(1);
726 char *s = tostr(args[0]), *e;726 char *s = tostr(args[0]), *e;
727 for(;;){
728 Rune r;
729 int n = chartorune(&r, s);
730 if(r == Runeerror)
731 return sl_nil;
732 if(!isspacerune(r))
733 break;
734 s += n;
735 }
727 sl_v n;736 sl_v n;
728 int base = 10;737 int base = 10;
729 if(nonnil(values[0]))738 if(nonnil(values[0]))

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t