/* resrc.c -- read and write Windows rc files.
   Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2007, 2008, 2011
   Free Software Foundation, Inc.
   Written by Ian Lance Taylor, Cygnus Support.
   Rewritten by Kai Tietz, Onevision.

   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 3 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., 51 Franklin Street - Fifth Floor, Boston, MA
   02110-1301, USA.  */

/* This file contains functions that read and write Windows rc files.
   These are text files that represent resources.  */

#include "sysdep.h"
#include "bfd.h"
#include "bucomm.h"
#include "libiberty.h"
#include "safe-ctype.h"
#include "windres.h"

#include <assert.h>

#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
#else /* ! HAVE_SYS_WAIT_H */
#if ! defined (_WIN32) || defined (__CYGWIN__)
#ifndef WIFEXITED
#define WIFEXITED(w)	(((w)&0377) == 0)
#endif
#ifndef WIFSIGNALED
#define WIFSIGNALED(w)	(((w)&0377) != 0177 && ((w)&~0377) == 0)
#endif
#ifndef WTERMSIG
#define WTERMSIG(w)	((w) & 0177)
#endif
#ifndef WEXITSTATUS
#define WEXITSTATUS(w)	(((w) >> 8) & 0377)
#endif
#else /* defined (_WIN32) && ! defined (__CYGWIN__) */
#ifndef WIFEXITED
#define WIFEXITED(w)	(((w) & 0xff) == 0)
#endif
#ifndef WIFSIGNALED
#define WIFSIGNALED(w)	(((w) & 0xff) != 0 && ((w) & 0xff) != 0x7f)
#endif
#ifndef WTERMSIG
#define WTERMSIG(w)	((w) & 0x7f)
#endif
#ifndef WEXITSTATUS
#define WEXITSTATUS(w)	(((w) & 0xff00) >> 8)
#endif
#endif /* defined (_WIN32) && ! defined (__CYGWIN__) */
#endif /* ! HAVE_SYS_WAIT_H */

#ifndef STDOUT_FILENO
#define STDOUT_FILENO 1
#endif

#if defined (_WIN32) && ! defined (__CYGWIN__)
#define popen _popen
#define pclose _pclose
#endif

/* The default preprocessor.  */

#define DEFAULT_PREPROCESSOR "gcc -E -xc -DRC_INVOKED"

/* We read the directory entries in a cursor or icon file into
   instances of this structure.  */

