Subversion Repositories tendra.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
2
    		 Crown Copyright (c) 1997
3
 
4
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
6
    acting through the Defence Evaluation and Research Agency
7
    (DERA).  It is made available to Recipients with a
8
    royalty-free licence for its use, reproduction, transfer
9
    to other parties and amendment for any purpose not excluding
10
    product development provided that any such use et cetera
11
    shall be deemed to be acceptance of the following conditions:-
12
 
13
        (1) Its Recipients shall ensure that this Notice is
14
        reproduced upon any copies or amended versions of it;
15
 
16
        (2) Any amended version of it shall be clearly marked to
17
        show both the nature of and the organisation responsible
18
        for the relevant amendment or amendments;
19
 
20
        (3) Its onward transfer from a recipient to another
21
        party shall be deemed to be that party's acceptance of
22
        these conditions;
23
 
24
        (4) DERA gives no warranty or assurance as to its
25
        quality or suitability for any purpose and DERA accepts
26
        no liability whatsoever in relation to any use to which
27
        it may be put.
28
*/
29
 
30
 
31
/**********************************************************************
32
$Author: pwe $
33
$Date: 1998/03/11 11:03:50 $
34
$Revision: 1.3 $
35
$Log: basicread.c,v $
36
 * Revision 1.3  1998/03/11  11:03:50  pwe
37
 * DWARF optimisation info
38
 *
39
 * Revision 1.2  1998/02/04  10:43:39  release
40
 * Changes during testing.
41
 *
42
 * Revision 1.1.1.1  1998/01/17  15:55:45  release
43
 * First version to be checked into rolling release.
44
 *
45
 * Revision 1.3  1996/06/18  09:21:14  currie
46
 * C torture long nats
47
 *
48
Revision 1.2  1995/07/06 09:14:29  currie
49
MAGIC NO
50
 
51
 * Revision 1.1  1995/04/06  10:43:34  currie
52
 * Initial revision
53
 *
54
***********************************************************************/
55
 
56
#include "config.h"
57
#include "common_types.h"
58
#include "xalloc.h"
59
#include "flags.h"
60
#include "messages_r.h"
61
#include "natmacs.h"
62
#include "readglob.h"
63
#include "flpt.h"
64
#include "f64.h"
65
#include "installglob.h"
66
 
67
#include "basicread.h"
68
 
69
/* MACROS */
70
 
71
#define bpby 8
72
 /* bits per byte */
73
 
74
#define cppkt 256
75
 /* bytes per packet */
76
 
77
#define bppkt (bpby*cppkt)
78
 /* the number of bits per packet (from the file). */
79
 
80
 
81
/* VARIABLES */
82
/* All variables are initialised, jmf */
83
 
84
static char * crt_ptr;	/* initialised by init_reader */
85
static char * end_ptr;	/* initialised by init_reader */
86
 
87
static int getcode_bitposn;
88
static union pun_u
89
  {unsigned int intc;
90
    struct pun_s {char a; char b; char c; char d;} chars;
91
  } crt_bits;		/* set before use */
92
 
93
 
94
 
95
static char *crt_dot_t;	/* initialised by init_reader */
96
int  crt_lno;		/* initialised to -1 by init_reader */
97
int crt_charno;		/* only used if crt_lno != -1. No init needed */
98
char * crt_flnm;	/* only used if crt_lno != -1. No init needed */
99
static int  failer_count;	/* initialised by init_reader */
100
				/* number of failures so far. To allow for
101
				   limiting error messages */
102
static int   pkt_index;	/* initialised by init_reader */
103
				/* the index of the current packet in the
104
				   file */
105
static int table_flag;	/* initialised by init_reader */
106
				/* 1 if reading from memory, 0 if reading
107
				   from file buffer */
108
static char *crt_line;	/* set before use */
109
				/* current line of encoding */
110
static int   file_pkt;	/* initialised by init_reader */
111
				/* holds the index of the packet in the
112
				   file */
113
static FILE * fpin;	/* initialised by init_reader */
114
				/* file pointer for input */
115
static int  buff[64];	/* set by read_line */
116
				/* file buffer for input */
117
static place current_place;	/* set before use */
118
static place bytestream_pickup;	/* set before use */
119
				/* records the end of a bytestream */
120
 
121
 
122
 
123
 
124
/* IDENTITIES */
125
 
