Back to index

cell-binutils  2.17cvs20070401
Classes | Defines | Enumerations | Functions | Variables
windres.c File Reference
#include "config.h"
#include <assert.h>
#include <time.h>
#include "bfd.h"
#include "getopt.h"
#include "bucomm.h"
#include "libiberty.h"
#include "safe-ctype.h"
#include "obstack.h"
#include "windres.h"

Go to the source code of this file.

Classes

struct  format_map
struct  include_dir

Defines

#define obstack_chunk_alloc   xmalloc
#define obstack_chunk_free   free
#define OPTION_PREPROCESSOR   150
#define OPTION_USE_TEMP_FILE   (OPTION_PREPROCESSOR + 1)
#define OPTION_NO_USE_TEMP_FILE   (OPTION_USE_TEMP_FILE + 1)
#define OPTION_YYDEBUG   (OPTION_NO_USE_TEMP_FILE + 1)

Enumerations

enum  res_format { RES_FORMAT_UNKNOWN, RES_FORMAT_RC, RES_FORMAT_RES, RES_FORMAT_COFF }

Functions

static void res_init (void)
static int extended_menuitems (const struct menuitem *)
static enum res_format format_from_name (const char *, int)
static enum res_format format_from_filename (const char *, int)
static void usage (FILE *, int)
static int cmp_res_entry (const void *, const void *)
static struct res_directorysort_resources (struct res_directory *)
static void reswr_init (void)
static const char * quot (const char *)
void * res_alloc (size_t bytes)
void * reswr_alloc (size_t bytes)
FILE * open_file_search (const char *filename, const char *mode, const char *errmsg, char **real_filename)
int res_id_cmp (struct res_id a, struct res_id b)
void res_id_print (FILE *stream, struct res_id id, int quote)
void res_ids_print (FILE *stream, int cids, const struct res_id *ids)
void res_string_to_id (struct res_id *res_id, const char *string)
struct res_resourcedefine_resource (struct res_directory **resources, int cids, const struct res_id *ids, int dupok)
struct res_resourcedefine_standard_resource (struct res_directory **resources, int type, struct res_id name, int language, int dupok)
int extended_dialog (const struct dialog *dialog)
int extended_menu (const struct menu *menu)
int main (int, char **)

Variables

int verbose = 0
static struct format_map []
static struct include_dirinclude_dirs
static struct obstack
static struct option []

Class Documentation

struct format_map

Definition at line 71 of file windres.c.

Class Members
const char * name
struct include_dir

Definition at line 101 of file windres.c.

Collaboration diagram for include_dir:
Class Members
char * dir
struct include_dir * next

Define Documentation

Definition at line 124 of file windres.c.

#define obstack_chunk_free   free

Definition at line 125 of file windres.c.

Definition at line 713 of file windres.c.

#define OPTION_PREPROCESSOR   150

Definition at line 711 of file windres.c.

Definition at line 712 of file windres.c.

Definition at line 714 of file windres.c.


Enumeration Type Documentation

enum res_format
Enumerator:
RES_FORMAT_UNKNOWN 
RES_FORMAT_RC 
RES_FORMAT_RES 
RES_FORMAT_COFF 

Definition at line 57 of file windres.c.

{
  /* Unknown format.  */
  RES_FORMAT_UNKNOWN,
  /* Textual RC file.  */
  RES_FORMAT_RC,
  /* Binary RES file.  */
  RES_FORMAT_RES,
  /* COFF file.  */
  RES_FORMAT_COFF
};

Function Documentation

static int cmp_res_entry ( const void *  p1,
const void *  p2 
) [static]

Definition at line 424 of file windres.c.

{
  const struct res_entry **re1, **re2;

  re1 = (const struct res_entry **) p1;
  re2 = (const struct res_entry **) p2;
  return res_id_cmp ((*re1)->id, (*re2)->id);
}

Here is the call graph for this function:

Here is the caller graph for this function:

struct res_resource* define_resource ( struct res_directory **  resources,
int  cids,
const struct res_id ids,
int  dupok 
) [read]

Definition at line 310 of file windres.c.

{
  struct res_entry *re = NULL;
  int i;

  assert (cids > 0);
  for (i = 0; i < cids; i++)
    {
      struct res_entry **pp;

      if (*resources == NULL)
       {
         static unsigned long timeval;

         /* Use the same timestamp for every resource created in a
             single run.  */
         if (timeval == 0)
           timeval = time (NULL);

         *resources = ((struct res_directory *)
                     res_alloc (sizeof **resources));
         (*resources)->characteristics = 0;
         (*resources)->time = timeval;
         (*resources)->major = 0;
         (*resources)->minor = 0;
         (*resources)->entries = NULL;
       }

      for (pp = &(*resources)->entries; *pp != NULL; pp = &(*pp)->next)
       if (res_id_cmp ((*pp)->id, ids[i]) == 0)
         break;

      if (*pp != NULL)
       re = *pp;
      else
       {
         re = (struct res_entry *) res_alloc (sizeof *re);
         re->next = NULL;
         re->id = ids[i];
         if ((i + 1) < cids)
           {
             re->subdir = 1;
             re->u.dir = NULL;
           }
         else
           {
             re->subdir = 0;
             re->u.res = NULL;
           }

         *pp = re;
       }

      if ((i + 1) < cids)
       {
         if (! re->subdir)
           {
             fprintf (stderr, "%s: ", program_name);
             res_ids_print (stderr, i, ids);
             fprintf (stderr, _(": expected to be a directory\n"));
             xexit (1);
           }

         resources = &re->u.dir;
       }
    }

  if (re->subdir)
    {
      fprintf (stderr, "%s: ", program_name);
      res_ids_print (stderr, cids, ids);
      fprintf (stderr, _(": expected to be a leaf\n"));
      xexit (1);
    }

  if (re->u.res != NULL)
    {
      if (dupok)
       return re->u.res;

      fprintf (stderr, _("%s: warning: "), program_name);
      res_ids_print (stderr, cids, ids);
      fprintf (stderr, _(": duplicate value\n"));
    }

  re->u.res = ((struct res_resource *)
              res_alloc (sizeof (struct res_resource)));
  memset (re->u.res, 0, sizeof (struct res_resource));

  re->u.res->type = RES_TYPE_UNINITIALIZED;
  return re->u.res;
}

Here is the call graph for this function:

Here is the caller graph for this function:

struct res_resource* define_standard_resource ( struct res_directory **  resources,
int  type,
struct res_id  name,
int  language,
int  dupok 
) [read]

Definition at line 408 of file windres.c.

{
  struct res_id a[3];

  a[0].named = 0;
  a[0].u.id = type;
  a[1] = name;
  a[2].named = 0;
  a[2].u.id = language;
  return define_resource (resources, 3, a, dupok);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 478 of file windres.c.

{
  const struct dialog_control *c;

  if (dialog->ex != NULL)
    return 1;

  for (c = dialog->controls; c != NULL; c = c->next)
    if (c->data != NULL || c->help != 0)
      return 1;

  return 0;
}

Here is the caller graph for this function:

Definition at line 495 of file windres.c.

{
  return extended_menuitems (menu->items);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int extended_menuitems ( const struct menuitem menuitems) [static]

Definition at line 501 of file windres.c.

{
  const struct menuitem *mi;

  for (mi = menuitems; mi != NULL; mi = mi->next)
    {
      if (mi->help != 0 || mi->state != 0)
       return 1;
      if (mi->popup != NULL && mi->id != 0)
       return 1;
      if ((mi->type
          & ~ (MENUITEM_CHECKED
              | MENUITEM_GRAYED
              | MENUITEM_HELP
              | MENUITEM_INACTIVE
              | MENUITEM_MENUBARBREAK
              | MENUITEM_MENUBREAK))
         != 0)
       return 1;
      if (mi->popup != NULL)
       {
         if (extended_menuitems (mi->popup))
           return 1;
       }
    }

  return 0;
}

Here is the caller graph for this function:

static enum res_format format_from_filename ( const char *  filename,
int  input 
) [static]

Definition at line 558 of file windres.c.

{
  const char *ext;
  FILE *e;
  unsigned char b1, b2, b3, b4, b5;
  int magic;

  /* If we have an extension, see if we recognize it as implying a
     particular format.  */
  ext = strrchr (filename, '.');
  if (ext != NULL)
    {
      const struct format_map *m;

      ++ext;
      for (m = format_fileexts; m->name != NULL; m++)
       if (strcasecmp (m->name, ext) == 0)
         return m->format;
    }

  /* If we don't recognize the name of an output file, assume it's a
     COFF file.  */
  if (! input)
    return RES_FORMAT_COFF;

  /* Read the first few bytes of the file to see if we can guess what
     it is.  */
  e = fopen (filename, FOPEN_RB);
  if (e == NULL)
    fatal ("%s: %s", filename, strerror (errno));

  b1 = getc (e);
  b2 = getc (e);
  b3 = getc (e);
  b4 = getc (e);
  b5 = getc (e);

  fclose (e);

  /* A PE executable starts with 0x4d 0x5a.  */
  if (b1 == 0x4d && b2 == 0x5a)
    return RES_FORMAT_COFF;

  /* A COFF .o file starts with a COFF magic number.  */
  magic = (b2 << 8) | b1;
  switch (magic)
    {
    case 0x14c: /* i386 */
    case 0x166: /* MIPS */
    case 0x184: /* Alpha */
    case 0x268: /* 68k */
    case 0x1f0: /* PowerPC */
    case 0x290: /* PA */
      return RES_FORMAT_COFF;
    }

  /* A RES file starts with 0x0 0x0 0x0 0x0 0x20 0x0 0x0 0x0.  */
  if (b1 == 0 && b2 == 0 && b3 == 0 && b4 == 0 && b5 == 0x20)
    return RES_FORMAT_RES;

  /* If every character is printable or space, assume it's an RC file.  */
  if ((ISPRINT (b1) || ISSPACE (b1))
      && (ISPRINT (b2) || ISSPACE (b2))
      && (ISPRINT (b3) || ISSPACE (b3))
      && (ISPRINT (b4) || ISSPACE (b4))
      && (ISPRINT (b5) || ISSPACE (b5)))
    return RES_FORMAT_RC;

  /* Otherwise, we give up.  */
  fatal (_("can not determine type of file `%s'; use the -J option"),
        filename);

  /* Return something to silence the compiler warning.  */
  return RES_FORMAT_UNKNOWN;
}

Here is the call graph for this function:

static enum res_format format_from_name ( const char *  name,
int  exit_on_error 
) [static]

Definition at line 533 of file windres.c.

{
  const struct format_map *m;

  for (m = format_names; m->name != NULL; m++)
    if (strcasecmp (m->name, name) == 0)
      break;

  if (m->name == NULL && exit_on_error)
    {
      non_fatal (_("unknown format type `%s'"), name);
      fprintf (stderr, _("%s: supported formats:"), program_name);
      for (m = format_names; m->name != NULL; m++)
       fprintf (stderr, " %s", m->name);
      fprintf (stderr, "\n");
      xexit (1);
    }

  return m->format;
}

Here is the call graph for this function:

int main ( int  argc,
char **  argv 
)
FILE* open_file_search ( const char *  filename,
const char *  mode,
const char *  errmsg,
char **  real_filename 
)

Definition at line 171 of file windres.c.

{
  FILE *e;
  struct include_dir *d;

  e = fopen (filename, mode);
  if (e != NULL)
    {
      *real_filename = xstrdup (filename);
      return e;
    }

  if (errno == ENOENT)
    {
      for (d = include_dirs; d != NULL; d = d->next)
       {
         char *n;

         n = (char *) xmalloc (strlen (d->dir) + strlen (filename) + 2);
         sprintf (n, "%s/%s", d->dir, filename);
         e = fopen (n, mode);
         if (e != NULL)
           {
             *real_filename = n;
             return e;
           }

         if (errno != ENOENT)
           break;
       }
    }

  fatal (_("can't open %s `%s': %s"), errmsg, filename, strerror (errno));

  /* Return a value to avoid a compiler warning.  */
  return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static const char * quot ( const char *  string) [static]

Definition at line 681 of file windres.c.

{
  static char *buf = 0;
  static int buflen = 0;
  int slen = strlen (string);
  const char *src;
  char *dest;

  if ((buflen < slen * 2 + 2) || !buf)
    {
      buflen = slen * 2 + 2;
      if (buf)
       free (buf);
      buf = (char *) xmalloc (buflen);
    }

  for (src=string, dest=buf; *src; src++, dest++)
    {
      if (*src == '(' || *src == ')' || *src == ' ')
       *dest++ = '\\';
      *dest = *src;
    }
  *dest = 0;
  return buf;
}

Here is the call graph for this function:

void* res_alloc ( size_t  bytes)

Definition at line 142 of file windres.c.

{
  return (void *) obstack_alloc (&res_obstack, bytes);
}

Here is the call graph for this function:

Definition at line 215 of file windres.c.

{
  if (! a.named)
    {
      if (b.named)
       return 1;
      if (a.u.id > b.u.id)
       return 1;
      else if (a.u.id < b.u.id)
       return -1;
      else
       return 0;
    }
  else
    {
      unichar *as, *ase, *bs, *bse;

      if (! b.named)
       return -1;

      as = a.u.n.name;
      ase = as + a.u.n.length;
      bs = b.u.n.name;
      bse = bs + b.u.n.length;

      while (as < ase)
       {
         int i;

         if (bs >= bse)
           return 1;
         i = (int) *as - (int) *bs;
         if (i != 0)
           return i;
         ++as;
         ++bs;
       }

      if (bs < bse)
       return -1;

      return 0;
    }
}

Here is the caller graph for this function:

void res_id_print ( FILE *  stream,
struct res_id  id,
int  quote 
)

Definition at line 263 of file windres.c.

{
  if (! id.named)
    fprintf (stream, "%lu", id.u.id);
  else
    {
      if (quote)
       putc ('"', stream);
      unicode_print (stream, id.u.n.name, id.u.n.length);
      if (quote)
       putc ('"', stream);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void res_ids_print ( FILE *  stream,
int  cids,
const struct res_id ids 
)

Definition at line 280 of file windres.c.

{
  int i;

  for (i = 0; i < cids; i++)
    {
      res_id_print (stream, ids[i], 1);
      if (i + 1 < cids)
       fprintf (stream, ": ");
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void res_init ( void  ) [static]

Definition at line 134 of file windres.c.

{
  obstack_init (&res_obstack);
}

Here is the call graph for this function:

void res_string_to_id ( struct res_id res_id,
const char *  string 
)

Definition at line 295 of file windres.c.

{
  res_id->named = 1;
  unicode_from_ascii (&res_id->u.n.length, &res_id->u.n.name, string);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void* reswr_alloc ( size_t  bytes)

Definition at line 163 of file windres.c.

{
  return (void *) obstack_alloc (&reswr_obstack, bytes);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void reswr_init ( void  ) [static]

Definition at line 155 of file windres.c.

{
  obstack_init (&reswr_obstack);
}

Here is the call graph for this function:

static struct res_directory * sort_resources ( struct res_directory resdir) [static, read]

Definition at line 436 of file windres.c.

{
  int c, i;
  struct res_entry *re;
  struct res_entry **a;

  if (resdir->entries == NULL)
    return resdir;

  c = 0;
  for (re = resdir->entries; re != NULL; re = re->next)
    ++c;

  /* This is a recursive routine, so using xmalloc is probably better
     than alloca.  */
  a = (struct res_entry **) xmalloc (c * sizeof (struct res_entry *));

  for (i = 0, re = resdir->entries; re != NULL; re = re->next, i++)
    a[i] = re;

  qsort (a, c, sizeof (struct res_entry *), cmp_res_entry);

  resdir->entries = a[0];
  for (i = 0; i < c - 1; i++)
    a[i]->next = a[i + 1];
  a[i]->next = NULL;

  free (a);

  /* Now sort the subdirectories.  */

  for (re = resdir->entries; re != NULL; re = re->next)
    if (re->subdir)
      re->u.dir = sort_resources (re->u.dir);

  return resdir;
}

Here is the call graph for this function:

static void usage ( FILE *  stream,
int  status 
) [static]

Definition at line 637 of file windres.c.

{
  fprintf (stream, _("Usage: %s [option(s)] [input-file] [output-file]\n"),
          program_name);
  fprintf (stream, _(" The options are:\n\
  -i --input=<file>            Name input file\n\
  -o --output=<file>           Name output file\n\
  -J --input-format=<format>   Specify input format\n\
  -O --output-format=<format>  Specify output format\n\
  -F --target=<target>         Specify COFF target\n\
     --preprocessor=<program>  Program to use to preprocess 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\
  -U --undefine <sym>          Undefine SYM when preprocessing rc file\n\
  -v --verbose                 Verbose - tells you what it's doing\n\
  -l --language=<val>          Set language when reading rc file\n\
     --use-temp-file           Use a temporary file instead of popen to read\n\
                               the preprocessor output\n\
     --no-use-temp-file        Use popen (default)\n"));
#ifdef YYDEBUG
  fprintf (stream, _("\
     --yydebug                 Turn on parser debugging\n"));
#endif
  fprintf (stream, _("\
  -r                           Ignored for compatibility with rc\n\
  @<file>                      Read options from <file>\n\
  -h --help                    Print this help message\n\
  -V --version                 Print version information\n"));
  fprintf (stream, _("\
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\
No input-file is stdin, default rc.  No output-file is stdout, default rc.\n"));

  list_supported_targets (program_name, stream);

  if (REPORT_BUGS_TO[0] && status == 0)
    fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);

  exit (status);
}

Here is the call graph for this function:


Variable Documentation

static struct format_map [static]
Initial value:
{
  { "rc", RES_FORMAT_RC },
  { "res", RES_FORMAT_RES },
  { "coff", RES_FORMAT_COFF },
  { NULL, RES_FORMAT_UNKNOWN }
}

Definition at line 79 of file windres.c.

Definition at line 107 of file windres.c.

static struct obstack [static]

Definition at line 129 of file windres.c.

struct option[] [static]
Initial value:
{
  {"input", required_argument, 0, 'i'},
  {"output", required_argument, 0, 'o'},
  {"input-format", required_argument, 0, 'J'},
  {"output-format", required_argument, 0, 'O'},
  {"target", required_argument, 0, 'F'},
  {"preprocessor", required_argument, 0, OPTION_PREPROCESSOR},
  {"include-dir", required_argument, 0, 'I'},
  {"define", required_argument, 0, 'D'},
  {"undefine", required_argument, 0, 'U'},
  {"verbose", no_argument, 0, 'v'},
  {"language", required_argument, 0, 'l'},
  {"use-temp-file", no_argument, 0, OPTION_USE_TEMP_FILE},
  {"no-use-temp-file", no_argument, 0, OPTION_NO_USE_TEMP_FILE},
  {"yydebug", no_argument, 0, OPTION_YYDEBUG},
  {"version", no_argument, 0, 'V'},
  {"help", no_argument, 0, 'h'},
  {0, no_argument, 0, 0}
}

Definition at line 716 of file windres.c.

int verbose = 0

Definition at line 53 of file windres.c.