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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [binutils/] [resres.c] - Blame information for rev 146

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

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

powered by: WebSVN 2.1.0

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