/*
* Copyright (c) 2002, The Tendra Project <http://www.ten15.org/>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice unmodified, this list of conditions, and the following
* disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
* Crown Copyright (c) 1997
*
* This TenDRA(r) Computer Program is subject to Copyright
* owned by the United Kingdom Secretary of State for Defence
* acting through the Defence Evaluation and Research Agency
* (DERA). It is made available to Recipients with a
* royalty-free licence for its use, reproduction, transfer
* to other parties and amendment for any purpose not excluding
* product development provided that any such use et cetera
* shall be deemed to be acceptance of the following conditions:-
*
* (1) Its Recipients shall ensure that this Notice is
* reproduced upon any copies or amended versions of it;
*
* (2) Any amended version of it shall be clearly marked to
* show both the nature of and the organisation responsible
* for the relevant amendment or amendments;
*
* (3) Its onward transfer from a recipient to another
* party shall be deemed to be that party's acceptance of
* these conditions;
*
* (4) DERA gives no warranty or assurance as to its
* quality or suitability for any purpose and DERA accepts
* no liability whatsoever in relation to any use to which
* it may be put.
*
* $TenDRA: tendra/src/tools/disp/tree.c,v 1.9 2005/11/05 12:03:15 stefanf Exp $
*/
#include "config.h"
#include "fmm.h"
#include "tdf_types.h"
#include "types.h"
#include "ascii.h"
#include "basic.h"
#include "file.h"
#include "pretty.h"
#include "tdf.h"
#include "tree.h"
/*
* INTERNAL MEMORY STORAGE AREA
*
* Some strings are output directly. Others are built up gradually
* in this buffer. length gives the length of the current string.
* page_length gives the size of the buffer.
*/
int length;
static int page_length;
static char *page = null;
/*
* TOP LEVEL WORD AND CURRENT WORD POINTER
*
* The top of the TDF tree is given by word1. The current position in
* the tree is given by word_ptr.
*/
word word1 = { SIMPLE, 0, null, null, null };
word *word_ptr;
/*
* SET UP INITIAL PAGE AND WORDS
*
* The page buffer is initialized and the current word pointer is set
* to the top-level word.
*/
void
initialize_tree(void)
{
if (page == null) {
page = xmalloc_nof (char, 10000);
page_length = 10000;
}
word_ptr = &word1;
length = 0;
return;
}
/*
* START A NEW WORD
*
* A new word of layout type c is created.
*/
word *
new_word(int c)
{
#define BLOCK 100
static word *wblock;
static int block_count = BLOCK;
word *new_ptr;
if (printflag) {
if (block_count == BLOCK) {
/* Allocate space if required */
wblock = xmalloc_nof (word, BLOCK);
block_count = 0;
}
/* set up fields of new word */
new_ptr = wblock + (block_count++);
if (word_ptr->type != SIMPLE && word_ptr->son == null) {
word_ptr->son = new_ptr;
} else {
word_ptr->bro = new_ptr;
}
word_ptr = new_ptr;
word_ptr->type = (char) c;
if (length) {
word_ptr->text = page;
word_ptr->length = length;
page += (length + 1);
page_length -= (length + 1);
if (page_length < 100) {
page = xmalloc_nof (char, 10000);
page_length = 10000;
}
length = 0;
} else {
word_ptr->text = "";
word_ptr->length = 0;
}
word_ptr->son = null;
word_ptr->bro = null;
}
return (word_ptr);
}
/*
* OUTPUT A SINGLE CHARACTER INTO INTERNAL MEMORY
*
* The character c is appended to the internal memory buffer.
*/
void
out_char(int c)
{
if (printflag) {
page [length] = (char) c;
length++;
page [length] = 0;
}
return;
}
/*
* OUTPUT A STRING INTO INTERNAL MEMORY
*
* The string str is appended to the internal memory buffer.
*/
void
out_string(char *str)
{
if (printflag) {
IGNORE strcpy (page + length, str);
length += (int) strlen (str);
}
return;
}
/*
* MAKE A STRING INTO A WORD
*
* This routine creates a simple word from the string str, appending it
* to any text in the internal memory buffer.
*/
void
out(char *str)
{
if (printflag) {
if (length) {
out_string (str);
IGNORE new_word (SIMPLE);
} else {
word *ptr = new_word (SIMPLE);
ptr->text = str;
ptr->length = (int) strlen (str);
}
}
return;
}
/*
* MAKE AN INTEGER INTO A WORD
*
* This routine creates a simple word from an integer.
*/
void
out_int(long n)
{
if (printflag) {
/* Note that the input is cast to an unsigned int */
unsigned long m = (unsigned long) n, dig, power = 1;
/* Get the highest power of 10 dividing m */
while ((m / power) >= 10) power *= 10;
/* Now output digits of m */
while (power != 0) {
dig = (m / power);
m -= dig * power;
power = (power / 10);
out_char (charact (dig));
}
/* Make this into a simple word */
IGNORE new_word (SIMPLE);
}
return;
}
/*
* MAKE A STRING OF OCTAL DIGITS INTO A WORD
*
* This routine creates a simple word from a string of octal digits
* and a sign. If the string of octal digits corresponds to a
* number of at most 32 bits, out_int is used, otherwise the string
* is output directly.
*/
void
out_signed(char *n, int sn)
{
if (printflag) {
/* Calculate the number of binary digits in n */
int a = digit (*n), d;
if (a & 4) {
d = 3 * tdf_int_digits;
} else {
if (a & 2) {
d = 3 * tdf_int_digits - 1;
} else {
d = 3 * tdf_int_digits - 2;
}
}
if (d <= BYTESIZE * (int) sizeof (long)) {
/* If n will fit into a long work out its value */
char *s;
long t = 0;
for (s = n; *s; s++) t = 8 * t + digit (*s);
if (sn && t) out_char ('-');
out_int (t);
} else {
/* Otherwise output n as a string of octal digits */
word *w;
out_string ("octal");
w = new_word (HORIZ_BRACKETS);
out_string (sn ? "-0" : "0");
out (n);
end_word (w);
}
}
return;
}
/*
* MAKE A UNIQUE INTO A WORD
*
* The unique u is output.
*/
void
out_unique(unique u)
{
word *w;
out_string ("unique");
w = new_word (HORIZ_BRACKETS);
while (*u) {
out (*u);
u++;
}
end_word (w);
return;
}
/*
* UTILITY FORMATTING ROUTINE
*
* This routine is used to format a function and its arguments. The
* function name is given by func, the layout type by c, and the
* arguments by the decode string args.
*/
void
format(int c, char *func, char *args)
{
if (printflag) {
word *ptr;
if (length) {
out_string (func);
ptr = new_word (c);
} else {
ptr = new_word (c);
ptr->text = func;
ptr->length = (int) strlen (func);
}
decode (args);
end_word (ptr);
} else {
decode (args);
}
return;
}
syntax highlighted by Code2HTML, v. 0.9.1