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