changeset 112:d03b011c50e9

Added missing file. This file is from the phobos source, with some modifications so that it can run in tango. Also slimed out unittests.
author Anders Johnsen <skabet@gmail.com>
date Sun, 25 May 2008 15:48:13 +0200
parents c658172ca8a0
children 244142a21cbc 3a0cd42de9cc
files basic/conv.d
diffstat 1 files changed, 464 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/basic/conv.d	Sun May 25 15:48:13 2008 +0200
@@ -0,0 +1,464 @@
+
+// Written in the D programming language.
+
+/*
+ *  Copyright (C) 2002-2006 by Digital Mars, www.digitalmars.com
+ *  Written by Walter Bright
+ *  Some parts contributed by David L. Davis
+ *
+ *  This software is provided 'as-is', without any express or implied
+ *  warranty. In no event will the authors be held liable for any damages
+ *  arising from the use of this software.
+ *
+ *  Permission is granted to anyone to use this software for any purpose,
+ *  including commercial applications, and to alter it and redistribute it
+ *  freely, subject to the following restrictions:
+ *
+ *  o  The origin of this software must not be misrepresented; you must not
+ *     claim that you wrote the original software. If you use this software
+ *     in a product, an acknowledgment in the product documentation would be
+ *     appreciated but is not required.
+ *  o  Altered source versions must be plainly marked as such, and must not
+ *     be misrepresented as being the original software.
+ *  o  This notice may not be removed or altered from any source
+ *     distribution.
+ */
+
+/***********
+ * Conversion building blocks. These differ from the C equivalents
+ * <tt>atoi()</tt> and <tt>atol()</tt> by
+ * checking for overflow and not allowing whitespace.
+ *
+ * For conversion to signed types, the grammar recognized is:
+ * <pre>
+$(I Integer):
+    $(I Sign UnsignedInteger)
+    $(I UnsignedInteger)
+
+$(I Sign):
+    $(B +)
+    $(B -)
+ * </pre>
+ * For conversion to signed types, the grammar recognized is:
+ * <pre>
+$(I UnsignedInteger):
+    $(I DecimalDigit)
+    $(I DecimalDigit) $(I UnsignedInteger)
+ * </pre>
+ * Macros:
+ *	WIKI=Phobos/StdConv
+ */
+
+
+/*************************
+  Changed to be used next to tango.
+
+  Unittests removed.
+ *************************/
+
+module basic.conv;
+
+private import tango.text.Util;  // for atof(), toString()
+private import tango.stdc.stringz;
+private import tango.stdc.ctype;
+private import tango.stdc.stdlib;
+private import tango.stdc.errno;
+//private import std.c.stdlib;
+//private import std.math;  // for fabs(), isnan()
+
+private
+{
+    extern (C) int getErrno();
+    extern (C) int setErrno(int);
+}
+
+//debug=conv;		// uncomment to turn on debugging printf's
+
+/* ************* Exceptions *************** */
+
+/**
+ * Thrown on conversion errors, which happens on deviation from the grammar.
+ */
+class ConvError : Exception
+{
+    this(char[] s)
+    {
+	super("conversion " ~ s);
+    }
+}
+
+private void conv_error(char[] s)
+{
+    throw new ConvError(s);
+}
+
+/**
+ * Thrown on conversion overflow errors.
+ */
+class ConvOverflowError : Exception
+{
+    this(char[] s)
+    {
+	super("Error: overflow " ~ s);
+    }
+}
+
+private void conv_overflow(char[] s)
+{
+    throw new ConvOverflowError(s);
+}
+
+/***************************************************************
+ * Convert character string to the return type.
+ */
+
+int toInt(char[] s)
+{
+    int length = s.length;
+
+    if (!length)
+	goto Lerr;
+
+    int sign = 0;
+    int v = 0;
+
+    for (int i = 0; i < length; i++)
+    {
+	char c = s[i];
+	if (c >= '0' && c <= '9')
+	{
+	    if (v < int.max/10 || (v == int.max/10 && c + sign <= '7'))
+		v = v * 10 + (c - '0');
+	    else
+		goto Loverflow;
+	}
+	else if (c == '-' && i == 0)
+	{
+	    sign = -1;
+	    if (length == 1)
+		goto Lerr;
+	}
+	else if (c == '+' && i == 0)
+	{
+	    if (length == 1)
+		goto Lerr;
+	}
+	else
+	    goto Lerr;
+    }
+    if (sign == -1)
+    {
+	if (cast(uint)v > 0x80000000)
+	    goto Loverflow;
+	v = -v;
+    }
+    else
+    {
+	if (cast(uint)v > 0x7FFFFFFF)
+	    goto Loverflow;
+    }
+    return v;
+
+Loverflow:
+    conv_overflow(s);
+
+Lerr:
+    conv_error(s);
+    return 0;
+}
+
+/*******************************************************
+ * ditto
+ */
+
+uint toUint(char[] s)
+{
+    int length = s.length;
+
+    if (!length)
+	goto Lerr;
+
+    uint v = 0;
+
+    for (int i = 0; i < length; i++)
+    {
+	char c = s[i];
+	if (c >= '0' && c <= '9')
+	{
+	    if (v < uint.max/10 || (v == uint.max/10 && c <= '5'))
+		v = v * 10 + (c - '0');
+	    else
+		goto Loverflow;
+	}
+	else
+	    goto Lerr;
+    }
+    return v;
+
+Loverflow:
+    conv_overflow(s);
+
+Lerr:
+    conv_error(s);
+    return 0;
+}
+
+/*******************************************************
+ * ditto
+ */
+
+long toLong(char[] s)
+{
+    int length = s.length;
+
+    if (!length)
+	goto Lerr;
+
+    int sign = 0;
+    long v = 0;
+
+    for (int i = 0; i < length; i++)
+    {
+	char c = s[i];
+	if (c >= '0' && c <= '9')
+	{
+	    if (v < long.max/10 || (v == long.max/10 && c + sign <= '7'))
+		v = v * 10 + (c - '0');
+	    else
+		goto Loverflow;
+	}
+	else if (c == '-' && i == 0)
+	{
+	    sign = -1;
+	    if (length == 1)
+		goto Lerr;
+	}
+	else if (c == '+' && i == 0)
+	{
+	    if (length == 1)
+		goto Lerr;
+	}
+	else
+	    goto Lerr;
+    }
+    if (sign == -1)
+    {
+	if (cast(ulong)v > 0x8000000000000000)
+	    goto Loverflow;
+	v = -v;
+    }
+    else
+    {
+	if (cast(ulong)v > 0x7FFFFFFFFFFFFFFF)
+	    goto Loverflow;
+    }
+    return v;
+
+Loverflow:
+    conv_overflow(s);
+
+Lerr:
+    conv_error(s);
+    return 0;
+}
+
+/*******************************************************
+ * ditto
+ */
+
+ulong toUlong(char[] s)
+{
+    int length = s.length;
+
+    if (!length)
+	goto Lerr;
+
+    ulong v = 0;
+
+    for (int i = 0; i < length; i++)
+    {
+	char c = s[i];
+	if (c >= '0' && c <= '9')
+	{
+	    if (v < ulong.max/10 || (v == ulong.max/10 && c <= '5'))
+		v = v * 10 + (c - '0');
+	    else
+		goto Loverflow;
+	}
+	else
+	    goto Lerr;
+    }
+    return v;
+
+Loverflow:
+    conv_overflow(s);
+
+Lerr:
+    conv_error(s);
+    return 0;
+}
+
+/*******************************************************
+ * ditto
+ */
+
+short toShort(char[] s)
+{
+    int v = toInt(s);
+
+    if (v != cast(short)v)
+	goto Loverflow;
+
+    return cast(short)v;
+
+Loverflow:
+    conv_overflow(s);
+    return 0;
+}
+
+/*******************************************************
+ * ditto
+ */
+
+ushort toUshort(char[] s)
+{
+    uint v = toUint(s);
+
+    if (v != cast(ushort)v)
+	goto Loverflow;
+
+    return cast(ushort)v;
+
+Loverflow:
+    conv_overflow(s);
+    return 0;
+}
+
+/*******************************************************
+ * ditto
+ */
+
+byte toByte(char[] s)
+{
+    int v = toInt(s);
+
+    if (v != cast(byte)v)
+	goto Loverflow;
+
+    return cast(byte)v;
+
+Loverflow:
+    conv_overflow(s);
+    return 0;
+}
+
+/*******************************************************
+ * ditto
+ */
+
+ubyte toUbyte(char[] s)
+{
+    uint v = toUint(s);
+
+    if (v != cast(ubyte)v)
+	goto Loverflow;
+
+    return cast(ubyte)v;
+
+Loverflow:
+    conv_overflow(s);
+    return 0;
+}
+
+/*******************************************************
+ * ditto
+ */
+
+float toFloat(in char[] s)
+{
+    float f;
+    char* endptr;
+    char* sz;
+
+    //writefln("toFloat('%s')", s);
+    sz = toStringz(s);
+    if (tango.stdc.ctype.isspace(*sz))
+	goto Lerr;
+
+    // BUG: should set __locale_decpoint to "." for DMC
+
+    setErrno(0);
+    f = strtof(sz, &endptr);
+    if (getErrno() == ERANGE)
+	goto Lerr;
+    if (endptr && (endptr == sz || *endptr != 0))
+	goto Lerr;
+
+    return f;
+        
+  Lerr:
+    conv_error(s ~ " not representable as a float");
+    assert(0);
+}
+
+/*******************************************************
+ * ditto
+ */
+
+double toDouble(in char[] s)
+{
+    double f;
+    char* endptr;
+    char* sz;
+
+    //writefln("toDouble('%s')", s);
+    sz = toStringz(s);
+    if (tango.stdc.ctype.isspace(*sz))
+	goto Lerr;
+
+    // BUG: should set __locale_decpoint to "." for DMC
+
+    setErrno(0);
+    f = strtod(sz, &endptr);
+    if (getErrno() == ERANGE)
+	goto Lerr;
+    if (endptr && (endptr == sz || *endptr != 0))
+	goto Lerr;
+
+    return f;
+        
+  Lerr:
+    conv_error(s ~ " not representable as a double");
+    assert(0);
+}
+
+/*******************************************************
+ * ditto
+ */
+real toReal(in char[] s)
+{
+    real f;
+    char* endptr;
+    char* sz;
+
+    //writefln("toReal('%s')", s);
+    sz = toStringz(s);
+    if (tango.stdc.ctype.isspace(*sz))
+	goto Lerr;
+
+    // BUG: should set __locale_decpoint to "." for DMC
+
+    setErrno(0);
+    f = strtold(sz, &endptr);
+    if (getErrno() == ERANGE)
+	goto Lerr;
+    if (endptr && (endptr == sz || *endptr != 0))
+	goto Lerr;
+
+    return f;
+        
+  Lerr:
+    conv_error(s ~ " not representable as a real");
+    assert(0);
+}
+