Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
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-winehq
Commits
923461f3
Commit
923461f3
authored
Nov 11, 2021
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
wrc: Windows file formats are always little-endian.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
7c5761ed
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
61 additions
and
875 deletions
+61
-875
genres.c
tools/wrc/genres.c
+16
-100
newstruc.c
tools/wrc/newstruc.c
+33
-637
parser.y
tools/wrc/parser.y
+9
-86
wrc.c
tools/wrc/wrc.c
+0
-34
wrc.h
tools/wrc/wrc.h
+1
-1
wrc.man.in
tools/wrc/wrc.man.in
+0
-6
wrctypes.h
tools/wrc/wrctypes.h
+2
-11
No files found.
tools/wrc/genres.c
View file @
923461f3
...
...
@@ -90,24 +90,8 @@ void put_word(res_t *res, unsigned w)
{
if
(
res
->
allocsize
-
res
->
size
<
sizeof
(
WORD
))
grow_res
(
res
,
RES_BLOCKSIZE
);
switch
(
byteorder
)
{
#ifdef WORDS_BIGENDIAN
default:
#endif
case
WRC_BO_BIG
:
res
->
data
[
res
->
size
+
0
]
=
HIBYTE
(
w
);
res
->
data
[
res
->
size
+
1
]
=
LOBYTE
(
w
);
break
;
#ifndef WORDS_BIGENDIAN
default:
#endif
case
WRC_BO_LITTLE
:
res
->
data
[
res
->
size
+
1
]
=
HIBYTE
(
w
);
res
->
data
[
res
->
size
+
0
]
=
LOBYTE
(
w
);
break
;
}
res
->
data
[
res
->
size
+
0
]
=
w
;
res
->
data
[
res
->
size
+
1
]
=
w
>>
8
;
res
->
size
+=
sizeof
(
WORD
);
}
...
...
@@ -115,28 +99,10 @@ void put_dword(res_t *res, unsigned d)
{
if
(
res
->
allocsize
-
res
->
size
<
sizeof
(
DWORD
))
grow_res
(
res
,
RES_BLOCKSIZE
);
switch
(
byteorder
)
{
#ifdef WORDS_BIGENDIAN
default:
#endif
case
WRC_BO_BIG
:
res
->
data
[
res
->
size
+
0
]
=
HIBYTE
(
HIWORD
(
d
));
res
->
data
[
res
->
size
+
1
]
=
LOBYTE
(
HIWORD
(
d
));
res
->
data
[
res
->
size
+
2
]
=
HIBYTE
(
LOWORD
(
d
));
res
->
data
[
res
->
size
+
3
]
=
LOBYTE
(
LOWORD
(
d
));
break
;
#ifndef WORDS_BIGENDIAN
default:
#endif
case
WRC_BO_LITTLE
:
res
->
data
[
res
->
size
+
3
]
=
HIBYTE
(
HIWORD
(
d
));
res
->
data
[
res
->
size
+
2
]
=
LOBYTE
(
HIWORD
(
d
));
res
->
data
[
res
->
size
+
1
]
=
HIBYTE
(
LOWORD
(
d
));
res
->
data
[
res
->
size
+
0
]
=
LOBYTE
(
LOWORD
(
d
));
break
;
}
res
->
data
[
res
->
size
+
0
]
=
d
;
res
->
data
[
res
->
size
+
1
]
=
d
>>
8
;
res
->
data
[
res
->
size
+
2
]
=
d
>>
16
;
res
->
data
[
res
->
size
+
3
]
=
d
>>
24
;
res
->
size
+=
sizeof
(
DWORD
);
}
...
...
@@ -164,50 +130,16 @@ static void put_pad(res_t *res)
*/
static
void
set_word
(
res_t
*
res
,
int
ofs
,
unsigned
w
)
{
switch
(
byteorder
)
{
#ifdef WORDS_BIGENDIAN
default:
#endif
case
WRC_BO_BIG
:
res
->
data
[
ofs
+
0
]
=
HIBYTE
(
w
);
res
->
data
[
ofs
+
1
]
=
LOBYTE
(
w
);
break
;
#ifndef WORDS_BIGENDIAN
default:
#endif
case
WRC_BO_LITTLE
:
res
->
data
[
ofs
+
1
]
=
HIBYTE
(
w
);
res
->
data
[
ofs
+
0
]
=
LOBYTE
(
w
);
break
;
}
res
->
data
[
ofs
+
0
]
=
w
;
res
->
data
[
ofs
+
1
]
=
w
>>
8
;
}
static
void
set_dword
(
res_t
*
res
,
int
ofs
,
unsigned
d
)
{
switch
(
byteorder
)
{
#ifdef WORDS_BIGENDIAN
default:
#endif
case
WRC_BO_BIG
:
res
->
data
[
ofs
+
0
]
=
HIBYTE
(
HIWORD
(
d
));
res
->
data
[
ofs
+
1
]
=
LOBYTE
(
HIWORD
(
d
));
res
->
data
[
ofs
+
2
]
=
HIBYTE
(
LOWORD
(
d
));
res
->
data
[
ofs
+
3
]
=
LOBYTE
(
LOWORD
(
d
));
break
;
#ifndef WORDS_BIGENDIAN
default:
#endif
case
WRC_BO_LITTLE
:
res
->
data
[
ofs
+
3
]
=
HIBYTE
(
HIWORD
(
d
));
res
->
data
[
ofs
+
2
]
=
LOBYTE
(
HIWORD
(
d
));
res
->
data
[
ofs
+
1
]
=
HIBYTE
(
LOWORD
(
d
));
res
->
data
[
ofs
+
0
]
=
LOBYTE
(
LOWORD
(
d
));
break
;
}
res
->
data
[
ofs
+
0
]
=
d
;
res
->
data
[
ofs
+
1
]
=
d
>>
8
;
res
->
data
[
ofs
+
2
]
=
d
>>
16
;
res
->
data
[
ofs
+
3
]
=
d
>>
24
;
}
/*
...
...
@@ -224,26 +156,10 @@ static void set_dword(res_t *res, int ofs, unsigned d)
*/
static
DWORD
get_dword
(
res_t
*
res
,
int
ofs
)
{
switch
(
byteorder
)
{
#ifdef WORDS_BIGENDIAN
default:
#endif
case
WRC_BO_BIG
:
return
(
res
->
data
[
ofs
+
0
]
<<
24
)
|
(
res
->
data
[
ofs
+
1
]
<<
16
)
|
(
res
->
data
[
ofs
+
2
]
<<
8
)
|
res
->
data
[
ofs
+
3
];
#ifndef WORDS_BIGENDIAN
default:
#endif
case
WRC_BO_LITTLE
:
return
(
res
->
data
[
ofs
+
3
]
<<
24
)
|
(
res
->
data
[
ofs
+
2
]
<<
16
)
|
(
res
->
data
[
ofs
+
1
]
<<
8
)
|
res
->
data
[
ofs
+
0
];
}
return
(
res
->
data
[
ofs
+
3
]
<<
24
)
|
(
res
->
data
[
ofs
+
2
]
<<
16
)
|
(
res
->
data
[
ofs
+
1
]
<<
8
)
|
res
->
data
[
ofs
+
0
];
}
static
res_t
*
end_res
(
res_t
*
res
,
int
ofs
)
...
...
tools/wrc/newstruc.c
View file @
923461f3
...
...
@@ -35,8 +35,6 @@
#include "wingdi.h"
/* for BITMAPINFOHEADER */
#define ICO_PNG_MAGIC 0x474e5089
#include <pshpack2.h>
typedef
struct
{
...
...
@@ -320,160 +318,15 @@ fontdir_t *new_fontdir(raw_data_t *rd, int *memopt)
}
/*
* Convert bitmaps to proper endian
*/
static
void
convert_bitmap_swap
(
BITMAPV5HEADER
*
bh
,
DWORD
size
)
{
bh
->
bV5Size
=
BYTESWAP_DWORD
(
bh
->
bV5Size
);
bh
->
bV5Width
=
BYTESWAP_DWORD
(
bh
->
bV5Width
);
bh
->
bV5Height
=
BYTESWAP_DWORD
(
bh
->
bV5Height
);
bh
->
bV5Planes
=
BYTESWAP_WORD
(
bh
->
bV5Planes
);
bh
->
bV5BitCount
=
BYTESWAP_WORD
(
bh
->
bV5BitCount
);
bh
->
bV5Compression
=
BYTESWAP_DWORD
(
bh
->
bV5Compression
);
bh
->
bV5SizeImage
=
BYTESWAP_DWORD
(
bh
->
bV5SizeImage
);
bh
->
bV5XPelsPerMeter
=
BYTESWAP_DWORD
(
bh
->
bV5XPelsPerMeter
);
bh
->
bV5YPelsPerMeter
=
BYTESWAP_DWORD
(
bh
->
bV5YPelsPerMeter
);
bh
->
bV5ClrUsed
=
BYTESWAP_DWORD
(
bh
->
bV5ClrUsed
);
bh
->
bV5ClrImportant
=
BYTESWAP_DWORD
(
bh
->
bV5ClrImportant
);
if
(
size
==
sizeof
(
BITMAPINFOHEADER
))
return
;
bh
->
bV5RedMask
=
BYTESWAP_DWORD
(
bh
->
bV5RedMask
);
bh
->
bV5GreenMask
=
BYTESWAP_DWORD
(
bh
->
bV5GreenMask
);
bh
->
bV5BlueMask
=
BYTESWAP_DWORD
(
bh
->
bV5BlueMask
);
bh
->
bV5AlphaMask
=
BYTESWAP_DWORD
(
bh
->
bV5AlphaMask
);
bh
->
bV5CSType
=
BYTESWAP_DWORD
(
bh
->
bV5CSType
);
bh
->
bV5Endpoints
.
ciexyzRed
.
ciexyzX
=
BYTESWAP_DWORD
(
bh
->
bV5Endpoints
.
ciexyzRed
.
ciexyzX
);
bh
->
bV5Endpoints
.
ciexyzRed
.
ciexyzY
=
BYTESWAP_DWORD
(
bh
->
bV5Endpoints
.
ciexyzRed
.
ciexyzY
);
bh
->
bV5Endpoints
.
ciexyzRed
.
ciexyzZ
=
BYTESWAP_DWORD
(
bh
->
bV5Endpoints
.
ciexyzRed
.
ciexyzZ
);
bh
->
bV5Endpoints
.
ciexyzGreen
.
ciexyzX
=
BYTESWAP_DWORD
(
bh
->
bV5Endpoints
.
ciexyzGreen
.
ciexyzX
);
bh
->
bV5Endpoints
.
ciexyzGreen
.
ciexyzY
=
BYTESWAP_DWORD
(
bh
->
bV5Endpoints
.
ciexyzGreen
.
ciexyzY
);
bh
->
bV5Endpoints
.
ciexyzGreen
.
ciexyzZ
=
BYTESWAP_DWORD
(
bh
->
bV5Endpoints
.
ciexyzGreen
.
ciexyzZ
);
bh
->
bV5Endpoints
.
ciexyzBlue
.
ciexyzX
=
BYTESWAP_DWORD
(
bh
->
bV5Endpoints
.
ciexyzBlue
.
ciexyzX
);
bh
->
bV5Endpoints
.
ciexyzBlue
.
ciexyzY
=
BYTESWAP_DWORD
(
bh
->
bV5Endpoints
.
ciexyzBlue
.
ciexyzY
);
bh
->
bV5Endpoints
.
ciexyzBlue
.
ciexyzZ
=
BYTESWAP_DWORD
(
bh
->
bV5Endpoints
.
ciexyzBlue
.
ciexyzZ
);
bh
->
bV5GammaRed
=
BYTESWAP_DWORD
(
bh
->
bV5GammaRed
);
bh
->
bV5GammaGreen
=
BYTESWAP_DWORD
(
bh
->
bV5GammaGreen
);
bh
->
bV5GammaBlue
=
BYTESWAP_DWORD
(
bh
->
bV5GammaBlue
);
if
(
size
==
sizeof
(
BITMAPV4HEADER
))
return
;
bh
->
bV5Intent
=
BYTESWAP_DWORD
(
bh
->
bV5Intent
);
bh
->
bV5ProfileData
=
BYTESWAP_DWORD
(
bh
->
bV5ProfileData
);
bh
->
bV5ProfileSize
=
BYTESWAP_DWORD
(
bh
->
bV5ProfileSize
);
bh
->
bV5Reserved
=
BYTESWAP_DWORD
(
bh
->
bV5Reserved
);
}
static
void
convert_bitmap_swap_os2
(
BITMAPOS2HEADER
*
boh
)
{
boh
->
biSize
=
BYTESWAP_DWORD
(
boh
->
biSize
);
boh
->
biWidth
=
BYTESWAP_WORD
(
boh
->
biWidth
);
boh
->
biHeight
=
BYTESWAP_WORD
(
boh
->
biHeight
);
boh
->
biPlanes
=
BYTESWAP_WORD
(
boh
->
biPlanes
);
boh
->
biBitCount
=
BYTESWAP_WORD
(
boh
->
biBitCount
);
}
#define FL_SIGBE 0x01
#define FL_SIZEBE 0x02
static
int
convert_bitmap
(
char
*
data
,
int
size
)
{
BITMAPV5HEADER
*
bih
=
(
BITMAPV5HEADER
*
)
data
;
BITMAPOS2HEADER
*
boh
=
(
BITMAPOS2HEADER
*
)
data
;
DWORD
bmsize
;
int
type
=
0
;
int
returnSize
=
0
;
/* size to be returned */
/*
* Originally the bih and b4h pointers were simply incremented here,
* and memmoved at the end of the function. This causes alignment
* issues on solaris, so we do the memmove here rather than at the end.
*/
if
(
data
[
0
]
==
'B'
&&
data
[
1
]
==
'M'
)
{
/* Little endian signature */
memmove
(
data
,
data
+
sizeof
(
BITMAPFILEHEADER
),
size
-
sizeof
(
BITMAPFILEHEADER
));
returnSize
=
sizeof
(
BITMAPFILEHEADER
);
}
else
if
(
data
[
0
]
==
'M'
&&
data
[
1
]
==
'B'
)
{
type
|=
FL_SIGBE
;
/* Big endian signature */
if
(
size
>
sizeof
(
BITMAPFILEHEADER
)
&&
data
[
0
]
==
'B'
&&
data
[
1
]
==
'M'
)
{
memmove
(
data
,
data
+
sizeof
(
BITMAPFILEHEADER
),
size
-
sizeof
(
BITMAPFILEHEADER
));
returnSize
=
sizeof
(
BITMAPFILEHEADER
);
}
bmsize
=
bih
->
bV5Size
;
switch
(
bmsize
)
{
case
sizeof
(
BITMAPOS2HEADER
):
case
sizeof
(
BITMAPINFOHEADER
):
case
sizeof
(
BITMAPV4HEADER
):
case
sizeof
(
BITMAPV5HEADER
):
#ifdef WORDS_BIGENDIAN
type
|=
FL_SIZEBE
;
#endif
break
;
case
BYTESWAP_DWORD
(
sizeof
(
BITMAPOS2HEADER
)
):
case
BYTESWAP_DWORD
(
sizeof
(
BITMAPINFOHEADER
)
):
case
BYTESWAP_DWORD
(
sizeof
(
BITMAPV4HEADER
)
):
case
BYTESWAP_DWORD
(
sizeof
(
BITMAPV5HEADER
)
):
#ifndef WORDS_BIGENDIAN
type
|=
FL_SIZEBE
;
#endif
bmsize
=
BYTESWAP_DWORD
(
bmsize
);
break
;
case
ICO_PNG_MAGIC
:
case
BYTESWAP_DWORD
(
ICO_PNG_MAGIC
):
return
0
;
/* nothing to convert */
default:
parser_error
(
"Invalid bitmap format, bih->biSize = %d"
,
bih
->
bV5Size
);
}
switch
(
type
)
{
case
FL_SIZEBE
:
parser_warning
(
"Bitmap signature little-endian, but size big-endian
\n
"
);
break
;
case
FL_SIGBE
:
parser_warning
(
"Bitmap signature big-endian, but size little-endian
\n
"
);
break
;
}
switch
(
byteorder
)
{
#ifdef WORDS_BIGENDIAN
default:
#endif
case
WRC_BO_BIG
:
if
(
!
(
type
&
FL_SIZEBE
))
{
if
(
bmsize
==
sizeof
(
BITMAPOS2HEADER
))
convert_bitmap_swap_os2
(
boh
);
else
convert_bitmap_swap
(
bih
,
bmsize
);
}
break
;
#ifndef WORDS_BIGENDIAN
default:
#endif
case
WRC_BO_LITTLE
:
if
(
type
&
FL_SIZEBE
)
{
if
(
bmsize
==
sizeof
(
BITMAPOS2HEADER
))
convert_bitmap_swap_os2
(
boh
);
else
convert_bitmap_swap
(
bih
,
bmsize
);
}
break
;
}
if
(
size
&&
(
void
*
)
data
!=
(
void
*
)
bih
)
{
/* We have the fileheader still attached, remove it */
memmove
(
data
,
data
+
sizeof
(
BITMAPFILEHEADER
),
size
-
sizeof
(
BITMAPFILEHEADER
));
return
sizeof
(
BITMAPFILEHEADER
);
}
return
returnSize
;
return
sizeof
(
BITMAPFILEHEADER
);
}
return
0
;
}
#undef FL_SIGBE
#undef FL_SIZEBE
/*
* Cursor and icon splitter functions used when allocating
...
...
@@ -536,19 +389,15 @@ static void split_icons(raw_data_t *rd, icon_group_t *icog, int *nico)
icon_t
*
ico
;
icon_t
*
list
=
NULL
;
icon_header_t
*
ih
=
(
icon_header_t
*
)
rd
->
data
;
int
swap
=
0
;
if
(
ih
->
type
==
1
)
swap
=
0
;
else
if
(
BYTESWAP_WORD
(
ih
->
type
)
==
1
)
swap
=
1
;
else
if
(
GET_WORD
(
&
ih
->
type
)
!=
1
)
parser_error
(
"Icon resource data has invalid type id %d"
,
ih
->
type
);
cnt
=
swap
?
BYTESWAP_WORD
(
ih
->
count
)
:
ih
->
count
;
cnt
=
GET_WORD
(
&
ih
->
count
)
;
for
(
i
=
0
;
i
<
cnt
;
i
++
)
{
icon_dir_entry_t
ide
;
int
offset
,
size
;
BITMAPINFOHEADER
info
;
memcpy
(
&
ide
,
rd
->
data
+
sizeof
(
icon_header_t
)
+
i
*
sizeof
(
icon_dir_entry_t
),
sizeof
(
ide
));
...
...
@@ -556,59 +405,22 @@ static void split_icons(raw_data_t *rd, icon_group_t *icog, int *nico)
ico
=
new_icon
();
ico
->
id
=
alloc_icon_id
(
icog
->
lvc
.
language
);
ico
->
lvc
=
icog
->
lvc
;
if
(
swap
)
{
ide
.
offset
=
BYTESWAP_DWORD
(
ide
.
offset
);
ide
.
ressize
=
BYTESWAP_DWORD
(
ide
.
ressize
);
}
if
(
ide
.
offset
>
rd
->
size
||
ide
.
offset
+
ide
.
ressize
>
rd
->
size
)
offset
=
GET_DWORD
(
&
ide
.
offset
);
size
=
GET_DWORD
(
&
ide
.
ressize
);
if
(
offset
>
rd
->
size
||
offset
+
size
>
rd
->
size
)
parser_error
(
"Icon resource data corrupt"
);
ico
->
width
=
ide
.
width
;
ico
->
height
=
ide
.
height
;
ico
->
nclr
=
ide
.
nclr
;
ico
->
planes
=
swap
?
BYTESWAP_WORD
(
ide
.
planes
)
:
ide
.
planes
;
ico
->
bits
=
swap
?
BYTESWAP_WORD
(
ide
.
bits
)
:
ide
.
bits
;
memcpy
(
&
info
,
rd
->
data
+
ide
.
offset
,
sizeof
(
info
));
convert_bitmap
((
char
*
)
&
info
,
0
);
memcpy
(
rd
->
data
+
ide
.
offset
,
&
info
,
sizeof
(
info
));
if
(
!
ico
->
planes
)
{
/* Argh! They did not fill out the resdir structure */
/* The bitmap is in destination byteorder. We want native for our structures */
switch
(
byteorder
)
{
#ifdef WORDS_BIGENDIAN
case
WRC_BO_LITTLE
:
#else
case
WRC_BO_BIG
:
#endif
ico
->
planes
=
BYTESWAP_WORD
(
info
.
biPlanes
);
break
;
default:
ico
->
planes
=
info
.
biPlanes
;
}
}
if
(
!
ico
->
bits
)
{
/* Argh! They did not fill out the resdir structure */
/* The bitmap is in destination byteorder. We want native for our structures */
switch
(
byteorder
)
{
#ifdef WORDS_BIGENDIAN
case
WRC_BO_LITTLE
:
#else
case
WRC_BO_BIG
:
#endif
ico
->
bits
=
BYTESWAP_WORD
(
info
.
biBitCount
);
break
;
default:
ico
->
bits
=
info
.
biBitCount
;
}
}
ico
->
planes
=
GET_WORD
(
&
ide
.
planes
);
ico
->
bits
=
GET_WORD
(
&
ide
.
bits
);
memcpy
(
&
info
,
rd
->
data
+
offset
,
sizeof
(
info
));
convert_bitmap
((
char
*
)
&
info
,
0
);
memcpy
(
rd
->
data
+
offset
,
&
info
,
sizeof
(
info
));
if
(
!
ico
->
planes
)
ico
->
planes
=
GET_WORD
(
&
info
.
biPlanes
);
if
(
!
ico
->
bits
)
ico
->
bits
=
GET_WORD
(
&
info
.
biBitCount
);
ico
->
data
=
new_raw_data
();
copy_raw_data
(
ico
->
data
,
rd
,
ide
.
offset
,
ide
.
res
size
);
copy_raw_data
(
ico
->
data
,
rd
,
offset
,
size
);
if
(
!
list
)
{
list
=
ico
;
...
...
@@ -631,18 +443,13 @@ static void split_cursors(raw_data_t *rd, cursor_group_t *curg, int *ncur)
cursor_t
*
cur
;
cursor_t
*
list
=
NULL
;
cursor_header_t
*
ch
=
(
cursor_header_t
*
)
rd
->
data
;
int
swap
=
0
;
if
(
ch
->
type
==
2
)
swap
=
0
;
else
if
(
BYTESWAP_WORD
(
ch
->
type
)
==
2
)
swap
=
1
;
else
parser_error
(
"Cursor resource data has invalid type id %d"
,
ch
->
type
);
cnt
=
swap
?
BYTESWAP_WORD
(
ch
->
count
)
:
ch
->
count
;
if
(
GET_WORD
(
&
ch
->
type
)
!=
2
)
parser_error
(
"Cursor resource data has invalid type id %d"
,
ch
->
type
);
cnt
=
GET_WORD
(
&
ch
->
count
);
for
(
i
=
0
;
i
<
cnt
;
i
++
)
{
cursor_dir_entry_t
cde
;
int
offset
,
size
;
BITMAPINFOHEADER
info
;
memcpy
(
&
cde
,
rd
->
data
+
sizeof
(
cursor_header_t
)
+
i
*
sizeof
(
cursor_dir_entry_t
),
sizeof
(
cde
));
...
...
@@ -650,41 +457,24 @@ static void split_cursors(raw_data_t *rd, cursor_group_t *curg, int *ncur)
cur
=
new_cursor
();
cur
->
id
=
alloc_cursor_id
(
curg
->
lvc
.
language
);
cur
->
lvc
=
curg
->
lvc
;
if
(
swap
)
{
cde
.
offset
=
BYTESWAP_DWORD
(
cde
.
offset
);
cde
.
ressize
=
BYTESWAP_DWORD
(
cde
.
ressize
);
}
if
(
cde
.
offset
>
rd
->
size
||
cde
.
offset
+
cde
.
ressize
>
rd
->
size
)
offset
=
GET_DWORD
(
&
cde
.
offset
);
size
=
GET_DWORD
(
&
cde
.
ressize
);
if
(
offset
>
rd
->
size
||
offset
+
size
>
rd
->
size
)
parser_error
(
"Cursor resource data corrupt"
);
cur
->
width
=
cde
.
width
;
cur
->
height
=
cde
.
height
;
cur
->
nclr
=
cde
.
nclr
;
memcpy
(
&
info
,
rd
->
data
+
cde
.
offset
,
sizeof
(
info
));
convert_bitmap
((
char
*
)
&
info
,
0
);
memcpy
(
rd
->
data
+
cde
.
offset
,
&
info
,
sizeof
(
info
));
/* The bitmap is in destination byteorder. We want native for our structures */
switch
(
byteorder
)
{
#ifdef WORDS_BIGENDIAN
case
WRC_BO_LITTLE
:
#else
case
WRC_BO_BIG
:
#endif
cur
->
planes
=
BYTESWAP_WORD
(
info
.
biPlanes
);
cur
->
bits
=
BYTESWAP_WORD
(
info
.
biBitCount
);
break
;
default:
cur
->
planes
=
info
.
biPlanes
;
cur
->
bits
=
info
.
biBitCount
;
}
memcpy
(
&
info
,
rd
->
data
+
offset
,
sizeof
(
info
));
convert_bitmap
((
char
*
)
&
info
,
0
);
memcpy
(
rd
->
data
+
offset
,
&
info
,
sizeof
(
info
));
cur
->
planes
=
GET_WORD
(
&
info
.
biPlanes
);
cur
->
bits
=
GET_WORD
(
&
info
.
biBitCount
);
if
(
!
win32
&&
(
cur
->
planes
!=
1
||
cur
->
bits
!=
1
))
parser_warning
(
"Win16 cursor contains colors
\n
"
);
cur
->
xhot
=
swap
?
BYTESWAP_WORD
(
cde
.
xhot
)
:
cde
.
xhot
;
cur
->
yhot
=
swap
?
BYTESWAP_WORD
(
cde
.
yhot
)
:
cde
.
yhot
;
cur
->
xhot
=
GET_WORD
(
&
cde
.
xhot
)
;
cur
->
yhot
=
GET_WORD
(
&
cde
.
yhot
)
;
cur
->
data
=
new_raw_data
();
copy_raw_data
(
cur
->
data
,
rd
,
cde
.
offset
,
cde
.
res
size
);
copy_raw_data
(
cur
->
data
,
rd
,
offset
,
size
);
if
(
!
list
)
{
list
=
cur
;
...
...
@@ -735,289 +525,12 @@ cursor_group_t *new_cursor_group(raw_data_t *rd, int *memopt)
return
curg
;
}
/*
* Animated cursors and icons
*
* The format of animated cursors and icons is yet another example
* of bad design by "The Company". The entire RIFF structure is
* flawed by design because it is inconsistent and single minded:
* - some tags have lengths attached, others don't. The use of these
* non-length tags is absolutely unclear;
* - the content of "icon" tags can be both icons and cursors;
* - tags lack proper alignment constraints. It seems that everything
* is 16bit aligned, but I could not find that in any docu. Just be
* prepared to eat anything;
* - there are no strict constraints on tag-nesting and the organization
* is highly illogical;
*
* Anyhow, here is the basic structure:
* "RIFF" { dword taglength }
* "ACON" // What does it do?
* "LIST" { dword taglength }
* "INFO" // And what does this do?
* "INAM" { dword taglength } // Icon/cursor name
* {inam data}
* "IART" { dword taglength } // The artist
* {iart data}
* "fram" // Is followed by "icon"s
* "icon" { dword taglength } // First frame
* { icon/cursor data }
* "icon" { dword taglength } // Second frame
* { icon/cursor data }
* ... // ...
* "anih" { dword taglength } // Header structure
* { aniheader_t structure }
* "rate" { dword taglength } // The rate for each frame
* { `steps' dwords }
* "seq " { dword taglength } // The frame blit-order
* { `steps' dwords }
*
* Tag length are bytelength without the header and length field (i.e. -8).
* The "LIST" tag may occur several times and may encapsulate different
* tags. The `steps' is the number of "icon" tags found (actually the
* number of steps specified in the aniheader_t structure). The "seq "uence
* tag can be omitted, in which case the sequence is equal to the sequence
* of "icon"s found in the file. Also "rate" may be omitted, in which case
* the default from the aniheader_t structure is used.
*
* An animated cursor puts `.cur' formatted files into each "icon" tag,
* whereas animated icons contain `.ico' formatted files.
*
* Note about the code: Yes, it can be shorter/compressed. Some tags can be
* dealt with in the same code. However, this version shows what is going on
* and is better debug-able.
*/
static
const
char
riff
[
4
]
=
"RIFF"
;
static
const
char
acon
[
4
]
=
"ACON"
;
static
const
char
list
[
4
]
=
"LIST"
;
static
const
char
info
[
4
]
=
"INFO"
;
static
const
char
inam
[
4
]
=
"INAM"
;
static
const
char
iart
[
4
]
=
"IART"
;
static
const
char
fram
[
4
]
=
"fram"
;
static
const
char
icon
[
4
]
=
"icon"
;
static
const
char
anih
[
4
]
=
"anih"
;
static
const
char
rate
[
4
]
=
"rate"
;
static
const
char
seq
[
4
]
=
"seq "
;
#define SKIP_TAG(p,size) ((riff_tag_t *)(((char *)p) + (size)))
#define NEXT_TAG(p) SKIP_TAG(p,(isswapped ? BYTESWAP_DWORD(p->size) : p->size) + sizeof(*p))
static
void
handle_ani_icon
(
riff_tag_t
*
rtp
,
enum
res_e
type
,
int
isswapped
)
{
cursor_dir_entry_t
*
cdp
;
cursor_header_t
*
chp
;
int
count
;
int
ctype
;
int
i
;
static
int
once
=
0
;
/* This will trigger only once per file! */
const
char
*
anistr
=
type
==
res_aniico
?
"icon"
:
"cursor"
;
/* Notes:
* Both cursor and icon directories are similar
* Both cursor and icon headers are similar
*/
chp
=
(
cursor_header_t
*
)(
rtp
+
1
);
cdp
=
(
cursor_dir_entry_t
*
)(
chp
+
1
);
count
=
isswapped
?
BYTESWAP_WORD
(
chp
->
count
)
:
chp
->
count
;
ctype
=
isswapped
?
BYTESWAP_WORD
(
chp
->
type
)
:
chp
->
type
;
chp
->
reserved
=
BYTESWAP_WORD
(
chp
->
reserved
);
chp
->
type
=
BYTESWAP_WORD
(
chp
->
type
);
chp
->
count
=
BYTESWAP_WORD
(
chp
->
count
);
if
(
type
==
res_anicur
&&
ctype
!=
2
&&
!
once
)
{
parser_warning
(
"Animated cursor contains invalid
\"
icon
\"
tag cursor-file (%d->%s)
\n
"
,
ctype
,
ctype
==
1
?
"icontype"
:
"?"
);
once
++
;
}
else
if
(
type
==
res_aniico
&&
ctype
!=
1
&&
!
once
)
{
parser_warning
(
"Animated icon contains invalid
\"
icon
\"
tag icon-file (%d->%s)
\n
"
,
ctype
,
ctype
==
2
?
"cursortype"
:
"?"
);
once
++
;
}
else
if
(
ctype
!=
1
&&
ctype
!=
2
&&
!
once
)
{
parser_warning
(
"Animated %s contains invalid
\"
icon
\"
tag file-type (%d; neither icon nor cursor)
\n
"
,
anistr
,
ctype
);
once
++
;
}
for
(
i
=
0
;
i
<
count
;
i
++
)
{
DWORD
ofs
=
isswapped
?
BYTESWAP_DWORD
(
cdp
[
i
].
offset
)
:
cdp
[
i
].
offset
;
DWORD
sze
=
isswapped
?
BYTESWAP_DWORD
(
cdp
[
i
].
ressize
)
:
cdp
[
i
].
ressize
;
if
(
ofs
>
rtp
->
size
||
ofs
+
sze
>
rtp
->
size
)
parser_error
(
"Animated %s's data corrupt"
,
anistr
);
convert_bitmap
((
char
*
)
chp
+
ofs
,
0
);
cdp
[
i
].
xhot
=
BYTESWAP_WORD
(
cdp
->
xhot
);
cdp
[
i
].
yhot
=
BYTESWAP_WORD
(
cdp
->
yhot
);
cdp
[
i
].
ressize
=
BYTESWAP_DWORD
(
cdp
->
ressize
);
cdp
[
i
].
offset
=
BYTESWAP_DWORD
(
cdp
->
offset
);
}
}
static
void
handle_ani_list
(
riff_tag_t
*
lst
,
enum
res_e
type
,
int
isswapped
)
{
riff_tag_t
*
rtp
=
lst
+
1
;
/* Skip the "LIST" tag */
while
((
char
*
)
rtp
<
(
char
*
)
lst
+
lst
->
size
+
sizeof
(
*
lst
))
{
if
(
!
memcmp
(
rtp
->
tag
,
info
,
sizeof
(
info
)))
{
rtp
=
SKIP_TAG
(
rtp
,
4
);
}
else
if
(
!
memcmp
(
rtp
->
tag
,
inam
,
sizeof
(
inam
)))
{
/* Ignore the icon/cursor name; it's a string */
rtp
=
NEXT_TAG
(
rtp
);
}
else
if
(
!
memcmp
(
rtp
->
tag
,
iart
,
sizeof
(
iart
)))
{
/* Ignore the author's name; it's a string */
rtp
=
NEXT_TAG
(
rtp
);
}
else
if
(
!
memcmp
(
rtp
->
tag
,
fram
,
sizeof
(
fram
)))
{
/* This should be followed by "icon"s, but we
* simply ignore this because it is pure
* non-information.
*/
rtp
=
SKIP_TAG
(
rtp
,
4
);
}
else
if
(
!
memcmp
(
rtp
->
tag
,
icon
,
sizeof
(
icon
)))
{
handle_ani_icon
(
rtp
,
type
,
isswapped
);
rtp
=
NEXT_TAG
(
rtp
);
}
else
error
(
"Unknown tag
\"
%c%c%c%c
\"
in RIFF file
\n
"
,
isprint
(
rtp
->
tag
[
0
])
?
rtp
->
tag
[
0
]
:
'.'
,
isprint
(
rtp
->
tag
[
1
])
?
rtp
->
tag
[
1
]
:
'.'
,
isprint
(
rtp
->
tag
[
2
])
?
rtp
->
tag
[
2
]
:
'.'
,
isprint
(
rtp
->
tag
[
3
])
?
rtp
->
tag
[
3
]
:
'.'
);
if
((
UINT_PTR
)
rtp
&
1
)
rtp
=
SKIP_TAG
(
rtp
,
1
);
}
}
ani_curico_t
*
new_ani_curico
(
enum
res_e
type
,
raw_data_t
*
rd
,
int
*
memopt
)
{
ani_curico_t
*
ani
=
xmalloc
(
sizeof
(
ani_curico_t
));
riff_tag_t
*
rtp
;
int
isswapped
=
0
;
int
doswap
;
const
char
*
anistr
=
type
==
res_aniico
?
"icon"
:
"cursor"
;
assert
(
!
memcmp
(
rd
->
data
,
riff
,
sizeof
(
riff
)));
assert
(
type
==
res_anicur
||
type
==
res_aniico
);
rtp
=
(
riff_tag_t
*
)
rd
->
data
;
if
(
BYTESWAP_DWORD
(
rtp
->
size
)
+
2
*
sizeof
(
DWORD
)
==
rd
->
size
)
isswapped
=
1
;
else
if
(
rtp
->
size
+
2
*
sizeof
(
DWORD
)
==
rd
->
size
)
isswapped
=
0
;
else
parser_error
(
"Animated %s has an invalid RIFF length"
,
anistr
);
switch
(
byteorder
)
{
#ifdef WORDS_BIGENDIAN
case
WRC_BO_LITTLE
:
#else
case
WRC_BO_BIG
:
#endif
doswap
=
!
isswapped
;
break
;
default:
doswap
=
isswapped
;
}
/*
* When to swap what:
* isswapped | doswap |
* ----------+--------+---------------------------------
* 0 | 0 | read native; don't convert
* 1 | 0 | read swapped size; don't convert
* 0 | 1 | read native; convert
* 1 | 1 | read swapped size; convert
* Reading swapped size if necessary to calculate in native
* format. E.g. a little-endian source on a big-endian
* processor.
*/
if
(
doswap
)
{
/* We only go through the RIFF file if we need to swap
* bytes in words/dwords. Else we couldn't care less
* what the file contains. This is consistent with
* MS' rc.exe, which doesn't complain at all, even though
* the file format might not be entirely correct.
*/
rtp
++
;
/* Skip the "RIFF" tag */
while
((
char
*
)
rtp
<
(
char
*
)
rd
->
data
+
rd
->
size
)
{
if
(
!
memcmp
(
rtp
->
tag
,
acon
,
sizeof
(
acon
)))
{
rtp
=
SKIP_TAG
(
rtp
,
4
);
}
else
if
(
!
memcmp
(
rtp
->
tag
,
list
,
sizeof
(
list
)))
{
handle_ani_list
(
rtp
,
type
,
isswapped
);
rtp
=
NEXT_TAG
(
rtp
);
}
else
if
(
!
memcmp
(
rtp
->
tag
,
anih
,
sizeof
(
anih
)))
{
aniheader_t
*
ahp
=
(
aniheader_t
*
)((
char
*
)(
rtp
+
1
));
ahp
->
structsize
=
BYTESWAP_DWORD
(
ahp
->
structsize
);
ahp
->
frames
=
BYTESWAP_DWORD
(
ahp
->
frames
);
ahp
->
steps
=
BYTESWAP_DWORD
(
ahp
->
steps
);
ahp
->
cx
=
BYTESWAP_DWORD
(
ahp
->
cx
);
ahp
->
cy
=
BYTESWAP_DWORD
(
ahp
->
cy
);
ahp
->
bitcount
=
BYTESWAP_DWORD
(
ahp
->
bitcount
);
ahp
->
planes
=
BYTESWAP_DWORD
(
ahp
->
planes
);
ahp
->
rate
=
BYTESWAP_DWORD
(
ahp
->
rate
);
ahp
->
flags
=
BYTESWAP_DWORD
(
ahp
->
flags
);
rtp
=
NEXT_TAG
(
rtp
);
}
else
if
(
!
memcmp
(
rtp
->
tag
,
rate
,
sizeof
(
rate
)))
{
int
cnt
=
rtp
->
size
/
sizeof
(
DWORD
);
DWORD
*
dwp
=
(
DWORD
*
)(
rtp
+
1
);
int
i
;
for
(
i
=
0
;
i
<
cnt
;
i
++
)
dwp
[
i
]
=
BYTESWAP_DWORD
(
dwp
[
i
]);
rtp
=
NEXT_TAG
(
rtp
);
}
else
if
(
!
memcmp
(
rtp
->
tag
,
seq
,
sizeof
(
seq
)))
{
int
cnt
=
rtp
->
size
/
sizeof
(
DWORD
);
DWORD
*
dwp
=
(
DWORD
*
)(
rtp
+
1
);
int
i
;
for
(
i
=
0
;
i
<
cnt
;
i
++
)
dwp
[
i
]
=
BYTESWAP_DWORD
(
dwp
[
i
]);
rtp
=
NEXT_TAG
(
rtp
);
}
else
error
(
"Unknown tag
\"
%c%c%c%c
\"
in RIFF file
\n
"
,
isprint
(
rtp
->
tag
[
0
])
?
rtp
->
tag
[
0
]
:
'.'
,
isprint
(
rtp
->
tag
[
1
])
?
rtp
->
tag
[
1
]
:
'.'
,
isprint
(
rtp
->
tag
[
2
])
?
rtp
->
tag
[
2
]
:
'.'
,
isprint
(
rtp
->
tag
[
3
])
?
rtp
->
tag
[
3
]
:
'.'
);
if
((
UINT_PTR
)
rtp
&
1
)
rtp
=
SKIP_TAG
(
rtp
,
1
);
}
/* We must end correctly here */
if
((
char
*
)
rtp
!=
(
char
*
)
rd
->
data
+
rd
->
size
)
parser_error
(
"Animated %s contains invalid field size(s)"
,
anistr
);
}
ani
->
data
=
rd
;
if
(
memopt
)
{
...
...
@@ -1028,7 +541,6 @@ ani_curico_t *new_ani_curico(enum res_e type, raw_data_t *rd, int *memopt)
ani
->
memopt
=
WRC_MO_MOVEABLE
|
WRC_MO_DISCARDABLE
;
return
ani
;
}
#undef NEXT_TAG
/* Bitmaps */
bitmap_t
*
new_bitmap
(
raw_data_t
*
rd
,
int
*
memopt
)
...
...
@@ -1068,11 +580,6 @@ ver_words_t *add_ver_words(ver_words_t *w, int i)
messagetable_t
*
new_messagetable
(
raw_data_t
*
rd
,
int
*
memopt
)
{
messagetable_t
*
msg
=
xmalloc
(
sizeof
(
messagetable_t
));
msgtab_block_t
*
mbp
;
DWORD
nblk
;
DWORD
i
;
WORD
lo
;
WORD
hi
;
msg
->
data
=
rd
;
if
(
memopt
)
...
...
@@ -1086,117 +593,6 @@ messagetable_t *new_messagetable(raw_data_t *rd, int *memopt)
if
(
rd
->
size
<
sizeof
(
DWORD
))
parser_error
(
"Invalid messagetable, size too small"
);
nblk
=
*
(
DWORD
*
)
rd
->
data
;
lo
=
WRC_LOWORD
(
nblk
);
hi
=
WRC_HIWORD
(
nblk
);
/* FIXME:
* This test will fail for all n*2^16 blocks in the messagetable.
* However, no sane person would want to have so many blocks
* and have a table of megabytes attached.
* So, I will assume that we have less than 2^16 blocks in the table
* and all will just work out fine. Otherwise, we would need to test
* the ID, offset and length (and flag) fields to be very sure.
*/
if
(
hi
&&
lo
)
error
(
"Messagetable contains more than 65535 blocks; cannot determine endian
\n
"
);
if
(
!
hi
&&
!
lo
)
parser_error
(
"Invalid messagetable block count 0"
);
if
(
!
hi
&&
lo
)
/* Messagetable byteorder == native byteorder */
{
#ifdef WORDS_BIGENDIAN
if
(
byteorder
!=
WRC_BO_LITTLE
)
goto
out
;
#else
if
(
byteorder
!=
WRC_BO_BIG
)
goto
out
;
#endif
/* Resource byteorder != native byteorder */
mbp
=
(
msgtab_block_t
*
)
&
(((
DWORD
*
)
rd
->
data
)[
1
]);
if
(
MSGTAB_BAD_PTR
(
mbp
,
rd
->
data
,
rd
->
size
,
nblk
*
sizeof
(
*
mbp
)))
parser_error
(
"Messagetable's blocks are outside of defined data"
);
for
(
i
=
0
;
i
<
nblk
;
i
++
)
{
msgtab_entry_t
*
mep
,
*
next_mep
;
DWORD
id
;
mep
=
(
msgtab_entry_t
*
)(((
char
*
)
rd
->
data
)
+
mbp
[
i
].
offset
);
for
(
id
=
mbp
[
i
].
idlo
;
id
<=
mbp
[
i
].
idhi
;
id
++
)
{
if
(
MSGTAB_BAD_PTR
(
mep
,
rd
->
data
,
rd
->
size
,
mep
->
length
))
parser_error
(
"Messagetable's data for block %d, ID 0x%08x is outside of defined data"
,
i
,
id
);
if
(
mep
->
flags
==
1
)
/* Docu says 'flags == 0x0001' for unicode */
{
WORD
*
wp
=
(
WORD
*
)
&
mep
[
1
];
int
l
=
mep
->
length
/
2
-
2
;
/* Length included header */
int
n
;
if
(
mep
->
length
&
1
)
parser_error
(
"Message 0x%08x is unicode (block %d), but has odd length (%d)"
,
id
,
i
,
mep
->
length
);
for
(
n
=
0
;
n
<
l
;
n
++
)
wp
[
n
]
=
BYTESWAP_WORD
(
wp
[
n
]);
}
next_mep
=
(
msgtab_entry_t
*
)(((
char
*
)
mep
)
+
mep
->
length
);
mep
->
length
=
BYTESWAP_WORD
(
mep
->
length
);
mep
->
flags
=
BYTESWAP_WORD
(
mep
->
flags
);
mep
=
next_mep
;
}
mbp
[
i
].
idlo
=
BYTESWAP_DWORD
(
mbp
[
i
].
idlo
);
mbp
[
i
].
idhi
=
BYTESWAP_DWORD
(
mbp
[
i
].
idhi
);
mbp
[
i
].
offset
=
BYTESWAP_DWORD
(
mbp
[
i
].
offset
);
}
}
if
(
hi
&&
!
lo
)
/* Messagetable byteorder != native byteorder */
{
#ifdef WORDS_BIGENDIAN
if
(
byteorder
==
WRC_BO_LITTLE
)
goto
out
;
#else
if
(
byteorder
==
WRC_BO_BIG
)
goto
out
;
#endif
/* Resource byteorder == native byteorder */
mbp
=
(
msgtab_block_t
*
)
&
(((
DWORD
*
)
rd
->
data
)[
1
]);
nblk
=
BYTESWAP_DWORD
(
nblk
);
if
(
MSGTAB_BAD_PTR
(
mbp
,
rd
->
data
,
rd
->
size
,
nblk
*
sizeof
(
*
mbp
)))
parser_error
(
"Messagetable's blocks are outside of defined data"
);
for
(
i
=
0
;
i
<
nblk
;
i
++
)
{
msgtab_entry_t
*
mep
;
DWORD
id
;
mbp
[
i
].
idlo
=
BYTESWAP_DWORD
(
mbp
[
i
].
idlo
);
mbp
[
i
].
idhi
=
BYTESWAP_DWORD
(
mbp
[
i
].
idhi
);
mbp
[
i
].
offset
=
BYTESWAP_DWORD
(
mbp
[
i
].
offset
);
mep
=
(
msgtab_entry_t
*
)(((
char
*
)
rd
->
data
)
+
mbp
[
i
].
offset
);
for
(
id
=
mbp
[
i
].
idlo
;
id
<=
mbp
[
i
].
idhi
;
id
++
)
{
mep
->
length
=
BYTESWAP_WORD
(
mep
->
length
);
mep
->
flags
=
BYTESWAP_WORD
(
mep
->
flags
);
if
(
MSGTAB_BAD_PTR
(
mep
,
rd
->
data
,
rd
->
size
,
mep
->
length
))
parser_error
(
"Messagetable's data for block %d, ID 0x%08x is outside of defined data"
,
i
,
id
);
if
(
mep
->
flags
==
1
)
/* Docu says 'flags == 0x0001' for unicode */
{
WORD
*
wp
=
(
WORD
*
)
&
mep
[
1
];
int
l
=
mep
->
length
/
2
-
2
;
/* Length included header */
int
n
;
if
(
mep
->
length
&
1
)
parser_error
(
"Message 0x%08x is unicode (block %d), but has odd length (%d)"
,
id
,
i
,
mep
->
length
);
for
(
n
=
0
;
n
<
l
;
n
++
)
wp
[
n
]
=
BYTESWAP_WORD
(
wp
[
n
]);
}
mep
=
(
msgtab_entry_t
*
)(((
char
*
)
mep
)
+
mep
->
length
);
}
}
}
out:
return
msg
;
}
#undef MSGTAB_BAD_PTR
...
...
tools/wrc/parser.y
View file @
923461f3
...
...
@@ -704,12 +704,6 @@ dlginit : tDLGINIT loadmemopts file_raw { $$ = new_dlginit($3, $2); }
/* ------------------------------ UserType ------------------------------ */
userres
:
usertype
loadmemopts
file_raw
{
#ifdef
WORDS_BIGENDIAN
if(pedantic
&&
byteorder
!=
WRC_BO_LITTLE)
#else
if(pedantic
&&
byteorder
==
WRC_BO_BIG)
#endif
parser_warning("Byteordering
is
not
little-endian
and
type
cannot
be
interpreted\n");
$$
=
new_user($1,
$3,
$2);
}
;
...
...
@@ -2197,24 +2191,8 @@ static raw_data_t *int2raw_data(int i)
rd
=
new_raw_data();
rd->size
=
sizeof(short);
rd->data
=
xmalloc(rd->size);
switch(byteorder)
{
#ifdef
WORDS_BIGENDIAN
default
:
#e
ndif
case
WRC_BO_BIG
:
rd-
>
data
[
0
]
=
HIBYTE
(
i
);
rd->data[1]
=
LOBYTE(i);
break;
#ifndef
WORDS_BIGENDIAN
default
:
#e
ndif
case
WRC_BO_LITTLE
:
rd-
>
data
[
1
]
=
HIBYTE
(
i
);
rd->data[0]
=
LOBYTE(i);
break;
}
rd->data[0]
=
i;
rd->data[1]
=
i
>>
8;
return
rd;
}
...
...
@@ -2224,28 +2202,10 @@ static raw_data_t *long2raw_data(int i)
rd
=
new_raw_data();
rd->size
=
sizeof(int);
rd->data
=
xmalloc(rd->size);
switch(byteorder)
{
#ifdef
WORDS_BIGENDIAN
default
:
#e
ndif
case
WRC_BO_BIG
:
rd-
>
data
[
0
]
=
HIBYTE
(
HIWORD
(
i
));
rd->data[1]
=
LOBYTE(HIWORD(i));
rd->data[2]
=
HIBYTE(LOWORD(i));
rd->data[3]
=
LOBYTE(LOWORD(i));
break;
#ifndef
WORDS_BIGENDIAN
default
:
#e
ndif
case
WRC_BO_LITTLE
:
rd-
>
data
[
3
]
=
HIBYTE
(
HIWORD
(
i
));
rd->data[2]
=
LOBYTE(HIWORD(i));
rd->data[1]
=
HIBYTE(LOWORD(i));
rd->data[0]
=
LOBYTE(LOWORD(i));
break;
}
rd->data[0]
=
i;
rd->data[1]
=
i
>>
8;
rd->data[2]
=
i
>>
16;
rd->data[3]
=
i
>>
24;
return
rd;
}
...
...
@@ -2263,28 +2223,10 @@ static raw_data_t *str2raw_data(string_t *str)
case
str_unicode
:
{
int
i
;
switch(byteorder
)
for(i
=
0;
i
<
str->size;
i++
)
{
#ifdef
WORDS_BIGENDIAN
default
:
#e
ndif
case
WRC_BO_BIG
:
for
(
i
=
0
;
i
<
str->size;
i++)
{
rd->data[2*i
+
0]
=
HIBYTE((WORD)str->str.wstr[i]);
rd->data[2*i
+
1]
=
LOBYTE((WORD)str->str.wstr[i]);
}
break
;
#ifndef
WORDS_BIGENDIAN
default
:
#endif
case
WRC_BO_LITTLE
:
for
(
i
=
0
;
i
<
str-
>
size
;
i
++)
{
rd->data[2*i
+
1]
=
HIBYTE((WORD)str->str.wstr[i]);
rd->data[2*i
+
0]
=
LOBYTE((WORD)str->str.wstr[i]);
}
break
;
rd->data[2*i
+
0]
=
str->str.wstr[i];
rd->data[2*i
+
1]
=
str->str.wstr[i]
>>
8;
}
}
}
...
...
@@ -2688,8 +2630,6 @@ static resource_t *build_fontdirs(resource_t *tail)
for
(
i
=
0
;
i
<
nfnd
;
i
++)
{
int
j;
WORD
cnt;
int
isswapped
=
0;
if(!fnd[i])
continue;
...
...
@@ -2704,23 +2644,6 @@ static resource_t *build_fontdirs(resource_t *tail)
fnt[j]
=
NULL;
}
}
cnt
=
*(
WORD
*)
fnd
[
i
]
-
>
res
.fnd-
>
data-
>
data
;
if
(
nlanfnt
==
cnt
)
isswapped
=
0
;
else
if
(
nlanfnt
==
BYTESWAP_WORD
(
cnt
))
isswapped
=
1
;
else
error
(
"FONTDIR for language %d,%d has wrong count (%d, expected %d)\n"
,
fnd
[
i
]
-
>
lan-
>
id
,
fnd
[
i
]
-
>
lan-
>
sub
,
cnt
,
nlanfnt
);
#ifdef
WORDS_BIGENDIAN
if
((
byteorder
==
WRC_BO_LITTLE
&&
!
isswapped
)
||
(
byteorder
!=
WRC_BO_LITTLE
&&
isswapped
))
#else
if
((
byteorder
==
WRC_BO_BIG
&&
!
isswapped
)
||
(
byteorder
!=
WRC_BO_BIG
&&
isswapped
))
#endif
{
error("User
supplied
FONTDIR
needs
byteswapping\n");
}
}
/* We now have fonts left where we need to make a fontdir resource */
...
...
tools/wrc/wrc.c
View file @
923461f3
...
...
@@ -42,19 +42,11 @@
#include "parser.h"
#include "wpp_private.h"
#ifdef WORDS_BIGENDIAN
#define ENDIAN "big"
#else
#define ENDIAN "little"
#endif
static
const
char
usage
[]
=
"Usage: wrc [options...] [infile[.rc|.res]]
\n
"
" -D, --define id[=val] Define preprocessor identifier id=val
\n
"
" --debug=nn Set debug level to 'nn'
\n
"
" -E Preprocess only
\n
"
" --endianness=e Set output byte-order e={n[ative], l[ittle], b[ig]}
\n
"
" (win32 only; default is "
ENDIAN
"-endian)
\n
"
" -F TARGET Ignored, for compatibility with windres
\n
"
" -fo FILE Synonym for -o for compatibility with windres
\n
"
" -h, --help Prints this summary
\n
"
...
...
@@ -128,11 +120,6 @@ language_t *currentlanguage = NULL;
int
pedantic
=
0
;
/*
* The output byte-order of resources (set with -B)
*/
int
byteorder
=
WRC_BO_NATIVE
;
/*
* Set when _only_ to run the preprocessor (-E option)
*/
int
preprocess_only
=
0
;
...
...
@@ -181,7 +168,6 @@ enum long_options_values
LONG_OPT_SYSROOT
,
LONG_OPT_VERSION
,
LONG_OPT_DEBUG
,
LONG_OPT_ENDIANNESS
,
LONG_OPT_PEDANTIC
,
LONG_OPT_VERIFY_TRANSL
};
...
...
@@ -191,7 +177,6 @@ static const char short_options[] =
static
const
struct
long_option
long_options
[]
=
{
{
"debug"
,
1
,
LONG_OPT_DEBUG
},
{
"define"
,
1
,
'D'
},
{
"endianness"
,
1
,
LONG_OPT_ENDIANNESS
},
{
"help"
,
0
,
'h'
},
{
"include-dir"
,
1
,
'I'
},
{
"input"
,
1
,
'i'
},
...
...
@@ -372,25 +357,6 @@ static void option_callback( int optc, char *optarg )
case
LONG_OPT_DEBUG
:
debuglevel
=
strtol
(
optarg
,
NULL
,
0
);
break
;
case
LONG_OPT_ENDIANNESS
:
switch
(
optarg
[
0
])
{
case
'n'
:
case
'N'
:
byteorder
=
WRC_BO_NATIVE
;
break
;
case
'l'
:
case
'L'
:
byteorder
=
WRC_BO_LITTLE
;
break
;
case
'b'
:
case
'B'
:
byteorder
=
WRC_BO_BIG
;
break
;
default:
error
(
"Byte ordering must be n[ative], l[ittle] or b[ig]
\n
"
);
}
break
;
case
LONG_OPT_PEDANTIC
:
pedantic
=
1
;
break
;
...
...
tools/wrc/wrc.h
View file @
923461f3
...
...
@@ -35,7 +35,7 @@ extern int debuglevel;
extern
int
win32
;
extern
int
extensions
;
extern
int
byteorder
;
extern
int
pedantic
;
extern
int
preprocess_only
;
extern
int
no_preprocess
;
extern
int
utf8_input
;
...
...
tools/wrc/wrc.man.in
View file @
923461f3
...
...
@@ -32,12 +32,6 @@ Set debug level to \fInn\fR. The value is a bitmask consisting of
1=verbose, 2=dump internals, 4=resource parser trace, 8=preprocessor
messages, 16=preprocessor scanner and 32=preprocessor parser trace.
.TP
.I \fB\-\-endianness\fR=\fIe\fR
Win32 only; set output byte\-ordering, where \fIe\fR is one of n[ative],
l[ittle] or b[ig]. Only resources in source-form can be reordered. Native
ordering depends on the system on which \fBwrc\fR was built. You can see
the native ordering by typing \fIwrc \-h\fR.
.TP
.I \fB\-E\fR
Preprocess only. The output is written to standard output if no
outputfile was selected. The output is compatible with what gcc would
...
...
tools/wrc/wrctypes.h
View file @
923461f3
...
...
@@ -68,17 +68,8 @@
#define CT_SCROLLBAR 0x84
#define CT_COMBOBOX 0x85
/* Byteordering defines */
#define WRC_BO_NATIVE 0x00
#define WRC_BO_LITTLE 0x01
#define WRC_BO_BIG 0x02
#define WRC_LOBYTE(w) ((WORD)(w) & 0xff)
#define WRC_HIBYTE(w) (((WORD)(w) >> 8) & 0xff)
#define WRC_LOWORD(d) ((DWORD)(d) & 0xffff)
#define WRC_HIWORD(d) (((DWORD)(d) >> 16) & 0xffff)
#define BYTESWAP_WORD(w) ((WORD)(((WORD)WRC_LOBYTE(w) << 8) + (WORD)WRC_HIBYTE(w)))
#define BYTESWAP_DWORD(d) ((DWORD)(((DWORD)BYTESWAP_WORD(WRC_LOWORD(d)) << 16) + ((DWORD)BYTESWAP_WORD(WRC_HIWORD(d)))))
#define GET_WORD(ptr) (((BYTE *)(ptr))[0] | (((BYTE *)(ptr))[1] << 8))
#define GET_DWORD(ptr) (((BYTE *)(ptr))[0] | (((BYTE *)(ptr))[1] << 8) | (((BYTE *)(ptr))[2] << 16) | (((BYTE *)(ptr))[3] << 24))
typedef
struct
{
...
...
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