Article View: gnu.g++.bug
Article #931decstation cc1plus: fatal signal
From: Karl Berry
Date: Wed, 09 Sep 1992 13:51
Date: Wed, 09 Sep 1992 13:51
4000 lines
62659 bytes
62659 bytes
gcc 2.2.2 -g -O on a DECstation 3100 running Ultrix 4.2a (configured as
`decstation') gets a fatal signal on the following input.
gcc -v -O -g -c temp.cc
Reading specs from /usr/local/gnu/lib/gcc-lib/decstation/2.2.2/specs
gcc version 2.2.2
/usr/local/gnu/lib/gcc-lib/decstation/2.2.2/cpp -lang-c++ -v -undef -D__GNUC__=2 -D__GNUG__=2 -D__cplusplus -D__ANSI_COMPAT -DMIPSEL -DR3000 -DSYSTYPE_BSD -D_SYSTYPE_BSD -Dbsd4_2 -Dhost_mips -Dmips -Dultrix -Dunix -D__ANSI_COMPAT -D__MIPSEL__ -D__R3000__ -D__SYSTYPE_BSD__ -D___SYSTYPE_BSD__ -D__bsd4_2__ -D__host_mips__ -D__mips__ -D__ultrix__ -D__unix__ -D__ANSI_COMPAT -D__MIPSEL -D__R3000 -D__SYSTYPE_BSD -D___SYSTYPE_BSD -D__bsd4_2 -D__host_mips -D__mips -D__ultrix -D__unix -D__OPTIMIZE__ -g -D__LANGUAGE
_C_PLUS_PLUS__ -D__LANGUAGE_C_PLUS_PLUS -D__LANGUAGE_C__ -D__LANGUAGE_C -DLANGUAGE_C temp.cc /tmp/cca04127.i
GNU CPP version 2.2.2 [AL 1.1, MM 19] DECstation running ultrix
/usr/local/gnu/lib/gcc-lib/decstation/2.2.2/cc1plus /tmp/cca04127.i -mgpopt -quiet -dumpbase temp.cc -g -O -version -o /tmp/cca04127.s
GNU C++ version 2.2.2 [AL 1.1, MM 19] DECstation running ultrix compiled by GNU C version 2.2.1.
gcc: Internal compiler error: program cc1plus got fatal signal 11
# 1 "main.cc"
# 1 "table.h" 1
# 1 "/usr/local/gnu/lib/g++-include/stdio.h" 1 3
#pragma interface
# 1 "/usr/local/gnu/lib/g++-include/_G_config.h" 1 3
# 33 "/usr/local/gnu/lib/g++-include/stdio.h" 2 3
extern "C" {
# 1 "/usr/include/stdio.h" 1 3
# 1 "/usr/include/ansi_compat.h" 1 3
# 116 "/usr/include/ansi_compat.h" 3
# 89 "/usr/include/stdio.h" 2 3
typedef unsigned int size_t;
extern struct _iobuf {
int _cnt;
char *_ptr;
char *_base;
int _bufsiz;
short _flag;
short _file;
} _iob[3 ];
typedef struct _iobuf FILE;
typedef long fpos_t;
extern int getc( FILE *__stream );
extern int getchar( void );
extern int putc( int __c, FILE *__stream);
extern int putchar( int __c);
extern int feof( FILE *__stream );
extern int ferror( FILE *__stream );
extern int fileno( FILE *__stream );
extern int _filbuf( FILE *p);
extern int __hide__flsbuf ( unsigned char x , FILE *p);
typedef char *va_list;
extern void clearerr( FILE *__stream);
extern int fclose( FILE *__stream );
extern FILE * __hide_fdopen ( int __filedes, char *__type );
extern int fflush( FILE *__stream );
extern int fgetc( FILE *__stream );
extern int fgetpos( FILE *__stream, fpos_t *__pos );
extern char * fgets( char *__s, int __n, FILE *__stream );
extern FILE * __hide_fopen ( const char *__filename, const char *__type );
extern int __hide_fprintf ( FILE *__stream, const char *__format, ... );
extern int fputc( int __c, FILE *__stream );
extern int __hide_fputs ( const char *__s, FILE *__stream );
extern size_t __hide_fread ( void *__ptr, size_t __size,
size_t __nitems, FILE *__stream );
extern FILE * __hide_freopen ( const char *__filename, const char *__type,
FILE *__stream );
extern int __hide_fscanf ( FILE *__stream, const char *__format, ... );
extern int fseek( FILE *__stream, long __offset, int __ptrname );
extern int fsetpos( FILE *__stream, const fpos_t *__pos );
extern long __hide_ftell ( FILE *__stream );
extern size_t __hide_fwrite ( const void *__ptr, size_t __size,
size_t __nitems, FILE *__stream );
extern char * gets( char *__s );
extern void __hide_perror ( const char *__s );
extern FILE * __hide_popen (const char *__command, const char *__type );
extern int __hide_printf ( const char *__format, ... );
extern int __hide_puts ( const char *__s );
extern int remove( const char *__filename );
extern int rename( const char *__from, const char *__to );
extern void __hide_rewind ( FILE *__stream );
extern int __hide_scanf ( const char *__format, ... );
extern void __hide_setbuf ( FILE *__stream, char *__buf );
extern int __hide_setvbuf ( FILE *__stream, char *__buf,
int __type, size_t __size );
extern int __hide_sscanf ( const char *__s, const char *__format, ... );
extern FILE * tmpfile( void );
extern char * tmpnam( char *__s );
extern int ungetc( int __c, FILE *__stream );
extern int __hide_vfprintf ( FILE *__stream, const char *__format, va_list __ap );
extern int __hide_vprintf ( const char *__format, va_list __ap );
extern int __hide_vsprintf ( char *__s, const char *__format, va_list __ap);
extern char * __hide_tempnam ( const char *__dir, const char *__pfx);
extern int __hide_putw ( int __w, FILE *__stream );
extern int getw(FILE *__stream);
extern int pclose( FILE *__stream );
# 298 "/usr/include/stdio.h" 3
extern int __hide_sprintf ( char *__s, const char *__format, ... );
# 69 "/usr/local/gnu/lib/g++-include/stdio.h" 2 3
}
extern "C" {
int fclose(FILE*);
FILE* fdopen(int, const char*);
int fflush(FILE*);
int fgetc(FILE*);
char* fgets(char*, int, FILE *);
FILE* fopen(const char*, const char*);
int fprintf(FILE*, const char* ...);
int fputc(int, FILE*);
int fputs(const char*, FILE*);
unsigned int fread(void*, unsigned int , unsigned int , FILE*);
FILE* freopen(const char*, const char*, FILE*);
int fscanf(FILE*, const char* ...);
int fseek(FILE*, long, int);
long ftell(FILE *);
unsigned int fwrite(const void*, unsigned int , unsigned int , FILE*);
char* gets(char*);
int getw(FILE*);
int pclose(FILE*);
void perror(const char*);
FILE* popen(const char*, const char*);
int printf(const char* ...);
int puts(const char*);
int putw(int, FILE*);
int rewind(FILE*);
int scanf(const char* ...);
void setbuf(FILE*, char*);
void setbuffer(FILE*, char*, int);
int setlinebuf(FILE*);
int setvbuf(FILE*, char*, int, unsigned int );
int sscanf(char*, const char* ...);
FILE* tmpfile();
int ungetc(int, FILE*);
int vfprintf (...) ;
int vprintf (...) ;
int sprintf (...) ;
int vsprintf (...) ;
extern int _filbuf (...) ;
extern int _flsbuf (...) ;
}
# 21 "table.h" 2
# 1 "/usr/local/gnu/lib/g++-include/stdlib.h" 1 3
# 1 "/usr/local/gnu/lib/g++-include/stddef.h" 1 3
extern "C" {
# 1 "/usr/local/gnu/lib/gcc-lib/decstation/2.2.2/include/stddef.h" 1 3
typedef long int ptrdiff_t;
# 87 "/usr/local/gnu/lib/gcc-lib/decstation/2.2.2/include/stddef.h" 3
typedef int wchar_t;
# 7 "/usr/local/gnu/lib/g++-include/stddef.h" 2 3
}
# 6 "/usr/local/gnu/lib/g++-include/stdlib.h" 2 3
extern "C" {
int abs(int);
void volatile abort(void);
double atof(const char*);
int atoi(const char*);
long atol(const char*);
int atexit(auto void (*p) (void));
int bsearch (const void *, const void *, unsigned int ,
unsigned int , auto int (*ptf)(const void*, const void*));
void* calloc(unsigned int , unsigned int );
void cfree(void*);
void volatile exit(int);
char* fcvt(double, int, int*, int*);
void free(void*);
char* getenv(const char*);
int getopt(int, char * const *, const char*);
int getpw(int, char*);
char* gcvt(double, int, char*);
char* ecvt(double, int, int*, int*);
extern char** environ;
long labs(long);
void* malloc(unsigned int );
unsigned int malloc_usable_size(void*);
int putenv(const char*);
extern char* optarg;
extern int opterr;
extern int optind;
void qsort(void*, unsigned int , unsigned int , auto int (*ptf)(void*,void*));
int rand(void);
void* realloc(void*, unsigned int );
int setkey(const char*);
int srand(unsigned int);
double strtod(const char*, char**);
long strtol(const char*, char**, int);
unsigned long stroul(const char**, int);
int system(const char*);
long random(void);
void srandom(int);
char* setstate(char*);
char* initstate(unsigned, char*, int);
double drand48(void);
void lcong48(short*);
long jrand48(short*);
long lrand48(void);
long mrand48(void);
long nrand48(short*);
short* seed48(short*);
void srand48(long);
char* ctermid(char*);
char* cuserid(char*);
char* tempnam(const char*, const char*);
char* tmpnam(char*);
}
# 22 "table.h" 2
# 1 "../include/assert.h" 1 3
volatile
void assertion_failed(int, const char *);
inline void do_assert(int expr, int line, const char *file)
{
if (!expr)
assertion_failed(line, file);
}
# 23 "table.h" 2
# 1 "/usr/local/gnu/lib/g++-include/ctype.h" 1 3
extern "C" {
# 1 "/usr/include/ctype.h" 1 3
extern unsigned short *_pctype;
extern unsigned short _ctype__[];
int isalnum( int __c );
int isalpha( int __c );
int isascii( int __c );
int iscntrl( int __c );
int isdigit( int __c );
int isgraph( int __c );
int islower( int __c );
int isprint( int __c );
int ispunct( int __c );
int isspace( int __c );
int isupper( int __c );
int isxdigit( int __c );
int toascii( int __c );
int _tolower( int __c );
int _toupper( int __c );
int tolower( int __c );
int toupper( int __c );
# 3 "/usr/local/gnu/lib/g++-include/ctype.h" 2 3
extern int toupper (...) ;
extern int tolower (...) ;
}
# 24 "table.h" 2
# 1 "/usr/local/gnu/lib/g++-include/errno.h" 1 3
extern "C" {
# 1 "/usr/include/errno.h" 1 3
extern int errno;
# 9 "/usr/local/gnu/lib/g++-include/errno.h" 2 3
extern char* sys_errlist[];
extern int sys_nerr;
extern int errno;
void perror(const char*);
char* strerr(int);
}
# 25 "table.h" 2
# 1 "../include/cset.h" 1
# 1 "/usr/local/gnu/lib/gcc-lib/decstation/2.2.2/include/limits.h" 1 3
# 1 "/usr/include/limits.h" 1 3
# 1 "/usr/include/ansi_compat.h" 1 3
# 116 "/usr/include/ansi_compat.h" 3
# 123 "/usr/include/limits.h" 2 3
# 228 "/usr/include/limits.h" 3
# 4 "/usr/local/gnu/lib/gcc-lib/decstation/2.2.2/include/limits.h" 2 3
# 22 "../include/cset.h" 2
enum cset_builtin { CSET_BUILTIN };
class cset {
public:
cset();
cset(cset_builtin);
cset(const char *);
cset(const unsigned char *);
int operator()(unsigned char) const;
cset &operator|=(const cset &);
cset &operator|=(unsigned char);
friend class cset_init;
private:
char v[255 +1];
void clear();
};
inline int cset::operator()(unsigned char c) const
{
return v[c];
}
inline cset &cset::operator|=(unsigned char c)
{
v[c] = 1;
return *this;
}
extern cset csalpha;
extern cset csupper;
extern cset cslower;
extern cset csdigit;
extern cset csxdigit;
extern cset csspace;
extern cset cspunct;
extern cset csalnum;
extern cset csprint;
extern cset csgraph;
extern cset cscntrl;
static class cset_init {
static int initialised;
public:
cset_init();
} _cset_init;
# 27 "table.h" 2
# 1 "../include/cmap.h" 1
enum cmap_builtin { CMAP_BUILTIN };
class cmap {
public:
cmap();
cmap(cmap_builtin);
int operator()(unsigned char) const;
unsigned char &operator[](unsigned char);
friend class cmap_init;
private:
unsigned char v[255 +1];
};
inline int cmap::operator()(unsigned char c) const
{
return v[c];
}
inline unsigned char &cmap::operator[](unsigned char c)
{
return v[c];
}
extern cmap cmlower;
extern cmap cmupper;
static class cmap_init {
static int initialised;
public:
cmap_init();
} _cmap_init;
# 28 "table.h" 2
# 1 "../include/stringclass.h" 1
# 1 "/usr/local/gnu/lib/g++-include/string.h" 1 3
extern "C" {
char* strcat(char*, const char*);
char* strchr(const char*, int);
int strcmp(const char*, const char*);
int strcoll(const char*, const char*);
char* strcpy(char*, const char*);
unsigned int strcspn(const char*, const char*);
char* strdup(const char*);
unsigned int strlen(const char*);
char* strncat(char*, const char*, unsigned int );
int strncmp(const char*, const char*, unsigned int );
char* strncpy(char*, const char*, unsigned int );
char* strpbrk(const char*, const char*);
char* strrchr(const char*, int);
unsigned int strspn(const char*, const char*);
char* strstr(const char*, const char *);
char* strtok(char*, const char*);
unsigned int strxfrm(char*, const char*, unsigned int );
char* index(const char*, int);
char* rindex(const char*, int);
}
# 1 "/usr/local/gnu/lib/g++-include/memory.h" 1 3
extern "C" {
void* memalign (...) ;
void* memccpy (...) ;
void* memchr (...) ;
int memcmp (...) ;
void* memcpy (...) ;
void* memmove (...) ;
void* memset (...) ;
int ffs (...) ;
unsigned int getpagesize (...) ;
void* valloc (...) ;
void bcopy (...) ;
int bcmp (...) ;
void bzero (...) ;
}
# 43 "/usr/local/gnu/lib/g++-include/string.h" 2 3
# 21 "../include/stringclass.h" 2
# 1 "/usr/local/gnu/lib/g++-include/stdio.h" 1 3
# 174 "/usr/local/gnu/lib/g++-include/stdio.h" 3
# 22 "../include/stringclass.h" 2
# 1 "../include/assert.h" 1 3
# 33 "../include/assert.h" 3
# 23 "../include/stringclass.h" 2
class string {
public:
string();
string(const string &);
string(const char *);
string(const char *, int);
string(char);
~string();
string &operator=(const string &);
string &operator=(const char *);
string &operator=(char);
string &operator+=(const string &);
string &operator+=(const char *);
string &operator+=(char);
void append(const char *, int);
int length() const;
int empty() const;
int operator*() const;
string substring(int i, int n) const;
char &operator[](int);
char operator[](int) const;
void set_length(int i);
const char *contents() const;
int search(char) const;
char *extract() const;
void clear();
void move(string &);
friend string operator+(const string &, const string &);
friend string operator+(const string &, const char *);
friend string operator+(const char *, const string &);
friend string operator+(const string &, char);
friend string operator+(char, const string &);
friend int operator==(const string &, const string &);
friend int operator!=(const string &, const string &);
friend int operator<=(const string &, const string &);
friend int operator<(const string &, const string &);
friend int operator>=(const string &, const string &);
friend int operator>(const string &, const string &);
private:
char *ptr;
int len;
int sz;
string(const char *, int, const char *, int);
void grow1();
};
inline char &string::operator[](int i)
{
do_assert(i >= 0 && i < len, 85, "../include/stringclass.h") ;
return ptr[i];
}
inline char string::operator[](int i) const
{
do_assert(i >= 0 && i < len, 91, "../include/stringclass.h") ;
return ptr[i];
}
inline int string::length() const
{
return len;
}
inline int string::empty() const
{
return len == 0;
}
inline int string::operator*() const
{
return len;
}
inline const char *string::contents() const
{
return ptr;
}
inline string operator+(const string &s1, const string &s2)
{
return string(s1.ptr, s1.len, s2.ptr, s2.len);
}
inline string operator+(const string &s1, const char *s2)
{
if (s2 == 0)
return s1;
else
return string(s1.ptr, s1.len, s2, strlen(s2));
}
inline string operator+(const char *s1, const string &s2)
{
if (s1 == 0)
return s2;
else
return string(s1, strlen(s1), s2.ptr, s2.len);
}
inline string operator+(const string &s, char c)
{
return string(s.ptr, s.len, &c, 1);
}
inline string operator+(char c, const string &s)
{
return string(&c, 1, s.ptr, s.len);
}
inline int operator==(const string &s1, const string &s2)
{
return (s1.len == s2.len
&& (s1.len == 0 || memcmp(s1.ptr, s2.ptr, s1.len) == 0));
}
inline int operator!=(const string &s1, const string &s2)
{
return (s1.len != s2.len
|| (s1.len != 0 && memcmp(s1.ptr, s2.ptr, s1.len) != 0));
}
inline string string::substring(int i, int n) const
{
do_assert(i >= 0 && i + n <= len, 160, "../include/stringclass.h") ;
return string(ptr + i, n);
}
inline string &string::operator+=(char c)
{
if (len >= sz)
grow1();
ptr[len++] = c;
return *this;
}
void put_string(const string &, FILE *);
string as_string(int);
# 29 "table.h" 2
# 1 "../include/errarg.h" 1
class errarg {
enum { EMPTY, STRING, CHAR, INTEGER, DOUBLE } type;
union {
const char *s;
int n;
char c;
double d;
};
public:
errarg();
errarg(const char *);
errarg(char);
errarg(unsigned char);
errarg(int);
errarg(double);
int empty() const;
void print() const;
};
extern errarg empty_errarg;
extern void errprint(const char *,
const errarg &arg1 = empty_errarg,
const errarg &arg2 = empty_errarg,
const errarg &arg3 = empty_errarg);
# 30 "table.h" 2
# 1 "../include/error.h" 1
extern void fatal_with_file_and_line(const char *filename, int lineno,
const char *format,
const errarg &arg1 = empty_errarg,
const errarg &arg2 = empty_errarg,
const errarg &arg3 = empty_errarg);
extern void error_with_file_and_line(const char *filename, int lineno,
const char *format,
const errarg &arg1 = empty_errarg,
const errarg &arg2 = empty_errarg,
const errarg &arg3 = empty_errarg);
extern void warning_with_file_and_line(const char *filename, int lineno,
const char *format,
const errarg &arg1 = empty_errarg,
const errarg &arg2 = empty_errarg,
const errarg &arg3 = empty_errarg);
extern void fatal(const char *,
const errarg &arg1 = empty_errarg,
const errarg &arg2 = empty_errarg,
const errarg &arg3 = empty_errarg);
extern void error(const char *,
const errarg &arg1 = empty_errarg,
const errarg &arg2 = empty_errarg,
const errarg &arg3 = empty_errarg);
extern void warning(const char *,
const errarg &arg1 = empty_errarg,
const errarg &arg2 = empty_errarg,
const errarg &arg3 = empty_errarg);
extern const char *program_name;
extern int current_lineno;
extern const char *current_filename;
# 31 "table.h" 2
# 1 "../include/lib.h" 1
extern "C" {
char *strerror(int);
const char *itoa(int);
const char *iftoa(int, int);
};
char *strsave(const char *s);
int is_prime(unsigned);
# 1 "/usr/local/gnu/lib/g++-include/stdio.h" 1 3
# 174 "/usr/local/gnu/lib/g++-include/stdio.h" 3
# 41 "../include/lib.h" 2
FILE *xtmpfile();
int interpret_lf_args(const char *p);
extern char illegal_char_table[];
inline int illegal_input_char(int c)
{
return c >= 0 && illegal_char_table[c];
}
# 1 "/usr/local/gnu/lib/gcc-lib/decstation/2.2.2/include/limits.h" 1 3
# 88 "/usr/local/gnu/lib/gcc-lib/decstation/2.2.2/include/limits.h" 3
# 55 "../include/lib.h" 2
# 32 "table.h" 2
struct inc_number {
short inc;
short val;
};
struct entry_modifier {
inc_number point_size;
inc_number vertical_spacing;
string font;
enum { CENTER, TOP, BOTTOM } vertical_alignment;
char zero_width;
char stagger;
entry_modifier();
~entry_modifier();
};
enum format_type {
FORMAT_LEFT,
FORMAT_CENTER,
FORMAT_RIGHT,
FORMAT_NUMERIC,
FORMAT_ALPHABETIC,
FORMAT_SPAN,
FORMAT_VSPAN,
FORMAT_HLINE,
FORMAT_DOUBLE_HLINE
};
struct entry_format : entry_modifier {
format_type type;
entry_format(format_type);
entry_format();
void debug_print() const;
};
struct table_entry;
struct horizontal_span;
struct stuff;
struct vertical_rule;
class table {
unsigned flags;
int nrows;
int ncolumns;
int linesize;
char delim[2];
vertical_rule *vrule_list;
stuff *stuff_list;
horizontal_span *span_list;
table_entry *entry_list;
table_entry ***entry;
char **vline;
char *row_is_all_lines;
string *minimum_width;
int *column_separation;
char *equal;
int left_separation;
int right_separation;
int allocated_rows;
void build_span_list();
void do_hspan(int r, int c);
void do_vspan(int r, int c);
void allocate(int r);
void compute_widths();
void divide_span(int, int);
void sum_columns(int, int);
void compute_separation_factor();
void compute_column_positions();
void do_row(int);
void init_output();
void add_stuff(stuff *);
void do_top();
void do_bottom();
void do_vertical_rules();
void build_vrule_list();
void add_vertical_rule(int, int, int, int);
void define_bottom_macro();
int vline_spanned(int r, int c);
int row_begins_section(int);
int row_ends_section(int);
void make_columns_equal();
void compute_vrule_top_adjust(int, int, string &);
void compute_vrule_bot_adjust(int, int, string &);
void determine_row_type();
public:
enum {
CENTER = 01,
EXPAND = 02,
BOX = 04,
ALLBOX = 010,
DOUBLEBOX = 020
};
table(int nc, unsigned flags, int linesize);
~table();
void add_text_line(int r, const string &, const char *, int);
void add_single_hline(int r);
void add_double_hline(int r);
void add_entry(int r, int c, const string &, const entry_format *,
const char *, int lineno);
void add_vlines(int r, const char *);
void check();
void print();
void set_minimum_width(int c, const string &w);
void set_column_separation(int c, int n);
void set_equal_column(int c);
void set_delim(char c1, char c2);
void print_single_hline(int r);
void print_double_hline(int r);
int get_nrows();
};
void set_troff_location(const char *, int);
# 21 "main.cc" 2
static int compatible_flag = 0;
class table_input {
FILE *fp;
enum { START, MIDDLE, REREAD_T, REREAD_TE, REREAD_E, END, ERROR } state;
string unget_stack;
public:
table_input(FILE *);
int get();
int ended() { return unget_stack.empty() && state == END; }
void unget(char);
};
table_input::table_input(FILE *p)
: fp(p), state(START)
{
}
void table_input::unget(char c)
{
do_assert(c != '\0', 46, "main.cc") ;
unget_stack += c;
if (c == '\n')
current_lineno--;
}
int table_input::get()
{
int len = unget_stack.length();
if (len != 0) {
unsigned char c = unget_stack[len - 1];
unget_stack.set_length(len - 1);
if (c == '\n')
current_lineno++;
return c;
}
int c;
for (;;) {
switch (state) {
case START:
if ((c = (--(fp)->_cnt>=0? *(fp)->_ptr++&0377:_filbuf(fp)) ) == '.') {
if ((c = (--(fp)->_cnt>=0? *(fp)->_ptr++&0377:_filbuf(fp)) ) == 'T') {
if ((c = (--(fp)->_cnt>=0? *(fp)->_ptr++&0377:_filbuf(fp)) ) == 'E') {
if (compatible_flag) {
state = END;
return (-1) ;
}
else {
c = (--(fp)->_cnt>=0? *(fp)->_ptr++&0377:_filbuf(fp)) ;
if (c != (-1) )
ungetc(c, fp);
if (c == (-1) || c == ' ' || c == '\n') {
state = END;
return (-1) ;
}
state = REREAD_TE;
return '.';
}
}
else {
if (c != (-1) )
ungetc(c, fp);
state = REREAD_T;
return '.';
}
}
else {
if (c != (-1) )
ungetc(c, fp);
state = MIDDLE;
return '.';
}
}
else if (c == (-1) ) {
state = ERROR;
return (-1) ;
}
else {
if (c == '\n')
current_lineno++;
else {
state = MIDDLE;
if (c == '\0') {
error("illegal input character code 0");
break;
}
}
return c;
}
break;
case MIDDLE:
if ((c = (--(fp)->_cnt>=0? *(fp)->_ptr++&0377:_filbuf(fp)) ) == '\\') {
c = (--(fp)->_cnt>=0? *(fp)->_ptr++&0377:_filbuf(fp)) ;
if (c == '\n')
c = (--(fp)->_cnt>=0? *(fp)->_ptr++&0377:_filbuf(fp)) ;
else {
if (c != (-1) )
ungetc(c, fp);
c = '\\';
}
}
if (c == (-1) ) {
state = ERROR;
return (-1) ;
}
else {
if (c == '\n') {
state = START;
current_lineno++;
}
else if (c == '\0') {
error("illegal input character code 0");
break;
}
return c;
}
case REREAD_T:
state = MIDDLE;
return 'T';
case REREAD_TE:
state = REREAD_E;
return 'T';
case REREAD_E:
state = MIDDLE;
return 'E';
case END:
case ERROR:
return (-1) ;
}
}
}
void process_input_file(FILE *);
void process_table(table_input &in);
void process_input_file(FILE *fp)
{
enum { START, MIDDLE, HAD_DOT, HAD_T, HAD_TS, HAD_l, HAD_lf } state;
state = START;
int c;
while ((c = (--(fp)->_cnt>=0? *(fp)->_ptr++&0377:_filbuf(fp)) ) != (-1) )
switch (state) {
case START:
if (c == '.')
state = HAD_DOT;
else {
if (c == '\n')
current_lineno++;
else
state = MIDDLE;
(--((&_iob[1]) )->_cnt>=0? ((int)(*(unsigned char *)((&_iob[1]) )->_ptr++=(c))): _flsbuf((unsigned char)(c),(&_iob[1]) )) ;
}
break;
case MIDDLE:
if (c == '\n') {
current_lineno++;
state = START;
}
(--((&_iob[1]) )->_cnt>=0? ((int)(*(unsigned char *)((&_iob[1]) )->_ptr++=(c))): _flsbuf((unsigned char)(c),(&_iob[1]) )) ;
break;
case HAD_DOT:
if (c == 'T')
state = HAD_T;
else if (c == 'l')
state = HAD_l;
else {
(--((&_iob[1]) )->_cnt>=0? ((int)(*(unsigned char *)((&_iob[1]) )->_ptr++=('.'))): _flsbuf((unsigned char)('.'),(&_iob[1]) )) ;
(--((&_iob[1]) )->_cnt>=0? ((int)(*(unsigned char *)((&_iob[1]) )->_ptr++=(c))): _flsbuf((unsigned char)(c),(&_iob[1]) )) ;
if (c == '\n') {
current_lineno++;
state = START;
}
else
state = MIDDLE;
}
break;
case HAD_T:
if (c == 'S')
state = HAD_TS;
else {
(--((&_iob[1]) )->_cnt>=0? ((int)(*(unsigned char *)((&_iob[1]) )->_ptr++=('.'))): _flsbuf((unsigned char)('.'),(&_iob[1]) )) ;
(--((&_iob[1]) )->_cnt>=0? ((int)(*(unsigned char *)((&_iob[1]) )->_ptr++=('T'))): _flsbuf((unsigned char)('T'),(&_iob[1]) )) ;
(--((&_iob[1]) )->_cnt>=0? ((int)(*(unsigned char *)((&_iob[1]) )->_ptr++=(c))): _flsbuf((unsigned char)(c),(&_iob[1]) )) ;
if (c == '\n') {
current_lineno++;
state = START;
}
else
state = MIDDLE;
}
break;
case HAD_TS:
if (c == ' ' || c == '\n' || compatible_flag) {
(--((&_iob[1]) )->_cnt>=0? ((int)(*(unsigned char *)((&_iob[1]) )->_ptr++=('.'))): _flsbuf((unsigned char)('.'),(&_iob[1]) )) ;
(--((&_iob[1]) )->_cnt>=0? ((int)(*(unsigned char *)((&_iob[1]) )->_ptr++=('T'))): _flsbuf((unsigned char)('T'),(&_iob[1]) )) ;
(--((&_iob[1]) )->_cnt>=0? ((int)(*(unsigned char *)((&_iob[1]) )->_ptr++=('S'))): _flsbuf((unsigned char)('S'),(&_iob[1]) )) ;
while (c != '\n') {
if (c == (-1) ) {
error("end of file at beginning of table");
return;
}
(--((&_iob[1]) )->_cnt>=0? ((int)(*(unsigned char *)((&_iob[1]) )->_ptr++=(c))): _flsbuf((unsigned char)(c),(&_iob[1]) )) ;
c = (--(fp)->_cnt>=0? *(fp)->_ptr++&0377:_filbuf(fp)) ;
}
(--((&_iob[1]) )->_cnt>=0? ((int)(*(unsigned char *)((&_iob[1]) )->_ptr++=('\n'))): _flsbuf((unsigned char)('\n'),(&_iob[1]) )) ;
current_lineno++;
{
table_input input(fp);
process_table(input);
set_troff_location(current_filename, current_lineno);
if (input.ended()) {
fputs(".TE", (&_iob[1]) );
while ((c = (--(fp)->_cnt>=0? *(fp)->_ptr++&0377:_filbuf(fp)) ) != '\n') {
if (c == (-1) ) {
(--((&_iob[1]) )->_cnt>=0? ((int)(*(unsigned char *)((&_iob[1]) )->_ptr++=('\n'))): _flsbuf((unsigned char)('\n'),(&_iob[1]) )) ;
return;
}
(--((&_iob[1]) )->_cnt>=0? ((int)(*(unsigned char *)((&_iob[1]) )->_ptr++=(c))): _flsbuf((unsigned char)(c),(&_iob[1]) )) ;
}
(--((&_iob[1]) )->_cnt>=0? ((int)(*(unsigned char *)((&_iob[1]) )->_ptr++=('\n'))): _flsbuf((unsigned char)('\n'),(&_iob[1]) )) ;
current_lineno++;
}
}
state = START;
}
else {
fputs(".TS", (&_iob[1]) );
(--((&_iob[1]) )->_cnt>=0? ((int)(*(unsigned char *)((&_iob[1]) )->_ptr++=(c))): _flsbuf((unsigned char)(c),(&_iob[1]) )) ;
state = MIDDLE;
}
break;
case HAD_l:
if (c == 'f')
state = HAD_lf;
else {
(--((&_iob[1]) )->_cnt>=0? ((int)(*(unsigned char *)((&_iob[1]) )->_ptr++=('.'))): _flsbuf((unsigned char)('.'),(&_iob[1]) )) ;
(--((&_iob[1]) )->_cnt>=0? ((int)(*(unsigned char *)((&_iob[1]) )->_ptr++=('l'))): _flsbuf((unsigned char)('l'),(&_iob[1]) )) ;
(--((&_iob[1]) )->_cnt>=0? ((int)(*(unsigned char *)((&_iob[1]) )->_ptr++=(c))): _flsbuf((unsigned char)(c),(&_iob[1]) )) ;
if (c == '\n') {
current_lineno++;
state = START;
}
else
state = MIDDLE;
}
break;
case HAD_lf:
if (c == ' ' || c == '\n' || compatible_flag) {
string line;
while (c != (-1) ) {
line += c;
if (c == '\n') {
current_lineno++;
break;
}
c = (--(fp)->_cnt>=0? *(fp)->_ptr++&0377:_filbuf(fp)) ;
}
line += '\0';
interpret_lf_args(line.contents());
printf(".lf%s", line.contents());
state = START;
}
else {
fputs(".lf", (&_iob[1]) );
(--((&_iob[1]) )->_cnt>=0? ((int)(*(unsigned char *)((&_iob[1]) )->_ptr++=(c))): _flsbuf((unsigned char)(c),(&_iob[1]) )) ;
state = MIDDLE;
}
break;
default:
do_assert(0, 296, "main.cc") ;
}
switch(state) {
case START:
break;
case MIDDLE:
(--((&_iob[1]) )->_cnt>=0? ((int)(*(unsigned char *)((&_iob[1]) )->_ptr++=('\n'))): _flsbuf((unsigned char)('\n'),(&_iob[1]) )) ;
break;
case HAD_DOT:
fputs(".\n", (&_iob[1]) );
break;
case HAD_l:
fputs(".l\n", (&_iob[1]) );
break;
case HAD_T:
fputs(".T\n", (&_iob[1]) );
break;
case HAD_lf:
fputs(".lf\n", (&_iob[1]) );
break;
case HAD_TS:
fputs(".TS\n", (&_iob[1]) );
break;
}
if (fp != (&_iob[0]) )
fclose(fp);
}
struct options {
unsigned flags;
int linesize;
char delim[2];
char tab_char;
options();
};
options::options()
: flags(0), tab_char('\t'), linesize(0)
{
delim[0] = delim[1] = '\0';
}
int strieq(const char *p, const char *q)
{
for (; cmlower(*p) == cmlower(*q); p++, q++)
if (*p == '\0')
return 1;
return 0;
}
options *process_options(table_input &in)
{
options *opt = new options;
string line;
int level = 0;
for (;;) {
int c = in.get();
if (c == (-1) ) {
int i = line.length();
while (--i >= 0)
in.unget(line[i]);
return opt;
}
if (c == '\n') {
in.unget(c);
int i = line.length();
while (--i >= 0)
in.unget(line[i]);
return opt;
}
else if (c == '(')
level++;
else if (c == ')')
level--;
else if (c == ';' && level == 0) {
line += '\0';
break;
}
line += c;
}
if (line.empty())
return opt;
char *p = &line[0];
for (;;) {
while (csspace(*p) || *p == ',')
p++;
if (*p == '\0')
break;
char *q = p;
while (*q != ' ' && *q != '\0' && *q != '\t' && *q != ',' && *q != '(')
q++;
char *arg = 0;
if (*q != '(' && *q != '\0')
*q++ = '\0';
while (csspace(*q))
q++;
if (*q == '(') {
*q++ = '\0';
arg = q;
while (*q != ')' && *q != '\0')
q++;
if (*q == '\0')
error("missing `)'");
else
*q++ = '\0';
}
if (*p == '\0') {
if (arg)
error("argument without option");
}
else if (strieq(p, "tab")) {
if (!arg)
error("`tab' option requires argument in parentheses");
else {
if (arg[0] == '\0' || arg[1] != '\0')
error("argument to `tab' option must be a single character");
else
opt->tab_char = arg[0];
}
}
else if (strieq(p, "linesize")) {
if (!arg)
error("`linesize' option requires argument in parentheses");
else {
if (sscanf(arg, "%d", &opt->linesize) != 1)
error("bad linesize `%s'", arg);
else if (opt->linesize <= 0) {
error("linesize must be positive");
opt->linesize = 0;
}
}
}
else if (strieq(p, "delim")) {
if (!arg)
error("`delim' option requires argument in parentheses");
else if (arg[0] == '\0' || arg[1] == '\0' || arg[2] != '\0')
error("argument to `delim' option must be two characters");
else {
opt->delim[0] = arg[0];
opt->delim[1] = arg[1];
}
}
else if (strieq(p, "center") || strieq(p, "centre")) {
if (arg)
error("`center' option does not take a argument");
opt->flags |= table::CENTER;
}
else if (strieq(p, "expand")) {
if (arg)
error("`expand' option does not take a argument");
opt->flags |= table::EXPAND;
}
else if (strieq(p, "box") || strieq(p, "frame")) {
if (arg)
error("`box' option does not take a argument");
opt->flags |= table::BOX;
}
else if (strieq(p, "doublebox") || strieq(p, "doubleframe")) {
if (arg)
error("`doublebox' option does not take a argument");
opt->flags |= table::DOUBLEBOX;
}
else if (strieq(p, "allbox")) {
if (arg)
error("`allbox' option does not take a argument");
opt->flags |= table::ALLBOX;
}
else {
error("unrecognised global option `%1'", p);
}
p = q;
}
return opt;
}
entry_modifier::entry_modifier()
: vertical_alignment(CENTER), zero_width(0), stagger(0)
{
vertical_spacing.inc = vertical_spacing.val = 0;
point_size.inc = point_size.val = 0;
}
entry_modifier::~entry_modifier()
{
}
entry_format::entry_format() : type(FORMAT_LEFT)
{
}
entry_format::entry_format(format_type t) : type(t)
{
}
void entry_format::debug_print() const
{
switch (type) {
case FORMAT_LEFT:
(--( (&_iob[2]) )->_cnt>=0? ((int)(*(unsigned char *)( (&_iob[2]) )->_ptr++=('l'))): _flsbuf((unsigned char)('l'), (&_iob[2]) )) ;
break;
case FORMAT_CENTER:
(--( (&_iob[2]) )->_cnt>=0? ((int)(*(unsigned char *)( (&_iob[2]) )->_ptr++=('c'))): _flsbuf((unsigned char)('c'), (&_iob[2]) )) ;
break;
case FORMAT_RIGHT:
(--( (&_iob[2]) )->_cnt>=0? ((int)(*(unsigned char *)( (&_iob[2]) )->_ptr++=('r'))): _flsbuf((unsigned char)('r'), (&_iob[2]) )) ;
break;
case FORMAT_NUMERIC:
(--( (&_iob[2]) )->_cnt>=0? ((int)(*(unsigned char *)( (&_iob[2]) )->_ptr++=('n'))): _flsbuf((unsigned char)('n'), (&_iob[2]) )) ;
break;
case FORMAT_ALPHABETIC:
(--( (&_iob[2]) )->_cnt>=0? ((int)(*(unsigned char *)( (&_iob[2]) )->_ptr++=('a'))): _flsbuf((unsigned char)('a'), (&_iob[2]) )) ;
break;
case FORMAT_SPAN:
(--( (&_iob[2]) )->_cnt>=0? ((int)(*(unsigned char *)( (&_iob[2]) )->_ptr++=('s'))): _flsbuf((unsigned char)('s'), (&_iob[2]) )) ;
break;
case FORMAT_VSPAN:
(--( (&_iob[2]) )->_cnt>=0? ((int)(*(unsigned char *)( (&_iob[2]) )->_ptr++=('^'))): _flsbuf((unsigned char)('^'), (&_iob[2]) )) ;
break;
case FORMAT_HLINE:
(--( (&_iob[2]) )->_cnt>=0? ((int)(*(unsigned char *)( (&_iob[2]) )->_ptr++=('_'))): _flsbuf((unsigned char)('_'), (&_iob[2]) )) ;
break;
case FORMAT_DOUBLE_HLINE:
(--( (&_iob[2]) )->_cnt>=0? ((int)(*(unsigned char *)( (&_iob[2]) )->_ptr++=('='))): _flsbuf((unsigned char)('='), (&_iob[2]) )) ;
break;
default:
do_assert(0, 528, "main.cc") ;
break;
}
if (point_size.val != 0) {
(--( (&_iob[2]) )->_cnt>=0? ((int)(*(unsigned char *)( (&_iob[2]) )->_ptr++=('p'))): _flsbuf((unsigned char)('p'), (&_iob[2]) )) ;
if (point_size.inc > 0)
(--( (&_iob[2]) )->_cnt>=0? ((int)(*(unsigned char *)( (&_iob[2]) )->_ptr++=('+'))): _flsbuf((unsigned char)('+'), (&_iob[2]) )) ;
else if (point_size.inc < 0)
(--( (&_iob[2]) )->_cnt>=0? ((int)(*(unsigned char *)( (&_iob[2]) )->_ptr++=('-'))): _flsbuf((unsigned char)('-'), (&_iob[2]) )) ;
fprintf((&_iob[2]) , "%d ", point_size.val);
}
if (vertical_spacing.val != 0) {
(--( (&_iob[2]) )->_cnt>=0? ((int)(*(unsigned char *)( (&_iob[2]) )->_ptr++=('v'))): _flsbuf((unsigned char)('v'), (&_iob[2]) )) ;
if (vertical_spacing.inc > 0)
(--( (&_iob[2]) )->_cnt>=0? ((int)(*(unsigned char *)( (&_iob[2]) )->_ptr++=('+'))): _flsbuf((unsigned char)('+'), (&_iob[2]) )) ;
else if (vertical_spacing.inc < 0)
(--( (&_iob[2]) )->_cnt>=0? ((int)(*(unsigned char *)( (&_iob[2]) )->_ptr++=('-'))): _flsbuf((unsigned char)('-'), (&_iob[2]) )) ;
fprintf((&_iob[2]) , "%d ", vertical_spacing.val);
}
if (!font.empty()) {
(--( (&_iob[2]) )->_cnt>=0? ((int)(*(unsigned char *)( (&_iob[2]) )->_ptr++=('f'))): _flsbuf((unsigned char)('f'), (&_iob[2]) )) ;
put_string(font, (&_iob[2]) );
(--( (&_iob[2]) )->_cnt>=0? ((int)(*(unsigned char *)( (&_iob[2]) )->_ptr++=(' '))): _flsbuf((unsigned char)(' '), (&_iob[2]) )) ;
}
switch (vertical_alignment) {
case entry_modifier::CENTER:
break;
case entry_modifier::TOP:
(--( (&_iob[2]) )->_cnt>=0? ((int)(*(unsigned char *)( (&_iob[2]) )->_ptr++=('t'))): _flsbuf((unsigned char)('t'), (&_iob[2]) )) ;
break;
case entry_modifier::BOTTOM:
(--( (&_iob[2]) )->_cnt>=0? ((int)(*(unsigned char *)( (&_iob[2]) )->_ptr++=('d'))): _flsbuf((unsigned char)('d'), (&_iob[2]) )) ;
break;
}
if (zero_width)
(--( (&_iob[2]) )->_cnt>=0? ((int)(*(unsigned char *)( (&_iob[2]) )->_ptr++=('z'))): _flsbuf((unsigned char)('z'), (&_iob[2]) )) ;
if (stagger)
(--( (&_iob[2]) )->_cnt>=0? ((int)(*(unsigned char *)( (&_iob[2]) )->_ptr++=('u'))): _flsbuf((unsigned char)('u'), (&_iob[2]) )) ;
}
struct format {
int nrows;
int ncolumns;
int *separation;
string *width;
char *equal;
entry_format **entry;
char **vline;
format(int nr, int nc);
~format();
void add_rows(int n);
};
format::format(int nr, int nc) : nrows(nr), ncolumns(nc)
{
int i;
separation = new int[ncolumns - 1];
for (i = 0; i < ncolumns-1; i++)
separation[i] = -1;
width = new string[ncolumns];
equal = new char[ncolumns];
for (i = 0; i < ncolumns; i++)
equal[i] = 0;
entry = new entry_format *[nrows];
for (i = 0; i < nrows; i++)
entry[i] = new entry_format[ncolumns];
vline = new char*[nrows];
for (i = 0; i < nrows; i++) {
vline[i] = new char[ncolumns+1];
for (int j = 0; j < ncolumns+1; j++)
vline[i][j] = 0;
}
}
void format::add_rows(int n)
{
int i;
char **old_vline = vline;
vline = new char*[nrows + n];
for (i = 0; i < nrows; i++)
vline[i] = old_vline[i];
delete [] old_vline;
for (i = 0; i < n; i++) {
vline[nrows + i] = new char[ncolumns + 1];
for (int j = 0; j < ncolumns + 1; j++)
vline[nrows + i][j] = 0;
}
entry_format **old_entry = entry;
entry = new entry_format *[nrows + n];
for (i = 0; i < nrows; i++)
entry[i] = old_entry[i];
delete [] old_entry;
for (i = 0; i < n; i++)
entry[nrows + i] = new entry_format[ncolumns];
nrows += n;
}
format::~format()
{
delete [] separation;
delete [] width;
delete [] equal;
for (int i = 0; i < nrows; i++) {
delete [] vline[i];
delete [] entry[i];
}
delete [] vline;
delete [] entry;
}
struct input_entry_format : entry_format {
input_entry_format *next;
string width;
int separation;
int vline;
int pre_vline;
int last_column;
int equal;
input_entry_format(format_type, input_entry_format * = 0);
~input_entry_format();
void debug_print();
};
input_entry_format::input_entry_format(format_type t, input_entry_format *p)
: entry_format(t), next(p)
{
separation = -1;
last_column = 0;
vline = 0;
pre_vline = 0;
equal = 0;
}
input_entry_format::~input_entry_format()
{
}
void free_input_entry_format_list(input_entry_format *list)
{
while (list) {
input_entry_format *tem = list;
list = list->next;
delete tem;
}
}
void input_entry_format::debug_print()
{
for (int i = 0; i < pre_vline; i++)
(--( (&_iob[2]) )->_cnt>=0? ((int)(*(unsigned char *)( (&_iob[2]) )->_ptr++=('|'))): _flsbuf((unsigned char)('|'), (&_iob[2]) )) ;
entry_format::debug_print();
if (!width.empty()) {
(--( (&_iob[2]) )->_cnt>=0? ((int)(*(unsigned char *)( (&_iob[2]) )->_ptr++=('w'))): _flsbuf((unsigned char)('w'), (&_iob[2]) )) ;
(--( (&_iob[2]) )->_cnt>=0? ((int)(*(unsigned char *)( (&_iob[2]) )->_ptr++=('('))): _flsbuf((unsigned char)('('), (&_iob[2]) )) ;
put_string(width, (&_iob[2]) );
(--( (&_iob[2]) )->_cnt>=0? ((int)(*(unsigned char *)( (&_iob[2]) )->_ptr++=(')'))): _flsbuf((unsigned char)(')'), (&_iob[2]) )) ;
}
if (equal)
(--( (&_iob[2]) )->_cnt>=0? ((int)(*(unsigned char *)( (&_iob[2]) )->_ptr++=('e'))): _flsbuf((unsigned char)('e'), (&_iob[2]) )) ;
if (separation >= 0)
fprintf((&_iob[2]) , "%d", separation);
for (i = 0; i < vline; i++)
(--( (&_iob[2]) )->_cnt>=0? ((int)(*(unsigned char *)( (&_iob[2]) )->_ptr++=('|'))): _flsbuf((unsigned char)('|'), (&_iob[2]) )) ;
if (last_column)
(--( (&_iob[2]) )->_cnt>=0? ((int)(*(unsigned char *)( (&_iob[2]) )->_ptr++=(','))): _flsbuf((unsigned char)(','), (&_iob[2]) )) ;
}
format *process_format(table_input &in, options *opt,
format *current_format = 0)
{
input_entry_format *list = 0;
int c = in.get();
for (;;) {
int pre_vline = 0;
int got_format = 0;
int got_period = 0;
format_type t;
for (;;) {
if (c == (-1) ) {
error("end of input while processing format");
free_input_entry_format_list(list);
return 0;
}
switch (c) {
case 'n':
case 'N':
t = FORMAT_NUMERIC;
got_format = 1;
break;
case 'a':
case 'A':
got_format = 1;
t = FORMAT_ALPHABETIC;
break;
case 'c':
case 'C':
got_format = 1;
t = FORMAT_CENTER;
break;
case 'l':
case 'L':
got_format = 1;
t = FORMAT_LEFT;
break;
case 'r':
case 'R':
got_format = 1;
t = FORMAT_RIGHT;
break;
case 's':
case 'S':
got_format = 1;
t = FORMAT_SPAN;
break;
case '^':
got_format = 1;
t = FORMAT_VSPAN;
break;
case '_':
got_format = 1;
t = FORMAT_HLINE;
break;
case '=':
got_format = 1;
t = FORMAT_DOUBLE_HLINE;
break;
case '.':
got_period = 1;
break;
case '|':
pre_vline++;
break;
case ' ':
case '\t':
case '\n':
break;
default:
if (c == opt->tab_char)
break;
error("unrecognised format `%1'", char(c));
free_input_entry_format_list(list);
return 0;
}
if (got_period)
break;
c = in.get();
if (got_format)
break;
}
if (got_period)
break;
list = new input_entry_format(t, list);
if (pre_vline)
list->pre_vline = pre_vline;
int success = 1;
do {
switch (c) {
case 't':
case 'T':
c = in.get();
list->vertical_alignment = entry_modifier::TOP;
break;
case 'd':
case 'D':
c = in.get();
list->vertical_alignment = entry_modifier::BOTTOM;
break;
case 'u':
case 'U':
c = in.get();
list->stagger = 1;
break;
case 'z':
case 'Z':
c = in.get();
list->zero_width = 1;
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
{
int w = 0;
do {
w = w*10 + (c - '0');
c = in.get();
} while (c != (-1) && csdigit(c));
list->separation = w;
}
break;
case 'f':
case 'F':
do {
c = in.get();
} while (c == ' ' || c == '\t');
if (c == (-1) ) {
error("missing font name");
break;
}
if (c == '(') {
for (;;) {
c = in.get();
if (c == (-1) || c == ' ' || c == '\t') {
error("missing `)'");
break;
}
if (c == ')') {
c = in.get();
break;
}
list->font += char(c);
}
}
else {
list->font = c;
char cc = c;
c = in.get();
if (!csdigit(cc)
&& c != (-1) && c != ' ' && c != '\t' && c != '.' && c != '\n') {
list->font += char(c);
c = in.get();
}
}
break;
case 'v':
case 'V':
c = in.get();
list->vertical_spacing.val = 0;
list->vertical_spacing.inc = 0;
if (c == '+' || c == '-') {
list->vertical_spacing.inc = (c == '+' ? 1 : -1);
c = in.get();
}
if (c == (-1) || !csdigit(c)) {
error("`v' modifier must be followed by number");
list->vertical_spacing.inc = 0;
}
else {
do {
list->vertical_spacing.val *= 10;
list->vertical_spacing.val += c - '0';
c = in.get();
} while (c != (-1) && csdigit(c));
}
if (list->vertical_spacing.val > 72
|| list->vertical_spacing.val < -72 ) {
error("unreasonable point size");
list->vertical_spacing.val = 0;
list->vertical_spacing.inc = 0;
}
break;
case 'p':
case 'P':
c = in.get();
list->point_size.val = 0;
list->point_size.inc = 0;
if (c == '+' || c == '-') {
list->point_size.inc = (c == '+' ? 1 : -1);
c = in.get();
}
if (c == (-1) || !csdigit(c)) {
error("`p' modifier must be followed by number");
list->point_size.inc = 0;
}
else {
do {
list->point_size.val *= 10;
list->point_size.val += c - '0';
c = in.get();
} while (c != (-1) && csdigit(c));
}
if (list->point_size.val > 99
|| list->point_size.val < -99 ) {
error("unreasonable point size");
list->point_size.val = 0;
list->point_size.inc = 0;
}
break;
case 'w':
case 'W':
c = in.get();
while (c == ' ' || c == '\t')
c = in.get();
if (c == '(') {
list->width = "";
c = in.get();
while (c != ')') {
if (c == (-1) || c == '\n') {
error("missing `)'");
free_input_entry_format_list(list);
return 0;
}
list->width += c;
c = in.get();
}
c = in.get();
}
else {
if (c == '+' || c == '-') {
list->width = char(c);
c = in.get();
}
else
list->width = "";
if (c == (-1) || !csdigit(c))
error("bad argument for `w' modifier");
else {
do {
list->width += char(c);
c = in.get();
} while (c != (-1) && csdigit(c));
}
}
break;
case 'e':
case 'E':
c = in.get();
list->equal++;
break;
case '|':
c = in.get();
list->vline++;
break;
case 'B':
case 'b':
c = in.get();
list->font = "B";
break;
case 'I':
case 'i':
c = in.get();
list->font = "I";
break;
case ' ':
case '\t':
c = in.get();
break;
default:
if (c == opt->tab_char)
c = in.get();
else
success = 0;
break;
}
} while (success);
if (list->vline > 2) {
list->vline = 2;
error("more than 2 vertical bars between key letters");
}
if (c == '\n' || c == ',') {
c = in.get();
list->last_column = 1;
}
}
if (c == '.') {
do {
c = in.get();
} while (c == ' ' || c == '\t');
if (c != '\n') {
error("`.' not last character on line");
free_input_entry_format_list(list);
return 0;
}
}
if (!list) {
error("no format");
free_input_entry_format_list(list);
return 0;
}
list->last_column = 1;
input_entry_format *rev = 0;
while (list != 0) {
input_entry_format *tem = list->next;
list->next = rev;
rev = list;
list = tem;
}
list = rev;
input_entry_format *tem;
int ncolumns = 0;
int nrows = 0;
int col = 0;
for (tem = list; tem; tem = tem->next) {
if (tem->last_column) {
if (col >= ncolumns)
ncolumns = col + 1;
col = 0;
nrows++;
}
else
col++;
}
int row;
format *f;
if (current_format) {
if (ncolumns > current_format->ncolumns) {
error("cannot increase the number of columns in a continued format");
free_input_entry_format_list(list);
return 0;
}
f = current_format;
row = f->nrows;
f->add_rows(nrows);
}
else {
f = new format(nrows, ncolumns);
row = 0;
}
col = 0;
for (tem = list; tem; tem = tem->next) {
f->entry[row][col] = *tem;
if (col < ncolumns-1) {
if (tem->separation > f->separation[col]) {
if (current_format)
error("cannot change column separation in continued format");
else
f->separation[col] = tem->separation;
}
}
else if (tem->separation >= 0)
error("column separation specified for last column");
if (tem->equal && !f->equal[col]) {
if (current_format)
error("cannot change which columns are equal in continued format");
else
f->equal[col] = 1;
}
if (!tem->width.empty()) {
if (!f->width[col].empty() && f->width[col] != tem->width)
error("multiple widths for column %1", col+1);
f->width[col] = tem->width;
}
if (tem->pre_vline) {
do_assert(col == 0, 1082, "main.cc") ;
f->vline[row][col] = tem->pre_vline;
}
f->vline[row][col+1] = tem->vline;
if (tem->last_column) {
row++;
col = 0;
}
else
col++;
}
free_input_entry_format_list(list);
for (col = 0; col < ncolumns; col++) {
entry_format *e = f->entry[f->nrows-1] + col;
if (e->type != FORMAT_HLINE
&& e->type != FORMAT_DOUBLE_HLINE
&& e->type != FORMAT_SPAN)
break;
}
if (col >= ncolumns) {
error("last row of format is all lines");
delete f;
return 0;
}
return f;
}
table *process_data(table_input &in, format *f, options *opt)
{
char tab_char = opt->tab_char;
int ncolumns = f->ncolumns;
int current_row = 0;
int format_index = 0;
int give_up = 0;
enum { DATA_INPUT_LINE, TROFF_INPUT_LINE, SINGLE_HLINE, DOUBLE_HLINE } type;
table *tbl = new table(ncolumns, opt->flags, opt->linesize);
if (opt->delim[0] != '\0')
tbl->set_delim(opt->delim[0], opt->delim[1]);
for (;;) {
int c = in.get();
if (c == (-1) )
break;
if (c == '.') {
int d = in.get();
if (d != (-1) && csdigit(d)) {
in.unget(d);
type = DATA_INPUT_LINE;
}
else {
in.unget(d);
type = TROFF_INPUT_LINE;
}
}
else if (c == '_' || c == '=') {
int d = in.get();
if (d == '\n') {
if (c == '_')
type = SINGLE_HLINE;
else
type = DOUBLE_HLINE;
}
else {
in.unget(d);
type = DATA_INPUT_LINE;
}
}
else {
type = DATA_INPUT_LINE;
}
switch (type) {
case DATA_INPUT_LINE:
{
string input_entry;
if (format_index >= f->nrows)
format_index = f->nrows - 1;
while (format_index < f->nrows - 1) {
for (int c = 0; c < ncolumns; c++) {
entry_format *e = f->entry[format_index] + c;
if (e->type != FORMAT_HLINE
&& e->type != FORMAT_DOUBLE_HLINE
)
break;
}
if (c < ncolumns)
break;
for (c = 0; c < ncolumns; c++)
tbl->add_entry(current_row, c, input_entry,
f->entry[format_index] + c, current_filename,
current_lineno);
tbl->add_vlines(current_row, f->vline[format_index]);
format_index++;
current_row++;
}
entry_format *line_format = f->entry[format_index];
int col = 0;
for (;;) {
if (c == tab_char || c == '\n') {
int ln = current_lineno;
if (c == '\n')
--ln;
while (col < ncolumns
&& line_format[col].type == FORMAT_SPAN) {
tbl->add_entry(current_row, col, "", &line_format[col],
current_filename, ln);
col++;
}
if (c == '\n' && input_entry.length() == 2
&& input_entry[0] == 'T' && input_entry[1] == '{') {
input_entry = "";
ln++;
enum {
START, MIDDLE, GOT_T, GOT_RIGHT_BRACE, GOT_DOT,
GOT_l, GOT_lf, END
} state = START;
while (state != END) {
c = in.get();
if (c == (-1) )
break;
switch (state) {
case START:
if (c == 'T')
state = GOT_T;
else if (c == '.')
state = GOT_DOT;
else {
input_entry += c;
if (c != '\n')
state = MIDDLE;
}
break;
case GOT_T:
if (c == '}')
state = GOT_RIGHT_BRACE;
else {
input_entry += 'T';
input_entry += c;
state = c == '\n' ? START : MIDDLE;
}
break;
case GOT_DOT:
if (c == 'l')
state = GOT_l;
else {
input_entry += '.';
input_entry += c;
state = c == '\n' ? START : MIDDLE;
}
break;
case GOT_l:
if (c == 'f')
state = GOT_lf;
else {
input_entry += ".l";
input_entry += c;
state = c == '\n' ? START : MIDDLE;
}
break;
case GOT_lf:
if (c == ' ' || c == '\n' || compatible_flag) {
string args;
input_entry += ".lf";
while (c != (-1) ) {
args += c;
if (c == '\n')
break;
c = in.get();
}
args += '\0';
interpret_lf_args(args.contents());
args.set_length(args.length() - 1);
input_entry += args;
state = START;
}
else {
input_entry += ".lf";
input_entry += c;
state = MIDDLE;
}
break;
case GOT_RIGHT_BRACE:
if (c == '\n' || c == tab_char)
state = END;
else {
input_entry += 'T';
input_entry += '}';
input_entry += c;
state = c == '\n' ? START : MIDDLE;
}
break;
case MIDDLE:
if (c == '\n')
state = START;
input_entry += c;
break;
case END:
default:
do_assert(0, 1283, "main.cc") ;
}
}
if (c == (-1) ) {
error("end of data in middle of text block");
give_up = 1;
break;
}
}
if (col >= ncolumns) {
if (!input_entry.empty()) {
if (c == '\n')
in.unget(c);
input_entry += '\0';
error("excess data entry `%1' discarded",
input_entry.contents());
if (c == '\n')
(void)in.get();
}
}
else
tbl->add_entry(current_row, col, input_entry,
&line_format[col], current_filename, ln);
col++;
if (c == '\n')
break;
input_entry = "";
}
else
input_entry += c;
c = in.get();
if (c == (-1) )
break;
}
if (give_up)
break;
input_entry = "";
for (; col < ncolumns; col++)
tbl->add_entry(current_row, col, input_entry, &line_format[col],
current_filename, current_lineno - 1);
tbl->add_vlines(current_row, f->vline[format_index]);
current_row++;
format_index++;
}
break;
case TROFF_INPUT_LINE:
{
string line;
int ln = current_lineno;
for (;;) {
line += c;
if (c == '\n')
break;
c = in.get();
if (c == (-1) ) {
break;
}
}
tbl->add_text_line(current_row, line, current_filename, ln);
if (line.length() >= 4
&& line[0] == '.' && line[1] == 'T' && line[2] == '&') {
format *newf = process_format(in, opt, f);
if (newf == 0)
give_up = 1;
else
f = newf;
}
if (line.length() >= 3
&& line[0] == '.' && line[1] == 'f' && line[2] == 'f') {
line += '\0';
interpret_lf_args(line.contents() + 3);
}
}
break;
case SINGLE_HLINE:
tbl->add_single_hline(current_row);
break;
case DOUBLE_HLINE:
tbl->add_double_hline(current_row);
break;
default:
do_assert(0, 1364, "main.cc") ;
}
if (give_up)
break;
}
if (!give_up && current_row == 0) {
error("no real data");
give_up = 1;
}
if (give_up) {
delete tbl;
return 0;
}
for (int i = 0; i < ncolumns - 1; i++)
if (f->separation[i] >= 0)
tbl->set_column_separation(i, f->separation[i]);
for (i = 0; i < ncolumns; i++)
if (!f->width[i].empty())
tbl->set_minimum_width(i, f->width[i]);
for (i = 0; i < ncolumns; i++)
if (f->equal[i])
tbl->set_equal_column(i);
return tbl;
}
void process_table(table_input &in)
{
int c;
options *opt = 0;
format *form = 0;
table *tbl = 0;
if ((opt = process_options(in)) != 0
&& (form = process_format(in, opt)) != 0
&& (tbl = process_data(in, form, opt)) != 0) {
tbl->print();
delete tbl;
}
else {
error("giving up on this table");
while ((c = in.get()) != (-1) )
;
}
delete opt;
delete form;
if (!in.ended())
error("premature end of file");
}
static void usage()
{
fprintf((&_iob[2]) , "usage: %s [ -vC ] [ files... ]\n", program_name);
exit(1);
}
int main(int argc, char **argv)
{
program_name = argv[0];
static char stderr_buf[1024 ];
setbuf((&_iob[2]) , stderr_buf);
int opt;
while ((opt = getopt(argc, argv, "vC")) != (-1) )
switch (opt) {
case 'C':
compatible_flag = 1;
break;
case 'v':
{
extern const char *version_string;
fprintf((&_iob[2]) , "GNU tbl version %s\n", version_string);
fflush((&_iob[2]) );
break;
}
case '?':
usage();
break;
default:
do_assert(0, 1442, "main.cc") ;
}
printf(".if !\\n(.g .ab GNU tbl requires GNU troff.\n"
".if !dTS .ds TS\n"
".if !dTE .ds TE\n");
if (argc > optind) {
for (int i = optind; i < argc; i++)
if (argv[i][0] == '-' && argv[i][1] == '\0') {
current_filename = "-";
current_lineno = 1;
printf(".lf 1 -\n");
process_input_file((&_iob[0]) );
}
else {
errno = 0;
FILE *fp = fopen(argv[i], "r");
if (fp == 0) {
current_lineno = -1;
error("can't open `%1': %2", argv[i], strerror(errno));
}
else {
current_lineno = 1;
current_filename = argv[i];
printf(".lf 1 %s\n", current_filename);
process_input_file(fp);
}
}
}
else {
current_filename = "-";
current_lineno = 1;
printf(".lf 1 -\n");
process_input_file((&_iob[0]) );
}
if (((((&_iob[1]) )->_flag& 00040 )!=0) || fflush((&_iob[1]) ) < 0)
fatal("output error");
exit(0);
}
Technical Details
Message-ID:
<199209092151.AA04205@ds1.cs.umb.edu>Path:
arc1-ca.pugleaf.net!sparky!uunet!cis.ohio-state.edu!ds1.cs.umb.edu!karlShow Full Headers
Complete Article Headers
Newsgroups: gnu.g++.bug Path: arc1-ca.pugleaf.net!sparky!uunet!cis.ohio-state.edu!ds1.cs.umb.edu!karl From: karl@ds1.cs.umb.edu (Karl Berry) Subject: decstation cc1plus: fatal signal Message-ID: <199209092151.AA04205@ds1.cs.umb.edu> Sender: gnulists@ai.mit.edu Reply-To: karl@cs.umb.edu Organization: GNUs Not Usenet Distribution: gnu Date: Wed, 9 Sep 1992 13:51:59 GMT Approved: bug-g++@prep.ai.mit.edu Lines: 4001