Switch RhConfig from TCHAR to char (#86393)
authorElinor Fung <elfung@microsoft.com>
Thu, 18 May 2023 22:35:07 +0000 (00:35 +0200)
committerGitHub <noreply@github.com>
Thu, 18 May 2023 22:35:07 +0000 (00:35 +0200)
- Hide away the details of reading the environment variable as `wchar` vs `char`
- Keep embedded variables as as ASCII (they are embedded as such already)
- Stop using `TCHAR` for the `RhConfig` APIs, which seemed to just be more confusing to consume

src/coreclr/nativeaot/Runtime/PalRedhawk.h
src/coreclr/nativeaot/Runtime/RhConfig.cpp
src/coreclr/nativeaot/Runtime/RhConfig.h
src/coreclr/nativeaot/Runtime/gcrhenv.cpp
src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp
src/coreclr/nativeaot/Runtime/windows/PalRedhawkMinWin.cpp

index 986ad2ac2c89f98e2079d279580aba854f3cafbb..81d08260015d95b62d925b77557179d2b12f8a29 100644 (file)
@@ -780,16 +780,6 @@ REDHAWK_PALIMPORT void PalPrintFatalError(const char* message);
 REDHAWK_PALIMPORT int32_t __cdecl _stricmp(const char *string1, const char *string2);
 #endif // TARGET_UNIX
 
-#ifdef UNICODE
-#define _tcsicmp _wcsicmp
-#define _tcscat wcscat
-#define _tcslen wcslen
-#else
-#define _tcsicmp _stricmp
-#define _tcscat strcat
-#define _tcslen strlen
-#endif
-
 #if defined(HOST_X86) || defined(HOST_AMD64)
 
 #ifdef TARGET_UNIX
index 3add440a89ec6ae46347e7e195158d7e10883642..a321b37cff259a82a93d8e944ac569d09f0b1e55 100644 (file)
 #include "common.h"
 #ifndef DACCESS_COMPILE
 #include "CommonTypes.h"
-#include "daccess.h"
 #include "CommonMacros.h"
 #include "PalRedhawkCommon.h"
 #include "PalRedhawk.h"
-#include "rhassert.h"
-#include "slist.h"
-#include "gcrhinterface.h"
-#include "varint.h"
-#include "regdisplay.h"
-#include "StackFrameIterator.h"
-#include "thread.h"
 #include "holder.h"
-#include "Crst.h"
-#include "event.h"
-#include "threadstore.h"
-#include "RuntimeInstance.h"
-#include "shash.h"
 #include "RhConfig.h"
 
 #include <string.h>
 
-bool RhConfig::ReadConfigValue(_In_z_ const TCHAR *wszName, uint64_t* pValue, bool decimal)
+bool RhConfig::ReadConfigValue(_In_z_ const char *name, uint64_t* pValue, bool decimal)
 {
-    TCHAR wszBuffer[CONFIG_VAL_MAXLEN + 1]; // hex digits plus a nul terminator.
-    const uint32_t cchBuffer = sizeof(wszBuffer) / sizeof(wszBuffer[0]);
+    TCHAR buffer[CONFIG_VAL_MAXLEN + 1]; // hex digits plus a nul terminator.
+    const uint32_t cchBuffer = ARRAY_SIZE(buffer);
 
     uint32_t cchResult = 0;
-
-#ifdef FEATURE_ENVIRONMENT_VARIABLE_CONFIG
-    TCHAR wszVariableName[64] = _T("DOTNET_");
-    assert(_tcslen(wszVariableName) + _tcslen(wszName) < sizeof(wszVariableName) / sizeof(wszVariableName[0]));
-    _tcscat(wszVariableName, wszName);
-    cchResult = PalGetEnvironmentVariable(wszVariableName, wszBuffer, cchBuffer);
-#endif // FEATURE_ENVIRONMENT_VARIABLE_CONFIG
-
-#ifdef FEATURE_EMBEDDED_CONFIG
-    // if the config key wasn't found in the ini file
-    if ((cchResult == 0) || (cchResult >= cchBuffer))
-        cchResult = GetEmbeddedVariable(wszName, wszBuffer, cchBuffer);
-#endif // FEATURE_EMBEDDED_CONFIG
-
-    if ((cchResult == 0) || (cchResult >= cchBuffer))
-        return false; // not found
-
-    uint64_t uiResult = 0;
-
-    for (uint32_t i = 0; i < cchResult; i++)
+    TCHAR variableName[64] = _T("DOTNET_");
+    assert(ARRAY_SIZE("DOTNET_") - 1 + strlen(name) < ARRAY_SIZE(variableName));
+#ifdef TARGET_WINDOWS
+    for (size_t i = 0; i < strlen(name); i++)
     {
-        TCHAR ch = wszBuffer[i];
+        variableName[ARRAY_SIZE("DOTNET_") - 1 + i] = name[i];
+    }
+#else
+    strcat(variableName, name);
+#endif
 
-        if (decimal)
+    cchResult = PalGetEnvironmentVariable(variableName, buffer, cchBuffer);
+    if (cchResult != 0 && cchResult < cchBuffer)
+    {
+        // Environment variable was set. Convert it to an integer.
+        uint64_t uiResult = 0;
+        for (uint32_t i = 0; i < cchResult; i++)
         {
-            uiResult *= 10;
+            TCHAR ch = buffer[i];
 
-            if ((ch >= _T('0')) && (ch <= _T('9')))
-                uiResult += ch - _T('0');
-            else
-                return false; // parse error
-        }
-        else
-        {
-            uiResult *= 16;
-
-            if ((ch >= _T('0')) && (ch <= _T('9')))
-                uiResult += ch - _T('0');
-            else if ((ch >= _T('a')) && (ch <= _T('f')))
-                uiResult += (ch - _T('a')) + 10;
-            else if ((ch >= _T('A')) && (ch <= _T('F')))
-                uiResult += (ch - _T('A')) + 10;
+            if (decimal)
+            {
+                uiResult *= 10;
+
+                if ((ch >= '0') && (ch <= '9'))
+                    uiResult += ch - '0';
+                else
+                    return false; // parse error
+            }
             else
-                return false; // parse error
+            {
+                uiResult *= 16;
+
+                if ((ch >= '0') && (ch <= '9'))
+                    uiResult += ch - '0';
+                else if ((ch >= 'a') && (ch <= 'f'))
+                    uiResult += (ch - 'a') + 10;
+                else if ((ch >= 'A') && (ch <= 'F'))
+                    uiResult += (ch - 'A') + 10;
+                else
+                    return false; // parse error
+            }
         }
-    }
 
-    *pValue = uiResult;
-    return true;
-}
+        *pValue = uiResult;
+        return true;
+    }
 
