9a7e3f42736e98b2fdaccac90eb5b700b3ed96a9
[vlc.git] / compat / strtoll.c
1 /*****************************************************************************
2  * strtoll.c: C strtoll() replacement
3  *****************************************************************************
4  * Copyright © 1998-2010 VLC authors and VideoLAN
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation; either version 2.1 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19  *****************************************************************************/
20
21 #ifdef HAVE_CONFIG_H
22 # include <config.h>
23 #endif
24
25 #include <stdlib.h>
26 #include <string.h>
27
28 long long int strtoll( const char *nptr, char **endptr, int base )
29 {
30     long long i_value = 0;
31     int sign = 1, newbase = base ? base : 10;
32
33     nptr += strspn( nptr, "\t " );
34     if( *nptr == '-' )
35     {
36         sign = -1;
37         nptr++;
38     }
39
40     /* Try to detect base */
41     if( *nptr == '0' )
42     {
43         newbase = 8;
44         nptr++;
45
46         if( *nptr == 'x' )
47         {
48             newbase = 16;
49             nptr++;
50         }
51     }
52
53     if( base && newbase != base )
54     {
55         if( endptr ) *endptr = (char *)nptr;
56         return i_value;
57     }
58
59     switch( newbase )
60     {
61         case 10:
62             while( *nptr >= '0' && *nptr <= '9' )
63             {
64                 i_value *= 10;
65                 i_value += ( *nptr++ - '0' );
66             }
67             if( endptr ) *endptr = (char *)nptr;
68             break;
69
70         case 16:
71             while( (*nptr >= '0' && *nptr <= '9') ||
72                    (*nptr >= 'a' && *nptr <= 'f') ||
73                    (*nptr >= 'A' && *nptr <= 'F') )
74             {
75                 int i_valc = 0;
76                 if(*nptr >= '0' && *nptr <= '9') i_valc = *nptr - '0';
77                 else if(*nptr >= 'a' && *nptr <= 'f') i_valc = *nptr - 'a' +10;
78                 else if(*nptr >= 'A' && *nptr <= 'F') i_valc = *nptr - 'A' +10;
79                 i_value *= 16;
80                 i_value += i_valc;
81                 nptr++;
82             }
83             if( endptr ) *endptr = (char *)nptr;
84             break;
85
86         default:
87             i_value = strtol( nptr, endptr, newbase );
88             break;
89     }
90
91     return i_value * sign;
92 }