[ACPICA]
[reactos.git] / reactos / drivers / bus / acpi / acpica / utilities / utnonansi.c
index 5f45aaa..70fb33e 100644 (file)
@@ -164,22 +164,110 @@ AcpiUtStricmp (
 }
 
 
+#if defined (ACPI_DEBUGGER) || defined (ACPI_APPLICATION)
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiUtSafeStrcpy, AcpiUtSafeStrcat, AcpiUtSafeStrncat
+ *
+ * PARAMETERS:  Adds a "DestSize" parameter to each of the standard string
+ *              functions. This is the size of the Destination buffer.
+ *
+ * RETURN:      TRUE if the operation would overflow the destination buffer.
+ *
+ * DESCRIPTION: Safe versions of standard Clib string functions. Ensure that
+ *              the result of the operation will not overflow the output string
+ *              buffer.
+ *
+ * NOTE:        These functions are typically only helpful for processing
+ *              user input and command lines. For most ACPICA code, the
+ *              required buffer length is precisely calculated before buffer
+ *              allocation, so the use of these functions is unnecessary.
+ *
+ ******************************************************************************/
+
+BOOLEAN
+AcpiUtSafeStrcpy (
+    char                    *Dest,
+    ACPI_SIZE               DestSize,
+    char                    *Source)
+{
+
+    if (strlen (Source) >= DestSize)
+    {
+        return (TRUE);
+    }
+
+    strcpy (Dest, Source);
+    return (FALSE);
+}
+
+BOOLEAN
+AcpiUtSafeStrcat (
+    char                    *Dest,
+    ACPI_SIZE               DestSize,
+    char                    *Source)
+{
+
+    if ((strlen (Dest) + strlen (Source)) >= DestSize)
+    {
+        return (TRUE);
+    }
+
+    strcat (Dest, Source);
+    return (FALSE);
+}
+
+BOOLEAN
+AcpiUtSafeStrncat (
+    char                    *Dest,
+    ACPI_SIZE               DestSize,
+    char                    *Source,
+    ACPI_SIZE               MaxTransferLength)
+{
+    ACPI_SIZE               ActualTransferLength;
+
+
+    ActualTransferLength = ACPI_MIN (MaxTransferLength, strlen (Source));
+
+    if ((strlen (Dest) + ActualTransferLength) >= DestSize)
+    {
+        return (TRUE);
+    }
+
+    strncat (Dest, Source, MaxTransferLength);
+    return (FALSE);
+}
+#endif
+
+
 /*******************************************************************************
  *
  * FUNCTION:    AcpiUtStrtoul64
  *
- * PARAMETERS:  String          - Null terminated string
- *              Base            - Radix of the string: 16 or ACPI_ANY_BASE;
- *                                ACPI_ANY_BASE means 'in behalf of ToInteger'
- *              RetInteger      - Where the converted integer is returned
+ * PARAMETERS:  String                  - Null terminated string
+ *              Base                    - Radix of the string: 16 or 10 or
+ *                                        ACPI_ANY_BASE
+ *              MaxIntegerByteWidth     - Maximum allowable integer,in bytes:
+ *                                        4 or 8 (32 or 64 bits)
+ *              RetInteger              - Where the converted integer is
+ *                                        returned
  *
  * RETURN:      Status and Converted value
  *
  * DESCRIPTION: Convert a string into an unsigned value. Performs either a
- *              32-bit or 64-bit conversion, depending on the current mode
- *              of the interpreter.
+ *              32-bit or 64-bit conversion, depending on the input integer
+ *              size (often the current mode of the interpreter).
  *
- * NOTE:        Does not support Octal strings, not needed.
+ * NOTES:       Negative numbers are not supported, as they are not supported
+ *              by ACPI.
+ *
+ *              AcpiGbl_IntegerByteWidth should be set to the proper width.
+ *              For the core ACPICA code, this width depends on the DSDT
+ *              version. For iASL, the default byte width is always 8 for the
+ *              parser, but error checking is performed later to flag cases
+ *              where a 64-bit constant is defined in a 32-bit DSDT/SSDT.
+ *
+ *              Does not support Octal strings, not needed at this time.
  *
  ******************************************************************************/
 
