diff options
author | Kyungwoo Lee <kyulee@microsoft.com> | 2015-12-03 14:26:05 -0800 |
---|---|---|
committer | Kyungwoo Lee <kyulee@microsoft.com> | 2015-12-03 20:41:18 -0800 |
commit | 1d34f6293740f4f79f8b362c2d605fa2a527d538 (patch) | |
tree | a716d441f4449582b25bf2de9b264ba56fd8ee19 /src/nativeresources | |
parent | 0bdc646c5955ca0c735a3976d01969b246e848ef (diff) | |
download | coreclr-1d34f6293740f4f79f8b362c2d605fa2a527d538.tar.gz coreclr-1d34f6293740f4f79f8b362c2d605fa2a527d538.tar.bz2 coreclr-1d34f6293740f4f79f8b362c2d605fa2a527d538.zip |
Refactoring resource string
This pulls out resource string handling out of mscorrc into top level.
The scripts (awk) are now parameterized to generate a unique string table for the
given name.
Added resourcestring.cpp to create an API "LoadResourceString".
Added a few macros into resourcestring.h, which are used for definition/uses of
the string table.
Diffstat (limited to 'src/nativeresources')
-rw-r--r-- | src/nativeresources/.gitmirror | 1 | ||||
-rw-r--r-- | src/nativeresources/CMakeLists.txt | 9 | ||||
-rw-r--r-- | src/nativeresources/processrc.awk | 64 | ||||
-rw-r--r-- | src/nativeresources/rctocpp.awk | 84 | ||||
-rw-r--r-- | src/nativeresources/rctopo.awk | 21 | ||||
-rw-r--r-- | src/nativeresources/resourcestring.cpp | 63 | ||||
-rw-r--r-- | src/nativeresources/resourcestring.h | 33 |
7 files changed, 275 insertions, 0 deletions
diff --git a/src/nativeresources/.gitmirror b/src/nativeresources/.gitmirror new file mode 100644 index 0000000000..f507630f94 --- /dev/null +++ b/src/nativeresources/.gitmirror @@ -0,0 +1 @@ +Only contents of this folder, excluding subfolders, will be mirrored by the Git-TFS Mirror.
\ No newline at end of file diff --git a/src/nativeresources/CMakeLists.txt b/src/nativeresources/CMakeLists.txt new file mode 100644 index 0000000000..5bc326492a --- /dev/null +++ b/src/nativeresources/CMakeLists.txt @@ -0,0 +1,9 @@ +project(nativeresourcestring) + +add_compile_options(-fPIC) + +add_library(nativeresourcestring + STATIC + resourcestring.cpp +) + diff --git a/src/nativeresources/processrc.awk b/src/nativeresources/processrc.awk new file mode 100644 index 0000000000..1632753956 --- /dev/null +++ b/src/nativeresources/processrc.awk @@ -0,0 +1,64 @@ +# Parse string resources from Windows native resource file +# and pass them to the writestringentry function that +# is responsible for writing the resource id and string +# to a platform specific resource file. +# A script containing this function needs to be specified +# using the -f command line parameter before this script. + +BEGIN { + inStringTable = 0; + inBeginEnd = 0; + arrayName = "nativeStringResourceArray_" name; + tableName = "nativeStringResourceTable_" name; + writeheader(arrayName, tableName); +} +{ + if ($1 == "STRINGTABLE" && $2 == "DISCARDABLE") + { + inStringTable = 1; + } + else if ($1 == "BEGIN") + { + inBeginEnd = inStringTable; + } + else if (inBeginEnd && $1 == "END") + { + inBeginEnd = 0; + inStringTable = 0; + } + else if (inBeginEnd && $1 != "") + { + # combine all items until the first string and remove them + # from the line + i = 1 + expression = "" + # string starts with either a quote or L followed by a quote + while (substr($i, 1, 1) != "\"" && substr($i, 1, 2) != "L\"") + { + # some of the resource IDs contain cast to HRESULT + gsub(/\(HRESULT\)/, "", $i); + # some of the resource IDs have trailing L + gsub(/L/, "", $i); + expression = expression $i; + $i=""; + i++; + } + # evaluate the resource ID expression + cmd = "echo $(("expression"))"; + cmd | getline var; + close(cmd); + # in case shell returned the result as a string, ensure the var has numeric type + var = var + 0; + + # remove the L prefix from strings + gsub(/L"/, "\"", $0); + # join strings "..." "..." into one + gsub(/" +"/, "", $0); + + # write the resource entry to the target file + writestringentry(var, $0); + } +} +END { + writefooter(arrayName, tableName); +} diff --git a/src/nativeresources/rctocpp.awk b/src/nativeresources/rctocpp.awk new file mode 100644 index 0000000000..e631021b35 --- /dev/null +++ b/src/nativeresources/rctocpp.awk @@ -0,0 +1,84 @@ +# Convert string resources from Windows native resource file to a C++ +# source file with an array of structs representing the resources. + +BEGIN { + numEntries = 0; +} + +# Takes a number and returns a string corresponding to its hex +# representation. A string representation that has fewer than 8 +# characters (not including the '0x' prefix) is padded with 0's +# to make it 8 characters. +# Example: an input of 49 yields "0x00000031". +function numberToHexString(number) +{ + quotient = number; + + hexString = ""; + for (digitCount = 0; digitCount < 8; digitCount++) + { + remainder = quotient % 16; + quotient = int(quotient / 16); + hexString = sprintf("%x"hexString, remainder); + } + + hexString = "0x" hexString; + return hexString; +} + +# Add each entry that is in our associative array of entries to the +# C++ array we are building. The C++ array will be ordered by the +# resourceId (lowest to highest) to facilitate quick lookups. +function writesortedentries() +{ + for (entry in resourceArray) + { + # Write the entries to the C++ array ordered by the ID. + printf " {%s,%s},\n", entry, resourceArray[entry] | "sort"; + } + + # Close the pipe to ensure that the data is written now. + close("sort"); +} + +# Write entry for a string resource +# This is called for each entry. Because we want to write them in +# sorted order once all the entries have come in, for now we just +# store each entry in an associative array. +function writestringentry(id, str) +{ + numEntries++; + + # Use the string representation of the ID as the array index + # because the precision of numeric indices can be lost during + # the number -> string -> number conversions that would occur + # if numeric indices are used. + resourceArray[numberToHexString(id)] = str; +} + +# Write file header and begin the array we will populate with the resources. +function writeheader(arrayName, tableName) +{ + print "// This code was generated by rctocpp.awk and is not meant to be modified manually." + print "#include <resourcestring.h>"; + print ""; + print "extern const NativeStringResourceTable " tableName ";"; + print "const NativeStringResource " arrayName "[] = {"; +} + +# Write file footer +# This function is called after all of the entries have been given to +# writestringentry. Because we know there are no more entries, we can +# now write all the entries we received so far when this is called. +# After we have written all the entries, we close the array and add a +# constant for the size of the array for convenience. +function writefooter(arrayName, tableName) +{ + writesortedentries(); + print "};"; + print ""; + + print "const NativeStringResourceTable " tableName " = {"; + print numEntries ","; + print arrayName "};"; +} diff --git a/src/nativeresources/rctopo.awk b/src/nativeresources/rctopo.awk new file mode 100644 index 0000000000..5229585ff5 --- /dev/null +++ b/src/nativeresources/rctopo.awk @@ -0,0 +1,21 @@ +# Convert string resources from Windows native resource file to the +# input format of the gettext toolchain. + +# Write entry for a string resource +function writestringentry(id, str) +{ + idAsStr = sprintf("%X", id); + print "msgid \""idAsStr"\""; + print "msgstr" str; + print ""; +} + +# Write file header +function writeheader() +{ +} + +# Write file footer +function writefooter() +{ +} diff --git a/src/nativeresources/resourcestring.cpp b/src/nativeresources/resourcestring.cpp new file mode 100644 index 0000000000..75fb1ececd --- /dev/null +++ b/src/nativeresources/resourcestring.cpp @@ -0,0 +1,63 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + + +#include <stdio.h> +#include <utilcode.h> +#include "resourcestring.h" + +static int CompareNativeStringResources(const void *a, const void *b) +{ + unsigned int resourceIdA = ((NativeStringResource*)a)->resourceId; + unsigned int resourceIdB = ((NativeStringResource*)b)->resourceId; + + if (resourceIdA < resourceIdB) + return -1; + + if (resourceIdA == resourceIdB) + return 0; + + return 1; +} + +int LoadNativeStringResource(const NativeStringResourceTable &nativeStringResourceTable, unsigned int iResourceID, WCHAR* szBuffer, int iMax, int *pcwchUsed) +{ + int len = 0; + if (szBuffer && iMax) + { + // Search the sorted set of resources for the ID we're interested in. + NativeStringResource searchEntry = {iResourceID, NULL}; + NativeStringResource *resourceEntry = (NativeStringResource*)bsearch( + &searchEntry, + nativeStringResourceTable.table, + nativeStringResourceTable.size, + sizeof(NativeStringResource), + CompareNativeStringResources); + + if (resourceEntry != NULL) + { + len = PAL_GetResourceString(NULL, resourceEntry->resourceString, szBuffer, iMax); + } + else + { + // The resource ID wasn't found in our array. Fall back on returning the ID as a string. + len = _snwprintf(szBuffer, iMax - 1, W("[Undefined resource string ID:0x%X]"), iResourceID); + if ((len < 0) || (len == (iMax - 1))) + { + // Add string terminator if the result of _snwprintf didn't fit the buffer. + szBuffer[iMax - 1] = W('\0'); + len = iMax - 1; + } + } + } + + if (pcwchUsed) + { + *pcwchUsed = len; + } + + return S_OK; +} + diff --git a/src/nativeresources/resourcestring.h b/src/nativeresources/resourcestring.h new file mode 100644 index 0000000000..1545b3c48f --- /dev/null +++ b/src/nativeresources/resourcestring.h @@ -0,0 +1,33 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +#ifndef __RESOURCE_STRING_H_ +#define __RESOURCE_STRING_H_ + +// Struct to contain a resource ID and its corresponding +// English language string. +struct NativeStringResource +{ + unsigned int resourceId; + const char* resourceString; +}; + +struct NativeStringResourceTable +{ + const int size; + const NativeStringResource *table; +}; + +int LoadNativeStringResource(const NativeStringResourceTable &nativeStringResourceTable, unsigned int iResourceID, char16_t* szBuffer, int iMax, int *pcwchUsed); + +#define CONCAT(a, b) a ## b + +#define NATIVE_STRING_RESOURCE_TABLE(name) CONCAT(nativeStringResourceTable_, name) + +#define DECLARE_NATIVE_STRING_RESOURCE_TABLE(name) \ + extern const NativeStringResourceTable NATIVE_STRING_RESOURCE_TABLE(name) + +#endif // __RESOURCE_STRING_H_ + |