Added script front-end for primer-design code
[htsworkflow.git] / htswanalysis / MACS / lib / gsl / gsl-1.11 / utils / strtol.c
1 /* Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc.
2
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 3 of the
8 License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB.  If
17 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
18 Cambridge, MA 02110-1301, USA.  */
19
20 #include <ctype.h>
21 #include <limits.h>
22 #include <stddef.h>
23 #include <stdlib.h>
24 #include <errno.h>
25
26 #ifndef UNSIGNED
27 #define UNSIGNED        0
28 #endif
29
30 /* Convert NPTR to an `unsigned long int' or `long int' in base BASE.
31    If BASE is 0 the base is determined by the presence of a leading
32    zero, indicating octal or a leading "0x" or "0X", indicating hexadecimal.
33    If BASE is < 2 or > 36, it is reset to 10.
34    If ENDPTR is not NULL, a pointer to the character after the last
35    one converted is stored in *ENDPTR.  */
36 #if     UNSIGNED
37 unsigned long int
38 #define strtol  strtoul
39 #else
40 long int
41 #endif
42 strtol (nptr, endptr, base)
43      const char *nptr;
44      char **endptr;
45      int base;
46 {
47   int negative;
48   register unsigned long int cutoff;
49   register unsigned int cutlim;
50   register unsigned long int i;
51   register const char *s;
52   register unsigned char c;
53   const char *save;
54   int overflow;
55
56   if (base < 0 || base == 1 || base > 36)
57     base = 10;
58
59   s = nptr;
60
61   /* Skip white space.  */
62   while (isspace (*s))
63     ++s;
64   if (*s == '\0')
65     goto noconv;
66
67   /* Check for a sign.  */
68   if (*s == '-')
69     {
70       negative = 1;
71       ++s;
72     }
73   else if (*s == '+')
74     {
75       negative = 0;
76       ++s;
77     }
78   else
79     negative = 0;
80
81   if (base == 16 && s[0] == '0' && toupper (s[1]) == 'X')
82     s += 2;
83
84   /* If BASE is zero, figure it out ourselves.  */
85   if (base == 0)
86     if (*s == '0')
87       {
88         if (toupper (s[1]) == 'X')
89           {
90             s += 2;
91             base = 16;
92           }
93         else
94           base = 8;
95       }
96     else
97       base = 10;
98
99   /* Save the pointer so we can check later if anything happened.  */
100   save = s;
101
102   cutoff = ULONG_MAX / (unsigned long int) base;
103   cutlim = ULONG_MAX % (unsigned long int) base;
104
105   overflow = 0;
106   i = 0;
107   for (c = *s; c != '\0'; c = *++s)
108     {
109       if (isdigit (c))
110         c -= '0';
111       else if (isalpha (c))
112         c = toupper (c) - 'A' + 10;
113       else
114         break;
115       if (c >= base)
116         break;
117       /* Check for overflow.  */
118       if (i > cutoff || (i == cutoff && c > cutlim))
119         overflow = 1;
120       else
121         {
122           i *= (unsigned long int) base;
123           i += c;
124         }
125     }
126
127   /* Check if anything actually happened.  */
128   if (s == save)
129     goto noconv;
130
131   /* Store in ENDPTR the address of one character
132      past the last character we converted.  */
133   if (endptr != NULL)
134     *endptr = (char *) s;
135
136 #if     !UNSIGNED
137   /* Check for a value that is within the range of
138      `unsigned long int', but outside the range of `long int'.  */
139   if (i > (negative ?
140            -(unsigned long int) LONG_MIN : (unsigned long int) LONG_MAX))
141     overflow = 1;
142 #endif
143
144   if (overflow)
145     {
146       errno = ERANGE;
147 #if     UNSIGNED
148       return ULONG_MAX;
149 #else
150       return negative ? LONG_MIN : LONG_MAX;
151 #endif
152     }
153
154   /* Return the result of the appropriate sign.  */
155   return (negative ? -i : i);
156
157 noconv:
158   /* There was no number to convert.  */
159   if (endptr != NULL)
160     *endptr = (char *) nptr;
161   return 0L;
162 }