Skip to content

Commit df3de09

Browse files
committed
Adds interfaces to GetACP() and GetOEMCP()
Patch from Steve Hay: However, they actually return information about the operating system defaults, so GetOEMCP() doesn't get the correct value of a Command Prompt's code page if you've changed it from its initial default value using (e.g.) "mode con cp select=...". The patch therefore adds GetConsoleCP() and GetConsoleOutputCP() as well. The latter is what you need to correctly get the current console's output code page. The patch also adds SetConsoleCP() and SetConsoleOutputCP(), since they can be very useful too. For example, in the core perl t/op/magic.t script, which started all this for me, it is now possible to set the console's output code page to match perl's code page (the Windows ANSI code page) and thus avoid the need to convert the encoding of data read from the console (which was originally going to be my approach).
1 parent 841409b commit df3de09

File tree

6 files changed

+128
-2
lines changed

6 files changed

+128
-2
lines changed

Changes

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
Revision history for the Perl extension Win32.
22

3+
0.45 [2012-08-07]
4+
- add Win32::GetACP(), Win32::GetConsoleCP(),
5+
Win32::GetConsoleOutputCP(), Win32::GetOEMCP(), Win32::SetConsoleCP()
6+
and Win32::SetConsoleOutputCP(). [rt#78820] (Steve Hay)
7+
38
0.44 [2011-01-12]
49
- fix memory leak introduced in 0.43
510

MANIFEST

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ README
66
Win32.pm
77
Win32.xs
88
longpath.inc
9+
t/CodePage.t
910
t/CreateFile.t
1011
t/ExpandEnvironmentStrings.t
1112
t/GetCurrentThreadId.t

META.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
--- #YAML:1.0
22
name: Win32
33
abstract: Interfaces to some Win32 API Functions
4-
version: 0.44
4+
version: 0.45
55
author:
66
- Jan Dubois <[email protected]>
77
license: perl

Win32.pm

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ package Win32;
88
require DynaLoader;
99

1010
@ISA = qw|Exporter DynaLoader|;
11-
$VERSION = '0.44';
11+
$VERSION = '0.45';
1212
$XS_VERSION = $VERSION;
1313
$VERSION = eval $VERSION;
1414

@@ -686,6 +686,11 @@ Unloads a previously loaded dynamic-link library. The HANDLE is
686686
no longer valid after this call. See L<LoadLibrary|Win32::LoadLibrary(LIBNAME)>
687687
for information on dynamically loading a library.
688688
689+
=item Win32::GetACP()
690+
691+
Returns the current Windows ANSI code page identifier for the operating
692+
system. See also GetOEMCP(), GetConsoleCP() and GetConsoleOutputCP().
693+
689694
=item Win32::GetANSIPathName(FILENAME)
690695
691696
Returns an ANSI version of FILENAME. This may be the short name
@@ -712,6 +717,20 @@ for the x64 processor and 2200 for the Itanium. Since it returns the
712717
native processor type it will return a 64-bit processor type even when
713718
called from a 32-bit Perl running on 64-bit Windows.
714719
720+
=item Win32::GetConsoleCP()
721+
722+
Returns the input code page used by the console associated with the
723+
calling process. To set the console's input code page, see
724+
SetConsoleCP(). See also GetConsoleOutputCP(), GetACP() and
725+
GetOEMCP().
726+
727+
=item Win32::GetConsoleOutputCP()
728+
729+
Returns the output code page used by the console associated with the
730+
calling process. To set the console's output code page, see
731+
SetConsoleOutputCP(). See also GetConsoleCP(), GetACP(), and
732+
GetOEMCP().
733+
715734
=item Win32::GetCwd()
716735
717736
[CORE] Returns the current active drive and directory. This function
@@ -848,6 +867,12 @@ before passing the path to a system call or another program.
848867
[CORE] Returns a string in the form of "<d>:" where <d> is the first
849868
available drive letter.
850869
870+
=item Win32::GetOEMCP()
871+
872+
Returns the current original equipment manufacturer (OEM) code page
873+
identifier for the operating system. See also GetACP(), GetConsoleCP()
874+
and GetConsoleOutputCP().
875+
851876
=item Win32::GetOSDisplayName()
852877
853878
Returns the "marketing" name of the Windows operating system version
@@ -1167,6 +1192,20 @@ The following symbolic constants for SHOWWINDOW are available
11671192
(but not exported) from the Win32 module: SW_HIDE, SW_SHOWNORMAL,
11681193
SW_SHOWMINIMIZED, SW_SHOWMAXIMIZED and SW_SHOWNOACTIVATE.
11691194
1195+
=item Win32::SetConsoleCP(ID)
1196+
1197+
Sets the input code page used by the console associated with the
1198+
calling process. The return value of SetConsoleCP() is nonzero on
1199+
success or zero on failure. To get the console's input code page, see
1200+
GetConsoleCP().
1201+
1202+
=item Win32::SetConsoleOutputCP(ID)
1203+
1204+
Sets the output code page used by the console associated with the
1205+
calling process. The return value of SetConsoleOutputCP() is nonzero on
1206+
success or zero on failure. To get the console's output code page, see
1207+
GetConsoleOutputCP().
1208+
11701209
=item Win32::SetCwd(NEWDIRECTORY)
11711210
11721211
[CORE] Sets the current active drive and directory. This function does not

Win32.xs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1705,6 +1705,54 @@ XS(w32_GetProductInfo)
17051705
XSRETURN_IV(0);
17061706
}
17071707

