162306a36Sopenharmony_ci// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
262306a36Sopenharmony_ci/*******************************************************************************
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci * Module Name: utstring - Common functions for strings and characters
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci ******************************************************************************/
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include <acpi/acpi.h>
962306a36Sopenharmony_ci#include "accommon.h"
1062306a36Sopenharmony_ci#include "acnamesp.h"
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#define _COMPONENT          ACPI_UTILITIES
1362306a36Sopenharmony_ciACPI_MODULE_NAME("utstring")
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci/*******************************************************************************
1662306a36Sopenharmony_ci *
1762306a36Sopenharmony_ci * FUNCTION:    acpi_ut_print_string
1862306a36Sopenharmony_ci *
1962306a36Sopenharmony_ci * PARAMETERS:  string          - Null terminated ASCII string
2062306a36Sopenharmony_ci *              max_length      - Maximum output length. Used to constrain the
2162306a36Sopenharmony_ci *                                length of strings during debug output only.
2262306a36Sopenharmony_ci *
2362306a36Sopenharmony_ci * RETURN:      None
2462306a36Sopenharmony_ci *
2562306a36Sopenharmony_ci * DESCRIPTION: Dump an ASCII string with support for ACPI-defined escape
2662306a36Sopenharmony_ci *              sequences.
2762306a36Sopenharmony_ci *
2862306a36Sopenharmony_ci ******************************************************************************/
2962306a36Sopenharmony_civoid acpi_ut_print_string(char *string, u16 max_length)
3062306a36Sopenharmony_ci{
3162306a36Sopenharmony_ci	u32 i;
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci	if (!string) {
3462306a36Sopenharmony_ci		acpi_os_printf("<\"NULL STRING PTR\">");
3562306a36Sopenharmony_ci		return;
3662306a36Sopenharmony_ci	}
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci	acpi_os_printf("\"");
3962306a36Sopenharmony_ci	for (i = 0; (i < max_length) && string[i]; i++) {
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci		/* Escape sequences */
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci		switch (string[i]) {
4462306a36Sopenharmony_ci		case 0x07:
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci			acpi_os_printf("\\a");	/* BELL */
4762306a36Sopenharmony_ci			break;
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci		case 0x08:
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci			acpi_os_printf("\\b");	/* BACKSPACE */
5262306a36Sopenharmony_ci			break;
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci		case 0x0C:
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci			acpi_os_printf("\\f");	/* FORMFEED */
5762306a36Sopenharmony_ci			break;
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci		case 0x0A:
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci			acpi_os_printf("\\n");	/* LINEFEED */
6262306a36Sopenharmony_ci			break;
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci		case 0x0D:
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci			acpi_os_printf("\\r");	/* CARRIAGE RETURN */
6762306a36Sopenharmony_ci			break;
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci		case 0x09:
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci			acpi_os_printf("\\t");	/* HORIZONTAL TAB */
7262306a36Sopenharmony_ci			break;
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci		case 0x0B:
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ci			acpi_os_printf("\\v");	/* VERTICAL TAB */
7762306a36Sopenharmony_ci			break;
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci		case '\'':	/* Single Quote */
8062306a36Sopenharmony_ci		case '\"':	/* Double Quote */
8162306a36Sopenharmony_ci		case '\\':	/* Backslash */
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci			acpi_os_printf("\\%c", (int)string[i]);
8462306a36Sopenharmony_ci			break;
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci		default:
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci			/* Check for printable character or hex escape */
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ci			if (isprint((int)string[i])) {
9162306a36Sopenharmony_ci				/* This is a normal character */
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci				acpi_os_printf("%c", (int)string[i]);
9462306a36Sopenharmony_ci			} else {
9562306a36Sopenharmony_ci				/* All others will be Hex escapes */
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ci				acpi_os_printf("\\x%2.2X", (s32)string[i]);
9862306a36Sopenharmony_ci			}
9962306a36Sopenharmony_ci			break;
10062306a36Sopenharmony_ci		}
10162306a36Sopenharmony_ci	}
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ci	acpi_os_printf("\"");
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ci	if (i == max_length && string[i]) {
10662306a36Sopenharmony_ci		acpi_os_printf("...");
10762306a36Sopenharmony_ci	}
10862306a36Sopenharmony_ci}
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci/*******************************************************************************
11162306a36Sopenharmony_ci *
11262306a36Sopenharmony_ci * FUNCTION:    acpi_ut_repair_name
11362306a36Sopenharmony_ci *
11462306a36Sopenharmony_ci * PARAMETERS:  name            - The ACPI name to be repaired
11562306a36Sopenharmony_ci *
11662306a36Sopenharmony_ci * RETURN:      Repaired version of the name
11762306a36Sopenharmony_ci *
11862306a36Sopenharmony_ci * DESCRIPTION: Repair an ACPI name: Change invalid characters to '*' and
11962306a36Sopenharmony_ci *              return the new name. NOTE: the Name parameter must reside in
12062306a36Sopenharmony_ci *              read/write memory, cannot be a const.
12162306a36Sopenharmony_ci *
12262306a36Sopenharmony_ci * An ACPI Name must consist of valid ACPI characters. We will repair the name
12362306a36Sopenharmony_ci * if necessary because we don't want to abort because of this, but we want
12462306a36Sopenharmony_ci * all namespace names to be printable. A warning message is appropriate.
12562306a36Sopenharmony_ci *
12662306a36Sopenharmony_ci * This issue came up because there are in fact machines that exhibit
12762306a36Sopenharmony_ci * this problem, and we want to be able to enable ACPI support for them,
12862306a36Sopenharmony_ci * even though there are a few bad names.
12962306a36Sopenharmony_ci *
13062306a36Sopenharmony_ci ******************************************************************************/
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_civoid acpi_ut_repair_name(char *name)
13362306a36Sopenharmony_ci{
13462306a36Sopenharmony_ci	u32 i;
13562306a36Sopenharmony_ci	u8 found_bad_char = FALSE;
13662306a36Sopenharmony_ci	u32 original_name;
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_ci	ACPI_FUNCTION_NAME(ut_repair_name);
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci	/*
14162306a36Sopenharmony_ci	 * Special case for the root node. This can happen if we get an
14262306a36Sopenharmony_ci	 * error during the execution of module-level code.
14362306a36Sopenharmony_ci	 */
14462306a36Sopenharmony_ci	if (ACPI_COMPARE_NAMESEG(name, ACPI_ROOT_PATHNAME)) {
14562306a36Sopenharmony_ci		return;
14662306a36Sopenharmony_ci	}
14762306a36Sopenharmony_ci
14862306a36Sopenharmony_ci	ACPI_COPY_NAMESEG(&original_name, &name[0]);
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_ci	/* Check each character in the name */
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_ci	for (i = 0; i < ACPI_NAMESEG_SIZE; i++) {
15362306a36Sopenharmony_ci		if (acpi_ut_valid_name_char(name[i], i)) {
15462306a36Sopenharmony_ci			continue;
15562306a36Sopenharmony_ci		}
15662306a36Sopenharmony_ci
15762306a36Sopenharmony_ci		/*
15862306a36Sopenharmony_ci		 * Replace a bad character with something printable, yet technically
15962306a36Sopenharmony_ci		 * "odd". This prevents any collisions with existing "good"
16062306a36Sopenharmony_ci		 * names in the namespace.
16162306a36Sopenharmony_ci		 */
16262306a36Sopenharmony_ci		name[i] = '_';
16362306a36Sopenharmony_ci		found_bad_char = TRUE;
16462306a36Sopenharmony_ci	}
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_ci	if (found_bad_char) {
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_ci		/* Report warning only if in strict mode or debug mode */
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_ci		if (!acpi_gbl_enable_interpreter_slack) {
17162306a36Sopenharmony_ci			ACPI_WARNING((AE_INFO,
17262306a36Sopenharmony_ci				      "Invalid character(s) in name (0x%.8X) %p, repaired: [%4.4s]",
17362306a36Sopenharmony_ci				      original_name, name, &name[0]));
17462306a36Sopenharmony_ci		} else {
17562306a36Sopenharmony_ci			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
17662306a36Sopenharmony_ci					  "Invalid character(s) in name (0x%.8X), repaired: [%4.4s]",
17762306a36Sopenharmony_ci					  original_name, name));
17862306a36Sopenharmony_ci		}
17962306a36Sopenharmony_ci	}
18062306a36Sopenharmony_ci}
18162306a36Sopenharmony_ci
18262306a36Sopenharmony_ci#if defined ACPI_ASL_COMPILER || defined ACPI_EXEC_APP
18362306a36Sopenharmony_ci/*******************************************************************************
18462306a36Sopenharmony_ci *
18562306a36Sopenharmony_ci * FUNCTION:    ut_convert_backslashes
18662306a36Sopenharmony_ci *
18762306a36Sopenharmony_ci * PARAMETERS:  pathname        - File pathname string to be converted
18862306a36Sopenharmony_ci *
18962306a36Sopenharmony_ci * RETURN:      Modifies the input Pathname
19062306a36Sopenharmony_ci *
19162306a36Sopenharmony_ci * DESCRIPTION: Convert all backslashes (0x5C) to forward slashes (0x2F) within
19262306a36Sopenharmony_ci *              the entire input file pathname string.
19362306a36Sopenharmony_ci *
19462306a36Sopenharmony_ci ******************************************************************************/
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_civoid ut_convert_backslashes(char *pathname)
19762306a36Sopenharmony_ci{
19862306a36Sopenharmony_ci
19962306a36Sopenharmony_ci	if (!pathname) {
20062306a36Sopenharmony_ci		return;
20162306a36Sopenharmony_ci	}
20262306a36Sopenharmony_ci
20362306a36Sopenharmony_ci	while (*pathname) {
20462306a36Sopenharmony_ci		if (*pathname == '\\') {
20562306a36Sopenharmony_ci			*pathname = '/';
20662306a36Sopenharmony_ci		}
20762306a36Sopenharmony_ci
20862306a36Sopenharmony_ci		pathname++;
20962306a36Sopenharmony_ci	}
21062306a36Sopenharmony_ci}
21162306a36Sopenharmony_ci#endif
212