126
static unsigned int  mask[33] = {
127
  0, 1, 3, 7, 15, 31, 63, 127, 255,
128
  0x1ff, 0x3ff, 0x7ff, 0xfff, 0x1fff, 0x3fff, 0x7fff, 0xffff,
129
  0x1ffff, 0x3ffff, 0x7ffff, 0xfffff, 0x1fffff, 0x3fffff, 0x7fffff, 0xffffff,
130
  0x1ffffff, 0x3ffffff, 0x7ffffff, 0xfffffff, 0x1fffffff, 0x3fffffff,
131
    0x7fffffff, 0xffffffff
132
};
133
 /* used to mask bits out of characters */
134
 
135
 
136
 
137
/**********************************************************************
138
   failer prints an error message on the standard output, and sets
139
   good_trans to 1 to indicate an error.
140
 **********************************************************************/
141
 
142
/* fails, giving error message s */
143
void failer
144
    PROTO_N ( (s) )
145
    PROTO_T ( char *s )
146
{
147
 
148
  good_trans = 1;
149
  if (crt_lno != -1)
150
    IGNORE fprintf (stderr, "trans:%s: internal error: after line %d: char %d: %s\n", crt_flnm, crt_lno, crt_charno, s);
151
  else
152
    IGNORE fprintf (stderr, "trans:%s: internal error: %s\n", crt_dot_t, s);
153
  ++failer_count;
154
  if (failer_count >= 15)	/* errors limited to 15 */
155
    exit(EXIT_FAILURE);
156
  return;
157
}
158
 
159
 
160
 
161
/**************************************************************
162
  read_line reads the next line from the file and
163
  updates pkt_index, file_pkt and crt_line.
164
 **************************************************************/
165
 
166
static void read_line
167
    PROTO_N ( (complain) )
168
    PROTO_T ( int complain )
169
{
170
 
171
  size_t   test = fread ((char *)buff, sizeof (char), cppkt, fpin);
172
 
173
  if (test == (size_t)0 && complain) {
174
    failer (READ_PAST_END);
175
    exit(EXIT_FAILURE);
176
  };
177
  pkt_index++;
178
  file_pkt++;
179
  crt_line = (char *)buff;
180
}
181
 
182
/***************************************************************
183
  initreader opens the file called n and sets initial values
184
  into variables.
185
 ***************************************************************/
186
void check_magic_no PROTO_S ( ( void ) ) ;
187
 
188
bool initreader
189
    PROTO_N ( (n) )
190
    PROTO_T ( char *n )
191
{
192
  crt_dot_t = n;
193
  crt_lno = -1;
194
  failer_count = 0;
195
 
196
  fpin = fopen (n, "rb");
197
  if (fpin == (FILE *) 0) {
198
    failer (CANT_OPEN_FILE);
199
    return (0);
200
  };
201
 
202
  pkt_index = -1;
203
  file_pkt = -1;
204
  table_flag = 0;
205
  getcode_bitposn = 0;
206
  read_line (1);
207
 
208
  crt_line = (char *)buff;
209
  crt_ptr = crt_line;
210
  end_ptr = crt_line + cppkt;
211
  check_magic_no();
212
  return (1);
213
}
214
 
215
void endreader
216
    PROTO_Z ()
217
{
218
  int   st = fclose (fpin);
219
  if (st == EOF) {
220
    failer ("failed to close file");
221
    exit(EXIT_FAILURE);
222
  };
223
}
224
 
225
int  getcode
226
    PROTO_N ( (np) )
227
    PROTO_T ( int np )
228
{
229
  /* np = no of bits to read, np is >= 1 */
230
  {
231
    unsigned int m;
232
    int p;
233
    {
234
      int n = np;
235
      p = getcode_bitposn - n;
236
      m = mask[n];
237
    };
238
    if (p >= 0) {
239
      getcode_bitposn = p;
240
      return (int)((crt_bits.intc >> p) & m);
241
    };
242
  };
243
 
244
  {
245
    int p = getcode_bitposn;
246
    int q;
247
    unsigned int m;
248
    {
249
      int n = np - p;
250
      m = mask[n];
251
      q = (int)((crt_bits.intc & mask[p]) << n);
252
      p = 32 - n;
253
    };
254
 
255
    if (crt_ptr == end_ptr) {
256
      read_line (1);
257
      crt_ptr = crt_line;
258
    };
259
 
260
#ifndef FS_LITTLE_ENDIAN
261
!!!!!!!!!!!!!  /* define FS_LITTLE_ENDIAN in config.h */
262
#else
263
#if FS_LITTLE_ENDIAN
264
    crt_bits.chars.d = crt_ptr[0];
265
    crt_bits.chars.c = crt_ptr[1];
266
    crt_bits.chars.b = crt_ptr[2];
267
    crt_bits.chars.a = crt_ptr[3];
268
#else
269
    crt_bits.intc = ((unsigned int*)crt_ptr)[0];
270
#endif
271
#endif
272
    crt_ptr += 4;
273
    getcode_bitposn = p;
274
    return q + (int)((crt_bits.intc >> p) & m);
275
  }
276
}
277
 
