1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2/*******************************************************************************
3 *
4 * Module Name: utnonansi - Non-ansi C library functions
5 *
6 ******************************************************************************/
7
8#include <acpi/acpi.h>
9#include "accommon.h"
10
11#define _COMPONENT          ACPI_UTILITIES
12ACPI_MODULE_NAME("utnonansi")
13
14/*
15 * Non-ANSI C library functions - strlwr, strupr, stricmp, and "safe"
16 * string functions.
17 */
18/*******************************************************************************
19 *
20 * FUNCTION:    acpi_ut_strlwr (strlwr)
21 *
22 * PARAMETERS:  src_string      - The source string to convert
23 *
24 * RETURN:      None
25 *
26 * DESCRIPTION: Convert a string to lowercase
27 *
28 ******************************************************************************/
29void acpi_ut_strlwr(char *src_string)
30{
31	char *string;
32
33	ACPI_FUNCTION_ENTRY();
34
35	if (!src_string) {
36		return;
37	}
38
39	/* Walk entire string, lowercasing the letters */
40
41	for (string = src_string; *string; string++) {
42		*string = (char)tolower((int)*string);
43	}
44}
45
46/*******************************************************************************
47 *
48 * FUNCTION:    acpi_ut_strupr (strupr)
49 *
50 * PARAMETERS:  src_string      - The source string to convert
51 *
52 * RETURN:      None
53 *
54 * DESCRIPTION: Convert a string to uppercase
55 *
56 ******************************************************************************/
57
58void acpi_ut_strupr(char *src_string)
59{
60	char *string;
61
62	ACPI_FUNCTION_ENTRY();
63
64	if (!src_string) {
65		return;
66	}
67
68	/* Walk entire string, uppercasing the letters */
69
70	for (string = src_string; *string; string++) {
71		*string = (char)toupper((int)*string);
72	}
73}
74
75/******************************************************************************
76 *
77 * FUNCTION:    acpi_ut_stricmp (stricmp)
78 *
79 * PARAMETERS:  string1             - first string to compare
80 *              string2             - second string to compare
81 *
82 * RETURN:      int that signifies string relationship. Zero means strings
83 *              are equal.
84 *
85 * DESCRIPTION: Case-insensitive string compare. Implementation of the
86 *              non-ANSI stricmp function.
87 *
88 ******************************************************************************/
89
90int acpi_ut_stricmp(char *string1, char *string2)
91{
92	int c1;
93	int c2;
94
95	do {
96		c1 = tolower((int)*string1);
97		c2 = tolower((int)*string2);
98
99		string1++;
100		string2++;
101	}
102	while ((c1 == c2) && (c1));
103
104	return (c1 - c2);
105}
106
107#if defined (ACPI_DEBUGGER) || defined (ACPI_APPLICATION) || defined (ACPI_DEBUG_OUTPUT)
108/*******************************************************************************
109 *
110 * FUNCTION:    acpi_ut_safe_strcpy, acpi_ut_safe_strcat, acpi_ut_safe_strncat
111 *
112 * PARAMETERS:  Adds a "DestSize" parameter to each of the standard string
113 *              functions. This is the size of the Destination buffer.
114 *
115 * RETURN:      TRUE if the operation would overflow the destination buffer.
116 *
117 * DESCRIPTION: Safe versions of standard Clib string functions. Ensure that
118 *              the result of the operation will not overflow the output string
119 *              buffer.
120 *
121 * NOTE:        These functions are typically only helpful for processing
122 *              user input and command lines. For most ACPICA code, the
123 *              required buffer length is precisely calculated before buffer
124 *              allocation, so the use of these functions is unnecessary.
125 *
126 ******************************************************************************/
127
128u8 acpi_ut_safe_strcpy(char *dest, acpi_size dest_size, char *source)
129{
130
131	if (strlen(source) >= dest_size) {
132		return (TRUE);
133	}
134
135	strcpy(dest, source);
136	return (FALSE);
137}
138
139u8 acpi_ut_safe_strcat(char *dest, acpi_size dest_size, char *source)
140{
141
142	if ((strlen(dest) + strlen(source)) >= dest_size) {
143		return (TRUE);
144	}
145
146	strcat(dest, source);
147	return (FALSE);
148}
149
150u8
151acpi_ut_safe_strncat(char *dest,
152		     acpi_size dest_size,
153		     char *source, acpi_size max_transfer_length)
154{
155	acpi_size actual_transfer_length;
156
157	actual_transfer_length = ACPI_MIN(max_transfer_length, strlen(source));
158
159	if ((strlen(dest) + actual_transfer_length) >= dest_size) {
160		return (TRUE);
161	}
162
163	strncat(dest, source, max_transfer_length);
164	return (FALSE);
165}
166
167void acpi_ut_safe_strncpy(char *dest, char *source, acpi_size dest_size)
168{
169	/* Always terminate destination string */
170
171	strncpy(dest, source, dest_size);
172	dest[dest_size - 1] = 0;
173}
174
175#endif
176