OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [binutils/] [windres.c] - Diff between revs 15 and 166

Only display areas with differences | Details | Blame | View Log

Rev 15 Rev 166
/* windres.c -- a program to manipulate Windows resources
/* windres.c -- a program to manipulate Windows resources
   Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008,
   Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008,
   2009, 2011 Free Software Foundation, Inc.
   2009, 2011, 2012 Free Software Foundation, Inc.
   Written by Ian Lance Taylor, Cygnus Support.
   Written by Ian Lance Taylor, Cygnus Support.
   Rewritten by Kai Tietz, Onevision.
   Rewritten by Kai Tietz, Onevision.
 
 
   This file is part of GNU Binutils.
   This file is part of GNU Binutils.
 
 
   This program is free software; you can redistribute it and/or modify
   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
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.
   (at your option) any later version.
 
 
   This program is distributed in the hope that it will be useful,
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   GNU General Public License for more details.
 
 
   You should have received a copy of the GNU General Public License
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
   02110-1301, USA.  */
   02110-1301, USA.  */
 
 
/* This program can read and write Windows resources in various
/* This program can read and write Windows resources in various
   formats.  In particular, it can act like the rc resource compiler
   formats.  In particular, it can act like the rc resource compiler
   program, and it can act like the cvtres res to COFF conversion
   program, and it can act like the cvtres res to COFF conversion
   program.
   program.
 
 
   It is based on information taken from the following sources:
   It is based on information taken from the following sources:
 
 
   * Microsoft documentation.
   * Microsoft documentation.
 
 
   * The rcl program, written by Gunther Ebert
   * The rcl program, written by Gunther Ebert
     <gunther.ebert@ixos-leipzig.de>.
     <gunther.ebert@ixos-leipzig.de>.
 
 
   * The res2coff program, written by Pedro A. Aranda <paag@tid.es>.  */
   * The res2coff program, written by Pedro A. Aranda <paag@tid.es>.  */
 
 
#include "sysdep.h"
#include "sysdep.h"
#include <assert.h>
#include <assert.h>
#include <time.h>
#include <time.h>
#include "bfd.h"
#include "bfd.h"
#include "getopt.h"
#include "getopt.h"
#include "bucomm.h"
#include "bucomm.h"
#include "libiberty.h"
#include "libiberty.h"
#include "safe-ctype.h"
#include "safe-ctype.h"
#include "obstack.h"
#include "obstack.h"
#include "windres.h"
#include "windres.h"
#include <sys/stat.h>
 
 
 
/* Used by resrc.c at least.  */
/* Used by resrc.c at least.  */
 
 
int verbose = 0;
int verbose = 0;
 
 
int target_is_bigendian = 0;
int target_is_bigendian = 0;
const char *def_target_arch;
const char *def_target_arch;
 
 
static void set_endianness (bfd *, const char *);
static void set_endianness (bfd *, const char *);
 
 
/* An enumeration of format types.  */
/* An enumeration of format types.  */
 
 
enum res_format
enum res_format
{
{
  /* Unknown format.  */
  /* Unknown format.  */
  RES_FORMAT_UNKNOWN,
  RES_FORMAT_UNKNOWN,
  /* Textual RC file.  */
  /* Textual RC file.  */
  RES_FORMAT_RC,
  RES_FORMAT_RC,
  /* Binary RES file.  */
  /* Binary RES file.  */
  RES_FORMAT_RES,
  RES_FORMAT_RES,
  /* COFF file.  */
  /* COFF file.  */
  RES_FORMAT_COFF
  RES_FORMAT_COFF
};
};
 
 
/* A structure used to map between format types and strings.  */
/* A structure used to map between format types and strings.  */
 
 
struct format_map
struct format_map
{
{
  const char *name;
  const char *name;
  enum res_format format;
  enum res_format format;
};
};
 
 
/* A mapping between names and format types.  */
/* A mapping between names and format types.  */
 
 
static const struct format_map format_names[] =
static const struct format_map format_names[] =
{
{
  { "rc", RES_FORMAT_RC },
  { "rc", RES_FORMAT_RC },
  { "res", RES_FORMAT_RES },
  { "res", RES_FORMAT_RES },
  { "coff", RES_FORMAT_COFF },
  { "coff", RES_FORMAT_COFF },
  { NULL, RES_FORMAT_UNKNOWN }
  { NULL, RES_FORMAT_UNKNOWN }
};
};
 
 
/* A mapping from file extensions to format types.  */
/* A mapping from file extensions to format types.  */
 
 
static const struct format_map format_fileexts[] =
static const struct format_map format_fileexts[] =
{
{
  { "rc", RES_FORMAT_RC },
  { "rc", RES_FORMAT_RC },
  { "res", RES_FORMAT_RES },
  { "res", RES_FORMAT_RES },
  { "exe", RES_FORMAT_COFF },
  { "exe", RES_FORMAT_COFF },
  { "obj", RES_FORMAT_COFF },
  { "obj", RES_FORMAT_COFF },
  { "o", RES_FORMAT_COFF },
  { "o", RES_FORMAT_COFF },
  { NULL, RES_FORMAT_UNKNOWN }
  { NULL, RES_FORMAT_UNKNOWN }
};
};
 
 
/* A list of include directories.  */
/* A list of include directories.  */
 
 
struct include_dir
struct include_dir
{
{
  struct include_dir *next;
  struct include_dir *next;
  char *dir;
  char *dir;
};
};
 
 
static struct include_dir *include_dirs;
static struct include_dir *include_dirs;
 
 
/* Static functions.  */
/* Static functions.  */
 
 
static void res_init (void);
static void res_init (void);
static int extended_menuitems (const rc_menuitem *);
static int extended_menuitems (const rc_menuitem *);
static enum res_format format_from_name (const char *, int);
static enum res_format format_from_name (const char *, int);
static enum res_format format_from_filename (const char *, int);
static enum res_format format_from_filename (const char *, int);
static void usage (FILE *, int);
static void usage (FILE *, int);
static int cmp_res_entry (const void *, const void *);
static int cmp_res_entry (const void *, const void *);
static rc_res_directory *sort_resources (rc_res_directory *);
static rc_res_directory *sort_resources (rc_res_directory *);
static void reswr_init (void);
static void reswr_init (void);
static const char * quot (const char *);
static const char * quot (const char *);


static rc_uint_type target_get_8 (const void *, rc_uint_type);
static rc_uint_type target_get_8 (const void *, rc_uint_type);
static void target_put_8 (void *, rc_uint_type);
static void target_put_8 (void *, rc_uint_type);
static rc_uint_type target_get_16 (const void *, rc_uint_type);
static rc_uint_type target_get_16 (const void *, rc_uint_type);
static void target_put_16 (void *, rc_uint_type);
static void target_put_16 (void *, rc_uint_type);
static rc_uint_type target_get_32 (const void *, rc_uint_type);
static rc_uint_type target_get_32 (const void *, rc_uint_type);
static void target_put_32 (void *, rc_uint_type);
static void target_put_32 (void *, rc_uint_type);
 
 


/* When we are building a resource tree, we allocate everything onto
/* When we are building a resource tree, we allocate everything onto
   an obstack, so that we can free it all at once if we want.  */
   an obstack, so that we can free it all at once if we want.  */
 
 
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
#define obstack_chunk_free free
 
 
/* The resource building obstack.  */
/* The resource building obstack.  */
 
 
static struct obstack res_obstack;
static struct obstack res_obstack;
 
 
/* Initialize the resource building obstack.  */
/* Initialize the resource building obstack.  */
 
 
static void
static void
res_init (void)
res_init (void)
{
{
  obstack_init (&res_obstack);
  obstack_init (&res_obstack);
}
}
 
 
/* Allocate space on the resource building obstack.  */
/* Allocate space on the resource building obstack.  */
 
 
void *
void *
res_alloc (rc_uint_type bytes)
res_alloc (rc_uint_type bytes)
{
{
  return obstack_alloc (&res_obstack, (size_t) bytes);
  return obstack_alloc (&res_obstack, (size_t) bytes);
}
}
 
 
/* We also use an obstack to save memory used while writing out a set
/* We also use an obstack to save memory used while writing out a set
   of resources.  */
   of resources.  */
 
 
static struct obstack reswr_obstack;
static struct obstack reswr_obstack;
 
 
/* Initialize the resource writing obstack.  */
/* Initialize the resource writing obstack.  */
 
 
static void
static void
reswr_init (void)
reswr_init (void)
{
{
  obstack_init (&reswr_obstack);
  obstack_init (&reswr_obstack);
}
}
 
 
/* Allocate space on the resource writing obstack.  */
/* Allocate space on the resource writing obstack.  */
 
 
void *
void *
reswr_alloc (rc_uint_type bytes)
reswr_alloc (rc_uint_type bytes)
{
{
  return obstack_alloc (&reswr_obstack, (size_t) bytes);
  return obstack_alloc (&reswr_obstack, (size_t) bytes);
}
}


