Commit 3d455c9b authored by Bertho Stultiens's avatar Bertho Stultiens Committed by Alexandre Julliard

- Bugfix: Corrected a SEGV in the rawdata handling. Mistakingly took the

address of a pointer instead of its value. This probably slipped in during the merge of my tree into the winetree. Lesson learned: always double check. - Verified most resources so that win16 compile also generates correct output for reversed endian. - Implemented byte-ordering for resources. All resources can be forced to be little-, big- or native endian with command-line option -B. - Reading resources from .res-files are only accepted in native byte- ordering so that no additional semantic analysis is required. - Resource directory is still written in native-only format, including the strings. - Wrc is now installed through the makefile with 'make install' and also uninstalled with 'make uninstall'. - Wrote a man-page for better reference. The manpage also gets installed and uninstalled. - Cleaned up the namespace a bit by more agressive use of static.
parent 8ee3144a
---------------------------------------------------------------------------
Version 1.1.2 (08-May-2000)
Bertho Stultiens <bertho@akhphd.au.dk>
- Bugfix: Corrected a SEGV in the rawdata handling. Mistakingly took the
address of a pointer instead of its value. This probably slipped in
during the merge of my tree into the winetree.
Lesson learned: always double check.
- Verified most resources so that win16 compile also generates correct
output for reversed endian.
---------------------------------------------------------------------------
Version 1.1.1 (07-May-2000)
Bertho Stultiens <bertho@akhphd.au.dk>
- Implemented byte-ordering for resources. All resources can be forced
to be little-, big- or native endian with command-line option -B.
- Reading resources from .res-files are only accepted in native byte-
ordering so that no additional semantic analysis is required.
- Resource directory is still written in native-only format, including
the strings.
- Wrc is now installed through the makefile with 'make install' and also
uninstalled with 'make uninstall'.
- Wrote a man-page for better reference. The manpage also gets installed
and uninstalled.
- Cleaned up the namespace a bit by more agressive use of static.
---------------------------------------------------------------------------
Version 1.1.0 (01-May-2000)
Bertho Stultiens <bertho@akhphd.au.dk>
......
......@@ -46,4 +46,13 @@ lex.ppl.c: ppl.l
clean::
$(RM) y.tab.c y.tab.h lex.yy.c ppy.tab.c ppy.tab.h lex.ppl.c ppy.output lex.backup y.output
install:: $(PROGRAMS)
[ -d $(bindir) ] || $(MKDIR) $(bindir)
[ -d $(mandir)/man$(prog_manext) ] || $(MKDIR) $(mandir)/man$(prog_manext)
$(INSTALL_DATA) wrc.man $(mandir)/man$(prog_manext)/wrc.$(prog_manext)
$(INSTALL_PROGRAM) wrc $(bindir)/wrc
uninstall::
$(RM) $(bindir)/wrc $(mandir)/man$(prog_manext)/wrc.$(prog_manext)
### Dependencies:
Release 1.1.0 of wrc (01-May-2000), the wine resource compiler.
Release 1.1.2 of wrc (08-May-2000), the wine resource compiler.
See the file CHANGES for differences between the version and what has been
corrected in the current version.
......@@ -13,6 +13,7 @@ Wrc features:
- indirect loadable resources
- NE/PE resource directory generation
- binary .res file generation/reading
- byte-order conversions
Wrc generates an assembly file that can be assembled with GNU's gas, or
passed to gcc. The assembly became necessary for two reasons. First, C does
......@@ -69,6 +70,8 @@ option to override the header-filename.
If no input filename is given and the output name is not overridden
with -o and/or -H, then the output is written to "wrc.tab.[sh]"
For more info see the wrc manpage.
Preprocessing
-------------
......@@ -264,7 +267,6 @@ though):
- grep for FIXME in the source
- Memory options are wrong under some conditions. There seems to be a
different action for win32 and win16
- Little/big-endian
Reporting bugs and patches
--------------------------
......
......@@ -152,7 +152,7 @@ char *get_nameid_str(name_id_t *n)
* Remarks :
*****************************************************************************
*/
void dump_memopt(DWORD memopt)
static void dump_memopt(DWORD memopt)
{
printf("Memory/load options: ");
if(memopt & 0x0040)
......@@ -183,7 +183,7 @@ void dump_memopt(DWORD memopt)
* Remarks :
*****************************************************************************
*/
void dump_lvc(lvc_t *l)
static void dump_lvc(lvc_t *l)
{
if(l->language)
printf("LANGUAGE %04x, %04x\n", l->language->id, l->language->sub);
......@@ -212,7 +212,7 @@ void dump_lvc(lvc_t *l)
* Remarks :
*****************************************************************************
*/
void dump_raw_data(raw_data_t *d)
static void dump_raw_data(raw_data_t *d)
{
int n;
int i;
......@@ -263,7 +263,7 @@ void dump_raw_data(raw_data_t *d)
* Remarks :
*****************************************************************************
*/
void dump_accelerator(accelerator_t *acc)
static void dump_accelerator(accelerator_t *acc)
{
event_t *ev = acc->events;
......@@ -297,7 +297,7 @@ void dump_accelerator(accelerator_t *acc)
* Remarks :
*****************************************************************************
*/
void dump_cursor(cursor_t *cur)
static void dump_cursor(cursor_t *cur)
{
printf("Id: %d\n", cur->id);
printf("Width: %d\n", cur->width);
......@@ -318,7 +318,7 @@ void dump_cursor(cursor_t *cur)
* Remarks :
*****************************************************************************
*/
void dump_cursor_group(cursor_group_t *curg)
static void dump_cursor_group(cursor_group_t *curg)
{
dump_memopt(curg->memopt);
printf("There are %d cursors in this group\n", curg->ncursor);
......@@ -335,7 +335,7 @@ void dump_cursor_group(cursor_group_t *curg)
* Remarks :
*****************************************************************************
*/
void dump_icon(icon_t *ico)
static void dump_icon(icon_t *ico)
{
printf("Id: %d\n", ico->id);
printf("Width: %d\n", ico->width);
......@@ -357,7 +357,7 @@ void dump_icon(icon_t *ico)
* Remarks :
*****************************************************************************
*/
void dump_icon_group(icon_group_t *icog)
static void dump_icon_group(icon_group_t *icog)
{
dump_memopt(icog->memopt);
printf("There are %d icons in this group\n", icog->nicon);
......@@ -374,7 +374,7 @@ void dump_icon_group(icon_group_t *icog)
* Remarks :
*****************************************************************************
*/
void dump_font(font_t *fnt)
static void dump_font(font_t *fnt)
{
dump_memopt(fnt->memopt);
dump_raw_data(fnt->data);
......@@ -391,7 +391,7 @@ void dump_font(font_t *fnt)
* Remarks :
*****************************************************************************
*/
void dump_bitmap(bitmap_t *bmp)
static void dump_bitmap(bitmap_t *bmp)
{
dump_memopt(bmp->memopt);
dump_raw_data(bmp->data);
......@@ -408,7 +408,7 @@ void dump_bitmap(bitmap_t *bmp)
* Remarks :
*****************************************************************************
*/
void dump_rcdata(rcdata_t *rdt)
static void dump_rcdata(rcdata_t *rdt)
{
dump_memopt(rdt->memopt);
dump_raw_data(rdt->data);
......@@ -425,7 +425,7 @@ void dump_rcdata(rcdata_t *rdt)
* Remarks :
*****************************************************************************
*/
void dump_user(user_t *usr)
static void dump_user(user_t *usr)
{
dump_memopt(usr->memopt);
printf("Class %s\n", get_nameid_str(usr->type));
......@@ -443,7 +443,7 @@ void dump_user(user_t *usr)
* Remarks :
*****************************************************************************
*/
void dump_messagetable(messagetable_t *msg)
static void dump_messagetable(messagetable_t *msg)
{
dump_raw_data(msg->data);
}
......@@ -459,7 +459,7 @@ void dump_messagetable(messagetable_t *msg)
* Remarks :
*****************************************************************************
*/
void dump_stringtable(stringtable_t *stt)
static void dump_stringtable(stringtable_t *stt)
{
int i;
for(; stt; stt = stt->next)
......@@ -491,7 +491,7 @@ void dump_stringtable(stringtable_t *stt)
* Remarks :
*****************************************************************************
*/
void dump_control(control_t *ctrl)
static void dump_control(control_t *ctrl)
{
printf("Control {\n\tClass: %s\n", get_nameid_str(ctrl->ctlclass));
printf("\tText: "); get_nameid_str(ctrl->title); printf("\n");
......@@ -530,7 +530,7 @@ void dump_control(control_t *ctrl)
* Remarks :
*****************************************************************************
*/
void dump_dialog(dialog_t *dlg)
static void dump_dialog(dialog_t *dlg)
{
control_t *c = dlg->controls;
......@@ -580,7 +580,7 @@ void dump_dialog(dialog_t *dlg)
* Remarks :
*****************************************************************************
*/
void dump_dialogex(dialogex_t *dlgex)
static void dump_dialogex(dialogex_t *dlgex)
{
control_t *c = dlgex->controls;
......@@ -630,7 +630,7 @@ void dump_dialogex(dialogex_t *dlgex)
* Remarks :
*****************************************************************************
*/
void dump_menu_item(menu_item_t *item)
static void dump_menu_item(menu_item_t *item)
{
while(item)
{
......@@ -668,7 +668,7 @@ void dump_menu_item(menu_item_t *item)
* Remarks :
*****************************************************************************
*/
void dump_menu(menu_t *men)
static void dump_menu(menu_t *men)
{
dump_memopt(men->memopt);
dump_lvc(&(men->lvc));
......@@ -685,7 +685,7 @@ void dump_menu(menu_t *men)
* Remarks :
*****************************************************************************
*/
void dump_menuex_item(menuex_item_t *item)
static void dump_menuex_item(menuex_item_t *item)
{
while(item)
{
......@@ -738,7 +738,7 @@ void dump_menuex_item(menuex_item_t *item)
* Remarks :
*****************************************************************************
*/
void dump_menuex(menuex_t *menex)
static void dump_menuex(menuex_t *menex)
{
dump_memopt(menex->memopt);
dump_lvc(&(menex->lvc));
......@@ -755,9 +755,10 @@ void dump_menuex(menuex_t *menex)
* Remarks :
*****************************************************************************
*/
void dump_ver_value(ver_value_t *val)
static void dump_ver_block(ver_block_t *); /* Forward ref */
static void dump_ver_value(ver_value_t *val)
{
extern void dump_ver_block(ver_block_t *);
if(val->type == val_str)
{
printf("VALUE ");
......@@ -791,7 +792,7 @@ void dump_ver_value(ver_value_t *val)
* Remarks :
*****************************************************************************
*/
void dump_ver_block(ver_block_t *blk)
static void dump_ver_block(ver_block_t *blk)
{
ver_value_t *val = blk->values;
printf("BLOCK ");
......@@ -816,7 +817,7 @@ void dump_ver_block(ver_block_t *blk)
* Remarks :
*****************************************************************************
*/
void dump_versioninfo(versioninfo_t *ver)
static void dump_versioninfo(versioninfo_t *ver)
{
ver_block_t *blk = ver->blocks;
......@@ -859,7 +860,7 @@ void dump_versioninfo(versioninfo_t *ver)
* Remarks :
*****************************************************************************
*/
void dump_toolbar_items(toolbar_item_t *items)
static void dump_toolbar_items(toolbar_item_t *items)
{
while(items)
{
......@@ -885,7 +886,7 @@ void dump_toolbar_items(toolbar_item_t *items)
* Remarks :
*****************************************************************************
*/
void dump_toolbar(toolbar_t *toolbar)
static void dump_toolbar(toolbar_t *toolbar)
{
dump_memopt(toolbar->memopt);
dump_lvc(&(toolbar->lvc));
......@@ -903,7 +904,7 @@ void dump_toolbar(toolbar_t *toolbar)
* Remarks :
*****************************************************************************
*/
void dump_dlginit(dlginit_t *dit)
static void dump_dlginit(dlginit_t *dit)
{
dump_memopt(dit->memopt);
dump_lvc(&(dit->lvc));
......
......@@ -3,6 +3,9 @@
*
* Copyright 1998 Bertho A. Stultiens
*
* 05-May-2000 BS - Added code to support endian conversions. The
* extra functions also aid unaligned access, but
* this is not yet implemented.
* 25-May-1998 BS - Added simple unicode -> char conversion for resource
* names in .s and .h files.
*/
......@@ -14,6 +17,7 @@
#include <string.h>
#include <assert.h>
#include <ctype.h>
#include <endian.h>
#include "wrc.h"
#include "genres.h"
......@@ -22,8 +26,7 @@
#include "wingdi.h"
#include "winuser.h"
#define SetResSize(res, tag) *(DWORD *)&((res)->data[(tag)]) = \
(res)->size - *(DWORD *)&((res)->data[(tag)])
#define SetResSize(res, tag) set_dword((res), (tag), (res)->size - get_dword((res), (tag)))
res_t *new_res(void)
{
......@@ -71,7 +74,19 @@ void put_word(res_t *res, unsigned w)
{
if(res->allocsize - res->size < sizeof(WORD))
grow_res(res, RES_BLOCKSIZE);
switch(byteorder)
{
#if BYTE_ORDER == LITTLE_ENDIAN
case WRC_BO_BIG:
#else
case WRC_BO_LITTLE:
#endif
*(WORD *)&(res->data[res->size]) = BYTESWAP_WORD((WORD)w);
break;
default:
*(WORD *)&(res->data[res->size]) = (WORD)w;
break;
}
res->size += sizeof(WORD);
}
......@@ -79,7 +94,19 @@ void put_dword(res_t *res, unsigned d)
{
if(res->allocsize - res->size < sizeof(DWORD))
grow_res(res, RES_BLOCKSIZE);
switch(byteorder)
{
#if BYTE_ORDER == LITTLE_ENDIAN
case WRC_BO_BIG:
#else
case WRC_BO_LITTLE:
#endif
*(DWORD *)&(res->data[res->size]) = BYTESWAP_DWORD((DWORD)d);
break;
default:
*(DWORD *)&(res->data[res->size]) = (DWORD)d;
break;
}
res->size += sizeof(DWORD);
}
......@@ -91,6 +118,101 @@ void put_pad(res_t *res)
/*
*****************************************************************************
* Function : set_word
* set_dword
* Syntax : void set_word(res_t *res, int ofs, unsigned w)
* void set_dword(res_t *res, int ofs, unsigned d)
* Input :
* res - Binary resource to put the data in
* ofs - Byte offset in data-array
* w, d - Data to put
* Output : nop
* Description : Set the value of a binary resource data array to a
* specific value.
* Remarks :
*****************************************************************************
*/
void set_word(res_t *res, int ofs, unsigned w)
{
switch(byteorder)
{
#if BYTE_ORDER == LITTLE_ENDIAN
case WRC_BO_BIG:
#else
case WRC_BO_LITTLE:
#endif
*(WORD *)&(res->data[ofs]) = BYTESWAP_WORD((WORD)w);
break;
default:
*(WORD *)&(res->data[ofs]) = (WORD)w;
break;
}
}
void set_dword(res_t *res, int ofs, unsigned d)
{
switch(byteorder)
{
#if BYTE_ORDER == LITTLE_ENDIAN
case WRC_BO_BIG:
#else
case WRC_BO_LITTLE:
#endif
*(DWORD *)&(res->data[ofs]) = BYTESWAP_DWORD((DWORD)d);
break;
default:
*(DWORD *)&(res->data[ofs]) = (DWORD)d;
break;
}
}
/*
*****************************************************************************
* Function : get_word
* get_dword
* Syntax : WORD get_word(res_t *res, int ofs)
* DWORD get_dword(res_t *res, int ofs)
* Input :
* res - Binary resource to put the data in
* ofs - Byte offset in data-array
* Output : The data in native endian
* Description : Get the value of a binary resource data array in native
* endian.
* Remarks :
*****************************************************************************
*/
WORD get_word(res_t *res, int ofs)
{
switch(byteorder)
{
#if BYTE_ORDER == LITTLE_ENDIAN
case WRC_BO_BIG:
#else
case WRC_BO_LITTLE:
#endif
return BYTESWAP_WORD(*(WORD *)&(res->data[ofs]));
default:
return *(WORD *)&(res->data[ofs]);
}
}
DWORD get_dword(res_t *res, int ofs)
{
switch(byteorder)
{
#if BYTE_ORDER == LITTLE_ENDIAN
case WRC_BO_BIG:
#else
case WRC_BO_LITTLE:
#endif
return BYTESWAP_DWORD(*(DWORD *)&(res->data[ofs]));
default:
return *(DWORD *)&(res->data[ofs]);
}
}
/*
*****************************************************************************
* Function : string_to_upper
* Syntax : void string_to_upper(string_t *str)
* Input :
......@@ -313,8 +435,8 @@ int put_res_header(res_t *res, int type, name_id_t *ntype, name_id_t *name,
put_dword(res, 0); /* DataVersion */
put_word(res, memopt); /* Memory options */
put_lvc(res, lvc); /* Language, version and characts */
((DWORD *)res->data)[0] = res->size; /* Set preliminary resource */
((DWORD *)res->data)[1] = res->size; /* Set HeaderSize */
set_dword(res, 0*sizeof(DWORD), res->size); /* Set preliminary resource */
set_dword(res, 1*sizeof(DWORD), res->size); /* Set HeaderSize */
res->dataidx = res->size;
return 0;
}
......@@ -332,7 +454,7 @@ int put_res_header(res_t *res, int type, name_id_t *ntype, name_id_t *name,
put_word(res, memopt); /* Memory options */
tag = res->size;
put_dword(res, 0); /* ResSize overwritten later*/
*(DWORD *)&(res->data[tag]) = res->size;
set_dword(res, tag, res->size);
res->dataidx = res->size;
return tag;
}
......@@ -350,7 +472,7 @@ int put_res_header(res_t *res, int type, name_id_t *ntype, name_id_t *name,
* Remarks :
*****************************************************************************
*/
res_t *accelerator2res(name_id_t *name, accelerator_t *acc)
static res_t *accelerator2res(name_id_t *name, accelerator_t *acc)
{
int restag;
res_t *res;
......@@ -401,7 +523,7 @@ res_t *accelerator2res(name_id_t *name, accelerator_t *acc)
* Remarks :
*****************************************************************************
*/
res_t *dialog2res(name_id_t *name, dialog_t *dlg)
static res_t *dialog2res(name_id_t *name, dialog_t *dlg)
{
int restag;
res_t *res;
......@@ -477,7 +599,7 @@ res_t *dialog2res(name_id_t *name, dialog_t *dlg)
ctrl = ctrl->next;
}
/* Set number of controls */
*(WORD *)&((char *)res->data)[tag_nctrl] = (WORD)nctrl;
set_word(res, tag_nctrl, (WORD)nctrl);
}
else /* win16 */
{
......@@ -560,7 +682,7 @@ res_t *dialog2res(name_id_t *name, dialog_t *dlg)
* Remarks :
*****************************************************************************
*/
res_t *dialogex2res(name_id_t *name, dialogex_t *dlgex)
static res_t *dialogex2res(name_id_t *name, dialogex_t *dlgex)
{
int restag;
res_t *res;
......@@ -653,7 +775,7 @@ res_t *dialogex2res(name_id_t *name, dialogex_t *dlgex)
ctrl = ctrl->next;
}
/* Set number of controls */
*(WORD *)&((char *)res->data)[tag_nctrl] = (WORD)nctrl;
set_word(res, tag_nctrl, (WORD)nctrl);
/* Set ResourceSize */
SetResSize(res, restag);
put_pad(res);
......@@ -678,7 +800,7 @@ res_t *dialogex2res(name_id_t *name, dialogex_t *dlgex)
* Remarks : Self recursive
*****************************************************************************
*/
void menuitem2res(res_t *res, menu_item_t *menitem)
static void menuitem2res(res_t *res, menu_item_t *menitem)
{
menu_item_t *itm = menitem;
if(win32)
......@@ -728,7 +850,7 @@ void menuitem2res(res_t *res, menu_item_t *menitem)
* Remarks :
*****************************************************************************
*/
res_t *menu2res(name_id_t *name, menu_t *men)
static res_t *menu2res(name_id_t *name, menu_t *men)
{
int restag;
res_t *res;
......@@ -757,7 +879,7 @@ res_t *menu2res(name_id_t *name, menu_t *men)
* Remarks : Self recursive
*****************************************************************************
*/
void menuexitem2res(res_t *res, menuex_item_t *menitem)
static void menuexitem2res(res_t *res, menuex_item_t *menitem)
{
menuex_item_t *itm = menitem;
assert(win32 != 0);
......@@ -794,7 +916,7 @@ void menuexitem2res(res_t *res, menuex_item_t *menitem)
* Remarks :
*****************************************************************************
*/
res_t *menuex2res(name_id_t *name, menuex_t *menex)
static res_t *menuex2res(name_id_t *name, menuex_t *menex)
{
int restag;
res_t *res;
......@@ -837,7 +959,7 @@ res_t *menuex2res(name_id_t *name, menuex_t *menex)
* Remarks :
*****************************************************************************
*/
res_t *cursorgroup2res(name_id_t *name, cursor_group_t *curg)
static res_t *cursorgroup2res(name_id_t *name, cursor_group_t *curg)
{
int restag;
res_t *res;
......@@ -945,7 +1067,7 @@ res_t *cursorgroup2res(name_id_t *name, cursor_group_t *curg)
* Remarks :
*****************************************************************************
*/
res_t *cursor2res(cursor_t *cur)
static res_t *cursor2res(cursor_t *cur)
{
int restag;
res_t *res;
......@@ -980,7 +1102,7 @@ res_t *cursor2res(cursor_t *cur)
* Remarks :
*****************************************************************************
*/
res_t *icongroup2res(name_id_t *name, icon_group_t *icog)
static res_t *icongroup2res(name_id_t *name, icon_group_t *icog)
{
int restag;
res_t *res;
......@@ -1048,7 +1170,7 @@ res_t *icongroup2res(name_id_t *name, icon_group_t *icog)
* Remarks :
*****************************************************************************
*/
res_t *icon2res(icon_t *ico)
static res_t *icon2res(icon_t *ico)
{
int restag;
res_t *res;
......@@ -1078,21 +1200,19 @@ res_t *icon2res(icon_t *ico)
* bmp - The bitmap descriptor
* Output : New .res format structure
* Description :
* Remarks :
* Remarks : The endian of the bitmap structures have been converted
* to native by the loader.
*****************************************************************************
*/
res_t *bitmap2res(name_id_t *name, bitmap_t *bmp)
static res_t *bitmap2res(name_id_t *name, bitmap_t *bmp)
{
int restag;
res_t *res;
assert(name != NULL);
assert(bmp != NULL);
HEAPCHECK();
res = new_res();
HEAPCHECK();
restag = put_res_header(res, WRC_RT_BITMAP, NULL, name, bmp->memopt, NULL);
HEAPCHECK();
if(bmp->data->data[0] == 'B'
&& bmp->data->data[1] == 'M'
&& ((BITMAPFILEHEADER *)bmp->data->data)->bfSize == bmp->data->size
......@@ -1105,13 +1225,10 @@ res_t *bitmap2res(name_id_t *name, bitmap_t *bmp)
{
put_raw_data(res, bmp->data, 0);
}
HEAPCHECK();
/* Set ResourceSize */
SetResSize(res, restag);
HEAPCHECK();
if(win32)
put_pad(res);
HEAPCHECK();
return res;
}
......@@ -1127,7 +1244,7 @@ res_t *bitmap2res(name_id_t *name, bitmap_t *bmp)
* Remarks :
*****************************************************************************
*/
res_t *font2res(name_id_t *name, font_t *fnt)
static res_t *font2res(name_id_t *name, font_t *fnt)
{
assert(name != NULL);
assert(fnt != NULL);
......@@ -1147,7 +1264,7 @@ res_t *font2res(name_id_t *name, font_t *fnt)
* Remarks :
*****************************************************************************
*/
res_t *rcdata2res(name_id_t *name, rcdata_t *rdt)
static res_t *rcdata2res(name_id_t *name, rcdata_t *rdt)
{
int restag;
res_t *res;
......@@ -1176,7 +1293,7 @@ res_t *rcdata2res(name_id_t *name, rcdata_t *rdt)
* Remarks :
*****************************************************************************
*/
res_t *messagetable2res(name_id_t *name, messagetable_t *msg)
static res_t *messagetable2res(name_id_t *name, messagetable_t *msg)
{
assert(name != NULL);
assert(msg != NULL);
......@@ -1195,7 +1312,7 @@ res_t *messagetable2res(name_id_t *name, messagetable_t *msg)
* Remarks :
*****************************************************************************
*/
res_t *stringtable2res(stringtable_t *stt)
static res_t *stringtable2res(stringtable_t *stt)
{
res_t *res;
name_id_t name;
......@@ -1255,7 +1372,7 @@ res_t *stringtable2res(stringtable_t *stt)
* Remarks :
*****************************************************************************
*/
res_t *user2res(name_id_t *name, user_t *usr)
static res_t *user2res(name_id_t *name, user_t *usr)
{
int restag;
res_t *res;
......@@ -1284,7 +1401,7 @@ res_t *user2res(name_id_t *name, user_t *usr)
* Remarks : Self recursive
*****************************************************************************
*/
void versionblock2res(res_t *res, ver_block_t *blk, int level)
static void versionblock2res(res_t *res, ver_block_t *blk, int level)
{
ver_value_t *val;
int blksizetag;
......@@ -1317,10 +1434,10 @@ void versionblock2res(res_t *res, ver_block_t *blk, int level)
tag = res->size;
put_string(res, val->value.str, win32 ? str_unicode : str_char, TRUE);
if(win32)
*(WORD *)&(res->data[valvalsizetag]) = (WORD)((res->size - tag) >> 1);
set_word(res, valvalsizetag, (WORD)((res->size - tag) >> 1));
else
*(WORD *)&(res->data[valvalsizetag]) = (WORD)(res->size - tag);
*(WORD *)&(res->data[valblksizetag]) = (WORD)(res->size - valblksizetag);
set_word(res, valvalsizetag, (WORD)(res->size - tag));
set_word(res, valblksizetag, (WORD)(res->size - valblksizetag));
put_pad(res);
}
else if(val->type == val_words)
......@@ -1340,8 +1457,8 @@ void versionblock2res(res_t *res, ver_block_t *blk, int level)
{
put_word(res, val->value.words->words[i]);
}
*(WORD *)&(res->data[valvalsizetag]) = (WORD)(res->size - tag);
*(WORD *)&(res->data[valblksizetag]) = (WORD)(res->size - valblksizetag);
set_word(res, valvalsizetag, (WORD)(res->size - tag));
set_word(res, valblksizetag, (WORD)(res->size - valblksizetag));
put_pad(res);
}
else if(val->type == val_block)
......@@ -1355,7 +1472,7 @@ void versionblock2res(res_t *res, ver_block_t *blk, int level)
}
/* Set blocksize */
*(WORD *)&(res->data[blksizetag]) = (WORD)(res->size - blksizetag);
set_word(res, blksizetag, (WORD)(res->size - blksizetag));
}
/*
......@@ -1370,7 +1487,7 @@ void versionblock2res(res_t *res, ver_block_t *blk, int level)
* Remarks :
*****************************************************************************
*/
res_t *versioninfo2res(name_id_t *name, versioninfo_t *ver)
static res_t *versioninfo2res(name_id_t *name, versioninfo_t *ver)
{
int restag;
int rootblocksizetag;
......@@ -1413,12 +1530,12 @@ res_t *versioninfo2res(name_id_t *name, versioninfo_t *ver)
put_dword(res, 0); /* FileDateMS */
put_dword(res, 0); /* FileDateLS */
/* Set ValueSize */
*(WORD *)&(res->data[valsizetag]) = (WORD)(res->size - tag);
set_word(res, valsizetag, (WORD)(res->size - tag));
/* Descend into the blocks */
for(blk = ver->blocks; blk; blk = blk->next)
versionblock2res(res, blk, 0);
/* Set root block's size */
*(WORD *)&(res->data[rootblocksizetag]) = (WORD)(res->size - rootblocksizetag);
set_word(res, rootblocksizetag, (WORD)(res->size - rootblocksizetag));
SetResSize(res, restag);
if(win32)
......@@ -1437,7 +1554,7 @@ res_t *versioninfo2res(name_id_t *name, versioninfo_t *ver)
* Remarks : Self recursive
*****************************************************************************
*/
void toolbaritem2res(res_t *res, toolbar_item_t *tbitem)
static void toolbaritem2res(res_t *res, toolbar_item_t *tbitem)
{
toolbar_item_t *itm = tbitem;
assert(win32 != 0);
......@@ -1461,7 +1578,7 @@ void toolbaritem2res(res_t *res, toolbar_item_t *tbitem)
* Remarks :
*****************************************************************************
*/
res_t *toolbar2res(name_id_t *name, toolbar_t *toolbar)
static res_t *toolbar2res(name_id_t *name, toolbar_t *toolbar)
{
int restag;
res_t *res;
......@@ -1505,7 +1622,7 @@ res_t *toolbar2res(name_id_t *name, toolbar_t *toolbar)
* Remarks :
*****************************************************************************
*/
res_t *dlginit2res(name_id_t *name, dlginit_t *dit)
static res_t *dlginit2res(name_id_t *name, dlginit_t *dit)
{
int restag;
res_t *res;
......
......@@ -18,6 +18,8 @@
#include "utils.h"
#include "parser.h"
#include "wingdi.h" /* for BITMAPINFOHEADER */
/* Generate new_* functions that have no parameters (NOTE: no ';') */
__NEW_STRUCT_FUNC(dialog)
__NEW_STRUCT_FUNC(dialogex)
......@@ -148,6 +150,382 @@ font_t *new_font(raw_data_t *rd, int *memopt)
return fnt;
}
/*
* Convert bitmaps to proper endian
*/
static void convert_bitmap_swap_v3(BITMAPINFOHEADER *bih)
{
bih->biSize = BYTESWAP_DWORD(bih->biSize);
bih->biWidth = BYTESWAP_DWORD(bih->biWidth);
bih->biHeight = BYTESWAP_DWORD(bih->biHeight);
bih->biPlanes = BYTESWAP_WORD(bih->biPlanes);
bih->biBitCount = BYTESWAP_WORD(bih->biBitCount);
bih->biCompression = BYTESWAP_DWORD(bih->biCompression);
bih->biSizeImage = BYTESWAP_DWORD(bih->biSizeImage);
bih->biXPelsPerMeter = BYTESWAP_DWORD(bih->biXPelsPerMeter);
bih->biYPelsPerMeter = BYTESWAP_DWORD(bih->biYPelsPerMeter);
bih->biClrUsed = BYTESWAP_DWORD(bih->biClrUsed);
bih->biClrImportant = BYTESWAP_DWORD(bih->biClrImportant);
}
static void convert_bitmap_swap_v4(BITMAPV4HEADER *b4h)
{
convert_bitmap_swap_v3((BITMAPINFOHEADER *)b4h);
b4h->bV4RedMask = BYTESWAP_DWORD(b4h->bV4RedMask);
b4h->bV4GreenMask = BYTESWAP_DWORD(b4h->bV4GreenMask);
b4h->bV4BlueMask = BYTESWAP_DWORD(b4h->bV4BlueMask);
b4h->bV4AlphaMask = BYTESWAP_DWORD(b4h->bV4AlphaMask);
b4h->bV4CSType = BYTESWAP_DWORD(b4h->bV4CSType);
b4h->bV4EndPoints.ciexyzRed.ciexyzX = BYTESWAP_DWORD(b4h->bV4EndPoints.ciexyzRed.ciexyzX);
b4h->bV4EndPoints.ciexyzRed.ciexyzY = BYTESWAP_DWORD(b4h->bV4EndPoints.ciexyzRed.ciexyzY);
b4h->bV4EndPoints.ciexyzRed.ciexyzZ = BYTESWAP_DWORD(b4h->bV4EndPoints.ciexyzRed.ciexyzZ);
b4h->bV4EndPoints.ciexyzGreen.ciexyzX = BYTESWAP_DWORD(b4h->bV4EndPoints.ciexyzGreen.ciexyzX);
b4h->bV4EndPoints.ciexyzGreen.ciexyzY = BYTESWAP_DWORD(b4h->bV4EndPoints.ciexyzGreen.ciexyzY);
b4h->bV4EndPoints.ciexyzGreen.ciexyzZ = BYTESWAP_DWORD(b4h->bV4EndPoints.ciexyzGreen.ciexyzZ);
b4h->bV4EndPoints.ciexyzBlue.ciexyzX = BYTESWAP_DWORD(b4h->bV4EndPoints.ciexyzBlue.ciexyzX);
b4h->bV4EndPoints.ciexyzBlue.ciexyzY = BYTESWAP_DWORD(b4h->bV4EndPoints.ciexyzBlue.ciexyzY);
b4h->bV4EndPoints.ciexyzBlue.ciexyzZ = BYTESWAP_DWORD(b4h->bV4EndPoints.ciexyzBlue.ciexyzZ);
b4h->bV4GammaRed = BYTESWAP_DWORD(b4h->bV4GammaRed);
b4h->bV4GammaGreen = BYTESWAP_DWORD(b4h->bV4GammaGreen);
b4h->bV4GammaBlue = BYTESWAP_DWORD(b4h->bV4GammaBlue);
}
#define FL_SIGBE 0x01
#define FL_SIZEBE 0x02
#define FL_V4 0x04
static int convert_bitmap(char *data, int size)
{
BITMAPINFOHEADER *bih = (BITMAPINFOHEADER *)data;
BITMAPV4HEADER *b4h = (BITMAPV4HEADER *)data;
int type = 0;
#if BYTE_ORDER == BIG_ENDIAN
DWORD bisizel = BYTESWAP_DWORD(sizeof(BITMAPINFOHEADER));
DWORD b4sizel = BYTESWAP_DWORD(sizeof(BITMAPV4HEADER));
DWORD bisizeb = sizeof(BITMAPINFOHEADER);
DWORD b4sizeb = sizeof(BITMAPV4HEADER);
#else
DWORD bisizel = sizeof(BITMAPINFOHEADER);
DWORD b4sizel = sizeof(BITMAPV4HEADER);
DWORD bisizeb = BYTESWAP_DWORD(sizeof(BITMAPINFOHEADER));
DWORD b4sizeb = BYTESWAP_DWORD(sizeof(BITMAPV4HEADER));
#endif
if(data[0] == 'B' && data[1] == 'M')
{
/* Little endian signature */
bih = (BITMAPINFOHEADER *)(data + sizeof(BITMAPFILEHEADER));
b4h = (BITMAPV4HEADER *)(data + sizeof(BITMAPFILEHEADER));
}
else if(data[0] == 'M' && data[1] == 'B')
{
type |= FL_SIGBE; /* Big endian signature */
bih = (BITMAPINFOHEADER *)(data + sizeof(BITMAPFILEHEADER));
b4h = (BITMAPV4HEADER *)(data + sizeof(BITMAPFILEHEADER));
}
if(bih->biSize == bisizel)
{
/* Little endian */
}
else if(bih->biSize == b4sizel)
{
type |= FL_V4;
}
else if(bih->biSize == bisizeb)
{
type |= FL_SIZEBE;
}
else if(bih->biSize == b4sizeb)
{
type |= FL_SIZEBE | FL_V4;
}
else
type = -1;
switch(type)
{
default:
break;
case FL_SIZEBE:
case FL_SIZEBE | FL_V4:
yywarning("Bitmap v%c signature little-endian, but size big-endian", type & FL_V4 ? '4' : '3');
break;
case FL_SIGBE:
case FL_SIGBE | FL_V4:
yywarning("Bitmap v%c signature big-endian, but size little-endian", type & FL_V4 ? '4' : '3');
break;
case -1:
yyerror("Invalid bitmap format");
break;
}
switch(byteorder)
{
#if BYTE_ORDER == BIG_ENDIAN
default:
#endif
case WRC_BO_BIG:
if(!(type & FL_SIZEBE))
{
if(type & FL_V4)
convert_bitmap_swap_v4(b4h);
else
convert_bitmap_swap_v3(bih);
}
break;
#if BYTE_ORDER == LITTLE_ENDIAN
default:
#endif
case WRC_BO_LITTLE:
if(type & FL_SIZEBE)
{
if(type & FL_V4)
convert_bitmap_swap_v4(b4h);
else
convert_bitmap_swap_v3(bih);
}
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 0;
}
#undef FL_SIGBE
#undef FL_SIZEBE
#undef FL_V4
/*
* Cursor and icon splitter functions used when allocating
* cursor- and icon-groups.
*/
typedef struct {
language_t lan;
int id;
} id_alloc_t;
static int get_new_id(id_alloc_t **list, int *n, language_t *lan)
{
int i;
assert(lan != NULL);
assert(list != NULL);
assert(n != NULL);
if(!*list)
{
*list = (id_alloc_t *)xmalloc(sizeof(id_alloc_t));
*n = 1;
(*list)[0].lan = *lan;
(*list)[0].id = 1;
return 1;
}
for(i = 0; i < *n; i++)
{
if((*list)[i].lan.id == lan->id && (*list)[i].lan.sub == lan->sub)
return ++((*list)[i].id);
}
*list = (id_alloc_t *)xrealloc(*list, sizeof(id_alloc_t) * (*n+1));
(*list)[*n].lan = *lan;
(*list)[*n].id = 1;
*n += 1;
return 1;
}
static int alloc_icon_id(language_t *lan)
{
static id_alloc_t *idlist = NULL;
static int nid = 0;
return get_new_id(&idlist, &nid, lan);
}
static int alloc_cursor_id(language_t *lan)
{
static id_alloc_t *idlist = NULL;
static int nid = 0;
return get_new_id(&idlist, &nid, lan);
}
static void split_icons(raw_data_t *rd, icon_group_t *icog, int *nico)
{
int cnt;
int i;
icon_dir_entry_t *ide;
icon_t *ico;
icon_t *list = NULL;
icon_header_t *ih = (icon_header_t *)rd->data;
int swap = 0;
/* FIXME: Distinguish between normal and animated icons (RIFF format) */
if(ih->type == 1)
swap = 0;
else if(BYTESWAP_WORD(ih->type) == 1)
swap = 1;
else
yyerror("Icon resource data has invalid type id %d", ih->type);
cnt = swap ? BYTESWAP_WORD(ih->count) : ih->count;
ide = (icon_dir_entry_t *)((char *)rd->data + sizeof(icon_header_t));
for(i = 0; i < cnt; i++)
{
ico = new_icon();
ico->id = alloc_icon_id(icog->lvc.language);
ico->lvc.language = dup_language(icog->lvc.language);
if(swap)
{
ide[i].offset = BYTESWAP_DWORD(ide[i].offset);
ide[i].ressize= BYTESWAP_DWORD(ide[i].ressize);
}
if(ide[i].offset > rd->size
|| ide[i].offset + ide[i].ressize > rd->size)
yyerror("Icon resource data corrupt");
ico->width = ide[i].width;
ico->height = ide[i].height;
ico->nclr = ide[i].nclr;
ico->planes = swap ? BYTESWAP_WORD(ide[i].planes) : ide[i].planes;
ico->bits = swap ? BYTESWAP_WORD(ide[i].bits) : ide[i].bits;
convert_bitmap((char *)rd->data + ide[i].offset, 0);
if(!ico->planes)
{
WORD planes;
/* Argh! They did not fill out the resdir structure */
planes = ((BITMAPINFOHEADER *)((char *)rd->data + ide[i].offset))->biPlanes;
/* The bitmap is in destination byteorder. We want native for our structures */
switch(byteorder)
{
#if BYTE_ORDER == BIG_ENDIAN
case WRC_BO_LITTLE:
#else
case WRC_BO_BIG:
#endif
ico->planes = BYTESWAP_WORD(planes);
break;
default:
ico->planes = planes;
}
}
if(!ico->bits)
{
WORD bits;
/* Argh! They did not fill out the resdir structure */
bits = ((BITMAPINFOHEADER *)((char *)rd->data + ide[i].offset))->biBitCount;
/* The bitmap is in destination byteorder. We want native for our structures */
switch(byteorder)
{
#if BYTE_ORDER == BIG_ENDIAN
case WRC_BO_LITTLE:
#else
case WRC_BO_BIG:
#endif
ico->bits = BYTESWAP_WORD(bits);
break;
default:
ico->bits = bits;
}
}
ico->data = new_raw_data();
copy_raw_data(ico->data, rd, ide[i].offset, ide[i].ressize);
if(!list)
{
list = ico;
}
else
{
ico->next = list;
list->prev = ico;
list = ico;
}
}
icog->iconlist = list;
*nico = cnt;
}
static void split_cursors(raw_data_t *rd, cursor_group_t *curg, int *ncur)
{
int cnt;
int i;
cursor_dir_entry_t *cde;
cursor_t *cur;
cursor_t *list = NULL;
cursor_header_t *ch = (cursor_header_t *)rd->data;
int swap = 0;
/* FIXME: Distinguish between normal and animated cursors (RIFF format)*/
if(ch->type == 2)
swap = 0;
else if(BYTESWAP_WORD(ch->type) == 2)
swap = 1;
else
yyerror("Cursor resource data has invalid type id %d", ch->type);
cnt = swap ? BYTESWAP_WORD(ch->count) : ch->count;
cde = (cursor_dir_entry_t *)((char *)rd->data + sizeof(cursor_header_t));
for(i = 0; i < cnt; i++)
{
WORD planes;
WORD bits;
cur = new_cursor();
cur->id = alloc_cursor_id(curg->lvc.language);
cur->lvc.language = dup_language(curg->lvc.language);
if(swap)
{
cde[i].offset = BYTESWAP_DWORD(cde[i].offset);
cde[i].ressize= BYTESWAP_DWORD(cde[i].ressize);
}
if(cde[i].offset > rd->size
|| cde[i].offset + cde[i].ressize > rd->size)
yyerror("Cursor resource data corrupt");
cur->width = cde[i].width;
cur->height = cde[i].height;
cur->nclr = cde[i].nclr;
convert_bitmap((char *)rd->data + cde[i].offset, 0);
/* The next two are to support color cursors */
planes = ((BITMAPINFOHEADER *)((char *)rd->data + cde[i].offset))->biPlanes;
bits = ((BITMAPINFOHEADER *)((char *)rd->data + cde[i].offset))->biBitCount;
/* The bitmap is in destination byteorder. We want native for our structures */
switch(byteorder)
{
#if BYTE_ORDER == BIG_ENDIAN
case WRC_BO_LITTLE:
#else
case WRC_BO_BIG:
#endif
cur->planes = BYTESWAP_WORD(planes);
cur->bits = BYTESWAP_WORD(bits);
break;
default:
cur->planes = planes;
cur->bits = bits;
}
if(!win32 && (cur->planes != 1 || cur->bits != 1))
yywarning("Win16 cursor contains colors");
cur->xhot = swap ? BYTESWAP_WORD(cde[i].xhot) : cde[i].xhot;
cur->yhot = swap ? BYTESWAP_WORD(cde[i].yhot) : cde[i].yhot;
cur->data = new_raw_data();
copy_raw_data(cur->data, rd, cde[i].offset, cde[i].ressize);
if(!list)
{
list = cur;
}
else
{
cur->next = list;
list->prev = cur;
list = cur;
}
}
curg->cursorlist = list;
*ncur = cnt;
}
icon_group_t *new_icon_group(raw_data_t *rd, int *memopt)
{
icon_group_t *icog = (icon_group_t *)xmalloc(sizeof(icon_group_t));
......@@ -185,6 +563,7 @@ cursor_group_t *new_cursor_group(raw_data_t *rd, int *memopt)
bitmap_t *new_bitmap(raw_data_t *rd, int *memopt)
{
bitmap_t *bmp = (bitmap_t *)xmalloc(sizeof(bitmap_t));
bmp->data = rd;
if(memopt)
{
......@@ -193,6 +572,7 @@ bitmap_t *new_bitmap(raw_data_t *rd, int *memopt)
}
else
bmp->memopt = WRC_MO_MOVEABLE | WRC_MO_PURE;
rd->size -= convert_bitmap(rd->data, rd->size);
return bmp;
}
......
......@@ -12,8 +12,6 @@ extern int yydebug;
extern int want_nl; /* Set when getting line-numers */
int yyparse(void);
void split_icons(raw_data_t *rd, icon_group_t *icog, int *nico);
void split_cursors(raw_data_t *rd, cursor_group_t *curg, int *ncur);
/* From parser.l */
extern FILE *yyin;
......
......@@ -207,7 +207,7 @@ static struct keyword keywords[] = {
#define NKEYWORDS (sizeof(keywords)/sizeof(keywords[0]))
#define KWP(p) ((struct keyword *)(p))
int kw_cmp_func(const void *s1, const void *s2)
static int kw_cmp_func(const void *s1, const void *s2)
{
int ret;
ret = strcasecmp(KWP(s1)->keyword, KWP(s2)->keyword);
......@@ -219,7 +219,7 @@ int kw_cmp_func(const void *s1, const void *s2)
#define KW_BSEARCH
#define DO_SORT
struct keyword *iskeyword(char *kw)
static struct keyword *iskeyword(char *kw)
{
struct keyword *kwp;
struct keyword key;
......
......@@ -105,6 +105,7 @@
#ifdef HAVE_ALLOCA_H
#include <alloca.h>
#endif
#include <endian.h>
#include "wrc.h"
#include "utils.h"
......@@ -131,8 +132,6 @@ static characts_t *tagstt_characts;
static version_t *tagstt_version;
/* Prototypes of here defined functions */
static int alloc_cursor_id(language_t *);
static int alloc_icon_id(language_t *);
static event_t *get_event_head(event_t *p);
static control_t *get_control_head(control_t *p);
static ver_value_t *get_ver_value_head(ver_value_t *p);
......@@ -2103,7 +2102,6 @@ static raw_data_t *load_file(string_t *name)
rd->data = (char *)xmalloc(rd->size);
fread(rd->data, rd->size, 1, fp);
fclose(fp);
HEAPCHECK();
return rd;
}
......@@ -2117,7 +2115,19 @@ static raw_data_t *int2raw_data(int i)
rd = new_raw_data();
rd->size = sizeof(short);
rd->data = (char *)xmalloc(rd->size);
*(short *)(rd->data) = (short)i;
switch(byteorder)
{
#if BYTE_ORDER == LITTLE_ENDIAN
case WRC_BO_BIG:
#else
case WRC_BO_LITTLE:
#endif
*(WORD *)(rd->data) = BYTESWAP_WORD((WORD)i);
break;
default:
*(WORD *)(rd->data) = (WORD)i;
break;
}
return rd;
}
......@@ -2127,7 +2137,19 @@ static raw_data_t *long2raw_data(int i)
rd = new_raw_data();
rd->size = sizeof(int);
rd->data = (char *)xmalloc(rd->size);
*(int *)(rd->data) = i;
switch(byteorder)
{
#if BYTE_ORDER == LITTLE_ENDIAN
case WRC_BO_BIG:
#else
case WRC_BO_LITTLE:
#endif
*(DWORD *)(rd->data) = BYTESWAP_DWORD((DWORD)i);
break;
default:
*(DWORD *)(rd->data) = (DWORD)i;
break;
}
return rd;
}
......@@ -2137,7 +2159,29 @@ static raw_data_t *str2raw_data(string_t *str)
rd = new_raw_data();
rd->size = str->size * (str->type == str_char ? 1 : 2);
rd->data = (char *)xmalloc(rd->size);
if(str->type == str_char)
memcpy(rd->data, str->str.cstr, rd->size);
else if(str->type == str_unicode)
{
int i;
switch(byteorder)
{
#if BYTE_ORDER == LITTLE_ENDIAN
case WRC_BO_BIG:
#else
case WRC_BO_LITTLE:
#endif
for(i = 0; i < str->size; i++)
*(WORD *)&(rd->data[2*i]) = BYTESWAP_WORD((WORD)str->str.wstr[i]);
break;
default:
for(i = 0; i < str->size; i++)
*(WORD *)&(rd->data[2*i]) = (WORD)str->str.wstr[i];
break;
}
}
else
internal_error(__FILE__, __LINE__, "Invalid stringtype");
return rd;
}
......@@ -2381,165 +2425,6 @@ static resource_t *build_stt_resources(stringtable_t *stthead)
return rsclist;
}
/* Cursor and icon splitter functions */
typedef struct {
language_t lan;
int id;
} id_alloc_t;
static int get_new_id(id_alloc_t **list, int *n, language_t *lan)
{
int i;
assert(lan != NULL);
assert(list != NULL);
assert(n != NULL);
if(!*list)
{
*list = (id_alloc_t *)xmalloc(sizeof(id_alloc_t));
*n = 1;
(*list)[0].lan = *lan;
(*list)[0].id = 1;
return 1;
}
for(i = 0; i < *n; i++)
{
if((*list)[i].lan.id == lan->id && (*list)[i].lan.sub == lan->sub)
return ++((*list)[i].id);
}
*list = (id_alloc_t *)xrealloc(*list, sizeof(id_alloc_t) * (*n+1));
(*list)[*n].lan = *lan;
(*list)[*n].id = 1;
*n += 1;
return 1;
}
static int alloc_icon_id(language_t *lan)
{
static id_alloc_t *idlist = NULL;
static int nid = 0;
return get_new_id(&idlist, &nid, lan);
}
static int alloc_cursor_id(language_t *lan)
{
static id_alloc_t *idlist = NULL;
static int nid = 0;
return get_new_id(&idlist, &nid, lan);
}
#define BPTR(base) ((char *)(rd->data + (base)))
#define WPTR(base) ((WORD *)(rd->data + (base)))
#define DPTR(base) ((DWORD *)(rd->data + (base)))
void split_icons(raw_data_t *rd, icon_group_t *icog, int *nico)
{
int cnt;
int i;
icon_dir_entry_t *ide;
icon_t *ico;
icon_t *list = NULL;
/* FIXME: Distinguish between normal and animated icons (RIFF format) */
if(WPTR(0)[1] != 1)
yyerror("Icon resource data has invalid type id %d", WPTR(0)[1]);
cnt = WPTR(0)[2];
ide = (icon_dir_entry_t *)&(WPTR(0)[3]);
for(i = 0; i < cnt; i++)
{
ico = new_icon();
ico->id = alloc_icon_id(icog->lvc.language);
ico->lvc.language = dup_language(icog->lvc.language);
if(ide[i].offset > rd->size
|| ide[i].offset + ide[i].ressize > rd->size)
yyerror("Icon resource data corrupt");
ico->width = ide[i].width;
ico->height = ide[i].height;
ico->nclr = ide[i].nclr;
ico->planes = ide[i].planes;
ico->bits = ide[i].bits;
if(!ico->planes)
{
/* Argh! They did not fill out the resdir structure */
ico->planes = ((BITMAPINFOHEADER *)BPTR(ide[i].offset))->biPlanes;
}
if(!ico->bits)
{
/* Argh! They did not fill out the resdir structure */
ico->bits = ((BITMAPINFOHEADER *)BPTR(ide[i].offset))->biBitCount;
}
ico->data = new_raw_data();
copy_raw_data(ico->data, rd, ide[i].offset, ide[i].ressize);
if(!list)
{
list = ico;
}
else
{
ico->next = list;
list->prev = ico;
list = ico;
}
}
icog->iconlist = list;
*nico = cnt;
}
void split_cursors(raw_data_t *rd, cursor_group_t *curg, int *ncur)
{
int cnt;
int i;
cursor_dir_entry_t *cde;
cursor_t *cur;
cursor_t *list = NULL;
/* FIXME: Distinguish between normal and animated cursors (RIFF format)*/
if(WPTR(0)[1] != 2)
yyerror("Cursor resource data has invalid type id %d", WPTR(0)[1]);
cnt = WPTR(0)[2];
cde = (cursor_dir_entry_t *)&(WPTR(0)[3]);
for(i = 0; i < cnt; i++)
{
cur = new_cursor();
cur->id = alloc_cursor_id(curg->lvc.language);
cur->lvc.language = dup_language(curg->lvc.language);
if(cde[i].offset > rd->size
|| cde[i].offset + cde[i].ressize > rd->size)
yyerror("Cursor resource data corrupt");
cur->width = cde[i].width;
cur->height = cde[i].height;
cur->nclr = cde[i].nclr;
/* The next two are to support color cursors */
cur->planes = ((BITMAPINFOHEADER *)BPTR(cde[i].offset))->biPlanes;
cur->bits = ((BITMAPINFOHEADER *)BPTR(cde[i].offset))->biBitCount;
if(!win32 && (cur->planes != 1 || cur->bits != 1))
yywarning("Win16 cursor contains colors");
cur->xhot = cde[i].xhot;
cur->yhot = cde[i].yhot;
cur->data = new_raw_data();
copy_raw_data(cur->data, rd, cde[i].offset, cde[i].ressize);
if(!list)
{
list = cur;
}
else
{
cur->next = list;
list->prev = cur;
list = cur;
}
}
curg->cursorlist = list;
*ncur = cnt;
}
#undef BPTR
#undef WPTR
#undef DPTR
static toolbar_item_t *ins_tlbr_button(toolbar_item_t *prev, toolbar_item_t *idrec)
{
......
......@@ -30,7 +30,8 @@ struct resheader32 {
WORD language; /* 0 */
DWORD version; /* 0 */
DWORD characts; /* 0 */
} emptyheader = {0, 0x20, 0xffff, 0, 0xffff, 0, 0, 0, 0, 0, 0};
} emptyheader = {0, 0x20, 0xffff, 0, 0xffff, 0, 0, 0, 0, 0, 0},
emptyheaderSWAPPED = {0, BYTESWAP_DWORD(0x20), 0xffff, 0, 0xffff, 0, 0, 0, 0, 0, 0};
/*
*****************************************************************************
......@@ -135,7 +136,7 @@ enum res_e res_type_from_id(name_id_t *nid)
#define get_word(idx) (*((WORD *)(&res->data[idx])))
#define get_dword(idx) (*((DWORD *)(&res->data[idx])))
resource_t *read_res32(FILE *fp)
static resource_t *read_res32(FILE *fp)
{
static char wrong_format[] = "Wrong resfile format (32bit)";
DWORD ressize;
......@@ -311,7 +312,7 @@ resource_t *read_res32(FILE *fp)
* Remarks :
*****************************************************************************
*/
resource_t *read_res16(FILE *fp)
static resource_t *read_res16(FILE *fp)
{
internal_error(__FILE__, __LINE__, "Can't yet read 16 bit .res files");
return NULL;
......@@ -331,7 +332,7 @@ resource_t *read_resfile(char *inname)
{
FILE *fp;
struct resheader32 rh;
int is32bit;
int is32bit = 1;
resource_t *top;
fp = fopen(inname, "rb");
......@@ -345,6 +346,8 @@ resource_t *read_resfile(char *inname)
{
if(!memcmp(&emptyheader, &rh, sizeof(rh)))
is32bit = 1;
else if(!memcmp(&emptyheaderSWAPPED, &rh, sizeof(rh)))
error("Binary .res-file has its byteorder swapped");
else
is32bit = 0;
}
......
......@@ -42,6 +42,7 @@
#include <assert.h>
#include <ctype.h>
#include <signal.h>
#include <endian.h>
#include "wrc.h"
#include "utils.h"
......@@ -53,10 +54,28 @@
#include "preproc.h"
#include "parser.h"
char usage[] = "Usage: wrc [options...] [infile[.rc|.res]]\n"
#ifndef BYTE_ORDER
# error BYTE_ORDER is not defined. Please report.
#endif
#if (!defined(BIG_ENDIAN) && !defined(LITTLE_ENDIAN)) || (BYTE_ORDER != BIG_ENDIAN && BYTE_ORDER != LITTLE_ENDIAN)
# error Neither BIG_ENDIAN nor LITTLE_ENDIAN system. This system is not supported. Please report.
#endif
static char usage[] =
"Usage: wrc [options...] [infile[.rc|.res]]\n"
" -a n Alignment of resource (win16 only, default is 4)\n"
" -A Auto register resources (only with gcc 2.7 and better)\n"
" -b Create a C array from a binary .res file\n"
" -b Create an assembly array from a binary .res file\n"
" -B x Set output byte-order x={n[ative], l[ittle], b[ig]}\n"
" (win32 only; default is n[ative] which equals "
#if BYTE_ORDER == BIG_ENDIAN
"big"
#else
"little"
#endif
"-endian)\n"
" -c Add 'const' prefix to C constants\n"
" -C cp Set the resource's codepage to cp (default is 0)\n"
" -d n Set debug level to 'n'\n"
......@@ -210,6 +229,11 @@ int auto_register = 0;
int leave_case = 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;
......@@ -265,7 +289,7 @@ int main(int argc,char *argv[])
strcat(cmdline, " ");
}
while((optc = getopt(argc, argv, "a:AbcC:d:D:eEghH:I:l:LnNo:p:rstTVw:W")) != EOF)
while((optc = getopt(argc, argv, "a:AbB:cC:d:D:eEghH:I:l:LnNo:p:rstTVw:W")) != EOF)
{
switch(optc)
{
......@@ -278,6 +302,26 @@ int main(int argc,char *argv[])
case 'b':
binary = 1;
break;
case 'B':
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:
fprintf(stderr, "Byteordering must be n[ative], l[ittle] or b[ig]\n");
lose++;
}
break;
case 'c':
constant = 1;
break;
......@@ -428,6 +472,12 @@ int main(int argc,char *argv[])
}
}
if(byteorder != WRC_BO_NATIVE)
{
if(binary)
error("Forced byteordering not supported for binary resources\n");
}
if(preprocess_only)
{
if(constant)
......
......@@ -16,16 +16,14 @@
#define WRC_MAJOR_VERSION 1
#define WRC_MINOR_VERSION 1
#define WRC_MICRO_VERSION 0
#define WRC_RELEASEDATE "(01-May-2000)"
#define WRC_MICRO_VERSION 2
#define WRC_RELEASEDATE "(08-May-2000)"
#define WRC_STRINGIZE(a) #a
#define WRC_VERSIONIZE(a,b,c) WRC_STRINGIZE(a) "." WRC_STRINGIZE(b) "." WRC_STRINGIZE(c)
#define WRC_VERSION WRC_VERSIONIZE(WRC_MAJOR_VERSION, WRC_MINOR_VERSION, WRC_MICRO_VERSION)
#define WRC_FULLVERSION WRC_VERSION " " WRC_RELEASEDATE
/* Only used in heavy debugging sessions */
#define HEAPCHECK()
/* From wrc.c */
extern int debuglevel;
......@@ -54,6 +52,7 @@ extern DWORD codepage;
extern int pedantic;
extern int auto_register;
extern int leave_case;
extern int byteorder;
extern int preprocess_only;
extern int no_preprocess;
......
.TH WRC 1 "May 8, 2000" "Version 1.1.2" "Wine Resource Compiler"
.SH NAME
wrc \- Wine Resource Compiler
.SH SYNOPSIS
.BI "wrc " "[options] " "[inputfile]"
.SH DESCRIPTION
.B wrc
compiles resources from
.I inputfile
into win16 and win32 compatible
binary format.
.B wrc
outputs the binary data either in a standard \fB.res\fR formatted binary
file, or an assembly file.
.B wrc
is also capable of reading \fB.res\fR formatted files and convert them
into an assembly file.
.PP
The source\-file is preprocessed with a builtin ANSI\-C compatible
preprocessor before the resources are compiled. See \fBPREPROCESSOR\fR
below.
.PP
.B wrc
takes only one \fBinputfile\fR as argument. The \fBinputfile\fR has
extension \fB.rc\fR for resources in source form and \fB.res\fR for
binary resources. The resources are read from standard input if no
inputfile is given. If the outputfile is not specified with \fI-o\fR,
then \fBwrc\fR will write the output to \fBinputfile.{s,h,res}\fR
with \fB.rc\fR stripped, depending on the mode of compilation.
The outputfile is named \fBwrc.tab.{s,h,res}\fR if no inputfile was
given.
.SH OPTIONS
.TP
.I \-a n
Win16 only; set the alignment between resources n. The alignment must
be a power of 2. The default is 4.
.TP
.I \-A
Obsolete; include code in the assembly output to auto register resources
by calling a special wine function (only with gcc 2.7 and better).
.TP
.I \-b
Create an assembly file from a binary \fB.res\fR file.
.TP
.I \-B x
Win32 only; set output byte\-ordering, where \fIx\fR is one of n[ative],
l[ittle] or b[ig]. Only resource in source-form can be reorderd. Native
ordering depends on the system on which \fBwrc\fR was built. You can see
the native ordering by typing \fI\"wrc \-?\"\fR.
.TP
.I \-c
Add 'const' prefix to C constants when writing header files.
.TP
.I \-C cp
Set the resource's codepage to \fIcp\fR. Default codepage is 0.
.TP
.I \-d n
Set debug level to \fIn\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 \-D id[=val]
Define preprocessor identifier \fIid\fR to (optionally) value \fIval\fR.
See also
.B PREPROCESSOR
below.
.TP
.I \-e
Win16 only; disable recognition of win32 keywords in 16bit compile.
Normally, all keywords are recognized in win16 compilation mode. Use
this switch if old sources use win32 reserved names as resource names.
.TP
.I \-E
Preprocess only. The output is written to standard output if no
outputfile was selected. The output is compatible with what gcc would
generate.
.TP
.I \-g
Add symbols to the global C namespace. This makes all symbols available
for linking by other modules.
.TP
.I \-h
Generate a \fB.h\fR header-file. The resource tables are described by
extern declarations.
.TP
.I \-H file
Same as \fI\-h\fR but written to \fIfile\fR.
.TP
.I \-I path
Add \fIpath\fR to include search directories. \fIPath\fR may contain
multiple directories, separated with ':'. It is allowed to specify
\fI\-I\fR multiple times. Include files are searched in the order in
with the \fI\-I\fR options were specified.
.br
The search is compatible with gcc, in which '<>' quoted filenames are
searched exclusively via the \fI\-I\fR set path, whereas the '""' quoted
filenames are first tried to be opened in the current directory. Also
resource statements with file references are located in the same way.
.TP
.I \-l lan
Set default language to \fIlan\fR. Default is the neutral language 0
(i.e. "LANGUAGE 0, 0").
.TP
.I \-L
Leave case of embedded filenames as is. All filenames are converted to
lower case before they are attemped to be opened without this option.
.TP
.I \-n
Do not generate an assembly outputfile (suppress generation of \fB.s\fR
file). Usefull if you are interested in a header file only.
.TP
.I \-N
Do not preprocess the input. This will most certainly result in
compilation failure, unless you have preprocessed the source with
another preprocessor before passing it to \fBwrc\fR.
.TP
.I \-o file
Write output to \fIfile\fR. Default is \fBinputfile.{res,s,h}\fR
with \fB.rc\fR stripped or \fBwrc.tab.{s,h,res}\fR, depending on the
compilation mode.
.TP
.I \-p prefix
Prefix all generated names with \fIprefix\fR. This is only relevant for
names in the assembly code and header file. Resource names are not
affected.
.TP
.I \-r
Create binary \fB.res\fR file (compile only).
.TP
.I \-s
Add structure with win32/16 (PE/NE) resource directory to outputfile.
This directory is always in native byteorder.
.TP
.I \-t
Obsolete; generate indirect loadable resource tables.
.TP
.I \-T
Obsolete; generate only indirect loadable resources tables.
.TP
.I \-V
Print version end exit.
.TP
.I \-w 16|32
Select win16 or win32 output. Default is win32.
.TP
.I \-W
Enable pedantic warnings. Notably redefinition of #define statements can
be discovered with this option.
.SH PREPROCESSOR
The preprocessor is ANSI\-C compatible with some extensions of the gcc
preprocessor.
.PP
The preprocessor recognizes these directives: #include, #define (both
simple and macro), #undef, #if, #ifdef, #ifndef, #elif, #else, #endif,
#error, #warning, #line, # (both null\- and line\-directive), #pragma
(ignored), #ident (ignored).
.PP
The preprocessor default sets several defines:
.br
RC_INVOKED set to 1
.br
__WRC__ Major version of wrc
.br
__WRC_MINOR__ Minor version of wrc
.br
__WRC_MICRO__ Patch level
.br
__WRC_PATCH__ Same as __WRC_MICRO__
.PP
Win32 compilation mode also sets __WIN32__ to 1 and __FLAT__ to 1.
.PP
Special macros __FILE__, __LINE__, __TIME__ and __DATE__ are also
recognized and expand to their respective equivalent.
.SH AUTHORS
.B wrc
was written by Bertho A. Stultiens and is a nearly complete rewrite of
the first wine resource compiler (1994) by Martin von Loewis.
Additional resource\-types were contributed Ulrich Czekalla and Albert
den Haan. Bugfixes have been contributed by many wine developpers.
.SH BUGS
\- The preprocessor recognizes variable argument macros, but does not
expanded them correctly.
.br
\- Codepage/UNICODE translations are not/not correct implemented.
.br
\- Default memory options should differ between win16 and win32.
.PP
\- There is no support for:
.br
\- MESSAGETABLE (parsed, but not generated).
.br
\- FONT (parsed, but not generated).
.br
\- RT_VXD and RT_PLUGPLAY (unknown format)
.br
\- Animated cursors and icons (RIFF format unknown).
.SH AVAILABILITY
.B wrc
is part of the wine distribution, which is available through
WineHQ, the
.B wine
development headquarters, at
.I http://www.winehq.com/.
.SH "SEE ALSO"
.BR wine (1),
......@@ -55,6 +55,17 @@
#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)))))
/* Binary resource structure */
#define RES_BLOCKSIZE 512
......@@ -281,6 +292,15 @@ typedef struct font {
raw_data_t *data;
} font_t;
/*
* Icon resources
*/
typedef struct icon_header {
WORD reserved; /* Don't know, should be 0 I guess */
WORD type; /* Always 1 for icons */
WORD count; /* Number of packed icons in resource */
} icon_header_t;
typedef struct icon_dir_entry {
BYTE width; /* From the SDK doc. */
BYTE height;
......@@ -312,6 +332,15 @@ typedef struct icon_group {
int nicon;
} icon_group_t;
/*
* Cursor resources
*/
typedef struct cursor_header {
WORD reserved; /* Don't know, should be 0 I guess */
WORD type; /* Always 2 for cursors */
WORD count; /* Number of packed cursors in resource */
} cursor_header_t;
typedef struct cursor_dir_entry {
BYTE width; /* From the SDK doc. */
BYTE height;
......
......@@ -24,7 +24,7 @@ char Underscore[] = "_";
char Underscore[] = "";
#endif
char s_file_head_str[] =
static char s_file_head_str[] =
"/* This file is generated with wrc version " WRC_FULLVERSION ". Do not edit! */\n"
"/* Source : %s */\n"
"/* Cmdline: %s */\n"
......@@ -34,12 +34,12 @@ char s_file_head_str[] =
"\n"
;
char s_file_tail_str[] =
static char s_file_tail_str[] =
"/* <eof> */\n"
"\n"
;
char s_file_autoreg_str[] =
static char s_file_autoreg_str[] =
"\t.text\n"
".LAuto_Register:\n"
"\tpushl\t$%s%s\n"
......@@ -58,7 +58,7 @@ char s_file_autoreg_str[] =
#endif
;
char h_file_head_str[] =
static char h_file_head_str[] =
"/*\n"
" * This file is generated with wrc version " WRC_FULLVERSION ". Do not edit!\n"
" * Source : %s\n"
......@@ -73,7 +73,7 @@ char h_file_head_str[] =
"\n"
;
char h_file_tail_str[] =
static char h_file_tail_str[] =
"#endif\n"
"/* <eof> */\n\n"
;
......@@ -174,7 +174,7 @@ void write_resfile(char *outname, resource_t *top)
*****************************************************************************
*/
#define BYTESPERLINE 8
void write_s_res(FILE *fp, res_t *res)
static void write_s_res(FILE *fp, res_t *res)
{
int idx = res->dataidx;
int end = res->size;
......@@ -203,6 +203,7 @@ void write_s_res(FILE *fp, res_t *res)
fprintf(fp, "\n");
}
}
#undef BYTESPERLINE
/*
*****************************************************************************
......@@ -214,7 +215,7 @@ void write_s_res(FILE *fp, res_t *res)
* Remarks : One level self recursive for string type conversion
*****************************************************************************
*/
void write_name_str(FILE *fp, name_id_t *nid)
static void write_name_str(FILE *fp, name_id_t *nid)
{
res_t res;
assert(nid->type == name_str);
......@@ -229,7 +230,7 @@ void write_name_str(FILE *fp, name_id_t *nid)
res.dataidx = 0;
res.data = (char *)xmalloc(res.size + 1);
res.data[0] = (char)res.size;
res.size++; /* We need to write the lenth byte as well */
res.size++; /* We need to write the length byte as well */
strcpy(res.data+1, nid->name.s_name->str.cstr);
write_s_res(fp, &res);
free(res.data);
......@@ -291,7 +292,7 @@ void write_name_str(FILE *fp, name_id_t *nid)
* Remarks :
*****************************************************************************
*/
int compare_name_id(name_id_t *n1, name_id_t *n2)
static int compare_name_id(name_id_t *n1, name_id_t *n2)
{
if(n1->type == name_ord && n2->type == name_ord)
{
......@@ -335,7 +336,7 @@ int compare_name_id(name_id_t *n1, name_id_t *n2)
* Remarks :
*****************************************************************************
*/
res_count_t *find_counter(name_id_t *type)
static res_count_t *find_counter(name_id_t *type)
{
int i;
for(i = 0; i < rccount; i++)
......@@ -362,12 +363,12 @@ res_count_t *find_counter(name_id_t *type)
*/
#define RCT(v) (*((resource_t **)(v)))
/* qsort sorting function */
int sort_name_id(const void *e1, const void *e2)
static int sort_name_id(const void *e1, const void *e2)
{
return compare_name_id(RCT(e1)->name, RCT(e2)->name);
}
int sort_language(const void *e1, const void *e2)
static int sort_language(const void *e1, const void *e2)
{
assert((RCT(e1)->lan) != NULL);
assert((RCT(e2)->lan) != NULL);
......@@ -377,13 +378,13 @@ int sort_language(const void *e1, const void *e2)
}
#undef RCT
#define RCT(v) ((res_count_t *)(v))
int sort_type(const void *e1, const void *e2)
static int sort_type(const void *e1, const void *e2)
{
return compare_name_id(&(RCT(e1)->type), &(RCT(e2)->type));
}
#undef RCT
void count_resources(resource_t *top)
static void count_resources(resource_t *top)
{
resource_t *rsc;
res_count_t *rcp;
......@@ -560,7 +561,7 @@ void count_resources(resource_t *top)
* Remarks :
*****************************************************************************
*/
void write_pe_segment(FILE *fp, resource_t *top)
static void write_pe_segment(FILE *fp, resource_t *top)
{
int i;
......@@ -760,7 +761,7 @@ void write_pe_segment(FILE *fp, resource_t *top)
* Remarks :
*****************************************************************************
*/
void write_ne_segment(FILE *fp, resource_t *top)
static void write_ne_segment(FILE *fp, resource_t *top)
{
int i, j;
......@@ -839,7 +840,7 @@ void write_ne_segment(FILE *fp, resource_t *top)
* Remarks :
*****************************************************************************
*/
void write_rsc_names(FILE *fp, resource_t *top)
static void write_rsc_names(FILE *fp, resource_t *top)
{
int i, j;
......@@ -1177,4 +1178,3 @@ void write_h_file(char *outname, resource_t *top)
fclose(fo);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment