xref: /aosp_15_r20/external/coreboot/src/vendorcode/cavium/bdk/lame_string.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
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