/* Open a file using the include directory search list.  */
/* Open a file using the include directory search list.  */
 
 
FILE *
FILE *
open_file_search (const char *filename, const char *mode, const char *errmsg,
open_file_search (const char *filename, const char *mode, const char *errmsg,
                  char **real_filename)
                  char **real_filename)
{
{
  FILE *e;
  FILE *e;
  struct include_dir *d;
  struct include_dir *d;
 
 
  e = fopen (filename, mode);
  e = fopen (filename, mode);
  if (e != NULL)
  if (e != NULL)
    {
    {
      *real_filename = xstrdup (filename);
      *real_filename = xstrdup (filename);
      return e;
      return e;
    }
    }
 
 
  if (errno == ENOENT)
  if (errno == ENOENT)
    {
    {
      for (d = include_dirs; d != NULL; d = d->next)
      for (d = include_dirs; d != NULL; d = d->next)
        {
        {
          char *n;
          char *n;
 
 
          n = (char *) xmalloc (strlen (d->dir) + strlen (filename) + 2);
          n = (char *) xmalloc (strlen (d->dir) + strlen (filename) + 2);
          sprintf (n, "%s/%s", d->dir, filename);
          sprintf (n, "%s/%s", d->dir, filename);
          e = fopen (n, mode);
          e = fopen (n, mode);
          if (e != NULL)
          if (e != NULL)
            {
            {
              *real_filename = n;
              *real_filename = n;
              return e;
              return e;
            }
            }
 
 
          if (errno != ENOENT)
          if (errno != ENOENT)
            break;
            break;
        }
        }
    }
    }
 
 
  fatal (_("can't open %s `%s': %s"), errmsg, filename, strerror (errno));
  fatal (_("can't open %s `%s': %s"), errmsg, filename, strerror (errno));
 
 
  /* Return a value to avoid a compiler warning.  */
  /* Return a value to avoid a compiler warning.  */
  return NULL;
  return NULL;
}
}


/* Compare two resource ID's.  We consider name entries to come before
/* Compare two resource ID's.  We consider name entries to come before
   numeric entries, because that is how they appear in the COFF .rsrc
   numeric entries, because that is how they appear in the COFF .rsrc
   section.  */
   section.  */
 
 
int
int
res_id_cmp (rc_res_id a, rc_res_id b)
res_id_cmp (rc_res_id a, rc_res_id b)
{
{
  if (! a.named)
  if (! a.named)
    {
    {
      if (b.named)
      if (b.named)
        return 1;
        return 1;
      if (a.u.id > b.u.id)
      if (a.u.id > b.u.id)
        return 1;
        return 1;
      else if (a.u.id < b.u.id)
      else if (a.u.id < b.u.id)
        return -1;
        return -1;
      else
      else
        return 0;
        return 0;
    }
    }
  else
  else
    {
    {
      unichar *as, *ase, *bs, *bse;
      unichar *as, *ase, *bs, *bse;
 
 
      if (! b.named)
      if (! b.named)
        return -1;
        return -1;
 
 
      as = a.u.n.name;
      as = a.u.n.name;
      ase = as + a.u.n.length;
      ase = as + a.u.n.length;
      bs = b.u.n.name;
      bs = b.u.n.name;
      bse = bs + b.u.n.length;
      bse = bs + b.u.n.length;
 
 
      while (as < ase)
      while (as < ase)
        {
        {
          int i;
          int i;
 
 
          if (bs >= bse)
          if (bs >= bse)
            return 1;
            return 1;
          i = (int) *as - (int) *bs;
          i = (int) *as - (int) *bs;
          if (i != 0)
          if (i != 0)
            return i;
            return i;
          ++as;
          ++as;
          ++bs;
          ++bs;
        }
        }
 
 
      if (bs < bse)
      if (bs < bse)
        return -1;
        return -1;
 
 
      return 0;
      return 0;
    }
    }
}
}
 
 
/* Print a resource ID.  */
/* Print a resource ID.  */
 
 
void
void
res_id_print (FILE *stream, rc_res_id id, int quote)
res_id_print (FILE *stream, rc_res_id id, int quote)
{
{
  if (! id.named)
  if (! id.named)
    fprintf (stream, "%u", (int) id.u.id);
    fprintf (stream, "%u", (int) id.u.id);
  else
  else
    {
    {
      if (quote)
      if (quote)
        unicode_print_quoted (stream, id.u.n.name, id.u.n.length);
        unicode_print_quoted (stream, id.u.n.name, id.u.n.length);
      else
      else
      unicode_print (stream, id.u.n.name, id.u.n.length);
      unicode_print (stream, id.u.n.name, id.u.n.length);
    }
    }
}
}
 
 
/* Print a list of resource ID's.  */
/* Print a list of resource ID's.  */
 
 
void
void
res_ids_print (FILE *stream, int cids, const rc_res_id *ids)
res_ids_print (FILE *stream, int cids, const rc_res_id *ids)
{
{
  int i;
  int i;
 
 
  for (i = 0; i < cids; i++)
  for (i = 0; i < cids; i++)
    {
    {
      res_id_print (stream, ids[i], 1);
      res_id_print (stream, ids[i], 1);
      if (i + 1 < cids)
      if (i + 1 < cids)
        fprintf (stream, ": ");
        fprintf (stream, ": ");
    }
    }
}
}
 
 
/* Convert an ASCII string to a resource ID.  */
/* Convert an ASCII string to a resource ID.  */
 
 
void
void
res_string_to_id (rc_res_id *res_id, const char *string)
res_string_to_id (rc_res_id *res_id, const char *string)
{
{
  res_id->named = 1;
  res_id->named = 1;
  unicode_from_ascii (&res_id->u.n.length, &res_id->u.n.name, string);
  unicode_from_ascii (&res_id->u.n.length, &res_id->u.n.name, string);
}
}
 
 
/* Convert an unicode string to a resource ID.  */
/* Convert an unicode string to a resource ID.  */
void
void
res_unistring_to_id (rc_res_id *res_id, const unichar *u)
res_unistring_to_id (rc_res_id *res_id, const unichar *u)
{
{
  res_id->named = 1;
  res_id->named = 1;
  res_id->u.n.length = unichar_len (u);
  res_id->u.n.length = unichar_len (u);
  res_id->u.n.name = unichar_dup_uppercase (u);
  res_id->u.n.name = unichar_dup_uppercase (u);
}
}
 
 
/* Define a resource.  The arguments are the resource tree, RESOURCES,
/* Define a resource.  The arguments are the resource tree, RESOURCES,
   and the location at which to put it in the tree, CIDS and IDS.
   and the location at which to put it in the tree, CIDS and IDS.
   This returns a newly allocated rc_res_resource structure, which the
   This returns a newly allocated rc_res_resource structure, which the
   caller is expected to initialize.  If DUPOK is non-zero, then if a
   caller is expected to initialize.  If DUPOK is non-zero, then if a
   resource with this ID exists, it is returned.  Otherwise, a warning
   resource with this ID exists, it is returned.  Otherwise, a warning
   is issued, and a new resource is created replacing the existing
   is issued, and a new resource is created replacing the existing
   one.  */
   one.  */
 
 
rc_res_resource *
rc_res_resource *
define_resource (rc_res_directory **resources, int cids,
define_resource (rc_res_directory **resources, int cids,
                 const rc_res_id *ids, int dupok)
                 const rc_res_id *ids, int dupok)
{
{
  rc_res_entry *re = NULL;
  rc_res_entry *re = NULL;
  int i;
  int i;
 
 
  assert (cids > 0);
  assert (cids > 0);
  for (i = 0; i < cids; i++)
  for (i = 0; i < cids; i++)
    {
    {
      rc_res_entry **pp;
      rc_res_entry **pp;
 
 
      if (*resources == NULL)
      if (*resources == NULL)
        {
        {
          static unsigned int timeval;
          static unsigned int timeval;
 
 
          /* Use the same timestamp for every resource created in a
          /* Use the same timestamp for every resource created in a
             single run.  */
             single run.  */
          if (timeval == 0)
          if (timeval == 0)
            timeval = time (NULL);
            timeval = time (NULL);
 
 
          *resources = ((rc_res_directory *)
          *resources = ((rc_res_directory *)
                        res_alloc (sizeof (rc_res_directory)));
                        res_alloc (sizeof (rc_res_directory)));
          (*resources)->characteristics = 0;
          (*resources)->characteristics = 0;
          (*resources)->time = timeval;
          (*resources)->time = timeval;
          (*resources)->major = 0;
          (*resources)->major = 0;
          (*resources)->minor = 0;
          (*resources)->minor = 0;
          (*resources)->entries = NULL;
          (*resources)->entries = NULL;
        }
        }
 
 
      for (pp = &(*resources)->entries; *pp != NULL; pp = &(*pp)->next)
      for (pp = &(*resources)->entries; *pp != NULL; pp = &(*pp)->next)
        if (res_id_cmp ((*pp)->id, ids[i]) == 0)
        if (res_id_cmp ((*pp)->id, ids[i]) == 0)
          break;
          break;
 
 
      if (*pp != NULL)
      if (*pp != NULL)
        re = *pp;
        re = *pp;
      else
      else
        {
        {
          re = (rc_res_entry *) res_alloc (sizeof (rc_res_entry));
          re = (rc_res_entry *) res_alloc (sizeof (rc_res_entry));
          re->next = NULL;
          re->next = NULL;
          re->id = ids[i];
          re->id = ids[i];
          if ((i + 1) < cids)
          if ((i + 1) < cids)
            {
            {
              re->subdir = 1;
              re->subdir = 1;
              re->u.dir = NULL;
              re->u.dir = NULL;
            }
            }
          else
          else
            {
            {
              re->subdir = 0;
              re->subdir = 0;
              re->u.res = NULL;
              re->u.res = NULL;
            }
            }
 
 
          *pp = re;
          *pp = re;
        }
        }
 
 
      if ((i + 1) < cids)
      if ((i + 1) < cids)
        {
        {
          if (! re->subdir)
          if (! re->subdir)
            {
            {
              fprintf (stderr, "%s: ", program_name);
              fprintf (stderr, "%s: ", program_name);
              res_ids_print (stderr, i, ids);
              res_ids_print (stderr, i, ids);
              fprintf (stderr, _(": expected to be a directory\n"));
              fprintf (stderr, _(": expected to be a directory\n"));
              xexit (1);
              xexit (1);
            }
            }
 
 
          resources = &re->u.dir;
          resources = &re->u.dir;
        }
        }
    }
    }
 
 
  if (re->subdir)
  if (re->subdir)
    {
    {
      fprintf (stderr, "%s: ", program_name);
      fprintf (stderr, "%s: ", program_name);
      res_ids_print (stderr, cids, ids);
      res_ids_print (stderr, cids, ids);
      fprintf (stderr, _(": expected to be a leaf\n"));
      fprintf (stderr, _(": expected to be a leaf\n"));
      xexit (1);
      xexit (1);
    }
    }
 
 
  if (re->u.res != NULL)
  if (re->u.res != NULL)
    {
    {
      if (dupok)
      if (dupok)
        return re->u.res;
        return re->u.res;
 
 
      fprintf (stderr, _("%s: warning: "), program_name);
      fprintf (stderr, _("%s: warning: "), program_name);
      res_ids_print (stderr, cids, ids);
      res_ids_print (stderr, cids, ids);
      fprintf (stderr, _(": duplicate value\n"));
      fprintf (stderr, _(": duplicate value\n"));
    }
    }
 
 
  re->u.res = ((rc_res_resource *)
  re->u.res = ((rc_res_resource *)
               res_alloc (sizeof (rc_res_resource)));
               res_alloc (sizeof (rc_res_resource)));
  memset (re->u.res, 0, sizeof (rc_res_resource));
  memset (re->u.res, 0, sizeof (rc_res_resource));
 
 
  re->u.res->type = RES_TYPE_UNINITIALIZED;
  re->u.res->type = RES_TYPE_UNINITIALIZED;
  return re->u.res;
  return re->u.res;
}
}
 
 
/* Define a standard resource.  This is a version of define_resource
/* Define a standard resource.  This is a version of define_resource
   that just takes type, name, and language arguments.  */
   that just takes type, name, and language arguments.  */
 
 
