Imported Upstream version 1.1.11
[platform/upstream/cdrkit.git] / librols / astoll.c
1 /*
2  * This file has been modified for the cdrkit suite.
3  *
4  * The behaviour and appearence of the program code below can differ to a major
5  * extent from the version distributed by the original author(s).
6  *
7  * For details, see Changelog file distributed with the cdrkit package. If you
8  * received this file from another source then ask the distributing person for
9  * a log of modifications.
10  *
11  */
12
13 /* @(#)astoll.c 1.3 03/06/15 Copyright 1985, 2000-2003 J. Schilling */
14 /*
15  *      astoll() converts a string to long long
16  *
17  *      Leading tabs and spaces are ignored.
18  *      Both return pointer to the first char that has not been used.
19  *      Caller must check if this means a bad conversion.
20  *
21  *      leading "+" is ignored
22  *      leading "0"  makes conversion octal (base 8)
23  *      leading "0x" makes conversion hex   (base 16)
24  *
25  *      Llong is silently reverted to long if the compiler does not
26  *      support long long.
27  *
28  *      Copyright (c) 1985, 2000-2003 J. Schilling
29  */
30 /*
31  * This program is free software; you can redistribute it and/or modify
32  * it under the terms of the GNU General Public License version 2
33  * as published by the Free Software Foundation.
34  *
35  * This program is distributed in the hope that it will be useful,
36  * but WITHOUT ANY WARRANTY; without even the implied warranty of
37  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
38  * GNU General Public License for more details.
39  *
40  * You should have received a copy of the GNU General Public License along with
41  * this program; see the file COPYING.  If not, write to the Free Software
42  * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
43  */
44
45 #include <mconfig.h>
46 #include <standard.h>
47 #include <utypes.h>
48 #include <schily.h>
49
50 #define is_space(c)      ((c) == ' ' || (c) == '\t')
51 #define is_digit(c)      ((c) >= '0' && (c) <= '9')
52 #define is_hex(c)       (\
53                         ((c) >= 'a' && (c) <= 'f') || \
54                         ((c) >= 'A' && (c) <= 'F'))
55
56 #define to_lower(c)     (((c) >= 'A' && (c) <= 'Z') ? (c) - 'A'+'a' : (c))
57
58 char *
59 astoll(s, l)
60         register const char *s;
61         Llong *l;
62 {
63         return (astollb(s, l, 0));
64 }
65
66 char *
67 astollb(s, l, base)
68         register const char *s;
69         Llong *l;
70         register int base;
71 {
72         int neg = 0;
73         register Llong ret = (Llong)0;
74         register int digit;
75         register char c;
76
77         while (is_space(*s))
78                 s++;
79
80         if (*s == '+') {
81                 s++;
82         } else if (*s == '-') {
83                 s++;
84                 neg++;
85         }
86
87         if (base == 0) {
88                 if (*s == '0') {
89                         base = 8;
90                         s++;
91                         if (*s == 'x' || *s == 'X') {
92                                 s++;
93                                 base = 16;
94                         }
95                 } else {
96                         base = 10;
97                 }
98         }
99         for (; (c = *s) != 0; s++) {
100
101                 if (is_digit(c)) {
102                         digit = c - '0';
103                 } else if (is_hex(c)) {
104                         digit = to_lower(c) - 'a' + 10;
105                 } else {
106                         break;
107                 }
108
109                 if (digit < base) {
110                         ret *= base;
111                         ret += digit;
112                 } else {
113                         break;
114                 }
115         }
116         if (neg)
117                 ret = -ret;
118         *l = ret;
119         return ((char *)s);
120 }