-#ifdef FEATURE_EMBEDDED_CONFIG
-uint32_t RhConfig::GetEmbeddedVariable(_In_z_ const TCHAR* configName, _Out_writes_all_(cchOutputBuffer) TCHAR* outputBuffer, _In_ uint32_t cchOutputBuffer)
-{
-    //the buffer needs to be big enough to read the value buffer + null terminator
-    if (cchOutputBuffer < CONFIG_VAL_MAXLEN + 1)
+    // Check the embedded configuration
+    const char *embeddedValue = nullptr;
+    if (GetEmbeddedVariable(name, &embeddedValue))
     {
-        return 0;
+        *pValue = strtoull(embeddedValue, NULL, decimal ? 10 : 16);
+        return true;
     }
 
-    //if we haven't read the config yet try to read
+    return false;
+}
+
+bool RhConfig::GetEmbeddedVariable(_In_z_ const char* configName, _Out_ const char** configValue)
+{
+    // Read the config if we haven't yet
     if (g_embeddedSettings == NULL)
     {
         ReadEmbeddedSettings();
     }
 
-    //if the config wasn't read or reading failed return 0 immediately
+    // Config wasn't read or reading failed
     if (g_embeddedSettings == CONFIG_INI_NOT_AVAIL)
     {
-        return 0;
+        return false;
     }
 
-    return GetConfigVariable(configName, (ConfigPair*)g_embeddedSettings, outputBuffer, cchOutputBuffer);
-}
-#endif // FEATURE_EMBEDDED_CONFIG
+    const ConfigPair* configPairs = (const ConfigPair*)g_embeddedSettings;
 
