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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.18.50/] [binutils/] [resres.c] - Blame information for rev 486

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 38 julius
/* resres.c: read_res_file and write_res_file implementation for windres.
2
   Copyright 1998, 1999, 2001, 2002, 2007
3
   Free Software Foundation, Inc.
4
   Written by Anders Norlander <anorland@hem2.passagen.se>.
5
   Rewritten by Kai Tietz, Onevision.
6
 
7
   This file is part of GNU Binutils.
8
 
9
   This program is free software; you can redistribute it and/or modify
10
   it under the terms of the GNU General Public License as published by
11
   the Free Software Foundation; either version 3 of the License, or
12
   (at your option) any later version.
13
 
14
   This program is distributed in the hope that it will be useful,
15
   but WITHOUT ANY WARRANTY; without even the implied warranty of
16
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
   GNU General Public License for more details.
18
 
19
   You should have received a copy of the GNU General Public License
20
   along with this program; if not, write to the Free Software
21
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
22
   02110-1301, USA.  */
23
 
24
/* FIXME: This file does not work correctly in a cross configuration.
25
   It assumes that it can use fread and fwrite to read and write
26
   integers.  It does no swapping.  */
27
 
28
#include "sysdep.h"
29
#include "bfd.h"
30
#include "bucomm.h"
31
#include "libiberty.h"
32
#include "windres.h"
33
 
34
#include <assert.h>
35
#include <time.h>
36
 
37
static rc_uint_type write_res_directory (windres_bfd *, rc_uint_type,
38
                                         const rc_res_directory *, const rc_res_id *,
39
                                         const rc_res_id *, rc_uint_type *, int);
40
static rc_uint_type write_res_resource (windres_bfd *, rc_uint_type,const rc_res_id *,
41
                                        const rc_res_id *, const rc_res_resource *,
42
                                        rc_uint_type *);
43
static rc_uint_type write_res_bin (windres_bfd *, rc_uint_type, const rc_res_resource *,
44
                                   const rc_res_id *, const rc_res_id *,
45
                                   const rc_res_res_info *);
46
 
47
static rc_uint_type write_res_id (windres_bfd *, rc_uint_type, const rc_res_id *);
48
static rc_uint_type write_res_info (windres_bfd *, rc_uint_type, const rc_res_res_info *);
49
static rc_uint_type write_res_data_hdr (windres_bfd *, rc_uint_type, res_hdr *);
50
 
51
static rc_uint_type write_res_header (windres_bfd *, rc_uint_type, rc_uint_type,
52
                                      const rc_res_id *, const rc_res_id *,
53
                                      const rc_res_res_info *);
54
 
55
static int read_resource_entry (windres_bfd *, rc_uint_type *, rc_uint_type);
56
static void read_res_data (windres_bfd *, rc_uint_type *, rc_uint_type, void *,
57
                           rc_uint_type);
58
static void read_res_data_hdr (windres_bfd *, rc_uint_type *, rc_uint_type, res_hdr *);
59
static void read_res_id (windres_bfd *, rc_uint_type *, rc_uint_type, rc_res_id *);
60
static unichar *read_unistring (windres_bfd *, rc_uint_type *, rc_uint_type, rc_uint_type *);
61
static void skip_null_resource (windres_bfd *, rc_uint_type *, rc_uint_type);
62
static int probe_binary (windres_bfd *wrbfd, rc_uint_type);
63
 
64
static unsigned long get_id_size (const rc_res_id *);
65
 
66
static void res_add_resource (rc_res_resource *, const rc_res_id *,
67
                              const rc_res_id *, rc_uint_type, int);
68
 
69
static void res_append_resource (rc_res_directory **, rc_res_resource *,
70
                                 int, const rc_res_id *, int);
71
 
72
static rc_res_directory *resources = NULL;
73
 
74
static const char *filename;
75
 
76
extern char *program_name;
77
 