struct icondir
{
  /* Width of image.  */
  bfd_byte width;
  /* Height of image.  */
  bfd_byte height;
  /* Number of colors in image.  */
  bfd_byte 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.  */

FILE *cpp_pipe;

/* The temporary file used if we're not using popen, so we can delete it
   if we exit.  */

static char *cpp_temp_file;

/* Input stream is either a file or a pipe.  */

static enum {ISTREAM_PIPE, ISTREAM_FILE} istream_type;

/* As we read the rc file, we attach information to this structure.  */

static rc_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.  */

rc_fontdir *fontdirs;

/* Resource info to use for fontdirs.  */

rc_res_res_info fontdirs_resinfo;

/* The number of icon resources we have written out.  */

static int icons;

/* The windres target bfd .  */

static windres_bfd wrtarget =
{
  (bfd *) NULL, (asection *) NULL, WR_KIND_TARGET
};

/* Local functions for rcdata based resource definitions.  */

static void define_font_rcdata (rc_res_id, const rc_res_res_info *,
				rc_rcdata_item *);
static void define_icon_rcdata (rc_res_id, const rc_res_res_info *,
				rc_rcdata_item *);
static void define_bitmap_rcdata (rc_res_id, const rc_res_res_info *,
				  rc_rcdata_item *);
static void define_cursor_rcdata (rc_res_id, const rc_res_res_info *,
				  rc_rcdata_item *);
static void define_fontdir_rcdata (rc_res_id, const rc_res_res_info *,
				   rc_rcdata_item *);
static void define_messagetable_rcdata (rc_res_id, const rc_res_res_info *,
					rc_rcdata_item *);
static rc_uint_type rcdata_copy (const rc_rcdata_item *, bfd_byte *);
static bfd_byte *rcdata_render_as_buffer (const rc_rcdata_item *, rc_uint_type *);

static int run_cmd (char *, const char *);
static FILE *open_input_stream (char *);
static FILE *look_for_default
  (char *, const char *, int, const char *, const char *);
static void close_input_stream (void);
static void unexpected_eof (const char *);
static int get_word (FILE *, const char *);
static unsigned long get_long (FILE *, const char *);
static void get_data (FILE *, bfd_byte *, rc_uint_type, const char *);
static void define_fontdirs (void);

/* Run `cmd' and redirect the output to `redir'.  */

static int
run_cmd (char *cmd, const char *redir)
{
  char *s;
  int pid, wait_status, retcode;
  int i;
  const char **argv;
  char *errmsg_fmt, *errmsg_arg;
  char *temp_base = choose_temp_base ();
  int in_quote;
  char sep;
  int redir_handle = -1;
  int stdout_save = -1;

  /* Count the args.  */
  i = 0;

  for (s = cmd; *s; s++)
    if (*s == ' ')
      i++;

  i++;
  argv = alloca (sizeof (char *) * (i + 3));
  i = 0;
  s = cmd;

  while (1)
    {
      while (*s == ' ' && *s != 0)
	s++;

      if (*s == 0)
	break;

      in_quote = (*s == '\'' || *s == '"');
      sep = (in_quote) ? *s++ : ' ';
      argv[i++] = s;

      while (*s != sep && *s != 0)
	s++;

      if (*s == 0)
	break;

      *s++ = 0;

      if (in_quote)
	s++;
    }
  argv[i++] = NULL;

  /* Setup the redirection.  We can't use the usual fork/exec and redirect
     since we may be running on non-POSIX Windows host.  */

  fflush (stdout);
  fflush (stderr);

  /* Open temporary output file.  */
  redir_handle = open (redir, O_WRONLY | O_TRUNC | O_CREAT, 0666);
  if (redir_handle == -1)
    fatal (_("can't open temporary file `%s': %s"), redir,
	   strerror (errno));

  /* Duplicate the stdout file handle so it can be restored later.  */
  stdout_save = dup (STDOUT_FILENO);
  if (stdout_save == -1)
    fatal (_("can't redirect stdout: `%s': %s"), redir, strerror (errno));

  /* Redirect stdout to our output file.  */
  dup2 (redir_handle, STDOUT_FILENO);

  pid = pexecute (argv[0], (char * const *) argv, program_name, temp_base,
		  &errmsg_fmt, &errmsg_arg, PEXECUTE_ONE | PEXECUTE_SEARCH);

  /* Restore stdout to its previous setting.  */
  dup2 (stdout_save, STDOUT_FILENO);

  /* Close response file.  */
  close (redir_handle);

  if (pid == -1)
    {
      fatal ("%s %s: %s", errmsg_fmt, errmsg_arg, strerror (errno));
      return 1;
    }

  retcode = 0;
  pid = pwait (pid, &wait_status, 0);

  if (pid == -1)
    {
      fatal (_("wait: %s"), strerror (errno));
      retcode = 1;
    }
  else if (WIFSIGNALED (wait_status))
    {
      fatal (_("subprocess got fatal signal %d"), WTERMSIG (wait_status));
      retcode = 1;
    }
  else if (WIFEXITED (wait_status))
    {
      if (WEXITSTATUS (wait_status) != 0)
	{
	  fatal (_("%s exited with status %d"), cmd,
	         WEXITSTATUS (wait_status));
	  retcode = 1;
	}
    }
  else
    retcode = 1;

  return retcode;
}

static FILE *
open_input_stream (char *cmd)
{
  if (istream_type == ISTREAM_FILE)
    {
      char *fileprefix;

      fileprefix = choose_temp_base ();
      cpp_temp_file = (char *) xmalloc (strlen (fileprefix) + 5);
      sprintf (cpp_temp_file, "%s.irc", fileprefix);
      free (fileprefix);

      if (run_cmd (cmd, cpp_temp_file))
	fatal (_("can't execute `%s': %s"), cmd, strerror (errno));

      cpp_pipe = fopen (cpp_temp_file, FOPEN_RT);;
      if (cpp_pipe == NULL)
	fatal (_("can't open temporary file `%s': %s"),
	       cpp_temp_file, strerror (errno));

      if (verbose)
	fprintf (stderr,
	         _("Using temporary file `%s' to read preprocessor output\n"),
		 cpp_temp_file);
    }
  else
    {
      cpp_pipe = popen (cmd, FOPEN_RT);
      if (cpp_pipe == NULL)
	fatal (_("can't popen `%s': %s"), cmd, strerror (errno));
      if (verbose)
	fprintf (stderr, _("Using popen to read preprocessor output\n"));
    }

  xatexit (close_input_stream);
  return cpp_pipe;
}

/* Determine if FILENAME contains special characters that
   can cause problems unless the entire filename is quoted.  */

static int
filename_need_quotes (const char *filename)
{
  if (filename == NULL || (filename[0] == '-' && filename[1] == 0))
    return 0;

  while (*filename != 0)
    {
      switch (*filename)
        {
        case '&':
        case ' ':
        case '<':
        case '>':
        case '|':
        case '%':
          return 1;
        }
      ++filename;
    }
  return 0;
}

/* Look for the preprocessor program.  */

static FILE *
look_for_default (char *cmd, const char *prefix, int end_prefix,
		  const char *preprocargs, const char *filename)
{
  char *space;
  int found;
  struct stat s;
  const char *fnquotes = (filename_need_quotes (filename) ? "\"" : "");

  strcpy (cmd, prefix);

  sprintf (cmd + end_prefix, "%s", DEFAULT_PREPROCESSOR);
  space = strchr (cmd + end_prefix, ' ');
  if (space)
    *space = 0;

  if (
#if defined (__DJGPP__) || defined (__CYGWIN__) || defined (_WIN32)
      strchr (cmd, '\\') ||
#endif
      strchr (cmd, '/'))
    {
      found = (stat (cmd, &s) == 0
#ifdef HAVE_EXECUTABLE_SUFFIX
	       || stat (strcat (cmd, EXECUTABLE_SUFFIX), &s) == 0
#endif
	       );

      if (! found)
	{
	  if (verbose)
	    fprintf (stderr, _("Tried `%s'\n"), cmd);
	  return NULL;
	}
    }

  strcpy (cmd, prefix);

  sprintf (cmd + end_prefix, "%s %s %s%s%s",
	   DEFAULT_PREPROCESSOR, preprocargs, fnquotes, filename, fnquotes);

  if (verbose)
    fprintf (stderr, _("Using `%s'\n"), cmd);

  cpp_pipe = open_input_stream (cmd);
  return cpp_pipe;
}

/* Read an rc file.  */

rc_res_directory *
read_rc_file (const char *filename, const char *preprocessor,
	      const char *preprocargs, int language, int use_temp_file)
{
  char *cmd;
  const char *fnquotes = (filename_need_quotes (filename) ? "\"" : "");

  if (filename == NULL)
    filename = "-";
  /* Setup the default resource import path taken from input file.  */
  else if (strchr (filename, '/') != NULL || strchr (filename, '\\') != NULL)
    {
      char *edit, *dir;

      if (filename[0] == '/'
	  || filename[0] == '\\'
	  || filename[1] == ':')
        /* Absolute path.  */
	edit = dir = xstrdup (filename);
      else
	{
	  /* Relative path.  */
	  edit = dir = xmalloc (strlen (filename) + 3);
	  sprintf (dir, "./%s", filename);
	}

      /* Walk dir backwards stopping at the first directory separator.  */
      edit += strlen (dir);
      while (edit > dir && (edit[-1] != '\\' && edit[-1] != '/'))
	{
	  --edit;
	  edit[0] = 0;
	}

      /* Cut off trailing slash.  */
      --edit;
      edit[0] = 0;

      /* Convert all back slashes to forward slashes.  */
      while ((edit = strchr (dir, '\\')) != NULL)
	*edit = '/';

      windres_add_include_dir (dir);
    }

  istream_type = (use_temp_file) ? ISTREAM_FILE : ISTREAM_PIPE;

  if (preprocargs == NULL)
    preprocargs = "";

  if (preprocessor)
    {
      cmd = xmalloc (strlen (preprocessor)
		     + strlen (preprocargs)
		     + strlen (filename)
		     + strlen (fnquotes) * 2
		     + 10);
      sprintf (cmd, "%s %s %s%s%s", preprocessor, preprocargs,
	       fnquotes, filename, fnquotes);

      cpp_pipe = open_input_stream (cmd);
    }
  else
    {
      char *dash, *slash, *cp;

      preprocessor = DEFAULT_PREPROCESSOR;

      cmd = xmalloc (strlen (program_name)
		     + strlen (preprocessor)
		     + strlen (preprocargs)
		     + strlen (filename)
		     + strlen (fnquotes) * 2
#ifdef HAVE_EXECUTABLE_SUFFIX
		     + strlen (EXECUTABLE_SUFFIX)
#endif
		     + 10);


      dash = slash = 0;
      for (cp = program_name; *cp; cp++)
	{
	  if (*cp == '-')
	    dash = cp;
	  if (
#if defined (__DJGPP__) || defined (__CYGWIN__) || defined(_WIN32)
	      *cp == ':' || *cp == '\\' ||
#endif
	      *cp == '/')
	    {
	      slash = cp;
	      dash = 0;
	    }
	}

      cpp_pipe = 0;

      if (dash)
	{
	  /* First, try looking for a prefixed gcc in the windres
	     directory, with the same prefix as windres */

	  cpp_pipe = look_for_default (cmd, program_name, dash - program_name + 1,
				       preprocargs, filename);
	}

      if (slash && ! cpp_pipe)
	{
	  /* Next, try looking for a gcc in the same directory as
             that windres */

	  cpp_pipe = look_for_default (cmd, program_name, slash - program_name + 1,
				       preprocargs, filename);
	}

      if (! cpp_pipe)
	{
	  /* Sigh, try the default */

	  cpp_pipe = look_for_default (cmd, "", 0, preprocargs, filename);
	}

    }

  free (cmd);

  rc_filename = xstrdup (filename);
  rc_lineno = 1;
  if (language != -1)
    rcparse_set_language (language);
  yyparse ();
  rcparse_discard_strings ();

  close_input_stream ();

  if (fontdirs != NULL)
    define_fontdirs ();

  free (rc_filename);
  rc_filename = NULL;

  return resources;
}

/* Close the input stream if it is open.  */

static void
close_input_stream (void)
{
  if (istream_type == ISTREAM_FILE)
    {
      if (cpp_pipe != NULL)
	fclose (cpp_pipe);

      if (cpp_temp_file != NULL)
	{
	  int errno_save = errno;

	  unlink (cpp_temp_file);
	  errno = errno_save;
	  free (cpp_temp_file);
	}
    }
  else
    {
      if (cpp_pipe != NULL)
        {
	  int err;
	  err = pclose (cpp_pipe);
	  /* We are reading from a pipe, therefore we don't
             know if cpp failed or succeeded until pclose.  */
	  if (err != 0 || errno == ECHILD)
	    {
	      /* Since this is also run via xatexit, safeguard.  */
	      cpp_pipe = NULL;
	      cpp_temp_file = NULL;
	      fatal (_("preprocessing failed."));
	    }
        }
    }

  /* Since this is also run via xatexit, safeguard.  */
  cpp_pipe = NULL;
  cpp_temp_file = NULL;
}

/* Report an error while reading an rc file.  */

void
yyerror (const char *msg)
{
  fatal ("%s:%d: %s", rc_filename, rc_lineno, msg);
}

/* Issue a warning while reading an rc file.  */

void
rcparse_warning (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 (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 (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 (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 (FILE *e, bfd_byte *p, rc_uint_type c, const char *msg)
{
  rc_uint_type got; // $$$d

  got = (rc_uint_type) fread (p, 1, c, e);
  if (got == c)
    return;

  fatal (_("%s: read of %lu returned %lu"),
	 msg, (unsigned long) c, (unsigned long) got);
}

/* Define an accelerator resource.  */

void
define_accelerator (rc_res_id id, const rc_res_res_info *resinfo,
		    rc_accelerator *data)
{
  rc_res_resource *r;

  r = define_standard_resource (&resources, RT_ACCELERATOR, 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 (rc_res_id id, const rc_res_res_info *resinfo,
	       const char *filename)
{
  FILE *e;
  char *real_filename;
  struct stat s;
  bfd_byte *data;
  rc_uint_type i;
  rc_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 = (bfd_byte *) 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 (rc_res_id id, const rc_res_res_info *resinfo,
	       const char *filename)
{
  FILE *e;
  char *real_filename;
  int type, count, i;
  struct icondir *icondirs;
  int first_cursor;
  rc_res_resource *r;
  rc_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++)
    {
      bfd_byte *data;
      rc_res_id name;
      rc_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 = (bfd_byte *) res_alloc (icondirs[i].bytes);

      get_data (e, data, icondirs[i].bytes, real_filename);

      c = (rc_cursor *) res_alloc (sizeof (rc_cursor));
      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++)
    {
      rc_group_cursor *cg;

      cg = (rc_group_cursor *) res_alloc (sizeof (rc_group_cursor));
      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 (rc_res_id id, const rc_res_res_info *resinfo,
	       const rc_dialog *dialog)
{
  rc_dialog *copy;
  rc_res_resource *r;

  copy = (rc_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.  */

rc_dialog_control *
define_control (const rc_res_id iid, rc_uint_type id, rc_uint_type x,
		rc_uint_type y, rc_uint_type width, rc_uint_type height,
		const rc_res_id class, rc_uint_type style,
		rc_uint_type exstyle)
{
  rc_dialog_control *n;

  n = (rc_dialog_control *) res_alloc (sizeof (rc_dialog_control));
  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 = class;
  n->text = iid;
  n->data = NULL;
  n->help = 0;

  return n;
}

rc_dialog_control *
define_icon_control (rc_res_id iid, rc_uint_type id, rc_uint_type x,
		     rc_uint_type y, rc_uint_type style,
		     rc_uint_type exstyle, rc_uint_type help,
		     rc_rcdata_item *data, rc_dialog_ex *ex)
{
  rc_dialog_control *n;
  rc_res_id tid;
  rc_res_id cid;

  if (style == 0)
    style = SS_ICON | WS_CHILD | WS_VISIBLE;
  res_string_to_id (&tid, "");
  cid.named = 0;
  cid.u.id = CTL_STATIC;
  n = define_control (tid, id, x, y, 0, 0, cid, style, exstyle);
  n->text = iid;
  if (help && ! ex)
    rcparse_warning (_("help ID requires DIALOGEX"));
  if (data && ! ex)
    rcparse_warning (_("control data requires DIALOGEX"));
  n->help = help;
  n->data = data;

  return n;
}

/* Define a font resource.  */

void
define_font (rc_res_id id, const rc_res_res_info *resinfo,
	     const char *filename)
{
  FILE *e;
  char *real_filename;
  struct stat s;
  bfd_byte *data;
  rc_res_resource *r;
  long offset;
  long fontdatalength;
  bfd_byte *fontdata;
  rc_fontdir *fd;
  const char *device, *face;
  rc_fontdir **pp;

  e = open_file_search (filename, FOPEN_RB, "font file", &real_filename);

  if (stat (real_filename, &s) < 0)
    fatal (_("stat failed on font file `%s': %s"), real_filename,
	   strerror (errno));

  data = (bfd_byte *) 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 = (bfd_byte *) res_alloc (fontdatalength);
  memcpy (fontdata, data, 56);
  strcpy ((char *) fontdata + 56, device);
  strcpy ((char *) fontdata + 57 + strlen (device), face);

  fd = (rc_fontdir *) res_alloc (sizeof (rc_fontdir));
  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;
}

static void
define_font_rcdata (rc_res_id id,const rc_res_res_info *resinfo,
		    rc_rcdata_item *data)
{
  rc_res_resource *r;
  rc_uint_type len_data;
  bfd_byte *pb_data;

  r = define_standard_resource (&resources, RT_FONT, id,
				resinfo->language, 0);

  pb_data = rcdata_render_as_buffer (data, &len_data);

  r->type = RES_TYPE_FONT;
  r->u.data.length = len_data;
  r->u.data.data = pb_data;
  r->res_info = *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 (void)
{
  rc_res_resource *r;
  rc_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;
}

static bfd_byte *
rcdata_render_as_buffer (const rc_rcdata_item *data, rc_uint_type *plen)
{
  const rc_rcdata_item *d;
  bfd_byte *ret = NULL, *pret;
  rc_uint_type len = 0;

  for (d = data; d != NULL; d = d->next)
    len += rcdata_copy (d, NULL);
  if (len != 0)
    {
      ret = pret = (bfd_byte *) res_alloc (len);
      for (d = data; d != NULL; d = d->next)
	pret += rcdata_copy (d, pret);
    }
  if (plen)
    *plen = len;
  return ret;
}

static void
define_fontdir_rcdata (rc_res_id id,const rc_res_res_info *resinfo,
		       rc_rcdata_item *data)
{
  rc_res_resource *r;
  rc_fontdir *fd, *fd_first, *fd_cur;
  rc_uint_type len_data;
  bfd_byte *pb_data;
  rc_uint_type c;

  fd_cur = fd_first = NULL;
  r = define_standard_resource (&resources, RT_FONTDIR, id, 0x409, 0);

  pb_data = rcdata_render_as_buffer (data, &len_data);

  if (pb_data)
    {
      rc_uint_type off = 2;
      c = windres_get_16 (&wrtarget, pb_data, len_data);
      for (; c > 0; c--)
	{
	  size_t len;
	  rc_uint_type safe_pos = off;
	  const struct bin_fontdir_item *bfi;

	  bfi = (const struct bin_fontdir_item *) pb_data + off;
	  fd = (rc_fontdir *) res_alloc (sizeof (rc_fontdir));
	  fd->index = windres_get_16 (&wrtarget, bfi->index, len_data - off);
	  fd->data = pb_data + off;
	  off += 56;
	  len = strlen ((char *) bfi->device_name) + 1;
	  off += (rc_uint_type) len;
	  off += (rc_uint_type) strlen ((char *) bfi->device_name + len) + 1;
	  fd->length = (off - safe_pos);
	  fd->next = NULL;
	  if (fd_first == NULL)
	    fd_first = fd;
	  else
	    fd_cur->next = fd;
	  fd_cur = fd;
	}
    }
  r->type = RES_TYPE_FONTDIR;
  r->u.fontdir = fd_first;
  r->res_info = *resinfo;
}

static void define_messagetable_rcdata (rc_res_id id, const rc_res_res_info *resinfo,
					rc_rcdata_item *data)
{
  rc_res_resource *r;
  rc_uint_type len_data;
  bfd_byte *pb_data;

  r = define_standard_resource (&resources, RT_MESSAGETABLE, id, resinfo->language, 0);

  pb_data = rcdata_render_as_buffer (data, &len_data);
  r->type = RES_TYPE_MESSAGETABLE;
  r->u.data.length = len_data;
  r->u.data.data = pb_data;
  r->res_info = *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 (rc_res_id id, const rc_res_res_info *resinfo,
	     const char *filename)
{
  FILE *e;
  char *real_filename;
  int type, count, i;
  struct icondir *icondirs;
  int first_icon;
  rc_res_resource *r;
  rc_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++)
    {
      bfd_byte *data;
      rc_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 = (bfd_byte *) 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++)
    {
      rc_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 = (rc_group_icon *) res_alloc (sizeof (rc_group_icon));
      cg->next = NULL;
      cg->width = icondirs[i].width;
      cg->height = icondirs[i].height;
      cg->colors = icondirs[i].colorcount;

      if (icondirs[i].u.icon.planes)
	cg->planes = icondirs[i].u.icon.planes;
      else
	cg->planes = 1;

      if (icondirs[i].u.icon.bits)
	cg->bits = icondirs[i].u.icon.bits;
      else
	{
	  cg->bits = 0;

	  while ((1L << 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;
}

static void
define_group_icon_rcdata (rc_res_id id, const rc_res_res_info *resinfo,
			  rc_rcdata_item *data)
{
  rc_res_resource *r;
  rc_group_icon *cg, *first, *cur;
  rc_uint_type len_data;
  bfd_byte *pb_data;

  pb_data = rcdata_render_as_buffer (data, &len_data);

  cur = NULL;
  first = NULL;

  while (len_data >= 6)
    {
      int c, i;
      unsigned short type;
      type = windres_get_16 (&wrtarget, pb_data + 2, len_data - 2);
      if (type != 1)
	fatal (_("unexpected group icon type %d"), type);
      c = windres_get_16 (&wrtarget, pb_data + 4, len_data - 4);
      len_data -= 6;
      pb_data += 6;

      for (i = 0; i < c; i++)
	{
	  if (len_data < 14)
	    fatal ("too small group icon rcdata");
	  cg = (rc_group_icon *) res_alloc (sizeof (rc_group_icon));
	  cg->next = NULL;
	  cg->width = pb_data[0];
	  cg->height = pb_data[1];
	  cg->colors = pb_data[2];
	  cg->planes = windres_get_16 (&wrtarget, pb_data + 4, len_data - 4);
	  cg->bits =  windres_get_16 (&wrtarget, pb_data + 6, len_data - 6);
	  cg->bytes = windres_get_32 (&wrtarget, pb_data + 8, len_data - 8);
	  cg->index = windres_get_16 (&wrtarget, pb_data + 12, len_data - 12);
	  if (! first)
	    first = cg;
	  else
	    cur->next = cg;
	  cur = cg;
	  pb_data += 14;
	  len_data -= 14;
	}
    }
  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;
}

static void
define_group_cursor_rcdata (rc_res_id id, const rc_res_res_info *resinfo,
			    rc_rcdata_item *data)
{
  rc_res_resource *r;
  rc_group_cursor *cg, *first, *cur;
  rc_uint_type len_data;
  bfd_byte *pb_data;

  pb_data = rcdata_render_as_buffer (data, &len_data);

  first = cur = NULL;

  while (len_data >= 6)
    {
      int c, i;
      unsigned short type;
      type = windres_get_16 (&wrtarget, pb_data + 2, len_data - 2);
      if (type != 2)
	fatal (_("unexpected group cursor type %d"), type);
      c = windres_get_16 (&wrtarget, pb_data + 4, len_data - 4);
      len_data -= 6;
      pb_data += 6;

      for (i = 0; i < c; i++)
	{
	  if (len_data < 14)
	    fatal ("too small group icon rcdata");
	  cg = (rc_group_cursor *) res_alloc (sizeof (rc_group_cursor));
	  cg->next = NULL;
	  cg->width = windres_get_16 (&wrtarget, pb_data, len_data);
	  cg->height = windres_get_16 (&wrtarget, pb_data + 2, len_data - 2);
	  cg->planes = windres_get_16 (&wrtarget, pb_data + 4, len_data - 4);
	  cg->bits =  windres_get_16 (&wrtarget, pb_data + 6, len_data - 6);
	  cg->bytes = windres_get_32 (&wrtarget, pb_data + 8, len_data - 8);
	  cg->index = windres_get_16 (&wrtarget, pb_data + 12, len_data - 12);
	  if (! first)
	    first = cg;
	  else
	    cur->next = cg;
	  cur = cg;
	  pb_data += 14;
	  len_data -= 14;
	}
    }

  r = define_standard_resource (&resources, RT_GROUP_ICON, id,
				resinfo->language, 0);
  r->type = RES_TYPE_GROUP_CURSOR;
  r->u.group_cursor = first;
  r->res_info = *resinfo;
}

static void
define_cursor_rcdata (rc_res_id id, const rc_res_res_info *resinfo,
		      rc_rcdata_item *data)
{
  rc_cursor *c;
  rc_res_resource *r;
  rc_uint_type len_data;
  bfd_byte *pb_data;

  pb_data = rcdata_render_as_buffer (data, &len_data);

  c = (rc_cursor *) res_alloc (sizeof (rc_cursor));
  c->xhotspot = windres_get_16 (&wrtarget, pb_data, len_data);
  c->yhotspot = windres_get_16 (&wrtarget, pb_data + 2, len_data - 2);
  c->length = len_data - BIN_CURSOR_SIZE;
  c->data = (const bfd_byte *) (data + BIN_CURSOR_SIZE);

  r = define_standard_resource (&resources, RT_CURSOR, id, resinfo->language, 0);
  r->type = RES_TYPE_CURSOR;
  r->u.cursor = c;
  r->res_info = *resinfo;
}

static void
define_bitmap_rcdata (rc_res_id id, const rc_res_res_info *resinfo,
		      rc_rcdata_item *data)
{
  rc_res_resource *r;
  rc_uint_type len_data;
  bfd_byte *pb_data;

  pb_data = rcdata_render_as_buffer (data, &len_data);

  r = define_standard_resource (&resources, RT_BITMAP, id, resinfo->language, 0);
  r->type = RES_TYPE_BITMAP;
  r->u.data.length = len_data;
  r->u.data.data = pb_data;
  r->res_info = *resinfo;
}

static void
define_icon_rcdata (rc_res_id id, const rc_res_res_info *resinfo,
		    rc_rcdata_item *data)
{
  rc_res_resource *r;
  rc_uint_type len_data;
  bfd_byte *pb_data;

  pb_data = rcdata_render_as_buffer (data, &len_data);

  r = define_standard_resource (&resources, RT_ICON, id, resinfo->language, 0);
  r->type = RES_TYPE_ICON;
  r->u.data.length = len_data;
  r->u.data.data = pb_data;
  r->res_info = *resinfo;
}

/* Define a menu resource.  */

void
define_menu (rc_res_id id, const rc_res_res_info *resinfo,
	     rc_menuitem *menuitems)
{
  rc_menu *m;
  rc_res_resource *r;

  m = (rc_menu *) res_alloc (sizeof (rc_menu));
  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.  */

rc_menuitem *
define_menuitem (const unichar *text, rc_uint_type menuid, rc_uint_type type,
		 rc_uint_type state, rc_uint_type help,
		 rc_menuitem *menuitems)
{
  rc_menuitem *mi;

  mi = (rc_menuitem *) res_alloc (sizeof (rc_menuitem));
  mi->next = NULL;
  mi->type = type;
  mi->state = state;
  mi->id = menuid;
  mi->text = unichar_dup (text);
  mi->help = help;
  mi->popup = menuitems;
  return mi;
}

/* Define a messagetable resource.  */

void
define_messagetable (rc_res_id id, const rc_res_res_info *resinfo,
		     const char *filename)
{
  FILE *e;
  char *real_filename;
  struct stat s;
  bfd_byte *data;
  rc_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 = (bfd_byte *) 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 (rc_res_id id, const rc_res_res_info *resinfo,
	       rc_rcdata_item *data)
{
  rc_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.  */

rc_rcdata_item *
define_rcdata_string (const char *string, rc_uint_type len)
{
  rc_rcdata_item *ri;
  char *s;

  ri = (rc_rcdata_item *) res_alloc (sizeof (rc_rcdata_item));
  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 unicode string.  */

rc_rcdata_item *
define_rcdata_unistring (const unichar *string, rc_uint_type len)
{
  rc_rcdata_item *ri;
  unichar *s;

  ri = (rc_rcdata_item *) res_alloc (sizeof (rc_rcdata_item));
  ri->next = NULL;
  ri->type = RCDATA_WSTRING;
  ri->u.wstring.length = len;
  s = (unichar *) res_alloc (len * sizeof (unichar));
  memcpy (s, string, len * sizeof (unichar));
  ri->u.wstring.w = s;

  return ri;
}

/* Create an rcdata item holding a number.  */

rc_rcdata_item *
define_rcdata_number (rc_uint_type val, int dword)
{
  rc_rcdata_item *ri;

  ri = (rc_rcdata_item *) res_alloc (sizeof (rc_rcdata_item));
  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 (const rc_res_res_info *resinfo,
		    rc_uint_type stringid, const unichar *string, int len)
{
  unichar *h;
  rc_res_id id;
  rc_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 = ((rc_stringtable *)
			  res_alloc (sizeof (rc_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;
    }
  h = (unichar *) res_alloc ((len + 1) * sizeof (unichar));
  if (len)
    memcpy (h, string, len * sizeof (unichar));
  h[len] = 0;
  r->u.stringtable->strings[stringid & 0xf].length = (rc_uint_type) len;
  r->u.stringtable->strings[stringid & 0xf].string = h;
}

void
define_toolbar (rc_res_id id, rc_res_res_info *resinfo, rc_uint_type width, rc_uint_type height,
		rc_toolbar_item *items)
{
  rc_toolbar *t;
  rc_res_resource *r;

  t = (rc_toolbar *) res_alloc (sizeof (rc_toolbar));
  t->button_width = width;
  t->button_height = height;
  t->nitems = 0;
  t->items = items;
  while (items != NULL)
  {
    t->nitems+=1;
    items = items->next;
  }
  r = define_standard_resource (&resources, RT_TOOLBAR, id, resinfo->language, 0);
  r->type = RES_TYPE_TOOLBAR;
  r->u.toolbar = t;
  r->res_info = *resinfo;
}

/* Define a user data resource where the data is in the rc file.  */

void
define_user_data (rc_res_id id, rc_res_id type,
		  const rc_res_res_info *resinfo,
		  rc_rcdata_item *data)
{
  rc_res_id ids[3];
  rc_res_resource *r;
  bfd_byte *pb_data;
  rc_uint_type len_data;

  /* We have to check if the binary data is parsed specially.  */
  if (type.named == 0)
    {
      switch (type.u.id)
      {
      case RT_FONTDIR:
	define_fontdir_rcdata (id, resinfo, data);
	return;
      case RT_FONT:
	define_font_rcdata (id, resinfo, data);
	return;
      case RT_ICON:
	define_icon_rcdata (id, resinfo, data);
	return;
      case RT_BITMAP:
	define_bitmap_rcdata (id, resinfo, data);
	return;
      case RT_CURSOR:
	define_cursor_rcdata (id, resinfo, data);
	return;
      case RT_GROUP_ICON:
	define_group_icon_rcdata (id, resinfo, data);
	return;
      case RT_GROUP_CURSOR:
	define_group_cursor_rcdata (id, resinfo, data);
	return;
      case RT_MESSAGETABLE:
	define_messagetable_rcdata (id, resinfo, data);
	return;
      default:
	/* Treat as normal user-data.  */
	break;
      }
    }
  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 = ((rc_rcdata_item *)
		   res_alloc (sizeof (rc_rcdata_item)));
  r->u.userdata->next = NULL;
  r->u.userdata->type = RCDATA_BUFFER;
  pb_data = rcdata_render_as_buffer (data, &len_data);
  r->u.userdata->u.buffer.length = len_data;
  r->u.userdata->u.buffer.data = pb_data;
  r->res_info = *resinfo;
}

void
define_rcdata_file (rc_res_id id, const rc_res_res_info *resinfo,
		    const char *filename)
{
  rc_rcdata_item *ri;
  FILE *e;
  char *real_filename;
  struct stat s;
  bfd_byte *data;

  e = open_file_search (filename, FOPEN_RB, "file", &real_filename);


  if (stat (real_filename, &s) < 0)
    fatal (_("stat failed on file `%s': %s"), real_filename,
	   strerror (errno));

  data = (bfd_byte *) res_alloc (s.st_size);

  get_data (e, data, s.st_size, real_filename);

  fclose (e);
  free (real_filename);

  ri = (rc_rcdata_item *) res_alloc (sizeof (rc_rcdata_item));
  ri->next = NULL;
  ri->type = RCDATA_BUFFER;
  ri->u.buffer.length = s.st_size;
  ri->u.buffer.data = data;

  define_rcdata (id, resinfo, ri);
}

/* Define a user data resource where the data is in a file.  */

void
define_user_file (rc_res_id id, rc_res_id type,
		  const rc_res_res_info *resinfo, const char *filename)
{
  FILE *e;
  char *real_filename;
  struct stat s;
  bfd_byte *data;
  rc_res_id ids[3];
  rc_res_resource *r;

  e = open_file_search (filename, FOPEN_RB, "file", &real_filename);

  if (stat (real_filename, &s) < 0)
    fatal (_("stat failed on file `%s': %s"), real_filename,
	   strerror (errno));

  data = (bfd_byte *) 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 = ((rc_rcdata_item *)
		   res_alloc (sizeof (rc_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 (rc_res_id id, rc_uint_type language,
		    rc_fixed_versioninfo *fixedverinfo,
		    rc_ver_info *verinfo)
{
  rc_res_resource *r;

  r = define_standard_resource (&resources, RT_VERSION, id, language, 0);
  r->type = RES_TYPE_VERSIONINFO;
  r->u.versioninfo = ((rc_versioninfo *)
		      res_alloc (sizeof (rc_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.  */

rc_ver_info *
append_ver_stringfileinfo (rc_ver_info *verinfo,
			   rc_ver_stringtable *stringtables)
{
  rc_ver_info *vi, **pp;

  vi = (rc_ver_info *) res_alloc (sizeof (rc_ver_info));
  vi->next = NULL;
  vi->type = VERINFO_STRING;
  vi->u.string.stringtables = stringtables;

  for (pp = &verinfo; *pp != NULL; pp = &(*pp)->next)
    ;
  *pp = vi;

  return verinfo;
}

rc_ver_stringtable *
append_ver_stringtable (rc_ver_stringtable *stringtable,
			const char *language,
			rc_ver_stringinfo *strings)
{
  rc_ver_stringtable *vst, **pp;

  vst = (rc_ver_stringtable *) res_alloc (sizeof (rc_ver_stringtable));
  vst->next = NULL;
  unicode_from_ascii ((rc_uint_type *) NULL, &vst->language, language);
  vst->strings = strings;

  for (pp = &stringtable; *pp != NULL; pp = &(*pp)->next)
    ;
  *pp = vst;

  return stringtable;
}

/* Add variable version info to a list of version information.  */

rc_ver_info *
append_ver_varfileinfo (rc_ver_info *verinfo, const unichar *key,
			rc_ver_varinfo *var)
{
  rc_ver_info *vi, **pp;

  vi = (rc_ver_info *) res_alloc (sizeof *vi);
  vi->next = NULL;
  vi->type = VERINFO_VAR;
  vi->u.var.key = unichar_dup (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.  */

rc_ver_stringinfo *
append_verval (rc_ver_stringinfo *strings, const unichar *key,
	       const unichar *value)
{
  rc_ver_stringinfo *vs, **pp;

  vs = (rc_ver_stringinfo *) res_alloc (sizeof (rc_ver_stringinfo));
  vs->next = NULL;
  vs->key = unichar_dup (key);
  vs->value = unichar_dup (value);

  for (pp = &strings; *pp != NULL; pp = &(*pp)->next)
    ;
  *pp = vs;

  return strings;
}

/* Append version variable information to a list.  */

rc_ver_varinfo *
append_vertrans (rc_ver_varinfo *var, rc_uint_type language,
		 rc_uint_type charset)
{
  rc_ver_varinfo *vv, **pp;

  vv = (rc_ver_varinfo *) res_alloc (sizeof (rc_ver_varinfo));
  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 (FILE *, int);
static void write_rc_directory (FILE *, const rc_res_directory *, const rc_res_id *,
				const rc_res_id *, rc_uint_type *, int);
static void write_rc_subdir (FILE *, const rc_res_entry *, const rc_res_id *,
			     const rc_res_id *, rc_uint_type *, int);
static void write_rc_resource (FILE *, const rc_res_id *, const rc_res_id *,
			       const rc_res_resource *, rc_uint_type *);
static void write_rc_accelerators (FILE *, const rc_accelerator *);
static void write_rc_cursor (FILE *, const rc_cursor *);
static void write_rc_group_cursor (FILE *, const rc_group_cursor *);
static void write_rc_dialog (FILE *, const rc_dialog *);
static void write_rc_dialog_control (FILE *, const rc_dialog_control *);
static void write_rc_fontdir (FILE *, const rc_fontdir *);
static void write_rc_group_icon (FILE *, const rc_group_icon *);
static void write_rc_menu (FILE *, const rc_menu *, int);
static void write_rc_toolbar (FILE *, const rc_toolbar *);
static void write_rc_menuitems (FILE *, const rc_menuitem *, int, int);
static void write_rc_messagetable (FILE *, rc_uint_type , const bfd_byte *);

static void write_rc_datablock (FILE *, rc_uint_type , const bfd_byte *, int, int, int);
static void write_rc_rcdata (FILE *, const rc_rcdata_item *, int);
static void write_rc_stringtable (FILE *, const rc_res_id *, const rc_stringtable *);
static void write_rc_versioninfo (FILE *, const rc_versioninfo *);

/* Indent a given number of spaces.  */

static void
indent (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.

   Reasoned by the fact, that some resources need to be stored into file and
   refer to that file, we use the user-data model for that to express it binary
   without the need to store it somewhere externally.  */

void
write_rc_file (const char *filename, const rc_res_directory *res_dir)
{
  FILE *e;
  rc_uint_type 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 = (rc_uint_type) ((bfd_signed_vma) -1);
  write_rc_directory (e, res_dir, (const rc_res_id *) NULL,
		      (const rc_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 (FILE *e, const rc_res_directory *rd,
		    const rc_res_id *type, const rc_res_id *name,
		    rc_uint_type *language, int level)
{
  const rc_res_entry *re;

  /* Print out some COFF information that rc files can't represent.  */
  if (rd->time != 0 || rd->characteristics != 0 || rd->major != 0 || rd->minor != 0)
    {
      wr_printcomment (e, "COFF information not part of RC");
  if (rd->time != 0)
	wr_printcomment (e, "Time stamp: %u", rd->time);
  if (rd->characteristics != 0)
	wr_printcomment (e, "Characteristics: %u", rd->characteristics);
  if (rd->major != 0 || rd->minor != 0)
	wr_printcomment (e, "Version major:%d minor:%d", 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 != (unsigned long) (unsigned int) *language
	      && (re->id.u.id & 0xffff) == re->id.u.id)
	    {
	      wr_print (e, "LANGUAGE %u, %u\n",
		       re->id.u.id & ((1 << SUBLANG_SHIFT) - 1),
		       (re->id.u.id >> SUBLANG_SHIFT) & 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
	    {
	      wr_printcomment (e, "Resource at unexpected level %d", level);
	      write_rc_resource (e, type, (rc_res_id *) NULL, re->u.res,
				 language);
	    }
	}
    }
  if (rd->entries == NULL)
    {
      wr_print_flush (e);
    }
}

/* 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 (FILE *e, const rc_res_entry *re,
		 const rc_res_id *type, const rc_res_id *name,
		 rc_uint_type *language, int level)
{
  fprintf (e, "\n");
  switch (level)
    {
    case 1:
      wr_printcomment (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_ACCELERATOR: 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;
	    case RT_TOOLBAR: s = "toolbar"; break;
	    case RT_HTML: s = "html"; break;
	    default: s = NULL; break;
	    }

	  if (s != NULL)
	    fprintf (e, "%s", s);
	  else
	    res_id_print (e, re->id, 1);
	}
      break;

    case 2:
      wr_printcomment (e, "Name: ");
      res_id_print (e, re->id, 1);
      break;

    case 3:
      wr_printcomment (e, "Language: ");
      res_id_print (e, re->id, 1);
      break;

    default:
      wr_printcomment (e, "Level %d: ", level);
      res_id_print (e, re->id, 1);
    }

  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 (FILE *e, const rc_res_id *type,
		   const rc_res_id *name, const rc_res_resource *res,
		   rc_uint_type *language)
{
  const char *s;
  int rt;
  int menuex = 0;

  switch (res->type)
    {
    default:
      abort ();

    case RES_TYPE_ACCELERATOR:
      s = "ACCELERATORS";
      rt = RT_ACCELERATOR;
      break;

    case RES_TYPE_BITMAP:
      s = "2 /* RT_BITMAP */";
      rt = RT_BITMAP;
      break;

    case RES_TYPE_CURSOR:
      s = "1 /* RT_CURSOR */";
      rt = RT_CURSOR;
      break;

    case RES_TYPE_GROUP_CURSOR:
      s = "12 /* RT_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 = "8 /* RT_FONT */";
      rt = RT_FONT;
      break;

    case RES_TYPE_FONTDIR:
      s = "7 /* RT_FONTDIR */";
      rt = RT_FONTDIR;
      break;

    case RES_TYPE_ICON:
      s = "3 /* RT_ICON */";
      rt = RT_ICON;
      break;

    case RES_TYPE_GROUP_ICON:
      s = "14 /* RT_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 = "11 /* RT_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;

    case RES_TYPE_TOOLBAR:
      s = "TOOLBAR";
      rt = RT_TOOLBAR;
      break;
    }

  if (rt != 0
      && type != NULL
      && (type->named || type->u.id != (unsigned long) rt))
    {
      wr_printcomment (e, "Unexpected resource type mismatch: ");
      res_id_print (e, *type, 1);
      fprintf (e, " != %d", rt);
    }

  if (res->coff_info.codepage != 0)
    wr_printcomment (e, "Code page: %u", res->coff_info.codepage);
  if (res->coff_info.reserved != 0)
    wr_printcomment (e, "COFF reserved value: %u", res->coff_info.reserved);

  wr_print (e, "\n");
  if (rt == RT_STRING)
    ;
  else
    {
  if (name != NULL)
	res_id_print (e, *name, 1);
  else
    fprintf (e, "??Unknown-Name??");
  fprintf (e, " ");
    }

  if (s != NULL)
    fprintf (e, "%s", s);
  else if (type != NULL)
    {
      if (type->named == 0)
	{
#define PRINT_RT_NAME(NAME) case NAME: \
	fprintf (e, "%u /* %s */", (unsigned int) NAME, #NAME); \
	break

	  switch (type->u.id)
	    {
	    default:
    res_id_print (e, *type, 0);
	      break;
	
	    PRINT_RT_NAME(RT_MANIFEST);
	    PRINT_RT_NAME(RT_ANICURSOR);
	    PRINT_RT_NAME(RT_ANIICON);
	    PRINT_RT_NAME(RT_RCDATA);
	    PRINT_RT_NAME(RT_ICON);
	    PRINT_RT_NAME(RT_CURSOR);
	    PRINT_RT_NAME(RT_BITMAP);
	    PRINT_RT_NAME(RT_PLUGPLAY);
	    PRINT_RT_NAME(RT_VXD);
	    PRINT_RT_NAME(RT_FONT);
	    PRINT_RT_NAME(RT_FONTDIR);
	    PRINT_RT_NAME(RT_HTML);
	    PRINT_RT_NAME(RT_MESSAGETABLE);
	    PRINT_RT_NAME(RT_DLGINCLUDE);
	    PRINT_RT_NAME(RT_DLGINIT);
	    }
#undef PRINT_RT_NAME
	}
      else
	res_id_print (e, *type, 1);
    }
  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",
	       (int) res->u.dialog->x, (int) res->u.dialog->y,
	       (int) res->u.dialog->width, (int) res->u.dialog->height);
      if (res->u.dialog->ex != NULL
	  && res->u.dialog->ex->help != 0)
	fprintf (e, ", %u", (unsigned int) res->u.dialog->ex->help);
    }
  else if (res->type == RES_TYPE_TOOLBAR)
  {
    fprintf (e, " %d, %d", (int) res->u.toolbar->button_width,
	     (int) res->u.toolbar->button_height);
    }

  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 ? "// " : "",
		 (int) res->res_info.language & ((1<<SUBLANG_SHIFT)-1),
		 (int) (res->res_info.language >> SUBLANG_SHIFT) & 0xff);
      if (res->res_info.characteristics != 0)
	fprintf (e, "%sCHARACTERISTICS %u\n",
		 modifiers ? "// " : "",
		 (unsigned int) res->res_info.characteristics);
      if (res->res_info.version != 0)
	fprintf (e, "%sVERSION %u\n",
		 modifiers ? "// " : "",
		 (unsigned int) 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_TOOLBAR:
      write_rc_toolbar (e, res->u.toolbar);
      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:
      write_rc_datablock (e, res->u.data.length, res->u.data.data, 0, 1, 0);
      break;
    case RES_TYPE_MESSAGETABLE:
      write_rc_messagetable (e, res->u.data.length, res->u.data.data);
      break;
    }
}

/* Write out accelerator information.  */

static void
write_rc_accelerators (FILE *e, const rc_accelerator *accelerators)
{
  const rc_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 (acc->key)
	  && (acc->flags & ACC_VIRTKEY) == 0)
	{
	  fprintf (e, "\"%c\"", (char) acc->key);
	  printable = 1;
	}
      else
	{
	  fprintf (e, "%d", (int) acc->key);
	  printable = 0;
	}

      fprintf (e, ", %d", (int) 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 (FILE *e, const rc_cursor *cursor)
{
  fprintf (e, "BEGIN\n");
  indent (e, 2);
  fprintf (e, " 0x%x, 0x%x,\t/* Hotspot x: %d, y: %d.  */\n",
	   (unsigned int) cursor->xhotspot, (unsigned int) cursor->yhotspot,
	   (int) cursor->xhotspot, (int) cursor->yhotspot);
  write_rc_datablock (e, (rc_uint_type) cursor->length, (const bfd_byte *) cursor->data,
  		      0, 0, 0);
  fprintf (e, "END\n");
}

/* Write out group cursor data.  This would normally be built from the
   cursor data.  */

static void
write_rc_group_cursor (FILE *e, const rc_group_cursor *group_cursor)
{
  const rc_group_cursor *gc;
  int c;

  for (c = 0, gc = group_cursor; gc != NULL; gc = gc->next, c++)
    ;
  fprintf (e, "BEGIN\n");

  indent (e, 2);
  fprintf (e, "0, 2, %d%s\t /* Having %d items.  */\n", c, (c != 0 ? "," : ""), c);
  indent (e, 4);
  fprintf (e, "/* width, height, planes, bits, bytes, index.  */\n");

  for (c = 1, gc = group_cursor; gc != NULL; gc = gc->next, c++)
    {
      indent (e, 4);
      fprintf (e, "%d, %d, %d, %d, 0x%xL, %d%s /* Element %d. */\n",
	(int) gc->width, (int) gc->height, (int) gc->planes, (int) gc->bits,
	(unsigned int) gc->bytes, (int) gc->index, (gc->next != NULL ? "," : ""), c);
      fprintf (e, "/* width: %d; height %d; planes %d; bits %d.  */\n",
	     (int) gc->width, (int) gc->height, (int) gc->planes,
	     (int) gc->bits);
    }
  fprintf (e, "END\n");
}

/* Write dialog data.  */

static void
write_rc_dialog (FILE *e, const rc_dialog *dialog)
{
  const rc_dialog_control *control;

  fprintf (e, "STYLE 0x%x\n", dialog->style);

  if (dialog->exstyle != 0)
    fprintf (e, "EXSTYLE 0x%x\n", (unsigned int) 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, 1);
      fprintf (e, "\n");
    }

  if (dialog->caption != NULL)
    {
      fprintf (e, "CAPTION ");
      unicode_print_quoted (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, ", (int) dialog->pointsize);
      unicode_print_quoted (e, dialog->font, -1);
      if (dialog->ex != NULL
	  && (dialog->ex->weight != 0
	      || dialog->ex->italic != 0
	      || dialog->ex->charset != 1))
	fprintf (e, ", %d, %d, %d",
		 (int) dialog->ex->weight,
		 (int) dialog->ex->italic,
		 (int) dialog->ex->charset);
      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 (FILE *e, const rc_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 == NULL)
    fprintf (e, "CONTROL");
  else if (ci->name != NULL)
    fprintf (e, "%s", ci->name);
  else
    {
    fprintf (e, "CONTROL");
      ci = NULL;
    }

  /* For EDITTEXT, COMBOBOX, LISTBOX, and SCROLLBAR don't dump text.  */
  if ((control->text.named || control->text.u.id != 0)
      && (!ci
          || (ci->class != CTL_EDIT
              && ci->class != CTL_COMBOBOX
              && ci->class != CTL_LISTBOX
              && ci->class != CTL_SCROLLBAR)))
    {
      fprintf (e, " ");
      res_id_print (e, control->text, 1);
      fprintf (e, ",");
    }

  fprintf (e, " %d, ", (int) control->id);

  if (ci == NULL)
    {
      if (control->class.named)
	fprintf (e, "\"");
      res_id_print (e, control->class, 0);
      if (control->class.named)
	fprintf (e, "\"");
      fprintf (e, ", 0x%x, ", (unsigned int) control->style);
    }

  fprintf (e, "%d, %d", (int) control->x, (int) control->y);

  if (control->style != SS_ICON
      || control->exstyle != 0
      || control->width != 0
      || control->height != 0
      || control->help != 0)
    {
      fprintf (e, ", %d, %d", (int) control->width, (int) 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.  */
      if (ci != NULL)
	fprintf (e, ", 0x%x", (unsigned int) control->style);

      if (control->exstyle != 0 || control->help != 0)
	fprintf (e, ", 0x%x, %u", (unsigned int) control->exstyle,
		 (unsigned int) 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 (FILE *e, const rc_fontdir *fontdir)
{
  const rc_fontdir *fc;
  int c;

  for (c = 0, fc = fontdir; fc != NULL; fc = fc->next, c++)
    ;
  fprintf (e, "BEGIN\n");
  indent (e, 2);
  fprintf (e, "%d%s\t /* Has %d elements.  */\n", c, (c != 0 ? "," : ""), c);
  for (c = 1, fc = fontdir; fc != NULL; fc = fc->next, c++)
    {
      indent (e, 4);
      fprintf (e, "%d,\t/* Font no %d with index %d.  */\n",
	(int) fc->index, c, (int) fc->index);
      write_rc_datablock (e, (rc_uint_type) fc->length - 2,
			  (const bfd_byte *) fc->data + 4,fc->next != NULL,
			  0, 0);
    }
  fprintf (e, "END\n");
}

/* Write out group icon data.  This would normally be built from the
   icon data.  */

static void
write_rc_group_icon (FILE *e, const rc_group_icon *group_icon)
{
  const rc_group_icon *gi;
  int c;

  for (c = 0, gi = group_icon; gi != NULL; gi = gi->next, c++)
    ;

  fprintf (e, "BEGIN\n");
  indent (e, 2);
  fprintf (e, " 0, 1, %d%s\t /* Has %d elements.  */\n", c, (c != 0 ? "," : ""), c);

  indent (e, 4);
  fprintf (e, "/* \"width height colors pad\", planes, bits, bytes, index.  */\n");
  for (c = 1, gi = group_icon; gi != NULL; gi = gi->next, c++)
    {
      indent (e, 4);
      fprintf (e, "\"\\%03o\\%03o\\%03o\\%03o\", %d, %d, 0x%xL, %d%s\t/* Element no %d.  */\n",
	gi->width, gi->height, gi->colors, 0, (int) gi->planes, (int) gi->bits,
	(unsigned int) gi->bytes, (int) gi->index, (gi->next != NULL ? "," : ""), c);
    }
  fprintf (e, "END\n");
}

/* Write out a menu resource.  */

static void
write_rc_menu (FILE *e, const rc_menu *menu, int menuex)
{
  if (menu->help != 0)
    fprintf (e, "// Help ID: %u\n", (unsigned int) menu->help);
  write_rc_menuitems (e, menu->items, menuex, 0);
}

static void
write_rc_toolbar (FILE *e, const rc_toolbar *tb)
{
  rc_toolbar_item *it;
  indent (e, 0);
  fprintf (e, "BEGIN\n");
  it = tb->items;
  while(it != NULL)
  {
    indent (e, 2);
    if (it->id.u.id == 0)
      fprintf (e, "SEPARATOR\n");
    else 
      fprintf (e, "BUTTON %d\n", (int) it->id.u.id);
    it = it->next;
  }
  indent (e, 0);
  fprintf (e, "END\n");
}

/* Write out menuitems.  */

static void
write_rc_menuitems (FILE *e, const rc_menuitem *menuitems, int menuex,
		    int ind)
{
  const rc_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_quoted (e, mi->text, -1);
	}

      if (! menuex)
	{
	  if (mi->popup == NULL)
	    fprintf (e, ", %d", (int) 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", (int) mi->id);
	      if (mi->type != 0 || mi->state != 0 || mi->help != 0)
		{
		  fprintf (e, ", %u", (unsigned int) mi->type);
		  if (mi->state != 0 || mi->help != 0)
		    {
		      fprintf (e, ", %u", (unsigned int) mi->state);
		      if (mi->help != 0)
			fprintf (e, ", %u", (unsigned int) 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");
}

static int
test_rc_datablock_unicode (rc_uint_type length, const bfd_byte *data)
{
  rc_uint_type i;
  if ((length & 1) != 0)
    return 0;

  for (i = 0; i < length; i += 2)
    {
      if (data[i] == 0 && data[i + 1] == 0 && (i + 2) < length)
	return 0;
      if (data[i] == 0xff && data[i + 1] == 0xff)
	return 0;
    }
  return 1;
}

static int
test_rc_datablock_text (rc_uint_type length, const bfd_byte *data)
{
  int has_nl;
  rc_uint_type c;
  rc_uint_type i;
  
  if (length <= 1)
    return 0;

  has_nl = 0;
  for (i = 0, c = 0; i < length; i++)
    {
      if (! ISPRINT (data[i]) && data[i] != '\n'
      	  && ! (data[i] == '\r' && (i + 1) < length && data[i + 1] == '\n')
      	  && data[i] != '\t'
	  && ! (data[i] == 0 && (i + 1) != length))
	{
	  if (data[i] <= 7)
	    return 0;
	  c++;
	}
      else if (data[i] == '\n') has_nl++;
    }
  if (length > 80 && ! has_nl)
    return 0;
  c = (((c * 10000) + (i / 100) - 1)) / i;
  if (c >= 150)
    return 0;
  return 1;
}

static void
write_rc_messagetable (FILE *e, rc_uint_type length, const bfd_byte *data)
{
  int has_error = 0;
  const struct bin_messagetable *mt;
  fprintf (e, "BEGIN\n");

  write_rc_datablock (e, length, data, 0, 0, 0);

  fprintf (e, "\n");
  wr_printcomment (e, "MC syntax dump");
  if (length < BIN_MESSAGETABLE_SIZE)
    has_error = 1;
  else
    do {
      rc_uint_type m, i;
      mt = (const struct bin_messagetable *) data;
      m = windres_get_32 (&wrtarget, mt->cblocks, length);
      if (length < (BIN_MESSAGETABLE_SIZE + m * BIN_MESSAGETABLE_BLOCK_SIZE))
	{
	  has_error = 1;
	  break;
	}
      for (i = 0; i < m; i++)
	{
	  rc_uint_type low, high, offset;
	  const struct bin_messagetable_item *mti;

	  low = windres_get_32 (&wrtarget, mt->items[i].lowid, 4);
	  high = windres_get_32 (&wrtarget, mt->items[i].highid, 4);
	  offset = windres_get_32 (&wrtarget, mt->items[i].offset, 4);
	  while (low <= high)
	    {
	      rc_uint_type elen, flags;
	      if ((offset + BIN_MESSAGETABLE_ITEM_SIZE) > length)
		{
		  has_error = 1;
	  break;
		}
	      mti = (const struct bin_messagetable_item *) &data[offset];
	      elen = windres_get_16 (&wrtarget, mti->length, 2);
	      flags = windres_get_16 (&wrtarget, mti->flags, 2);
	      if ((offset + elen) > length)
		{
		  has_error = 1;
		  break;
		}
	      wr_printcomment (e, "MessageId = 0x%x", low);
	      wr_printcomment (e, "");
	      if ((flags & MESSAGE_RESOURCE_UNICODE) == MESSAGE_RESOURCE_UNICODE)
		unicode_print (e, (const unichar *) mti->data,
			       (elen - BIN_MESSAGETABLE_ITEM_SIZE) / 2);
	      else
		ascii_print (e, (const char *) mti->data,
			     (elen - BIN_MESSAGETABLE_ITEM_SIZE));
	      wr_printcomment (e,"");
	      ++low;
	      offset += elen;
	    }
	}
    } while (0);
  if (has_error)
    wr_printcomment (e, "Illegal data");
  wr_print_flush (e);
  fprintf (e, "END\n");
}

static void
write_rc_datablock (FILE *e, rc_uint_type length, const bfd_byte *data, int has_next,
		    int hasblock, int show_comment)
{
  int plen;

  if (hasblock)
    fprintf (e, "BEGIN\n");

  if (show_comment == -1)
	  {
      if (test_rc_datablock_text(length, data))
	{
	  rc_uint_type i, c;
	  for (i = 0; i < length;)
	    {
	      indent (e, 2);
	      fprintf (e, "\"");

	      for (c = 0; i < length && c < 160 && data[i] != '\n'; c++, i++)
		;
	      if (i < length && data[i] == '\n')
		++i, ++c;
	      ascii_print (e, (const char *) &data[i - c], c);
	    fprintf (e, "\"");
	      if (i < length)
		fprintf (e, "\n");
	    }
          
	  if (i == 0)
	      {
	      indent (e, 2);
	      fprintf (e, "\"\"");
	      }
	  if (has_next)
	    fprintf (e, ",");
	  fprintf (e, "\n");
	  if (hasblock)
	    fprintf (e, "END\n");
	  return;
	  }
      if (test_rc_datablock_unicode (length, data))
	{
	  rc_uint_type i, c;
	  for (i = 0; i < length;)
	    {
	      const unichar *u;

	      u = (const unichar *) &data[i];
	      indent (e, 2);
	  fprintf (e, "L\"");
    	  
	      for (c = 0; i < length && c < 160 && u[c] != '\n'; c++, i += 2)
		;
	      if (i < length && u[c] == '\n')
		i += 2, ++c;
	      unicode_print (e, u, c);
	  fprintf (e, "\"");
	      if (i < length)
		fprintf (e, "\n");
	    }

	  if (i == 0)
	  {
	      indent (e, 2);
	      fprintf (e, "L\"\"");
	    }
	  if (has_next)
	    fprintf (e, ",");
	  fprintf (e, "\n");
	  if (hasblock)
	    fprintf (e, "END\n");
	  return;
	}

      show_comment = 0;
    }

  if (length != 0)
	      {
      rc_uint_type i, max_row;
      int first = 1;

      max_row = (show_comment ? 4 : 8);
      indent (e, 2);
      for (i = 0; i + 3 < length;)
		  {
	  rc_uint_type k;
	  rc_uint_type comment_start;
	  
	  comment_start = i;
	  
	  if (! first)
	    indent (e, 2);

	  for (k = 0; k < max_row && i + 3 < length; k++, i += 4)
		      {
	      if (k == 0)
		plen  = fprintf (e, "0x%lxL",
				 (unsigned long) windres_get_32 (&wrtarget, data + i, length - i));
			else
		plen = fprintf (e, " 0x%lxL",
				(unsigned long) windres_get_32 (&wrtarget, data + i, length - i)) - 1;
	      if (has_next || (i + 4) < length)
			  {
		  if (plen>0 && plen < 11)
		    indent (e, 11 - plen);
		  fprintf (e, ",");
			  }
		      }
	  if (show_comment)
	    {
	      fprintf (e, "\t/* ");
	      ascii_print (e, (const char *) &data[comment_start], i - comment_start);
	      fprintf (e, ".  */");
		  }
		fprintf (e, "\n");
		first = 0;
	      }

      if (i + 1 < length)
	      {
		if (! first)
	    indent (e, 2);
	  plen = fprintf (e, "0x%x",
	  		  (int) windres_get_16 (&wrtarget, data + i, length - i));
	  if (has_next || i + 2 < length)
		  {
	      if (plen > 0 && plen < 11)
		indent (e, 11 - plen);
	      fprintf (e, ",");
		      }
	  if (show_comment)
	    {
	      fprintf (e, "\t/* ");
	      ascii_print (e, (const char *) &data[i], 2);
	      fprintf (e, ".  */");
		  }
		fprintf (e, "\n");
		i += 2;
		first = 0;
	      }

      if (i < length)
	      {
		if (! first)
	    indent (e, 2);
	  fprintf (e, "\"");
	  ascii_print (e, (const char *) &data[i], 1);
	  fprintf (e, "\"");
	  if (has_next)
		  fprintf (e, ",");
		fprintf (e, "\n");
		first = 0;
	      }
    }
  if (hasblock)
    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 (FILE *e, const rc_rcdata_item *rcdata, int ind)
{
  const rc_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;

      switch (ri->type)
	{
	default:
	  abort ();

	case RCDATA_WORD:
	  indent (e, ind + 2);
	  fprintf (e, "%ld", (long) (ri->u.word & 0xffff));
	  break;

	case RCDATA_DWORD:
	  indent (e, ind + 2);
	  fprintf (e, "%luL", (unsigned long) ri->u.dword);
	  break;

	case RCDATA_STRING:
	  indent (e, ind + 2);
	  fprintf (e, "\"");
	  ascii_print (e, ri->u.string.s, ri->u.string.length);
	  fprintf (e, "\"");
	  break;

	case RCDATA_WSTRING:
	  indent (e, ind + 2);
	  fprintf (e, "L\"");
	  unicode_print (e, ri->u.wstring.w, ri->u.wstring.length);
	  fprintf (e, "\"");
	  break;

	case RCDATA_BUFFER:
	  write_rc_datablock (e, (rc_uint_type) ri->u.buffer.length,
	  		      (const bfd_byte *) ri->u.buffer.data,
	    		      ri->next != NULL, 0, -1);
	    break;
	}

      if (ri->type != RCDATA_BUFFER)
	{
	  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 (FILE *e, const rc_res_id *name,
		      const rc_stringtable *stringtable)
{
  rc_uint_type 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, ", (unsigned long) offset + i);
	  unicode_print_quoted (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 (FILE *e, const rc_versioninfo *versioninfo)
{
  const rc_fixed_versioninfo *f;
  const rc_ver_info *vi;

  f = versioninfo->fixed;
  if (f->file_version_ms != 0 || f->file_version_ls != 0)
    fprintf (e, " FILEVERSION %u, %u, %u, %u\n",
	     (unsigned int) ((f->file_version_ms >> 16) & 0xffff),
	     (unsigned int) (f->file_version_ms & 0xffff),
	     (unsigned int) ((f->file_version_ls >> 16) & 0xffff),
	     (unsigned int) (f->file_version_ls & 0xffff));
  if (f->product_version_ms != 0 || f->product_version_ls != 0)
    fprintf (e, " PRODUCTVERSION %u, %u, %u, %u\n",
	     (unsigned int) ((f->product_version_ms >> 16) & 0xffff),
	     (unsigned int) (f->product_version_ms & 0xffff),
	     (unsigned int) ((f->product_version_ls >> 16) & 0xffff),
	     (unsigned int) (f->product_version_ls & 0xffff));
  if (f->file_flags_mask != 0)
    fprintf (e, " FILEFLAGSMASK 0x%x\n", (unsigned int) f->file_flags_mask);
  if (f->file_flags != 0)
    fprintf (e, " FILEFLAGS 0x%x\n", (unsigned int) f->file_flags);
  if (f->file_os != 0)
    fprintf (e, " FILEOS 0x%x\n", (unsigned int) f->file_os);
  if (f->file_type != 0)
    fprintf (e, " FILETYPE 0x%x\n", (unsigned int) f->file_type);
  if (f->file_subtype != 0)
    fprintf (e, " FILESUBTYPE 0x%x\n", (unsigned int) f->file_subtype);
  if (f->file_date_ms != 0 || f->file_date_ls != 0)
    fprintf (e, "/* Date: %u, %u.  */\n",
    	     (unsigned int) f->file_date_ms, (unsigned int) f->file_date_ls);

  fprintf (e, "BEGIN\n");

  for (vi = versioninfo->var; vi != NULL; vi = vi->next)
    {
      switch (vi->type)
	{
	case VERINFO_STRING:
	  {
	    const rc_ver_stringtable *vst;
	    const rc_ver_stringinfo *vs;

	    fprintf (e, "  BLOCK \"StringFileInfo\"\n");
	    fprintf (e, "  BEGIN\n");

	    for (vst = vi->u.string.stringtables; vst != NULL; vst = vst->next)
	      {
		fprintf (e, "    BLOCK ");
		unicode_print_quoted (e, vst->language, -1);

		fprintf (e, "\n");
		fprintf (e, "    BEGIN\n");

		for (vs = vst->strings; vs != NULL; vs = vs->next)
		  {
		    fprintf (e, "      VALUE ");
		    unicode_print_quoted (e, vs->key, -1);
		    fprintf (e, ", ");
		    unicode_print_quoted (e, vs->value, -1);
		    fprintf (e, "\n");
		  }

		fprintf (e, "    END\n");
	      }
	    fprintf (e, "  END\n");
	    break;
	  }

	case VERINFO_VAR:
	  {
	    const rc_ver_varinfo *vv;

	    fprintf (e, "  BLOCK \"VarFileInfo\"\n");
	    fprintf (e, "  BEGIN\n");
	    fprintf (e, "    VALUE ");
	    unicode_print_quoted (e, vi->u.var.key, -1);

	    for (vv = vi->u.var.var; vv != NULL; vv = vv->next)
	      fprintf (e, ", 0x%x, %d", (unsigned int) vv->language,
		       (int) vv->charset);

	    fprintf (e, "\n  END\n");

	    break;
	  }
	}
    }

  fprintf (e, "END\n");
}

static rc_uint_type
rcdata_copy (const rc_rcdata_item *src, bfd_byte *dst)
{
  if (! src)
    return 0;
  switch (src->type)
	{
    case RCDATA_WORD:
      if (dst)
	windres_put_16 (&wrtarget, dst, (rc_uint_type) src->u.word);
      return 2;
    case RCDATA_DWORD:
      if (dst)
	windres_put_32 (&wrtarget, dst, (rc_uint_type) src->u.dword);
      return 4;
    case RCDATA_STRING:
      if (dst && src->u.string.length)
	memcpy (dst, src->u.string.s, src->u.string.length);
      return (rc_uint_type) src->u.string.length;
    case RCDATA_WSTRING:
      if (dst && src->u.wstring.length)
	memcpy (dst, src->u.wstring.w, src->u.wstring.length * sizeof (unichar));
      return (rc_uint_type) (src->u.wstring.length  * sizeof (unichar));
    case RCDATA_BUFFER:
      if (dst && src->u.buffer.length)
	memcpy (dst, src->u.buffer.data, src->u.buffer.length);
      return (rc_uint_type) src->u.buffer.length;
    default:
      abort ();
    }
  /* Never reached.  */
  return 0;
}