-uint32_t RhConfig::GetConfigVariable(_In_z_ const TCHAR* configName, const ConfigPair* configPairs, _Out_writes_all_(cchOutputBuffer) TCHAR* outputBuffer, _In_ uint32_t cchOutputBuffer)
-{
-    //find the first name which matches (case insensitive to be compat with environment variable counterpart)
+    // Find the first name which matches (case insensitive to be compat with environment variable counterpart)
     for (int iSettings = 0; iSettings < RCV_Count; iSettings++)
     {
-        if (_tcsicmp(configName, configPairs[iSettings].Key) == 0)
+        if (_stricmp(configName, configPairs[iSettings].Key) == 0)
         {
-            bool nullTerm = FALSE;
-
-            uint32_t iValue;
-
-            for (iValue = 0; (iValue < CONFIG_VAL_MAXLEN + 1) && (iValue < cchOutputBuffer); iValue++)
-            {
-                outputBuffer[iValue] = configPairs[iSettings].Value[iValue];
-
-                if (outputBuffer[iValue] == '\0')
-                {
-                    nullTerm = true;
-                    break;
-                }
-            }
-
-            //return the length of the config value if null terminated else return zero
-            return nullTerm ? iValue : 0;
+            *configValue = configPairs[iSettings].Value;
+            return true;
         }
     }
 
-    //if the config key was not found return 0
-    return 0;
+    // Config key was not found
+    return false;
 }
 
-#ifdef FEATURE_EMBEDDED_CONFIG
 struct CompilerEmbeddedSettingsBlob
 {
     uint32_t Size;
@@ -210,7 +178,6 @@ void RhConfig::ReadEmbeddedSettings()
 
     return;
 }
-#endif // FEATURE_EMBEDDED_CONFIG
 
 //Parses one line of config and populates values in the passed in configPair
 //returns: true if the parsing was successful, false if the parsing failed.
index debc566df166c87bc869664418b0a328d82c5dbe..86e8c38a52bcfd311050bc7402c33e59a044d59b 100644 (file)
@@ -14,9 +14,6 @@
 
 #ifndef DACCESS_COMPILE
 
