Subversion Repositories tendra.SVN

Rev

Go to most recent revision | Details | 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
#define calculus_IO_ROUTINES
32
#include "config.h"
33
#include "read.h"
34
#include "calculus.h"
35
#include "common.h"
36
#include "error.h"
37
#include "write.h"
38
 
39
 
40
/*
41
    OUTPUT FILE
42
 
43
    These variables describe the output file.  There is a one byte output
44
    buffer.
45
*/
46
 
47
static FILE *output_file ;
48
static unsigned long output_buff = 0 ;
49
static int output_bits = 0 ;
50
 
51
 
52
/*
53
    WRITE A NUMBER OF BITS
54
 
55
    This routine writes the value v into n bits.
56
*/
57
 
58
static void write_bits
59
    PROTO_N ( ( n, v ) )
60
    PROTO_T ( int n X unsigned long v )
61
{
62
    if ( n > CHAR_BIT ) {
63
	write_bits ( n - CHAR_BIT, ( v >> CHAR_BIT ) ) ;
64
	write_bits ( CHAR_BIT, ( v & ( unsigned ) MASK ( CHAR_BIT ) ) ) ;
65
    } else {
66
	int b = output_bits + n ;
67
	unsigned long m = ( output_buff << n ) | v ;
68
	int c = b - CHAR_BIT ;
69
	if ( c >= 0 ) {
70
	    /* Write next byte */
71
	    int p = ( int ) ( m >> c ) ;
72
	    fputc_v ( p, output_file ) ;
73
	    m &= bitmask [c] ;
74
	    b = c ;
75
	}
76
	output_bits = b ;
77
	output_buff = m ;
78
    }
79
    return ;
80
}
81
 
82
 
83
/*
84
    WRITE AN INTEGER
85
 
86
    This routine writes the integer n to the output file.  This is
87
    encoded as a sequence of octal digits, plus a flag to indicate the
88
    last digit.  The variable d is used to indicate whether this last
89
    digit marker should be output.  The normal method of accessing the
90
    routine is via the macro write_int.
91
*/
92
 
93
static void write_int_aux
94
    PROTO_N ( ( n, d ) )
95
    PROTO_T ( unsigned long n X unsigned long d )
96
{
97
    unsigned long m = ( n >> 3 ) ;
98
    if ( m ) write_int_aux ( m, ( unsigned long ) 0x00 ) ;
99
    write_bits ( 4, ( ( n & 0x07 ) | d ) ) ;
100
    return ;
101
}
102
 
103
#define write_int( N )	write_int_aux ( ( N ), ( unsigned long ) 0x08 )
104
 
105
 
106
/*
107
    WRITE A STRING
108
 
109
    This routine writes the string s to the output file.  This is
110
    encoded as the string length followed by the component characters
111
    (8 bits each).
112
*/
113
 
114
static void write_string
115
    PROTO_N ( ( s ) )
116
    PROTO_T ( char *s )
117
{
118
    unsigned long i, n = ( unsigned long ) strlen ( s ) ;
119
    write_int ( n ) ;
120
    for ( i = 0 ; i < n ; i++ ) {
121
	write_bits ( 8, ( unsigned long ) s [i] ) ;
122
    }
123
    return ;
124
}
125
 
126
 
127
/*
128
    LAST FILE NAME WRITTEN
129
 
130
    This variable is used to store the last file name written.
131
*/
132
 
133
static char *last_filename = NULL ;
134
 
135
 
136
/*
137
    WRITE A FILE NAME
138
 
139
    This routine writes the file name s.  This is just a simple string,
140
    but file names are buffered using last_filename.
141
*/
142
 
143
static void write_filename
144
    PROTO_N ( ( s ) )
145
    PROTO_T ( char *s )
146
{
147
    char *t = last_filename ;
148
    if ( t && streq ( t, s ) ) {
149
	write_bits ( 1, ( unsigned long ) 1 ) ;
150
    } else {
151
	write_bits ( 1, ( unsigned long ) 0 ) ;
152
	write_string ( s ) ;
153
	last_filename = s ;
154
    }
155
    return ;
156
}
157
 
158
 
159
/*
160
    AUTOMATICALLY GENERATED DISK WRITING ROUTINES
161
 
162
    The main disk writing routines are automatically generated.  The
163
    various macros are used to customise these routines.
164
*/
165
 
166
#define WRITE_BITS( A, B )	write_bits ( ( A ), ( unsigned long ) ( B ) )
167
#define WRITE_ALIAS( A )	write_int ( ( unsigned long ) ( A ) )
168
#define WRITE_DIM( A )		write_int ( ( unsigned long ) ( A ) )
169
#define WRITE_int( A )		write_int ( ( unsigned long ) ( A ) )
170
#define WRITE_number( A )	write_int ( ( unsigned long ) ( A ) )
171
#define WRITE_string( A )	write_string ( A )
172
#define WRITE_name_string( A )	write_filename ( A )
173
#define WRITE_zero_int( A )	UNUSED ( A )
174
#define crt_disk_alias		crt_calculus_alias
175
 
176
#include "write_def.h"
177
 
178
 
179
/*
180
    WRITE A FILE
181
 
182
    This routine writes the current algebra to disk into the file nm.
183
*/
184
 
185
void write_file
186
    PROTO_N ( ( nm ) )
187
    PROTO_T ( char *nm )
188
{
189
    /* Open file */
190
    if ( streq ( nm, "." ) ) {
191
	error ( ERROR_SERIOUS, "Output file not specified" ) ;
192
	return ;
193
    }
194
    output_file = fopen ( nm, "wb" ) ;
195
    if ( output_file == NULL ) {
196
	error ( ERROR_SERIOUS, "Can't open output file, '%s'", nm ) ;
197
	return ;
198
    }
199
    init_bitmask () ;
200
    output_buff = 0 ;
201
    output_bits = 0 ;
202
    last_filename = NULL ;
203
 
204
    /* Write the file header */
205
    WRITE_string ( calculus_NAME ) ;
206
    WRITE_string ( calculus_VERSION ) ;
207
 
208
    /* Write the algebra */
209
    WRITE_string ( algebra->name ) ;
210
    WRITE_int ( algebra->major_no ) ;
211
    WRITE_int ( algebra->minor_no ) ;
212
    WRITE_list_ptr_type ( algebra->types ) ;
213
 
214
    /* Close file */
215
    if ( output_bits ) {
216
	/* Tidy up any odd bits */
217
	write_bits ( CHAR_BIT - output_bits, ( unsigned long ) 0 ) ;
218
    }
219
    clear_calculus_alias () ;
220
    fclose_v ( output_file ) ;
221
    return ;
222
}