浏览代码

qcacmn: Add int/bool parse functions to QDF

Add the following function implementations to QDF:
 * qdf_bool_parse()
 * qdf_int32_parse()
 * qdf_uint32_parse()
 * qdf_int64_parse()
 * qdf_uint64_parse()

Change-Id: Ic31e3eb70f684799bd6e1e524cfc1cb816ddc01a
CRs-Fixed: 2185282
Dustin Brown 7 年之前
父节点
当前提交
6461e566f4
共有 3 个文件被更改,包括 294 次插入24 次删除
  1. 3 2
      qdf/inc/qdf_status.h
  2. 64 0
      qdf/inc/qdf_types.h
  3. 227 22
      qdf/src/qdf_types.c

+ 3 - 2
qdf/inc/qdf_status.h

@@ -1,9 +1,8 @@
 /*
- * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2018 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
- *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
  * above copyright notice and this permission notice appear in all
@@ -86,6 +85,7 @@
  * @QDF_STATUS_CRYPTO_MIC_FAILURE: MIC failure in received frame
  * @QDF_STATUS_CRYPTO_ENCRYPT_FAILED: encryption failed
  * @QDF_STATUS_CRYPTO_DECRYPT_FAILED: decryption failed
+ * @QDF_STATUS_E_RANGE: result/parameter/operation was out of range
  * @QDF_STATUS_MAX: not a realy value just a place holder for max
  */
 typedef enum {
@@ -140,6 +140,7 @@ typedef enum {
 	QDF_STATUS_CRYPTO_ENCRYPT_FAILED,
 	QDF_STATUS_CRYPTO_DECRYPT_FAILED,
 	QDF_STATUS_E_DEFRAG_ERROR,
+	QDF_STATUS_E_RANGE,
 	QDF_STATUS_MAX
 } QDF_STATUS;
 

+ 64 - 0
qdf/inc/qdf_types.h

@@ -660,6 +660,70 @@ typedef enum {
 #endif
 #endif
 
+/**
+ * qdf_bool_parse() - parse the given string as a boolean value
+ * @bool_str: the input boolean string to parse
+ * @out_bool: the output boolean value, populated on success
+ *
+ * 1, y, Y are mapped to true, 0, n, N are mapped to false.
+ * Leading/trailing whitespace is ignored.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS qdf_bool_parse(const char *bool_str, bool *out_bool);
+
+/**
+ * qdf_int32_parse() - parse the given string as a 32-bit signed integer
+ * @int_str: the input integer string to parse
+ * @out_int: the output integer value, populated on success
+ *
+ * Supports binary (0b), octal (0o), decimal (no prefix), and hexadecimal (0x)
+ * encodings via typical prefix notation. Leading/trailing whitespace is
+ * ignored.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS qdf_int32_parse(const char *int_str, int32_t *out_int);
+
+/**
+ * qdf_uint32_parse() - parse the given string as a 32-bit unsigned integer
+ * @int_str: the input integer string to parse
+ * @out_int: the output integer value, populated on success
+ *
+ * Supports binary (0b), octal (0o), decimal (no prefix), and hexadecimal (0x)
+ * encodings via typical prefix notation. Leading/trailing whitespace is
+ * ignored.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS qdf_uint32_parse(const char *int_str, uint32_t *out_int);
+
+/**
+ * qdf_int64_parse() - parse the given string as a 64-bit signed integer
+ * @int_str: the input integer string to parse
+ * @out_int: the output integer value, populated on success
+ *
+ * Supports binary (0b), octal (0o), decimal (no prefix), and hexadecimal (0x)
+ * encodings via typical prefix notation. Leading/trailing whitespace is
+ * ignored.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS qdf_int64_parse(const char *int_str, int64_t *out_int);
+
+/**
+ * qdf_uint64_parse() - parse the given string as a 64-bit unsigned integer
+ * @int_str: the input integer string to parse
+ * @out_int: the output integer value, populated on success
+ *
+ * Supports binary (0b), octal (0o), decimal (no prefix), and hexadecimal (0x)
+ * encodings via typical prefix notation. Leading/trailing whitespace is
+ * ignored.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS qdf_uint64_parse(const char *int_str, uint64_t *out_int);
+
 #define QDF_MAC_ADDR_SIZE 6
 #define QDF_MAC_ADDR_STR "%02x:%02x:%02x:%02x:%02x:%02x"
 #define QDF_MAC_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]

+ 227 - 22
qdf/src/qdf_types.c

@@ -17,13 +17,14 @@
  */
 
 #include "qdf_mem.h"
+#include "qdf_module.h"
 #include "qdf_status.h"
 #include "qdf_trace.h"
 #include "qdf_types.h"
 
 static QDF_STATUS qdf_consume_char(const char **str, char c)
 {
-	if (*str[0] != c)
+	if ((*str)[0] != c)
 		return QDF_STATUS_E_FAILURE;
 
 	(*str)++;
@@ -33,12 +34,12 @@ static QDF_STATUS qdf_consume_char(const char **str, char c)
 
 static QDF_STATUS qdf_consume_whitespace(const char **str, char *c)
 {
-	switch (*str[0]) {
+	switch ((*str)[0]) {
 	case ' ':
 	case '\t':
 	case '\n':
 	case '\r':
-		*c = *str[0];
+		*c = (*str)[0];
 		(*str)++;
 		return QDF_STATUS_SUCCESS;
 	default:
@@ -58,7 +59,7 @@ static void qdf_skip_whitespace(const char **str)
 
 static QDF_STATUS qdf_consume_dec(const char **str, uint8_t *out_digit)
 {
-	uint8_t c = *str[0];
+	uint8_t c = (*str)[0];
 
 	if (c >= '0' && c <= '9')
 		*out_digit = c - '0';
@@ -70,6 +71,24 @@ static QDF_STATUS qdf_consume_dec(const char **str, uint8_t *out_digit)
 	return QDF_STATUS_SUCCESS;
 }
 
+static QDF_STATUS qdf_consume_hex(const char **str, uint8_t *out_nibble)
+{
+	uint8_t c = (*str)[0];
+
+	if (c >= '0' && c <= '9')
+		*out_nibble = c - '0';
+	else if (c >= 'a' && c <= 'f')
+		*out_nibble = c - 'a' + 10;
+	else if (c >= 'A' && c <= 'F')
+		*out_nibble = c - 'A' + 10;
+	else
+		return QDF_STATUS_E_FAILURE;
+
+	(*str)++;
+
+	return QDF_STATUS_SUCCESS;
+}
+
 static QDF_STATUS qdf_consume_octet_dec(const char **str, uint8_t *out_octet)
 {
 	uint8_t len = 0;
@@ -101,24 +120,6 @@ static QDF_STATUS qdf_consume_octet_dec(const char **str, uint8_t *out_octet)
 	return QDF_STATUS_SUCCESS;
 }
 
-static QDF_STATUS qdf_consume_hex(const char **str, uint8_t *out_nibble)
-{
-	uint8_t c = *str[0];
-
-	if (c >= '0' && c <= '9')
-		*out_nibble = c - '0';
-	else if (c >= 'a' && c <= 'f')
-		*out_nibble = c - 'a' + 10;
-	else if (c >= 'A' && c <= 'F')
-		*out_nibble = c - 'A' + 10;
-	else
-		return QDF_STATUS_E_FAILURE;
-
-	(*str)++;
-
-	return QDF_STATUS_SUCCESS;
-}
-
 static QDF_STATUS qdf_consume_hex_pair(const char **str, uint8_t *out_byte)
 {
 	QDF_STATUS status;
@@ -167,6 +168,210 @@ static QDF_STATUS qdf_consume_hextet(const char **str, uint16_t *out_hextet)
 	return QDF_STATUS_SUCCESS;
 }
 
+static QDF_STATUS qdf_consume_radix(const char **str, uint8_t *out_radix)
+{
+	if ((*str)[0] == '0') {
+		switch ((*str)[1]) {
+		case 'b':
+			*out_radix = 2;
+			*str += 2;
+			break;
+		case 'o':
+			*out_radix = 8;
+			*str += 2;
+			break;
+		case 'x':
+			*out_radix = 16;
+			*str += 2;
+			break;
+		default:
+			*out_radix = 10;
+			break;
+		}
+
+		return QDF_STATUS_SUCCESS;
+	}
+
+	if (*str[0] >= '0' && *str[0] <= '9') {
+		*out_radix = 10;
+		return QDF_STATUS_SUCCESS;
+	}
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+static QDF_STATUS
+qdf_int_parse(const char *int_str, uint64_t *out_int, bool *out_negate)
+{
+	QDF_STATUS status;
+	bool negate = false;
+	uint8_t radix;
+	uint8_t digit;
+	uint64_t value = 0;
+	uint64_t next_value;
+
+	QDF_BUG(int_str);
+	if (!int_str)
+		return QDF_STATUS_E_INVAL;
+
+	QDF_BUG(out_int);
+	if (!out_int)
+		return QDF_STATUS_E_INVAL;
+
+	qdf_skip_whitespace(&int_str);
+
+	status = qdf_consume_char(&int_str, '-');
+	if (QDF_IS_STATUS_SUCCESS(status))
+		negate = true;
+	else
+		qdf_consume_char(&int_str, '+');
+
+	status = qdf_consume_radix(&int_str, &radix);
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
+	while (QDF_IS_STATUS_SUCCESS(qdf_consume_hex(&int_str, &digit))) {
+		if (digit >= radix)
+			return QDF_STATUS_E_FAILURE;
+
+		next_value = value * radix + digit;
+		if (next_value < value)
+			return QDF_STATUS_E_RANGE;
+
+		value = next_value;
+	}
+
+	qdf_skip_whitespace(&int_str);
+	if (int_str[0] != '\0')
+		return QDF_STATUS_E_FAILURE;
+
+	*out_negate = negate;
+	*out_int = value;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS qdf_int32_parse(const char *int_str, int32_t *out_int)
+{
+	QDF_STATUS status;
+	int64_t value;
+
+	status = qdf_int64_parse(int_str, &value);
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
+	if ((int32_t)value != value)
+		return QDF_STATUS_E_RANGE;
+
+	*out_int = value;
+
+	return QDF_STATUS_SUCCESS;
+}
+qdf_export_symbol(qdf_int32_parse);
+
+QDF_STATUS qdf_uint32_parse(const char *int_str, uint32_t *out_int)
+{
+	QDF_STATUS status;
+	uint64_t value;
+
+	status = qdf_uint64_parse(int_str, &value);
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
+	if ((uint32_t)value != value)
+		return QDF_STATUS_E_RANGE;
+
+	*out_int = value;
+
+	return QDF_STATUS_SUCCESS;
+}
+qdf_export_symbol(qdf_uint32_parse);
+
+QDF_STATUS qdf_int64_parse(const char *int_str, int64_t *out_int)
+{
+	QDF_STATUS status;
+	bool negate;
+	uint64_t value;
+	int64_t signed_value;
+
+	status = qdf_int_parse(int_str, &value, &negate);
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
+	if (negate) {
+		signed_value = -value;
+		if (signed_value > 0)
+			return QDF_STATUS_E_RANGE;
+	} else {
+		signed_value = value;
+		if (signed_value < 0)
+			return QDF_STATUS_E_RANGE;
+	}
+
+	*out_int = signed_value;
+
+	return QDF_STATUS_SUCCESS;
+}
+qdf_export_symbol(qdf_int64_parse);
+
+QDF_STATUS qdf_uint64_parse(const char *int_str, uint64_t *out_int)
+{
+	QDF_STATUS status;
+	bool negate;
+	uint64_t value;
+
+	status = qdf_int_parse(int_str, &value, &negate);
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
+	if (negate)
+		return QDF_STATUS_E_RANGE;
+
+	*out_int = value;
+
+	return QDF_STATUS_SUCCESS;
+}
+qdf_export_symbol(qdf_uint64_parse);
+
+QDF_STATUS qdf_bool_parse(const char *bool_str, bool *out_bool)
+{
+	bool value;
+
+	QDF_BUG(bool_str);
+	if (!bool_str)
+		return QDF_STATUS_E_INVAL;
+
+	QDF_BUG(out_bool);
+	if (!out_bool)
+		return QDF_STATUS_E_INVAL;
+
+	qdf_skip_whitespace(&bool_str);
+
+	switch (bool_str[0]) {
+	case '1':
+	case 'y':
+	case 'Y':
+		value = true;
+		break;
+	case '0':
+	case 'n':
+	case 'N':
+		value = false;
+		break;
+	default:
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	qdf_skip_whitespace(&bool_str);
+	if (bool_str[0] != '\0')
+		return QDF_STATUS_E_FAILURE;
+
+	*out_bool = value;
+
+	return QDF_STATUS_SUCCESS;
+}
+qdf_export_symbol(qdf_bool_parse);
+
 QDF_STATUS qdf_mac_parse(const char *mac_str, struct qdf_mac_addr *out_addr)
 {
 	QDF_STATUS status;