/* xlpp.c - xlisp pretty printer */
/* Copyright (c) 1989, by David Michael Betz. */
/* You may give out copies of this software; for conditions see the file */
/* COPYING included with this distribution. */
#include "xlisp.h"
/* local variables */
static int pplevel,ppmargin,ppmaxlen;
static LVAL ppfile;
/* forward declarations */
LOCAL VOID pp P1H(LVAL);
LOCAL VOID pplist P1H(LVAL);
LOCAL VOID ppexpr P1H(LVAL);
LOCAL VOID ppputc P1H(int);
LOCAL VOID ppterpri(V);
LOCAL int ppflatsize P1H(LVAL);
/* xpp - pretty-print an expression */
LVAL xpp(V)
{
LVAL expr;
/* get printlevel and depth values */
expr = getvalue(s_printlevel);
if (fixp(expr) && getfixnum(expr) <= MAXPLEV && getfixnum(expr) >= 0) {
plevel = (int)getfixnum(expr);
}
else {
plevel = MAXPLEV;
}
expr = getvalue(s_printlength);
if (fixp(expr) && getfixnum(expr) <= MAXPLEN && getfixnum(expr) >= 0) {
plength = (int)getfixnum(expr);
}
else
plength = MAXPLEN;
/* get expression to print and file pointer */
expr = xlgetarg();
ppfile = (moreargs() ? xlgetfile(TRUE) : getvalue(s_stdout));
xllastarg();
/* pretty print the expression */
pplevel = ppmargin = 0; ppmaxlen = 40;
pp(expr); ppterpri();
/* return nil */
#ifdef MULVALS
xlnumresults = 0; /* no returned results if Multiple values */
xlresults[0] = NIL;
#endif /* MULVALS */
return (NIL);
}
/* pp - pretty print an expression */
LOCAL VOID pp P1C(LVAL, expr)
{
if (consp(expr))
pplist(expr);
else if (darrayp(expr)) {
LVAL value;
ppputc('#');
if (plevel == 0) return;
/* protect a pointer */
xlsave1(value);
value = cvfixnum((FIXTYPE) getdarrayrank(expr));
ppexpr(value);
ppputc('A');
value = array_to_nested_list(expr);
if (null(value)) {
ppputc('(');
ppputc(')');
}
else
pplist(value);
/* restore the stack frame */
xlpop();
}
else
ppexpr(expr);
}
/* pplist - pretty print a list */
LOCAL VOID pplist P1C(LVAL, expr)
{
int n;
/* if the expression will fit on one line, print it on one */
if ((n = ppflatsize(expr)) < ppmaxlen) {
xlprintl(ppfile,expr,TRUE);
pplevel += n;
}
/* otherwise print it on several lines */
else {
int llength = plength;
if (plevel-- == 0) {
ppputc('#');
plevel++;
return;
}
n = ppmargin;
ppputc('(');
if (atom(car(expr))) {
ppexpr(car(expr));
ppputc(' ');
ppmargin = pplevel;
expr = cdr(expr);
}
else
ppmargin = pplevel;
for (; consp(expr); expr = cdr(expr)) {
if (llength-- == 0) {
xlputstr(ppfile,"... )");
pplevel += 5;
ppmargin =n;
plevel++;
return;
}
pp(car(expr));
if (consp(cdr(expr)))
ppterpri();
}
if (expr != NIL) {
ppputc(' '); ppputc('.'); ppputc(' ');
ppexpr(expr);
}
ppputc(')');
ppmargin = n;
plevel++;
}
}
/* ppexpr - print an expression and update the indent level */
LOCAL VOID ppexpr P1C(LVAL, expr)
{
xlprintl(ppfile,expr,TRUE);
pplevel += ppflatsize(expr);
}
/* ppputc - output a character and update the indent level */
LOCAL VOID ppputc P1C(int, ch)
{
xlputc(ppfile,ch);
pplevel++;
}
/* ppterpri - terminate the print line and indent */
LOCAL VOID ppterpri(V)
{
xlterpri(ppfile);
for (pplevel = 0; pplevel < ppmargin; pplevel++)
xlputc(ppfile,' ');
}
/* ppflatsize - compute the flat size of an expression */
LOCAL int ppflatsize P1C(LVAL, expr)
{
LVAL ustream = newustream();
int size;
xlprot1(ustream);
xlprint(ustream,expr,TRUE);
/* calculate size */
for (size = 0, ustream = gethead(ustream);
!null(ustream);
size++, ustream = cdr(ustream)) ;
xlpop();
return (size);
}
syntax highlighted by Code2HTML, v. 0.9.1