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