Back to index

cell-binutils  2.17cvs20070401
Classes | Functions | Variables
resres.c File Reference
#include "bfd.h"
#include "bucomm.h"
#include "libiberty.h"
#include "windres.h"
#include <assert.h>
#include <time.h>

Go to the source code of this file.

Classes

struct  res_hdr

Functions

static void write_res_directory PARAMS ((const struct res_directory *, const struct res_id *, const struct res_id *, int *, int))
static void write_res_resource PARAMS ((const struct res_id *, const struct res_id *, const struct res_resource *, int *))
static void write_res_bin PARAMS ((const struct res_resource *, const struct res_id *, const struct res_id *, const struct res_res_info *))
static void write_res_id PARAMS ((const struct res_id *))
static void write_res_info PARAMS ((const struct res_res_info *))
static void write_res_data PARAMS ((const void *, size_t, int))
static void write_res_header PARAMS ((unsigned long, const struct res_id *, const struct res_id *, const struct res_res_info *))
static int read_resource_entry PARAMS ((void))
static void read_res_data PARAMS ((void *, size_t, int))
static void read_res_id PARAMS ((struct res_id *))
static unichar *read_unistring PARAMS ((int *))
static void res_add_resource PARAMS ((struct res_resource *, const struct res_id *, const struct res_id *, int, int))
void res_append_resource PARAMS ((struct res_directory **, struct res_resource *, int, const struct res_id *, int))
struct res_directoryread_res_file (char *fn) const
void write_res_file (char *fn, const struct res_directory *resdir) const
static int read_resource_entry (void)
static void write_res_directory (struct res_directory *rd, const struct res_id *type, const struct res_id *name, int *language, int level) const
static void write_res_resource (struct res_id *type, const struct res_id *name, const struct res_resource *res, language) const
static void write_res_bin (struct res_resource *res, const struct res_id *type, const struct res_id *name, const struct res_res_info *resinfo) const
static unsigned long get_id_size (struct res_id *id) const
static void write_res_header (unsigned long datasize, const struct res_id *type, const struct res_id *name, const struct res_res_info *resinfo)
static void write_res_data (void *data, size_t size, int count) const
static void read_res_data (void *data, size_t size, int count)
static void write_res_id (struct res_id *id) const
static void write_res_info (struct res_res_info *info) const
void read_res_id (struct res_id *id)
static unicharread_unistring (int *len)
static void res_align_file (void)
static void skip_null_resource (void)
void res_add_resource (struct res_resource *r, const struct res_id *type, const struct res_id *id, int language, int dupok)
void res_append_resource (struct res_directory **resources, struct res_resource *resource, int cids, const struct res_id *ids, int dupok)

Variables

static struct res_directoryresources = NULL
static FILE * fres
static const char * filename
char * program_name

Class Documentation

struct res_hdr

Definition at line 34 of file resres.c.

Class Members
unsigned long data_size
unsigned long header_size

Function Documentation

static unsigned long get_id_size ( struct res_id id) const [static]

Definition at line 369 of file resres.c.

{
  if (id->named)
    return sizeof (unichar) * (id->u.n.length + 1);
  else
    return sizeof (unichar) * 2;
}

Here is the caller graph for this function:

static void write_res_id PARAMS ( (const struct res_id *)  ) [static]
static void write_res_info PARAMS ( (const struct res_res_info *)  ) [static]
static void write_res_data PARAMS ( (const void *, size_t, int ) [static]
static int read_resource_entry PARAMS ( (void)  ) [static]
static void read_res_data PARAMS ( (void *, size_t, int ) [static]
static void read_res_id PARAMS ( (struct res_id *)  ) [static]
static unichar* read_unistring PARAMS ( (int *)  ) [static]
static void read_res_data ( void *  data,
size_t  size,
int  count 
) [static]

Definition at line 417 of file resres.c.

{
  if (fread (data, size, count, fres) != (size_t) count)
    fatal ("%s: unexpected end of file", filename);
}

Here is the call graph for this function:

Here is the caller graph for this function:

struct res_directory* read_res_file ( char *  fn) const [read]

Definition at line 86 of file resres.c.

{
  filename = fn;
  fres = fopen (filename, "rb");
  if (fres == NULL)
    fatal ("can't open `%s' for output: %s", filename, strerror (errno));

  skip_null_resource ();

  while (read_resource_entry ())
    ;

  fclose (fres);

  return resources;
}

Here is the call graph for this function:

void read_res_id ( struct res_id id)

Definition at line 461 of file resres.c.

{
  unsigned short ord;
  unichar *id_s = NULL;
  int len;

  read_res_data (&ord, sizeof (ord), 1);
  if (ord == 0xFFFF)        /* an ordinal id */
    {
      read_res_data (&ord, sizeof (ord), 1);
      id->named = 0;
      id->u.id = ord;
    }
  else
    /* named id */
    {
      if (fseek (fres, -sizeof (ord), SEEK_CUR) != 0)
       fatal ("%s: %s: could not seek in file", program_name, filename);
      id_s = read_unistring (&len);
      id->named = 1;
      id->u.n.length = len;
      id->u.n.name = id_s;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int read_resource_entry ( void  ) [static]

Definition at line 143 of file resres.c.

{
  struct res_id type;
  struct res_id name;
  struct res_res_info resinfo;
  struct res_hdr reshdr;
  long version;
  void *buff;

  struct res_resource *r;

  res_align_file ();

  /* Read header */
  if (fread (&reshdr, sizeof (reshdr), 1, fres) != 1)
    return 0;

  /* read resource type */
  read_res_id (&type);
  /* read resource id */
  read_res_id (&name);

  res_align_file ();

  /* Read additional resource header */
  read_res_data (&resinfo.version, sizeof (resinfo.version), 1);
  read_res_data (&resinfo.memflags, sizeof (resinfo.memflags), 1);
  read_res_data (&resinfo.language, sizeof (resinfo.language), 1);
  read_res_data (&version, sizeof (version), 1);
  read_res_data (&resinfo.characteristics, sizeof (resinfo.characteristics), 1);

  res_align_file ();

  /* Allocate buffer for data */
  buff = res_alloc (reshdr.data_size);
  /* Read data */
  read_res_data (buff, reshdr.data_size, 1);
  /* Convert binary data to resource */
  r = bin_to_res (type, buff, reshdr.data_size, 0);
  r->res_info = resinfo;
  /* Add resource to resource directory */
  res_add_resource (r, &type, &name, resinfo.language, 0);

  return 1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static unichar* read_unistring ( int len) [static]

Definition at line 489 of file resres.c.

{
  unichar *s;
  unichar c;
  unichar *p;
  int l;

  *len = 0;
  l = 0;

  /* there are hardly any names longer than 256 characters */
  p = s = (unichar *) xmalloc (sizeof (unichar) * 256);
  do
    {
      read_res_data (&c, sizeof (c), 1);
      *p++ = c;
      if (c != 0)
       l++;
    }
  while (c != 0);
  *len = l;
  return s;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void res_add_resource ( struct res_resource r,
const struct res_id type,
const struct res_id id,
int  language,
int  dupok 
)

Definition at line 551 of file resres.c.

{
  struct res_id a[3];

  a[0] = *type;
  a[1] = *id;
  a[2].named = 0;
  a[2].u.id = language;
  res_append_resource (&resources, r, 3, a, dupok);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void res_align_file ( void  ) [static]

Definition at line 516 of file resres.c.

{
  int pos = ftell (fres);
  int skip = ((pos + 3) & ~3) - pos;
  if (fseek (fres, skip, SEEK_CUR) != 0)
    fatal ("%s: %s: unable to align file", program_name, filename);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void res_append_resource ( struct res_directory **  resources,
struct res_resource resource,
int  cids,
const struct res_id ids,
int  dupok 
)

Definition at line 572 of file resres.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;

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

  re->u.res = resource;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void skip_null_resource ( void  ) [static]

Definition at line 529 of file resres.c.

{
  struct res_hdr reshdr =
  {0, 0};
  read_res_data (&reshdr, sizeof (reshdr), 1);
  if ((reshdr.data_size != 0) || (reshdr.header_size != 0x20))
    goto skip_err;

  /* Subtract size of HeaderSize and DataSize */
  if (fseek (fres, reshdr.header_size - 8, SEEK_CUR) != 0)
    goto skip_err;

  return;

skip_err:
  fprintf (stderr, "%s: %s: Not a valid WIN32 resource file\n", program_name,
          filename);
  xexit (1);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void write_res_bin ( struct res_resource res,
const struct res_id type,
const struct res_id name,
const struct res_res_info resinfo 
) const [static]

Definition at line 348 of file resres.c.

{
  unsigned long datasize = 0;
  const struct bindata *bin_rep, *data;

  bin_rep = res_to_bin (res, 0);
  for (data = bin_rep; data != NULL; data = data->next)
    datasize += data->length;

  write_res_header (datasize, type, name, resinfo);

  for (data = bin_rep; data != NULL; data = data->next)
    write_res_data (data->data, data->length, 1);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void write_res_data ( void *  data,
size_t  size,
int  count 
) const [static]

Definition at line 406 of file resres.c.

{
  if ((size_t) fwrite (data, size, count, fres) != (size_t) count)
    fatal ("%s: could not write to file", filename);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void write_res_directory ( struct res_directory rd,
const struct res_id type,
const struct res_id name,
int language,
int  level 
) const [static]

Definition at line 191 of file resres.c.

{
  const struct res_entry *re;

  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) *language
             && (re->id.u.id & 0xffff) == re->id.u.id)
           {
             *language = re->id.u.id;
           }
         break;

       default:
         break;
       }

      if (re->subdir)
       write_res_directory (re->u.dir, type, name, language, level + 1);
      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_res_resource (type, name, re->u.res, language);
           }
         else
           {
             fprintf (stderr, "// Resource at unexpected level %d\n", level);
             write_res_resource (type, (struct res_id *) NULL, re->u.res,
                              language);
           }
       }
    }

}

Here is the call graph for this function:

Here is the caller graph for this function:

void write_res_file ( char *  fn,
const struct res_directory resdir 
) const

Definition at line 106 of file resres.c.

{
  int language;
  static const unsigned char sign[] =
  {0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
   0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  long fpos;

  filename = fn;

  fres = fopen (filename, "wb");
  if (fres == NULL)
    fatal ("can't open `%s' for output: %s", filename, strerror (errno));

  /* Write 32 bit resource signature */
  write_res_data (sign, sizeof (sign), 1);

  /* write resources */

  language = -1;
  write_res_directory (resdir, (const struct res_id *) NULL,
                     (const struct res_id *) NULL, &language, 1);

  /* end file on DWORD boundary */
  fpos = ftell (fres);
  if (fpos % 4)
    write_res_data (sign, fpos % 4, 1);

  fclose (fres);
}

Here is the call graph for this function:

static void write_res_header ( unsigned long  datasize,
const struct res_id type,
const struct res_id name,
const struct res_res_info resinfo 
) [static]

Definition at line 380 of file resres.c.

{
  struct res_hdr reshdr;
  reshdr.data_size = datasize;
  reshdr.header_size = 24 + get_id_size (type) + get_id_size (name);

  reshdr.header_size = (reshdr.header_size + 3) & ~3;

  res_align_file ();
  write_res_data (&reshdr, sizeof (reshdr), 1);
  write_res_id (type);
  write_res_id (name);

  res_align_file ();

  write_res_info (resinfo);
  res_align_file ();
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void write_res_id ( struct res_id id) const [static]

Definition at line 428 of file resres.c.

{
  if (id->named)
    {
      unsigned long len = id->u.n.length;
      unichar null_term = 0;
      write_res_data (id->u.n.name, len * sizeof (unichar), 1);
      write_res_data (&null_term, sizeof (null_term), 1);
    }
  else
    {
      unsigned short i = 0xFFFF;
      write_res_data (&i, sizeof (i), 1);
      i = id->u.id;
      write_res_data (&i, sizeof (i), 1);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void write_res_info ( struct res_res_info info) const [static]

Definition at line 449 of file resres.c.

{
  write_res_data (&info->version, sizeof (info->version), 1);
  write_res_data (&info->memflags, sizeof (info->memflags), 1);
  write_res_data (&info->language, sizeof (info->language), 1);
  write_res_data (&info->version, sizeof (info->version), 1);
  write_res_data (&info->characteristics, sizeof (info->characteristics), 1);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void write_res_resource ( struct res_id type,
const struct res_id name,
const struct res_resource res,
language   
) const [static]

Definition at line 258 of file resres.c.

{
  int rt;

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

    case RES_TYPE_ACCELERATOR:
      rt = RT_ACCELERATOR;
      break;

    case RES_TYPE_BITMAP:
      rt = RT_BITMAP;
      break;

    case RES_TYPE_CURSOR:
      rt = RT_CURSOR;
      break;

    case RES_TYPE_GROUP_CURSOR:
      rt = RT_GROUP_CURSOR;
      break;

    case RES_TYPE_DIALOG:
      rt = RT_DIALOG;
      break;

    case RES_TYPE_FONT:
      rt = RT_FONT;
      break;

    case RES_TYPE_FONTDIR:
      rt = RT_FONTDIR;
      break;

    case RES_TYPE_ICON:
      rt = RT_ICON;
      break;

    case RES_TYPE_GROUP_ICON:
      rt = RT_GROUP_ICON;
      break;

    case RES_TYPE_MENU:
      rt = RT_MENU;
      break;

    case RES_TYPE_MESSAGETABLE:
      rt = RT_MESSAGETABLE;
      break;

    case RES_TYPE_RCDATA:
      rt = RT_RCDATA;
      break;

    case RES_TYPE_STRINGTABLE:
      rt = RT_STRING;
      break;

    case RES_TYPE_USERDATA:
      rt = 0;
      break;

    case RES_TYPE_VERSIONINFO:
      rt = RT_VERSION;
      break;
    }

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

  write_res_bin (res, type, name, &res->res_info);
  return;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

const char* filename [static]

Definition at line 80 of file resres.c.

FILE* fres [static]

Definition at line 79 of file resres.c.

char* program_name

Definition at line 49 of file bucomm.c.

Definition at line 77 of file resres.c.