[Mono-dev] [Patch] Support for exponents in Int32.Parse
Hey! I was going to commit the attached patch, in order to support exponent notation in our Int32.Parse method (as declared in NumberStyles.AllowExponent). But then I thought it would be a good idea to throw the patch to the public, in case somebody is interested - specially in the overflow handling. Carlos. Index: Int32.cs === --- Int32.cs (revisiĆ³n: 148618) +++ Int32.cs (copia de trabajo) @@ -274,21 +274,52 @@ } } - internal static bool FindExponent (ref int pos, string s) + internal static bool FindExponent (ref int pos, string s, ref int exponent, bool tryParse, ref Exception exc) { +exponent = 0; +long exp = 0; // temp long value + int i = s.IndexOfAny(new char [] {'e', 'E'}, pos); -if (i 0) - return false; -if (++i == s.Length) - return false; -if (s [i] == '+' || s [i] == '-') - if (++i == s.Length) -return false; -if (!Char.IsDigit (s [i])) - return false; -for (; i s.Length; ++i) - if (!Char.IsDigit (s [i])) -break; +if (i 0) { + exc = null; + return false; +} + +if (++i == s.Length) { + exc = tryParse ? null : GetFormatException (); + return true; +} + +// negative exponent not valid for Int32 +if (s [i] == '-') { + exc = tryParse ? null : new OverflowException (Value too large or too small.); + return true; +} + +if (s [i] == '+' ++i == s.Length) { + exc = tryParse ? null : GetFormatException (); + return true; +} + +for (; i s.Length; i++) { + if (!Char.IsDigit (s [i])) { + exc = tryParse ? null : GetFormatException (); + return true; + } + + // Reduce the risk of throwing an overflow exc + exp = checked (exp * 10 - (int) (s [i] - '0')); + if (exp Int32.MinValue || exp Int32.MaxValue) { + exc = tryParse ? null : new OverflowException (Value too large or too small.); + return true; + } +} + +// exp value saved as negative +exp = -exp; + +exc = null; +exponent = (int)exp; pos = i; return true; } @@ -430,6 +461,7 @@ bool decimalPointFound = false; int digitValue; char hexDigit; + int exponent = 0; // Number stuff do { @@ -504,8 +536,9 @@ return false; } - if (AllowExponent) - FindExponent(ref pos, s); + if (AllowExponent) +if (FindExponent (ref pos, s, ref exponent, tryParse, ref exc) exc != null) + return false; if (AllowTrailingSign !foundSign) { // Sign + Currency @@ -561,6 +594,19 @@ } else number = checked (-number); } + + // result *= 10^exponent + if (exponent 0) { +// Reduce the risk of throwing an overflow exc +double res = checked (Math.Pow (10, exponent) * number); +if (res Int32.MinValue || res Int32.MaxValue) { + if (!tryParse) + exc = new OverflowException (Value too large or too small.); + return false; +} + +number = (int)res; + } result = number; Index: Int32Test.cs === --- Int32Test.cs (revisiĆ³n: 148618) +++ Int32Test.cs (copia de trabajo) @@ -235,6 +235,59 @@ Int32.Parse (123, new DateTimeFormatInfo ()); } + [Test] + public void TestParseExponent () + { + Assert.AreEqual (2, Int32.Parse (2E0, NumberStyles.AllowExponent), A#1); + Assert.AreEqual (20, Int32.Parse (2E1, NumberStyles.AllowExponent), A#2); + Assert.AreEqual (200, Int32.Parse (2E2, NumberStyles.AllowExponent), A#3); + Assert.AreEqual (200, Int32.Parse (2E6, NumberStyles.AllowExponent), A#4); + Assert.AreEqual (200, Int32.Parse (2E+2, NumberStyles.AllowExponent), A#5); + + try { + Int32.Parse (2E); + Assert.Fail (B#1); + } catch (FormatException) { + } + + try { + Int32.Parse (2E3.0, NumberStyles.AllowExponent); // decimal notation for the exponent + Assert.Fail (B#2); + } catch (FormatException) { + } + + try { + Int32.Parse (2E 2, NumberStyles.AllowExponent); + Assert.Fail (B#3); + } catch (FormatException) { + } + + try { + Int32.Parse (2E2 , NumberStyles.AllowExponent); + Assert.Fail (B#4); + } catch (FormatException) { + } + + try { + Int32.Parse (2E66, NumberStyles.AllowExponent); // final result overflow + Assert.Fail (B#5); + } catch (OverflowException) { + } + + try { + long exponent = (long)Int32.MaxValue + 10; + Int32.Parse (2E + exponent.ToString (), NumberStyles.AllowExponent); + Assert.Fail (B#6); + } catch (OverflowException) { + } + + try { + Int32.Parse (2E-1, NumberStyles.AllowExponent); // negative exponent + Assert.Fail (B#7); + } catch (OverflowException) { + } + } + #if NET_2_0 [Test] public void TestTryParse() ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
[Mono-dev] LLVM backend won't compile
Hi, I'm configuring Mono 2.6.1 with --enable-llvm and can see that configure picks up the llvm-config script, but subsequently compiling gives errors due to missing LLVM include paths: 18:14|me...@juggle2:~/c/mono-2.6.1 ./configure --prefix=/home/melis/mono --enable-llvm [...] checking for llvm-config... /home/melis/llvm/bin/llvm-config [...] DTrace:no Parallel Mark: yes LLVM Back End: yes IMPORTANT: IMPORTANT: The LLVM Back End is experimental and has known problems. IMPORTANT: 18:17|me...@juggle2:~/c/mono-2.6.1 make [...] make[3]: Entering directory `/home/melis/c/mono-2.6.1/mono/mini' make all-am make[4]: Entering directory `/home/melis/c/mono-2.6.1/mono/mini' CC mini-llvm.lo mini-llvm.c:14:25: error: llvm-c/Core.h: No such file or directory mini-llvm.c:15:36: error: llvm-c/ExecutionEngine.h: No such file or directory mini-llvm.c:17:27: error: mini-llvm-cpp.h: No such file or directory mini-llvm.c:23: error: expected specifier-qualifier-list before 'LLVMModuleRef' mini-llvm.c:39: error: expected specifier-qualifier-list before 'LLVMValueRef' mini-llvm.c:112: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'cond_to_llvm_cond' mini-llvm.c:125: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'fpcond_to_llvm_cond' mini-llvm.c:138: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'ee' mini-llvm.c:150: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'IntPtrType' mini-llvm.c:179: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'type_to_llvm_type' Btw, I can't seem to find the switch to make to have it output the command it's executing (for checking -I flags)... Paul ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] LLVM backend won't compile
Hi, Btw, I can't seem to find the switch to make to have it output the command it's executing (for checking -I flags)... Its make V=1, just like with the linux kernel. Zoltan Paul ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] LLVM backend won't compile
Zoltan Varga wrote: Hi, Btw, I can't seem to find the switch to make to have it output the command it's executing (for checking -I flags)... Its make V=1, just like with the linux kernel. Ah, didn't know that :) Well, it seems the llvm include path is missing: [...] make[4]: Entering directory `/home/melis/c/mono-2.6.1/mono/mini' ../../doltcompile /home/melis/local/bin/gcc -DHAVE_CONFIG_H -I. -I../.. -DGC_LINUX_THREADS -D_GNU_SOURCE -D_REENTRANT -DUSE_MMAP -DUSE_MUNMAP -D_FILE_OFFSET_BITS=64 -DUSE_COMPILER_TLS -I../.. -I../../libgc/include -pthread -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -g -O2 -fno-strict-aliasing -Wdeclaration-after-statement -g -Wall -Wunused -Wmissing-prototypes -Wmissing-declarations -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Wpointer-arith -Wno-cast-qual -Wwrite-strings -mno-tls-direct-seg-refs -MT mini-llvm.lo -MD -MP -MF .deps/mini-llvm.Tpo -c -o mini-llvm.lo mini-llvm.c mini-llvm.c:14:25: error: llvm-c/Core.h: No such file or directory mini-llvm.c:15:36: error: llvm-c/ExecutionEngine.h: No such file or directory mini-llvm.c:17:27: error: mini-llvm-cpp.h: No such file or directory mini-llvm.c:23: error: expected specifier-qualifier-list before 'LLVMModuleRef' mini-llvm.c:39: error: expected specifier-qualifier-list before 'LLVMValueRef' [...] I do see the correct values in mono/mini/Makefile though: LLVM_CONFIG = /home/melis/llvm/bin/llvm-config LLVM_CXXFLAGS = -I/home/melis/llvm/include -D_DEBUG -D_GNU_SOURCE -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -O2 -fomit-frame-pointer -fPIC LLVM_LDFLAGS = -L/home/melis/llvm/lib -lpthread -lffi -ldl -lm LLVM_LIBS = -L/home/melis/llvm/lib -lpthread -lffi -ldl -lm -lLLVMX86CodeGen -lLLVMX86Info -lLLVMX86Disassembler -lLLVMSelectionDAG -lLLVMAsmPrinter -lLLVMJIT -lLLVMExecutionEngine -lLLVMCodeGen -lLLVMScalarOpts -lLLVMTransformUtils -lLLVMipa -lLLVMAnalysis -lLLVMTarget -lLLVMMC -lLLVMBitWriter -lLLVMCore -lLLVMSupport -lLLVMSystem -lstdc++ A bug in the build system? Paul ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] LLVM backend won't compile
Hi, This is now fixed in SVN HEAD/2.6 branches. Zoltan On Mon, Dec 21, 2009 at 6:55 PM, Paul Melis mono-de...@assumetheposition.nl wrote: Zoltan Varga wrote: Hi, Btw, I can't seem to find the switch to make to have it output the command it's executing (for checking -I flags)... Its make V=1, just like with the linux kernel. Ah, didn't know that :) Well, it seems the llvm include path is missing: [...] make[4]: Entering directory `/home/melis/c/mono-2.6.1/mono/mini' ../../doltcompile /home/melis/local/bin/gcc -DHAVE_CONFIG_H -I. -I../.. -DGC_LINUX_THREADS -D_GNU_SOURCE -D_REENTRANT -DUSE_MMAP -DUSE_MUNMAP -D_FILE_OFFSET_BITS=64 -DUSE_COMPILER_TLS -I../.. -I../../libgc/include -pthread -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -g -O2 -fno-strict-aliasing -Wdeclaration-after-statement -g -Wall -Wunused -Wmissing-prototypes -Wmissing-declarations -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Wpointer-arith -Wno-cast-qual -Wwrite-strings -mno-tls-direct-seg-refs -MT mini-llvm.lo -MD -MP -MF .deps/mini-llvm.Tpo -c -o mini-llvm.lo mini-llvm.c mini-llvm.c:14:25: error: llvm-c/Core.h: No such file or directory mini-llvm.c:15:36: error: llvm-c/ExecutionEngine.h: No such file or directory mini-llvm.c:17:27: error: mini-llvm-cpp.h: No such file or directory mini-llvm.c:23: error: expected specifier-qualifier-list before 'LLVMModuleRef' mini-llvm.c:39: error: expected specifier-qualifier-list before 'LLVMValueRef' [...] I do see the correct values in mono/mini/Makefile though: LLVM_CONFIG = /home/melis/llvm/bin/llvm-config LLVM_CXXFLAGS = -I/home/melis/llvm/include -D_DEBUG -D_GNU_SOURCE -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -O2 -fomit-frame-pointer -fPIC LLVM_LDFLAGS = -L/home/melis/llvm/lib -lpthread -lffi -ldl -lm LLVM_LIBS = -L/home/melis/llvm/lib -lpthread -lffi -ldl -lm -lLLVMX86CodeGen -lLLVMX86Info -lLLVMX86Disassembler -lLLVMSelectionDAG -lLLVMAsmPrinter -lLLVMJIT -lLLVMExecutionEngine -lLLVMCodeGen -lLLVMScalarOpts -lLLVMTransformUtils -lLLVMipa -lLLVMAnalysis -lLLVMTarget -lLLVMMC -lLLVMBitWriter -lLLVMCore -lLLVMSupport -lLLVMSystem -lstdc++ A bug in the build system? Paul ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] LLVM backend won't compile
Hello, I noticed this problem on trunk, and I was fixing the Makefiles, but I forgot to commit the code before I left. The fix is simple, just add the LLVM_CFLAGS to the Makefile.am's definitions. On Dec 21, 2009, at 12:55 PM, Paul Melis wrote: Zoltan Varga wrote: Hi, Btw, I can't seem to find the switch to make to have it output the command it's executing (for checking -I flags)... Its make V=1, just like with the linux kernel. Ah, didn't know that :) Well, it seems the llvm include path is missing: [...] make[4]: Entering directory `/home/melis/c/mono-2.6.1/mono/mini' ../../doltcompile /home/melis/local/bin/gcc -DHAVE_CONFIG_H -I. -I../.. -DGC_LINUX_THREADS -D_GNU_SOURCE -D_REENTRANT -DUSE_MMAP -DUSE_MUNMAP -D_FILE_OFFSET_BITS=64 -DUSE_COMPILER_TLS -I../.. -I../../libgc/include -pthread -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -g -O2 -fno-strict-aliasing -Wdeclaration-after-statement -g -Wall -Wunused -Wmissing-prototypes -Wmissing-declarations -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Wpointer-arith -Wno-cast-qual -Wwrite-strings -mno-tls-direct-seg-refs -MT mini-llvm.lo -MD -MP -MF .deps/mini-llvm.Tpo -c -o mini-llvm.lo mini-llvm.c mini-llvm.c:14:25: error: llvm-c/Core.h: No such file or directory mini-llvm.c:15:36: error: llvm-c/ExecutionEngine.h: No such file or directory mini-llvm.c:17:27: error: mini-llvm-cpp.h: No such file or directory mini-llvm.c:23: error: expected specifier-qualifier-list before 'LLVMModuleRef' mini-llvm.c:39: error: expected specifier-qualifier-list before 'LLVMValueRef' [...] I do see the correct values in mono/mini/Makefile though: LLVM_CONFIG = /home/melis/llvm/bin/llvm-config LLVM_CXXFLAGS = -I/home/melis/llvm/include -D_DEBUG -D_GNU_SOURCE -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -O2 -fomit-frame-pointer -fPIC LLVM_LDFLAGS = -L/home/melis/llvm/lib -lpthread -lffi -ldl -lm LLVM_LIBS = -L/home/melis/llvm/lib -lpthread -lffi -ldl -lm -lLLVMX86CodeGen -lLLVMX86Info -lLLVMX86Disassembler -lLLVMSelectionDAG -lLLVMAsmPrinter -lLLVMJIT -lLLVMExecutionEngine -lLLVMCodeGen -lLLVMScalarOpts -lLLVMTransformUtils -lLLVMipa -lLLVMAnalysis -lLLVMTarget -lLLVMMC -lLLVMBitWriter -lLLVMCore -lLLVMSupport -lLLVMSystem -lstdc++ A bug in the build system? Paul ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list