diff options
Diffstat (limited to 'contrib/binutils/binutils/resrc.c')
| -rw-r--r-- | contrib/binutils/binutils/resrc.c | 2260 | 
1 files changed, 0 insertions, 2260 deletions
diff --git a/contrib/binutils/binutils/resrc.c b/contrib/binutils/binutils/resrc.c deleted file mode 100644 index a836780107ca..000000000000 --- a/contrib/binutils/binutils/resrc.c +++ /dev/null @@ -1,2260 +0,0 @@ -/* resrc.c -- read and write Windows rc files. -   Copyright 1997, 1998 Free Software Foundation, Inc. -   Written by Ian Lance Taylor, Cygnus Support. - -   This file is part of GNU Binutils. - -   This program is free software; you can redistribute it and/or modify -   it under the terms of the GNU General Public License as published by -   the Free Software Foundation; either version 2 of the License, or -   (at your option) any later version. - -   This program is distributed in the hope that it will be useful, -   but WITHOUT ANY WARRANTY; without even the implied warranty of -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -   GNU General Public License for more details. - -   You should have received a copy of the GNU General Public License -   along with this program; if not, write to the Free Software -   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -   02111-1307, USA.  */ - -/* This file contains functions that read and write Windows rc files. -   These are text files that represent resources.  */ - -#include "bfd.h" -#include "bucomm.h" -#include "libiberty.h" -#include "windres.h" - -#include <assert.h> -#include <ctype.h> -#include <sys/stat.h> - -#if defined (_WIN32) && ! defined (__CYGWIN32__) -#define popen _popen -#define pclose _pclose -#endif - -/* The default preprocessor.  */ - -#define DEFAULT_PREPROCESSOR "gcc -E -xc-header -DRC_INVOKED" - -/* We read the directory entries in a cursor or icon file into -   instances of this structure.  */ - -struct icondir -{ -  /* Width of image.  */ -  unsigned char width; -  /* Height of image.  */ -  unsigned char height; -  /* Number of colors in image.  */ -  unsigned char colorcount; -  union -  { -    struct -    { -      /* Color planes.  */ -      unsigned short planes; -      /* Bits per pixel.  */ -      unsigned short bits; -    } icon; -    struct -    { -      /* X coordinate of hotspot.  */ -      unsigned short xhotspot; -      /* Y coordinate of hotspot.  */ -      unsigned short yhotspot; -    } cursor; -  } u; -  /* Bytes in image.  */ -  unsigned long bytes; -  /* File offset of image.  */ -  unsigned long offset; -}; - -/* The name of the rc file we are reading.  */ - -char *rc_filename; - -/* The line number in the rc file.  */ - -int rc_lineno; - -/* The pipe we are reading from, so that we can close it if we exit.  */ - -static FILE *cpp_pipe; - -/* As we read the rc file, we attach information to this structure.  */ - -static struct res_directory *resources; - -/* The number of cursor resources we have written out.  */ - -static int cursors; - -/* The number of font resources we have written out.  */ - -static int fonts; - -/* Font directory information.  */ - -struct fontdir *fontdirs; - -/* Resource info to use for fontdirs.  */ - -struct res_res_info fontdirs_resinfo; - -/* The number of icon resources we have written out.  */ - -static int icons; - -/* Local functions.  */ - -static void close_pipe PARAMS ((void)); -static void unexpected_eof PARAMS ((const char *)); -static int get_word PARAMS ((FILE *, const char *)); -static unsigned long get_long PARAMS ((FILE *, const char *)); -static void get_data -  PARAMS ((FILE *, unsigned char *, unsigned long, const char *)); -static void define_fontdirs PARAMS ((void)); - -/* Read an rc file.  */ - -struct res_directory * -read_rc_file (filename, preprocessor, preprocargs, language) -     const char *filename; -     const char *preprocessor; -     const char *preprocargs; -     int language; -{ -  char *cmd; - -  if (preprocessor == NULL) -    preprocessor = DEFAULT_PREPROCESSOR; - -  if (preprocargs == NULL) -    preprocargs = ""; -  if (filename == NULL) -    filename = "-"; - -  cmd = xmalloc (strlen (preprocessor) -		 + strlen (preprocargs) -		 + strlen (filename) -		 + 10); -  sprintf (cmd, "%s %s %s", preprocessor, preprocargs, filename); - -  cpp_pipe = popen (cmd, FOPEN_RT); -  if (cpp_pipe == NULL) -    fatal ("can't popen `%s': %s", cmd, strerror (errno)); -  free (cmd); - -  xatexit (close_pipe); - -  rc_filename = xstrdup (filename); -  rc_lineno = 1; -  if (language != -1) -    rcparse_set_language (language); -  yyin = cpp_pipe; -  yyparse (); - -  if (pclose (cpp_pipe) != 0) -    fprintf (stderr, "%s: warning: preprocessor failed\n", program_name); -  cpp_pipe = NULL; - -  if (fontdirs != NULL) -    define_fontdirs (); - -  free (rc_filename); -  rc_filename = NULL; - -  return resources; -} - -/* Close the pipe if it is open.  This is called via xatexit.  */ - -void -close_pipe () -{ -  if (cpp_pipe != NULL) -    pclose (cpp_pipe); -} - -/* Report an error while reading an rc file.  */ - -void -yyerror (msg) -     const char *msg; -{ -  fatal ("%s:%d: %s", rc_filename, rc_lineno, msg); -} - -/* Issue a warning while reading an rc file.  */ - -void -rcparse_warning (msg) -     const char *msg; -{ -  fprintf (stderr, "%s:%d: %s\n", rc_filename, rc_lineno, msg); -} - -/* Die if we get an unexpected end of file.  */ - -static void -unexpected_eof (msg) -     const char *msg; -{ -  fatal ("%s: unexpected EOF", msg); -} - -/* Read a 16 bit word from a file.  The data is assumed to be little -   endian.  */ - -static int -get_word (e, msg) -     FILE *e; -     const char *msg; -{ -  int b1, b2; - -  b1 = getc (e); -  b2 = getc (e); -  if (feof (e)) -    unexpected_eof (msg); -  return ((b2 & 0xff) << 8) | (b1 & 0xff); -} - -/* Read a 32 bit word from a file.  The data is assumed to be little -   endian.  */ - -static unsigned long -get_long (e, msg) -     FILE *e; -     const char *msg; -{ -  int b1, b2, b3, b4; - -  b1 = getc (e); -  b2 = getc (e); -  b3 = getc (e); -  b4 = getc (e); -  if (feof (e)) -    unexpected_eof (msg); -  return (((((((b4 & 0xff) << 8) -	      | (b3 & 0xff)) << 8) -	    | (b2 & 0xff)) << 8) -	  | (b1 & 0xff)); -} - -/* Read data from a file.  This is a wrapper to do error checking.  */ - -static void -get_data (e, p, c, msg) -     FILE *e; -     unsigned char *p; -     unsigned long c; -     const char *msg; -{ -  unsigned long got; - -  got = fread (p, 1, c, e); -  if (got == c) -    return; - -  fatal ("%s: read of %lu returned %lu", msg, c, got); -} - -/* Define an accelerator resource.  */ - -void -define_accelerator (id, resinfo, data) -     struct res_id id; -     const struct res_res_info *resinfo; -     struct accelerator *data; -{ -  struct res_resource *r; - -  r = define_standard_resource (&resources, RT_ACCELERATORS, id, -				resinfo->language, 0); -  r->type = RES_TYPE_ACCELERATOR; -  r->u.acc = data; -  r->res_info = *resinfo; -} - -/* Define a bitmap resource.  Bitmap data is stored in a file.  The -   first 14 bytes of the file are a standard header, which is not -   included in the resource data.  */ - -#define BITMAP_SKIP (14) - -void -define_bitmap (id, resinfo, filename) -     struct res_id id; -     const struct res_res_info *resinfo; -     const char *filename; -{ -  FILE *e; -  char *real_filename; -  struct stat s; -  unsigned char *data; -  int i; -  struct res_resource *r; - -  e = open_file_search (filename, FOPEN_RB, "bitmap file", &real_filename); - -  if (stat (real_filename, &s) < 0) -    fatal ("stat failed on bitmap file `%s': %s", real_filename, -	   strerror (errno)); - -  data = (unsigned char *) res_alloc (s.st_size - BITMAP_SKIP); - -  for (i = 0; i < BITMAP_SKIP; i++) -    getc (e); - -  get_data (e, data, s.st_size - BITMAP_SKIP, real_filename); - -  fclose (e); -  free (real_filename); - -  r = define_standard_resource (&resources, RT_BITMAP, id, -				resinfo->language, 0); - -  r->type = RES_TYPE_BITMAP; -  r->u.data.length = s.st_size - BITMAP_SKIP; -  r->u.data.data = data; -  r->res_info = *resinfo; -} - -/* Define a cursor resource.  A cursor file may contain a set of -   bitmaps, each representing the same cursor at various different -   resolutions.  They each get written out with a different ID.  The -   real cursor resource is then a group resource which can be used to -   select one of the actual cursors.  */ - -void -define_cursor (id, resinfo, filename) -     struct res_id id; -     const struct res_res_info *resinfo; -     const char *filename; -{ -  FILE *e; -  char *real_filename; -  int type, count, i; -  struct icondir *icondirs; -  int first_cursor; -  struct res_resource *r; -  struct group_cursor *first, **pp; - -  e = open_file_search (filename, FOPEN_RB, "cursor file", &real_filename); - -  /* A cursor file is basically an icon file.  The start of the file -     is a three word structure.  The first word is ignored.  The -     second word is the type of data.  The third word is the number of -     entries.  */ - -  get_word (e, real_filename); -  type = get_word (e, real_filename); -  count = get_word (e, real_filename); -  if (type != 2) -    fatal ("cursor file `%s' does not contain cursor data", real_filename); - -  /* Read in the icon directory entries.  */ - -  icondirs = (struct icondir *) xmalloc (count * sizeof *icondirs); - -  for (i = 0; i < count; i++) -    { -      icondirs[i].width = getc (e); -      icondirs[i].height = getc (e); -      icondirs[i].colorcount = getc (e); -      getc (e); -      icondirs[i].u.cursor.xhotspot = get_word (e, real_filename); -      icondirs[i].u.cursor.yhotspot = get_word (e, real_filename); -      icondirs[i].bytes = get_long (e, real_filename); -      icondirs[i].offset = get_long (e, real_filename); - -      if (feof (e)) -	unexpected_eof (real_filename); -    } - -  /* Define each cursor as a unique resource.  */ - -  first_cursor = cursors; - -  for (i = 0; i < count; i++) -    { -      unsigned char *data; -      struct res_id name; -      struct cursor *c; - -      if (fseek (e, icondirs[i].offset, SEEK_SET) != 0) -	fatal ("%s: fseek to %lu failed: %s", real_filename, -	       icondirs[i].offset, strerror (errno)); - -      data = (unsigned char *) res_alloc (icondirs[i].bytes); - -      get_data (e, data, icondirs[i].bytes, real_filename); - -      c = (struct cursor *) res_alloc (sizeof *c); -      c->xhotspot = icondirs[i].u.cursor.xhotspot; -      c->yhotspot = icondirs[i].u.cursor.yhotspot; -      c->length = icondirs[i].bytes; -      c->data = data; - -      ++cursors; - -      name.named = 0; -      name.u.id = cursors; - -      r = define_standard_resource (&resources, RT_CURSOR, name, -				    resinfo->language, 0); -      r->type = RES_TYPE_CURSOR; -      r->u.cursor = c; -      r->res_info = *resinfo; -    } - -  fclose (e); -  free (real_filename); - -  /* Define a cursor group resource.  */ - -  first = NULL; -  pp = &first; -  for (i = 0; i < count; i++) -    { -      struct group_cursor *cg; - -      cg = (struct group_cursor *) res_alloc (sizeof *cg); -      cg->next = NULL; -      cg->width = icondirs[i].width; -      cg->height = 2 * icondirs[i].height; - -      /* FIXME: What should these be set to?  */ -      cg->planes = 1; -      cg->bits = 1; - -      cg->bytes = icondirs[i].bytes + 4; -      cg->index = first_cursor + i + 1; - -      *pp = cg; -      pp = &(*pp)->next; -    } - -  free (icondirs); - -  r = define_standard_resource (&resources, RT_GROUP_CURSOR, id, -				resinfo->language, 0); -  r->type = RES_TYPE_GROUP_CURSOR; -  r->u.group_cursor = first; -  r->res_info = *resinfo; -} - -/* Define a dialog resource.  */ - -void -define_dialog (id, resinfo, dialog) -     struct res_id id; -     const struct res_res_info *resinfo; -     const struct dialog *dialog; -{ -  struct dialog *copy; -  struct res_resource *r; - -  copy = (struct dialog *) res_alloc (sizeof *copy); -  *copy = *dialog; - -  r = define_standard_resource (&resources, RT_DIALOG, id, -				resinfo->language, 0); -  r->type = RES_TYPE_DIALOG; -  r->u.dialog = copy; -  r->res_info = *resinfo; -} - -/* Define a dialog control.  This does not define a resource, but -   merely allocates and fills in a structure.  */ - -struct dialog_control * -define_control (text, id, x, y, width, height, class, style, exstyle) -     const char *text; -     unsigned long id; -     unsigned long x; -     unsigned long y; -     unsigned long width; -     unsigned long height; -     unsigned long class; -     unsigned long style; -     unsigned long exstyle; -{ -  struct dialog_control *n; - -  n = (struct dialog_control *) res_alloc (sizeof *n); -  n->next = NULL; -  n->id = id; -  n->style = style; -  n->exstyle = exstyle; -  n->x = x; -  n->y = y; -  n->width = width; -  n->height = height; -  n->class.named = 0; -  n->class.u.id = class; -  if (text != NULL) -    res_string_to_id (&n->text, text); -  else -    { -      n->text.named = 0; -      n->text.u.id = 0; -    } -  n->data = NULL; -  n->help = 0; - -  return n; -} - -/* Define a font resource.  */ - -void -define_font (id, resinfo, filename) -     struct res_id id; -     const struct res_res_info *resinfo; -     const char *filename; -{ -  FILE *e; -  char *real_filename; -  struct stat s; -  unsigned char *data; -  struct res_resource *r; -  long offset; -  long fontdatalength; -  unsigned char *fontdata; -  struct fontdir *fd; -  const char *device, *face; -  struct fontdir **pp; - -  e = open_file_search (filename, FOPEN_RB, "font file", &real_filename); - -  if (stat (real_filename, &s) < 0) -    fatal ("stat failed on bitmap file `%s': %s", real_filename, -	   strerror (errno)); - -  data = (unsigned char *) res_alloc (s.st_size); - -  get_data (e, data, s.st_size, real_filename); - -  fclose (e); -  free (real_filename); - -  r = define_standard_resource (&resources, RT_FONT, id, -				resinfo->language, 0); - -  r->type = RES_TYPE_FONT; -  r->u.data.length = s.st_size; -  r->u.data.data = data; -  r->res_info = *resinfo; - -  /* For each font resource, we must add an entry in the FONTDIR -     resource.  The FONTDIR resource includes some strings in the font -     file.  To find them, we have to do some magic on the data we have -     read.  */ - -  offset = ((((((data[47] << 8) -		| data[46]) << 8) -	      | data[45]) << 8) -	    | data[44]); -  if (offset > 0 && offset < s.st_size) -    device = (char *) data + offset; -  else -    device = ""; - -  offset = ((((((data[51] << 8) -		| data[50]) << 8) -	      | data[49]) << 8) -	    | data[48]); -  if (offset > 0 && offset < s.st_size) -    face = (char *) data + offset; -  else -    face = ""; - -  ++fonts; - -  fontdatalength = 58 + strlen (device) + strlen (face); -  fontdata = (unsigned char *) res_alloc (fontdatalength); -  memcpy (fontdata, data, 56); -  strcpy ((char *) fontdata + 56, device); -  strcpy ((char *) fontdata + 57 + strlen (device), face); - -  fd = (struct fontdir *) res_alloc (sizeof *fd); -  fd->next = NULL; -  fd->index = fonts; -  fd->length = fontdatalength; -  fd->data = fontdata; - -  for (pp = &fontdirs; *pp != NULL; pp = &(*pp)->next) -    ; -  *pp = fd; - -  /* For the single fontdirs resource, we always use the resource -     information of the last font.  I don't know what else to do.  */ -  fontdirs_resinfo = *resinfo; -} - -/* Define the fontdirs resource.  This is called after the entire rc -   file has been parsed, if any font resources were seen.  */ - -static void -define_fontdirs () -{ -  struct res_resource *r; -  struct res_id id; - -  id.named = 0; -  id.u.id = 1; - -  r = define_standard_resource (&resources, RT_FONTDIR, id, 0x409, 0); - -  r->type = RES_TYPE_FONTDIR; -  r->u.fontdir = fontdirs; -  r->res_info = fontdirs_resinfo; -} - -/* Define an icon resource.  An icon file may contain a set of -   bitmaps, each representing the same icon at various different -   resolutions.  They each get written out with a different ID.  The -   real icon resource is then a group resource which can be used to -   select one of the actual icon bitmaps.  */ - -void -define_icon (id, resinfo, filename) -     struct res_id id; -     const struct res_res_info *resinfo; -     const char *filename; -{ -  FILE *e; -  char *real_filename; -  int type, count, i; -  struct icondir *icondirs; -  int first_icon; -  struct res_resource *r; -  struct group_icon *first, **pp; - -  e = open_file_search (filename, FOPEN_RB, "icon file", &real_filename); - -  /* The start of an icon file is a three word structure.  The first -     word is ignored.  The second word is the type of data.  The third -     word is the number of entries.  */ - -  get_word (e, real_filename); -  type = get_word (e, real_filename); -  count = get_word (e, real_filename); -  if (type != 1) -    fatal ("icon file `%s' does not contain icon data", real_filename); - -  /* Read in the icon directory entries.  */ - -  icondirs = (struct icondir *) xmalloc (count * sizeof *icondirs); - -  for (i = 0; i < count; i++) -    { -      icondirs[i].width = getc (e); -      icondirs[i].height = getc (e); -      icondirs[i].colorcount = getc (e); -      getc (e); -      icondirs[i].u.icon.planes = get_word (e, real_filename); -      icondirs[i].u.icon.bits = get_word (e, real_filename); -      icondirs[i].bytes = get_long (e, real_filename); -      icondirs[i].offset = get_long (e, real_filename); - -      if (feof (e)) -	unexpected_eof (real_filename); -    } - -  /* Define each icon as a unique resource.  */ - -  first_icon = icons; - -  for (i = 0; i < count; i++) -    { -      unsigned char *data; -      struct res_id name; - -      if (fseek (e, icondirs[i].offset, SEEK_SET) != 0) -	fatal ("%s: fseek to %lu failed: %s", real_filename, -	       icondirs[i].offset, strerror (errno)); - -      data = (unsigned char *) res_alloc (icondirs[i].bytes); - -      get_data (e, data, icondirs[i].bytes, real_filename); - -      ++icons; - -      name.named = 0; -      name.u.id = icons; - -      r = define_standard_resource (&resources, RT_ICON, name, -				    resinfo->language, 0); -      r->type = RES_TYPE_ICON; -      r->u.data.length = icondirs[i].bytes; -      r->u.data.data = data; -      r->res_info = *resinfo; -    } - -  fclose (e); -  free (real_filename); - -  /* Define an icon group resource.  */ - -  first = NULL; -  pp = &first; -  for (i = 0; i < count; i++) -    { -      struct group_icon *cg; - -      /* For some reason, at least in some files the planes and bits -         are zero.  We instead set them from the color.  This is -         copied from rcl.  */ - -      cg = (struct group_icon *) res_alloc (sizeof *cg); -      cg->next = NULL; -      cg->width = icondirs[i].width; -      cg->height = icondirs[i].height; -      cg->colors = icondirs[i].colorcount; - -      cg->planes = 1; -      cg->bits = 0; -      while ((1 << cg->bits) < cg->colors) -	++cg->bits; - -      cg->bytes = icondirs[i].bytes; -      cg->index = first_icon + i + 1; - -      *pp = cg; -      pp = &(*pp)->next; -    } - -  free (icondirs); - -  r = define_standard_resource (&resources, RT_GROUP_ICON, id, -				resinfo->language, 0); -  r->type = RES_TYPE_GROUP_ICON; -  r->u.group_icon = first; -  r->res_info = *resinfo; -} - -/* Define a menu resource.  */ - -void -define_menu (id, resinfo, menuitems) -     struct res_id id; -     const struct res_res_info *resinfo; -     struct menuitem *menuitems; -{ -  struct menu *m; -  struct res_resource *r; - -  m = (struct menu *) res_alloc (sizeof *m); -  m->items = menuitems; -  m->help = 0; - -  r = define_standard_resource (&resources, RT_MENU, id, resinfo->language, 0); -  r->type = RES_TYPE_MENU; -  r->u.menu = m; -  r->res_info = *resinfo; -} - -/* Define a menu item.  This does not define a resource, but merely -   allocates and fills in a structure.  */ - -struct menuitem * -define_menuitem (text, menuid, type, state, help, menuitems) -     const char *text; -     int menuid; -     unsigned long type; -     unsigned long state; -     unsigned long help; -     struct menuitem *menuitems; -{ -  struct menuitem *mi; - -  mi = (struct menuitem *) res_alloc (sizeof *mi); -  mi->next = NULL; -  mi->type = type; -  mi->state = state; -  mi->id = menuid; -  if (text == NULL) -    mi->text = NULL; -  else -    unicode_from_ascii ((int *) NULL, &mi->text, text); -  mi->help = help; -  mi->popup = menuitems; -  return mi; -} - -/* Define a messagetable resource.  */ - -void -define_messagetable (id, resinfo, filename) -     struct res_id id; -     const struct res_res_info *resinfo; -     const char *filename; -{ -  FILE *e; -  char *real_filename; -  struct stat s; -  unsigned char *data; -  struct res_resource *r; - -  e = open_file_search (filename, FOPEN_RB, "messagetable file", -			&real_filename); - -  if (stat (real_filename, &s) < 0) -    fatal ("stat failed on bitmap file `%s': %s", real_filename, -	   strerror (errno)); - -  data = (unsigned char *) res_alloc (s.st_size); - -  get_data (e, data, s.st_size, real_filename); - -  fclose (e); -  free (real_filename); - -  r = define_standard_resource (&resources, RT_MESSAGETABLE, id, -				resinfo->language, 0); - -  r->type = RES_TYPE_MESSAGETABLE; -  r->u.data.length = s.st_size; -  r->u.data.data = data; -  r->res_info = *resinfo; -} - -/* Define an rcdata resource.  */ - -void -define_rcdata (id, resinfo, data) -     struct res_id id; -     const struct res_res_info *resinfo; -     struct rcdata_item *data; -{ -  struct res_resource *r; - -  r = define_standard_resource (&resources, RT_RCDATA, id, -				resinfo->language, 0); -  r->type = RES_TYPE_RCDATA; -  r->u.rcdata = data; -  r->res_info = *resinfo; -} - -/* Create an rcdata item holding a string.  */ - -struct rcdata_item * -define_rcdata_string (string, len) -     const char *string; -     unsigned long len; -{ -  struct rcdata_item *ri; -  char *s; - -  ri = (struct rcdata_item *) res_alloc (sizeof *ri); -  ri->next = NULL; -  ri->type = RCDATA_STRING; -  ri->u.string.length = len; -  s = (char *) res_alloc (len); -  memcpy (s, string, len); -  ri->u.string.s = s; - -  return ri; -} - -/* Create an rcdata item holding a number.  */ - -struct rcdata_item * -define_rcdata_number (val, dword) -     unsigned long val; -     int dword; -{ -  struct rcdata_item *ri; - -  ri = (struct rcdata_item *) res_alloc (sizeof *ri); -  ri->next = NULL; -  ri->type = dword ? RCDATA_DWORD : RCDATA_WORD; -  ri->u.word = val; - -  return ri; -} - -/* Define a stringtable resource.  This is called for each string -   which appears in a STRINGTABLE statement.  */ - -void -define_stringtable (resinfo, stringid, string) -     const struct res_res_info *resinfo; -     unsigned long stringid; -     const char *string; -{ -  struct res_id id; -  struct res_resource *r; - -  id.named = 0; -  id.u.id = (stringid >> 4) + 1; -  r = define_standard_resource (&resources, RT_STRING, id, -				resinfo->language, 1); - -  if (r->type == RES_TYPE_UNINITIALIZED) -    { -      int i; - -      r->type = RES_TYPE_STRINGTABLE; -      r->u.stringtable = ((struct stringtable *) -			  res_alloc (sizeof (struct stringtable))); -      for (i = 0; i < 16; i++) -	{ -	  r->u.stringtable->strings[i].length = 0; -	  r->u.stringtable->strings[i].string = NULL; -	} - -      r->res_info = *resinfo; -    } - -  unicode_from_ascii (&r->u.stringtable->strings[stringid & 0xf].length, -		      &r->u.stringtable->strings[stringid & 0xf].string, -		      string); -} - -/* Define a user data resource where the data is in the rc file.  */ - -void -define_user_data (id, type, resinfo, data) -     struct res_id id; -     struct res_id type; -     const struct res_res_info *resinfo; -     struct rcdata_item *data; -{ -  struct res_id ids[3]; -  struct res_resource *r; - -  ids[0] = type; -  ids[1] = id; -  ids[2].named = 0; -  ids[2].u.id = resinfo->language; - -  r = define_resource (&resources, 3, ids, 0); -  r->type = RES_TYPE_USERDATA; -  r->u.userdata = data; -  r->res_info = *resinfo; -} - -/* Define a user data resource where the data is in a file.  */ - -void -define_user_file (id, type, resinfo, filename) -     struct res_id id; -     struct res_id type; -     const struct res_res_info *resinfo; -     const char *filename; -{ -  FILE *e; -  char *real_filename; -  struct stat s; -  unsigned char *data; -  struct res_id ids[3]; -  struct res_resource *r; - -  e = open_file_search (filename, FOPEN_RB, "font file", &real_filename); - -  if (stat (real_filename, &s) < 0) -    fatal ("stat failed on bitmap file `%s': %s", real_filename, -	   strerror (errno)); - -  data = (unsigned char *) res_alloc (s.st_size); - -  get_data (e, data, s.st_size, real_filename); - -  fclose (e); -  free (real_filename); - -  ids[0] = type; -  ids[1] = id; -  ids[2].named = 0; -  ids[2].u.id = resinfo->language; - -  r = define_resource (&resources, 3, ids, 0); -  r->type = RES_TYPE_USERDATA; -  r->u.userdata = ((struct rcdata_item *) -		   res_alloc (sizeof (struct rcdata_item))); -  r->u.userdata->next = NULL; -  r->u.userdata->type = RCDATA_BUFFER; -  r->u.userdata->u.buffer.length = s.st_size; -  r->u.userdata->u.buffer.data = data; -  r->res_info = *resinfo; -} - -/* Define a versioninfo resource.  */ - -void -define_versioninfo (id, language, fixedverinfo, verinfo) -     struct res_id id; -     int language; -     struct fixed_versioninfo *fixedverinfo; -     struct ver_info *verinfo; -{ -  struct res_resource *r; - -  r = define_standard_resource (&resources, RT_VERSION, id, language, 0); -  r->type = RES_TYPE_VERSIONINFO; -  r->u.versioninfo = ((struct versioninfo *) -		      res_alloc (sizeof (struct versioninfo))); -  r->u.versioninfo->fixed = fixedverinfo; -  r->u.versioninfo->var = verinfo; -  r->res_info.language = language; -} - -/* Add string version info to a list of version information.  */ - -struct ver_info * -append_ver_stringfileinfo (verinfo, language, strings) -     struct ver_info *verinfo; -     const char *language; -     struct ver_stringinfo *strings; -{ -  struct ver_info *vi, **pp; - -  vi = (struct ver_info *) res_alloc (sizeof *vi); -  vi->next = NULL; -  vi->type = VERINFO_STRING; -  unicode_from_ascii ((int *) NULL, &vi->u.string.language, language); -  vi->u.string.strings = strings; - -  for (pp = &verinfo; *pp != NULL; pp = &(*pp)->next) -    ; -  *pp = vi; - -  return verinfo; -} - -/* Add variable version info to a list of version information.  */ - -struct ver_info * -append_ver_varfileinfo (verinfo, key, var) -     struct ver_info *verinfo; -     const char *key; -     struct ver_varinfo *var; -{ -  struct ver_info *vi, **pp; - -  vi = (struct ver_info *) res_alloc (sizeof *vi); -  vi->next = NULL; -  vi->type = VERINFO_VAR; -  unicode_from_ascii ((int *) NULL, &vi->u.var.key, key); -  vi->u.var.var = var; - -  for (pp = &verinfo; *pp != NULL; pp = &(*pp)->next) -    ; -  *pp = vi; - -  return verinfo; -} - -/* Append version string information to a list.  */ - -struct ver_stringinfo * -append_verval (strings, key, value) -     struct ver_stringinfo *strings; -     const char *key; -     const char *value; -{ -  struct ver_stringinfo *vs, **pp; - -  vs = (struct ver_stringinfo *) res_alloc (sizeof *vs); -  vs->next = NULL; -  unicode_from_ascii ((int *) NULL, &vs->key, key); -  unicode_from_ascii ((int *) NULL, &vs->value, value); - -  for (pp = &strings; *pp != NULL; pp = &(*pp)->next) -    ; -  *pp = vs; - -  return strings; -} - -/* Append version variable information to a list.  */ - -struct ver_varinfo * -append_vertrans (var, language, charset) -     struct ver_varinfo *var; -     unsigned long language; -     unsigned long charset; -{ -  struct ver_varinfo *vv, **pp; - -  vv = (struct ver_varinfo *) res_alloc (sizeof *vv); -  vv->next = NULL; -  vv->language = language; -  vv->charset = charset; - -  for (pp = &var; *pp != NULL; pp = &(*pp)->next) -    ; -  *pp = vv; - -  return var; -} - -/* Local functions used to write out an rc file.  */ - -static void indent PARAMS ((FILE *, int)); -static void write_rc_directory -  PARAMS ((FILE *, const struct res_directory *, const struct res_id *, -	   const struct res_id *, int *, int)); -static void write_rc_subdir -  PARAMS ((FILE *, const struct res_entry *, const struct res_id *, -	   const struct res_id *, int *, int)); -static void write_rc_resource -  PARAMS ((FILE *, const struct res_id *, const struct res_id *, -	   const struct res_resource *, int *)); -static void write_rc_accelerators -  PARAMS ((FILE *, const struct accelerator *)); -static void write_rc_cursor PARAMS ((FILE *, const struct cursor *)); -static void write_rc_group_cursor -  PARAMS ((FILE *, const struct group_cursor *)); -static void write_rc_dialog PARAMS ((FILE *, const struct dialog *)); -static void write_rc_dialog_control -  PARAMS ((FILE *, const struct dialog_control *)); -static void write_rc_fontdir PARAMS ((FILE *, const struct fontdir *)); -static void write_rc_group_icon PARAMS ((FILE *, const struct group_icon *)); -static void write_rc_menu PARAMS ((FILE *, const struct menu *, int)); -static void write_rc_menuitems -  PARAMS ((FILE *, const struct menuitem *, int, int)); -static void write_rc_rcdata PARAMS ((FILE *, const struct rcdata_item *, int)); -static void write_rc_stringtable -  PARAMS ((FILE *, const struct res_id *, const struct stringtable *)); -static void write_rc_versioninfo PARAMS ((FILE *, const struct versioninfo *)); -static void write_rc_filedata -  PARAMS ((FILE *, unsigned long, const unsigned char *)); - -/* Indent a given number of spaces.  */ - -static void -indent (e, c) -     FILE *e; -     int c; -{ -  int i; - -  for (i = 0; i < c; i++) -    putc (' ', e); -} - -/* Dump the resources we have read in the format of an rc file. - -   Actually, we don't use the format of an rc file, because it's way -   too much of a pain--for example, we'd have to write icon resources -   into a file and refer to that file.  We just generate a readable -   format that kind of looks like an rc file, and is useful for -   understanding the contents of a resource file.  Someday we may want -   to generate an rc file which the rc compiler can read; if that day -   comes, this code will have to be fixed up.  */ - -void -write_rc_file (filename, resources) -     const char *filename; -     const struct res_directory *resources; -{ -  FILE *e; -  int language; - -  if (filename == NULL) -    e = stdout; -  else -    { -      e = fopen (filename, FOPEN_WT); -      if (e == NULL) -	fatal ("can't open `%s' for output: %s", filename, strerror (errno)); -    } - -  language = -1; -  write_rc_directory (e, resources, (const struct res_id *) NULL, -		      (const struct res_id *) NULL, &language, 1); -} - -/* Write out a directory.  E is the file to write to.  RD is the -   directory.  TYPE is a pointer to the level 1 ID which serves as the -   resource type.  NAME is a pointer to the level 2 ID which serves as -   an individual resource name.  LANGUAGE is a pointer to the current -   language.  LEVEL is the level in the tree.  */ - -static void -write_rc_directory (e, rd, type, name, language, level) -     FILE *e; -     const struct res_directory *rd; -     const struct res_id *type; -     const struct res_id *name; -     int *language; -     int level; -{ -  const struct res_entry *re; - -  /* Print out some COFF information that rc files can't represent.  */ - -  if (rd->time != 0) -    fprintf (e, "// Time stamp: %lu\n", rd->time); -  if (rd->characteristics != 0) -    fprintf (e, "// Characteristics: %lu\n", rd->characteristics); -  if (rd->major != 0 || rd->minor != 0) -    fprintf (e, "// Version: %d %d\n", rd->major, rd->minor); - -  for (re = rd->entries;  re != NULL; re = re->next) -    { -      switch (level) -	{ -	case 1: -	  /* If we're at level 1, the key of this resource is the -             type.  This normally duplicates the information we have -             stored with the resource itself, but we need to remember -             the type if this is a user define resource type.  */ -	  type = &re->id; -	  break; - -	case 2: -	  /* If we're at level 2, the key of this resource is the name -	     we are going to use in the rc printout. */ -	  name = &re->id; -	  break; - -	case 3: -	  /* If we're at level 3, then this key represents a language. -	     Use it to update the current language.  */ -	  if (! re->id.named -	      && re->id.u.id != *language -	      && (re->id.u.id & 0xffff) == re->id.u.id) -	    { -	      fprintf (e, "LANGUAGE %lu, %lu\n", -		       re->id.u.id & 0xff, (re->id.u.id >> 8) & 0xff); -	      *language = re->id.u.id; -	    } -	  break; - -	default: -	  break; -	} - -      if (re->subdir) -	write_rc_subdir (e, re, type, name, language, level); -      else -	{ -	  if (level == 3) -	    { -	      /* This is the normal case: the three levels are -                 TYPE/NAME/LANGUAGE.  NAME will have been set at level -                 2, and represents the name to use.  We probably just -                 set LANGUAGE, and it will probably match what the -                 resource itself records if anything.  */ -	      write_rc_resource (e, type, name, re->u.res, language); -	    } -	  else -	    { -	      fprintf (e, "// Resource at unexpected level %d\n", level); -	      write_rc_resource (e, type, (struct res_id *) NULL, re->u.res, -				 language); -	    } -	} -    } -} - -/* Write out a subdirectory entry.  E is the file to write to.  RE is -   the subdirectory entry.  TYPE and NAME are pointers to higher level -   IDs, or NULL.  LANGUAGE is a pointer to the current language. -   LEVEL is the level in the tree.  */ - -static void -write_rc_subdir (e, re, type, name, language, level) -     FILE *e; -     const struct res_entry *re; -     const struct res_id *type; -     const struct res_id *name; -     int *language; -     int level; -{ -  fprintf (e, "\n"); -  switch (level) -    { -    case 1: -      fprintf (e, "// Type: "); -      if (re->id.named) -	res_id_print (e, re->id, 1); -      else -	{ -	  const char *s; - -	  switch (re->id.u.id) -	    { -	    case RT_CURSOR: s = "cursor"; break; -	    case RT_BITMAP: s = "bitmap"; break; -	    case RT_ICON: s = "icon"; break; -	    case RT_MENU: s = "menu"; break; -	    case RT_DIALOG: s = "dialog"; break; -	    case RT_STRING: s = "stringtable"; break; -	    case RT_FONTDIR: s = "fontdir"; break; -	    case RT_FONT: s = "font"; break; -	    case RT_ACCELERATORS: s = "accelerators"; break; -	    case RT_RCDATA: s = "rcdata"; break; -	    case RT_MESSAGETABLE: s = "messagetable"; break; -	    case RT_GROUP_CURSOR: s = "group cursor"; break; -	    case RT_GROUP_ICON: s = "group icon"; break; -	    case RT_VERSION: s = "version"; break; -	    case RT_DLGINCLUDE: s = "dlginclude"; break; -	    case RT_PLUGPLAY: s = "plugplay"; break; -	    case RT_VXD: s = "vxd"; break; -	    case RT_ANICURSOR: s = "anicursor"; break; -	    case RT_ANIICON: s = "aniicon"; break; -	    default: s = NULL; break; -	    } - -	  if (s != NULL) -	    fprintf (e, "%s", s); -	  else -	    res_id_print (e, re->id, 1); -	} -      fprintf (e, "\n"); -      break; - -    case 2: -      fprintf (e, "// Name: "); -      res_id_print (e, re->id, 1); -      fprintf (e, "\n"); -      break; - -    case 3: -      fprintf (e, "// Language: "); -      res_id_print (e, re->id, 1); -      fprintf (e, "\n"); -      break; - -    default: -      fprintf (e, "// Level %d: ", level); -      res_id_print (e, re->id, 1); -      fprintf (e, "\n"); -    }		 - -  write_rc_directory (e, re->u.dir, type, name, language, level + 1); -} - -/* Write out a single resource.  E is the file to write to.  TYPE is a -   pointer to the type of the resource.  NAME is a pointer to the name -   of the resource; it will be NULL if there is a level mismatch.  RES -   is the resource data.  LANGUAGE is a pointer to the current -   language.  */ - -static void -write_rc_resource (e, type, name, res, language) -     FILE *e; -     const struct res_id *type; -     const struct res_id *name; -     const struct res_resource *res; -     int *language; -{ -  const char *s; -  int rt; -  int menuex = 0; - -  fprintf (e, "\n"); - -  switch (res->type) -    { -    default: -      abort (); - -    case RES_TYPE_ACCELERATOR: -      s = "ACCELERATOR"; -      rt = RT_ACCELERATORS; -      break; - -    case RES_TYPE_BITMAP: -      s = "BITMAP"; -      rt = RT_BITMAP; -      break; - -    case RES_TYPE_CURSOR: -      s = "CURSOR"; -      rt = RT_CURSOR; -      break; - -    case RES_TYPE_GROUP_CURSOR: -      s = "GROUP_CURSOR"; -      rt = RT_GROUP_CURSOR; -      break; - -    case RES_TYPE_DIALOG: -      if (extended_dialog (res->u.dialog)) -	s = "DIALOGEX"; -      else -	s = "DIALOG"; -      rt = RT_DIALOG; -      break; - -    case RES_TYPE_FONT: -      s = "FONT"; -      rt = RT_FONT; -      break; - -    case RES_TYPE_FONTDIR: -      s = "FONTDIR"; -      rt = RT_FONTDIR; -      break; - -    case RES_TYPE_ICON: -      s = "ICON"; -      rt = RT_ICON; -      break; - -    case RES_TYPE_GROUP_ICON: -      s = "GROUP_ICON"; -      rt = RT_GROUP_ICON; -      break; - -    case RES_TYPE_MENU: -      if (extended_menu (res->u.menu)) -	{ -	  s = "MENUEX"; -	  menuex = 1; -	} -      else -	{ -	  s = "MENU"; -	  menuex = 0; -	} -      rt = RT_MENU; -      break; - -    case RES_TYPE_MESSAGETABLE: -      s = "MESSAGETABLE"; -      rt = RT_MESSAGETABLE; -      break; - -    case RES_TYPE_RCDATA: -      s = "RCDATA"; -      rt = RT_RCDATA; -      break; - -    case RES_TYPE_STRINGTABLE: -      s = "STRINGTABLE"; -      rt = RT_STRING; -      break; - -    case RES_TYPE_USERDATA: -      s = NULL; -      rt = 0; -      break; - -    case RES_TYPE_VERSIONINFO: -      s = "VERSIONINFO"; -      rt = RT_VERSION; -      break; -    } - -  if (rt != 0 -      && type != NULL -      && (type->named || type->u.id != rt)) -    { -      fprintf (e, "// Unexpected resource type mismatch: "); -      res_id_print (e, *type, 1); -      fprintf (e, " != %d", rt); -    } - -  if (res->coff_info.codepage != 0) -    fprintf (e, "// Code page: %lu\n", res->coff_info.codepage); -  if (res->coff_info.reserved != 0) -    fprintf (e, "// COFF reserved value: %lu\n", res->coff_info.reserved); - -  if (name != NULL) -    res_id_print (e, *name, 0); -  else -    fprintf (e, "??Unknown-Name??"); - -  fprintf (e, " "); -  if (s != NULL) -    fprintf (e, "%s", s); -  else if (type != NULL) -    res_id_print (e, *type, 0); -  else -    fprintf (e, "??Unknown-Type??"); - -  if (res->res_info.memflags != 0) -    { -      if ((res->res_info.memflags & MEMFLAG_MOVEABLE) != 0) -	fprintf (e, " MOVEABLE"); -      if ((res->res_info.memflags & MEMFLAG_PURE) != 0) -	fprintf (e, " PURE"); -      if ((res->res_info.memflags & MEMFLAG_PRELOAD) != 0) -	fprintf (e, " PRELOAD"); -      if ((res->res_info.memflags & MEMFLAG_DISCARDABLE) != 0) -	fprintf (e, " DISCARDABLE"); -    } - -  if (res->type == RES_TYPE_DIALOG) -    { -      fprintf (e, " %d, %d, %d, %d", res->u.dialog->x, res->u.dialog->y, -	       res->u.dialog->width, res->u.dialog->height); -      if (res->u.dialog->ex != NULL -	  && res->u.dialog->ex->help != 0) -	fprintf (e, ", %lu", res->u.dialog->ex->help); -    } - -  fprintf (e, "\n"); - -  if ((res->res_info.language != 0 && res->res_info.language != *language) -      || res->res_info.characteristics != 0 -      || res->res_info.version != 0) -    { -      int modifiers; - -      switch (res->type) -	{ -	case RES_TYPE_ACCELERATOR: -	case RES_TYPE_DIALOG: -	case RES_TYPE_MENU: -	case RES_TYPE_RCDATA: -	case RES_TYPE_STRINGTABLE: -	  modifiers = 1; -	  break; - -	default: -	  modifiers = 0; -	  break; -	} - -      if (res->res_info.language != 0 && res->res_info.language != *language) -	fprintf (e, "%sLANGUAGE %d, %d\n", -		 modifiers ? "// " : "", -		 res->res_info.language & 0xff, -		 (res->res_info.language >> 8) & 0xff); -      if (res->res_info.characteristics != 0) -	fprintf (e, "%sCHARACTERISTICS %lu\n", -		 modifiers ? "// " : "", -		 res->res_info.characteristics); -      if (res->res_info.version != 0) -	fprintf (e, "%sVERSION %lu\n", -		 modifiers ? "// " : "", -		 res->res_info.version); -    } - -  switch (res->type) -    { -    default: -      abort (); - -    case RES_TYPE_ACCELERATOR: -      write_rc_accelerators (e, res->u.acc); -      break; - -    case RES_TYPE_CURSOR: -      write_rc_cursor (e, res->u.cursor); -      break; - -    case RES_TYPE_GROUP_CURSOR: -      write_rc_group_cursor (e, res->u.group_cursor); -      break; - -    case RES_TYPE_DIALOG: -      write_rc_dialog (e, res->u.dialog); -      break; - -    case RES_TYPE_FONTDIR: -      write_rc_fontdir (e, res->u.fontdir); -      break; - -    case RES_TYPE_GROUP_ICON: -      write_rc_group_icon (e, res->u.group_icon); -      break; - -    case RES_TYPE_MENU: -      write_rc_menu (e, res->u.menu, menuex); -      break; - -    case RES_TYPE_RCDATA: -      write_rc_rcdata (e, res->u.rcdata, 0); -      break; - -    case RES_TYPE_STRINGTABLE: -      write_rc_stringtable (e, name, res->u.stringtable); -      break; - -    case RES_TYPE_USERDATA: -      write_rc_rcdata (e, res->u.userdata, 0); -      break; - -    case RES_TYPE_VERSIONINFO: -      write_rc_versioninfo (e, res->u.versioninfo); -      break; - -    case RES_TYPE_BITMAP: -    case RES_TYPE_FONT: -    case RES_TYPE_ICON: -    case RES_TYPE_MESSAGETABLE: -      write_rc_filedata (e, res->u.data.length, res->u.data.data); -      break; -    } -} - -/* Write out accelerator information.  */ - -static void -write_rc_accelerators (e, accelerators) -     FILE *e; -     const struct accelerator *accelerators; -{ -  const struct accelerator *acc; - -  fprintf (e, "BEGIN\n"); -  for (acc = accelerators; acc != NULL; acc = acc->next) -    { -      int printable; - -      fprintf (e, "  "); - -      if ((acc->key & 0x7f) == acc->key -	  && isprint ((unsigned char) acc->key) -	  && (acc->flags & ACC_VIRTKEY) == 0) -	{ -	  fprintf (e, "\"%c\"", acc->key); -	  printable = 1; -	} -      else -	{ -	  fprintf (e, "%d", acc->key); -	  printable = 0; -	} - -      fprintf (e, ", %d", acc->id); - -      if (! printable) -	{ -	  if ((acc->flags & ACC_VIRTKEY) != 0) -	    fprintf (e, ", VIRTKEY"); -	  else -	    fprintf (e, ", ASCII"); -	} - -      if ((acc->flags & ACC_SHIFT) != 0) -	fprintf (e, ", SHIFT"); -      if ((acc->flags & ACC_CONTROL) != 0) -	fprintf (e, ", CONTROL"); -      if ((acc->flags & ACC_ALT) != 0) -	fprintf (e, ", ALT"); - -      fprintf (e, "\n"); -    } - -  fprintf (e, "END\n"); -} - -/* Write out cursor information.  This would normally be in a separate -   file, which the rc file would include.  */ - -static void -write_rc_cursor (e, cursor) -     FILE *e; -     const struct cursor *cursor; -{ -  fprintf (e, "// Hotspot: x: %d; y: %d\n", cursor->xhotspot, -	   cursor->yhotspot); -  write_rc_filedata (e, cursor->length, cursor->data); -} - -/* Write out group cursor data.  This would normally be built from the -   cursor data.  */ - -static void -write_rc_group_cursor (e, group_cursor) -     FILE *e; -     const struct group_cursor *group_cursor; -{ -  const struct group_cursor *gc; - -  for (gc = group_cursor; gc != NULL; gc = gc->next) -    { -      fprintf (e, "// width: %d; height %d; planes %d; bits %d\n", -	     gc->width, gc->height, gc->planes, gc->bits); -      fprintf (e, "// data bytes: %lu; index: %d\n", -	       gc->bytes, gc->index); -    } -} - -/* Write dialog data.  */ - -static void -write_rc_dialog (e, dialog) -     FILE *e; -     const struct dialog *dialog; -{ -  const struct dialog_control *control; - -  if (dialog->style != 0) -    fprintf (e, "STYLE 0x%lx\n", dialog->style); -  if (dialog->exstyle != 0) -    fprintf (e, "EXSTYLE 0x%lx\n", dialog->exstyle); -  if ((dialog->class.named && dialog->class.u.n.length > 0) -      || dialog->class.u.id != 0) -    { -      fprintf (e, "CLASS "); -      res_id_print (e, dialog->class, 0); -      fprintf (e, "\n"); -    } -  if (dialog->caption != NULL) -    { -      fprintf (e, "CAPTION \""); -      unicode_print (e, dialog->caption, -1); -      fprintf (e, "\"\n"); -    } -  if ((dialog->menu.named && dialog->menu.u.n.length > 0) -      || dialog->menu.u.id != 0) -    { -      fprintf (e, "MENU "); -      res_id_print (e, dialog->menu, 0); -      fprintf (e, "\n"); -    } -  if (dialog->font != NULL) -    { -      fprintf (e, "FONT %d, \"", dialog->pointsize); -      unicode_print (e, dialog->font, -1); -      fprintf (e, "\""); -      if (dialog->ex != NULL -	  && (dialog->ex->weight != 0 || dialog->ex->italic != 0)) -	fprintf (e, ", %d, %d", dialog->ex->weight, dialog->ex->italic); -      fprintf (e, "\n"); -    } - -  fprintf (e, "BEGIN\n"); - -  for (control = dialog->controls; control != NULL; control = control->next) -    write_rc_dialog_control (e, control); - -  fprintf (e, "END\n"); -} - -/* For each predefined control keyword, this table provides the class -   and the style.  */ - -struct control_info -{ -  const char *name; -  unsigned short class; -  unsigned long style; -}; - -static const struct control_info control_info[] = -{ -  { "AUTO3STATE", CTL_BUTTON, BS_AUTO3STATE }, -  { "AUTOCHECKBOX", CTL_BUTTON, BS_AUTOCHECKBOX }, -  { "AUTORADIOBUTTON", CTL_BUTTON, BS_AUTORADIOBUTTON }, -  { "CHECKBOX", CTL_BUTTON, BS_CHECKBOX }, -  { "COMBOBOX", CTL_COMBOBOX, (unsigned long) -1 }, -  { "CTEXT", CTL_STATIC, SS_CENTER }, -  { "DEFPUSHBUTTON", CTL_BUTTON, BS_DEFPUSHBUTTON }, -  { "EDITTEXT", CTL_EDIT, (unsigned long) -1 }, -  { "GROUPBOX", CTL_BUTTON, BS_GROUPBOX }, -  { "ICON", CTL_STATIC, SS_ICON }, -  { "LISTBOX", CTL_LISTBOX, (unsigned long) -1 }, -  { "LTEXT", CTL_STATIC, SS_LEFT }, -  { "PUSHBOX", CTL_BUTTON, BS_PUSHBOX }, -  { "PUSHBUTTON", CTL_BUTTON, BS_PUSHBUTTON }, -  { "RADIOBUTTON", CTL_BUTTON, BS_RADIOBUTTON }, -  { "RTEXT", CTL_STATIC, SS_RIGHT }, -  { "SCROLLBAR", CTL_SCROLLBAR, (unsigned long) -1 }, -  { "STATE3", CTL_BUTTON, BS_3STATE }, -  /* It's important that USERBUTTON come after all the other button -     types, so that it won't be matched too early.  */ -  { "USERBUTTON", CTL_BUTTON, (unsigned long) -1 }, -  { NULL, 0, 0 } -}; - -/* Write a dialog control.  */ - -static void -write_rc_dialog_control (e, control) -     FILE *e; -     const struct dialog_control *control; -{ -  const struct control_info *ci; - -  fprintf (e, "  "); - -  if (control->class.named) -    ci = NULL; -  else -    { -      for (ci = control_info; ci->name != NULL; ++ci) -	if (ci->class == control->class.u.id -	    && (ci->style == (unsigned long) -1 -		|| ci->style == (control->style & 0xff))) -	  break; -    } - -  if (ci->name != NULL) -    fprintf (e, "%s", ci->name); -  else -    fprintf (e, "CONTROL"); -   -  if (control->text.named || control->text.u.id != 0) -    { -      fprintf (e, " "); -      res_id_print (e, control->text, 1); -      fprintf (e, ","); -    } - -  fprintf (e, " %d, ", control->id); - -  if (ci->name == NULL) -    { -      res_id_print (e, control->class, 0); -      fprintf (e, ", 0x%lx, ", control->style); -    } - -  fprintf (e, "%d, %d", control->x, control->y); - -  if (control->style != SS_ICON -      || control->exstyle != 0 -      || control->width != 0 -      || control->height != 0 -      || control->help != 0) -    { -      fprintf (e, ", %d, %d", control->width, control->height); - -      /* FIXME: We don't need to print the style if it is the default. -	 More importantly, in certain cases we actually need to turn -	 off parts of the forced style, by using NOT.  */ -      fprintf (e, ", 0x%lx", control->style); - -      if (control->exstyle != 0 || control->help != 0) -	fprintf (e, ", 0x%lx, %lu", control->exstyle, control->help); -    } - -  fprintf (e, "\n"); - -  if (control->data != NULL) -    write_rc_rcdata (e, control->data, 2); -} - -/* Write out font directory data.  This would normally be built from -   the font data.  */ - -static void -write_rc_fontdir (e, fontdir) -     FILE *e; -     const struct fontdir *fontdir; -{ -  const struct fontdir *fc; - -  for (fc = fontdir; fc != NULL; fc = fc->next) -    { -      fprintf (e, "// Font index: %d\n", fc->index); -      write_rc_filedata (e, fc->length, fc->data); -    } -} - -/* Write out group icon data.  This would normally be built from the -   icon data.  */ - -static void -write_rc_group_icon (e, group_icon) -     FILE *e; -     const struct group_icon *group_icon; -{ -  const struct group_icon *gi; - -  for (gi = group_icon; gi != NULL; gi = gi->next) -    { -      fprintf (e, "// width: %d; height %d; colors: %d; planes %d; bits %d\n", -	       gi->width, gi->height, gi->colors, gi->planes, gi->bits); -      fprintf (e, "// data bytes: %lu; index: %d\n", -	       gi->bytes, gi->index); -    } -} - -/* Write out a menu resource.  */ - -static void -write_rc_menu (e, menu, menuex) -     FILE *e; -     const struct menu *menu; -     int menuex; -{ -  if (menu->help != 0) -    fprintf (e, "// Help ID: %lu\n", menu->help); -  write_rc_menuitems (e, menu->items, menuex, 0); -} - -/* Write out menuitems.  */ - -static void -write_rc_menuitems (e, menuitems, menuex, ind) -     FILE *e; -     const struct menuitem *menuitems; -     int menuex; -     int ind; -{ -  const struct menuitem *mi; - -  indent (e, ind); -  fprintf (e, "BEGIN\n"); - -  for (mi = menuitems; mi != NULL; mi = mi->next) -    { -      indent (e, ind + 2); - -      if (mi->popup == NULL) -	fprintf (e, "MENUITEM"); -      else -	fprintf (e, "POPUP"); - -      if (! menuex -	  && mi->popup == NULL -	  && mi->text == NULL -	  && mi->type == 0 -	  && mi->id == 0) -	{ -	  fprintf (e, " SEPARATOR\n"); -	  continue; -	} - -      if (mi->text == NULL) -	fprintf (e, " \"\""); -      else -	{ -	  fprintf (e, " \""); -	  unicode_print (e, mi->text, -1); -	  fprintf (e, "\""); -	} - -      if (! menuex) -	{ -	  if (mi->popup == NULL) -	    fprintf (e, ", %d", mi->id); - -	  if ((mi->type & MENUITEM_CHECKED) != 0) -	    fprintf (e, ", CHECKED"); -	  if ((mi->type & MENUITEM_GRAYED) != 0) -	    fprintf (e, ", GRAYED"); -	  if ((mi->type & MENUITEM_HELP) != 0) -	    fprintf (e, ", HELP"); -	  if ((mi->type & MENUITEM_INACTIVE) != 0) -	    fprintf (e, ", INACTIVE"); -	  if ((mi->type & MENUITEM_MENUBARBREAK) != 0) -	    fprintf (e, ", MENUBARBREAK"); -	  if ((mi->type & MENUITEM_MENUBREAK) != 0) -	    fprintf (e, ", MENUBREAK"); -	} -      else -	{ -	  if (mi->id != 0 || mi->type != 0 || mi->state != 0 || mi->help != 0) -	    { -	      fprintf (e, ", %d", mi->id); -	      if (mi->type != 0 || mi->state != 0 || mi->help != 0) -		{ -		  fprintf (e, ", %lu", mi->type); -		  if (mi->state != 0 || mi->help != 0) -		    { -		      fprintf (e, ", %lu", mi->state); -		      if (mi->help != 0) -			fprintf (e, ", %lu", mi->help); -		    } -		} -	    } -	} - -      fprintf (e, "\n"); - -      if (mi->popup != NULL) -	write_rc_menuitems (e, mi->popup, menuex, ind + 2); -    } - -  indent (e, ind); -  fprintf (e, "END\n"); -} - -/* Write out an rcdata resource.  This is also used for other types of -   resources that need to print arbitrary data.  */ - -static void -write_rc_rcdata (e, rcdata, ind) -     FILE *e; -     const struct rcdata_item *rcdata; -     int ind; -{ -  const struct rcdata_item *ri; - -  indent (e, ind); -  fprintf (e, "BEGIN\n"); - -  for (ri = rcdata; ri != NULL; ri = ri->next) -    { -      if (ri->type == RCDATA_BUFFER && ri->u.buffer.length == 0) -	continue; - -      indent (e, ind + 2); - -      switch (ri->type) -	{ -	default: -	  abort (); - -	case RCDATA_WORD: -	  fprintf (e, "%d", ri->u.word); -	  break; - -	case RCDATA_DWORD: -	  fprintf (e, "%luL", ri->u.dword); -	  break; - -	case RCDATA_STRING: -	  { -	    const char *s; -	    unsigned long i; - -	    fprintf (e, "\""); -	    s = ri->u.string.s; -	    for (i = 0; i < ri->u.string.length; i++) -	      { -		if (isprint (*s)) -		  putc (*s, e); -		else -		  fprintf (e, "\\%03o", *s); -	      } -	    fprintf (e, "\""); -	    break; -	  } - -	case RCDATA_WSTRING: -	  fprintf (e, "L\""); -	  unicode_print (e, ri->u.wstring.w, ri->u.wstring.length); -	  fprintf (e, "\""); -	  break; - -	case RCDATA_BUFFER: -	  { -	    unsigned long i; -	    int first; - -	    /* Assume little endian data.  */ - -	    first = 1; -	    for (i = 0; i + 3 < ri->u.buffer.length; i += 4) -	      { -		unsigned long l; - -		l = ((((((ri->u.buffer.data[i + 3] << 8) -			 | ri->u.buffer.data[i + 2]) << 8) -		       | ri->u.buffer.data[i + 1]) << 8) -		     | ri->u.buffer.data[i]); -		if (first) -		  first = 0; -		else -		  { -		    fprintf (e, ",\n"); -		    indent (e, ind + 2); -		  } -		fprintf (e, "%luL", l); -	      } - -	    if (i + 1 < ri->u.buffer.length) -	      { -		int i; - -		i = (ri->u.buffer.data[i + 1] << 8) | ri->u.buffer.data[i]; -		if (first) -		  first = 0; -		else -		  { -		    fprintf (e, ",\n"); -		    indent (e, ind + 2); -		  } -		fprintf (e, "%d", i); -		i += 2; -	      } - -	    if (i < ri->u.buffer.length) -	      { -		if (first) -		  first = 0; -		else -		  { -		    fprintf (e, ",\n"); -		    indent (e, ind + 2); -		  } -		if ((ri->u.buffer.data[i] & 0x7f) == ri->u.buffer.data[i] -		    && isprint (ri->u.buffer.data[i])) -		  fprintf (e, "\"%c\"", ri->u.buffer.data[i]); -		else -		  fprintf (e, "\"\%03o\"", ri->u.buffer.data[i]); -	      } - -	    break; -	  } -	} - -      if (ri->next != NULL) -	fprintf (e, ","); -      fprintf (e, "\n"); -    } - -  indent (e, ind); -  fprintf (e, "END\n"); -} - -/* Write out a stringtable resource.  */ - -static void -write_rc_stringtable (e, name, stringtable) -     FILE *e; -     const struct res_id *name; -     const struct stringtable *stringtable; -{ -  unsigned long offset; -  int i; - -  if (name != NULL && ! name->named) -    offset = (name->u.id - 1) << 4; -  else -    { -      fprintf (e, "// %s string table name\n", -	       name == NULL ? "Missing" : "Invalid"); -      offset = 0; -    } - -  fprintf (e, "BEGIN\n"); - -  for (i = 0; i < 16; i++) -    { -      if (stringtable->strings[i].length != 0) -	{ -	  fprintf (e, "  %lu, \"", offset + i); -	  unicode_print (e, stringtable->strings[i].string, -			 stringtable->strings[i].length); -	  fprintf (e, "\"\n"); -	} -    } - -  fprintf (e, "END\n"); -} - -/* Write out a versioninfo resource.  */ - -static void -write_rc_versioninfo (e, versioninfo) -     FILE *e; -     const struct versioninfo *versioninfo; -{ -  const struct fixed_versioninfo *f; -  const struct ver_info *vi; - -  f = versioninfo->fixed; -  if (f->file_version_ms != 0 || f->file_version_ls != 0) -    fprintf (e, " FILEVERSION %lu, %lu, %lu, %lu\n", -	     (f->file_version_ms >> 16) & 0xffff, -	     f->file_version_ms & 0xffff, -	     (f->file_version_ls >> 16) & 0xffff, -	     f->file_version_ls & 0xffff); -  if (f->product_version_ms != 0 || f->product_version_ls != 0) -    fprintf (e, " PRODUCTVERSION %lu, %lu, %lu, %lu\n", -	     (f->product_version_ms >> 16) & 0xffff, -	     f->product_version_ms & 0xffff, -	     (f->product_version_ls >> 16) & 0xffff, -	     f->product_version_ls & 0xffff); -  if (f->file_flags_mask != 0) -    fprintf (e, " FILEFLAGSMASK 0x%lx\n", f->file_flags_mask); -  if (f->file_flags != 0) -    fprintf (e, " FILEFLAGS 0x%lx\n", f->file_flags); -  if (f->file_os != 0) -    fprintf (e, " FILEOS 0x%lx\n", f->file_os); -  if (f->file_type != 0) -    fprintf (e, " FILETYPE 0x%lx\n", f->file_type); -  if (f->file_subtype != 0) -    fprintf (e, " FILESUBTYPE 0x%lx\n", f->file_subtype); -  if (f->file_date_ms != 0 || f->file_date_ls != 0) -    fprintf (e, "// Date: %lu, %lu\n", f->file_date_ms, f->file_date_ls); - -  fprintf (e, "BEGIN\n"); - -  for (vi = versioninfo->var; vi != NULL; vi = vi->next) -    { -      switch (vi->type) -	{ -	case VERINFO_STRING: -	  { -	    const struct ver_stringinfo *vs; - -	    fprintf (e, "  BLOCK \"StringFileInfo\"\n"); -	    fprintf (e, "  BEGIN\n"); -	    fprintf (e, "    BLOCK \""); -	    unicode_print (e, vi->u.string.language, -1); -	    fprintf (e, "\"\n"); -	    fprintf (e, "    BEGIN\n"); - -	    for (vs = vi->u.string.strings; vs != NULL; vs = vs->next) -	      { -		fprintf (e, "      VALUE \""); -		unicode_print (e, vs->key, -1); -		fprintf (e, "\", \""); -		unicode_print (e, vs->value, -1); -		fprintf (e, "\"\n"); -	      } - -	    fprintf (e, "    END\n"); -	    fprintf (e, "  END\n"); -	    break; -	  } - -	case VERINFO_VAR: -	  { -	    const struct ver_varinfo *vv; - -	    fprintf (e, "  BLOCK \"VarFileInfo\"\n"); -	    fprintf (e, "  BEGIN\n"); -	    fprintf (e, "    VALUE \""); -	    unicode_print (e, vi->u.var.key, -1); -	    fprintf (e, "\""); - -	    for (vv = vi->u.var.var; vv != NULL; vv = vv->next) -	      fprintf (e, ", 0x%x, %d", (unsigned int) vv->language, -		       vv->charset); - -	    fprintf (e, "\n  END\n"); - -	    break; -	  } -	} -    } - -  fprintf (e, "END\n"); -} - -/* Write out data which would normally be read from a file.  */ - -static void -write_rc_filedata (e, length, data) -     FILE *e; -     unsigned long length; -     const unsigned char *data; -{ -  unsigned long i; - -  for (i = 0; i + 15 < length; i += 16) -    { -      fprintf (e, "// %4lx: ", i); -      fprintf (e, "%02x %02x %02x %02x %02x %02x %02x %02x ", -	       data[i + 0], data[i + 1], data[i + 2], data[i + 3], -	       data[i + 4], data[i + 5], data[i + 6], data[i + 7]); -      fprintf (e, "%02x %02x %02x %02x %02x %02x %02x %02x\n", -	       data[i +  8], data[i +  9], data[i + 10], data[i + 11], -	       data[i + 12], data[i + 13], data[i + 14], data[i + 15]); -    } - -  if (i < length) -    { -      fprintf (e, "// %4lx:", i); -      while (i < length) -	{ -	  fprintf (e, " %02x", data[i]); -	  ++i; -	} -      fprintf (e, "\n"); -    } -}  | 
