mirror of
https://github.com/dlang/phobos.git
synced 2025-04-28 22:21:09 +03:00
fix Issue 16291 - EncodingScheme.create fails
- add EncodingScheme.register overload that references the registered class - just adding the FQN name of a class does not reference that class, so it must not end up in the binary and subsequently EncodingScheme.create failed - This used to work by chance b/c all the EncodingScheme implementations were in a module w/ static ctor. Any user of std.encoding did drag in that ModuleInfo, which in turn referenced all classes of std.encoding. Since moving the static ctor to std.internal.phobosinit to break a cycle, the classes were no longer referenced by a ModuleInfo w/ shared ctor, so they wouldn't end up in the binary unless explicitly referenced elsewhere. - deprecate the old EncodingScheme.register(string fqn) b/c relying on Object.factory is slow, error prone (linkage), and really unnecessary - import encodinginit in std.encoding so that the std_encoding_shared_static_this callback actually gets run
This commit is contained in:
parent
ebbdf21a7e
commit
9d73d18c0c
6 changed files with 60 additions and 32 deletions
|
@ -216,7 +216,7 @@ EXTRA_MODULES_INTERNAL := $(addprefix \
|
||||||
std/internal/digest/, sha_SSSE3 ) $(addprefix \
|
std/internal/digest/, sha_SSSE3 ) $(addprefix \
|
||||||
std/internal/math/, biguintcore biguintnoasm biguintx86 \
|
std/internal/math/, biguintcore biguintnoasm biguintx86 \
|
||||||
gammafunction errorfunction) $(addprefix std/internal/, \
|
gammafunction errorfunction) $(addprefix std/internal/, \
|
||||||
cstring phobosinit processinit unicode_tables scopebuffer\
|
cstring encodinginit processinit unicode_tables scopebuffer\
|
||||||
unicode_comp unicode_decomp unicode_grapheme unicode_norm) \
|
unicode_comp unicode_decomp unicode_grapheme unicode_norm) \
|
||||||
$(addprefix std/internal/test/, dummyrange) \
|
$(addprefix std/internal/test/, dummyrange) \
|
||||||
$(addprefix std/experimental/ndslice/, internal) \
|
$(addprefix std/experimental/ndslice/, internal) \
|
||||||
|
|
|
@ -55,6 +55,7 @@ module std.encoding;
|
||||||
import std.traits;
|
import std.traits;
|
||||||
import std.typecons;
|
import std.typecons;
|
||||||
import std.range.primitives;
|
import std.range.primitives;
|
||||||
|
import std.internal.encodinginit;
|
||||||
|
|
||||||
@system unittest
|
@system unittest
|
||||||
{
|
{
|
||||||
|
@ -2360,17 +2361,30 @@ abstract class EncodingScheme
|
||||||
* This function allows user-defined subclasses of EncodingScheme to
|
* This function allows user-defined subclasses of EncodingScheme to
|
||||||
* be declared in other modules.
|
* be declared in other modules.
|
||||||
*
|
*
|
||||||
|
* Params:
|
||||||
|
* Klass = The subclass of EncodingScheme to register.
|
||||||
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* ----------------------------------------------
|
* ----------------------------------------------
|
||||||
* class Amiga1251 : EncodingScheme
|
* class Amiga1251 : EncodingScheme
|
||||||
* {
|
* {
|
||||||
* shared static this()
|
* shared static this()
|
||||||
* {
|
* {
|
||||||
* EncodingScheme.register("path.to.Amiga1251");
|
* EncodingScheme.register!Amiga1251;
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
* ----------------------------------------------
|
* ----------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
static void register(Klass:EncodingScheme)()
|
||||||
|
{
|
||||||
|
scope scheme = new Klass();
|
||||||
|
foreach (encodingName;scheme.names())
|
||||||
|
{
|
||||||
|
supported[toLower(encodingName)] = () => new Klass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deprecated("Please pass the EncodingScheme subclass as template argument instead.")
|
||||||
static void register(string className)
|
static void register(string className)
|
||||||
{
|
{
|
||||||
auto scheme = cast(EncodingScheme)ClassInfo.find(className).create();
|
auto scheme = cast(EncodingScheme)ClassInfo.find(className).create();
|
||||||
|
@ -2378,7 +2392,7 @@ abstract class EncodingScheme
|
||||||
throw new EncodingException("Unable to create class "~className);
|
throw new EncodingException("Unable to create class "~className);
|
||||||
foreach (encodingName;scheme.names())
|
foreach (encodingName;scheme.names())
|
||||||
{
|
{
|
||||||
supported[toLower(encodingName)] = className;
|
supportedFactories[toLower(encodingName)] = className;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2396,7 +2410,12 @@ abstract class EncodingScheme
|
||||||
*/
|
*/
|
||||||
static EncodingScheme create(string encodingName)
|
static EncodingScheme create(string encodingName)
|
||||||
{
|
{
|
||||||
auto p = toLower(encodingName) in supported;
|
encodingName = toLower(encodingName);
|
||||||
|
|
||||||
|
if (auto p = encodingName in supported)
|
||||||
|
return (*p)();
|
||||||
|
|
||||||
|
auto p = encodingName in supportedFactories;
|
||||||
if (p is null)
|
if (p is null)
|
||||||
throw new EncodingException("Unrecognized Encoding: "~encodingName);
|
throw new EncodingException("Unrecognized Encoding: "~encodingName);
|
||||||
string className = *p;
|
string className = *p;
|
||||||
|
@ -2650,7 +2669,8 @@ abstract class EncodingScheme
|
||||||
return t.length - s.length;
|
return t.length - s.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
__gshared string[string] supported;
|
__gshared EncodingScheme function()[string] supported;
|
||||||
|
__gshared string[string] supportedFactories;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3297,6 +3317,20 @@ class EncodingSchemeUtf32Native : EncodingScheme
|
||||||
assert(ub.length == 8);
|
assert(ub.length == 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// shared static this() called from encodinginit to break ctor cycle
|
||||||
|
extern(C) void std_encoding_shared_static_this()
|
||||||
|
{
|
||||||
|
EncodingScheme.register!EncodingSchemeASCII;
|
||||||
|
EncodingScheme.register!EncodingSchemeLatin1;
|
||||||
|
EncodingScheme.register!EncodingSchemeLatin2;
|
||||||
|
EncodingScheme.register!EncodingSchemeWindows1250;
|
||||||
|
EncodingScheme.register!EncodingSchemeWindows1252;
|
||||||
|
EncodingScheme.register!EncodingSchemeUtf8;
|
||||||
|
EncodingScheme.register!EncodingSchemeUtf16Native;
|
||||||
|
EncodingScheme.register!EncodingSchemeUtf32Native;
|
||||||
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
|
|
||||||
|
|
19
std/internal/encodinginit.d
Normal file
19
std/internal/encodinginit.d
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
// Written in the D programming language.
|
||||||
|
|
||||||
|
/++
|
||||||
|
The purpose of this module is to perform static construction away from the
|
||||||
|
normal modules to eliminate cyclic construction errors.
|
||||||
|
|
||||||
|
Copyright: Copyright 2011 - 2016
|
||||||
|
License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
|
||||||
|
Authors: Martin Nowak, Steven Schveighoffer
|
||||||
|
Source: $(PHOBOSSRC std/internal/_encodinginit.d)
|
||||||
|
+/
|
||||||
|
module std.internal.encodinginit;
|
||||||
|
|
||||||
|
extern(C) void std_encoding_shared_static_this();
|
||||||
|
|
||||||
|
shared static this()
|
||||||
|
{
|
||||||
|
std_encoding_shared_static_this();
|
||||||
|
}
|
|
@ -1,25 +0,0 @@
|
||||||
// Written in the D programming language.
|
|
||||||
|
|
||||||
/++
|
|
||||||
The purpose of this module is to perform static construction away from the
|
|
||||||
normal modules to eliminate cyclic construction errors.
|
|
||||||
|
|
||||||
Copyright: Copyright 2011 - 2016
|
|
||||||
License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
|
|
||||||
Authors: Jonathan M Davis, Kato Shoichi, Steven Schveighoffer
|
|
||||||
Source: $(PHOBOSSRC std/internal/_phobosinit.d)
|
|
||||||
+/
|
|
||||||
module std.internal.phobosinit;
|
|
||||||
|
|
||||||
shared static this()
|
|
||||||
{
|
|
||||||
import std.encoding : EncodingScheme;
|
|
||||||
EncodingScheme.register("std.encoding.EncodingSchemeASCII");
|
|
||||||
EncodingScheme.register("std.encoding.EncodingSchemeLatin1");
|
|
||||||
EncodingScheme.register("std.encoding.EncodingSchemeLatin2");
|
|
||||||
EncodingScheme.register("std.encoding.EncodingSchemeWindows1250");
|
|
||||||
EncodingScheme.register("std.encoding.EncodingSchemeWindows1252");
|
|
||||||
EncodingScheme.register("std.encoding.EncodingSchemeUtf8");
|
|
||||||
EncodingScheme.register("std.encoding.EncodingSchemeUtf16Native");
|
|
||||||
EncodingScheme.register("std.encoding.EncodingSchemeUtf32Native");
|
|
||||||
}
|
|
|
@ -267,7 +267,7 @@ SRC_STD_C_FREEBSD= \
|
||||||
|
|
||||||
SRC_STD_INTERNAL= \
|
SRC_STD_INTERNAL= \
|
||||||
std\internal\cstring.d \
|
std\internal\cstring.d \
|
||||||
std\internal\phobosinit.d \
|
std\internal\encodinginit.d \
|
||||||
std\internal\processinit.d \
|
std\internal\processinit.d \
|
||||||
std\internal\unicode_tables.d \
|
std\internal\unicode_tables.d \
|
||||||
std\internal\unicode_comp.d \
|
std\internal\unicode_comp.d \
|
||||||
|
|
|
@ -286,7 +286,7 @@ SRC_STD_C_FREEBSD= \
|
||||||
|
|
||||||
SRC_STD_INTERNAL= \
|
SRC_STD_INTERNAL= \
|
||||||
std\internal\cstring.d \
|
std\internal\cstring.d \
|
||||||
std\internal\phobosinit.d \
|
std\internal\encodinginit.d \
|
||||||
std\internal\processinit.d \
|
std\internal\processinit.d \
|
||||||
std\internal\unicode_tables.d \
|
std\internal\unicode_tables.d \
|
||||||
std\internal\unicode_comp.d \
|
std\internal\unicode_comp.d \
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue