- 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.
diff --git a/tools/wrc/CHANGES b/tools/wrc/CHANGES
index 6b7b648..ec35e5c 100644
--- a/tools/wrc/CHANGES
+++ b/tools/wrc/CHANGES
@@ -1,4 +1,31 @@
---------------------------------------------------------------------------
+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>
diff --git a/tools/wrc/Makefile.in b/tools/wrc/Makefile.in
index 8fd50bf..a17cd4f 100644
--- a/tools/wrc/Makefile.in
+++ b/tools/wrc/Makefile.in
@@ -46,4 +46,13 @@
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:
diff --git a/tools/wrc/README.wrc b/tools/wrc/README.wrc
index 30bc0e2..3b2d7aa 100644
--- a/tools/wrc/README.wrc
+++ b/tools/wrc/README.wrc
@@ -1,4 +1,4 @@
-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 @@
- 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 @@
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 @@
- 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
--------------------------
diff --git a/tools/wrc/dumpres.c b/tools/wrc/dumpres.c
index 70b7a37..32b93e7 100644
--- a/tools/wrc/dumpres.c
+++ b/tools/wrc/dumpres.c
@@ -152,7 +152,7 @@
* Remarks :
*****************************************************************************
*/
-void dump_memopt(DWORD memopt)
+static void dump_memopt(DWORD memopt)
{
printf("Memory/load options: ");
if(memopt & 0x0040)
@@ -183,7 +183,7 @@
* 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 @@
* 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 @@
* Remarks :
*****************************************************************************
*/
-void dump_accelerator(accelerator_t *acc)
+static void dump_accelerator(accelerator_t *acc)
{
event_t *ev = acc->events;
@@ -297,7 +297,7 @@
* 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 @@
* 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 @@
* 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 @@
* 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 @@
* 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 @@
* 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 @@
* 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 @@
* 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 @@
* Remarks :
*****************************************************************************
*/
-void dump_messagetable(messagetable_t *msg)
+static void dump_messagetable(messagetable_t *msg)
{
dump_raw_data(msg->data);
}
@@ -459,7 +459,7 @@
* 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 @@
* 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 @@
* Remarks :
*****************************************************************************
*/
-void dump_dialog(dialog_t *dlg)
+static void dump_dialog(dialog_t *dlg)
{
control_t *c = dlg->controls;
@@ -580,7 +580,7 @@
* Remarks :
*****************************************************************************
*/
-void dump_dialogex(dialogex_t *dlgex)
+static void dump_dialogex(dialogex_t *dlgex)
{
control_t *c = dlgex->controls;
@@ -630,7 +630,7 @@
* Remarks :
*****************************************************************************
*/
-void dump_menu_item(menu_item_t *item)
+static void dump_menu_item(menu_item_t *item)
{
while(item)
{
@@ -668,7 +668,7 @@
* 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 @@
* Remarks :
*****************************************************************************
*/
-void dump_menuex_item(menuex_item_t *item)
+static void dump_menuex_item(menuex_item_t *item)
{
while(item)
{
@@ -738,7 +738,7 @@
* 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 @@
* 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 @@
* 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 @@
* Remarks :
*****************************************************************************
*/
-void dump_versioninfo(versioninfo_t *ver)
+static void dump_versioninfo(versioninfo_t *ver)
{
ver_block_t *blk = ver->blocks;
@@ -859,7 +860,7 @@
* Remarks :
*****************************************************************************
*/
-void dump_toolbar_items(toolbar_item_t *items)
+static void dump_toolbar_items(toolbar_item_t *items)
{
while(items)
{
@@ -885,7 +886,7 @@
* 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 @@
* Remarks :
*****************************************************************************
*/
-void dump_dlginit(dlginit_t *dit)
+static void dump_dlginit(dlginit_t *dit)
{
dump_memopt(dit->memopt);
dump_lvc(&(dit->lvc));
diff --git a/tools/wrc/genres.c b/tools/wrc/genres.c
index 0d527a3..8091021 100644
--- a/tools/wrc/genres.c
+++ b/tools/wrc/genres.c
@@ -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 @@
{
if(res->allocsize - res->size < sizeof(WORD))
grow_res(res, RES_BLOCKSIZE);
- *(WORD *)&(res->data[res->size]) = (WORD)w;
+ 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 @@
{
if(res->allocsize - res->size < sizeof(DWORD))
grow_res(res, RES_BLOCKSIZE);
- *(DWORD *)&(res->data[res->size]) = (DWORD)d;
+ 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 @@
/*
*****************************************************************************
+ * 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 @@
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 @@
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 @@
* 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 @@
* 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 @@
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 @@
* 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 @@
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 @@
* 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 @@
* 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 @@
* 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 @@
* 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 @@
* 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 @@
* Remarks :
*****************************************************************************
*/
-res_t *cursor2res(cursor_t *cur)
+static res_t *cursor2res(cursor_t *cur)
{
int restag;
res_t *res;
@@ -980,7 +1102,7 @@
* 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 @@
* Remarks :
*****************************************************************************
*/
-res_t *icon2res(icon_t *ico)
+static res_t *icon2res(icon_t *ico)
{
int restag;
res_t *res;
@@ -1078,21 +1200,19 @@
* 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 @@
{
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 @@
* 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 @@
* 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 @@
* 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 @@
* 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 @@
* 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 @@
* 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 @@
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 @@
{
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 @@
}
/* Set blocksize */
- *(WORD *)&(res->data[blksizetag]) = (WORD)(res->size - blksizetag);
+ set_word(res, blksizetag, (WORD)(res->size - blksizetag));
}
/*
@@ -1370,7 +1487,7 @@
* 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 @@
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 @@
* 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 @@
* 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 @@
* 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;
diff --git a/tools/wrc/newstruc.c b/tools/wrc/newstruc.c
index 0e4d1f9..1120a67 100644
--- a/tools/wrc/newstruc.c
+++ b/tools/wrc/newstruc.c
@@ -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 @@
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 @@
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 @@
}
else
bmp->memopt = WRC_MO_MOVEABLE | WRC_MO_PURE;
+ rd->size -= convert_bitmap(rd->data, rd->size);
return bmp;
}
diff --git a/tools/wrc/parser.h b/tools/wrc/parser.h
index 494362c..53de131 100644
--- a/tools/wrc/parser.h
+++ b/tools/wrc/parser.h
@@ -12,8 +12,6 @@
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;
diff --git a/tools/wrc/parser.l b/tools/wrc/parser.l
index 99fd275..b395330 100644
--- a/tools/wrc/parser.l
+++ b/tools/wrc/parser.l
@@ -207,7 +207,7 @@
#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 @@
#define KW_BSEARCH
#define DO_SORT
-struct keyword *iskeyword(char *kw)
+static struct keyword *iskeyword(char *kw)
{
struct keyword *kwp;
struct keyword key;
diff --git a/tools/wrc/parser.y b/tools/wrc/parser.y
index a79c40f..dcf61b7 100644
--- a/tools/wrc/parser.y
+++ b/tools/wrc/parser.y
@@ -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 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 @@
rd->data = (char *)xmalloc(rd->size);
fread(rd->data, rd->size, 1, fp);
fclose(fp);
- HEAPCHECK();
return rd;
}
@@ -2117,7 +2115,19 @@
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 @@
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 @@
rd = new_raw_data();
rd->size = str->size * (str->type == str_char ? 1 : 2);
rd->data = (char *)xmalloc(rd->size);
- memcpy(rd->data, str->str.cstr, 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 @@
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)
{
diff --git a/tools/wrc/readres.c b/tools/wrc/readres.c
index 776c659..d57c42f 100644
--- a/tools/wrc/readres.c
+++ b/tools/wrc/readres.c
@@ -30,7 +30,8 @@
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 @@
#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 @@
* 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 @@
{
FILE *fp;
struct resheader32 rh;
- int is32bit;
+ int is32bit = 1;
resource_t *top;
fp = fopen(inname, "rb");
@@ -345,6 +346,8 @@
{
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;
}
diff --git a/tools/wrc/wrc.c b/tools/wrc/wrc.c
index 77bf932..7d1bb12 100644
--- a/tools/wrc/wrc.c
+++ b/tools/wrc/wrc.c
@@ -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 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 @@
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 @@
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 @@
}
}
+ if(byteorder != WRC_BO_NATIVE)
+ {
+ if(binary)
+ error("Forced byteordering not supported for binary resources\n");
+ }
+
if(preprocess_only)
{
if(constant)
diff --git a/tools/wrc/wrc.h b/tools/wrc/wrc.h
index a789645..0297903 100644
--- a/tools/wrc/wrc.h
+++ b/tools/wrc/wrc.h
@@ -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 int pedantic;
extern int auto_register;
extern int leave_case;
+extern int byteorder;
extern int preprocess_only;
extern int no_preprocess;
diff --git a/tools/wrc/wrc.man b/tools/wrc/wrc.man
new file mode 100644
index 0000000..a15d573
--- /dev/null
+++ b/tools/wrc/wrc.man
@@ -0,0 +1,205 @@
+.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),
diff --git a/tools/wrc/wrctypes.h b/tools/wrc/wrctypes.h
index 73c8d03..53151ba 100644
--- a/tools/wrc/wrctypes.h
+++ b/tools/wrc/wrctypes.h
@@ -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 @@
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 @@
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;
diff --git a/tools/wrc/writeres.c b/tools/wrc/writeres.c
index f0874ee..4ff255a 100644
--- a/tools/wrc/writeres.c
+++ b/tools/wrc/writeres.c
@@ -24,7 +24,7 @@
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 @@
"\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 @@
#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 @@
"\n"
;
-char h_file_tail_str[] =
+static char h_file_tail_str[] =
"#endif\n"
"/* <eof> */\n\n"
;
@@ -174,7 +174,7 @@
*****************************************************************************
*/
#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 @@
fprintf(fp, "\n");
}
}
+#undef BYTESPERLINE
/*
*****************************************************************************
@@ -214,7 +215,7 @@
* 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 @@
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 @@
* 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 @@
* 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 @@
*/
#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 @@
}
#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 @@
* 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 @@
* 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 @@
* 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 @@
fclose(fo);
}
-