rc_res_resource *
rc_res_resource *
define_standard_resource (rc_res_directory **resources, int type,
define_standard_resource (rc_res_directory **resources, int type,
                          rc_res_id name, rc_uint_type language, int dupok)
                          rc_res_id name, rc_uint_type language, int dupok)
{
{
  rc_res_id a[3];
  rc_res_id a[3];
 
 
  a[0].named = 0;
  a[0].named = 0;
  a[0].u.id = type;
  a[0].u.id = type;
  a[1] = name;
  a[1] = name;
  a[2].named = 0;
  a[2].named = 0;
  a[2].u.id = language;
  a[2].u.id = language;
  return define_resource (resources, 3, a, dupok);
  return define_resource (resources, 3, a, dupok);
}
}
 
 
/* Comparison routine for resource sorting.  */
/* Comparison routine for resource sorting.  */
 
 
static int
static int
cmp_res_entry (const void *p1, const void *p2)
cmp_res_entry (const void *p1, const void *p2)
{
{
  const rc_res_entry **re1, **re2;
  const rc_res_entry **re1, **re2;
 
 
  re1 = (const rc_res_entry **) p1;
  re1 = (const rc_res_entry **) p1;
  re2 = (const rc_res_entry **) p2;
  re2 = (const rc_res_entry **) p2;
  return res_id_cmp ((*re1)->id, (*re2)->id);
  return res_id_cmp ((*re1)->id, (*re2)->id);
}
}
 
 
/* Sort the resources.  */
/* Sort the resources.  */
 
 
static rc_res_directory *
static rc_res_directory *
sort_resources (rc_res_directory *resdir)
sort_resources (rc_res_directory *resdir)
{
{
  int c, i;
  int c, i;
  rc_res_entry *re;
  rc_res_entry *re;
  rc_res_entry **a;
  rc_res_entry **a;
 
 
  if (resdir->entries == NULL)
  if (resdir->entries == NULL)
    return resdir;
    return resdir;
 
 
  c = 0;
  c = 0;
  for (re = resdir->entries; re != NULL; re = re->next)
  for (re = resdir->entries; re != NULL; re = re->next)
    ++c;
    ++c;
 
 
  /* This is a recursive routine, so using xmalloc is probably better
  /* This is a recursive routine, so using xmalloc is probably better
     than alloca.  */
     than alloca.  */
  a = (rc_res_entry **) xmalloc (c * sizeof (rc_res_entry *));
  a = (rc_res_entry **) xmalloc (c * sizeof (rc_res_entry *));
 
 
  for (i = 0, re = resdir->entries; re != NULL; re = re->next, i++)
  for (i = 0, re = resdir->entries; re != NULL; re = re->next, i++)
    a[i] = re;
    a[i] = re;
 
 
  qsort (a, c, sizeof (rc_res_entry *), cmp_res_entry);
  qsort (a, c, sizeof (rc_res_entry *), cmp_res_entry);
 
 
  resdir->entries = a[0];
  resdir->entries = a[0];
  for (i = 0; i < c - 1; i++)
  for (i = 0; i < c - 1; i++)
    a[i]->next = a[i + 1];
    a[i]->next = a[i + 1];
  a[i]->next = NULL;
  a[i]->next = NULL;
 
 
  free (a);
  free (a);
 
 
  /* Now sort the subdirectories.  */
  /* Now sort the subdirectories.  */
 
 
  for (re = resdir->entries; re != NULL; re = re->next)
  for (re = resdir->entries; re != NULL; re = re->next)
    if (re->subdir)
    if (re->subdir)
      re->u.dir = sort_resources (re->u.dir);
      re->u.dir = sort_resources (re->u.dir);
 
 
  return resdir;
  return resdir;
}
}


/* Return whether the dialog resource DIALOG is a DIALOG or a
/* Return whether the dialog resource DIALOG is a DIALOG or a
   DIALOGEX.  */
   DIALOGEX.  */
 
 
int
int
extended_dialog (const rc_dialog *dialog)
extended_dialog (const rc_dialog *dialog)
{
{
  const rc_dialog_control *c;
  const rc_dialog_control *c;
 
 
  if (dialog->ex != NULL)
  if (dialog->ex != NULL)
    return 1;
    return 1;
 
 
  for (c = dialog->controls; c != NULL; c = c->next)
  for (c = dialog->controls; c != NULL; c = c->next)
    if (c->data != NULL || c->help != 0)
    if (c->data != NULL || c->help != 0)
      return 1;
      return 1;
 
 
  return 0;
  return 0;
}
}
 
 
/* Return whether MENUITEMS are a MENU or a MENUEX.  */
/* Return whether MENUITEMS are a MENU or a MENUEX.  */
 
 
int
int
extended_menu (const rc_menu *menu)
extended_menu (const rc_menu *menu)
{
{
  return extended_menuitems (menu->items);
  return extended_menuitems (menu->items);
}
}
 
 
static int
static int
extended_menuitems (const rc_menuitem *menuitems)
extended_menuitems (const rc_menuitem *menuitems)
{
{
  const rc_menuitem *mi;
  const rc_menuitem *mi;
 
 
  for (mi = menuitems; mi != NULL; mi = mi->next)
  for (mi = menuitems; mi != NULL; mi = mi->next)
    {
    {
      if (mi->help != 0 || mi->state != 0)
      if (mi->help != 0 || mi->state != 0)
        return 1;
        return 1;
      if (mi->popup != NULL && mi->id != 0)
      if (mi->popup != NULL && mi->id != 0)
        return 1;
        return 1;
      if ((mi->type
      if ((mi->type
           & ~ (MENUITEM_CHECKED
           & ~ (MENUITEM_CHECKED
                | MENUITEM_GRAYED
                | MENUITEM_GRAYED
                | MENUITEM_HELP
                | MENUITEM_HELP
                | MENUITEM_INACTIVE
                | MENUITEM_INACTIVE
                | MENUITEM_MENUBARBREAK
                | MENUITEM_MENUBARBREAK
                | MENUITEM_MENUBREAK))
                | MENUITEM_MENUBREAK))
          != 0)
          != 0)
        return 1;
        return 1;
      if (mi->popup != NULL)
      if (mi->popup != NULL)
        {
        {
          if (extended_menuitems (mi->popup))
          if (extended_menuitems (mi->popup))
            return 1;
            return 1;
        }
        }
    }
    }
 
 
  return 0;
  return 0;
}
}


/* Convert a string to a format type, or exit if it can't be done.  */
/* Convert a string to a format type, or exit if it can't be done.  */
 
 
static enum res_format
static enum res_format
format_from_name (const char *name, int exit_on_error)
format_from_name (const char *name, int exit_on_error)
{
{
  const struct format_map *m;
  const struct format_map *m;
 
 
  for (m = format_names; m->name != NULL; m++)
  for (m = format_names; m->name != NULL; m++)
    if (strcasecmp (m->name, name) == 0)
    if (strcasecmp (m->name, name) == 0)
      break;
      break;
 
 
  if (m->name == NULL && exit_on_error)
  if (m->name == NULL && exit_on_error)
    {
    {
      non_fatal (_("unknown format type `%s'"), name);
      non_fatal (_("unknown format type `%s'"), name);
      fprintf (stderr, _("%s: supported formats:"), program_name);
      fprintf (stderr, _("%s: supported formats:"), program_name);
      for (m = format_names; m->name != NULL; m++)
      for (m = format_names; m->name != NULL; m++)
        fprintf (stderr, " %s", m->name);
        fprintf (stderr, " %s", m->name);
      fprintf (stderr, "\n");
      fprintf (stderr, "\n");
      xexit (1);
      xexit (1);
    }
    }
 
 
  return m->format;
  return m->format;
}
}
 
 
/* Work out a format type given a file name.  If INPUT is non-zero,
/* Work out a format type given a file name.  If INPUT is non-zero,
   it's OK to look at the file itself.  */
   it's OK to look at the file itself.  */
 
 
