Subversion Repositories tendra.SVN

Rev

Rev 2 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2 Rev 7
Line -... Line 1...
-
 
1
/*
-
 
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
 */
1
/*
31
/*
2
    		 Crown Copyright (c) 1997
32
    		 Crown Copyright (c) 1997
3
    
33
 
4
    This TenDRA(r) Computer Program is subject to Copyright
34
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
35
    owned by the United Kingdom Secretary of State for Defence
6
    acting through the Defence Evaluation and Research Agency
36
    acting through the Defence Evaluation and Research Agency
7
    (DERA).  It is made available to Recipients with a
37
    (DERA).  It is made available to Recipients with a
8
    royalty-free licence for its use, reproduction, transfer
38
    royalty-free licence for its use, reproduction, transfer
9
    to other parties and amendment for any purpose not excluding
39
    to other parties and amendment for any purpose not excluding
10
    product development provided that any such use et cetera
40
    product development provided that any such use et cetera
11
    shall be deemed to be acceptance of the following conditions:-
41
    shall be deemed to be acceptance of the following conditions:-
12
    
42
 
13
        (1) Its Recipients shall ensure that this Notice is
43
        (1) Its Recipients shall ensure that this Notice is
14
        reproduced upon any copies or amended versions of it;
44
        reproduced upon any copies or amended versions of it;
15
    
45
 
16
        (2) Any amended version of it shall be clearly marked to
46
        (2) Any amended version of it shall be clearly marked to
17
        show both the nature of and the organisation responsible
47
        show both the nature of and the organisation responsible
18
        for the relevant amendment or amendments;
48
        for the relevant amendment or amendments;
19
    
49
 
20
        (3) Its onward transfer from a recipient to another
50
        (3) Its onward transfer from a recipient to another
21
        party shall be deemed to be that party's acceptance of
51
        party shall be deemed to be that party's acceptance of
22
        these conditions;
52
        these conditions;
23
    
53
 
24
        (4) DERA gives no warranty or assurance as to its
54
        (4) DERA gives no warranty or assurance as to its
25
        quality or suitability for any purpose and DERA accepts
55
        quality or suitability for any purpose and DERA accepts
26
        no liability whatsoever in relation to any use to which
56
        no liability whatsoever in relation to any use to which
27
        it may be put.
57
        it may be put.
28
*/
58
*/
Line 30... Line 60...
30
 
60
 
31
#include "config.h"
61
#include "config.h"
32
#include "types.h"
62
#include "types.h"
33
#include "ascii.h"
63
#include "ascii.h"
34
#include "file.h"
64
#include "file.h"
-
 
65
#include "pretty.h"
35
#include "tree.h"
66
#include "tree.h"
36
 
67
 
37
 
68
 
38
/*
69
/*
39
    FORWARD DECLARATIONS
70
    FORWARD DECLARATIONS
40
*/
71
*/
41
 
72
 
42
static void display PROTO_S ( ( int ) ) ;
73
static void display(int);
43
static void expression PROTO_S ( ( word *, int, int, int, int, int ) ) ;
74
static void expression(word *, int, int, int, int, int);
44
 
75
 
45
 
76
 
46
/*
77
/*
47
    FLAGS SET BY EXTERNAL OPTIONS
78
    FLAGS SET BY EXTERNAL OPTIONS
48
 
79
 
49
    Various flags may be given on the command line with affect the form
80
    Various flags may be given on the command line with affect the form
50
    of the output.  These are documented elsewhere.
81
    of the output.  These are documented elsewhere.
51
*/
82
*/
52
 
83
 
53
int helpflag = 1 ;
84
int helpflag = 1;
54
int dflag = 1 ;
85
int dflag = 1;
55
int progress = 0 ;
86
int progress = 0;
56
int quickflag = 0 ;
87
int quickflag = 0;
57
 
88
 
58
 
89
 
59
/*
90
/*
60
    VARIABLES USED IN PRINTING ROUTINE
91
    VARIABLES USED IN PRINTING ROUTINE
61
 
92
 
Line 63... Line 94...
63
    into which the output should be fitted.  maxtab gives the current
94
    into which the output should be fitted.  maxtab gives the current
64
    indentation.  dot_spacing is used to indicate the distance between
95
    indentation.  dot_spacing is used to indicate the distance between
65
    the vertical alignment lines when helpflag is true.
96
    the vertical alignment lines when helpflag is true.
66
*/
97
*/
67
 
98
 
68
int maxcol = 80 ;
99
int maxcol = 80;
69
static int maxtab ;
100
static int maxtab;
70
static int dot_spacing ;
101
static int dot_spacing;
71
 
102
 
72
 
103
 
73
/*
104
/*
74
    CHOICE TABLE
105
    CHOICE TABLE
75
 
106
 
Line 80... Line 111...
80
    indentation b.
111
    indentation b.
81
*/
112
*/
82
 
113
 
83
#define M 100
114
#define M 100
84
 
115
 
85
static int dec [7][3] = {
116
static int dec[7][3] = {
86
    { 4, 2, 8 },
117
    { 4, 2, 8 },
87
    { 2, 1, 3 },
118
    { 2, 1, 3 },
88
    { 8, 6, M },
119
    { 8, 6, M },
89
    { 1, 0, 1 },
120
    { 1, 0, 1 },
90
    { 3, 2, 3 },
121
    { 3, 2, 3 },
91
    { 6, 4, 6 },
122
    { 6, 4, 6 },
92
    { M, 8, M }
123
    { M, 8, M }
93
} ;
124
};
94
 
125
 
95
 
126
 
96
/*
127
/*
97
    PRINT THE TDF TREE
128
    PRINT THE TDF TREE
98
 
129
 
99
    This routine has overall control of the printing of the tree.  It
130
    This routine has overall control of the printing of the tree.  It
100
    determines the most suitable indentation by means of trial runs,
131
    determines the most suitable indentation by means of trial runs,
101
    and then prints the tree with that indentation.
132
    and then prints the tree with that indentation.
102
*/
133
*/
103
 
134
 
104
void pretty_tree
135
void
105
    PROTO_Z ()
136
pretty_tree(void)
106
{
137
{
107
    int i, j ;
138
    int i, j;
108
    int maximum0 ;
139
    int maximum0;
109
 
140
 
110
    initialize_tree () ;
141
    initialize_tree();
111
 
142
 
112
    /* Do some trial runs to try to fit into right number of columns... */
143
    /* Do some trial runs to try to fit into right number of columns... */
113
    printflag = 0 ;
144
    printflag = 0;
114
 
145
 
115
    /* With a maximum identation of 0... */
146
    /* With a maximum identation of 0... */
116
    maxtab = 0 ;
147
    maxtab = 0;
117
    display ( 0 ) ;
148
    display(0);
118
    maximum0 = maximum ;
149
    maximum0 = maximum;
119
 
150
 
120
    /* Try some larger/smaller values */
151
    /* Try some larger/smaller values */
121
    if ( !quickflag && maximum < maxcol ) {
152
    if (!quickflag && maximum < maxcol) {
122
	maxtab = 4 ;
153
	maxtab = 4;
123
	for ( i = 0 ; i < 3 ; i++ ) {
154
	for (i = 0; i < 3; i++) {
124
	    display ( 1 ) ;
155
	    display(1);
125
	    j = -1 ;
156
	    j = -1;
126
	    while ( dec[++j][0] != maxtab ) ;
157
	    while (dec[++j][0]!= maxtab);
127
	    maxtab = dec[j][ maximum < maxcol ? 2 : 1 ] ;
158
	    maxtab = dec[j][maximum < maxcol ? 2 : 1];
128
	}
159
	}
129
    }
160
    }
130
 
161
 
131
    /* Work out dot spacing */
162
    /* Work out dot spacing */
132
    dot_spacing = 8 ;
163
    dot_spacing = 8;
133
    if ( maxtab != 100 ) dot_spacing = 2 * ( maxtab + 1 ) ;
164
    if (maxtab != 100) dot_spacing = 2 *(maxtab + 1);
134
    if ( maxtab == 0 ) {
165
    if (maxtab == 0) {
135
	if ( maximum0 > maxcol ) maxcol = maximum0 ;
166
	if (maximum0 > maxcol)maxcol = maximum0;
136
	dot_spacing = 4 ;
167
	dot_spacing = 4;
137
    }
168
    }
138
    init_spaces ( dot_spacing ) ;
169
    init_spaces(dot_spacing);
139
 
170
 
140
    /* Actually do the printing */
171
    /* Actually do the printing */
141
    printflag = 1 ;
172
    printflag = 1;
142
    display ( 0 ) ;
173
    display(0);
143
    if ( progress ) {
174
    if (progress) {
144
	IGNORE fprintf ( stderr, "Printed in %d columns.\n", maximum ) ;
175
	IGNORE fprintf(stderr, "Printed in %d columns.\n", maximum);
145
    }
176
    }
146
    return ;
177
    return;
147
}
178
}
148
 
179
 
149
 
180
 
150
/*
181
/*
151
    TRY TO PRETTY-PRINT THE TDF TREE
182
    TRY TO PRETTY-PRINT THE TDF TREE
Line 153... Line 184...
153
    This routine actually outputs the tree.  If test is true, then this
184
    This routine actually outputs the tree.  If test is true, then this
154
    is only a trial run, and may be aborted if the output exceeds the
185
    is only a trial run, and may be aborted if the output exceeds the
155
    required number of columns.
186
    required number of columns.
156
*/
187
*/
157
 
188
 
158
static void display
189
static void
159
    PROTO_N ( ( test ) )
-
 
160
    PROTO_T ( int test )
190
display(int test)
161
{
191
{
162
    word *ptr ;
192
    word *ptr;
163
    maximum = 0 ;
193
    maximum = 0;
164
    for ( ptr = word1.bro ; ptr ; ptr = ptr->bro ) {
194
    for (ptr = word1.bro; ptr; ptr = ptr->bro) {
165
	column = 0 ;
195
	column = 0;
166
	expression ( ptr, 0, 0, 0, 1, 0 ) ;
196
	expression(ptr, 0, 0, 0, 1, 0);
167
	if ( test && ( maximum > maxcol ) ) return ;
197
	if (test && (maximum > maxcol)) return;
168
    }
198
    }
169
    return ;
199
    return;
170
}
200
}
171
 
201
 
172
 
202
 
173
/*
203
/*
174
    OUTPUT A CHARACTER
204
    OUTPUT A CHARACTER
175
 
205
 
176
    This routine outputs a single character into the output file.
206
    This routine outputs a single character into the output file.
177
*/
207
*/
178
 
208
 
179
#define put_out( c )						\
209
#define put_out(c)						\
180
    {								\
210
    {								\
181
	if ( c ) {						\
211
	if (c) {						\
182
	    if ( printflag ) IGNORE fputc ( ( c ), pp_file ) ;	\
212
	    if (printflag)IGNORE fputc((c), pp_file); \
183
	    column++ ;						\
213
	    column++; \
184
	    lastc = ( c ) ;					\
214
	    lastc = (c);					\
185
	}							\
215
	}							\
186
    }
216
    }
187
 
217
 
188
 
218
 
189
/*
219
/*
Line 193... Line 223...
193
    It also causes column to be compared against maximum.
223
    It also causes column to be compared against maximum.
194
*/
224
*/
195
 
225
 
196
#define new_line()						\
226
#define new_line()						\
197
    {								\
227
    {								\
198
	if ( column > maximum ) maximum = column ;		\
228
	if (column > maximum)maximum = column; \
199
	if ( printflag ) IGNORE fputc ( NEWLINE, pp_file ) ;	\
229
	if (printflag)IGNORE fputc(NEWLINE, pp_file); \
200
	column = 0 ;						\
230
	column = 0; \
201
	lastc = NEWLINE ;					\
231
	lastc = NEWLINE; \
202
    }
232
    }
203
 
233
 
204
 
234
 
205
/*
235
/*
206
    OUTPUT A TDF EXPRESSION
236
    OUTPUT A TDF EXPRESSION
Line 212... Line 242...
212
    of trailing close brackets which are pending.  first gives a
242
    of trailing close brackets which are pending.  first gives a
213
    character which needs to be output before the current
243
    character which needs to be output before the current
214
    expression, and last gives one which should be output after it.
244
    expression, and last gives one which should be output after it.
215
*/
245
*/
216
 
246
 
217
static void expression
247
static void
218
    PROTO_N ( ( ptr, col, first, last, flag, pending ) )
-
 
219
    PROTO_T ( word *ptr X int col X int first X int last X int flag X int pending )
248
expression(word *ptr, int col, int first, int last, int flag, int pending)
220
{
249
{
221
    word *p ;
250
    word *p;
222
    char bar = '|' ;
251
    char bar = '|';
223
    char open = '(' ;
252
    char open = '(';
224
    char close = ')' ;
253
    char close = ')';
225
    char comma = ',';
254
    char comma = ',';
226
    int more, pends ;
255
    int more, pends;
227
    char sort, opener, sep ;
256
    char sort, opener, sep;
228
    int len, visible, horiz ;
257
    int len, visible, horiz;
229
    int mflag, new_col, temp_col, temp_max ;
258
    int mflag, new_col, temp_col, temp_max;
230
 
259
 
231
    /* print initial spaces */
260
    /* print initial spaces */
232
    if ( column == 0 ) spaces ( col ) ;
261
    if (column == 0)spaces(col);
233
 
262
 
234
    /* output first character */
263
    /* output first character */
235
    put_out ( first ) ;
264
    put_out(first);
236
 
265
 
237
    /* copy out initial text */
266
    /* copy out initial text */
238
    col = column ;
267
    col = column;
239
    len = ( int ) ptr->length ;
268
    len = (int)ptr->length;
240
    sort = ptr->type ;
269
    sort = ptr->type;
241
    if ( printflag ) IGNORE fputs ( ptr->text, pp_file ) ;
270
    if (printflag)IGNORE fputs(ptr->text, pp_file);
242
    column += len ;
271
    column += len;
243
 
272
 
244
    /* if we have parameters, we need to decode them */
273
    /* if we have parameters, we need to decode them */
245
    if ( sort != SIMPLE ) {
274
    if (sort != SIMPLE) {
246
 
275
 
247
	/* are the brackets visible or not? */
276
	/* are the brackets visible or not? */
248
	visible = ( ( sort == HORIZ_NONE || sort == VERT_NONE ) ? 0 : 1 ) ;
277
	visible = ((sort == HORIZ_NONE || sort == VERT_NONE)? 0 : 1);
249
	if ( !visible ) {
278
	if (!visible) {
250
	    open = close = bar = 0 ;
279
	    open = close = bar = 0;
251
	    comma = ' ' ;
280
	    comma = ' ';
252
	}
281
	}
253
 
282
 
254
	/* are we printing horizontally or vertically? */
283
	/* are we printing horizontally or vertically? */
255
	horiz = ( sort == HORIZ_BRACKETS || sort == HORIZ_NONE ) ;
284
	horiz = (sort == HORIZ_BRACKETS || sort == HORIZ_NONE);
256
 
285
 
257
	/* does the maximum tab come into effect? */
286
	/* does the maximum tab come into effect? */
258
	mflag = ( !horiz && ( len > maxtab ) ) ;
287
	mflag = (!horiz && (len > maxtab));
259
	new_col = col + ( mflag ? maxtab : len ) + 1 ;
288
	new_col = col + (mflag ? maxtab : len) + 1;
260
 
289
 
261
	if ( sort == VERT_BRACKETS ) {
290
	if (sort == VERT_BRACKETS) {
262
	    /* try to print things with only one parameter horizontally */
291
	    /* try to print things with only one parameter horizontally */
263
	    p = ptr->son ;
292
	    p = ptr->son;
264
	    if ( p == null ) {
293
	    if (p == null) {
265
		horiz = 1 ;
294
		horiz = 1;
266
	    } else {
295
	    } else {
267
		if ( p->son == null && p->bro == null ) horiz = 1 ;
296
		if (p->son == null && p->bro == null)horiz = 1;
268
	    }
297
	    }
269
	}
298
	}
270
 
299
 
271
	/* have a test run, if printing horizontally */
300
	/* have a test run, if printing horizontally */
272
	if ( horiz && printflag ) {
301
	if (horiz && printflag) {
273
	    horiz = 1 ;
302
	    horiz = 1;
274
	    /* save old values */
303
	    /* save old values */
275
	    temp_col = column ;
304
	    temp_col = column;
276
	    temp_max = maximum ;
305
	    temp_max = maximum;
277
	    printflag = 0 ;
306
	    printflag = 0;
278
	    maximum = column ;
307
	    maximum = column;
279
	    /* open bracket */
308
	    /* open bracket */
280
	    put_out ( open ) ;
309
	    put_out(open);
281
	    sep = comma ;
310
	    sep = comma;
282
	    pends = 0 ;
311
	    pends = 0;
283
	    /* print parameters */
312
	    /* print parameters */
284
	    for ( p = ptr->son ; p ; p = p->bro ) {
313
	    for (p = ptr->son; p; p = p->bro) {
285
		if ( p->bro == null ) {
314
		if (p->bro == null) {
286
		    /* for last, take trailing brackets into account */
315
		    /* for last, take trailing brackets into account */
287
		    sep = close ;
316
		    sep = close;
288
		    pends = pending + visible ;
317
		    pends = pending + visible;
289
		}
318
		}
290
		/* print this parameter */
319
		/* print this parameter */
291
		expression ( p, column, 0, sep, 0, pends ) ;
320
		expression(p, column, 0, sep, 0, pends);
292
	    }
321
	    }
293
	    /* close bracket */
322
	    /* close bracket */
294
	    put_out ( last ) ;
323
	    put_out(last);
295
	    /* if this doesn't fit in, try vertically */
324
	    /* if this doesn't fit in, try vertically */
296
	    if ( maximum >= maxcol || column + pending >= maxcol ) {
325
	    if (maximum >= maxcol || column + pending >= maxcol) {
297
		horiz = 0 ;
326
		horiz = 0;
298
		mflag = ( len > maxtab ) ;
327
		mflag = (len > maxtab);
299
		new_col = col + ( mflag ? maxtab : len ) + 1 ;
328
		new_col = col + (mflag ? maxtab : len) + 1;
300
	    }
329
	    }
301
	    /* restore old values */
330
	    /* restore old values */
302
	    column = temp_col ;
331
	    column = temp_col;
303
	    maximum = temp_max ;
332
	    maximum = temp_max;
304
	    printflag = 1 ;
333
	    printflag = 1;
305
	}
334
	}
306
 
335
 
307
	if ( horiz && printflag ) {
336
	if (horiz && printflag) {
308
	    /* do horizontal printing of parameters */
337
	    /* do horizontal printing of parameters */
309
	    /* open bracket */
338
	    /* open bracket */
310
	    put_out ( open ) ;
339
	    put_out(open);
311
	    sep = comma ;
340
	    sep = comma;
312
	    pends = 0 ;
341
	    pends = 0;
313
	    /* print parameters */
342
	    /* print parameters */
314
	    for ( p = ptr->son ; p ; p = p->bro ) {
343
	    for (p = ptr->son; p; p = p->bro) {
315
		/* for last, take trailing brackets into account */
344
		/* for last, take trailing brackets into account */
316
		if ( p->bro == null ) {
345
		if (p->bro == null) {
317
		    sep = close ;
346
		    sep = close;
318
		    pends = pending + visible ;
347
		    pends = pending + visible;
319
		}
348
		}
320
		/* print this parameter */
349
		/* print this parameter */
321
		expression ( p, column, 0, sep, 0, pends ) ;
350
		expression(p, column, 0, sep, 0, pends);
322
	    }
351
	    }
323
	} else {
352
	} else {
324
	    /* do vertical printing of parameters */
353
	    /* do vertical printing of parameters */
325
	    put_out ( open ) ;
354
	    put_out(open);
326
	    opener = bar ;
355
	    opener = bar;
327
	    if ( mflag ) {
356
	    if (mflag) {
328
		new_line () ;
357
		new_line();
329
		spaces ( new_col - 1 ) ;
358
		spaces(new_col - 1);
330
	    }
359
	    }
331
	    sep = comma ;
360
	    sep = comma;
332
	    more = 1 ;
361
	    more = 1;
333
	    pends = 0 ;
362
	    pends = 0;
334
	    new_col = column ;
363
	    new_col = column;
335
	    if ( !mflag ) {
364
	    if (!mflag) {
336
		new_col-- ;
365
		new_col--;
337
		opener = 0 ;
366
		opener = 0;
338
	    }
367
	    }
339
	    /* print parameters */
368
	    /* print parameters */
340
	    for ( p = ptr->son ; p ; p = p->bro ) {
369
	    for (p = ptr->son; p; p = p->bro) {
341
		if ( p->bro == null ) {
370
		if (p->bro == null) {
342
		    /* last requires special treatment */
371
		    /* last requires special treatment */
343
		    sep = 0 ;
372
		    sep = 0;
344
		    more = 0 ;
373
		    more = 0;
345
		    pends = pending + visible ;
374
		    pends = pending + visible;
346
		}
375
		}
347
		/* print this parameter */
376
		/* print this parameter */
348
		expression ( p, new_col, opener, sep, more, pends ) ;
377
		expression(p, new_col, opener, sep, more, pends);
349
		opener = bar ;
378
		opener = bar;
350
	    }
379
	    }
351
	    if ( visible ) put_out ( close ) ;
380
	    if (visible)put_out(close);
352
	}
381
	}
353
    }
382
    }
354
 
383
 
355
    /* output last character */
384
    /* output last character */
356
    if ( last != ',' || ( lastc != '.' && lastc != ':' ) ) put_out ( last ) ;
385
    if (last != ',' || (lastc != '.' && lastc != ':'))put_out(last);
357
 
386
 
358
    /* and a newline if required */
387
    /* and a newline if required */
359
    if ( flag ) new_line () ;
388
    if (flag)new_line();
360
    return ;
389
    return;
361
}
390
}