1708+
XS(w32_GetACP)
1709+
{
1710+
dXSARGS;
1711+
EXTEND(SP,1);
1712+
XSRETURN_IV(GetACP());
1713+
}
1714+
1715+
XS(w32_GetConsoleCP)
1716+
{
1717+
dXSARGS;
1718+
EXTEND(SP,1);
1719+
XSRETURN_IV(GetConsoleCP());
1720+
}
1721+
1722+
XS(w32_GetConsoleOutputCP)
1723+
{
1724+
dXSARGS;
1725+
EXTEND(SP,1);
1726+
XSRETURN_IV(GetConsoleOutputCP());
1727+
}
1728+
1729+
XS(w32_GetOEMCP)
1730+
{
1731+
dXSARGS;
1732+
EXTEND(SP,1);
1733+
XSRETURN_IV(GetOEMCP());
1734+
}
1735+
1736+
XS(w32_SetConsoleCP)
1737+
{
1738+
dXSARGS;
1739+
1740+
if (items != 1)
1741+
Perl_croak(aTHX_ "usage: Win32::SetConsoleCP($id)");
1742+
1743+
XSRETURN_IV(SetConsoleCP((int)SvIV(ST(0))));
1744+
}
1745+
1746+
XS(w32_SetConsoleOutputCP)
1747+
{
1748+
dXSARGS;
1749+
1750+
if (items != 1)
1751+
Perl_croak(aTHX_ "usage: Win32::SetConsoleOutputCP($id)");
1752+
1753+
XSRETURN_IV(SetConsoleOutputCP((int)SvIV(ST(0))));
1754+
}
1755+
17081756
MODULE = Win32 PACKAGE = Win32
17091757

17101758
PROTOTYPES: DISABLE
@@ -1768,6 +1816,12 @@ BOOT:
17681816
newXS("Win32::CreateFile", w32_CreateFile, file);
17691817
newXS("Win32::GetSystemMetrics", w32_GetSystemMetrics, file);
17701818
newXS("Win32::GetProductInfo", w32_GetProductInfo, file);
1819+
newXS("Win32::GetACP", w32_GetACP, file);
1820+
newXS("Win32::GetConsoleCP", w32_GetConsoleCP, file);
1821+
newXS("Win32::GetConsoleOutputCP", w32_GetConsoleOutputCP, file);
1822+
newXS("Win32::GetOEMCP", w32_GetOEMCP, file);
1823+
newXS("Win32::SetConsoleCP", w32_SetConsoleCP, file);
1824+
newXS("Win32::SetConsoleOutputCP", w32_SetConsoleOutputCP, file);
17711825
#ifdef __CYGWIN__
17721826
newXS("Win32::SetChildShowWindow", w32_SetChildShowWindow, file);
17731827
#endif

t/CodePage.t

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
use strict;
2+
use Test;
3+
use Win32;
4+
5+
plan tests => 8;
6+
7+
my $ansicp = Win32::GetACP();
8+
ok($ansicp > 0 && $ansicp <= 65001);
9+
10+
my $inputcp = Win32::GetConsoleCP();
11+
ok($inputcp > 0 && $inputcp <= 65001);
12+
13+
my $outputcp = Win32::GetConsoleOutputCP();
14+
ok($outputcp > 0 && $outputcp <= 65001);
15+
16+
my $oemcp = Win32::GetOEMCP();
17+
ok($oemcp > 0 && $oemcp <= 65001);
18+
19+
ok(Win32::SetConsoleCP($ansicp));
20+
ok(Win32::GetConsoleCP() == $ansicp);
21+
22+
ok(Win32::SetConsoleOutputCP($ansicp));
23+
ok(Win32::GetConsoleOutputCP() == $ansicp);
24+
25+
# Reset things when we're done.
26+
Win32::SetConsoleCP($inputcp);
27+
Win32::SetConsoleOutputCP($outputcp);

0 commit comments

Comments
 (0)