1 /*
2 * Copyright (c) 2003-2017 Cavium Inc. ([email protected]). All rights
3 * reserved.
4 * Copyright 2018-present Facebook, Inc.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 *
8 * string.c: hastily cobbled-together string functions
9 */
10
11 #include <assert.h>
12 #include <ctype.h>
13 #include <string.h>
14 #include <lame_string.h>
15
char_to_val(char c)16 static int char_to_val(char c)
17 {
18 if (c >= '0' && c <= '9') /* digits */
19 return c - '0';
20 if (c >= 'A' && c <= 'F') /* uppercase */
21 return c - 'A' + 10;
22 if (c >= 'a' && c <= 'f') /* lowercase */
23 return c - 'a' + 10;
24 return -1;
25 }
26
strtoull(const char * nptr,char ** endptr,int base)27 unsigned long long int strtoull(const char *nptr, char **endptr, int base)
28 {
29 unsigned long long int val;
30 size_t i, error = 0;
31
32 /* TODO: enforce lameness of this API for now... */
33 assert((base == 0) || (base == 16) || base == 10);
34
35 if (!nptr)
36 return 0;
37
38 /* Trim whitespace */
39 for (i = 0; i < strlen(nptr); i++)
40 if (nptr[i] != ' ')
41 break;
42
43 if (base == 0) {
44 /* Autodetect base */
45 if (strlen(&nptr[i]) >= 2 && ((nptr[i] == '0') &&
46 ((nptr[i + 1] == 'x') || (nptr[i + 1] == 'X')))) {
47 base = 16;
48 i += 2; /* start loop after prefix */
49 } else
50 base = 10;
51 }
52
53 val = 0;
54 for (; i < strlen(nptr); i++) {
55 if (base == 16) {
56 if (!isxdigit(nptr[i])) {
57 if (*endptr)
58 *endptr = (char *)&nptr[i];
59 error = 1;
60 break;
61 }
62 } else {
63 if (!isdigit(nptr[i])) {
64 if (*endptr)
65 *endptr = (char *)&nptr[i];
66 error = 1;
67 break;
68 }
69 }
70
71 val *= base;
72 val += char_to_val(nptr[i]);
73 }
74
75 if (error) {
76 printk(BIOS_ERR, "Failed to convert string '%s', base %d to "
77 "int\n", nptr, base);
78 return 0;
79 }
80 return val;
81 }
82
strtoul(const char * nptr,char ** endptr,int base)83 unsigned long int strtoul(const char *nptr, char **endptr, int base)
84 {
85 unsigned long long int u = strtol(nptr, endptr, base);
86 /* FIXME: check for overflow (u > max) */
87 return (unsigned long int)u;
88 }
89
strtol(const char * nptr,char ** endptr,int base)90 long int strtol(const char *nptr, char **endptr, int base)
91 {
92 unsigned long long int u;
93 int is_neg = 0;
94 const char *p;
95 long int ret;
96
97 if (nptr[0] == '-') {
98 is_neg = 1;
99 p = &nptr[1];
100 } else {
101 p = &nptr[0];
102 }
103 u = strtoull(p, NULL, base);
104 /* FIXME: check for overflow (u > max) */
105 if (is_neg)
106 ret = 0 - (long int)u;
107 else
108 ret = (long int)u;
109 return ret;
110 }
111
strtoll(const char * nptr,char ** endptr,int base)112 long long int strtoll(const char *nptr, char **endptr, int base)
113 {
114 unsigned long long int u;
115 int is_neg = 0;
116 const char *p;
117 long long int ret;
118
119 if (nptr[0] == '-') {
120 is_neg = 1;
121 p = &nptr[1];
122 } else {
123 p = &nptr[0];
124 }
125 u = strtoull(p, NULL, base);
126 /* FIXME: check for overflow (sign-bit set) */
127 if (is_neg)
128 ret = 0 - (long long int)u;
129 else
130 ret = (long long int)u;
131 return ret;
132 }
133
134 /* FIXME: replace sscanf() usage for bdk_config_get_int. returns number of
135 * strings converted, so 1 if successful and 0 if not */
str_to_int(const char * str,int64_t * val)136 int str_to_int(const char *str, int64_t *val)
137 {
138 *val = strtol(str, NULL, 10);
139 return 1;
140 }
141
142 /* FIXME: replace sscanf() usage for bdk_config_get_int. returns number of
143 * strings converted, so 1 if successful and 0 if not */
str_to_hex(const char * str,int64_t * val)144 int str_to_hex(const char *str, int64_t *val)
145 {
146 *val = strtol(str, NULL, 16);
147 return 1;
148 }
149