@@ -187,25 +275,25 @@ ACPI_STATUS
 AcpiUtStrtoul64 (
     char                    *String,
     UINT32                  Base,
+    UINT32                  MaxIntegerByteWidth,
     UINT64                  *RetInteger)
 {
     UINT32                  ThisDigit = 0;
     UINT64                  ReturnValue = 0;
     UINT64                  Quotient;
     UINT64                  Dividend;
-    UINT32                  ToIntegerOp = (Base == ACPI_ANY_BASE);
-    UINT32                  Mode32 = (AcpiGbl_IntegerByteWidth == 4);
     UINT8                   ValidDigits = 0;
     UINT8                   SignOf0x = 0;
     UINT8                   Term = 0;
 
 
-    ACPI_FUNCTION_TRACE_STR (UtStroul64, String);
+    ACPI_FUNCTION_TRACE_STR (UtStrtoul64, String);
 
 
     switch (Base)
     {
     case ACPI_ANY_BASE:
+    case 10:
     case 16:
 
         break;
@@ -229,10 +317,10 @@ AcpiUtStrtoul64 (
         String++;
     }
 
-    if (ToIntegerOp)
+    if (Base == ACPI_ANY_BASE)
     {
         /*
-         * Base equal to ACPI_ANY_BASE means 'ToInteger operation case'.
+         * Base equal to ACPI_ANY_BASE means 'Either decimal or hex'.
          * We need to determine if it is decimal or hexadecimal.
          */
         if ((*String == '0') && (tolower ((int) *(String + 1)) == 'x'))
@@ -253,7 +341,7 @@ AcpiUtStrtoul64 (
 
     if (!(*String) || isspace ((int) *String) || *String == '\t')
     {
-        if (ToIntegerOp)
+        if (Base == ACPI_ANY_BASE)
         {
             goto ErrorExit;
         }
@@ -264,10 +352,11 @@ AcpiUtStrtoul64 (
     }
 
     /*
-     * Perform a 32-bit or 64-bit conversion, depending upon the current
-     * execution mode of the interpreter
+     * Perform a 32-bit or 64-bit conversion, depending upon the input
+     * byte width
      */
-    Dividend = (Mode32) ? ACPI_UINT32_MAX : ACPI_UINT64_MAX;
+    Dividend = (MaxIntegerByteWidth <= ACPI_MAX32_BYTE_WIDTH) ?
+        ACPI_UINT32_MAX : ACPI_UINT64_MAX;
 
     /* Main loop: convert the string to a 32- or 64-bit integer */
 
@@ -302,7 +391,7 @@ AcpiUtStrtoul64 (
 
         if (Term)
         {
-            if (ToIntegerOp)
+            if (Base == ACPI_ANY_BASE)
             {
                 goto ErrorExit;
             }
@@ -320,11 +409,12 @@ AcpiUtStrtoul64 (
 
         ValidDigits++;
 
-        if (SignOf0x && ((ValidDigits > 16) || ((ValidDigits > 8) && Mode32)))
+        if (SignOf0x && ((ValidDigits > 16) ||
+            ((ValidDigits > 8) && (MaxIntegerByteWidth <= ACPI_MAX32_BYTE_WIDTH))))
         {
             /*
              * This is ToInteger operation case.
-             * No any restrictions for string-to-integer conversion,
+             * No restrictions for string-to-integer conversion,
              * see ACPI spec.
              */
             goto ErrorExit;
@@ -337,7 +427,7 @@ AcpiUtStrtoul64 (
 
         if (ReturnValue > Quotient)
         {
-            if (ToIntegerOp)
+            if (Base == ACPI_ANY_BASE)
             {
                 goto ErrorExit;
             }
@@ -364,7 +454,8 @@ AllDone:
 
 
 ErrorExit:
-    /* Base was set/validated above */
+
+    /* Base was set/validated above (10 or 16) */
 
     if (Base == 10)
     {
@@ -377,77 +468,200 @@ ErrorExit:
 }
 
 
-#if defined (ACPI_DEBUGGER) || defined (ACPI_APPLICATION)
+#ifdef _OBSOLETE_FUNCTIONS
+/* Removed: 01/2016 */
+
 /*******************************************************************************
  *
- * FUNCTION:    AcpiUtSafeStrcpy, AcpiUtSafeStrcat, AcpiUtSafeStrncat
+ * FUNCTION:    strtoul64
  *
- * PARAMETERS:  Adds a "DestSize" parameter to each of the standard string
- *              functions. This is the size of the Destination buffer.
+ * PARAMETERS:  String              - Null terminated string
+ *              Terminater          - Where a pointer to the terminating byte
+ *                                    is returned
+ *              Base                - Radix of the string
  *
- * RETURN:      TRUE if the operation would overflow the destination buffer.
+ * RETURN:      Converted value
  *
- * DESCRIPTION: Safe versions of standard Clib string functions. Ensure that
- *              the result of the operation will not overflow the output string
- *              buffer.
- *
- * NOTE:        These functions are typically only helpful for processing
- *              user input and command lines. For most ACPICA code, the
- *              required buffer length is precisely calculated before buffer
- *              allocation, so the use of these functions is unnecessary.
+ * DESCRIPTION: Convert a string into an unsigned value.
  *
  ******************************************************************************/
 
-BOOLEAN
-AcpiUtSafeStrcpy (
-    char                    *Dest,
-    ACPI_SIZE               DestSize,
-    char                    *Source)
+ACPI_STATUS
+strtoul64 (
+    char                    *String,
+    UINT32                  Base,
+    UINT64                  *RetInteger)
 {
+    UINT32                  Index;
+    UINT32                  Sign;
+    UINT64                  ReturnValue = 0;
+    ACPI_STATUS             Status = AE_OK;
 
-    if (strlen (Source) >= DestSize)
+
+    *RetInteger = 0;
+
+    switch (Base)
     {
-        return (TRUE);
+    case 0:
+    case 8:
+    case 10:
+    case 16:
+
+        break;
+
+    default:
+        /*
+         * The specified Base parameter is not in the domain of
+         * this function:
+         */
+        return (AE_BAD_PARAMETER);
     }
 
-    strcpy (Dest, Source);
-    return (FALSE);
-}
+    /* Skip over any white space in the buffer: */
 
-BOOLEAN
-AcpiUtSafeStrcat (
-    char                    *Dest,
-    ACPI_SIZE               DestSize,
-    char                    *Source)
-{
+    while (isspace ((int) *String) || *String == '\t')
+    {
+        ++String;
+    }
 
-    if ((strlen (Dest) + strlen (Source)) >= DestSize)
+    /*
+     * The buffer may contain an optional plus or minus sign.
+     * If it does, then skip over it but remember what is was:
+     */
+    if (*String == '-')
     {
-        return (TRUE);
+        Sign = ACPI_SIGN_NEGATIVE;
+        ++String;
+    }
+    else if (*String == '+')
+    {
+        ++String;
+        Sign = ACPI_SIGN_POSITIVE;
+    }
+    else
+    {
+        Sign = ACPI_SIGN_POSITIVE;
     }
 
-    strcat (Dest, Source);
-    return (FALSE);
-}
+    /*
+     * If the input parameter Base is zero, then we need to
+     * determine if it is octal, decimal, or hexadecimal:
+     */
+    if (Base == 0)
+    {
+        if (*String == '0')
+        {
+            if (tolower ((int) *(++String)) == 'x')
+            {
+                Base = 16;
+                ++String;
+            }
+            else
+            {
+                Base = 8;
+            }
+        }
+        else
+        {
+            Base = 10;
+        }
+    }
 
-BOOLEAN
-AcpiUtSafeStrncat (
-    char                    *Dest,
-    ACPI_SIZE               DestSize,
-    char                    *Source,
-    ACPI_SIZE               MaxTransferLength)
-{
-    ACPI_SIZE               ActualTransferLength;
+    /*
+     * For octal and hexadecimal bases, skip over the leading
+     * 0 or 0x, if they are present.
+     */
+    if (Base == 8 && *String == '0')
+    {
+        String++;
+    }
 
+    if (Base == 16 &&
+        *String == '0' &&
+        tolower ((int) *(++String)) == 'x')
+    {
+        String++;
+    }
 
-    ActualTransferLength = ACPI_MIN (MaxTransferLength, strlen (Source));
+    /* Main loop: convert the string to an unsigned long */
 
-    if ((strlen (Dest) + ActualTransferLength) >= DestSize)
+    while (*String)
     {
-        return (TRUE);
+        if (isdigit ((int) *String))
+        {
+            Index = ((UINT8) *String) - '0';
+        }
+        else
+        {
+            Index = (UINT8) toupper ((int) *String);
+            if (isupper ((int) Index))
+            {
+                Index = Index - 'A' + 10;
+            }
+            else
+            {
+                goto ErrorExit;
+            }
+        }
+
+        if (Index >= Base)
+        {
+            goto ErrorExit;
+        }
+
+        /* Check to see if value is out of range: */
+
+        if (ReturnValue > ((ACPI_UINT64_MAX - (UINT64) Index) /
+            (UINT64) Base))
+        {
+            goto ErrorExit;
+        }
+        else
+        {
+            ReturnValue *= Base;
+            ReturnValue += Index;
+        }
+
+        ++String;
     }
 
-    strncat (Dest, Source, MaxTransferLength);
-    return (FALSE);
+
+    /* If a minus sign was present, then "the conversion is negated": */
+
+    if (Sign == ACPI_SIGN_NEGATIVE)
+    {
+        ReturnValue = (ACPI_UINT32_MAX - ReturnValue) + 1;
+    }
+
+    *RetInteger = ReturnValue;
+    return (Status);
+
+
+ErrorExit:
+    switch (Base)
+    {
+    case 8:
+
+        Status = AE_BAD_OCTAL_CONSTANT;
+        break;
+
+    case 10:
+
+        Status = AE_BAD_DECIMAL_CONSTANT;
+        break;
+
+    case 16:
+
+        Status = AE_BAD_HEX_CONSTANT;
+        break;
+
+    default:
+
+        /* Base validated above */
+
+        break;
+    }
+
+    return (Status);
 }
 #endif