278
int get_big_code
279
    PROTO_N ( (n) )
280
    PROTO_T ( int n )
281
{
282
  int t;
283
  int res = 0;
284
 
285
  while (1)
286
   {
287
     t = getcode(n);
288
     if (t == 0)
289
       res += (int)(mask[n]);
290
     else
291
       return (res + t);
292
   };
293
}
294
 
295
/********************************************************************
296
   keep_place records the present state of the getcode variables
297
   in a place. It condenses the position variables into the
298
   bits_on field, measured from the start of the recorded line.
299
 ********************************************************************/
300
 
301
place keep_place
302
    PROTO_Z ()
303
{
304
  place new_pl;
305
  new_pl.flag = table_flag;
306
  if (table_flag)
307
    new_pl.pl_mem = crt_line;
308
  new_pl.bits_on = (int)(crt_ptr - crt_line) * 8 - getcode_bitposn;
309
  if (!table_flag)
310
    new_pl.bits_on += pkt_index * bppkt;
311
  return (new_pl);
312
}
313
 
314
/********************************************************************
315
  set_place resets the getcode variables from the place pl, which
316
  was produced by keep_place or add_place. If necessary it reads more
317
  lines from the file.
318
 ********************************************************************/
319
 
320
 
321
void set_place
322
    PROTO_N ( (pl) )
323
    PROTO_T ( place pl )
324
{
325
  int  new_pi;
326
  table_flag = pl.flag;
327
  if (!table_flag) {
328
    new_pi = pl.bits_on / bppkt;
329
    crt_line = (char *)buff;
330
    crt_ptr = crt_line + (pl.bits_on / 32) * 4 - new_pi * cppkt;
331
    getcode_bitposn = 32 - pl.bits_on % 32;
332
    pkt_index = file_pkt;
333
    while (pkt_index < new_pi)
334
      read_line (0);
335
  }
336
  else {
337
    crt_line = pl.pl_mem;
338
    crt_ptr = crt_line + (pl.bits_on/32)*4;
339
    getcode_bitposn = 32 - pl.bits_on % 32;
340
    current_place = pl;
341
  };
342
  if (getcode_bitposn == 32)
343
    getcode_bitposn = 0;
344
 
345
  if (getcode_bitposn > 0) {
346
#if FS_LITTLE_ENDIAN
347
    crt_bits.chars.d = crt_ptr[0];
348
    crt_bits.chars.c = crt_ptr[1];
349
    crt_bits.chars.b = crt_ptr[2];
350
    crt_bits.chars.a = crt_ptr[3];
351
#else
352
    crt_bits.intc = ((unsigned int*)crt_ptr)[0];
353
#endif
354
    crt_ptr += 4;
355
  };
356
  return;
357
}
358
 
359
/********************************************************************
360
   add_place produces a place n bits on from the place pl.
361
 ********************************************************************/
362
 
363
 
364
place add_place
365
    PROTO_N ( (pl, n) )
366
    PROTO_T ( place pl X int n )
367
{
368
  place new_pl;
369
  new_pl.bits_on = pl.bits_on + n;
370
  new_pl.pl_mem = pl.pl_mem;
371
  new_pl.flag = pl.flag;
372
  return (new_pl);
373
}
374
 
375
/**********************************************************************
376
   new_place memorises a line starting from the current position
377
   and going on for bn bits. This may cause more lines to be read
378
   from the file.
379
 **********************************************************************/
380
void add_capsule_frees
381
    PROTO_N ( (vp) )
382
    PROTO_T ( void * vp )
383
{
384
  capsule_frees * cf;
385
  cf = (capsule_frees*)xmalloc(sizeof(capsule_frees));
386
  cf->next = capsule_freelist;
387
  cf->ptr = vp;
388
  capsule_freelist = cf;
389
  return;
390
}
391
 
392
 
393
place new_place
394
    PROTO_N ( (bn) )
395
    PROTO_T ( int bn )
