Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
8ea4102a
Commit
8ea4102a
authored
Dec 04, 2009
by
Nikolay Sivov
Committed by
Alexandre Julliard
Dec 04, 2009
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
kernel32/lcformat: Add support for genitive month names in GetDateFormat().
parent
8e4f283e
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
150 additions
and
9 deletions
+150
-9
lcformat.c
dlls/kernel32/lcformat.c
+81
-9
locale.c
dlls/kernel32/tests/locale.c
+69
-0
No files found.
dlls/kernel32/lcformat.c
View file @
8ea4102a
...
...
@@ -52,7 +52,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(nls);
*
* Our cache takes the form of a singly linked list, whose node is below:
*/
#define NLS_NUM_CACHED_STRINGS
45
#define NLS_NUM_CACHED_STRINGS
57
typedef
struct
_NLS_FORMAT_NODE
{
...
...
@@ -72,14 +72,15 @@ typedef struct _NLS_FORMAT_NODE
#define GetLongDate(fmt) fmt->lppszStrings[1]
#define GetShortDate(fmt) fmt->lppszStrings[2]
#define GetTime(fmt) fmt->lppszStrings[3]
#define GetAM(fmt) fmt->lppszStrings[
42
]
#define GetPM(fmt) fmt->lppszStrings[
43
]
#define GetYearMonth(fmt) fmt->lppszStrings[
44
]
#define GetAM(fmt) fmt->lppszStrings[
54
]
#define GetPM(fmt) fmt->lppszStrings[
55
]
#define GetYearMonth(fmt) fmt->lppszStrings[
56
]
#define GetLongDay(fmt,day) fmt->lppszStrings[4 + day]
#define GetShortDay(fmt,day) fmt->lppszStrings[11 + day]
#define GetLongMonth(fmt,mth) fmt->lppszStrings[18 + mth]
#define GetShortMonth(fmt,mth) fmt->lppszStrings[30 + mth]
#define GetLongDay(fmt,day) fmt->lppszStrings[4 + day]
#define GetShortDay(fmt,day) fmt->lppszStrings[11 + day]
#define GetLongMonth(fmt,mth) fmt->lppszStrings[18 + mth]
#define GetGenitiveMonth(fmt,mth) fmt->lppszStrings[30 + mth]
#define GetShortMonth(fmt,mth) fmt->lppszStrings[42 + mth]
/* Write access to the cache is protected by this critical section */
static
CRITICAL_SECTION
NLS_FormatsCS
;
...
...
@@ -150,7 +151,7 @@ static WCHAR* NLS_GetLocaleString(LCID lcid, DWORD dwFlags)
static
const
NLS_FORMAT_NODE
*
NLS_GetFormats
(
LCID
lcid
,
DWORD
dwFlags
)
{
/* GetLocaleInfo() identifiers for cached formatting strings */
static
const
USHORT
NLS_LocaleIndices
[]
=
{
static
const
LCTYPE
NLS_LocaleIndices
[]
=
{
LOCALE_SNEGATIVESIGN
,
LOCALE_SLONGDATE
,
LOCALE_SSHORTDATE
,
LOCALE_STIMEFORMAT
,
...
...
@@ -163,6 +164,18 @@ static const NLS_FORMAT_NODE *NLS_GetFormats(LCID lcid, DWORD dwFlags)
LOCALE_SMONTHNAME4
,
LOCALE_SMONTHNAME5
,
LOCALE_SMONTHNAME6
,
LOCALE_SMONTHNAME7
,
LOCALE_SMONTHNAME8
,
LOCALE_SMONTHNAME9
,
LOCALE_SMONTHNAME10
,
LOCALE_SMONTHNAME11
,
LOCALE_SMONTHNAME12
,
LOCALE_SMONTHNAME1
|
LOCALE_RETURN_GENITIVE_NAMES
,
LOCALE_SMONTHNAME2
|
LOCALE_RETURN_GENITIVE_NAMES
,
LOCALE_SMONTHNAME3
|
LOCALE_RETURN_GENITIVE_NAMES
,
LOCALE_SMONTHNAME4
|
LOCALE_RETURN_GENITIVE_NAMES
,
LOCALE_SMONTHNAME5
|
LOCALE_RETURN_GENITIVE_NAMES
,
LOCALE_SMONTHNAME6
|
LOCALE_RETURN_GENITIVE_NAMES
,
LOCALE_SMONTHNAME7
|
LOCALE_RETURN_GENITIVE_NAMES
,
LOCALE_SMONTHNAME8
|
LOCALE_RETURN_GENITIVE_NAMES
,
LOCALE_SMONTHNAME9
|
LOCALE_RETURN_GENITIVE_NAMES
,
LOCALE_SMONTHNAME10
|
LOCALE_RETURN_GENITIVE_NAMES
,
LOCALE_SMONTHNAME11
|
LOCALE_RETURN_GENITIVE_NAMES
,
LOCALE_SMONTHNAME12
|
LOCALE_RETURN_GENITIVE_NAMES
,
LOCALE_SABBREVMONTHNAME1
,
LOCALE_SABBREVMONTHNAME2
,
LOCALE_SABBREVMONTHNAME3
,
LOCALE_SABBREVMONTHNAME4
,
LOCALE_SABBREVMONTHNAME5
,
LOCALE_SABBREVMONTHNAME6
,
LOCALE_SABBREVMONTHNAME7
,
LOCALE_SABBREVMONTHNAME8
,
LOCALE_SABBREVMONTHNAME9
,
...
...
@@ -249,6 +262,16 @@ static const NLS_FORMAT_NODE *NLS_GetFormats(LCID lcid, DWORD dwFlags)
{
GET_LOCALE_STRING
(
new_node
->
lppszStrings
[
i
],
NLS_LocaleIndices
[
i
]);
}
/* Save some memory if month genitive name is the same or not present */
for
(
i
=
0
;
i
<
12
;
i
++
)
{
if
(
strcmpW
(
GetLongMonth
(
new_node
,
i
),
GetGenitiveMonth
(
new_node
,
i
))
==
0
)
{
HeapFree
(
GetProcessHeap
(),
0
,
GetGenitiveMonth
(
new_node
,
i
));
GetGenitiveMonth
(
new_node
,
i
)
=
NULL
;
}
}
new_node
->
szShortAM
[
0
]
=
GetAM
(
new_node
)[
0
];
new_node
->
szShortAM
[
1
]
=
'\0'
;
new_node
->
szShortPM
[
0
]
=
GetPM
(
new_node
)[
0
];
new_node
->
szShortPM
[
1
]
=
'\0'
;
...
...
@@ -352,6 +375,7 @@ static INT NLS_GetDateTimeFormatW(LCID lcid, DWORD dwFlags,
INT
cchWritten
=
0
;
INT
lastFormatPos
=
0
;
BOOL
bSkipping
=
FALSE
;
/* Skipping text around marker? */
BOOL
d_dd_formatted
=
FALSE
;
/* previous formatted part was for d or dd */
/* Verify our arguments */
if
((
cchOut
&&
!
lpStr
)
||
!
(
node
=
NLS_GetFormats
(
lcid
,
dwFlags
)))
...
...
@@ -485,6 +509,7 @@ static INT NLS_GetDateTimeFormatW(LCID lcid, DWORD dwFlags,
}
buff
[
0
]
=
'\0'
;
if
(
fmtChar
!=
'M'
)
d_dd_formatted
=
FALSE
;
switch
(
fmtChar
)
{
case
'd'
:
...
...
@@ -496,12 +521,59 @@ static INT NLS_GetDateTimeFormatW(LCID lcid, DWORD dwFlags,
{
dwVal
=
lpTime
->
wDay
;
szAdd
=
buff
;
d_dd_formatted
=
TRUE
;
}
break
;
case
'M'
:
if
(
count
>=
4
)
{
LPCWSTR
genitive
=
GetGenitiveMonth
(
node
,
lpTime
->
wMonth
-
1
);
if
(
genitive
)
{
if
(
d_dd_formatted
)
{
szAdd
=
genitive
;
break
;
}
else
{
LPCWSTR
format
=
lpFormat
;
/* Look forward now, if next format pattern is for day genitive
name should be used */
while
(
*
format
)
{
/* Skip parts within markers */
if
(
IsLiteralMarker
(
*
format
))
{
++
format
;
while
(
*
format
)
{
if
(
IsLiteralMarker
(
*
format
))
{
++
format
;
if
(
!
IsLiteralMarker
(
*
format
))
break
;
}
}
}
if
(
*
format
!=
' '
)
break
;
++
format
;
}
/* Only numeric day form matters */
if
(
*
format
&&
*
format
==
'd'
)
{
INT
dcount
=
1
;
while
(
*++
format
==
'd'
)
dcount
++
;
if
(
dcount
<
3
)
{
szAdd
=
genitive
;
break
;
}
}
}
}
szAdd
=
GetLongMonth
(
node
,
lpTime
->
wMonth
-
1
);
}
else
if
(
count
==
3
)
szAdd
=
GetShortMonth
(
node
,
lpTime
->
wMonth
-
1
);
else
...
...
dlls/kernel32/tests/locale.c
View file @
8ea4102a
...
...
@@ -28,6 +28,7 @@
#include <assert.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include "wine/test.h"
#include "windef.h"
...
...
@@ -466,7 +467,9 @@ static void test_GetDateFormatA(void)
int
ret
;
SYSTEMTIME
curtime
;
LCID
lcid
=
MAKELCID
(
MAKELANGID
(
LANG_ENGLISH
,
SUBLANG_ENGLISH_US
),
SORT_DEFAULT
);
LCID
lcid_ru
=
MAKELCID
(
MAKELANGID
(
LANG_RUSSIAN
,
SUBLANG_NEUTRAL
),
SORT_DEFAULT
);
char
buffer
[
BUFFER_SIZE
],
input
[
BUFFER_SIZE
],
Expected
[
BUFFER_SIZE
];
char
short_day
[
10
],
month
[
10
],
genitive_month
[
10
];
memset
(
&
curtime
,
2
,
sizeof
(
SYSTEMTIME
));
/* Invalid time */
STRINGSA
(
"ddd',' MMM dd yy"
,
""
);
...
...
@@ -542,6 +545,72 @@ static void test_GetDateFormatA(void)
&
curtime
,
input
,
buffer
,
COUNTOF
(
buffer
));
ok
(
!
ret
&&
GetLastError
()
==
ERROR_INVALID_FLAGS
,
"Expected ERROR_INVALID_FLAGS, got %d
\n
"
,
GetLastError
());
ret
=
GetDateFormat
(
lcid_ru
,
0
,
&
curtime
,
"ddMMMM"
,
buffer
,
COUNTOF
(
buffer
));
if
(
!
ret
)
{
win_skip
(
"LANG_RUSSIAN locale data unavailable
\n
"
);
return
;
}
/* month part should be in genitive form */
strcpy
(
genitive_month
,
buffer
+
2
);
ret
=
GetDateFormat
(
lcid_ru
,
0
,
&
curtime
,
"MMMM"
,
buffer
,
COUNTOF
(
buffer
));
ok
(
ret
,
"Expected ret != 0, got %d, error %d
\n
"
,
ret
,
GetLastError
());
strcpy
(
month
,
buffer
);
ok
(
strcmp
(
genitive_month
,
month
)
!=
0
,
"Expected different month forms
\n
"
);
ret
=
GetDateFormat
(
lcid_ru
,
0
,
&
curtime
,
"ddd"
,
buffer
,
COUNTOF
(
buffer
));
ok
(
ret
,
"Expected ret != 0, got %d, error %d
\n
"
,
ret
,
GetLastError
());
strcpy
(
short_day
,
buffer
);
STRINGSA
(
"dd MMMMddd dd"
,
""
);
sprintf
(
Expected
,
"04 %s%s 04"
,
genitive_month
,
short_day
);
ret
=
GetDateFormat
(
lcid_ru
,
0
,
&
curtime
,
input
,
buffer
,
COUNTOF
(
buffer
));
ok
(
ret
,
"Expected ret != 0, got %d, error %d
\n
"
,
ret
,
GetLastError
());
EXPECT_EQA
;
STRINGSA
(
"MMMMddd dd"
,
""
);
sprintf
(
Expected
,
"%s%s 04"
,
month
,
short_day
);
ret
=
GetDateFormat
(
lcid_ru
,
0
,
&
curtime
,
input
,
buffer
,
COUNTOF
(
buffer
));
ok
(
ret
,
"Expected ret != 0, got %d, error %d
\n
"
,
ret
,
GetLastError
());
EXPECT_EQA
;
STRINGSA
(
"MMMMddd"
,
""
);
sprintf
(
Expected
,
"%s%s"
,
month
,
short_day
);
ret
=
GetDateFormat
(
lcid_ru
,
0
,
&
curtime
,
input
,
buffer
,
COUNTOF
(
buffer
));
ok
(
ret
,
"Expected ret != 0, got %d, error %d
\n
"
,
ret
,
GetLastError
());
EXPECT_EQA
;
STRINGSA
(
"MMMMdd"
,
""
);
sprintf
(
Expected
,
"%s04"
,
genitive_month
);
ret
=
GetDateFormat
(
lcid_ru
,
0
,
&
curtime
,
input
,
buffer
,
COUNTOF
(
buffer
));
ok
(
ret
,
"Expected ret != 0, got %d, error %d
\n
"
,
ret
,
GetLastError
());
EXPECT_EQA
;
STRINGSA
(
"MMMMdd ddd"
,
""
);
sprintf
(
Expected
,
"%s04 %s"
,
genitive_month
,
short_day
);
ret
=
GetDateFormat
(
lcid_ru
,
0
,
&
curtime
,
input
,
buffer
,
COUNTOF
(
buffer
));
ok
(
ret
,
"Expected ret != 0, got %d, error %d
\n
"
,
ret
,
GetLastError
());
EXPECT_EQA
;
STRINGSA
(
"dd dddMMMM"
,
""
);
sprintf
(
Expected
,
"04 %s%s"
,
short_day
,
month
);
ret
=
GetDateFormat
(
lcid_ru
,
0
,
&
curtime
,
input
,
buffer
,
COUNTOF
(
buffer
));
ok
(
ret
,
"Expected ret != 0, got %d, error %d
\n
"
,
ret
,
GetLastError
());
EXPECT_EQA
;
STRINGSA
(
"dd dddMMMM ddd MMMMdd"
,
""
);
sprintf
(
Expected
,
"04 %s%s %s %s04"
,
short_day
,
month
,
short_day
,
genitive_month
);
ret
=
GetDateFormat
(
lcid_ru
,
0
,
&
curtime
,
input
,
buffer
,
COUNTOF
(
buffer
));
ok
(
ret
,
"Expected ret != 0, got %d, error %d
\n
"
,
ret
,
GetLastError
());
EXPECT_EQA
;
/* with literal part */
STRINGSA
(
"ddd',' MMMM dd"
,
""
);
sprintf
(
Expected
,
"%s, %s 04"
,
short_day
,
genitive_month
);
ret
=
GetDateFormat
(
lcid_ru
,
0
,
&
curtime
,
input
,
buffer
,
COUNTOF
(
buffer
));
ok
(
ret
,
"Expected ret != 0, got %d, error %d
\n
"
,
ret
,
GetLastError
());
EXPECT_EQA
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment