Subversion Repositories tendra.SVN

Rev

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

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