mirror of
https://github.com/carp-lang/Carp.git
synced 2024-09-11 05:25:28 +03:00
core: made format not leak memory; test: added test for format and fmt
This commit is contained in:
parent
6a5e73e088
commit
7c9eaeac9f
@ -3,4 +3,5 @@
|
||||
(register /= (Fn [Bool Bool] Bool))
|
||||
(register str (Fn [Bool] String))
|
||||
(register copy (Fn [&Bool] Bool))
|
||||
(register format (Fn [&String Bool] String))
|
||||
)
|
||||
|
@ -4,6 +4,7 @@
|
||||
(register to-int (Fn [Char] Int))
|
||||
(register from-int (Fn [Int] Char))
|
||||
(register copy (Fn [&Char] Char))
|
||||
(register format (Fn [&String Char] String))
|
||||
|
||||
(defn random []
|
||||
(from-int (Int.random)))
|
||||
|
@ -39,7 +39,7 @@
|
||||
(register mod (Fn [Double Double] Double))
|
||||
(register copy (Fn [(Ref Double)] Double))
|
||||
(register abs (Fn [Double] Double))
|
||||
(register format (Fn [String Double] String))
|
||||
(register format (Fn [&String Double] String))
|
||||
|
||||
(defn clamp [min, max, val]
|
||||
(if (> val max)
|
||||
|
@ -11,7 +11,7 @@
|
||||
(register random-between (λ [Float Float] Float))
|
||||
(register str (Fn [Float] String))
|
||||
(register copy (Fn [(Ref Float)] Float))
|
||||
(register format (Fn [String Float] String))
|
||||
(register format (Fn [&String Float] String))
|
||||
|
||||
(register = (Fn [Float Float] Bool))
|
||||
(defn /= [x y]
|
||||
|
@ -17,9 +17,9 @@
|
||||
(if (= -1 next)
|
||||
(if (< 1 (count args))
|
||||
(macro-error "error in format string: too many arguments to format string")
|
||||
(list 'format (list 'copy s) (car args)))
|
||||
(list 'format s (car args)))
|
||||
(let [slice (String.substring s 0 (+ (inc idx) next))]
|
||||
(list 'String.append (list 'format (list 'copy slice) (car args))
|
||||
(list 'String.append (list 'format slice (car args))
|
||||
(fmt-internal (String.substring s (+ (inc idx) next) len)
|
||||
(cdr args)))))))))))
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
(register inc (λ [Int] Int))
|
||||
(register dec (λ [Int] Int))
|
||||
(register copy (λ [&Int] Int)) ;; TODO: Should not be needed when refs to value types are auto-converted to non-refs.
|
||||
(register format (Fn [String Int] String))
|
||||
(register format (Fn [&String Int] String))
|
||||
|
||||
(register safe-add (λ [Int Int (Ref Int)] Bool))
|
||||
(register safe-sub (λ [Int Int (Ref Int)] Bool))
|
||||
|
@ -1,6 +1,6 @@
|
||||
(definterface = (λ [a a] Bool))
|
||||
(definterface /= (λ [a a] Bool))
|
||||
(definterface format (λ [String a] String))
|
||||
(definterface format (λ [&String a] String))
|
||||
|
||||
(definterface zero (λ [] a))
|
||||
(definterface add-ref (λ [&a &a] a))
|
||||
|
@ -23,7 +23,7 @@
|
||||
(register to-int (λ [Long] Int))
|
||||
(register from-int (λ [Int] Long))
|
||||
(register copy (λ [&Long] Long)) ;; TODO: Should not be needed when refs to value types are auto-converted to non-refs.
|
||||
(register format (Fn [String Long] String))
|
||||
(register format (Fn [&String Long] String))
|
||||
|
||||
(defn /= [x y]
|
||||
(not (Long.= x y)))
|
||||
|
@ -12,7 +12,7 @@
|
||||
(register chars (Fn [&String] (Array Char)))
|
||||
(register from-chars (Fn [(Array Char)] String))
|
||||
(register tail (λ [(Ref String)] String))
|
||||
(register format (Fn [String String] String))
|
||||
(register format (Fn [&String &String] String))
|
||||
|
||||
(defn /= [a b]
|
||||
(not (= (the (Ref String) a) b)))
|
||||
|
45
core/core.h
45
core/core.h
@ -186,10 +186,10 @@ string Int_str(int x) {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
string Int_format(string str, int x) {
|
||||
int n = strlen(str) + 32;
|
||||
string Int_format(string* str, int x) {
|
||||
int n = strlen(*str) + 32;
|
||||
char *buffer = CARP_MALLOC(n+1);
|
||||
snprintf(buffer, n+1, str, x);
|
||||
snprintf(buffer, n+1, *str, x);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@ -224,10 +224,10 @@ string Long_str(long x) {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
string Long_format(string str, long x) {
|
||||
int n = strlen(str) + 32;
|
||||
string Long_format(string* str, long x) {
|
||||
int n = strlen(*str) + 32;
|
||||
char *buffer = CARP_MALLOC(n+1);
|
||||
snprintf(buffer, n+1, str, x);
|
||||
snprintf(buffer, n+1, *str, x);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@ -297,10 +297,10 @@ char String_char_MINUS_at(string* s, int i) {
|
||||
return (*s)[i];
|
||||
}
|
||||
|
||||
string String_format(string str, string s) {
|
||||
int n = strlen(s) + strlen(str);
|
||||
string String_format(string *str, string *s) {
|
||||
int n = strlen(*s) + strlen(*str);
|
||||
string buffer = CARP_MALLOC(n+1);
|
||||
snprintf(buffer, n+1, str, s);
|
||||
snprintf(buffer, n+1, *str, *s);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@ -353,6 +353,14 @@ char Char_copy(char *c) {
|
||||
return *c;
|
||||
}
|
||||
|
||||
string Char_format(string* str, char b) {
|
||||
int n = strlen(*str) + 32;
|
||||
char *buffer = CARP_MALLOC(n+1);
|
||||
snprintf(buffer, n+1, *str, b);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
// Double.toInt : Double -> Int
|
||||
int Double_to_MINUS_int(double x) {
|
||||
return (int)x;
|
||||
@ -470,10 +478,10 @@ double Double_random_MINUS_between(double lower, double upper) {
|
||||
return lower + diff * r;
|
||||
}
|
||||
|
||||
string Double_format(string s, double x) {
|
||||
int n = strlen(s) + 32;
|
||||
string Double_format(string* s, double x) {
|
||||
int n = strlen(*s) + 32;
|
||||
char *buffer = CARP_MALLOC(n+1);
|
||||
snprintf(buffer, n+1, s, x);
|
||||
snprintf(buffer, n+1, *s, x);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@ -585,10 +593,10 @@ string Float_str(float x) {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
string Float_format(string str, float x) {
|
||||
int n = strlen(str) + 32;
|
||||
string Float_format(string* str, float x) {
|
||||
int n = strlen(*str) + 32;
|
||||
char *buffer = CARP_MALLOC(n+1);
|
||||
snprintf(buffer, n+1, str, x);
|
||||
snprintf(buffer, n+1, *str, x);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@ -615,6 +623,13 @@ string Bool_str(bool b) {
|
||||
}
|
||||
}
|
||||
|
||||
string Bool_format(string* str, bool b) {
|
||||
int n = strlen(*str) + 32;
|
||||
char *buffer = CARP_MALLOC(n+1);
|
||||
snprintf(buffer, n+1, *str, b);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void System_exit(int code) {
|
||||
exit(code);
|
||||
}
|
||||
|
46
test/format.carp
Normal file
46
test/format.carp
Normal file
@ -0,0 +1,46 @@
|
||||
(load "Test.carp")
|
||||
(use Test)
|
||||
|
||||
(defn main []
|
||||
(with-test test
|
||||
(assert-equal test
|
||||
"c"
|
||||
&(format "%c" \c)
|
||||
"format works on chars"
|
||||
)
|
||||
(assert-equal test
|
||||
"1"
|
||||
&(format "%d" true)
|
||||
"format works on bools"
|
||||
)
|
||||
(assert-equal test
|
||||
"10"
|
||||
&(format "%d" 10)
|
||||
"format works on ints"
|
||||
)
|
||||
(assert-equal test
|
||||
"10"
|
||||
&(format "%ld" 10)
|
||||
"format works on longs"
|
||||
)
|
||||
(assert-equal test
|
||||
"10.0"
|
||||
&(format "%.1f" 10.0f)
|
||||
"format works on floats"
|
||||
)
|
||||
(assert-equal test
|
||||
"10.050"
|
||||
&(format "%2.3f" 10.05)
|
||||
"format works on doubles"
|
||||
)
|
||||
(assert-equal test
|
||||
"outside string: inside string :outside string"
|
||||
&(format "outside string: %s :outside string" "inside string")
|
||||
"format works on strings"
|
||||
)
|
||||
(assert-equal test
|
||||
"10 %% 12.0 yay"
|
||||
&(fmt "%d %% %.1f %s" 10 12.0 "yay")
|
||||
"fmt macro works"
|
||||
)
|
||||
(print-test-results test)))
|
Loading…
Reference in New Issue
Block a user