compiler/clib/include: Moved sys/fs_types.h inside sys/mount.h
[AROS.git] / compiler / clib / atol.c
blob90c1f6fa4d3dd04c9bf91a4d89e94709c5f4231f
1 /*
2 Copyright © 1995-2003, The AROS Development Team. All rights reserved.
3 $Id$
5 ANSI C function atol().
6 */
8 #include <limits.h>
9 #include <ctype.h>
11 /*****************************************************************************
13 NAME */
14 #include <stdlib.h>
16 long atol (
18 /* SYNOPSIS */
19 const char * str)
21 /* FUNCTION
22 Convert a string of digits into an long integer.
24 INPUTS
25 str - The string which should be converted. Leading
26 whitespace are ignored. The number may be prefixed
27 by a '+' or '-'.
29 RESULT
30 The value of string str.
32 NOTES
34 EXAMPLE
35 // returns 1
36 atol (" \t +1");
38 // returns 1
39 atol ("1");
41 // returns -1
42 atol (" \n -1");
44 BUGS
46 SEE ALSO
47 atof(), atoi(), strtod(), strtol(), strtoul()
49 INTERNALS
51 ******************************************************************************/
53 unsigned long val = 0;
54 int digit;
55 char c = 0;
56 unsigned long cutoff;
57 int cutlim;
58 int any;
60 while (isspace (*str))
61 str ++;
63 if (*str)
65 if (*str == '+' || *str == '-')
66 c = *str ++;
69 Conversion loop, from FreeBSD's src/lib/libc/stdlib/strtoul.c
71 The previous AROS loop was
72 a) inefficient - it did a division each time around.
73 b) buggy - it returned the wrong value in endptr on overflow.
75 cutoff = (unsigned long)ULONG_MAX / (unsigned long)10;
76 cutlim = (unsigned long)ULONG_MAX % (unsigned long)10;
77 val = 0;
78 any = 0;
80 while (*str)
82 digit = *str;
84 if (!isdigit(digit))
85 break;
87 digit -= '0';
90 any < 0 when we have overflowed. We still need to find the
91 end of the subject sequence
93 if (any < 0 || val > cutoff || (val == cutoff && digit > cutlim))
95 any = -1;
97 else
99 any = 1;
100 val = (val * 10) + digit;
103 str++;
106 /* Range overflow */
107 if (any < 0)
109 val = ULONG_MAX;
112 if (c == '-')
113 val = -val;
116 return val;
117 } /* atol */