78
/* Read resource file */
79
rc_res_directory *
80
read_res_file (const char *fn)
81
{
82
  rc_uint_type off, flen;
83
  windres_bfd wrbfd;
84
  bfd *abfd;
85
  asection *sec;
86
  filename = fn;
87
 
88
  flen = (rc_uint_type) get_file_size (filename);
89
  if (! flen)
90
    fatal ("can't open '%s' for input.", filename);
91
  abfd = windres_open_as_binary (filename, 1);
92
  sec = bfd_get_section_by_name (abfd, ".data");
93
  if (sec == NULL)
94
    bfd_fatal ("bfd_get_section_by_name");
95
  set_windres_bfd (&wrbfd, abfd, sec,
96
                   (target_is_bigendian ? WR_KIND_BFD_BIN_B
97
                                        : WR_KIND_BFD_BIN_L));
98
  off = 0;
99
 
100
  if (! probe_binary (&wrbfd, flen))
101
    set_windres_bfd_endianess (&wrbfd, ! target_is_bigendian);
102
 
103
  skip_null_resource (&wrbfd, &off, flen);
104
 
105
  while (read_resource_entry (&wrbfd, &off, flen))
106
    ;
107
 
108
  bfd_close (abfd);
109
 
110
  return resources;
111
}
112
 
113
/* Write resource file */
114
void
115
write_res_file (const char *fn,const rc_res_directory *resdir)
116
{
117
  asection *sec;
118
  rc_uint_type language;
119
  bfd *abfd;
120
  windres_bfd wrbfd;
121
  unsigned long sec_length = 0,sec_length_wrote;
122
  static const bfd_byte sign[] =
123
  {0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
124
   0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00,
125
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
126
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
127
 
128
  filename = fn;
129
 
130
  abfd = windres_open_as_binary (filename, 0);
131
  sec = bfd_make_section (abfd, ".data");
132
  if (sec == NULL)
133
    bfd_fatal ("bfd_make_section");
134
  if (! bfd_set_section_flags (abfd, sec,
135
                               (SEC_HAS_CONTENTS | SEC_ALLOC
136
                                | SEC_LOAD | SEC_DATA)))
137
    bfd_fatal ("bfd_set_section_flags");
138
  /* Requiring this is probably a bug in BFD.  */
139
  sec->output_section = sec;
140
 
141
  set_windres_bfd (&wrbfd, abfd, sec,
142
                   (target_is_bigendian ? WR_KIND_BFD_BIN_B
143
                                        : WR_KIND_BFD_BIN_L));
144
 
145
  language = -1;
146
  sec_length = write_res_directory ((windres_bfd *) NULL, 0x20UL, resdir,
147
                                    (const rc_res_id *) NULL,
148
                                    (const rc_res_id *) NULL, &language, 1);
149
  if (! bfd_set_section_size (abfd, sec, (sec_length + 3) & ~3))
150
    bfd_fatal ("bfd_set_section_size");
151
  if ((sec_length & 3) != 0)
152
    set_windres_bfd_content (&wrbfd, sign, sec_length, 4-(sec_length & 3));
153
  set_windres_bfd_content (&wrbfd, sign, 0, sizeof (sign));
154
  language = -1;
155
  sec_length_wrote = write_res_directory (&wrbfd, 0x20UL, resdir,
156
                                          (const rc_res_id *) NULL,
157
                                          (const rc_res_id *) NULL,
158
                                          &language, 1);
159
  if (sec_length != sec_length_wrote)
160
    fatal ("res write failed with different sizes (%lu/%lu).", (long) sec_length,
161
           (long) sec_length_wrote);
162
 
163
  bfd_close (abfd);
164
  return;
165
}
166
 
167
/* Read a resource entry, returns 0 when all resources are read */
168
static int
169
read_resource_entry (windres_bfd *wrbfd, rc_uint_type *off, rc_uint_type omax)
170
{
171
  rc_res_id type;
172
  rc_res_id name;
173
  rc_res_res_info resinfo;
174
  res_hdr reshdr;
175
  void *buff;
176
 
177
  rc_res_resource *r;
178
  struct bin_res_info l;
179
 
180
  off[0] = (off[0] + 3) & ~3;
181
 
182
  /* Read header */
183
  if ((off[0] + 8) > omax)
184
    return 0;
185
  read_res_data_hdr (wrbfd, off, omax, &reshdr);
186
 
187
  /* read resource type */
188
  read_res_id (wrbfd, off, omax, &type);
189
  /* read resource id */
190
  read_res_id (wrbfd, off, omax, &name);
191
 
192
  off[0] = (off[0] + 3) & ~3;
193
 
194
  /* Read additional resource header */
195
  read_res_data (wrbfd, off, omax, &l, BIN_RES_INFO_SIZE);
196
  resinfo.version = windres_get_32 (wrbfd, l.version, 4);
197
  resinfo.memflags = windres_get_16 (wrbfd, l.memflags, 2);
198
  resinfo.language = windres_get_16 (wrbfd, l.language, 2);
199
  /* resinfo.version2 = windres_get_32 (wrbfd, l.version2, 4); */
200
  resinfo.characteristics = windres_get_32 (wrbfd, l.characteristics, 4);
201
 
202
  off[0] = (off[0] + 3) & ~3;
203
 
204
  /* Allocate buffer for data */
205
  buff = res_alloc (reshdr.data_size);
206
  /* Read data */
207
  read_res_data (wrbfd, off, omax, buff, reshdr.data_size);
208
  /* Convert binary data to resource */
209
  r = bin_to_res (wrbfd, type, buff, reshdr.data_size);
210
  r->res_info = resinfo;
211
  /* Add resource to resource directory */
212
  res_add_resource (r, &type, &name, resinfo.language, 0);
213
 
214
  return 1;
215
}
216
 
217
/* write resource directory to binary resource file */
218
static rc_uint_type
219
write_res_directory (windres_bfd *wrbfd, rc_uint_type off, const rc_res_directory *rd,
220
                     const rc_res_id *type, const rc_res_id *name, rc_uint_type *language,
221
                     int level)
222
{
223
  const rc_res_entry *re;
224
 
225
  for (re = rd->entries; re != NULL; re = re->next)
226
    {
227
      switch (level)
228
        {
229
        case 1:
230
          /* If we're at level 1, the key of this resource is the
231
             type.  This normally duplicates the information we have
232
             stored with the resource itself, but we need to remember
233
             the type if this is a user define resource type.  */
234
          type = &re->id;
235
          break;
236
 
237
        case 2:
238
          /* If we're at level 2, the key of this resource is the name
239
             we are going to use in the rc printout.  */
240
          name = &re->id;
241
          break;
242
 
243
        case 3:
244
          /* If we're at level 3, then this key represents a language.
245
             Use it to update the current language.  */
246
          if (! re->id.named
247
              && re->id.u.id != (unsigned long) *language
248
              && (re->id.u.id & 0xffff) == re->id.u.id)
249
            {
250
              *language = re->id.u.id;
251
            }
252
          break;
253
 
254
        default:
255
          break;
256
        }
257
 
258
      if (re->subdir)
259
        off = write_res_directory (wrbfd, off, re->u.dir, type, name, language,
260
                                   level + 1);
261
      else
262
        {
263
          if (level == 3)
264
            {
265
              /* This is the normal case: the three levels are
266
                 TYPE/NAME/LANGUAGE.  NAME will have been set at level
267
                 2, and represents the name to use.  We probably just
268
                 set LANGUAGE, and it will probably match what the
269
                 resource itself records if anything.  */
270
              off = write_res_resource (wrbfd, off, type, name, re->u.res,
271
                                        language);
272
            }
273
          else
274
            {
275
              fprintf (stderr, "// Resource at unexpected level %d\n", level);
276
              off = write_res_resource (wrbfd, off, type, (rc_res_id *) NULL,
277
                                        re->u.res, language);
278
            }
279
        }
280
    }
281
 
282
  return off;
283
}
284
 
285
static rc_uint_type
286
write_res_resource (windres_bfd *wrbfd, rc_uint_type off, const rc_res_id *type,
287
                    const rc_res_id *name, const rc_res_resource *res,
288
                    rc_uint_type *language ATTRIBUTE_UNUSED)
289
{
290
  int rt;
291
 
292
  switch (res->type)
293
    {
294
    default:
295
      abort ();
296
 
297
    case RES_TYPE_ACCELERATOR:
298
      rt = RT_ACCELERATOR;
299
      break;
300
 
301
    case RES_TYPE_BITMAP:
302
      rt = RT_BITMAP;
303
      break;
304
 
305
    case RES_TYPE_CURSOR:
306
      rt = RT_CURSOR;
307
      break;
308
 
309
    case RES_TYPE_GROUP_CURSOR:
310
      rt = RT_GROUP_CURSOR;
311
      break;
312
 
313
    case RES_TYPE_DIALOG:
314
      rt = RT_DIALOG;
315
      break;
316
 
317
    case RES_TYPE_FONT:
318
      rt = RT_FONT;
319
      break;
320
 
321
    case RES_TYPE_FONTDIR:
322
      rt = RT_FONTDIR;
323
      break;
324
 
325
    case RES_TYPE_ICON:
326
      rt = RT_ICON;
327
      break;
328
 
329
    case RES_TYPE_GROUP_ICON:
330
      rt = RT_GROUP_ICON;
331
      break;
332
 
333
    case RES_TYPE_MENU:
334
      rt = RT_MENU;
335
      break;
336
 
337
    case RES_TYPE_MESSAGETABLE:
338
      rt = RT_MESSAGETABLE;
339
      break;
340
 
341
    case RES_TYPE_RCDATA:
342
      rt = RT_RCDATA;
343
      break;
344
 
345
    case RES_TYPE_STRINGTABLE:
346
      rt = RT_STRING;
347
      break;
348
 
349
    case RES_TYPE_USERDATA:
350
      rt = 0;
351
      break;
352
 
353
    case RES_TYPE_VERSIONINFO:
354
      rt = RT_VERSION;
355
      break;
356
 
357
    case RES_TYPE_TOOLBAR:
358
      rt = RT_TOOLBAR;
359
      break;
360
    }
361
 
362
  if (rt != 0
363
      && type != NULL
364
      && (type->named || type->u.id != (unsigned long) rt))
365
    {
366
      fprintf (stderr, "// Unexpected resource type mismatch: ");
367
      res_id_print (stderr, *type, 1);
368
      fprintf (stderr, " != %d", rt);
369
      abort ();
370
    }
371
 
372
  return write_res_bin (wrbfd, off, res, type, name, &res->res_info);
373
}
374
 
375
/* Write a resource in binary resource format */
376
static rc_uint_type
377
write_res_bin (windres_bfd *wrbfd, rc_uint_type off, const rc_res_resource *res,
378
               const rc_res_id *type, const rc_res_id *name,
379
               const rc_res_res_info *resinfo)
380
{
381
  rc_uint_type noff;
382
  rc_uint_type datasize = 0;
383
 
384
  noff = res_to_bin ((windres_bfd *) NULL, off, res);
385
  datasize = noff - off;
386
 
387
  off = write_res_header (wrbfd, off, datasize, type, name, resinfo);
388
  return res_to_bin (wrbfd, off, res);
389
}
390
 
391
/* Get number of bytes needed to store an id in binary format */
392
static unsigned long
393
get_id_size (id)
394
     const rc_res_id *id;
395
{
396
  if (id->named)
397
    return sizeof (unichar) * (id->u.n.length + 1);
398
  else
399
    return sizeof (unichar) * 2;
400
}
401
 
402
/* Write a resource header */
403
static rc_uint_type
404
write_res_header (windres_bfd *wrbfd, rc_uint_type off, rc_uint_type datasize,
405
                  const rc_res_id *type, const rc_res_id *name,
406
                  const rc_res_res_info *resinfo)
407
{
408
  res_hdr reshdr;
409
  reshdr.data_size = datasize;
410
  reshdr.header_size = 24 + get_id_size (type) + get_id_size (name);
411
 
412
  reshdr.header_size = (reshdr.header_size + 3) & ~3;
413
 
414
  off = (off + 3) & ~3;
415
 
416
  off = write_res_data_hdr (wrbfd, off, &reshdr);
417
  off = write_res_id (wrbfd, off, type);
418
  off = write_res_id (wrbfd, off, name);
419
 
420
  off = (off + 3) & ~3;
421
 
422
  off = write_res_info (wrbfd, off, resinfo);
423
  off = (off + 3) & ~3;
424
  return off;
425
}
426
 
427
static rc_uint_type
428
write_res_data_hdr (windres_bfd *wrbfd, rc_uint_type off, res_hdr *hdr)
429
{
430
  if (wrbfd)
431
    {
432
      struct bin_res_hdr brh;
433
      windres_put_32 (wrbfd, brh.data_size, hdr->data_size);
434
      windres_put_32 (wrbfd, brh.header_size, hdr->header_size);
435
      set_windres_bfd_content (wrbfd, &brh, off, BIN_RES_HDR_SIZE);
436
    }
437
  return off + BIN_RES_HDR_SIZE;
438
}
439
 
440
static void
441
read_res_data_hdr (windres_bfd *wrbfd, rc_uint_type *off, rc_uint_type omax,
442
                   res_hdr *reshdr)
443
{
444
  struct bin_res_hdr brh;
445
 
446
  if ((off[0] + BIN_RES_HDR_SIZE) > omax)
447
    fatal ("%s: unexpected end of file %ld/%ld", filename,(long) off[0], (long) omax);
448
 
449
  get_windres_bfd_content (wrbfd, &brh, off[0], BIN_RES_HDR_SIZE);
450
  reshdr->data_size = windres_get_32 (wrbfd, brh.data_size, 4);
451
  reshdr->header_size = windres_get_32 (wrbfd, brh.header_size, 4);
452
  off[0] += BIN_RES_HDR_SIZE;
453
}
454
 
455
/* Read data from file, abort on failure */
456
static void
457
read_res_data (windres_bfd *wrbfd, rc_uint_type *off, rc_uint_type omax, void *data,
458
               rc_uint_type size)
459
{
460
  if ((off[0] + size) > omax)
461
    fatal ("%s: unexpected end of file %ld/%ld %ld", filename,(long) off[0],
462
           (long) omax, (long) size);
463
  get_windres_bfd_content (wrbfd, data, off[0], size);
464
  off[0] += size;
465
}
466
 
467
/* Write a resource id */
468
static rc_uint_type
469
write_res_id (windres_bfd *wrbfd, rc_uint_type off, const rc_res_id *id)
470
{
471
  if (id->named)
472
    {
473
      rc_uint_type len = (((bfd_signed_vma) id->u.n.length < 0 ? 0 : id->u.n.length) + 1);
474
      if (wrbfd)
475
        {
476
          rc_uint_type i;
477
          bfd_byte *d = (bfd_byte *) xmalloc (len * sizeof (unichar));
478
          for (i = 0; i < (len - 1); i++)
479
            windres_put_16 (wrbfd, d + (i * sizeof (unichar)), id->u.n.name[i]);
480
          windres_put_16 (wrbfd, d + (i * sizeof (unichar)), 0);
481
          set_windres_bfd_content (wrbfd, d, off, (len * sizeof (unichar)));
482
        }
483
      off += (len * sizeof (unichar));
484
    }
485
  else
486
    {
487
      if (wrbfd)
488
        {
489
          struct bin_res_id bid;
490
          windres_put_16 (wrbfd, bid.sig, 0xffff);
491
          windres_put_16 (wrbfd, bid.id, id->u.id);
492
          set_windres_bfd_content (wrbfd, &bid, off, BIN_RES_ID);
493
        }
494
      off += BIN_RES_ID;
495
    }
496
  return off;
497
}
498
 
499
/* Write resource info */
500
static rc_uint_type
501
write_res_info (windres_bfd *wrbfd, rc_uint_type off, const rc_res_res_info *info)
502
{
503
  if (wrbfd)
504
    {
505
      struct bin_res_info l;
506
 
507
      windres_put_32 (wrbfd, l.version, info->version);
508
      windres_put_16 (wrbfd, l.memflags, info->memflags);
509
      windres_put_16 (wrbfd, l.language, info->language);
510
      windres_put_32 (wrbfd, l.version2, info->version);
511
      windres_put_32 (wrbfd, l.characteristics, info->characteristics);
512
      set_windres_bfd_content (wrbfd, &l, off, BIN_RES_INFO_SIZE);
513
    }
514
  return off + BIN_RES_INFO_SIZE;
515
}
516
 
517
/* read a resource identifier */
518
static void
519
read_res_id (windres_bfd *wrbfd, rc_uint_type *off, rc_uint_type omax, rc_res_id *id)
520
{
521
  struct bin_res_id bid;
522
  unsigned short ord;
523
  unichar *id_s = NULL;
524
  rc_uint_type len;
525
 
526
  read_res_data (wrbfd, off, omax, &bid, BIN_RES_ID - 2);
527
  ord = (unsigned short) windres_get_16 (wrbfd, bid.sig, 2);
528
  if (ord == 0xFFFF)            /* an ordinal id */
529
    {
530
      read_res_data (wrbfd, off, omax, bid.id, BIN_RES_ID - 2);
531
      id->named = 0;
532
      id->u.id = windres_get_16 (wrbfd, bid.id, 2);
533
    }
534
  else
535
    /* named id */
536
    {
537
      off[0] -= 2;
538
      id_s = read_unistring (wrbfd, off, omax, &len);
539
      id->named = 1;
540
      id->u.n.length = len;
541
      id->u.n.name = id_s;
542
    }
543
}
544
 
545
/* Read a null terminated UNICODE string */
546
static unichar *
547
read_unistring (windres_bfd *wrbfd, rc_uint_type *off, rc_uint_type omax,
548
                rc_uint_type *len)
549
{
550
  unichar *s;
551
  bfd_byte d[2];
552
  unichar c;
553
  unichar *p;
554
  rc_uint_type l;
555
  rc_uint_type soff = off[0];
556
 
557
  do
558
    {
559
      read_res_data (wrbfd, &soff, omax, d, sizeof (unichar));
560
      c = windres_get_16 (wrbfd, d, 2);
561
    }
562
  while (c != 0);
563
  l = ((soff - off[0]) / sizeof (unichar));
564
 
565
  /* there are hardly any names longer than 256 characters, but anyway. */
566
  p = s = (unichar *) xmalloc (sizeof (unichar) * l);
567
  do
568
    {
569
      read_res_data (wrbfd, off, omax, d, sizeof (unichar));
570
      c = windres_get_16 (wrbfd, d, 2);
571
      *p++ = c;
572
    }
573
  while (c != 0);
574
  *len = l - 1;
575
  return s;
576
}
577
 
578
static int
579
probe_binary (windres_bfd *wrbfd, rc_uint_type omax)
580
{
581
  rc_uint_type off;
582
  res_hdr reshdr;
583
 
584
  off = 0;
585
  read_res_data_hdr (wrbfd, &off, omax, &reshdr);
586
  if (reshdr.data_size != 0)
587
    return 1;
588
  if ((reshdr.header_size != 0x20 && ! target_is_bigendian)
589
      || (reshdr.header_size != 0x20000000 && target_is_bigendian))
590
    return 1;
591
 
592
  /* Subtract size of HeaderSize. DataSize has to be zero. */
593
  off += 0x20 - BIN_RES_HDR_SIZE;
594
  if ((off + BIN_RES_HDR_SIZE) >= omax)
595
    return 1;
596
  read_res_data_hdr (wrbfd, &off, omax, &reshdr);
597
  /* off is advanced by BIN_RES_HDR_SIZE in read_res_data_hdr()
598
     which is part of reshdr.header_size. We shouldn't take it
599
     into account twice.  */
600
  if ((off - BIN_RES_HDR_SIZE + reshdr.data_size + reshdr.header_size) > omax)
601
    return 0;
602
  return 1;
603
}
604
 
605
/* Check if file is a win32 binary resource file, if so
606
   skip past the null resource. Returns 0 if successful, -1 on
607
   error.
608
 */
609
static void
610
skip_null_resource (windres_bfd *wrbfd, rc_uint_type *off, rc_uint_type omax)
611
{
612
  res_hdr reshdr;
613
  read_res_data_hdr (wrbfd, off, omax, &reshdr);
614
  if (reshdr.data_size != 0)
615
    goto skip_err;
616
  if ((reshdr.header_size != 0x20 && ! target_is_bigendian)
617
    || (reshdr.header_size != 0x20000000 && target_is_bigendian))
618
    goto skip_err;
619
 
620
  /* Subtract size of HeaderSize. DataSize has to be zero. */
621
  off[0] += 0x20 - BIN_RES_HDR_SIZE;
622
  if (off[0] >= omax)
623
    goto skip_err;
624
 
625
  return;
626
 
627
skip_err:
628
  fprintf (stderr, "%s: %s: Not a valid WIN32 resource file\n", program_name,
629
           filename);
630
  xexit (1);
631
}
632
 
633
/* Add a resource to resource directory */
634
static void
635
res_add_resource (rc_res_resource *r, const rc_res_id *type, const rc_res_id *id,
636
                  rc_uint_type language, int dupok)
637
{
638
  rc_res_id a[3];
639
 
640
  a[0] = *type;
641
  a[1] = *id;
642
  a[2].named = 0;
643
  a[2].u.id = language;
644
  res_append_resource (&resources, r, 3, a, dupok);
645
}
646
 
647
/* Append a resource to resource directory.
648
   This is just copied from define_resource
649
   and modified to add an existing resource.
650
 */
651
static void
652
res_append_resource (rc_res_directory **resources, rc_res_resource *resource,
653
                     int cids, const rc_res_id *ids, int dupok)
654
{
655
  rc_res_entry *re = NULL;
656
  int i;
657
 
658
  assert (cids > 0);
659
  for (i = 0; i < cids; i++)
660
    {
661
      rc_res_entry **pp;
662
 
663
      if (*resources == NULL)
664
        {
665
          static unsigned long timeval;
666
 
667
          /* Use the same timestamp for every resource created in a
668
             single run.  */
669
          if (timeval == 0)
670
            timeval = time (NULL);
671
 
672
          *resources = ((rc_res_directory *)
673
                        res_alloc (sizeof (rc_res_directory)));
674
          (*resources)->characteristics = 0;
675
          (*resources)->time = timeval;
676
          (*resources)->major = 0;
677
          (*resources)->minor = 0;
678
          (*resources)->entries = NULL;
679
        }
680
 
681
      for (pp = &(*resources)->entries; *pp != NULL; pp = &(*pp)->next)
682
        if (res_id_cmp ((*pp)->id, ids[i]) == 0)
683
          break;
684
 
685
      if (*pp != NULL)
686
        re = *pp;
687
      else
688
        {
689
          re = (rc_res_entry *) res_alloc (sizeof (rc_res_entry));
690
          re->next = NULL;
691
          re->id = ids[i];
692
          if ((i + 1) < cids)
693
            {
694
              re->subdir = 1;
695
              re->u.dir = NULL;
696
            }
697
          else
698
            {
699
              re->subdir = 0;
700
              re->u.res = NULL;
701
            }
702
 
703
          *pp = re;
704
        }
705
 
706
      if ((i + 1) < cids)
707
        {
708
          if (! re->subdir)
709
            {
710
              fprintf (stderr, "%s: ", program_name);
711
              res_ids_print (stderr, i, ids);
712
              fprintf (stderr, ": expected to be a directory\n");
713
              xexit (1);
714
            }
715
 
716
          resources = &re->u.dir;
717
        }
718
    }
719
 
720
  if (re->subdir)
721
    {
722
      fprintf (stderr, "%s: ", program_name);
723
      res_ids_print (stderr, cids, ids);
724
      fprintf (stderr, ": expected to be a leaf\n");
725
      xexit (1);
726
    }
727
 
728
  if (re->u.res != NULL)
729
    {
730
      if (dupok)
731
        return;
732
 
733
      fprintf (stderr, "%s: warning: ", program_name);
734
      res_ids_print (stderr, cids, ids);
735
      fprintf (stderr, ": duplicate value\n");
736
    }
737
 
738
  re->u.res = resource;
739
}

powered by: WebSVN 2.1.0

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