396
{
397
  place pl;
398
  int   no_chars,
399
        i;
400
  char *mem;
401
  char  c;
402
  pl.flag = 1;
403
 
404
  if (!table_flag)  {
405
    pl.bits_on = 32 - getcode_bitposn;
406
    if (getcode_bitposn == 0)
407
      pl.bits_on = 0;
408
    no_chars = ((pl.bits_on + bn + 31) / 32) * 4;
409
    if (getcode_bitposn > 0) {
410
      crt_ptr -= 4;
411
    };
412
    mem = (char *) xcalloc (no_chars, sizeof (char));
413
    for (i = 0; i < no_chars; ++i) {
414
      if (crt_ptr == end_ptr) {
415
        read_line (1);
416
        crt_ptr = crt_line;
417
      };
418
      c = *crt_ptr++;
419
      mem[i] = c;
420
    };
421
    pl.pl_mem = mem;
422
    add_capsule_frees((void*)mem);
423
    return (pl);
424
  };
425
 
426
  pl.bits_on = (int)(crt_ptr - crt_line) * 8 - getcode_bitposn;
427
  pl.pl_mem = current_place.pl_mem;
428
  return pl;
429
}
430
 
431
/*********************************************************************
432
  small_dtdfint reads one TDF integer using getcode. TDF integers are
433
  encoded as a number of octal digits, most significant first.
434
  These octal digits are encoded in 4-bit chunks with 8 added on
435
  to the last digit only.
436
 *********************************************************************/
437
 
438
int small_dtdfint
439
    PROTO_Z ()
440
{
441
  int  digit;
442
  int total = 0;
443
  while (digit = getcode (4), digit < 8)
444
    total = 8 * total + digit;
445
  return (8 * total + (digit - 8));
446
}
447
 
448
 /* step the input stream on to the next byte boundary */
449
 
450
void to_boundary
451
    PROTO_Z ()
452
{
453
  getcode_bitposn = getcode_bitposn - getcode_bitposn % 8;
454
  return;
455
}
456
 
457
 
458
 /* delivers a new place for the bitstream in the input stream and steps
459
    over it */
460
 
461
bitstream d_bitstream
462
    PROTO_Z ()
463
{
464
  bitstream crt_bitstream;
465
  place here;
466
  int  length;
467
  length = small_dtdfint ();
468
  here = keep_place ();
469
  crt_bitstream = new_place (length);
470
  set_place (add_place (here, length));
471
  return crt_bitstream;
472
}
473
 
474
 
475
 
476
 
477
bytestream d_bytestream
478
    PROTO_Z ()
479
{
480
  return bytestream_pickup;
481
}
482
 
483
void ignore_bytestream
484
    PROTO_Z ()
485
{
486
  /* steps over a bytestream */
487
  int  length;
488
  place here;
489
  length = small_dtdfint ();
490
  to_boundary ();
491
  here = keep_place ();
492
  set_place (add_place (here, (length * 8)));
493
  return;
494
}
495
 
496
 /* records in bytestream_pickup the end of a bytestream */
497
 
498
void start_bytestream
499
    PROTO_Z ()
500
{
501
  int  length;
502
  place here;
503
  length = small_dtdfint ();
504
  to_boundary ();
505
  here = keep_place ();
506
  bytestream_pickup = add_place (here, (length * 8));
507
  return;
508
}
509
 
510
 
511
 /* resets the input stream from bytestream_pickup */
512
 
513
void end_bytestream
514
    PROTO_Z ()
515
{
516
  set_place (bytestream_pickup);
517
  return;
518
}
519
 
520
tdfstring d_tdfstring
521
    PROTO_Z ()
522
{
523
  /* reads a tdfstring from the input stream */
524
  int  bits = small_dtdfint ();
525
  int  n = small_dtdfint ();
526
  tdfstring tdb;
527
  int  i;
528
  tdb.number = n;
529
  if (bits <= 8) {
530
    tdb.ints.chars = (char *) xcalloc (n + 1, sizeof (char));
531
    for (i = 0; i < n; ++i)
532
      tdb.ints.chars[i] = (char)getcode (bits);
533
    tdb.ints.chars[n] = 0;
534
    tdb.size = 8;
535
    return tdb;
536
  };
537
  if (bits <= 16) {
538
    tdb.ints.shorts = (short *) xcalloc (n + 1, sizeof (short));
539
    for (i = 0; i < n; ++i)
540
      tdb.ints.shorts[i] = (short)getcode (bits);
541
    tdb.ints.shorts[n] = 0;
542
    tdb.size = 16;
543
    return tdb;
544
  };
545
  if (bits <= 32) {
546
    tdb.ints.longs = (int *) xcalloc (n + 1, sizeof (int));
547
    for (i = 0; i < n; ++i)
548
      tdb.ints.longs[i] = getcode (bits);
549
    tdb.ints.longs[n] = 0;
550
    tdb.size = 32;
551
    return tdb;
552
  };
553
  if (bits <= 64) {
554
    tdb.ints.longs = (int *) xcalloc (n + 1, sizeof (int));
555
    for (i = 0; i < n; ++i) {
556
      flt64 x;
557
      flpt f;
558
      x.big = getcode(bits - 32);
559
      x.small = (unsigned int)getcode(32);
560
      f = f64_to_flt(x, 0);
561
      tdb.ints.longs[i] = f;
562
    };
563
    tdb.ints.longs[n] = 0;
564
    tdb.size = 64;
565
    return tdb;
566
  };
567
  failer(NO_BIG_STRINGS);
568
  return tdb;
569
}
570
 