-#define FEATURE_EMBEDDED_CONFIG
-#define FEATURE_ENVIRONMENT_VARIABLE_CONFIG
-
 class RhConfig
 {
 
@@ -28,21 +25,19 @@ private:
     struct ConfigPair
     {
     public:
-        TCHAR Key[CONFIG_KEY_MAXLEN + 1];  //maxlen + null terminator
-        TCHAR Value[CONFIG_VAL_MAXLEN + 1]; //maxlen + null terminator
+        char Key[CONFIG_KEY_MAXLEN + 1];  //maxlen + null terminator
+        char Value[CONFIG_VAL_MAXLEN + 1]; //maxlen + null terminator
     };
 
-#ifdef FEATURE_EMBEDDED_CONFIG
     // g_embeddedSettings is a buffer of ConfigPair structs embedded in the compiled binary.
     //
     //NOTE: g_embeddedSettings is only set in ReadEmbeddedSettings and must be set atomically only once
     //      using PalInterlockedCompareExchangePointer to avoid races when initializing
     void* volatile g_embeddedSettings = NULL;
-#endif // FEATURE_EMBEDDED_CONFIG
 
 public:
 
-    bool ReadConfigValue(_In_z_ const TCHAR* wszName, uint64_t* pValue, bool decimal = false);
+    bool ReadConfigValue(_In_z_ const char* wszName, uint64_t* pValue, bool decimal = false);
 
 #define DEFINE_VALUE_ACCESSOR(_name, defaultVal)        \
     uint64_t Get##_name()                                 \
@@ -50,7 +45,7 @@ public:
         if (m_uiConfigValuesRead & (1 << RCV_##_name))  \
             return m_uiConfigValues[RCV_##_name];       \
         uint64_t uiValue;                               \
-        m_uiConfigValues[RCV_##_name] = ReadConfigValue(_T(#_name), &uiValue) ? uiValue : defaultVal; \
+        m_uiConfigValues[RCV_##_name] = ReadConfigValue(#_name, &uiValue) ? uiValue : defaultVal; \
         m_uiConfigValuesRead |= 1 << RCV_##_name;       \
         return m_uiConfigValues[RCV_##_name];           \
     }
@@ -96,19 +91,11 @@ private:
     //NOTE: if the method fails configPair is left in an uninitialized state
     bool ParseConfigLine(_Out_ ConfigPair* configPair, _In_z_ const char * line);
 
-#ifdef FEATURE_EMBEDDED_CONFIG
     void ReadEmbeddedSettings();
 
-    uint32_t GetEmbeddedVariable(_In_z_ const TCHAR* configName, _Out_writes_all_(cchOutputBuffer) TCHAR* outputBuffer, _In_ uint32_t cchOutputBuffer);
-#endif // FEATURE_EMBEDDED_CONFIG
-
-    uint32_t GetConfigVariable(_In_z_ const TCHAR* configName, const ConfigPair* configPairs, _Out_writes_all_(cchOutputBuffer) TCHAR* outputBuffer, _In_ uint32_t cchOutputBuffer);
-
-    static bool priv_isspace(char c)
-    {
-        return (c == ' ') || (c == '\t') || (c == '\n') || (c == '\r');
-    }
-
+    // Gets a pointer to the embedded configuration value. Memory is held by the callee.
+    // Returns true if the variable was found, false otherwise
+    bool GetEmbeddedVariable(_In_z_ const char* configName, _Out_ const char** configValue);
 
     uint32_t  m_uiConfigValuesRead;
     uint64_t  m_uiConfigValues[RCV_Count];
index cfa8905b3471fdb3ea3a34c4024222c4f6ee8432..528cb89d4e4b13c62e4ffeadd67b8a727a80290d 100644 (file)
@@ -1366,17 +1366,8 @@ bool GCToEEInterface::GetBooleanConfigValue(const char* privateKey, const char*
         return true;
     }
 
-#ifdef UNICODE
-    size_t keyLength = strlen(privateKey) + 1;
-    TCHAR* pKey = (TCHAR*)_alloca(sizeof(TCHAR) * keyLength);
-    for (size_t i = 0; i < keyLength; i++)
-        pKey[i] = privateKey[i];
-#else
-    const TCHAR* pKey = privateKey;
-#endif
-
     uint64_t uiValue;
-    if (!g_pRhConfig->ReadConfigValue(pKey, &uiValue))
+    if (!g_pRhConfig->ReadConfigValue(privateKey, &uiValue))
         return false;
 
     *value = uiValue != 0;
@@ -1385,17 +1376,8 @@ bool GCToEEInterface::GetBooleanConfigValue(const char* privateKey, const char*
 
 bool GCToEEInterface::GetIntConfigValue(const char* privateKey, const char* publicKey, int64_t* value)
 {
-#ifdef UNICODE
-    size_t keyLength = strlen(privateKey) + 1;
-    TCHAR* pKey = (TCHAR*)_alloca(sizeof(TCHAR) * keyLength);
-    for (size_t i = 0; i < keyLength; i++)
-        pKey[i] = privateKey[i];
-#else
-    const TCHAR* pKey = privateKey;
-#endif
-
     uint64_t uiValue;
-    if (!g_pRhConfig->ReadConfigValue(pKey, &uiValue))
+    if (!g_pRhConfig->ReadConfigValue(privateKey, &uiValue))
         return false;
 
     *value = uiValue;
index 795aa8891e82900f399523fd3526ed0ae91b57aa..407adf5838626c7d80e83f34f2183ada7ac90aee 100644 (file)
@@ -354,7 +354,7 @@ void InitializeCurrentProcessCpuCount()
     const unsigned int MAX_PROCESSOR_COUNT = 0xffff;
     uint64_t configValue;
 
-    if (g_pRhConfig->ReadConfigValue(_T("PROCESSOR_COUNT"), &configValue, true /* decimal */) &&
+    if (g_pRhConfig->ReadConfigValue("PROCESSOR_COUNT", &configValue, true /* decimal */) &&
         0 < configValue && configValue <= MAX_PROCESSOR_COUNT)
     {
         count = configValue;
index 2f38d47c1631d7adb6aabe55ca8fa36be6972b5a..568d9c1cdb000cfe0788f7f25b8ca19dc8fb4ba4 100644 (file)
@@ -72,7 +72,7 @@ void InitializeCurrentProcessCpuCount()
     const unsigned int MAX_PROCESSOR_COUNT = 0xffff;
     uint64_t configValue;
 
-    if (g_pRhConfig->ReadConfigValue(_T("PROCESSOR_COUNT"), &configValue, true /* decimal */) &&
+    if (g_pRhConfig->ReadConfigValue("PROCESSOR_COUNT", &configValue, true /* decimal */) &&
         0 < configValue && configValue <= MAX_PROCESSOR_COUNT)
     {
         count = (DWORD)configValue;