static enum res_format
static enum res_format
format_from_filename (const char *filename, int input)
format_from_filename (const char *filename, int input)
{
{
  const char *ext;
  const char *ext;
  FILE *e;
  FILE *e;
  bfd_byte b1, b2, b3, b4, b5;
  bfd_byte b1, b2, b3, b4, b5;
  int magic;
  int magic;
 
 
  /* If we have an extension, see if we recognize it as implying a
  /* If we have an extension, see if we recognize it as implying a
     particular format.  */
     particular format.  */
  ext = strrchr (filename, '.');
  ext = strrchr (filename, '.');
  if (ext != NULL)
  if (ext != NULL)
    {
    {
      const struct format_map *m;
      const struct format_map *m;
 
 
      ++ext;
      ++ext;
      for (m = format_fileexts; m->name != NULL; m++)
      for (m = format_fileexts; m->name != NULL; m++)
        if (strcasecmp (m->name, ext) == 0)
        if (strcasecmp (m->name, ext) == 0)
          return m->format;
          return m->format;
    }
    }
 
 
  /* If we don't recognize the name of an output file, assume it's a
  /* If we don't recognize the name of an output file, assume it's a
     COFF file.  */
     COFF file.  */
  if (! input)
  if (! input)
    return RES_FORMAT_COFF;
    return RES_FORMAT_COFF;
 
 
  /* Read the first few bytes of the file to see if we can guess what
  /* Read the first few bytes of the file to see if we can guess what
     it is.  */
     it is.  */
  e = fopen (filename, FOPEN_RB);
  e = fopen (filename, FOPEN_RB);
  if (e == NULL)
  if (e == NULL)
    fatal ("%s: %s", filename, strerror (errno));
    fatal ("%s: %s", filename, strerror (errno));
 
 
  b1 = getc (e);
  b1 = getc (e);
  b2 = getc (e);
  b2 = getc (e);
  b3 = getc (e);
  b3 = getc (e);
  b4 = getc (e);
  b4 = getc (e);
  b5 = getc (e);
  b5 = getc (e);
 
 
  fclose (e);
  fclose (e);
 
 
  /* A PE executable starts with 0x4d 0x5a.  */
  /* A PE executable starts with 0x4d 0x5a.  */
  if (b1 == 0x4d && b2 == 0x5a)
  if (b1 == 0x4d && b2 == 0x5a)
    return RES_FORMAT_COFF;
    return RES_FORMAT_COFF;
 
 
  /* A COFF .o file starts with a COFF magic number.  */
  /* A COFF .o file starts with a COFF magic number.  */
  magic = (b2 << 8) | b1;
  magic = (b2 << 8) | b1;
  switch (magic)
  switch (magic)
    {
    {
    case 0x14c: /* i386 */
    case 0x14c: /* i386 */
    case 0x166: /* MIPS */
    case 0x166: /* MIPS */
    case 0x184: /* Alpha */
    case 0x184: /* Alpha */
    case 0x268: /* 68k */
    case 0x268: /* 68k */
    case 0x1f0: /* PowerPC */
    case 0x1f0: /* PowerPC */
    case 0x290: /* PA */
    case 0x290: /* PA */
      return RES_FORMAT_COFF;
      return RES_FORMAT_COFF;
    }
    }
 
 
  /* A RES file starts with 0x0 0x0 0x0 0x0 0x20 0x0 0x0 0x0.  */
  /* A RES file starts with 0x0 0x0 0x0 0x0 0x20 0x0 0x0 0x0.  */
  if (b1 == 0 && b2 == 0 && b3 == 0 && b4 == 0 && b5 == 0x20)
  if (b1 == 0 && b2 == 0 && b3 == 0 && b4 == 0 && b5 == 0x20)
    return RES_FORMAT_RES;
    return RES_FORMAT_RES;
 
 
  /* If every character is printable or space, assume it's an RC file.  */
  /* If every character is printable or space, assume it's an RC file.  */
  if ((ISPRINT (b1) || ISSPACE (b1))
  if ((ISPRINT (b1) || ISSPACE (b1))
      && (ISPRINT (b2) || ISSPACE (b2))
      && (ISPRINT (b2) || ISSPACE (b2))
      && (ISPRINT (b3) || ISSPACE (b3))
      && (ISPRINT (b3) || ISSPACE (b3))
      && (ISPRINT (b4) || ISSPACE (b4))
      && (ISPRINT (b4) || ISSPACE (b4))
      && (ISPRINT (b5) || ISSPACE (b5)))
      && (ISPRINT (b5) || ISSPACE (b5)))
    return RES_FORMAT_RC;
    return RES_FORMAT_RC;
 
 
  /* Otherwise, we give up.  */
  /* Otherwise, we give up.  */
  fatal (_("can not determine type of file `%s'; use the -J option"),
  fatal (_("can not determine type of file `%s'; use the -J option"),
         filename);
         filename);
 
 
  /* Return something to silence the compiler warning.  */
  /* Return something to silence the compiler warning.  */
  return RES_FORMAT_UNKNOWN;
  return RES_FORMAT_UNKNOWN;
}
}
 
 
/* Print a usage message and exit.  */
/* Print a usage message and exit.  */
 
 
static void
static void
usage (FILE *stream, int status)
usage (FILE *stream, int status)
{
{
  fprintf (stream, _("Usage: %s [option(s)] [input-file] [output-file]\n"),
  fprintf (stream, _("Usage: %s [option(s)] [input-file] [output-file]\n"),
           program_name);
           program_name);
  fprintf (stream, _(" The options are:\n\
  fprintf (stream, _(" The options are:\n\
  -i --input=<file>            Name input file\n\
  -i --input=<file>            Name input file\n\
  -o --output=<file>           Name output file\n\
  -o --output=<file>           Name output file\n\
  -J --input-format=<format>   Specify input format\n\
  -J --input-format=<format>   Specify input format\n\
  -O --output-format=<format>  Specify output format\n\
  -O --output-format=<format>  Specify output format\n\
  -F --target=<target>         Specify COFF target\n\
  -F --target=<target>         Specify COFF target\n\
     --preprocessor=<program>  Program to use to preprocess rc file\n\
     --preprocessor=<program>  Program to use to preprocess rc file\n\
     --preprocessor-arg=<arg>  Additional preprocessor argument\n\
     --preprocessor-arg=<arg>  Additional preprocessor argument\n\
  -I --include-dir=<dir>       Include directory when preprocessing rc file\n\
  -I --include-dir=<dir>       Include directory when preprocessing rc file\n\
  -D --define <sym>[=<val>]    Define SYM when preprocessing rc file\n\
  -D --define <sym>[=<val>]    Define SYM when preprocessing rc file\n\
  -U --undefine <sym>          Undefine SYM when preprocessing rc file\n\
  -U --undefine <sym>          Undefine SYM when preprocessing rc file\n\
  -v --verbose                 Verbose - tells you what it's doing\n\
  -v --verbose                 Verbose - tells you what it's doing\n\
  -c --codepage=<codepage>     Specify default codepage\n\
  -c --codepage=<codepage>     Specify default codepage\n\
  -l --language=<val>          Set language when reading rc file\n\
  -l --language=<val>          Set language when reading rc file\n\
     --use-temp-file           Use a temporary file instead of popen to read\n\
     --use-temp-file           Use a temporary file instead of popen to read\n\
                               the preprocessor output\n\
                               the preprocessor output\n\
     --no-use-temp-file        Use popen (default)\n"));
     --no-use-temp-file        Use popen (default)\n"));
#ifdef YYDEBUG
#ifdef YYDEBUG
  fprintf (stream, _("\
  fprintf (stream, _("\
     --yydebug                 Turn on parser debugging\n"));
     --yydebug                 Turn on parser debugging\n"));
#endif
#endif
  fprintf (stream, _("\
  fprintf (stream, _("\
  -r                           Ignored for compatibility with rc\n\
  -r                           Ignored for compatibility with rc\n\
  @<file>                      Read options from <file>\n\
  @<file>                      Read options from <file>\n\
  -h --help                    Print this help message\n\
  -h --help                    Print this help message\n\
  -V --version                 Print version information\n"));
  -V --version                 Print version information\n"));
  fprintf (stream, _("\
  fprintf (stream, _("\
FORMAT is one of rc, res, or coff, and is deduced from the file name\n\
FORMAT is one of rc, res, or coff, and is deduced from the file name\n\
extension if not specified.  A single file name is an input file.\n\
extension if not specified.  A single file name is an input file.\n\
No input-file is stdin, default rc.  No output-file is stdout, default rc.\n"));
No input-file is stdin, default rc.  No output-file is stdout, default rc.\n"));
 
 
  list_supported_targets (program_name, stream);
  list_supported_targets (program_name, stream);
 
 
  if (REPORT_BUGS_TO[0] && status == 0)
  if (REPORT_BUGS_TO[0] && status == 0)
    fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
    fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
 
 
  exit (status);
  exit (status);
}
}
 
 
/* Quote characters that will confuse the shell when we run the preprocessor.  */
/* Quote characters that will confuse the shell when we run the preprocessor.  */
 
 
static const char *
static const char *
quot (const char *string)
quot (const char *string)
{
{
  static char *buf = 0;
  static char *buf = 0;
  static int buflen = 0;
  static int buflen = 0;
  int slen = strlen (string);
  int slen = strlen (string);
  const char *src;
  const char *src;
  char *dest;
  char *dest;
 
 
  if ((buflen < slen * 2 + 2) || ! buf)
  if ((buflen < slen * 2 + 2) || ! buf)
    {
    {
      buflen = slen * 2 + 2;
      buflen = slen * 2 + 2;
      if (buf)
      if (buf)
        free (buf);
        free (buf);
      buf = (char *) xmalloc (buflen);
      buf = (char *) xmalloc (buflen);
    }
    }
 
 
  for (src=string, dest=buf; *src; src++, dest++)
  for (src=string, dest=buf; *src; src++, dest++)
    {
    {
      if (*src == '(' || *src == ')' || *src == ' ')
      if (*src == '(' || *src == ')' || *src == ' ')
        *dest++ = '\\';
        *dest++ = '\\';
      *dest = *src;
      *dest = *src;
    }
    }
  *dest = 0;
  *dest = 0;
  return buf;
  return buf;
}
}
 
 
/* Long options.  */
/* Long options.  */
 
 
enum option_values
enum option_values
{
{
  /* 150 isn't special; it's just an arbitrary non-ASCII char value.  */
  /* 150 isn't special; it's just an arbitrary non-ASCII char value.  */
  OPTION_PREPROCESSOR   = 150,
  OPTION_PREPROCESSOR   = 150,
  OPTION_USE_TEMP_FILE,
  OPTION_USE_TEMP_FILE,
  OPTION_NO_USE_TEMP_FILE,
  OPTION_NO_USE_TEMP_FILE,
  OPTION_YYDEBUG,
  OPTION_YYDEBUG,
  OPTION_INCLUDE_DIR,
  OPTION_INCLUDE_DIR,
  OPTION_PREPROCESSOR_ARG
  OPTION_PREPROCESSOR_ARG
};
};
 
 
static const struct option long_options[] =
static const struct option long_options[] =
{
{
  {"input", required_argument, 0, 'i'},
  {"input", required_argument, 0, 'i'},
  {"output", required_argument, 0, 'o'},
  {"output", required_argument, 0, 'o'},
  {"input-format", required_argument, 0, 'J'},
  {"input-format", required_argument, 0, 'J'},
  {"output-format", required_argument, 0, 'O'},
  {"output-format", required_argument, 0, 'O'},
  {"target", required_argument, 0, 'F'},
  {"target", required_argument, 0, 'F'},
  {"preprocessor", required_argument, 0, OPTION_PREPROCESSOR},
  {"preprocessor", required_argument, 0, OPTION_PREPROCESSOR},
  {"preprocessor-arg", required_argument, 0, OPTION_PREPROCESSOR_ARG},
  {"preprocessor-arg", required_argument, 0, OPTION_PREPROCESSOR_ARG},
  {"include-dir", required_argument, 0, OPTION_INCLUDE_DIR},
  {"include-dir", required_argument, 0, OPTION_INCLUDE_DIR},
  {"define", required_argument, 0, 'D'},
  {"define", required_argument, 0, 'D'},
  {"undefine", required_argument, 0, 'U'},
  {"undefine", required_argument, 0, 'U'},
  {"verbose", no_argument, 0, 'v'},
  {"verbose", no_argument, 0, 'v'},
  {"codepage", required_argument, 0, 'c'},
  {"codepage", required_argument, 0, 'c'},
  {"language", required_argument, 0, 'l'},
  {"language", required_argument, 0, 'l'},
  {"use-temp-file", no_argument, 0, OPTION_USE_TEMP_FILE},
  {"use-temp-file", no_argument, 0, OPTION_USE_TEMP_FILE},
  {"no-use-temp-file", no_argument, 0, OPTION_NO_USE_TEMP_FILE},
  {"no-use-temp-file", no_argument, 0, OPTION_NO_USE_TEMP_FILE},
  {"yydebug", no_argument, 0, OPTION_YYDEBUG},
  {"yydebug", no_argument, 0, OPTION_YYDEBUG},
  {"version", no_argument, 0, 'V'},
  {"version", no_argument, 0, 'V'},
  {"help", no_argument, 0, 'h'},
  {"help", no_argument, 0, 'h'},
  {0, no_argument, 0, 0}
  {0, no_argument, 0, 0}
};
};
 
 
void
void
windres_add_include_dir (const char *p)
windres_add_include_dir (const char *p)
{
{
  struct include_dir *n, **pp;
  struct include_dir *n, **pp;
 
 
  /* Computing paths is often complicated and error prone.
  /* Computing paths is often complicated and error prone.
     The easiest way to check for mistakes is at the time
     The easiest way to check for mistakes is at the time
     we add them to include_dirs.  */
     we add them to include_dirs.  */
  assert (p != NULL);
  assert (p != NULL);
  assert (*p != '\0');
  assert (*p != '\0');
 
 
  n = xmalloc (sizeof *n);
  n = xmalloc (sizeof *n);
  n->next = NULL;
  n->next = NULL;
  n->dir = (char * ) p;
  n->dir = (char * ) p;
 
 
  for (pp = &include_dirs; *pp != NULL; pp = &(*pp)->next)
  for (pp = &include_dirs; *pp != NULL; pp = &(*pp)->next)
    ;
    ;
  *pp = n;
  *pp = n;
}
}
 
 
/* This keeps gcc happy when using -Wmissing-prototypes -Wstrict-prototypes.  */
/* This keeps gcc happy when using -Wmissing-prototypes -Wstrict-prototypes.  */
int main (int, char **);
int main (int, char **);
 
 
/* The main function.  */
/* The main function.  */
 
 
int
int
main (int argc, char **argv)
main (int argc, char **argv)
{
{
  int c;
  int c;
  char *input_filename;
  char *input_filename;
  char *output_filename;
  char *output_filename;
  enum res_format input_format;
  enum res_format input_format;
  enum res_format input_format_tmp;
  enum res_format input_format_tmp;
  enum res_format output_format;
  enum res_format output_format;
  char *target;
  char *target;
  char *preprocessor;
  char *preprocessor;
  char *preprocargs;
  char *preprocargs;
  const char *quotedarg;
  const char *quotedarg;
  int language;
  int language;
  rc_res_directory *resources;
  rc_res_directory *resources;
  int use_temp_file;
  int use_temp_file;
 
 
#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
  setlocale (LC_MESSAGES, "");
  setlocale (LC_MESSAGES, "");
#endif
#endif
#if defined (HAVE_SETLOCALE)
#if defined (HAVE_SETLOCALE)
  setlocale (LC_CTYPE, "");
  setlocale (LC_CTYPE, "");
#endif
#endif
  bindtextdomain (PACKAGE, LOCALEDIR);
  bindtextdomain (PACKAGE, LOCALEDIR);
  textdomain (PACKAGE);
  textdomain (PACKAGE);
 
 
  program_name = argv[0];
  program_name = argv[0];
  xmalloc_set_program_name (program_name);
  xmalloc_set_program_name (program_name);
 
 
  expandargv (&argc, &argv);
  expandargv (&argc, &argv);
 
 
  bfd_init ();
  bfd_init ();
  set_default_bfd_target ();
  set_default_bfd_target ();
 
 
  res_init ();
  res_init ();
 
 
  input_filename = NULL;
  input_filename = NULL;
  output_filename = NULL;
  output_filename = NULL;
  input_format = RES_FORMAT_UNKNOWN;
  input_format = RES_FORMAT_UNKNOWN;
  output_format = RES_FORMAT_UNKNOWN;
  output_format = RES_FORMAT_UNKNOWN;
  target = NULL;
  target = NULL;
  preprocessor = NULL;
  preprocessor = NULL;
  preprocargs = NULL;
  preprocargs = NULL;
  language = 0x409;   /* LANG_ENGLISH, SUBLANG_ENGLISH_US.  */
  language = 0x409;   /* LANG_ENGLISH, SUBLANG_ENGLISH_US.  */
  use_temp_file = 0;
  use_temp_file = 0;
 
 
  while ((c = getopt_long (argc, argv, "c:f:i:l:o:I:J:O:F:D:U:rhHvV", long_options,
  while ((c = getopt_long (argc, argv, "c:f:i:l:o:I:J:O:F:D:U:rhHvV", long_options,
                           (int *) 0)) != EOF)
                           (int *) 0)) != EOF)
    {
    {
      switch (c)
      switch (c)
        {
        {
        case 'c':
        case 'c':
          {
          {
            rc_uint_type ncp;
            rc_uint_type ncp;
 
 
            if (optarg[0] == '0' && (optarg[1] == 'x' || optarg[1] == 'X'))
            if (optarg[0] == '0' && (optarg[1] == 'x' || optarg[1] == 'X'))
              ncp = (rc_uint_type) strtol (optarg + 2, NULL, 16);
              ncp = (rc_uint_type) strtol (optarg + 2, NULL, 16);
            else
            else
              ncp = (rc_uint_type) strtol (optarg, NULL, 10);
              ncp = (rc_uint_type) strtol (optarg, NULL, 10);
            if (ncp == CP_UTF16 || ! unicode_is_valid_codepage (ncp))
            if (ncp == CP_UTF16 || ! unicode_is_valid_codepage (ncp))
              fatal (_("invalid codepage specified.\n"));
              fatal (_("invalid codepage specified.\n"));
            wind_default_codepage = wind_current_codepage = ncp;
            wind_default_codepage = wind_current_codepage = ncp;
          }
          }
          break;
          break;
 
 
        case 'i':
        case 'i':
          input_filename = optarg;
          input_filename = optarg;
          break;
          break;
 
 
        case 'f':
        case 'f':
          /* For compatibility with rc we accept "-fo <name>" as being the
          /* For compatibility with rc we accept "-fo <name>" as being the
             equivalent of "-o <name>".  We do not advertise this fact
             equivalent of "-o <name>".  We do not advertise this fact
             though, as we do not want users to use non-GNU like command
             though, as we do not want users to use non-GNU like command
             line switches.  */
             line switches.  */
          if (*optarg != 'o')
          if (*optarg != 'o')
            fatal (_("invalid option -f\n"));
            fatal (_("invalid option -f\n"));
          optarg++;
          optarg++;
          if (* optarg == 0)
          if (* optarg == 0)
            {
            {
              if (optind == argc)
              if (optind == argc)
                fatal (_("No filename following the -fo option.\n"));
                fatal (_("No filename following the -fo option.\n"));
              optarg = argv [optind++];
              optarg = argv [optind++];
            }
            }
          /* Fall through.  */
          /* Fall through.  */
 
 
        case 'o':
        case 'o':
          output_filename = optarg;
          output_filename = optarg;
          break;
          break;
 
 
        case 'J':
        case 'J':
          input_format = format_from_name (optarg, 1);
          input_format = format_from_name (optarg, 1);
          break;
          break;
 
 
        case 'O':
        case 'O':
          output_format = format_from_name (optarg, 1);
          output_format = format_from_name (optarg, 1);
          break;
          break;
 
 
        case 'F':
        case 'F':
          target = optarg;
          target = optarg;
          break;
          break;
 
 
        case OPTION_PREPROCESSOR:
        case OPTION_PREPROCESSOR:
          preprocessor = optarg;
          preprocessor = optarg;
          break;
          break;
 
 
        case OPTION_PREPROCESSOR_ARG:
        case OPTION_PREPROCESSOR_ARG:
          if (preprocargs == NULL)
          if (preprocargs == NULL)
            {
            {
              quotedarg = quot (optarg);
              quotedarg = quot (optarg);
              preprocargs = xstrdup (quotedarg);
              preprocargs = xstrdup (quotedarg);
            }
            }
          else
          else
            {
            {
              char *n;
              char *n;
 
 
              quotedarg = quot (optarg);
              quotedarg = quot (optarg);
              n = xmalloc (strlen (preprocargs) + strlen (quotedarg) + 2);
              n = xmalloc (strlen (preprocargs) + strlen (quotedarg) + 2);
              sprintf (n, "%s %s", preprocargs, quotedarg);
              sprintf (n, "%s %s", preprocargs, quotedarg);
              free (preprocargs);
              free (preprocargs);
              preprocargs = n;
              preprocargs = n;
            }
            }
          break;
          break;
 
 
        case 'D':
        case 'D':
        case 'U':
        case 'U':
          if (preprocargs == NULL)
          if (preprocargs == NULL)
            {
            {
              quotedarg = quot (optarg);
              quotedarg = quot (optarg);
              preprocargs = xmalloc (strlen (quotedarg) + 3);
              preprocargs = xmalloc (strlen (quotedarg) + 3);
              sprintf (preprocargs, "-%c%s", c, quotedarg);
              sprintf (preprocargs, "-%c%s", c, quotedarg);
            }
            }
          else
          else
            {
            {
              char *n;
              char *n;
 
 
              quotedarg = quot (optarg);
              quotedarg = quot (optarg);
              n = xmalloc (strlen (preprocargs) + strlen (quotedarg) + 4);
              n = xmalloc (strlen (preprocargs) + strlen (quotedarg) + 4);
              sprintf (n, "%s -%c%s", preprocargs, c, quotedarg);
              sprintf (n, "%s -%c%s", preprocargs, c, quotedarg);
              free (preprocargs);
              free (preprocargs);
              preprocargs = n;
              preprocargs = n;
            }
            }
          break;
          break;
 
 
        case 'r':
        case 'r':
          /* Ignored for compatibility with rc.  */
          /* Ignored for compatibility with rc.  */
          break;
          break;
 
 
        case 'v':
        case 'v':
          verbose ++;
          verbose ++;
          break;
          break;
 
 
        case 'I':
        case 'I':
          /* For backward compatibility, should be removed in the future.  */
          /* For backward compatibility, should be removed in the future.  */
          input_format_tmp = format_from_name (optarg, 0);
          input_format_tmp = format_from_name (optarg, 0);
          if (input_format_tmp != RES_FORMAT_UNKNOWN)
          if (input_format_tmp != RES_FORMAT_UNKNOWN)
            {
            {
              struct stat statbuf;
              struct stat statbuf;
              char modebuf[11];
              char modebuf[11];
 
 
              if (stat (optarg, & statbuf) == 0
              if (stat (optarg, & statbuf) == 0
                  /* Coded this way to avoid importing knowledge of S_ISDIR into this file.  */
                  /* Coded this way to avoid importing knowledge of S_ISDIR into this file.  */
                  && (mode_string (statbuf.st_mode, modebuf), modebuf[0] == 'd'))
                  && (mode_string (statbuf.st_mode, modebuf), modebuf[0] == 'd'))
                /* We have a -I option with a directory name that just happens
                /* We have a -I option with a directory name that just happens
                   to match a format name as well.  eg: -I res  Assume that the
                   to match a format name as well.  eg: -I res  Assume that the
                   user knows what they are doing and do not complain.  */
                   user knows what they are doing and do not complain.  */
                ;
                ;
              else
              else
                {
                {
                  fprintf (stderr,
                  fprintf (stderr,
                           _("Option -I is deprecated for setting the input format, please use -J instead.\n"));
                           _("Option -I is deprecated for setting the input format, please use -J instead.\n"));
                  input_format = input_format_tmp;
                  input_format = input_format_tmp;
                  break;
                  break;
                }
                }
            }
            }
          /* Fall through.  */
          /* Fall through.  */
 
 
        case OPTION_INCLUDE_DIR:
        case OPTION_INCLUDE_DIR:
          if (preprocargs == NULL)
          if (preprocargs == NULL)
            {
            {
              quotedarg = quot (optarg);
              quotedarg = quot (optarg);
              preprocargs = xmalloc (strlen (quotedarg) + 3);
              preprocargs = xmalloc (strlen (quotedarg) + 3);
              sprintf (preprocargs, "-I%s", quotedarg);
              sprintf (preprocargs, "-I%s", quotedarg);
            }
            }
          else
          else
            {
            {
              char *n;
              char *n;
 
 
              quotedarg = quot (optarg);
              quotedarg = quot (optarg);
              n = xmalloc (strlen (preprocargs) + strlen (quotedarg) + 4);
              n = xmalloc (strlen (preprocargs) + strlen (quotedarg) + 4);
              sprintf (n, "%s -I%s", preprocargs, quotedarg);
              sprintf (n, "%s -I%s", preprocargs, quotedarg);
              free (preprocargs);
              free (preprocargs);
              preprocargs = n;
              preprocargs = n;
            }
            }
 
 
          windres_add_include_dir (optarg);
          windres_add_include_dir (optarg);
 
 
          break;
          break;
 
 
        case 'l':
        case 'l':
          language = strtol (optarg, (char **) NULL, 16);
          language = strtol (optarg, (char **) NULL, 16);
          break;
          break;
 
 
        case OPTION_USE_TEMP_FILE:
        case OPTION_USE_TEMP_FILE:
          use_temp_file = 1;
          use_temp_file = 1;
          break;
          break;
 
 
        case OPTION_NO_USE_TEMP_FILE:
        case OPTION_NO_USE_TEMP_FILE:
          use_temp_file = 0;
          use_temp_file = 0;
          break;
          break;
 
 
#ifdef YYDEBUG
#ifdef YYDEBUG
        case OPTION_YYDEBUG:
        case OPTION_YYDEBUG:
          yydebug = 1;
          yydebug = 1;
          break;
          break;
#endif
#endif
 
 
        case 'h':
        case 'h':
        case 'H':
        case 'H':
          usage (stdout, 0);
          usage (stdout, 0);
          break;
          break;
 
 
        case 'V':
        case 'V':
          print_version ("windres");
          print_version ("windres");
          break;
          break;
 
 
        default:
        default:
          usage (stderr, 1);
          usage (stderr, 1);
          break;
          break;
        }
        }
    }
    }
 
 
  if (input_filename == NULL && optind < argc)
  if (input_filename == NULL && optind < argc)
    {
    {
      input_filename = argv[optind];
      input_filename = argv[optind];
      ++optind;
      ++optind;
    }
    }
 
 
  if (output_filename == NULL && optind < argc)
  if (output_filename == NULL && optind < argc)
    {
    {
      output_filename = argv[optind];
      output_filename = argv[optind];
      ++optind;
      ++optind;
    }
    }
 
 
  if (argc != optind)
  if (argc != optind)
    usage (stderr, 1);
    usage (stderr, 1);
 
 
  if (input_format == RES_FORMAT_UNKNOWN)
  if (input_format == RES_FORMAT_UNKNOWN)
    {
    {
      if (input_filename == NULL)
      if (input_filename == NULL)
        input_format = RES_FORMAT_RC;
        input_format = RES_FORMAT_RC;
      else
      else
        input_format = format_from_filename (input_filename, 1);
        input_format = format_from_filename (input_filename, 1);
    }
    }
 
 
  if (output_format == RES_FORMAT_UNKNOWN)
  if (output_format == RES_FORMAT_UNKNOWN)
    {
    {
      if (output_filename == NULL)
      if (output_filename == NULL)
        output_format = RES_FORMAT_RC;
        output_format = RES_FORMAT_RC;
      else
      else
        output_format = format_from_filename (output_filename, 0);
        output_format = format_from_filename (output_filename, 0);
    }
    }
 
 
  set_endianness (NULL, target);
  set_endianness (NULL, target);
 
 
  /* Read the input file.  */
  /* Read the input file.  */
  switch (input_format)
  switch (input_format)
    {
    {
    default:
    default:
      abort ();
      abort ();
    case RES_FORMAT_RC:
    case RES_FORMAT_RC:
      resources = read_rc_file (input_filename, preprocessor, preprocargs,
      resources = read_rc_file (input_filename, preprocessor, preprocargs,
                                language, use_temp_file);
                                language, use_temp_file);
      break;
      break;
    case RES_FORMAT_RES:
    case RES_FORMAT_RES:
      resources = read_res_file (input_filename);
      resources = read_res_file (input_filename);
      break;
      break;
    case RES_FORMAT_COFF:
    case RES_FORMAT_COFF:
      resources = read_coff_rsrc (input_filename, target);
      resources = read_coff_rsrc (input_filename, target);
      break;
      break;
    }
    }
 
 
  if (resources == NULL)
  if (resources == NULL)
    fatal (_("no resources"));
    fatal (_("no resources"));
 
 
  /* Sort the resources.  This is required for COFF, convenient for
  /* Sort the resources.  This is required for COFF, convenient for
     rc, and unimportant for res.  */
     rc, and unimportant for res.  */
  resources = sort_resources (resources);
  resources = sort_resources (resources);
 
 
  /* Write the output file.  */
  /* Write the output file.  */
  reswr_init ();
  reswr_init ();
 
 
  switch (output_format)
  switch (output_format)
    {
    {
    default:
    default:
      abort ();
      abort ();
    case RES_FORMAT_RC:
    case RES_FORMAT_RC:
      write_rc_file (output_filename, resources);
      write_rc_file (output_filename, resources);
      break;
      break;
    case RES_FORMAT_RES:
    case RES_FORMAT_RES:
      write_res_file (output_filename, resources);
      write_res_file (output_filename, resources);
      break;
      break;
    case RES_FORMAT_COFF:
    case RES_FORMAT_COFF:
      write_coff_file (output_filename, target, resources);
      write_coff_file (output_filename, target, resources);
      break;
      break;
    }
    }
 
 
  xexit (0);
  xexit (0);
  return 0;
  return 0;
}
}
 
 
static void
static void
set_endianness (bfd *abfd, const char *target)
set_endianness (bfd *abfd, const char *target)
{
{
  const bfd_target *target_vec;
  const bfd_target *target_vec;
 
 
  def_target_arch = NULL;
  def_target_arch = NULL;
  target_vec = bfd_get_target_info (target, abfd, &target_is_bigendian, NULL,
  target_vec = bfd_get_target_info (target, abfd, &target_is_bigendian, NULL,
                                   &def_target_arch);
                                   &def_target_arch);
  if (! target_vec)
  if (! target_vec)
    fatal ("Can't detect target endianness and architecture.");
    fatal ("Can't detect target endianness and architecture.");
  if (! def_target_arch)
  if (! def_target_arch)
    fatal ("Can't detect architecture.");
    fatal ("Can't detect architecture.");
}
}
 
 
bfd *
bfd *
windres_open_as_binary (const char *filename, int rdmode)
windres_open_as_binary (const char *filename, int rdmode)
{
{
  bfd *abfd;
  bfd *abfd;
 
 
  abfd = (rdmode ? bfd_openr (filename, "binary") : bfd_openw (filename, "binary"));
  abfd = (rdmode ? bfd_openr (filename, "binary") : bfd_openw (filename, "binary"));
  if (! abfd)
  if (! abfd)
    fatal ("can't open `%s' for %s", filename, (rdmode ? "input" : "output"));
    fatal ("can't open `%s' for %s", filename, (rdmode ? "input" : "output"));
 
 
  if (rdmode && ! bfd_check_format (abfd, bfd_object))
  if (rdmode && ! bfd_check_format (abfd, bfd_object))
    fatal ("can't open `%s' for input.", filename);
    fatal ("can't open `%s' for input.", filename);
 
 
  return abfd;
  return abfd;
}
}
 
 
void
void
set_windres_bfd_endianness (windres_bfd *wrbfd, int is_bigendian)
set_windres_bfd_endianness (windres_bfd *wrbfd, int is_bigendian)
{
{
  assert (!! wrbfd);
  assert (!! wrbfd);
  switch (WR_KIND(wrbfd))
  switch (WR_KIND(wrbfd))
  {
  {
  case WR_KIND_BFD_BIN_L:
  case WR_KIND_BFD_BIN_L:
    if (is_bigendian)
    if (is_bigendian)
      WR_KIND(wrbfd) = WR_KIND_BFD_BIN_B;
      WR_KIND(wrbfd) = WR_KIND_BFD_BIN_B;
    break;
    break;
  case WR_KIND_BFD_BIN_B:
  case WR_KIND_BFD_BIN_B:
    if (! is_bigendian)
    if (! is_bigendian)
      WR_KIND(wrbfd) = WR_KIND_BFD_BIN_L;
      WR_KIND(wrbfd) = WR_KIND_BFD_BIN_L;
    break;
    break;
  default:
  default:
    /* only binary bfd can be overriden. */
    /* only binary bfd can be overriden. */
    abort ();
    abort ();
  }
  }
}
}
 
 
void
void
set_windres_bfd (windres_bfd *wrbfd, bfd *abfd, asection *sec, rc_uint_type kind)
set_windres_bfd (windres_bfd *wrbfd, bfd *abfd, asection *sec, rc_uint_type kind)
{
{
  assert (!! wrbfd);
  assert (!! wrbfd);
  switch (kind)
  switch (kind)
  {
  {
  case WR_KIND_TARGET:
  case WR_KIND_TARGET:
    abfd = NULL;
    abfd = NULL;
    sec = NULL;
    sec = NULL;
    break;
    break;
  case WR_KIND_BFD:
  case WR_KIND_BFD:
  case WR_KIND_BFD_BIN_L:
  case WR_KIND_BFD_BIN_L:
  case WR_KIND_BFD_BIN_B:
  case WR_KIND_BFD_BIN_B:
    assert (!! abfd);
    assert (!! abfd);
    assert (!!sec);
    assert (!!sec);
    break;
    break;
  default:
  default:
    abort ();
    abort ();
  }
  }
  WR_KIND(wrbfd) = kind;
  WR_KIND(wrbfd) = kind;
  WR_BFD(wrbfd) = abfd;
  WR_BFD(wrbfd) = abfd;
  WR_SECTION(wrbfd) = sec;
  WR_SECTION(wrbfd) = sec;
}
}
 
 
void
void
set_windres_bfd_content (windres_bfd *wrbfd, const void *data, rc_uint_type off,
set_windres_bfd_content (windres_bfd *wrbfd, const void *data, rc_uint_type off,
                         rc_uint_type length)
                         rc_uint_type length)
{
{
  if (WR_KIND(wrbfd) != WR_KIND_TARGET)
  if (WR_KIND(wrbfd) != WR_KIND_TARGET)
    {
    {
      if (! bfd_set_section_contents (WR_BFD(wrbfd), WR_SECTION(wrbfd), data, off, length))
      if (! bfd_set_section_contents (WR_BFD(wrbfd), WR_SECTION(wrbfd), data, off, length))
        bfd_fatal ("bfd_set_section_contents");
        bfd_fatal ("bfd_set_section_contents");
    }
    }
  else
  else
    abort ();
    abort ();
}
}
 
 
void
void
get_windres_bfd_content (windres_bfd *wrbfd, void *data, rc_uint_type off,
get_windres_bfd_content (windres_bfd *wrbfd, void *data, rc_uint_type off,
                         rc_uint_type length)
                         rc_uint_type length)
{
{
  if (WR_KIND(wrbfd) != WR_KIND_TARGET)
  if (WR_KIND(wrbfd) != WR_KIND_TARGET)
    {
    {
      if (! bfd_get_section_contents (WR_BFD(wrbfd), WR_SECTION(wrbfd), data, off, length))
      if (! bfd_get_section_contents (WR_BFD(wrbfd), WR_SECTION(wrbfd), data, off, length))
        bfd_fatal ("bfd_get_section_contents");
        bfd_fatal ("bfd_get_section_contents");
    }
    }
  else
  else
    abort ();
    abort ();
}
}
 
 
void
void
windres_put_8 (windres_bfd *wrbfd, void *p, rc_uint_type value)
windres_put_8 (windres_bfd *wrbfd, void *p, rc_uint_type value)
{
{
  switch (WR_KIND(wrbfd))
  switch (WR_KIND(wrbfd))
    {
    {
    case WR_KIND_TARGET:
    case WR_KIND_TARGET:
      target_put_8 (p, value);
      target_put_8 (p, value);
      break;
      break;
    case WR_KIND_BFD:
    case WR_KIND_BFD:
    case WR_KIND_BFD_BIN_L:
    case WR_KIND_BFD_BIN_L:
    case WR_KIND_BFD_BIN_B:
    case WR_KIND_BFD_BIN_B:
      bfd_put_8 (WR_BFD(wrbfd), value, p);
      bfd_put_8 (WR_BFD(wrbfd), value, p);
      break;
      break;
    default:
    default:
      abort ();
      abort ();
    }
    }
}
}
 
 
void
void
windres_put_16 (windres_bfd *wrbfd, void *data, rc_uint_type value)
windres_put_16 (windres_bfd *wrbfd, void *data, rc_uint_type value)
{
{
  switch (WR_KIND(wrbfd))
  switch (WR_KIND(wrbfd))
    {
    {
    case WR_KIND_TARGET:
    case WR_KIND_TARGET:
      target_put_16 (data, value);
      target_put_16 (data, value);
      break;
      break;
    case WR_KIND_BFD:
    case WR_KIND_BFD:
    case WR_KIND_BFD_BIN_B:
    case WR_KIND_BFD_BIN_B:
      bfd_put_16 (WR_BFD(wrbfd), value, data);
      bfd_put_16 (WR_BFD(wrbfd), value, data);
      break;
      break;
    case WR_KIND_BFD_BIN_L:
    case WR_KIND_BFD_BIN_L:
      bfd_putl16 (value, data);
      bfd_putl16 (value, data);
      break;
      break;
    default:
    default:
      abort ();
      abort ();
    }
    }
}
}
 
 
void
void
windres_put_32 (windres_bfd *wrbfd, void *data, rc_uint_type value)
windres_put_32 (windres_bfd *wrbfd, void *data, rc_uint_type value)
{
{
  switch (WR_KIND(wrbfd))
  switch (WR_KIND(wrbfd))
    {
    {
    case WR_KIND_TARGET:
    case WR_KIND_TARGET:
      target_put_32 (data, value);
      target_put_32 (data, value);
      break;
      break;
    case WR_KIND_BFD:
    case WR_KIND_BFD:
    case WR_KIND_BFD_BIN_B:
    case WR_KIND_BFD_BIN_B:
      bfd_put_32 (WR_BFD(wrbfd), value, data);
      bfd_put_32 (WR_BFD(wrbfd), value, data);
      break;
      break;
    case WR_KIND_BFD_BIN_L:
    case WR_KIND_BFD_BIN_L:
      bfd_putl32 (value, data);
      bfd_putl32 (value, data);
      break;
      break;
    default:
    default:
      abort ();
      abort ();
    }
    }
}
}
 
 
rc_uint_type
rc_uint_type
windres_get_8 (windres_bfd *wrbfd, const void *data, rc_uint_type length)
windres_get_8 (windres_bfd *wrbfd, const void *data, rc_uint_type length)
{
{
  if (length < 1)
  if (length < 1)
    fatal ("windres_get_8: unexpected eob.");
    fatal ("windres_get_8: unexpected eob.");
  switch (WR_KIND(wrbfd))
  switch (WR_KIND(wrbfd))
    {
    {
    case WR_KIND_TARGET:
    case WR_KIND_TARGET:
      return target_get_8 (data, length);
      return target_get_8 (data, length);
    case WR_KIND_BFD:
    case WR_KIND_BFD:
    case WR_KIND_BFD_BIN_B:
    case WR_KIND_BFD_BIN_B:
    case WR_KIND_BFD_BIN_L:
    case WR_KIND_BFD_BIN_L:
      return bfd_get_8 (WR_BFD(wrbfd), data);
      return bfd_get_8 (WR_BFD(wrbfd), data);
    default:
    default:
      abort ();
      abort ();
    }
    }
  return 0;
  return 0;
}
}
 
 
rc_uint_type
rc_uint_type
windres_get_16 (windres_bfd *wrbfd, const void *data, rc_uint_type length)
windres_get_16 (windres_bfd *wrbfd, const void *data, rc_uint_type length)
{
{
  if (length < 2)
  if (length < 2)
    fatal ("windres_get_16: unexpected eob.");
    fatal ("windres_get_16: unexpected eob.");
  switch (WR_KIND(wrbfd))
  switch (WR_KIND(wrbfd))
    {
    {
    case WR_KIND_TARGET:
    case WR_KIND_TARGET:
      return target_get_16 (data, length);
      return target_get_16 (data, length);
    case WR_KIND_BFD:
    case WR_KIND_BFD:
    case WR_KIND_BFD_BIN_B:
    case WR_KIND_BFD_BIN_B:
      return bfd_get_16 (WR_BFD(wrbfd), data);
      return bfd_get_16 (WR_BFD(wrbfd), data);
    case WR_KIND_BFD_BIN_L:
    case WR_KIND_BFD_BIN_L:
      return bfd_getl16 (data);
      return bfd_getl16 (data);
    default:
    default:
      abort ();
      abort ();
    }
    }
  return 0;
  return 0;
}
}
 
 
rc_uint_type
rc_uint_type
windres_get_32 (windres_bfd *wrbfd, const void *data, rc_uint_type length)
windres_get_32 (windres_bfd *wrbfd, const void *data, rc_uint_type length)
{
{
  if (length < 4)
  if (length < 4)
    fatal ("windres_get_32: unexpected eob.");
    fatal ("windres_get_32: unexpected eob.");
  switch (WR_KIND(wrbfd))
  switch (WR_KIND(wrbfd))
    {
    {
    case WR_KIND_TARGET:
    case WR_KIND_TARGET:
      return target_get_32 (data, length);
      return target_get_32 (data, length);
    case WR_KIND_BFD:
    case WR_KIND_BFD:
    case WR_KIND_BFD_BIN_B:
    case WR_KIND_BFD_BIN_B:
      return bfd_get_32 (WR_BFD(wrbfd), data);
      return bfd_get_32 (WR_BFD(wrbfd), data);
    case WR_KIND_BFD_BIN_L:
    case WR_KIND_BFD_BIN_L:
      return bfd_getl32 (data);
      return bfd_getl32 (data);
    default:
    default:
      abort ();
      abort ();
    }
    }
  return 0;
  return 0;
}
}
 
 
static rc_uint_type
static rc_uint_type
target_get_8 (const void *p, rc_uint_type length)
target_get_8 (const void *p, rc_uint_type length)
{
{
  rc_uint_type ret;
  rc_uint_type ret;
 
 
  if (length < 1)
  if (length < 1)
    fatal ("Resource too small for getting 8-bit value.");
    fatal ("Resource too small for getting 8-bit value.");
 
 
  ret = (rc_uint_type) *((const bfd_byte *) p);
  ret = (rc_uint_type) *((const bfd_byte *) p);
  return ret & 0xff;
  return ret & 0xff;
}
}
 
 
static rc_uint_type
static rc_uint_type
target_get_16 (const void *p, rc_uint_type length)
target_get_16 (const void *p, rc_uint_type length)
{
{
  if (length < 2)
  if (length < 2)
    fatal ("Resource too small for getting 16-bit value.");
    fatal ("Resource too small for getting 16-bit value.");
 
 
  if (target_is_bigendian)
  if (target_is_bigendian)
    return bfd_getb16 (p);
    return bfd_getb16 (p);
  else
  else
    return bfd_getl16 (p);
    return bfd_getl16 (p);
}
}
 
 
static rc_uint_type
static rc_uint_type
target_get_32 (const void *p, rc_uint_type length)
target_get_32 (const void *p, rc_uint_type length)
{
{
  if (length < 4)
  if (length < 4)
    fatal ("Resource too small for getting 32-bit value.");
    fatal ("Resource too small for getting 32-bit value.");
 
 
  if (target_is_bigendian)
  if (target_is_bigendian)
    return bfd_getb32 (p);
    return bfd_getb32 (p);
  else
  else
    return bfd_getl32 (p);
    return bfd_getl32 (p);
}
}
 
 
static void
static void
target_put_8 (void *p, rc_uint_type value)
target_put_8 (void *p, rc_uint_type value)
{
{
  assert (!! p);
  assert (!! p);
  *((bfd_byte *) p)=(bfd_byte) value;
  *((bfd_byte *) p)=(bfd_byte) value;
}
}
 
 
static void
static void
target_put_16 (void *p, rc_uint_type value)
target_put_16 (void *p, rc_uint_type value)
{
{
  assert (!! p);
  assert (!! p);
 
 
  if (target_is_bigendian)
  if (target_is_bigendian)
    bfd_putb16 (value, p);
    bfd_putb16 (value, p);
  else
  else
    bfd_putl16 (value, p);
    bfd_putl16 (value, p);
}
}
 
 
static void
static void
target_put_32 (void *p, rc_uint_type value)
target_put_32 (void *p, rc_uint_type value)
{
{
  assert (!! p);
  assert (!! p);
 
 
  if (target_is_bigendian)
  if (target_is_bigendian)
    bfd_putb32 (value, p);
    bfd_putb32 (value, p);
  else
  else
    bfd_putl32 (value, p);
    bfd_putl32 (value, p);
}
}
 
 
static int isInComment = 0;
static int isInComment = 0;
 
 
int wr_printcomment (FILE *e, const char *fmt, ...)
int wr_printcomment (FILE *e, const char *fmt, ...)
{
{
  va_list arg;
  va_list arg;
  int r = 0;
  int r = 0;
 
 
  if (isInComment)
  if (isInComment)
    r += fprintf (e, "\n   ");
    r += fprintf (e, "\n   ");
  else
  else
    fprintf (e, "/* ");
    fprintf (e, "/* ");
  isInComment = 1;
  isInComment = 1;
  if (fmt == NULL)
  if (fmt == NULL)
    return r;
    return r;
  va_start (arg, fmt);
  va_start (arg, fmt);
  r += vfprintf (e, fmt, arg);
  r += vfprintf (e, fmt, arg);
  va_end (arg);
  va_end (arg);
  return r;
  return r;
}
}
 
 
int wr_print (FILE *e, const char *fmt, ...)
int wr_print (FILE *e, const char *fmt, ...)
{
{
  va_list arg;
  va_list arg;
  int r = 0;
  int r = 0;
  if (isInComment)
  if (isInComment)
    r += fprintf (e, ".  */\n");
    r += fprintf (e, ".  */\n");
  isInComment = 0;
  isInComment = 0;
  if (! fmt)
  if (! fmt)
    return r;
    return r;
  va_start (arg, fmt);
  va_start (arg, fmt);
  r += vfprintf (e, fmt, arg);
  r += vfprintf (e, fmt, arg);
  va_end (arg);
  va_end (arg);
  return r;
  return r;
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.