gcl-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gcl-devel] Re: format: comma-interval bug fix


From: Camm Maguire
Subject: [Gcl-devel] Re: format: comma-interval bug fix
Date: 09 Aug 2005 01:19:32 -0400
User-agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.2

Greetings again!  Likewise in cvs head past t4.  Thanks so much!

Robert Boyer <address@hidden> writes:

> Below is a slightly revised version of o/format.c that fixes an ANSI
> compliance bug, namely that ~B, ~D, ~X, ~O, and ~R now all take a 5th
> parameter, comma-interval.
> 
> Bob
> 
> -------------------------------------------------------------------------------
> 
> 
> /*
>  Copyright (C) 1994 M. Hagiya, W. Schelter, T. Yuasa
> 
> This file is part of GNU Common Lisp, herein referred to as GCL
> 
> GCL is free software; you can redistribute it and/or modify it under
> the terms of the GNU LIBRARY GENERAL PUBLIC LICENSE as published by
> the Free Software Foundation; either version 2, or (at your option)
> any later version.
> 
> GCL is distributed in the hope that it will be useful, but WITHOUT
> ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public 
> License for more details.
> 
> You should have received a copy of the GNU Library General Public License 
> along with GCL; see the file COPYING.  If not, write to the Free Software
> Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
> 
> */
> 
> /*
>       format.c
> */
> 
> #include "include.h"
> 
> static int
> fmt_thousand(int,int,bool,bool,int);
> 
> static void
> fmt_exponent1(int);
> 
> static void
> fmt_write_numeral(int,int);
> 
> static void
> fmt_write_ordinal(int,int);
> 
> static int
> fmt_nonillion(int,int,bool,bool,int);
> 
> static void
> fmt_roman(int,int,int,int,int);
> 
> static void
> fmt_integer(object,bool,bool,int,int,int,int,int);
> 
> static void
> fmt_semicolon(bool,bool);
> 
> static void
> fmt_up_and_out(bool,bool);
> 
> static void
> fmt_justification(volatile bool,bool);
> 
> static void
> fmt_iteration(bool,bool);
> 
> static void
> fmt_conditional(bool,bool);
> 
> static void
> fmt_case(bool,bool);
> 
> static void
> fmt_indirection(bool,bool);
> 
> static void
> fmt_asterisk(bool,bool);
> 
> static void
> fmt_tabulate(bool,bool);
> 
> static void
> fmt_newline(bool,bool);
> 
> static void
> fmt_tilde(bool,bool);
> 
> static void
> fmt_bar(bool,bool);
> 
> static void
> fmt_ampersand(bool,bool);
> 
> static void
> fmt_percent(bool,bool);
> 
> static void
> fmt_dollars_float(bool,bool);
> 
> static void
> fmt_general_float(bool,bool);
> 
> static void
> fmt_exponential_float(bool,bool);
> 
> static void
> fmt_fix_float(bool,bool);
> 
> static void
> fmt_character(bool,bool);
> 
> static void
> fmt_plural(bool,bool);
> 
> static void
> fmt_radix(bool,bool);
> 
> static void
> fmt_hexadecimal(bool,bool);
> 
> static void
> fmt_octal(bool,bool);
> 
> static void
> fmt_binary(bool,bool);
> 
> static void
> fmt_error(char *);
> 
> static void
> fmt_ascii(bool, bool);
> 
> static void
> fmt_S_expression(bool, bool);
> 
> static void
> fmt_decimal(bool, bool);
> 
> 
> object sSAindent_formatted_outputA;
> 
> #define       ctl_string      (fmt_string->st.st_self + ctl_origin)
> 
> #define       fmt_old         VOL object old_fmt_stream; \
>                       VOL int old_ctl_origin; \
>                       VOL int old_ctl_index; \
>                       VOL int old_ctl_end; \
>                       object * VOL old_fmt_base; \
>                       VOL int old_fmt_index; \
>                       VOL int old_fmt_end; \
>                       jmp_bufp   VOL old_fmt_jmp_bufp; \
>                       VOL int old_fmt_indents; \
>                       VOL object old_fmt_string ; \
>                         VOL format_parameter *old_fmt_paramp
> #define       fmt_save        old_fmt_stream = fmt_stream; \
>                       old_ctl_origin = ctl_origin; \
>                       old_ctl_index = ctl_index; \
>                       old_ctl_end = ctl_end; \
>                       old_fmt_base = fmt_base; \
>                       old_fmt_index = fmt_index; \
>                       old_fmt_end = fmt_end; \
>                       old_fmt_jmp_bufp = fmt_jmp_bufp; \
>                       old_fmt_indents = fmt_indents; \
>                       old_fmt_string = fmt_string ; \
>                         old_fmt_paramp = fmt_paramp
> #define       fmt_restore     fmt_stream = old_fmt_stream; \
>                       ctl_origin = old_ctl_origin; \
>                       ctl_index = old_ctl_index; \
>                       ctl_end = old_ctl_end; \
>                       fmt_base = old_fmt_base; \
>                       fmt_index = old_fmt_index; \
>                       fmt_end = old_fmt_end; \
>                       fmt_jmp_bufp = old_fmt_jmp_bufp; \
>                       fmt_indents = old_fmt_indents; \
>                       fmt_string = old_fmt_string ; \
>                         fmt_paramp = old_fmt_paramp 
> 
> #define       fmt_restore1    fmt_stream = old_fmt_stream; \
>                       ctl_origin = old_ctl_origin; \
>                       ctl_index = old_ctl_index; \
>                       ctl_end = old_ctl_end; \
>                       fmt_jmp_bufp = old_fmt_jmp_bufp; \
>                       fmt_indents = old_fmt_indents; \
>                       fmt_string = old_fmt_string ; \
>                         fmt_paramp = old_fmt_paramp 
> 
> typedef struct {
>         int fmt_param_type;
>         int fmt_param_value;
>       } format_parameter;
> 
> format_parameter fmt_param[100];
> VOL format_parameter *fmt_paramp;
> #define FMT_PARAM (fmt_paramp)
> 
> #ifndef WRITEC_NEWLINE
> #define  WRITEC_NEWLINE(strm) (writec_stream('\n',strm))
> #endif
> 
> object fmt_temporary_stream;
> object fmt_temporary_string;
> 
> int fmt_nparam;
> enum fmt_types {
>   fmt_null,
>   fmt_int,
>   fmt_char};
> 
> char *fmt_big_numeral[] = {
>       "thousand",
>       "million",
>       "billion",
>       "trillion",
>       "quadrillion",
>       "quintillion",
>       "sextillion",
>       "septillion",
>       "octillion"
> };
> 
> char *fmt_numeral[] = {
>       "zero", "one", "two", "three", "four",
>       "five", "six", "seven", "eight", "nine",
>       "ten", "eleven", "twelve", "thirteen", "fourteen",
>       "fifteen", "sixteen", "seventeen", "eighteen", "nineteen",
>       "zero", "ten", "twenty", "thirty", "forty",
>       "fifty", "sixty", "seventy", "eighty", "ninety"
> };
> 
> char *fmt_ordinal[] = {
>       "zeroth", "first", "second", "third", "fourth",
>       "fifth", "sixth", "seventh", "eighth", "ninth",
>       "tenth", "eleventh", "twelfth", "thirteenth", "fourteenth",
>       "fifteenth", "sixteenth", "seventeenth", "eighteenth", "nineteenth",
>       "zeroth", "tenth", "twentieth", "thirtieth", "fortieth",
>       "fiftieth", "sixtieth", "seventieth", "eightieth", "ninetieth"
> };
> 
> 
> int fmt_spare_spaces;
> int fmt_line_length;
> 
> 
> static int
> fmt_tempstr(int s)
> {
>       return(fmt_temporary_string->st.st_self[s]);
> }
> 
> static int
> ctl_advance(void)
> {
>       if (ctl_index >= ctl_end)
>               fmt_error("unexpected end of control string");
>       return(ctl_string[ctl_index++]);
> }
> 
> static object
> fmt_advance(void)
> {
>       if (fmt_index >= fmt_end)
>               fmt_error("arguments exhausted");
>       return(fmt_base[fmt_index++]);
> }
> 
> 
> static void
> format(object fmt_stream0, int ctl_origin0, int ctl_end0)
> {
>       int c, i, n;
>       bool colon, atsign;
>       object x;
>       fmt_paramp = fmt_param;
> 
>       /* could eliminate the no interrupt if made the
>          temporary stream on the stack... */
>        {BEGIN_NO_INTERRUPT;
>       fmt_stream = fmt_stream0;
>       ctl_origin = ctl_origin0;
>       ctl_index = 0;
>       ctl_end = ctl_end0;
> 
> LOOP:
>       if (ctl_index >= ctl_end)
>         { END_NO_INTERRUPT;
>               return;}
>       if ((c = ctl_advance()) != '~') {
>               writec_stream(c, fmt_stream);
>               goto LOOP;
>       }
>       n = 0;
>       for (;;) {
>               switch (c = ctl_advance()) {
>               case ',':
>                       fmt_param[n].fmt_param_type = fmt_null;
>                       break;
> 
>               case '0':  case '1':  case '2':  case '3':  case '4':
>               case '5':  case '6':  case '7':  case '8':  case '9':
>               DIGIT:
>                       i = 0;
>                       do {
>                               i = i*10 + (c - '0');
>                               c = ctl_advance();
>                       } while (isDigit(c));
>                       fmt_param[n].fmt_param_type = fmt_int;
>                       fmt_param[n].fmt_param_value = i;
>                       break;
> 
>               case '+':
>                       c = ctl_advance();
>                       if (!isDigit(c))
>                               fmt_error("digit expected");
>                       goto DIGIT;
> 
>               case '-':
>                       c = ctl_advance();
>                       if (!isDigit(c))
>                               fmt_error("digit expected");
>                       i = 0;
>                       do {
>                               i = i*10 + (c - '0');
>                               c = ctl_advance();
>                       } while (isDigit(c));
>                       fmt_param[n].fmt_param_type = fmt_int;
>                       fmt_param[n].fmt_param_value = -i;
>                       break;
> 
>               case '\'':
>                       fmt_param[n].fmt_param_type = fmt_char;
>                       fmt_param[n].fmt_param_value = ctl_advance();
>                       c = ctl_advance();
>                       break;
> 
>               case 'v':  case 'V':
>                       x = fmt_advance();
>                       if (type_of(x) == t_fixnum) {
>                               fmt_param[n].fmt_param_type = fmt_int;
>                               fmt_param[n].fmt_param_value = fix(x);
>                       } else if (type_of(x) == t_character) {
>                               fmt_param[n].fmt_param_type = fmt_char;
>                               fmt_param[n].fmt_param_value = x->ch.ch_code;
>                         } else if (x == Cnil) {
>                                  fmt_param[n].fmt_param_type = fmt_null;      
>                         
>                       } else
>                               fmt_error("illegal V parameter");
>                       c = ctl_advance();
>                       break;
> 
>               case '#':
>                       fmt_param[n].fmt_param_type = fmt_int;
>                       fmt_param[n].fmt_param_value = fmt_end - fmt_index;
>                       c = ctl_advance();
>                       break;
> 
>               default:
> /*                    if (n > 0)
>                               fmt_error("illegal ,");
>                       else
> */
>             /* allow (FORMAT NIL "~5,,X" 10) ; ie ,just before directive */ 
> 
>                               goto DIRECTIVE;
>               }
>               n++;
>               if (c != ',')
>                       break;
>       }
> 
> DIRECTIVE:
>       colon = atsign = FALSE;
>       if (c == ':') {
>               colon = TRUE;
>               c = ctl_advance();
>       }
>       if (c == '@') {
>               atsign = TRUE;
>               c = ctl_advance();
>       }
>       fmt_nparam = n;
>       switch (c) {
>       case 'a':  case 'A':
>               fmt_ascii(colon, atsign);
>               break;
> 
>       case 's':  case 'S':
>               fmt_S_expression(colon, atsign);
>               break;
> 
>       case 'd':  case 'D':
>               fmt_decimal(colon, atsign);
>               break;
> 
>       case 'b':  case 'B':
>               fmt_binary(colon, atsign);
>               break;
> 
>       case 'o':  case 'O':
>               fmt_octal(colon, atsign);
>               break;
> 
>       case 'x':  case 'X':
>               fmt_hexadecimal(colon, atsign);
>               break;
> 
>       case 'r':  case 'R':
>               fmt_radix(colon, atsign);
>               break;
> 
>       case 'p':  case 'P':
>               fmt_plural(colon, atsign);
>               break;
> 
>       case 'c':  case 'C':
>               fmt_character(colon, atsign);
>               break;
> 
>       case 'f':  case 'F':
>               fmt_fix_float(colon, atsign);
>               break;
> 
>       case 'e':  case 'E':
>               fmt_exponential_float(colon, atsign);
>               break;
> 
>       case 'g':  case 'G':
>               fmt_general_float(colon, atsign);
>               break;
> 
>       case '$':
>               fmt_dollars_float(colon, atsign);
>               break;
> 
>       case '%':
>               fmt_percent(colon, atsign);
>               break;
> 
>       case '&':
>               fmt_ampersand(colon, atsign);
>               break;
> 
>       case '|':
>               fmt_bar(colon, atsign);
>               break;
> 
>       case '~':
>               fmt_tilde(colon, atsign);
>               break;
> 
>       case '\n':
>       case '\r':      
>               fmt_newline(colon, atsign);
>               break;
> 
>       case 't':  case 'T':
>               fmt_tabulate(colon, atsign);
>               break;
> 
>       case '*':
>               fmt_asterisk(colon, atsign);
>               break;
> 
>       case '?':
>               fmt_indirection(colon, atsign);
>               break;
> 
>       case '(':
>               fmt_case(colon, atsign);
>               break;
> 
>       case '[':
>               fmt_conditional(colon, atsign);
>               break;
> 
>       case '{':
>               fmt_iteration(colon, atsign);
>               break;
> 
>       case '<':
>               fmt_justification(colon, atsign);
>               break;
> 
>       case '^':
>               fmt_up_and_out(colon, atsign);
>               break;
> 
>       case ';':
>               fmt_semicolon(colon, atsign);
>               break;
> 
>       default:
>    {object 
> user_fmt=getf(sSAindent_formatted_outputA->s.s_plist,make_fixnum(c),Cnil);
>     
>     if (user_fmt!=Cnil)
>      {object *oldbase=vs_base;
>       object *oldtop=vs_top;
>       vs_base=vs_top;
>       vs_push(fmt_advance());
>       vs_push(fmt_stream);
>       vs_push(make_fixnum(colon));
>       vs_push(make_fixnum(atsign));
>       if (type_of(user_fmt)==t_symbol) user_fmt=symbol_function(user_fmt);
>       funcall(user_fmt);
>       vs_base=oldbase; vs_top=oldtop; break;}}
>               fmt_error("illegal directive");
>       }
>       goto LOOP;
> }}
> 
> 
> 
> static int
> fmt_skip(void)
> {
>       int c, level = 0;
>       
> LOOP:
>       if (ctl_advance() != '~')
>               goto LOOP;
>       for (;;)
>               switch (c = ctl_advance()) {
>               case '\'':
>                       ctl_advance();
> 
>               case ',':
>               case '0':  case '1':  case '2':  case '3':  case '4':
>               case '5':  case '6':  case '7':  case '8':  case '9':
>               case '+':
>               case '-':
>               case 'v':  case 'V':
>               case '#':
>               case ':':  case '@':
>                       continue;
> 
>               default:
>                       goto DIRECTIVE;
>               }
> 
> DIRECTIVE:
>       switch (c) {
>       case '(':  case '[':  case '<':  case '{':
>               level++;
>               break;
> 
>       case ')':  case ']':  case '>':  case '}':
>               if (level == 0)
>                       return(ctl_index);
>               else
>                       --level;
>               break;
> 
>       case ';':
>               if (level == 0)
>                       return(ctl_index);
>               break;
>       }
>       goto LOOP;
> }
> 
> 
> static void
> fmt_max_param(int n)
> {
>       if (fmt_nparam > n)
>               fmt_error("too many parameters");
> }
> 
> static void
> fmt_not_colon(bool colon)
> {
>       if (colon)
>               fmt_error("illegal :");
> }
> 
> static void
> fmt_not_atsign(bool atsign)
> {
>       if (atsign)
>               fmt_error("illegal @");
> }
> 
> static void
> fmt_not_colon_atsign(bool colon, bool atsign)
> {
>       if (colon && atsign)
>               fmt_error("illegal :@");
> }
> 
> static void
> fmt_set_param(int i, int *p, int t, int v)
> {
>       if (i >= fmt_nparam || FMT_PARAM[i].fmt_param_type == fmt_null)
>               *p = v;
>       else if (FMT_PARAM[i].fmt_param_type != t)
>               fmt_error("illegal parameter type");
>       else
>               *p = FMT_PARAM[i].fmt_param_value;
> }     
> 
> 
> static void
> fmt_ascii(bool colon, bool atsign)
> {
>       int mincol=0, colinc=0, minpad=0, padchar=0;
>       object x;
>       int l, i;
> 
>       fmt_max_param(4);
>       fmt_set_param(0, &mincol, fmt_int, 0);
>       fmt_set_param(1, &colinc, fmt_int, 1);
>       fmt_set_param(2, &minpad, fmt_int, 0);
>       fmt_set_param(3, &padchar, fmt_char, ' ');
> 
>       fmt_temporary_string->st.st_fillp = 0;
>       /* fmt_temporary_stream->sm.sm_int0 = file_column(fmt_stream); */
>       STREAM_FILE_COLUMN(fmt_temporary_stream) = file_column(fmt_stream);
>       x = fmt_advance();
>       if (colon && x == Cnil)
>               writestr_stream("()", fmt_temporary_stream);
>       else if (mincol == 0 && minpad == 0) {
>               princ(x, fmt_stream);
>               return;
>       } else
>               princ(x, fmt_temporary_stream);
>       l = fmt_temporary_string->st.st_fillp;
>       for (i = minpad;  l + i < mincol;  i += colinc)
>               ;
>       if (!atsign) {
>               write_string(fmt_temporary_string, fmt_stream);
>               while (i-- > 0)
>                       writec_stream(padchar, fmt_stream);
>       } else {
>               while (i-- > 0)
>                       writec_stream(padchar, fmt_stream);
>               write_string(fmt_temporary_string, fmt_stream);
>       }
> }
> 
> static void
> fmt_S_expression(bool colon, bool atsign)
> {
>       int mincol=0, colinc=0, minpad=0, padchar=0;
>       object x;
>       int l, i;
> 
>       fmt_max_param(4);
>       fmt_set_param(0, &mincol, fmt_int, 0);
>       fmt_set_param(1, &colinc, fmt_int, 1);
>       fmt_set_param(2, &minpad, fmt_int, 0);
>       fmt_set_param(3, &padchar, fmt_char, ' ');
> 
>       fmt_temporary_string->st.st_fillp = 0;
>       /* fmt_temporary_stream->sm.sm_int0 = file_column(fmt_stream); */
>       STREAM_FILE_COLUMN(fmt_temporary_stream) = file_column(fmt_stream);
>       x = fmt_advance();
>       if (colon && x == Cnil)
>               writestr_stream("()", fmt_temporary_stream);
>       else if (mincol == 0 && minpad == 0) {
>               prin1(x, fmt_stream);
>               return;
>       } else
>               prin1(x, fmt_temporary_stream);
>       l = fmt_temporary_string->st.st_fillp;
>       for (i = minpad;  l + i < mincol;  i += colinc)
>               ;
>       if (!atsign) {
>               write_string(fmt_temporary_string, fmt_stream);
>               while (i-- > 0)
>                       writec_stream(padchar, fmt_stream);
>       } else {
>               while (i-- > 0)
>                       writec_stream(padchar, fmt_stream);
>               write_string(fmt_temporary_string, fmt_stream);
>       }
> }
> 
> static void
> fmt_decimal(bool colon, bool atsign)
> {
>       int mincol=0, padchar=0, commachar=0, commainterval=0;
> 
>       fmt_max_param(4);
>       fmt_set_param(0, &mincol, fmt_int, 0);
>       fmt_set_param(1, &padchar, fmt_char, ' ');
>       fmt_set_param(2, &commachar, fmt_char, ',');
>       fmt_set_param(3, &commainterval, fmt_int, 3);
>       fmt_integer(fmt_advance(), colon, atsign,
>                   10, mincol, padchar, commachar, commainterval);
> }
> 
> static void
> fmt_binary(bool colon, bool atsign)
> {
>       int mincol=0, padchar=0, commachar=0, commainterval=0;
> 
>       fmt_max_param(4);
>       fmt_set_param(0, &mincol, fmt_int, 0);
>       fmt_set_param(1, &padchar, fmt_char, ' ');
>       fmt_set_param(2, &commachar, fmt_char, ',');
>       fmt_set_param(3, &commainterval, fmt_int, 3);
>       fmt_integer(fmt_advance(), colon, atsign,
>                   2, mincol, padchar, commachar, commainterval);
> }
> 
> static void
> fmt_octal(bool colon, bool atsign)
> {
>       int mincol=0, padchar=0, commachar=0, commainterval=0;;
> 
>       fmt_max_param(4);
>       fmt_set_param(0, &mincol, fmt_int, 0);
>       fmt_set_param(1, &padchar, fmt_char, ' ');
>       fmt_set_param(2, &commachar, fmt_char, ',');
>       fmt_set_param(3, &commainterval, fmt_int, 3);
>       fmt_integer(fmt_advance(), colon, atsign,
>                   8, mincol, padchar, commachar, commainterval);
> }
> 
> static void
> fmt_hexadecimal(bool colon, bool atsign)
> {
>       int mincol=0, padchar=0, commachar=0, commainterval=0;;
> 
>       fmt_max_param(4);
>       fmt_set_param(0, &mincol, fmt_int, 0);
>       fmt_set_param(1, &padchar, fmt_char, ' ');
>       fmt_set_param(2, &commachar, fmt_char, ',');
>       fmt_set_param(3, &commainterval, fmt_int, 3);
>       fmt_integer(fmt_advance(), colon, atsign,
>                   16, mincol, padchar, commachar, commainterval);
> }
> 
> static void
> fmt_radix(bool colon, bool atsign)
> {
>       int radix=0, mincol=0, padchar=0, commachar=0, commainterval=0;;
>       object x;
>       int i, j, k;
>       int s, t;
>       bool b;
>       extern void (*write_ch_fun)(int), writec_PRINTstream(int);
> 
>       if (fmt_nparam == 0) {
>               x = fmt_advance();
>               check_type_integer(&x);
>               if (atsign) {
>                       if (type_of(x) == t_fixnum)
>                               i = fix(x);
>                       else
>                               i = -1;
>                       if ((!colon && (i <= 0 || i >= 4000)) ||
>                           (colon && (i <= 0 || i >= 5000))) {
>                               fmt_integer(x, FALSE, FALSE, 10, 0, ' ', ',', 
> 3);
>                               return;
>                       }
>                       fmt_roman(i/1000, 'M', '*', '*', colon);
>                       fmt_roman(i%1000/100, 'C', 'D', 'M', colon);
>                       fmt_roman(i%100/10, 'X', 'L', 'C', colon);
>                       fmt_roman(i%10, 'I', 'V', 'X', colon);
>                       return;
>               }
>               fmt_temporary_string->st.st_fillp = 0;
>               /* fmt_temporary_stream->sm.sm_int0 = file_column(fmt_stream); 
> */
>               STREAM_FILE_COLUMN(fmt_temporary_stream) = 
> file_column(fmt_stream);
>               PRINTstream = fmt_temporary_stream;
>               PRINTradix = FALSE;
>               PRINTbase = 10;
>               write_ch_fun = writec_PRINTstream;
>               write_object(x, 0);
>               s = 0;
>               i = fmt_temporary_string->st.st_fillp;
>               if (i == 1 && fmt_tempstr(s) == '0') {
>                       writestr_stream("zero", fmt_stream);
>                       if (colon)
>                               writestr_stream("th", fmt_stream);
>                       return;
>               } else if (fmt_tempstr(s) == '-') {
>                       writestr_stream("minus ", fmt_stream);
>                       --i;
>                       s++;
>               }
>               t = fmt_temporary_string->st.st_fillp;
>               for (;;)
>                       if (fmt_tempstr(--t) != '0')
>                               break;
>               for (b = FALSE;  i > 0;  i -= j) {
>                       b = fmt_nonillion(s, j = (i+29)%30+1, b,
>                                         i<=30&&colon, t);
>                       s += j;
>                       if (b && i > 30) {
>                               for (k = (i - 1)/30;  k > 0;  --k)
>                                       writestr_stream(" nonillion",
>                                                       fmt_stream);
>                               if (colon && s > t)
>                                       writestr_stream("th", fmt_stream);
>                       }
>               }
>               return;
>       }
>       fmt_max_param(5);
>       fmt_set_param(0, &radix, fmt_int, 10);
>       fmt_set_param(1, &mincol, fmt_int, 0);
>       fmt_set_param(2, &padchar, fmt_char, ' ');
>       fmt_set_param(3, &commachar, fmt_char, ',');
>       fmt_set_param(4, &commainterval, fmt_int, 3);
>       x = fmt_advance();
>       check_type_integer(&x);
>       if (radix < 0 || radix > 36) {
>               vs_push(make_fixnum(radix));
>               FEerror("~D is illegal as a radix.", 1, vs_head);
>       }
>       fmt_integer(x, colon, atsign, radix, mincol, padchar, commachar, 
> commainterval);
> }     
> 
> static void
> fmt_integer(object x, bool colon, bool atsign, int radix, int mincol, int 
> padchar, int commachar, int commainterval)
> {
>       int l, l1;
>       int s;
>       extern void (*write_ch_fun)(int), writec_PRINTstream(int);
> 
>       if (type_of(x) != t_fixnum && type_of(x) != t_bignum) {
>               fmt_temporary_string->st.st_fillp = 0;
>               /* fmt_temporary_stream->sm.sm_int0 = file_column(fmt_stream); 
> */
>               STREAM_FILE_COLUMN(fmt_temporary_stream) = 
> file_column(fmt_stream);
>               {SETUP_PRINT_DEFAULT(x);
>               PRINTstream = fmt_temporary_stream;
>               PRINTescape = FALSE;
>               PRINTbase = radix;
>               write_ch_fun = writec_PRINTstream;
>               write_object(x, 0);
>               CLEANUP_PRINT_DEFAULT;}
>               l = fmt_temporary_string->st.st_fillp;
>               mincol -= l;
>               while (mincol-- > 0)
>                       writec_stream(padchar, fmt_stream);
>               for (s = 0;  l > 0;  --l, s++)
>                       writec_stream(fmt_tempstr(s), fmt_stream);
>               return;
>       }
>       fmt_temporary_string->st.st_fillp = 0;
>       /* fmt_temporary_stream->sm.sm_int0 = file_column(fmt_stream);*/
>       STREAM_FILE_COLUMN(fmt_temporary_stream) = file_column(fmt_stream);
>       PRINTstream = fmt_temporary_stream;
>       PRINTradix = FALSE;
>       PRINTbase = radix;
>       write_ch_fun = writec_PRINTstream;
>       write_object(x, 0);
>       l = l1 = fmt_temporary_string->st.st_fillp;
>       s = 0;
>       if (fmt_tempstr(s) == '-')
>               --l1;
>       mincol -= l;
>       if (colon)
>               mincol -= (l1 - 1)/3;
>       if (atsign && fmt_tempstr(s) != '-')
>               --mincol;
>       while (mincol-- > 0)
>               writec_stream(padchar, fmt_stream);
>       if (fmt_tempstr(s) == '-') {
>               s++;
>               writec_stream('-', fmt_stream);
>       } else if (atsign)
>               writec_stream('+', fmt_stream);
>       while (l1-- > 0) {
>               writec_stream(fmt_tempstr(s++), fmt_stream);
>               if (colon && l1 > 0 && l1%(commainterval) == 0)
>                       writec_stream(commachar, fmt_stream);
>       }
> }
> 
> static int
> fmt_nonillion(int s, int i, bool b, bool o, int t)
> {
>       int j;
> 
>       for (;  i > 3;  i -= j) {
>               b = fmt_thousand(s, j = (i+2)%3+1, b, FALSE, t);
>               if (j != 3 || fmt_tempstr(s) != '0' ||
>                   fmt_tempstr(s+1) != '0' || fmt_tempstr(s+2) != '0') {
>                       writec_stream(' ', fmt_stream);
>                       writestr_stream(fmt_big_numeral[(i - 1)/3 - 1],
>                                       fmt_stream);
>                       s += j;
>                       if (o && s > t)
>                               writestr_stream("th", fmt_stream);
>               } else
>                       s += j;
>       }
>       return(fmt_thousand(s, i, b, o, t));
> }             
> 
> static int
> fmt_thousand(int s, int i, bool b, bool o, int t)
> {
>       if (i == 3 && fmt_tempstr(s) > '0') {
>               if (b)
>                       writec_stream(' ', fmt_stream);
>               fmt_write_numeral(s, 0);
>               writestr_stream(" hundred", fmt_stream);
>               --i;
>               s++;
>               b = TRUE;
>               if (o && s > t)
>                       writestr_stream("th", fmt_stream);
>       }
>       if (i == 3) {
>               --i;
>               s++;
>       }
>       if (i == 2 && fmt_tempstr(s) > '0') {
>               if (b)
>                       writec_stream(' ', fmt_stream);
>               if (fmt_tempstr(s) == '1') {
>                       if (o && s + 2 > t)
>                               fmt_write_ordinal(++s, 10);
>                       else
>                               fmt_write_numeral(++s, 10);
>                       return(TRUE);
>               } else {
>                       if (o && s + 1 > t)
>                               fmt_write_ordinal(s, 20);
>                       else
>                               fmt_write_numeral(s, 20);
>                       s++;
>                       if (fmt_tempstr(s) > '0') {
>                               writec_stream('-', fmt_stream);
>                               if (o && s + 1 > t)
>                                       fmt_write_ordinal(s, 0);
>                               else
>                                       fmt_write_numeral(s, 0);
>                       }
>                       return(TRUE);
>               }
>       }
>       if (i == 2)
>               s++;
>       if (fmt_tempstr(s) > '0') {
>               if (b)
>                       writec_stream(' ', fmt_stream);
>               if (o && s + 1 > t)
>                       fmt_write_ordinal(s, 0);
>               else
>                       fmt_write_numeral(s, 0);
>               return(TRUE);
>       }
>       return(b);
> }
>       
> static void
> fmt_write_numeral(int s, int i)
> {
>       writestr_stream(fmt_numeral[fmt_tempstr(s) - '0' + i], fmt_stream);
> }
> 
> static void
> fmt_write_ordinal(int s, int i)
> {
>       writestr_stream(fmt_ordinal[fmt_tempstr(s) - '0' + i], fmt_stream);
> }
> 
> static void
> fmt_roman(int i, int one, int five, int ten, int colon)
> {
>       int j;
> 
>       if (i == 0)
>               return;
>       if ((!colon && i < 4) || (colon && i < 5))
>               for (j = 0;  j < i;  j++)
>                       writec_stream(one, fmt_stream);
>       else if (!colon && i == 4) {
>               writec_stream(one, fmt_stream);
>               writec_stream(five, fmt_stream);
>       } else if ((!colon && i < 9) || colon) {
>               writec_stream(five, fmt_stream);
>               for (j = 5;  j < i;  j++)
>                       writec_stream(one, fmt_stream);
>       } else if (!colon && i == 9) {
>               writec_stream(one, fmt_stream);
>               writec_stream(ten, fmt_stream);
>       }
> }
> 
> static void
> fmt_plural(bool colon, bool atsign)
> {
>       fmt_max_param(0);
>       if (colon) {
>               if (fmt_index == 0)
>                       fmt_error("can't back up");
>               --fmt_index;
>       }
>       if (eql(fmt_advance(), make_fixnum(1)))
>               if (atsign)
>                       writec_stream('y', fmt_stream);
>               else
>                       ;
>       else
>               if (atsign)
>                       writestr_stream("ies", fmt_stream);
>               else
>                       writec_stream('s', fmt_stream);
> }
> 
> static void
> fmt_character(bool colon, bool atsign)
> {
>       object x;
>       int i;
> 
>       fmt_max_param(0);
>       fmt_temporary_string->st.st_fillp = 0;
>       /* fmt_temporary_stream->sm.sm_int0 = 0;*/
>       STREAM_FILE_COLUMN(fmt_temporary_stream) = 0;
>       x = fmt_advance();
>       check_type_character(&x);
>       prin1(x, fmt_temporary_stream);
>       if (!colon && atsign)
>               i = 0;
>       else
>               i = 2;
>       for (;  i < fmt_temporary_string->st.st_fillp;  i++)
>               writec_stream(fmt_tempstr(i), fmt_stream);
> }
> 
> static void
> fmt_fix_float(bool colon, bool atsign)
> {
>       int w=0, d=0, k=0, overflowchar=0, padchar=0;
>       double f;
>       int sign;
>       char buff[256], *b, buff1[256];
>       int exp;
>       int i, j;
>       object x;
>       int n, m;
>       vs_mark;
> 
>       b = buff1 + 1;
> 
>       fmt_not_colon(colon);
>       fmt_max_param(5);
>       fmt_set_param(0, &w, fmt_int, 0);
>       if (w < 0)
>               fmt_error("illegal width");
>       fmt_set_param(0, &w, fmt_int, -1);
>       fmt_set_param(1, &d, fmt_int, 0);
>       if (d < 0)
>               fmt_error("illegal number of digits");
>       fmt_set_param(1, &d, fmt_int, -1);
>       fmt_set_param(2, &k, fmt_int, 0);
>       fmt_set_param(3, &overflowchar, fmt_char, -1);
>       fmt_set_param(4, &padchar, fmt_char, ' ');
> 
>       x = fmt_advance();
>       if (type_of(x) == t_fixnum ||
>           type_of(x) == t_bignum ||
>           type_of(x) == t_ratio) {
>               x = make_shortfloat((shortfloat)number_to_double(x));
>               vs_push(x);
>       }
>       if (type_of(x) == t_complex) {
>               if (w < 0)
>                       prin1(x, fmt_stream);
>               else {
>                       fmt_nparam = 1;
>                       --fmt_index;
>                       fmt_decimal(colon, atsign);
>               }
>               vs_reset;
>               return;
>       }
>       if (type_of(x) == t_longfloat)
> /*            n = 16; */
>               n = 17;
>       else
> /*            n = 7; */
>               n = 8;
>       f = number_to_double(x);
>       edit_double(n, f, &sign, buff, &exp);
>       if (exp + k > 100 || exp + k < -100 || d > 100) {
>               prin1(x, fmt_stream);
>               vs_reset;
>               return;
>       }
>       if (d >= 0)
>               m = d + exp + k + 1;
>       else if (w >= 0) {
>               if (exp + k >= 0)
>                       m = w - 1;
>               else
>                       m = w + exp + k - 2;
>               if (sign < 0 || atsign)
>                       --m;
>               if (m == 0)
>                       m = 1;
>       } else
>               m = n;
>       if (m <= 0) {
>               if (m == 0 && buff[0] >= '5') {
>                       exp++;
>                       n = m = 1;
>                       buff[0] = '1';
>               } else
>                       n = m = 0;
>       } else if (m < n) {
>               n = m;
>               edit_double(n, f, &sign, buff, &exp);
>       }
>       while (n >= 0)
>               if (buff[n - 1] == '0')
>                       --n;
>               else
>                       break;
>       exp += k;
>       j = 0;
>       if (exp >= 0) {
>               for (i = 0;  i <= exp;  i++)
>                       b[j++] = i < n ? buff[i] : '0';
>               b[j++] = '.';
>               if (d >= 0)
>                       for (m = i + d;  i < m;  i++)
>                               b[j++] = i < n ? buff[i] : '0';
>               else
>                       for (;  i < n;  i++)
>                               b[j++] = buff[i];
>       } else {
>               b[j++] = '.';
>               if (d >= 0) {
>                       for (i = 0;  i < (-exp) - 1 && i < d;  i++)
>                               b[j++] = '0';
>                       for (m = d - i, i = 0;  i < m;  i++)
>                               b[j++] = i < n ? buff[i] : '0';
>               } else if (n > 0) {
>                       for (i = 0;  i < (-exp) - 1;  i++)
>                               b[j++] = '0';
>                       for (i = 0;  i < n;  i++)
>                               b[j++] = buff[i];
>               }
>       }
>       b[j] = '\0';
>       if (w >= 0) {
>               if (sign < 0 || atsign)
>                       --w;
>               if (j > w && overflowchar >= 0)
>                       goto OVER;
>               if (j < w && b[j-1] == '.' && d) {
>                       b[j++] = '0';
>                       b[j] = '\0';
>               }
>               if (j < w && b[0] == '.') {
>                       *--b = '0';
>                       j++;
>               }
>               for (i = j;  i < w;  i++)
>                       writec_stream(padchar, fmt_stream);
>       } else {
>               if (b[0] == '.') {
>                       *--b = '0';
>                       j++;
>               }
>               if (d < 0 && b[j-1] == '.') {
>                       b[j++] = '0';
>                       b[j] = '\0';
>               }
>       }
>       if (sign < 0)
>               writec_stream('-', fmt_stream);
>       else if (atsign)
>               writec_stream('+', fmt_stream);
>       writestr_stream(b, fmt_stream);
>       vs_reset;
>       return;
> 
> OVER:
>       fmt_set_param(0, &w, fmt_int, 0);
>       for (i = 0;  i < w;  i++)
>               writec_stream(overflowchar, fmt_stream);
>       vs_reset;
>       return;
> }
> 
> static int
> fmt_exponent_length(int e)
> {
>       int i;
> 
>       if (e == 0)
>               return(1);
>       if (e < 0)
>               e = -e;
>       for (i = 0;  e > 0;  i++, e /= 10)
>               ;
>       return(i);
> }
> 
> static void
> fmt_exponent(int e)
> {
>       if (e == 0) {
>               writec_stream('0', fmt_stream);
>               return;
>       }
>       if (e < 0)
>               e = -e;
>       fmt_exponent1(e);
> }
>       
> static void
> fmt_exponent1(int e)
> {
>       if (e == 0)
>               return;
>       fmt_exponent1(e/10);
>       writec_stream('0' + e%10, fmt_stream);
> }
> 
> static void
> fmt_exponential_float(bool colon, bool atsign)
> {
>       int w=0, d=0, e=0, k=0, overflowchar=0, padchar=0, exponentchar=0;
>       double f;
>       int sign;
>       char buff[256], *b, buff1[256];
>       int exp;
>       int i, j;
>       object x, y;
>       int n, m;
>       enum type t;
>       vs_mark;
> 
>       b = buff1 + 1;
> 
>       fmt_not_colon(colon);
>       fmt_max_param(7);
>       fmt_set_param(0, &w, fmt_int, 0);
>       if (w < 0)
>               fmt_error("illegal width");
>       fmt_set_param(0, &w, fmt_int, -1);
>       fmt_set_param(1, &d, fmt_int, 0);
>       if (d < 0)
>               fmt_error("illegal number of digits");
>       fmt_set_param(1, &d, fmt_int, -1);
>       fmt_set_param(2, &e, fmt_int, 0);
>       if (e < 0)
>               fmt_error("illegal number of digits in exponent");
>       fmt_set_param(2, &e, fmt_int, -1);
>       fmt_set_param(3, &k, fmt_int, 1);
>       fmt_set_param(4, &overflowchar, fmt_char, -1);
>       fmt_set_param(5, &padchar, fmt_char, ' ');
>       fmt_set_param(6, &exponentchar, fmt_char, -1);
> 
>       x = fmt_advance();
>       if (type_of(x) == t_fixnum ||
>           type_of(x) == t_bignum ||
>           type_of(x) == t_ratio) {
>               x = make_shortfloat((shortfloat)number_to_double(x));
>               vs_push(x);
>       }
>       if (type_of(x) == t_complex) {
>               if (w < 0)
>                       prin1(x, fmt_stream);
>               else {
>                       fmt_nparam = 1;
>                       --fmt_index;
>                       fmt_decimal(colon, atsign);
>               }
>               vs_reset;
>               return;
>       }
>       if (type_of(x) == t_longfloat)
> /*            n = 16; */
>               n = 17;
>       else
> /*            n = 7; */
>               n = 8;
>       f = number_to_double(x);
>       edit_double(n, f, &sign, buff, &exp);
>       if (d >= 0) {
>               if (k > 0) {
>                       if (!(k < d + 2))
>                               fmt_error("illegal scale factor");
>                       m = d + 1;
>               } else {
>                       if (!(k > -d))
>                               fmt_error("illegal scale factor");
>                       m = d + k;
>               }
>       } else if (w >= 0) {
>               if (k > 0)
>                       m = w - 1;
>               else
>                       m = w + k - 1;
>               if (sign < 0 || atsign)
>                       --m;
>               if (e >= 0)
>                       m -= e + 2;
>               else
>                       m -= fmt_exponent_length(e - k + 1) + 2;
>       } else
>               m = n;
>       if (m <= 0) {
>               if (m == 0 && buff[0] >= '5') {
>                       exp++;
>                       n = m = 1;
>                       buff[0] = '1';
>               } else
>                       n = m = 0;
>       } else if (m < n) {
>               n = m;
>               edit_double(n, f, &sign, buff, &exp);
>       }
>       while (n >= 0)
>               if (buff[n - 1] == '0')
>                       --n;
>               else
>                       break;
>       exp = exp - k + 1;
>       j = 0;
>       if (k > 0) {
>               for (i = 0;  i < k;  i++)
>                       b[j++] = i < n ? buff[i] : '0';
>               b[j++] = '.';
>               if (d >= 0)
>                       for (m = i + (d - k + 1);  i < m;  i++)
>                               b[j++] = i < n ? buff[i] : '0';
>               else
>                       for (;  i < n;  i++)
>                               b[j++] = buff[i];
>       } else {
>               b[j++] = '.';
>               if (d >= 0) {
>                       for (i = 0;  i < -k && i < d;  i++)
>                               b[j++] = '0';
>                       for (m = d - i, i = 0;  i < m;  i++)
>                               b[j++] = i < n ? buff[i] : '0';
>               } else if (n > 0) {
>                       for (i = 0;  i < -k;  i++)
>                               b[j++] = '0';
>                       for (i = 0;  i < n;  i++)
>                               b[j++] = buff[i];
>               }
>       }
>       b[j] = '\0';
>       if (w >= 0) {
>               if (sign < 0 || atsign)
>                       --w;
>               i = fmt_exponent_length(exp);
>               if (e >= 0) {
>                       if (i > e) {
>                               if (overflowchar >= 0)
>                                       goto OVER;
>                               else
>                                       e = i;
>                       }
>                       w -= e + 2;
>               } else
>                       w -= i + 2;
>               if (j > w && overflowchar >= 0)
>                       goto OVER;
>               if (j < w && b[j-1] == '.') {
>                       b[j++] = '0';
>                       b[j] = '\0';
>               }
>               if (j < w && b[0] == '.') {
>                       *--b = '0';
>                       j++;
>               }
>               for (i = j;  i < w;  i++)
>                       writec_stream(padchar, fmt_stream);
>       } else {
>               if (b[j-1] == '.') {
>                       b[j++] = '0';
>                       b[j] = '\0';
>               }
>               if (d < 0 && b[0] == '.') {
>                       *--b = '0';
>                       j++;
>               }
>       }
>       if (sign < 0)
>               writec_stream('-', fmt_stream);
>       else if (atsign)
>               writec_stream('+', fmt_stream);
>       writestr_stream(b, fmt_stream);
>       y = symbol_value(sLAread_default_float_formatA);
>       if (exponentchar < 0) {
>               if (y == sLlong_float || y == sLdouble_float
>                   || y == sLsingle_float 
> 
>                   )
>                       t = t_longfloat;
>               else
>                       t = t_shortfloat;
>               if (type_of(x) == t)
>                       exponentchar = 'E';
>               else if (type_of(x) == t_shortfloat)
>                       exponentchar = 'S';
>               else
>                       exponentchar = 'L';
>       }
>       writec_stream(exponentchar, fmt_stream);
>       if (exp < 0)
>               writec_stream('-', fmt_stream);
>       else
>               writec_stream('+', fmt_stream);
>       if (e >= 0)
>               for (i = e - fmt_exponent_length(exp);  i > 0;  --i)
>                       writec_stream('0', fmt_stream);
>       fmt_exponent(exp);
>       vs_reset;
>       return;
> 
> OVER:
>       fmt_set_param(0, &w, fmt_int, -1);
>       for (i = 0;  i < w;  i++)
>               writec_stream(overflowchar, fmt_stream);
>       vs_reset;
>       return;
> }
> 
> static void
> fmt_general_float(bool colon, bool atsign)
> {
>       int w=0, d=0, e=0, k, overflowchar, padchar=0, exponentchar;
>       int sign, exp;
>       char buff[256];
>       object x;
>       int n, ee, ww, q, dd;
>       vs_mark;
> 
>       fmt_not_colon(colon);
>       fmt_max_param(7);
>       fmt_set_param(0, &w, fmt_int, 0);
>       if (w < 0)
>               fmt_error("illegal width");
>       fmt_set_param(0, &w, fmt_int, -1);
>       fmt_set_param(1, &d, fmt_int, 0);
>       if (d < 0)
>               fmt_error("illegal number of digits");
>       fmt_set_param(1, &d, fmt_int, -1);
>       fmt_set_param(2, &e, fmt_int, 0);
>       if (e < 0)
>               fmt_error("illegal number of digits in exponent");
>       fmt_set_param(2, &e, fmt_int, -1);
>       fmt_set_param(3, &k, fmt_int, 1);
>       fmt_set_param(4, &overflowchar, fmt_char, -1);
>       fmt_set_param(5, &padchar, fmt_char, ' ');
>       fmt_set_param(6, &exponentchar, fmt_char, -1);
> 
>       x = fmt_advance();
>       if (type_of(x) == t_complex) {
>               if (w < 0)
>                       prin1(x, fmt_stream);
>               else {
>                       fmt_nparam = 1;
>                       --fmt_index;
>                       fmt_decimal(colon, atsign);
>               }
>               vs_reset;
>               return;
>       }
>       if (type_of(x) == t_longfloat)
> /*            q = 16; */
>               q = 17;
>       else
> /*            q = 7; */
>               q = 8;
>       edit_double(q, number_to_double(x), &sign, buff, &exp);
>       n = exp + 1;
>       while (q >= 0)
>               if (buff[q - 1] == '0')
>                       --q;
>               else
>                       break;
>       if (e >= 0)
>               ee = e + 2;
>       else
>               ee = 4;
>       ww = w - ee;
>       if (d < 0) {
>               d = n < 7 ? n : 7;
>               d = q > d ? q : d;
>       }
>       dd = d - n;
>       if (0 <= dd && dd <= d) {
>               FMT_PARAM[0].fmt_param_value = ww;
>               if (w < 0) FMT_PARAM[0].fmt_param_type = fmt_null;
>               FMT_PARAM[1].fmt_param_value = dd;
>               FMT_PARAM[1].fmt_param_type = fmt_int;
>               FMT_PARAM[2].fmt_param_type = fmt_null;
>               if (fmt_nparam > 4)
>                 {FMT_PARAM[3] =    FMT_PARAM[4]; }
>               else FMT_PARAM[3].fmt_param_type = fmt_null;
>               if (fmt_nparam > 5)
>                 {FMT_PARAM[4] = FMT_PARAM[5];}
>               else FMT_PARAM[4].fmt_param_type = fmt_null;
>               fmt_nparam = 5;
>               --fmt_index;
>               fmt_fix_float(colon, atsign);
>               if (w >= 0)
>                       while (ww++ < w)
>                               writec_stream(padchar, fmt_stream);
>               vs_reset;
>               return;
>       }
>       FMT_PARAM[1].fmt_param_value = d;
>       FMT_PARAM[1].fmt_param_type = fmt_int;
>       --fmt_index;
>       fmt_exponential_float(colon, atsign);
>       vs_reset;
> }
> 
> static void
> fmt_dollars_float(bool colon, bool atsign)
> {
>       int d=0, n=0, w=0, padchar=0;
>       double f;
>       int sign;
>       char buff[256];
>       int exp;
>       int q, i;
>       object x;
>       vs_mark;
> 
>       fmt_max_param(4);
>       fmt_set_param(0, &d, fmt_int, 2);
>       if (d < 0)
>               fmt_error("illegal number of digits");
>       fmt_set_param(1, &n, fmt_int, 1);
>       if (n < 0)
>               fmt_error("illegal number of digits");
>       fmt_set_param(2, &w, fmt_int, 0);
>       if (w < 0)
>               fmt_error("illegal width");
>       fmt_set_param(3, &padchar, fmt_char, ' ');
>       x = fmt_advance();
>       if (type_of(x) == t_complex) {
>               if (w < 0)
>                       prin1(x, fmt_stream);
>               else {
>                       fmt_nparam = 1;
>                       FMT_PARAM[0] = FMT_PARAM[2];
>                       --fmt_index;
>                       fmt_decimal(colon, atsign);
>               }
>               vs_reset;
>               return;
>       }
> /*    q = 7; */
>       q = 8;
>       if (type_of(x) == t_longfloat)
> /*            q = 16; */
>               q = 17;
>       f = number_to_double(x);
>       edit_double(q, f, &sign, buff, &exp);
>       if ((q = exp + d + 1) > 0)
>               edit_double(q, f, &sign, buff, &exp);
>       exp++;
>       if (w > 100 || exp > 100 || exp < -100) {
>               fmt_nparam = 6;
>               FMT_PARAM[0] = FMT_PARAM[2];
>               FMT_PARAM[1].fmt_param_value = d + n - 1;
>               FMT_PARAM[1].fmt_param_type = fmt_int;
>               FMT_PARAM[2].fmt_param_type =
>               FMT_PARAM[3].fmt_param_type =
>               FMT_PARAM[4].fmt_param_type = fmt_null;
>               FMT_PARAM[5] = FMT_PARAM[3];
>               --fmt_index;
>               fmt_exponential_float(colon, atsign);
>       }
>       if (exp > n)
>               n = exp;
>       if (sign < 0 || atsign)
>               --w;
>       if (colon) {
>               if (sign < 0)
>                       writec_stream('-', fmt_stream);
>               else if (atsign)
>                       writec_stream('+', fmt_stream);
>               while (--w > n + d)
>                       writec_stream(padchar, fmt_stream);
>       } else {
>               while (--w > n + d)
>                       writec_stream(padchar, fmt_stream);
>               if (sign < 0)
>                       writec_stream('-', fmt_stream);
>               else if (atsign)
>                       writec_stream('+', fmt_stream);
>       }
>       for (i = n - exp;  i > 0;  --i)
>               writec_stream('0', fmt_stream);
>       for (i = 0;  i < exp;  i++)
>               writec_stream((i < q ? buff[i] : '0'), fmt_stream);
>       writec_stream('.', fmt_stream);
>       for (d += i;  i < d;  i++)
>               writec_stream((i < q ? buff[i] : '0'), fmt_stream);
>       vs_reset;
> }
> 
> static void
> fmt_percent(bool colon, bool atsign)
> {
>       int n=0, i;
> 
>       fmt_max_param(1);
>       fmt_set_param(0, &n, fmt_int, 1);
>       fmt_not_colon(colon);
>       fmt_not_atsign(atsign);
>       while (n-- > 0) {
>                 WRITEC_NEWLINE(fmt_stream);
>               if (n == 0)
>                       for (i = fmt_indents;  i > 0;  --i)
>                               writec_stream(' ', fmt_stream);
>       }
> }
> 
> static void
> fmt_ampersand(bool colon, bool atsign)
> {
>       int n=0;
> 
>       fmt_max_param(1);
>       fmt_set_param(0, &n, fmt_int, 1);
>       fmt_not_colon(colon);
>       fmt_not_atsign(atsign);
>       if (n == 0)
>               return;
>       if (file_column(fmt_stream) != 0)
>         WRITEC_NEWLINE(fmt_stream);
>       while (--n > 0)
>                 WRITEC_NEWLINE(fmt_stream);
>       fmt_indents = 0;
> }
> 
> static void
> fmt_bar(bool colon, bool atsign)
> {
>       int n=0;
> 
>       fmt_max_param(1);
>       fmt_set_param(0, &n, fmt_int, 1);
>       fmt_not_colon(colon);
>       fmt_not_atsign(atsign);
>       while (n-- > 0)
>               writec_stream('\f', fmt_stream);
> }
> 
> static void
> fmt_tilde(bool colon, bool atsign)
> {
>       int n=0;
> 
>       fmt_max_param(1);
>       fmt_set_param(0, &n, fmt_int, 1);
>       fmt_not_colon(colon);
>       fmt_not_atsign(atsign);
>       while (n-- > 0)
>               writec_stream('~', fmt_stream);
> }
> 
> static void
> fmt_newline(bool colon, bool atsign)
> {
> 
>       fmt_max_param(0);
>       fmt_not_colon_atsign(colon, atsign);
>       if (atsign)
>         WRITEC_NEWLINE(fmt_stream);
>       while (ctl_index < ctl_end && isspace((int)ctl_string[ctl_index])) {
>               if (colon)
>                       writec_stream(ctl_string[ctl_index], fmt_stream);
>               ctl_index++;
>       }
> }
> 
> static void
> fmt_tabulate(bool colon, bool atsign)
> {
>       int colnum=0, colinc=0;
>       int c, i;
>       
>       fmt_max_param(2);
>       fmt_not_colon(colon);
>       fmt_set_param(0, &colnum, fmt_int, 1);
>       fmt_set_param(1, &colinc, fmt_int, 1);
>       if (!atsign) {
>               c = file_column(fmt_stream);
>               if (c < 0) {
>                       writestr_stream("  ", fmt_stream);
>                       return;
>               }
>               if (c > colnum && colinc <= 0)
>                       return;
>               while (c > colnum)
>                       colnum += colinc;
>               for (i = colnum - c;  i > 0;  --i)
>                       writec_stream(' ', fmt_stream);
>       } else {
>               for (i = colnum;  i > 0;  --i)
>                       writec_stream(' ', fmt_stream);
>               c = file_column(fmt_stream);
>               if (c < 0 || colinc <= 0)
>                       return;
>               colnum = 0;
>               while (c > colnum)
>                       colnum += colinc;
>               for (i = colnum - c;  i > 0;  --i)
>                       writec_stream(' ', fmt_stream);
>       }
> }
> 
> static void
> fmt_asterisk(bool colon, bool atsign)
> {
>       int n=0;
> 
>       fmt_max_param(1);
>       fmt_not_colon_atsign(colon, atsign);
>       if (atsign) {
>               fmt_set_param(0, &n, fmt_int, 0);
>               if (n < 0 || n >= fmt_end)
>                       fmt_error("can't goto");
>               fmt_index = n;
>       } else if (colon) {
>               fmt_set_param(0, &n, fmt_int, 1);
>               if (n > fmt_index)
>                       fmt_error("can't back up");
>               fmt_index -= n;
>       } else {
>               fmt_set_param(0, &n, fmt_int, 1);
>               while (n-- > 0)
>                       fmt_advance();
>       }
> }     
> 
> static void
> fmt_indirection(bool colon, bool atsign) {
>       object s, l;
>       fmt_old;
>       jmp_buf fmt_jmp_buf0;
>       int up_colon;
> 
>       /* to prevent longjmp clobber */
>       up_colon=(long)&old_fmt_paramp;
>       fmt_max_param(0);
>       fmt_not_colon(colon);
>       s = fmt_advance();
>       if (type_of(s) != t_string)
>               fmt_error("control string expected");
>       if (atsign) {
>               fmt_save;
>               fmt_jmp_bufp = &fmt_jmp_buf0;
>               fmt_string = s;
>               if ((up_colon = setjmp(*fmt_jmp_bufp))) {
>                       if (--up_colon)
>                               fmt_error("illegal ~:^");
>               } else
>                       format(fmt_stream, 0, s->st.st_fillp);
>               fmt_restore1;
>       } else {
>               l = fmt_advance();
>               fmt_save;
>               fmt_base = vs_top;
>               fmt_index = 0;
>               for (fmt_end = 0;  !endp(l);  fmt_end++, l = l->c.c_cdr)
>                       vs_check_push(l->c.c_car);
>               fmt_jmp_bufp = &fmt_jmp_buf0;
>               fmt_string = s;
>               if ((up_colon = setjmp(*fmt_jmp_bufp))) {
>                       if (--up_colon)
>                               fmt_error("illegal ~:^");
>               } else
>                       format(fmt_stream, 0, s->st.st_fillp);
>               vs_top = fmt_base;
>               fmt_restore;
>       }
> }
> 
> static void
> fmt_case(bool colon, bool atsign)
> {
>       VOL object x;
>       VOL int i, j;
>       fmt_old;
>       jmp_buf fmt_jmp_buf0;
>       int up_colon;
>       bool b;
> 
>       x = make_string_output_stream(64);
>       vs_push(x);
>       i = ctl_index;
>       j = fmt_skip();
>       if (ctl_string[--j] != ')' || ctl_string[--j] != '~')
>               fmt_error("~) expected");
>       fmt_save;
>       fmt_jmp_bufp = &fmt_jmp_buf0;
>       if ((up_colon = setjmp(*fmt_jmp_bufp)))
>               ;
>       else
>               format(x, ctl_origin + i, j - i);
>       fmt_restore1;
>       x = x->sm.sm_object0;
>       if (!colon && !atsign)
>               for (i = 0;  i < x->st.st_fillp;  i++) {
>                 j = x->st.st_self[i];
>                 if (isUpper(j))
>                   j += 'a' - 'A';
>                 writec_stream(j, fmt_stream);
>               }
>       else if (colon && !atsign)
>               for (b = TRUE, i = 0;  i < x->st.st_fillp;  i++) {
>                 j = x->st.st_self[i];
>                 if (isLower(j)) {
>                   if (b)
>                     j -= 'a' - 'A';
>                   b = FALSE;
>                 } else if (isUpper(j)) {
>                   if (!b)
>                     j += 'a' - 'A';
>                   b = FALSE;
>                 } else if (!isDigit(j))
>                   b = TRUE;
>                 writec_stream(j, fmt_stream);
>               }
>       else if (!colon && atsign)
>               for (b = TRUE, i = 0;  i < x->st.st_fillp;  i++) {
>                 j = x->st.st_self[i];
>                 if (isLower(j)) {
>                   if (b)
>                     j -= 'a' - 'A';
>                   b = FALSE;
>                 } else if (isUpper(j)) {
>                   if (!b)
>                     j += 'a' - 'A';
>                   b = FALSE;
>                 }
>                 writec_stream(j, fmt_stream);
>               }
>       else
>               for (i = 0;  i < x->st.st_fillp;  i++) {
>                 j = x->st.st_self[i];
>                 if (isLower(j))
>                   j -= 'a' - 'A';
>                 writec_stream(j, fmt_stream);
>               }
>       vs_popp;
>       if (up_colon)
>               longjmp(*fmt_jmp_bufp, up_colon);
> }
> 
> static void
> fmt_conditional(bool colon, bool atsign)
> {
>       int i, j, k;
>       object x;
>       int n=0;
>       bool done;
>       fmt_old;
> 
>       fmt_not_colon_atsign(colon, atsign);
>       if (colon) {
>               fmt_max_param(0);
>               i = ctl_index;
>               j = fmt_skip();
>               if (ctl_string[--j] != ';' || ctl_string[--j] != '~')
>                       fmt_error("~; expected");
>               k = fmt_skip();
>               if (ctl_string[--k] != ']' || ctl_string[--k] != '~')
>                       fmt_error("~] expected");
>               if (fmt_advance() == Cnil) {
>                       fmt_save;
>                       format(fmt_stream, ctl_origin + i, j - i);
>                       fmt_restore1;
>               } else {
>                       fmt_save;
>                       format(fmt_stream, ctl_origin + j + 2, k - (j + 2));
>                       fmt_restore1;
>               }
>       } else if (atsign) {
>               i = ctl_index;
>               j = fmt_skip();
>               if (ctl_string[--j] != ']' || ctl_string[--j] != '~')
>                       fmt_error("~] expected");
>               if (fmt_advance() == Cnil)
>                       ;
>               else {
>                       --fmt_index;
>                       fmt_save;
>                       format(fmt_stream, ctl_origin + i, j - i);
>                       fmt_restore1;
>               }
>       } else {
>               fmt_max_param(1);
>               if (fmt_nparam == 0) {
>                       x = fmt_advance();
>                       if (type_of(x) != t_fixnum)
>                               fmt_error("illegal argument for conditional");
>                       n = fix(x);
>               } else
>                       fmt_set_param(0, &n, fmt_int, 0);
>               i = ctl_index;
>               for (done = FALSE;;  --n) {
>                       j = fmt_skip();
>                       for (k = j;  ctl_string[--k] != '~';)
>                               ;
>                       if (n == 0) {
>                               fmt_save;
>                               format(fmt_stream, ctl_origin + i, k - i);
>                               fmt_restore1;
>                               done = TRUE;
>                       }
>                       i = j;
>                       if (ctl_string[--j] == ']') {
>                               if (ctl_string[--j] != '~')
>                                       fmt_error("~] expected");
>                               return;
>                       }
>                       if (ctl_string[j] == ';') {
>                               if (ctl_string[--j] == '~')
>                                       continue;
>                               if (ctl_string[j] == ':')
>                                       goto ELSE;
>                       }
>                       fmt_error("~; or ~] expected");
>               }
>       ELSE:
>               if (ctl_string[--j] != '~')
>                       fmt_error("~:; expected");
>               j = fmt_skip();
>               if (ctl_string[--j] != ']' || ctl_string[--j] != '~')
>                       fmt_error("~] expected");
>               if (!done) {
>                       fmt_save;
>                       format(fmt_stream, ctl_origin + i, j - i);
>                       fmt_restore1;
>               }
>       }
> }     
> 
> static void
> fmt_iteration(bool colon, bool atsign) {
>       int i,n=0;
>       VOL int j;
>       int o;
>       bool colon_close = FALSE;
>       object l;
>       VOL object l0;
>       fmt_old;
>       jmp_buf fmt_jmp_buf0;
>       int up_colon;
> 
>       /* to prevent longjmp clobber */
>       up_colon=(long)&old_fmt_paramp;
>       fmt_max_param(1);
>       fmt_set_param(0, &n, fmt_int, 1000000);
>       i = ctl_index;
>       j = fmt_skip();
>       if (ctl_string[--j] != '}')
>               fmt_error("~} expected");
>       if (ctl_string[--j] == ':') {
>               colon_close = TRUE;
>               --j;
>       }
>       if (ctl_string[j] != '~')
>               fmt_error("syntax error");
>       o = ctl_origin;
>       if (!colon && !atsign) {
>               l = fmt_advance();
>               fmt_save;
>               fmt_base = vs_top;
>               fmt_index = 0;
>               for (fmt_end = 0;  !endp(l);  fmt_end++, l = l->c.c_cdr)
>                       vs_check_push(l->c.c_car);
>               fmt_jmp_bufp = &fmt_jmp_buf0;
>               if (colon_close)
>                       goto L1;
>               while (fmt_index < fmt_end) {
>               L1:
>                       if (n-- <= 0)
>                               break;
>                       if ((up_colon = setjmp(*fmt_jmp_bufp))) {
>                               if (--up_colon)
>                                       fmt_error("illegal ~:^");
>                               break;
>                       }
>                       format(fmt_stream, o + i, j - i);
>               }
>               vs_top = fmt_base;
>               fmt_restore;
>       } else if (colon && !atsign) {
>               l0 = fmt_advance();
>               fmt_save;
>               fmt_base = vs_top;
>               fmt_jmp_bufp = &fmt_jmp_buf0;
>               if (colon_close)
>                       goto L2;
>               while (!endp(l0)) {
>               L2:
>                       if (n-- <= 0)
>                               break;
>                       l = l0->c.c_car;
>                       l0 = l0->c.c_cdr;
>                       fmt_index = 0;
>                       for (fmt_end = 0; !endp(l); fmt_end++, l = l->c.c_cdr)
>                               vs_check_push(l->c.c_car);
>                       if ((up_colon = setjmp(*fmt_jmp_bufp))) {
>                               vs_top = fmt_base;
>                               if (--up_colon)
>                                       break;
>                               else
>                                       continue;
>                       }
>                       format(fmt_stream, o + i, j - i);
>                       vs_top = fmt_base;
>               }
>               fmt_restore;
>       } else if (!colon && atsign) {
>               fmt_save;
>               fmt_jmp_bufp = &fmt_jmp_buf0;
>               if (colon_close)
>                       goto L3;
>               while (fmt_index < fmt_end) {
>               L3:
>                       if (n-- <= 0)
>                               break;
>                       if ((up_colon = setjmp(*fmt_jmp_bufp))) {
>                               if (--up_colon)
>                                       fmt_error("illegal ~:^");
>                               break;
>                       }
>                       format(fmt_stream, o + i, j - i);
>               }
>               fmt_restore1;
>       } else if (colon && atsign) {
>               if (colon_close)
>                       goto L4;
>               while (fmt_index < fmt_end) {
>               L4:
>                       if (n-- <= 0)
>                               break;
>                       l = fmt_advance();
>                       fmt_save;
>                       fmt_base = vs_top;
>                       fmt_index = 0;
>                       for (fmt_end = 0; !endp(l); fmt_end++, l = l->c.c_cdr)
>                               vs_check_push(l->c.c_car);
>                       fmt_jmp_bufp = &fmt_jmp_buf0;
>                       if ((up_colon = setjmp(*fmt_jmp_bufp))) {
>                               vs_top = fmt_base;
>                               fmt_restore;
>                               if (--up_colon)
>                                       break;
>                               else
>                                       continue;
>                       }
>                       format(fmt_stream, o + i, j - i);
>                       vs_top = fmt_base;
>                       fmt_restore;
>               }
>       }
> }
> 
> #define FORMAT_DIRECTIVE_LIMIT 100
> 
> static void
> fmt_justification(volatile bool colon, bool atsign)
> {
>       int mincol=0, colinc=0, minpad=0, padchar=0;
>       object fields[FORMAT_DIRECTIVE_LIMIT];
>       fmt_old;
>       jmp_buf fmt_jmp_buf0;
>       VOL int i,j,n,j0;
>       int k,l,m,l0;
>       int up_colon;
>       VOL int special = 0;
>       volatile int spare_spaces=0, line_length=0;
>       vs_mark;
> 
>       /* to prevent longjmp clobber */
>       up_colon=(long)&old_fmt_paramp;
>       fmt_max_param(4);
>       fmt_set_param(0, &mincol, fmt_int, 0);
>       fmt_set_param(1, &colinc, fmt_int, 1);
>       fmt_set_param(2, &minpad, fmt_int, 0);
>       fmt_set_param(3, &padchar, fmt_char, ' ');
> 
>       n = 0;
>       for (;;) {
>               if (n >= FORMAT_DIRECTIVE_LIMIT)
>                       fmt_error("too many fields");
>               i = ctl_index;
>               j0 = j = fmt_skip();
>               while (ctl_string[--j] != '~')
>                       ;
>               fields[n] = make_string_output_stream(64);
>               vs_push(fields[n]);
>               fmt_save;
>               fmt_jmp_bufp = &fmt_jmp_buf0;
>               if ((up_colon = setjmp(*fmt_jmp_bufp))) {
>                       --n;
>                       if (--up_colon)
>                               fmt_error("illegal ~:^");
>                       fmt_restore1;
>                       while (ctl_string[--j0] != '>')
>                               j0 = fmt_skip();
>                       if (ctl_string[j0-1] == '@') {
>                           j0--;
>                           if (ctl_string[j0-1] == ':') j0--;
>                       } else
>                       if (ctl_string[j0-1] == ':') {
>                           j0--;
>                           if (ctl_string[j0-1] == '@') j0--;
>                       }
>                       if (ctl_string[--j0] != '~')
>                               fmt_error("~> expected");
>                       break;
>               }
>               format(fields[n++], ctl_origin + i, j - i);
>               fmt_restore1;
>               if (ctl_string[--j0] == '>') {
>                       if (ctl_string[j0-1] == '@') {
>                           j0--;
>                           if (ctl_string[j0-1] == ':') j0--;
>                       } else
>                       if (ctl_string[j0-1] == ':') {
>                           j0--;
>                           if (ctl_string[j0-1] == '@') j0--;
>                       }
>                       if (ctl_string[--j0] != '~')
>                               fmt_error("~> expected");
>                       break;
>               } else if (ctl_string[j0] != ';')
>                       fmt_error("~; expected");
>               else {
>                   if (ctl_string[j0] == '@')
>                       --j0;
>                   if (ctl_string[--j0] == ':') {
>                       if (n != 1)
>                               fmt_error("illegal ~:;");
>                       special = 1;
>                       for (j = j0;  ctl_string[j] != '~';  --j)
>                               ;
>                       fmt_save;
>                       format(fmt_stream, ctl_origin + j, j0 - j + 2);
>                       fmt_restore1;
>                       spare_spaces = fmt_spare_spaces;
>                       line_length = fmt_line_length;
>                   } else {
>                       if (ctl_string[j0] == '@')
>                           --j0;
>                       if (ctl_string[j0] != '~')
>                           fmt_error("~; expected");
>                       
> sSAprint_line_prefixA->s.s_dbind=fields[n-1]->sm.sm_object0;
>                   }
>               }
>       }
>       sSAprint_line_prefixA->s.s_dbind=Cnil;
>       for (i = special, l = 0;  i < n;  i++)
>               l += fields[i]->sm.sm_object0->st.st_fillp;
>       m = n - 1 - special;
>       if (m <= 0 && !colon && !atsign) {
>               m = 0;
>               colon = TRUE;
>       }
>       if (colon)
>               m++;
>       if (atsign)
>               m++;
>       l0 = l;
>       l += minpad * m;
>       for (k = 0;  mincol + k * colinc < l;  k++)
>               ;
>       l = mincol + k * colinc;
>       if (special != 0 &&
>           file_column(fmt_stream) + l + spare_spaces >= line_length)
>               princ(fields[0]->sm.sm_object0, fmt_stream);
>       l -= l0;
>       for (i = special;  i < n;  i++) {
>               if (m > 0 && (i > 0 || colon))
>                       for (j = l / m, l -= j, --m;  j > 0;  --j)
>                               writec_stream(padchar, fmt_stream);
>               princ(fields[i]->sm.sm_object0, fmt_stream);
>       }
>       if (atsign)
>               for (j = l;  j > 0;  --j)
>                       writec_stream(padchar, fmt_stream);
>       vs_reset;
> }
> 
> 
> static void
> fmt_up_and_out(bool colon, bool atsign)
> {
>       int i=0, j=0, k=0;
> 
>       fmt_max_param(3);
>       fmt_not_atsign(atsign);
>       if (fmt_nparam == 0) {
>               if (fmt_index >= fmt_end)
>                       longjmp(*fmt_jmp_bufp, ++colon);
>       } else if (fmt_nparam == 1) {
>               fmt_set_param(0, &i, fmt_int, 0);
>               if (i == 0)
>                       longjmp(*fmt_jmp_bufp, ++colon);
>       } else if (fmt_nparam == 2) {
>               fmt_set_param(0, &i, fmt_int, 0);
>               fmt_set_param(1, &j, fmt_int, 0);
>               if (i == j)
>                       longjmp(*fmt_jmp_bufp, ++colon);
>       } else {
>               fmt_set_param(0, &i, fmt_int, 0);
>               fmt_set_param(1, &j, fmt_int, 0);
>               fmt_set_param(2, &k, fmt_int, 0);
>               if (i <= j && j <= k)
>                       longjmp(*fmt_jmp_bufp, ++colon);
>       }
> }
> 
> 
> static void
> fmt_semicolon(bool colon, bool atsign)
> {
>       fmt_not_atsign(atsign);
>       if (!colon)
>               fmt_error("~:; expected");
>       fmt_max_param(2);
>       fmt_set_param(0, &fmt_spare_spaces, fmt_int, 0);
>       fmt_set_param(1, &fmt_line_length, fmt_int, 72);
> }
> 
> DEFUNO_NEW("FORMAT",object,fLformat,LISP
>        ,2,F_ARG_LIMIT,NONE,OO,OO,OO,OO,void,Lformat,(object strm, object 
> control,...),"")
> {       va_list ap; 
>         VOL int nargs= VFUN_NARGS;
>       VOL object x = OBJNULL;
>       jmp_buf fmt_jmp_buf0;
>       bool colon, e;
>       object *l;
>       fmt_old;
> 
>       nargs=nargs-2;
>       if (nargs < 0)
>               too_few_arguments();
>       if (strm == Cnil) {
>               strm = make_string_output_stream(64);
>               x = strm->sm.sm_object0;
>       } else if (strm == Ct)
>               strm = symbol_value(sLAstandard_outputA);
>       else if (type_of(strm) == t_string) {
>               x = strm;
>               if (!x->st.st_hasfillp)
>                 FEerror("The string ~S doesn't have a fill-pointer.", 1, x);
>               strm = make_string_output_stream(0);
>               strm->sm.sm_object0 = x;
>       } else
>               check_type_stream(&strm);
> 
>       /* check_type_string(&control); */
>       if (type_of(control) == t_string) {
>           fmt_save;
>           va_start(ap,control);
>           frs_push(FRS_PROTECT, Cnil);
>           if (nlj_active) {
>                   e = TRUE;
>                   goto L;
>           }
>       {
>           COERCE_VA_LIST(l,ap,nargs);
>           fmt_base = l;
>           fmt_index = 0;
>           fmt_end = nargs;
>           fmt_jmp_bufp = & fmt_jmp_buf0;
>           if (symbol_value(sSAindent_formatted_outputA) != Cnil)
>                   fmt_indents = file_column(strm);
>           else
>                   fmt_indents = 0;
>           fmt_string = control;
>           if ((colon = setjmp(*fmt_jmp_bufp))) {
>                   if (--colon)
>                           fmt_error("illegal ~:^");
>                   vs_base = vs_top;
>                   if (x != OBJNULL)
>                           vs_push(x);
>                   else
>                           vs_push(Cnil);
>                   e = FALSE;
>                   goto L;
>           }
>           format(strm, 0, control->st.st_fillp);
>           flush_stream(strm);
>       }
>           e = FALSE;
> L:
>           va_end(ap);
>           frs_pop();
>           fmt_restore;
>           if (e) {
>                   nlj_active = FALSE;
>                   unwind(nlj_fr, nlj_tag);
>           }
>       } else
>       switch (type_of(control)) {
>           case t_cfun:
>           case t_gfun:
>           case t_sfun:
>           case t_vfun:
>           case t_afun:
>           case t_closure:
>           case t_cclosure:
>           case t_symbol:
>           case t_cons:
>               if (nargs >= 64) FEerror("Too plong vl",0);
>           {   int i;
>               object Xxvl[65];
>               vs_mark;
>               va_start(ap,control);
>               
>               Xxvl[0] = strm;
>               for (i=1 ; i <= nargs; i++) Xxvl[i]=va_arg(ap,object);
>               va_end(ap);
>               IapplyVector(control,nargs+1,Xxvl);
>               vs_reset;
>           }
>               break;
>           default:
>               FEwrong_type_argument(sLstring,control);
>       }
>     
>     RETURN1 (x ==0 ? Cnil : x);  
> }
> 
> object 
> fLformat_1(object strm, object control,object x) {
>   VFUN_NARGS=3;
>   return FFN(fLformat)(strm,control,x);
> 
> }
> 
> /*  object c_apply_n(long int (*fn) (), int n, object *x); */
> 
> static void
> fmt_error(char *s)
> {
>       vs_push(make_simple_string(s));
>       vs_push(make_fixnum(&ctl_string[ctl_index] - fmt_string->st.st_self));
>       FEerror("Format error: address@hidden"~A\"~%",
>               3, vs_top[-2], vs_top[-1], fmt_string);
> }
> 
> DEFVAR("*INDENT-FORMATTED-OUTPUT*",sSAindent_formatted_outputA,SI,Cnil,"");
> void
> gcl_init_format(void)
> {
>       fmt_temporary_stream = make_string_output_stream(64);
>       enter_mark_origin(&fmt_temporary_stream);
>       fmt_temporary_string = fmt_temporary_stream->sm.sm_object0;
> }
> 
> 
> 

-- 
Camm Maguire                                            address@hidden
==========================================================================
"The earth is but one country, and mankind its citizens."  --  Baha'u'llah




reply via email to

[Prev in Thread] Current Thread [Next in Thread]