571
tdfstring d_tdfident
572
    PROTO_Z ()
573
{
574
  /* reads a tdfident from the input stream */
575
  int  bits = small_dtdfint ();
576
  int  n = small_dtdfint ();
577
  tdfstring tdb;
578
  int  i;
579
  tdb.size = bits;
580
  tdb.number = n;
581
  if (bits <= 8) {
582
    tdb.ints.chars = (char *) xcalloc (n + 1, sizeof (char));
583
    to_boundary ();
584
    for (i = 0; i < n; ++i)
585
      tdb.ints.chars[i] = (char)getcode (bits);
586
    tdb.ints.chars[n] = 0;
587
    to_boundary ();
588
    return tdb;
589
  };
590
  if (bits <= 16) {
591
    tdb.ints.shorts = (short *) xcalloc (n + 1, sizeof (short));
592
    to_boundary ();
593
    for (i = 0; i < n; ++i)
594
      tdb.ints.shorts[i] = (short)getcode (bits);
595
    tdb.ints.shorts[n] = 0;
596
    to_boundary ();
597
    return tdb;
598
  };
599
  tdb.ints.longs = (int *) xcalloc (n + 1, sizeof (int));
600
  to_boundary ();
601
  for (i = 0; i < n; ++i)
602
    tdb.ints.longs[i] = getcode (bits);
603
  tdb.ints.longs[n] = 0;
604
  to_boundary ();
605
  return tdb;
606
}
607
 
608
tdfbool d_tdfbool
609
    PROTO_Z ()
610
{
611
  /* reads a tdfbool from the input stream */
612
  return (tdfbool)getcode (1);
613
}
614
 
615
 
616
 
617
tdfint d_tdfint
618
    PROTO_Z ()
619
{
620
  /* reads a tdfint from the input stream */
621
  nat n;
622
  unsigned int  digit;
623
  unsigned int total = 0;
624
  int  small = 1;
625
  int goon = 1;
626
  flpt f;
627
 
628
  while (goon)
629
   {
630
     digit = (unsigned int)getcode(4);
631
     if (digit >= 8)
632
       { goon = 0;
633
         digit -= 8;
634
       };
635
     if (small)
636
       { if (total > 0x1fffffff)
637
           { small = 0;
638
	     f = floatrep_unsigned(total);
639
             flpt_newdig(digit, &flptnos[f], 8);
640
           }
641
         else
642
           total = (total << 3) + digit;
643
       }
644
     else {
645
       SET(f);
646
       flpt_newdig(digit, &flptnos[f], 8);
647
     };
648
   };
649
  nat_issmall(n) = (bool)small;
650
  if (small)
651
    natint(n) = (int)total;
652
  else
653
   {
654
     SET(f);
655
     nat_issmall(n) = 0;
656
     natbig(n) = f;
657
   };
658
  return n;
659
}
660
 
661
void check_magic_no
662
    PROTO_Z ()
663
{
664
	tdfint maj;
665
	tdfint min;
666
 
667
	if (getcode(8) != 'T' || getcode(8) != 'D' || getcode(8) != 'F' ||
668
		getcode(8) != 'C') {
669
		failer("This is not a TDF Version >= 4 capsule");
670
		exit(EXIT_FAILURE);
671
	}
672
	maj = d_tdfint();
673
	if (natint(maj) > MAJOR_VERSION) {
674
		failer("TDF version of capsule is later than version dealt with by translator - update the translator");
675
		exit(EXIT_FAILURE);
676
	}
677
	else
678
	if (natint(maj) < MAJOR_VERSION) {
679
		failer("TDF version dealt with by translator is later than version of capsule - recompile capsule with later compiler");
680
		exit(EXIT_FAILURE);
681
	}
682
	min = d_tdfint();
683
	if (natint(min) > MINOR_VERSION) {
684
	    IGNORE fprintf(stderr, "Warning: capsule may contain constructions not dealt with in this minor version of the translator\n");
685
	}
686
	to_boundary();
687
}