[Top][All Lists]
[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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gcl-devel] Re: format: comma-interval bug fix,
Camm Maguire <=