staelin@PRINCETON.EDU (Carl Staelin) (05/04/89)
I have stumbled across an infinite loop in G++. I am running G++ version 1.34 on a VAX 8650 running 4.3BSD+NFS (and on a 785 running MACH). G++ was configured using "config.g++ vax". On the 8650 I let it consume over 95 minutes of CPU time to make sure that it would not complete. (of course - this is a practical application of the Halting Problem). I have included a copy of the code which crashed g++. This was generated from the original code "g++ $(C++FLAGS) -E xx.cc > xx.E.cc", and then compressed by deleting spurious information. This file was then compiled using "g++ -c xx.E.cc", and g++ infinite looped on this file. Carl Staelin staelin@princeton.edu *************************** Input File ******************************* static char rcsid[] = "$Header$"; struct flock { short l_type; short l_whence; long l_start; long l_len; short l_pid; short l_xxx; }; struct disktab { char *d_name; char *d_type; int d_secsize; int d_ntracks; int d_nsectors; int d_ncylinders; int d_rpm; int d_badsectforw; int d_sectoffset; struct partition { int p_size; short p_bsize; short p_fsize; } d_partitions[8]; }; struct disktab *getdiskbyname(); overload abs; extern void _exit (int) asm ("_" "_exit") ; extern void abort () asm ("_" "abort") ; extern int abs (int) asm ("_" "abs") ; extern int access (const char*, int) asm ("_" "access") ; extern int acct (const char*) asm ("_" "acct") ; extern unsigned alarm (unsigned) asm ("_" "alarm") ; extern void* alloca (int) asm ("_" "alloca") ; extern double atof (const char*) asm ("_" "atof") ; extern int atoi (const char*) asm ("_" "atoi") ; extern long atol (const char*) asm ("_" "atol") ; extern int bcmp (const void*, const void*, int) asm ("_" "bcmp") ; extern void bcopy (const void*, void*, int) asm ("_" "bcopy") ; extern void* brk (void*) asm ("_" "brk") ; extern void bzero (void*, int) asm ("_" "bzero") ; extern void* calloc (unsigned, unsigned) asm ("_" "calloc") ; extern void cfree (void*) asm ("_" "cfree") ; extern int chdir (const char*) asm ("_" "chdir") ; extern int chmod (const char*, int) asm ("_" "chmod") ; extern int chown (const char*, int, int) asm ("_" "chown") ; extern long clock () asm ("_" "clock") ; extern int close (int) asm ("_" "close") ; extern int creat (const char*, int) asm ("_" "creat") ; extern char* crypt (const char*, const char*) asm ("_" "crypt") ; extern char* ctermid (char*) asm ("_" "ctermid") ; extern char* cuserid (char*) asm ("_" "cuserid") ; extern double drand48 () asm ("_" "drand48") ; extern int dup (int) asm ("_" "dup") ; extern int dup2 (int, int) asm ("_" "dup2") ; extern int dysize (int) asm ("_" "dysize") ; extern char* ecvt (double, int, int*, int*) asm ("_" "ecvt") ; extern char* encrypt (char*, int) asm ("_" "encrypt") ; extern double erand (short*) asm ("_" "erand") ; extern int execl (const char*, const char *, ...) asm ("_" "execl") ; extern int execle (const char*, const char *, ...) asm ("_" "execle") ; extern int execlp (const char*, const char*, ...) asm ("_" "execlp") ; extern int exect (const char*, const char**, char**) asm ("_" "exect") ; extern int execv (const char*, const char**) asm ("_" "execv") ; extern int execve (const char*, const char**, char**) asm ("_" "execve") ; extern int execvp (const char*, const char**) asm ("_" "execvp") ; extern void exit (int) asm ("_" "exit") ; extern int fchmod (int, int) asm ("_" "fchmod") ; extern int fchown (int, int, int) asm ("_" "fchown") ; extern int fcntl (int, int, int) asm ("_" "fcntl") ; extern char* fcvt (double, int, int*, int*) asm ("_" "fcvt") ; extern int ffs (int) asm ("_" "ffs") ; extern int flock (int, int) asm ("_" "flock") ; extern int fork () asm ("_" "fork") ; extern void free (void*) asm ("_" "free") ; extern int fsync (int) asm ("_" "fsync") ; extern long ftok (const char*, int) asm ("_" "ftok") ; extern int ftruncate (int, unsigned long) asm ("_" "ftruncate") ; extern char* gcvt (double, int, char*) asm ("_" "gcvt") ; extern char* getcwd (char*, int) asm ("_" "getcwd") ; extern int getdomainname (char*, int) asm ("_" "getdomainname") ; extern int getdtablesize () asm ("_" "getdtablesize") ; extern int getegid () asm ("_" "getegid") ; extern char* getenv (const char*) asm ("_" "getenv") ; extern int geteuid () asm ("_" "geteuid") ; extern int getgid () asm ("_" "getgid") ; extern int getgroups (int, int*) asm ("_" "getgroups") ; extern long gethostid () asm ("_" "gethostid") ; extern int gethostname (char*, int) asm ("_" "gethostname") ; extern char* getlogin () asm ("_" "getlogin") ; extern int getopt (int, char**, char*) asm ("_" "getopt") ; extern int getpagesize () asm ("_" "getpagesize") ; extern char* getpass (const char*) asm ("_" "getpass") ; extern int getpgrp () asm ("_" "getpgrp") ; extern int getpid () asm ("_" "getpid") ; extern int getppid () asm ("_" "getppid") ; extern int getpriority (int, int) asm ("_" "getpriority") ; extern int getpw (int, char*) asm ("_" "getpw") ; extern unsigned getuid () asm ("_" "getuid") ; extern char* getwd (const char*) asm ("_" "getwd") ; extern char* index (const char*, int) asm ("_" "index") ; extern char* initstate (unsigned, char*, int) asm ("_" "initstate") ; extern int ioctl (int, int, char*) asm ("_" "ioctl") ; extern int isatty (int) asm ("_" "isatty") ; extern long jrand48 (short*) asm ("_" "jrand48") ; extern int kill (int, int) asm ("_" "kill") ; extern int killpg (int, int) asm ("_" "killpg") ; extern void lcong48 (short*) asm ("_" "lcong48") ; extern int link (const char*, const char*) asm ("_" "link") ; extern int lock (int, int, long) asm ("_" "lock") ; extern long lrand48 () asm ("_" "lrand48") ; extern long lseek (int, long, int) asm ("_" "lseek") ; extern void* malloc (unsigned) asm ("_" "malloc") ; extern void* memalign (unsigned, unsigned) asm ("_" "memalign") ; extern void* memccpy (void*, const void*, int, int) asm ("_" "memccpy") ; extern void* memchr (const void*, int, int) asm ("_" "memchr") ; extern int memcmp (const void*, const void*, int) asm ("_" "memcmp") ; extern void* memcpy (void*, const void*, int) asm ("_" "memcpy") ; extern void* memset (void*, int, int) asm ("_" "memset") ; extern int mkdir (const char*, int) asm ("_" "mkdir") ; extern int mknod (const char*, int, int) asm ("_" "mknod") ; extern int mkstemp (char*) asm ("_" "mkstemp") ; extern char* mktemp (char*) asm ("_" "mktemp") ; extern long mrand48 () asm ("_" "mrand48") ; extern int nice (int) asm ("_" "nice") ; extern long nrand48 (short*) asm ("_" "nrand48") ; extern int open (const char*, int, ...) asm ("_" "open") ; extern void pause () asm ("_" "pause") ; extern void perror (const char*) asm ("_" "perror") ; extern int pipe (int*) asm ("_" "pipe") ; extern void profil (char*, int, int, int) asm ("_" "profil") ; extern int psignal (unsigned, char*) asm ("_" "psignal") ; extern int ptrace (int, int, int, int) asm ("_" "ptrace") ; extern int putenv (const char*) asm ("_" "putenv") ; extern int rand () asm ("_" "rand") ; extern long random () asm ("_" "random") ; extern int read (int, void*, unsigned) asm ("_" "read") ; extern int readlink (const char*, char*, int) asm ("_" "readlink") ; extern void* realloc (void*, unsigned) asm ("_" "realloc") ; extern int rename (const char*, const char*) asm ("_" "rename") ; extern char* rindex (const char*, int) asm ("_" "rindex") ; extern int rmdir (const char*) asm ("_" "rmdir") ; extern void* sbrk (int) asm ("_" "sbrk") ; extern short* seed48 (short*) asm ("_" "seed48") ; extern int send (int, char*, int, int) asm ("_" "send") ; extern int setgid (int) asm ("_" "setgid") ; extern int sethostname (char*, int) asm ("_" "sethostname") ; extern int setkey (const char*) asm ("_" "setkey") ; extern int setpgrp (int, int) asm ("_" "setpgrp") ; extern int setpriority (int, int, int) asm ("_" "setpriority") ; extern int setregid (int, int) asm ("_" "setregid") ; extern int setreuid (int, int) asm ("_" "setreuid") ; extern char* setstate (char*) asm ("_" "setstate") ; extern int setuid (int) asm ("_" "setuid") ; extern int sigblock (int) asm ("_" "sigblock") ; extern int siginterrupt (int, int) asm ("_" "siginterrupt") ; extern int sigpause (int) asm ("_" "sigpause") ; extern int sigsetmask (int) asm ("_" "sigsetmask") ; extern unsigned sleep (unsigned) asm ("_" "sleep") ; extern int srand (int) asm ("_" "srand") ; extern void srand48 (long) asm ("_" "srand48") ; extern void srandom (int) asm ("_" "srandom") ; extern int stime (long*) asm ("_" "stime") ; extern char* strcat (char*, const char*) asm ("_" "strcat") ; extern char* strchr (const char*, int) asm ("_" "strchr") ; extern int strcmp (const char*, const char*) asm ("_" "strcmp") ; extern char* strcpy (char*, const char*) asm ("_" "strcpy") ; extern int strcspn (const char*, const char*) asm ("_" "strcspn") ; extern char* strdup (const char*) asm ("_" "strdup") ; extern int strlen (const char*) asm ("_" "strlen") ; extern char* strncat (char*, const char*, int) asm ("_" "strncat") ; extern int strncmp (const char*, const char*, int) asm ("_" "strncmp") ; extern char* strncpy (char*, const char*, int) asm ("_" "strncpy") ; extern char* strpbrk (const char*, const char*) asm ("_" "strpbrk") ; extern char* strrchr (const char*, int) asm ("_" "strrchr") ; extern int strspn (const char*, const char*) asm ("_" "strspn") ; extern double strtod (const char*, char**) asm ("_" "strtod") ; extern char* strtok (char*, const char*) asm ("_" "strtok") ; extern long strtol (const char*, char**, int) asm ("_" "strtol") ; extern void swab (void*, void*, int) asm ("_" "swab") ; extern int symlink (const char*, const char*) asm ("_" "symlink") ; extern int syscall (int, ...) asm ("_" "syscall") ; extern int system (const char*) asm ("_" "system") ; extern char* tempnam (char*, char*) asm ("_" "tempnam") ; extern int tgetent (char*, char*) asm ("_" "tgetent") ; extern int tgetnum (char*) asm ("_" "tgetnum") ; extern int tgetflag (char*) asm ("_" "tgetflag") ; extern char* tgetstr (char *, char **) asm ("_" "tgetstr") ; extern char* tgoto (char*, int, int) asm ("_" "tgoto") ; extern long time (long*) asm ("_" "time") ; extern char* tmpnam (char*) asm ("_" "tmpnam") ; extern int truncate (const char*, unsigned long) asm ("_" "truncate") ; extern char* ttyname (int) asm ("_" "ttyname") ; extern int ttyslot () asm ("_" "ttyslot") ; extern unsigned ualarm (unsigned, unsigned) asm ("_" "ualarm") ; extern long ulimit (int, long) asm ("_" "ulimit") ; extern int umask (int) asm ("_" "umask") ; extern int unlink (const char*) asm ("_" "unlink") ; extern unsigned usleep (unsigned) asm ("_" "usleep") ; extern int vadvise (int) asm ("_" "vadvise") ; extern void* valloc (unsigned) asm ("_" "valloc") ; extern int vfork () asm ("_" "vfork") ; extern int vhangup () asm ("_" "vhangup") ; extern int wait (int*) asm ("_" "wait") ; extern int write (int, const void*, unsigned) asm ("_" "write") ; extern char** environ; extern int errno; extern char* sys_errlist[]; extern int sys_nerr; extern char* optarg; extern int opterr; extern int optind; extern struct _iobuf { int _cnt; char* _ptr; char* _base; int _bufsiz; short _flag; char _file; } _iob[]; extern int _doprnt(const char*, void*, struct _iobuf *); extern int _doscan( struct _iobuf *, const char*, void*); extern int _filbuf( struct _iobuf *); extern int _flsbuf(unsigned, struct _iobuf *); extern int fclose( struct _iobuf *); extern struct _iobuf * fdopen(int, const char*); extern int fflush( struct _iobuf *); extern int fgetc( struct _iobuf *); extern char* fgets(char*, int, struct _iobuf *); extern struct _iobuf * fopen(const char*, const char*); extern int fprintf( struct _iobuf *, const char* ...); extern int fputc(int, struct _iobuf *); extern int fputs(const char*, struct _iobuf *); extern int fread(void*, int, int, struct _iobuf *); extern struct _iobuf * freopen(const char*, const char*, struct _iobuf *); extern int fscanf( struct _iobuf *, const char* ...); extern int fseek( struct _iobuf *, long, int); extern long ftell( struct _iobuf *); extern int fwrite(const void*, int, int, struct _iobuf *); extern char* gets(char*); extern int getw( struct _iobuf *); extern int pclose( struct _iobuf *); extern struct _iobuf * popen(const char*, const char*); extern int printf(const char* ...); extern void puts(const char*); extern int putw(int, struct _iobuf *); extern int scanf(const char* ...); extern void setbuf( struct _iobuf *, char*); extern void setbuffer( struct _iobuf *, char*, int); extern void setlinebuf( struct _iobuf *); extern void setvbuf( struct _iobuf *, char*, int, int); extern int sscanf(char*, const char* ...); extern struct _iobuf * tmpfile(); extern int ungetc(int, struct _iobuf *); extern int vfprintf( struct _iobuf *, const char*, void* ap); extern int vprintf(const char*, void* ap); extern int vsprintf(char*, const char*, void* ap); extern int sprintf(char*, const char* ...); overload clearbit; overload dec; overload gcd; overload hex; overload lcm; overload lg; overload oct; overload setbit; overload sign; overload sqr; overload testbit; enum bool { FALSE = 0, TRUE = 1 }; typedef void (*one_arg_error_handler_t)(const char*); typedef void (*two_arg_error_handler_t)(const char*, const char*); overload acos; overload acosh; overload asin; overload asinh; overload atan2; overload atanh; overload ceil; overload cos; overload cosh; overload exp; overload floor; overload gamma; overload hypot; overload log; overload log10; overload pow; overload sin; overload sinh; overload sqrt; overload tan; overload tanh; extern double acos (double) asm ("_" "acos") ; extern double acosh (double) asm ("_" "acosh") ; extern double asin (double) asm ("_" "asin") ; extern double asinh (double) asm ("_" "asinh") ; extern double atan (double) asm ("_" "atan") ; extern double atan2 (double, double) asm ("_" "atan2") ; extern double atanh (double) asm ("_" "atanh") ; extern double cbrt (double) asm ("_" "cbrt") ; extern double ceil (double) asm ("_" "ceil") ; extern double copysign (double,double) asm ("_" "copysign") ; extern double cos (double) asm ("_" "cos") ; extern double cosh (double) asm ("_" "cosh") ; extern double drem (double,double) asm ("_" "drem") ; extern double erf (double) asm ("_" "erf") ; extern double erfc (double) asm ("_" "erfc") ; extern double exp (double) asm ("_" "exp") ; extern double expm1 (double) asm ("_" "expm1") ; extern double fabs (double) asm ("_" "fabs") ; extern double finite (double) asm ("_" "finite") ; extern double floor (double) asm ("_" "floor") ; extern double frexp (double, int*) asm ("_" "frexp") ; extern double gamma (double) asm ("_" "gamma") ; extern double hypot (double,double) asm ("_" "hypot") ; extern double infnan (int) asm ("_" "infnan") ; extern int isinf (double) asm ("_" "isinf") ; extern int isnan (double) asm ("_" "isnan") ; extern double j0 (double) asm ("_" "j0") ; extern double j1 (double) asm ("_" "j1") ; extern double jn (int, double) asm ("_" "jn") ; extern double ldexp (double, int) asm ("_" "ldexp") ; extern double lgamma (double) asm ("_" "lgamma") ; extern double log (double) asm ("_" "log") ; extern double log10 (double) asm ("_" "log10") ; extern double log1p (double) asm ("_" "log1p") ; extern double logb (double) asm ("_" "logb") ; extern double modf (double, double*) asm ("_" "modf") ; extern double pow (double, double) asm ("_" "pow") ; extern double rint (double) asm ("_" "rint") ; extern double scalb (double, int) asm ("_" "scalb") ; extern double sin (double) asm ("_" "sin") ; extern double sinh (double) asm ("_" "sinh") ; extern double sqrt (double) asm ("_" "sqrt") ; extern double tan (double) asm ("_" "tan") ; extern double tanh (double) asm ("_" "tanh") ; extern double y0 (double) asm ("_" "y0") ; extern double y1 (double) asm ("_" "y1") ; extern double yn (int, double) asm ("_" "yn") ; struct exception { int type; char* name; double arg1, arg2, retval; }; int matherr(exception*); long abs(long); double abs(double); void clearbit(long&, long); void setbit(long&, long); int testbit(long, long); int even(long); long gcd(long, long); long lg(long); long lcm(long, long); int odd(long); double pow(double, long); long pow(long, long); int sign(long); int sign(double); long sqr(long); double sqr(double); long sqrt(long); double start_timer(); double return_elapsed_time(double); char* itoa(long x, int base = 10, int width = 0); char* hex(long x, int width = 0); char* oct(long x, int width = 0); char* dec(long x, int width = 0); char* form(const char* fmt ...); unsigned int hashpjw(const char*); unsigned int multiplicativehash(int); unsigned int foldhash(double); extern void default_one_arg_error_handler(const char*); extern void default_two_arg_error_handler(const char*, const char*); extern two_arg_error_handler_t lib_error_handler; extern two_arg_error_handler_t set_lib_error_handler(two_arg_error_handler_t f); inline double abs(double _arg) { return (_arg < 0.0)? -_arg : _arg; } inline long abs(long _arg) { return (_arg < 0)? -_arg : _arg; } inline int sign(long _arg) { return (_arg == 0) ? 0 : ( (_arg > 0) ? 1 : -1 ); } inline int sign(double _arg) { return (_arg == 0.0) ? 0 : ( (_arg > 0.0) ? 1 : -1 ); } inline long sqr(long _arg) { return _arg * _arg; } inline double sqr(double _arg) { return _arg * _arg; } inline int even(long _arg) { return !(_arg & 1); } inline int odd(long _arg) { return (_arg & 1); } inline long lcm(long _x, long _y) { return _x / gcd(_x, _y) * _y; } inline void setbit(long& _x, long _b) { _x |= (1 << _b); } inline void clearbit(long& _x, long _b) { _x &= ~(1 << _b); } inline int testbit(long _x, long _b) { return ((_x & (1 << _b)) != 0); } enum io_mode { io_readonly = 0, io_writeonly = 1, io_readwrite = 2, io_appendonly = 3, io_append = 4, }; enum access_mode { a_createonly = 0, a_create = 1, a_useonly = 2, a_use = 3, }; enum state_value { _good = 0, _eof = 1, _fail = 2, _bad = 4 }; class File { protected: struct _iobuf * fp; char* nm; char rw; state_value state; long stat; void initialize(); void reinitialize(const char*); public: File(); File(const char* filename, io_mode m, access_mode a); File(const char* filename, const char* m); File(int filedesc, io_mode m); File( struct _iobuf * fileptr); File(int sz, char* buf, io_mode m); ~File(); File& open(const char* filename, io_mode m, access_mode a); File& open(const char* filename, const char* m); File& open(int filedesc, io_mode m); File& open( struct _iobuf * fileptr); File& close(); File& remove(); int filedesc(); const char* name(); void setname(const char* newname); int iocount(); int rdstate(); int eof(); int fail(); int bad(); int good(); int readable(); int writable(); int is_open(); void* operator void*(); void error(); void clear(state_value f = 0); File& failif(int cond); void check_state(); File& get(char& c); File& put(char c); File& unget(char c); File& putback(char c); File& put(const char* s); File& get (char* s, int n, char terminator = '\n'); File& getline(char* s, int n, char terminator = '\n'); File& read(void* x, int sz, int n); File& write(void* x, int sz, int n); File& seek(long pos, int seek_mode=0); long tell(); File& flush(); File& setbuf(int buffer_kind); File& setbuf(int size, char* buf); File& raw(); }; extern void verbose_File_error_handler(char*); extern void quiet_File_error_handler(char*); extern void fatal_File_error_handler(char*); extern one_arg_error_handler_t File_error_handler; extern one_arg_error_handler_t set_File_error_handler(one_arg_error_handler_t); inline int File::filedesc() { return ((fp)->_file) ; } inline const char* File::name() { return nm; } inline int File::iocount() { return stat; } inline int File::readable() { if (fp != 0) { if ( (((fp)->_flag& 00020 )!=0) ) state |= _eof; if ( (((fp)->_flag& 00040 )!=0) ) state |= _bad;} return (state == _good && (rw & 01)); } inline int File::writable() { if (fp != 0 && (((fp)->_flag& 00040 )!=0) ) state |= _bad; return ((state & (_fail|_bad)) == 0 && (rw & 02)); } inline int File::is_open() { return (fp != 0); } inline void File::clear(state_value flag = 0) { state = flag; } inline File& File::raw() { return File::setbuf( 00004 ); } inline void File::check_state() { if (fp != 0) { if ( (((fp)->_flag& 00020 )!=0) ) state |= _eof; else state &= ~_eof; if ( (((fp)->_flag& 00040 )!=0) ) state |= _bad; } } inline File& File::failif(int cond) { if (cond) state |= _fail; return *this; } inline File& File::get(char& c) { if (readable()) { int ch = (--(fp)->_cnt>=0?(int)(*(unsigned char*)(fp)->_ptr++):_filbuf(fp)) ; c = ch; failif (ch == (-1) ); } return *this; } inline File& File::put(char c) { return failif (!writable() || (--( fp)->_cnt>=0? ((int)((unsigned char)((*( fp)->_ptr++=(unsigned)(c))))):_flsbuf((unsigned)(c), fp)) == (-1) ); } inline File& File::unget(char c) { return failif(!is_open() || !(rw & 01) || ungetc(c, fp) == (-1) ); } inline File& File::putback(char c) { return failif (!is_open() || !(rw & 01) || ungetc(c, fp) == (-1) ); } inline File& File::read(void* x, int sz, int n) { return failif (!readable() || (stat = fread(x, sz, n, fp)) != n); } inline File& File::write(void* x, int sz, int n) { return failif (!writable() || (stat = fwrite(x, sz, n, fp)) != n); } inline File& File::flush() { return failif(!is_open() || fflush(fp) == (-1) ); } inline File& File::seek(long pos, int seek_mode = 0) { return failif (!is_open() || fseek(fp, pos, seek_mode) < 0); } inline long File::tell() { failif (!is_open() || (stat = ftell(fp) < 0)); return stat; } inline int File::rdstate() { check_state(); return state; } inline void* File::operator void*() { check_state(); return (state & (_bad|_fail))? 0 : this ; } inline int File::eof() { check_state(); return state & _eof; } inline int File::fail() { check_state(); return state & _fail; } inline int File::bad() { check_state(); return state & _bad; } inline int File::good() { check_state(); return rdstate() == _good; } class whitespace { char filler; }; class ostream: File { public: File::open; File::close; File::remove; File::filedesc; File::is_open; File::raw; File::put; File::check_state; File::iocount; File::error; File::name; File::setname; File::rdstate; File::flush; File::eof; File::fail; File::bad; File::good; File::clear; File::failif; File::setbuf; File::writable; File::readable; ostream(); ostream(const char* filename, io_mode m, access_mode a); ostream(const char* filename, const char* m); ostream(int filedesc, io_mode m = io_writeonly); ostream( struct _iobuf * fileptr); ostream(int sz, char* buf); ~ostream(); void* operator void*(); ostream& form(const char* fmt, ...); ostream& operator << (char c); ostream& operator << (short n); ostream& operator << (unsigned short n); ostream& operator << (int n); ostream& operator << (unsigned int n); ostream& operator << (long n); ostream& operator << (unsigned long n); ostream& operator << (float n); ostream& operator << (double n); ostream& operator << (const char* s); }; class istream: File { protected: ostream* tied_to; void _flush(); public: File::open; File::close; File::get; File::remove; File::filedesc; File::is_open; File::raw; File::unget; File::getline; File::iocount; File::error; File::name; File::setname; File::rdstate; File::putback; File::eof; File::fail; File::bad; File::good; File::clear; File::failif; File::setbuf; File::writable; File::readable; File::check_state; istream(); istream(const char* filename, io_mode m, access_mode a); istream(const char* filename, const char* m); istream(int filedesc, io_mode m = io_readonly); istream( struct _iobuf * fileptr); istream(int sz, char* buf); ~istream(); void* operator void*(); ostream* tie(ostream* s); istream& scan(const char* fmt, ...); istream& operator >> (char& c); istream& operator >> (short& n); istream& operator >> (unsigned short& n); istream& operator >> (int& n); istream& operator >> (unsigned int& n); istream& operator >> (long& n); istream& operator >> (unsigned long& n); istream& operator >> (float& n); istream& operator >> (double& n); istream& operator >> (char* s); istream& operator >> (whitespace& w); }; void eatwhite(istream& s); extern istream cin; extern ostream cout; extern ostream cerr; extern whitespace WS; inline void* ostream::operator void*() { check_state(); return (state & (_bad|_fail))? 0 : this ; } inline ostream& ostream::operator<<(char c) { put(c); return *this; } inline void* istream::operator void*() { check_state(); return (state & (_bad|_fail))? 0 : this ; } inline void istream::_flush() { if (tied_to) tied_to->flush(); } inline istream& istream::operator>>(char& c) { _flush(); get(c); return *this; } void __eprintf (char*, int, char*); void abort(); struct StrRep { unsigned short len; unsigned short sz; char s[1]; friend StrRep* Salloc(StrRep*, const char*, int, int); friend StrRep* Scopy(StrRep*, StrRep*); friend StrRep* Sresize(StrRep*, int); friend StrRep* Scat(StrRep*, const char*, int, const char*, int); friend StrRep* Sprepend(StrRep*, const char*, int); friend StrRep* Sreverse(StrRep*, StrRep*); friend StrRep* Supcase(StrRep*, StrRep*); friend StrRep* Sdowncase(StrRep*, StrRep*); friend StrRep* Scapitalize(StrRep*, StrRep*); }; class String; class SubString; class StrTmp; struct re_pattern_buffer; struct re_registers; class Regex { friend class String; friend class SubString; protected: re_pattern_buffer* buf; re_registers* reg; void initialize(const char* t, int tlen, int fast, int bufsize, const char* transtable); public: Regex(const char* t, int fast = 0, int bufsize = 40, const char* transtable = 0); Regex(String& x, int fast = 0, int bufsize = 40, const char* transtable = 0); ~Regex(); int match(const char* s, int len, int pos = 0); int search(const char* s, int len, int& matchlen, int startpos = 0); int OK(); }; class SubString { friend class String; friend class StrTmp; protected: String* S; unsigned short pos; unsigned short len; void assign(StrRep*, const char*, int = -1); SubString(String* x, int p, int l); SubString(const SubString& x); public: ~SubString(); void operator = (String& y); void operator = (SubString& y); void operator = (const char* t); void operator = (char c); StrTmp operator + (String& y); StrTmp operator + (SubString& y); StrTmp operator + (const char* t); StrTmp operator + (char c); StrTmp operator + (StrTmp& y); friend StrTmp operator + (const char* t,SubString& y); friend StrTmp operator + (char c, SubString& x); friend int operator == (SubString& x, String& y); friend int operator == (String& x, SubString& y); friend int operator == (SubString& x, SubString& y); friend int operator == (SubString& x, const char* t); friend int operator != (SubString& x, String& y); friend int operator != (String& x, SubString& y); friend int operator != (SubString& x, SubString& y); friend int operator != (SubString& x, const char* t); friend int operator <= (SubString& x, String& y); friend int operator <= (String& x, SubString& y); friend int operator <= (SubString& x, SubString& y); friend int operator <= (SubString& x, const char* t); friend int operator < (SubString& x, String& y); friend int operator < (String& x, SubString& y); friend int operator < (SubString& x, SubString& y); friend int operator < (SubString& x, const char* t); friend int operator >= (SubString& x, String& y); friend int operator >= (String& x, SubString& y); friend int operator >= (SubString& x, SubString& y); friend int operator >= (SubString& x, const char* t); friend int operator > (SubString& x, String& y); friend int operator > (String& x, SubString& y); friend int operator > (SubString& x, SubString& y); friend int operator > (SubString& x, const char* t); int contains(char c); int contains(String& y); int contains(SubString& y); int contains(const char* t); int contains(Regex& r); int matches(Regex& r); int length(); int empty(); friend ostream& operator<<(ostream& s, SubString& x); int OK(); friend int compare(SubString& x, String& y); friend int compare(String& x, SubString& y); friend int compare(SubString& x, SubString& y); friend int compare(SubString& x, const char* y); }; class String { friend class SubString; friend class Regex; friend class StrTmp; protected: StrRep* rep; int search(int, int, const char*, int = -1); int search(int, int, char); int match(int, int, int, const char*, int = -1); int _gsub(const char*, int, const char* ,int); int _gsub(Regex&, const char*, int); public: String(); String(String& x); String(SubString& x); String(const char* t); String(const char* t, int len); String(char c); ~String(); void operator = (String& y); void operator = (StrTmp& y); void operator = (const char* y); void operator = (char c); void operator = (SubString& y); StrTmp operator + (String& y); StrTmp operator + (const char* t); StrTmp operator + (char c); StrTmp operator + (SubString& y); StrTmp operator + (StrTmp& y); friend StrTmp operator + (const char* t, String& y); friend StrTmp operator + (char c, String& x); void operator += (String& y); void operator += (SubString& y); void operator += (const char* t); void operator += (char c); void prepend(String& y); void prepend(SubString& y); void prepend(const char* t); void prepend(char c); friend int operator == (String& x, String& y); friend int operator == (String& x, const char* t); friend int operator == (String& x, SubString& y); friend int operator == (SubString& x, String& y); friend int operator != (String& x, String& y); friend int operator != (String& x, const char* t); friend int operator != (String& x, SubString& y); friend int operator != (SubString& x, String& y); friend int operator <= (String& x, String& y); friend int operator <= (String& x, const char* t); friend int operator <= (String& x, SubString& y); friend int operator <= (SubString& x, String& y); friend int operator < (String& x, String& y); friend int operator < (String& x, const char* t); friend int operator < (String& x, SubString& y); friend int operator < (SubString& x, String& y); friend int operator >= (String& x, String& y); friend int operator >= (String& x, const char* t); friend int operator >= (String& x, SubString& y); friend int operator >= (SubString& x, String& y); friend int operator > (String& x, String& y); friend int operator > (String& x, const char* t); friend int operator > (String& x, SubString& y); friend int operator > (SubString& x, String& y); friend int fcompare(String& x, String& y); int index(char c, int startpos = 0); int index(String& y, int startpos = 0); int index(SubString& y, int startpos = 0); int index(const char* t, int startpos = 0); int index(Regex& r, int startpos = 0); int contains(char c); int contains(String& y); int contains(SubString& y); int contains(const char* t); int contains(Regex& r); int contains(char c, int pos); int contains(String& y, int pos); int contains(SubString& y, int pos); int contains(const char* t, int pos); int contains(Regex& r, int pos); int matches(char c, int pos = 0); int matches(String& y, int pos = 0); int matches(SubString& y, int pos = 0); int matches(const char* t, int pos = 0); int matches(Regex& r, int pos = 0); int freq(char c); int freq(String& y); int freq(SubString& y); int freq(const char* t); SubString at(int pos, int len); SubString at(String& x, int startpos = 0); SubString at(SubString& x, int startpos = 0); SubString at(const char* t, int startpos = 0); SubString at(char c, int startpos = 0); SubString at(Regex& r, int startpos = 0); SubString before(int pos); SubString before(String& x, int startpos = 0); SubString before(SubString& x, int startpos = 0); SubString before(const char* t, int startpos = 0); SubString before(char c, int startpos = 0); SubString before(Regex& r, int startpos = 0); SubString through(int pos); SubString through(String& x, int startpos = 0); SubString through(SubString& x, int startpos = 0); SubString through(const char* t, int startpos = 0); SubString through(char c, int startpos = 0); SubString through(Regex& r, int startpos = 0); SubString from(int pos); SubString from(String& x, int startpos = 0); SubString from(SubString& x, int startpos = 0); SubString from(const char* t, int startpos = 0); SubString from(char c, int startpos = 0); SubString from(Regex& r, int startpos = 0); SubString after(int pos); SubString after(String& x, int startpos = 0); SubString after(SubString& x, int startpos = 0); SubString after(const char* t, int startpos = 0); SubString after(char c, int startpos = 0); SubString after(Regex& r, int startpos = 0); void del(int pos, int len); void del(String& y, int startpos = 0); void del(SubString& y, int startpos = 0); void del(const char* t, int startpos = 0); void del(char c, int startpos = 0); void del(Regex& r, int startpos = 0); int gsub(String& pat, String& repl); int gsub(SubString& pat, String& repl); int gsub(const char* pat, String& repl); int gsub(const char* pat, const char* repl); int gsub(Regex& pat, String& repl); friend int split(String& x, String res[], int maxn, String& sep); friend int split(String& x, String res[], int maxn, Regex& sep); friend StrTmp join(String src[], int n, String& sep); friend StrTmp replicate(char c, int n); friend StrTmp replicate(String& y, int n); friend StrTmp common_prefix(String& x, String& y, int startpos = 0); friend StrTmp common_suffix(String& x, String& y, int startpos = -1); friend StrTmp reverse(String& x); friend StrTmp upcase(String& x); friend StrTmp downcase(String& x); friend StrTmp capitalize(String& x); void reverse(); void upcase(); void downcase(); void capitalize(); char& operator [] (int i); const char* operator char*(); friend ostream& operator<<(ostream& s, String& x); friend ostream& operator<<(ostream& s, SubString& x); friend istream& operator>>(istream& s, String& x); friend int readline(istream& s, String& x, char terminator = '\n', int discard_terminator = 1); int length(); int empty(); void alloc(int newsize); void error(char* msg); int OK(); friend int compare(String& x, String& y); friend int compare(String& x, SubString& y); friend int compare(String& x, const char* y); friend int compare(SubString& x, String& y); }; class StrTmp : public String { public: StrTmp(StrRep* p); StrTmp(String& x); StrTmp(StrTmp& x); ~StrTmp(); StrTmp operator + (String& y); StrTmp operator + (SubString& y); StrTmp operator + (const char* y); StrTmp operator + (char y); friend StrTmp operator + (const char* x, StrTmp& y); friend StrTmp operator + (char x, StrTmp& y); friend StrTmp reverse(StrTmp& x); friend StrTmp upcase(StrTmp& x); friend StrTmp downcase(StrTmp& x); friend StrTmp capitalize(StrTmp& x); }; extern Regex RXwhite; extern Regex RXint; extern Regex RXdouble; extern Regex RXalpha; extern Regex RXlowercase; extern Regex RXuppercase; extern Regex RXalphanum; extern Regex RXidentifier; extern StrRep _nilStrRep; extern String _nilString; inline String::String() { rep = &_nilStrRep; } inline String::String(String& x) { rep = Scopy(0, x.rep); } inline String::String(const char* t) { rep = Salloc(0, t, -1, -1); } inline StrTmp::StrTmp(StrRep* r) { rep = r; } inline StrTmp::StrTmp(String& x) { rep = x.rep; x.rep = &_nilStrRep; } inline StrTmp::StrTmp(StrTmp& x) { rep = x.rep; x.rep = &_nilStrRep; } inline String::String(const char* t, int tlen) { rep = Salloc(0, t, tlen, tlen); } inline String::String(SubString& y) { rep = Salloc(0, &(y.S->rep->s[y.pos]), y.len, y.len); } inline String::String(char c) { rep = Salloc(0, &c, 1, 1); } inline String::~String() { if (rep != &_nilStrRep) delete rep; } inline StrTmp::~StrTmp() {} inline void String::operator = (String& y) { rep = Scopy(rep, y.rep); } inline void String::operator = (StrTmp& y) { if (rep != &_nilStrRep) delete rep; rep = y.rep; y.rep = &_nilStrRep; } inline void String::operator=(const char* t) { rep = Salloc(rep, t, -1, -1); } inline void String::operator=(SubString& y) { rep = Salloc(rep, &(y.S->rep->s[y.pos]), y.len, y.len); } inline void String::operator=(char c) { rep = Salloc(rep, &c, 1, 1); } inline void String::operator +=(String& y) { rep = Scat(rep, rep->s, rep->len, y.rep->s, y.rep->len); } inline void String::operator +=(SubString& y) { rep = Scat(rep, rep->s, rep->len, &(y.S->rep->s[y.pos]),y.len); } inline void String::operator += (const char* y) { rep = Scat(rep, rep->s, rep->len, y, -1); } inline void String:: operator +=(char y) { rep = Scat(rep, rep->s, rep->len, &y, 1); } inline StrTmp String::operator + (String& y) { return(Scat(0, rep->s, rep->len, y.rep->s, y.rep->len)); } inline StrTmp String::operator +(SubString& y) { return(Scat(0, rep->s, rep->len, &(y.S->rep->s[y.pos]),y.len)); } inline StrTmp String::operator + (const char* y) { return(Scat(0, rep->s, rep->len, y, -1)); } inline StrTmp String::operator + (char y) { return(Scat(0, rep->s, rep->len, &y, 1)); } inline StrTmp SubString::operator + (String& y) { return(Scat(0, &(S->rep->s[pos]), len, y.rep->s, y.rep->len)); } inline StrTmp SubString::operator + (SubString& y) { return(Scat(0, &(S->rep->s[pos]), len, &(y.S->rep->s[y.pos]), y.len)); } inline StrTmp SubString::operator + (const char* y) { return(Scat(0, &(S->rep->s[pos]), len, y, -1)); } inline StrTmp SubString::operator + (char y) { return(Scat(0, &(S->rep->s[pos]), len, &y, 1)); } inline StrTmp operator +(const char* t, String& y) { return(Scat(0, t, -1, y.rep->s, y.rep->len)); } inline StrTmp operator + (const char* t, SubString& y) { return(Scat(0, t, -1, &(y.S->rep->s[y.pos]), y.len)); } inline StrTmp operator + (char c, String& y) { return(Scat(0, &c, 1, y.rep->s, y.rep->len)); } inline StrTmp operator + (char c, SubString& y) { return(Scat(0, &c, 1, &(y.S->rep->s[y.pos]), y.len)); } inline StrTmp StrTmp::operator + (String& y) { rep = Scat(rep, rep->s, rep->len, y.rep->s, y.rep->len); return *this; } inline StrTmp StrTmp::operator + (SubString& y) { rep = Scat(rep, rep->s, rep->len, &(y.S->rep->s[y.pos]),y.len); return *this; } inline StrTmp StrTmp::operator + (const char* y) { rep = Scat(rep, rep->s, rep->len, y, -1); return *this; } inline StrTmp StrTmp::operator + (char y) { rep = Scat(rep, rep->s, rep->len, &y, 1); return *this; } inline StrTmp String::operator + (StrTmp& y) { y.rep = Sprepend(y.rep, rep->s, rep->len); return y; } inline StrTmp SubString::operator + (StrTmp& y) { y.rep = Sprepend(y.rep, &(S->rep->s[pos]), len); return y; } inline StrTmp operator + (const char* x, StrTmp& y) { y.rep = Sprepend(y.rep, x, -1); return y; } inline StrTmp operator + (char x, StrTmp& y) { y.rep = Sprepend(y.rep, &x, 1); return y; } inline void String::prepend(String& y) { rep = Sprepend(rep, y.rep->s, y.rep->len); } inline void String::prepend(const char* y) { rep = Sprepend(rep, y, -1); } inline void String::prepend(char y) { rep = Sprepend(rep, &y, 1); } inline void String::prepend(SubString& y) { rep = Sprepend(rep, &(y.S->rep->s[y.pos]), y.len); } inline StrTmp reverse(String& x) { return(Sreverse(x.rep, 0)); } inline StrTmp reverse(StrTmp& x) { x.rep = Sreverse(x.rep, x.rep); return x; } inline void String::reverse() { rep = Sreverse(rep, rep); } inline StrTmp upcase(String& x) { return(Supcase(x.rep, 0)); } inline StrTmp upcase(StrTmp& x) { x.rep = Supcase(x.rep, x.rep); return x; } inline void String::upcase() { rep = Supcase(rep, rep); } inline StrTmp downcase(String& x) { return(Sdowncase(x.rep, 0)); } inline StrTmp downcase(StrTmp& x) { x.rep = Sdowncase(x.rep, x.rep); return x; } inline void String::downcase() { rep = Sdowncase(rep, rep); } inline StrTmp capitalize(String& x) { return(Scapitalize(x.rep, 0)); } inline StrTmp capitalize(StrTmp& x) { x.rep = Scapitalize(x.rep, x.rep); return x; } inline void String::capitalize() { rep = Scapitalize(rep, rep); } inline void String::alloc(int newsize) { rep = Sresize(rep, newsize); } inline SubString::SubString(const SubString& x) { S = x.S; pos = x.pos; len = x.len; } inline SubString::SubString(String* x, int first, int l) { if (first < 0 || (unsigned)(first + l) > x->rep->len) { S = &_nilString; pos = len = 0; } else { S = x; pos = first; len = l; } } inline SubString::~SubString() {} inline void SubString::operator = (const char* ys) { assign(0, ys); } inline void SubString::operator = (char ch) { assign(0, &ch, 1); } inline void SubString::operator = (String& y) { assign(y.rep, y.rep->s, y.rep->len); } inline void SubString::operator = (SubString& y) { assign(y.S->rep, &(y.S->rep->s[y.pos]), y.len); } inline int String::length() { return rep->len; } inline int String::empty() { return rep->len == 0; } inline char& String::operator [] (int i) { if (((unsigned)i) >= rep->len) error("invalid index"); return rep->s[i]; } inline int String::index(char c, int startpos = 0) { return search(startpos, rep->len, c); } inline int String::index(const char* t, int startpos = 0) { return search(startpos, rep->len, t); } inline int String::index(String& y, int startpos = 0) { return search(startpos, rep->len, y.rep->s, y.rep->len); } inline int String::index(SubString& y, int startpos = 0) { return search(startpos, rep->len, &(y.S->rep->s[y.pos]), y.len); } inline int String::contains(char c) { return search(0, rep->len, c) >= 0; } inline int SubString::contains(char c) { return S->search(pos, pos+len, 0, c) >= 0; } inline int String::contains(const char* t) { return search(0, rep->len, t) >= 0; } inline int String::contains(String& y) { return search(0, rep->len, y.rep->s, y.rep->len) >= 0; } inline int String::contains(SubString& y) { return search(0, rep->len, &(y.S->rep->s[y.pos]), y.len) >= 0; } inline int SubString::contains(const char* t) { return S->search(pos, pos+len, t) >= 0; } inline int SubString::contains(String& y) { return S->search(pos, pos+len, y.rep->s, y.rep->len) >= 0; } inline int SubString::contains(SubString& y) { return S->search(pos, pos+len, &(y.S->rep->s[y.pos]), y.len) >= 0; } inline int String::contains(char c, int p) { return match(p, rep->len, 0, &c, 1); } inline int String::matches(char c, int p = 0) { return match(p, rep->len, 1, &c, 1); } inline int String::contains(const char* t, int p) { return match(p, rep->len, 0, t); } inline int String::matches(const char* t, int p = 0) { return match(p, rep->len, 1, t); } inline int String::contains(String& y, int p) { return match(p, rep->len, 0, y.rep->s, y.rep->len); } inline int String::matches(String& y, int p = 0) { return match(p, rep->len, 1, y.rep->s, y.rep->len); } inline int String::contains(SubString& y, int p) { return match(p, rep->len, 0, &(y.S->rep->s[y.pos]), y.len); } inline int String::matches(SubString& y, int p = 0) { return match(p, rep->len, 1, &(y.S->rep->s[y.pos]), y.len); } inline int String::contains(Regex& r) { int unused; return r.search(rep->s, rep->len, unused, 0) >= 0; } inline int SubString::contains(Regex& r) { int unused; return r.search(&(S->rep->s[pos]), len, unused, 0) >= 0; } inline int String::contains(Regex& r, int p) { return r.match(rep->s, rep->len, p) >= 0; } inline int String::matches(Regex& r, int p = 0) { int l = (p < 0)? -p : rep->len - p; return r.match(rep->s, rep->len, p) == l; } inline int SubString::matches(Regex& r) { return r.match(&(S->rep->s[pos]), len, 0) == len; } inline const char* String::operator char*() { return rep->s; } inline int String::index(Regex& r, int startpos = 0) { int unused; return r.search(rep->s, rep->len, unused, startpos); } inline int SubString::length() { return len; } inline int SubString::empty() { return len == 0; } inline ostream& operator<<(ostream& s, String& x) { s.put(x.rep->s); return s; } inline int operator==(String& x, String& y) { return compare(x, y) == 0; } inline int operator!=(String& x, String& y) { return compare(x, y) != 0; } inline int operator>(String& x, String& y) { return compare(x, y) > 0; } inline int operator>=(String& x, String& y) { return compare(x, y) >= 0; } inline int operator<(String& x, String& y) { return compare(x, y) < 0; } inline int operator<=(String& x, String& y) { return compare(x, y) <= 0; } inline int operator==(String& x, SubString& y) { return compare(x, y) == 0; } inline int operator!=(String& x, SubString& y) { return compare(x, y) != 0; } inline int operator>(String& x, SubString& y) { return compare(x, y) > 0; } inline int operator>=(String& x, SubString& y) { return compare(x, y) >= 0; } inline int operator<(String& x, SubString& y) { return compare(x, y) < 0; } inline int operator<=(String& x, SubString& y) { return compare(x, y) <= 0; } inline int operator==(String& x, const char* t) { return compare(x, t) == 0; } inline int operator!=(String& x, const char* t) { return compare(x, t) != 0; } inline int operator>(String& x, const char* t) { return compare(x, t) > 0; } inline int operator>=(String& x, const char* t) { return compare(x, t) >= 0; } inline int operator<(String& x, const char* t) { return compare(x, t) < 0; } inline int operator<=(String& x, const char* t) { return compare(x, t) <= 0; } inline int operator==(SubString& x, String& y) { return compare(y, x) == 0; } inline int operator!=(SubString& x, String& y) { return compare(y, x) != 0; } inline int operator>(SubString& x, String& y) { return compare(y, x) < 0; } inline int operator>=(SubString& x, String& y) { return compare(y, x) <= 0; } inline int operator<(SubString& x, String& y) { return compare(y, x) > 0; } inline int operator<=(SubString& x, String& y) { return compare(y, x) >= 0; } inline int operator==(SubString& x, SubString& y) { return compare(x, y) == 0; } inline int operator!=(SubString& x, SubString& y) { return compare(x, y) != 0; } inline int operator>(SubString& x, SubString& y) { return compare(x, y) > 0; } inline int operator>=(SubString& x, SubString& y) { return compare(x, y) >= 0; } inline int operator<(SubString& x, SubString& y) { return compare(x, y) < 0; } inline int operator<=(SubString& x, SubString& y) { return compare(x, y) <= 0; } inline int operator==(SubString& x, const char* t) { return compare(x, t) == 0; } inline int operator!=(SubString& x, const char* t) { return compare(x, t) != 0; } inline int operator>(SubString& x, const char* t) { return compare(x, t) > 0; } inline int operator>=(SubString& x, const char* t) { return compare(x, t) >= 0; } inline int operator<(SubString& x, const char* t) { return compare(x, t) < 0; } inline int operator<=(SubString& x, const char* t) { return compare(x, t) <= 0; } inline SubString String::at(int first, int len) { return SubString(this, first, len); } inline SubString String::before(int pos) { return SubString(this, 0, pos); } inline SubString String::through(int pos) { return SubString(this, 0, pos+1); } inline SubString String::after(int pos) { return SubString(this, pos + 1, rep->len - (pos + 1)); } inline SubString String::from(int pos) { return SubString(this, pos, rep->len - pos); } inline int String::gsub(String& pat, String& r) { return _gsub(pat.rep->s, pat.rep->len, r.rep->s, r.rep->len); } inline int String::gsub(SubString& pat, String& r) { return _gsub(&(pat.S->rep->s[pat.pos]), pat.len, r.rep->s, r.rep->len); } inline int String::gsub(Regex& pat, String& r) { return _gsub(pat, r.rep->s, r.rep->len); } inline int String::gsub(const char* pat, String& r) { return _gsub(pat, -1, r.rep->s, r.rep->len); } inline int String::gsub(const char* pat, const char* r) { return _gsub(pat, -1, r, -1); } inline void String::del(String& y, int startpos = 0) { del(search(startpos, rep->len, y.rep->s, y.rep->len), y.rep->len); } inline void String::del(SubString& y, int startpos = 0) { del(search(startpos, rep->len, &(y.S->rep->s[y.pos]), y.len), y.len); } inline void String::del(char c, int startpos = 0) { del(search(startpos, rep->len, c), 1); } inline Regex::Regex(String& x, int fast = 0, int bufsize = 40, const char* transtable = 0) { initialize(x.rep->s, x.rep->len, fast, bufsize, transtable); } inline Regex::Regex(const char* t, int fast = 0, int bufsize = 40, const char* transtable = 0) { initialize(t, -1, fast, bufsize, transtable); } typedef void* Pix; overload hash; typedef long int l_int; typedef l_int* l_int_p; typedef unsigned int u_int; typedef u_int* u_int_p; typedef long unsigned int l_u_int; typedef l_u_int* l_u_int_p; typedef unsigned short u_short; typedef u_short* u_short_p; typedef unsigned char u_char; typedef u_char* u_char_p; typedef int* int_p; typedef short* short_p; typedef char* char_p; typedef void* void_p; typedef char Boolean; extern l_u_int roundup (l_u_int size) ; overload MIN; extern char MIN (char a, char b) ; extern u_char MIN (u_char a, u_char b) ; extern short MIN (short a, short b) ; extern u_short MIN (u_short a, u_short b) ; extern int MIN (int a, int b) ; extern u_int MIN (u_int a, u_int b) ; extern l_int MIN (l_int a, l_int b) ; extern l_u_int MIN (l_u_int a, l_u_int b) ; extern char_p MIN (char_p a, char_p b) ; overload MAX; extern char MAX (char a, char b) ; extern u_char MAX (u_char a, u_char b) ; extern short MAX (short a, short b) ; extern u_short MAX (u_short a, u_short b) ; extern int MAX (int a, int b) ; extern u_int MAX (u_int a, u_int b) ; extern l_int MAX (l_int a, l_int b) ; extern l_u_int MAX (l_u_int a, l_u_int b) ; extern char_p MAX (char_p a, char_p b) ; class Disk { private: int fildes; public: Disk(); Disk(String& n); ~Disk(); String operator String(); void read (l_u_int start, l_u_int count, char *buf); void write (l_u_int start, l_u_int count, char *buf); String name; l_u_int size(); l_u_int block_size(); }; typedef Disk* Disk_p; Disk::Disk() { fildes = -1; } Disk::Disk(String& n) { name = n; if ((fildes = ::open ((char *)name, 2 , 0)) < 0) { cerr << "open: error opening file " << name << "\n"; ::exit (1); } } void Disk::~Disk() { if (fildes >= 0) if (::close (fildes) < 0) { cerr << "close: error closing file " << name << "\n"; ::exit (1); } } String Disk::operator String() { String result = form ("Disk <%s> = { fildes = %d }", (char *)name, fildes); return result; } void Disk::read(l_u_int start, l_u_int count, char *buf) { l_int s; int c; ((fildes >= 0) ? 1 : (__eprintf("Failed assertion " "fildes >= 0" " at line %d of `%s'.\n", 53, "Disk.cc"), abort (), 0)) ; if (start != (s = ::lseek (fildes, (l_int)start, 0 ))) { cerr << form("read: error seeking file %s, addr = %d, seeked to %d\n", (char *)name, start, s); ::exit (1); } if (count != (c = ::read (fildes, buf, (int)count))) { cerr << form("read: error reading file %s, tried to read %d bytes, read %d bytes\n", (char *)name, count, c); ::exit (1); } } void Disk::write (l_u_int start, l_u_int count, char *buf) { l_int s; int c; ((fildes >= 0) ? 1 : (__eprintf("Failed assertion " "fildes >= 0" " at line %d of `%s'.\n", 77, "Disk.cc"), abort (), 0)) ; if (start != (s = ::lseek (fildes, (l_int)start, 0 ))) { cerr << form("write: error seeking file %s, addr = %d, seeked to %d\n", (char *)name, start, s); ::exit (1); } if (count != (c = ::write (fildes, buf, (int)count))) { cerr << form("write: error reading file %s, tried to read %d bytes, read %d bytes\n", (char *)name, count, c); ::exit (1); } } l_u_int Disk::size() { ((fildes >= 0) ? 1 : (__eprintf("Failed assertion " "fildes >= 0" " at line %d of `%s'.\n", 98, "Disk.cc"), abort (), 0)) ; Regex devices ("/dev"); if (name.contains (devices)) { struct disktab *getdiskbyname (char *), *disktab_entry; typedef enum partitions {a, b, c, d, e, f, g, h}; partitions part = c; disktab_entry = getdiskbyname ("cmu81"); return disktab_entry->d_partitions[part].p_size * disktab_entry->d_secsize; } return (l_u_int)::lseek (fildes, 0, 2 ); } l_u_int Disk::block_size() { ((fildes >= 0) ? 1 : (__eprintf("Failed assertion " "fildes >= 0" " at line %d of `%s'.\n", 126, "Disk.cc"), abort (), 0)) ; Regex devices ("/dev"); if (name.contains (devices)) { struct disktab *getdiskbyname (char *), *disktab_entry; typedef enum partitions {a, b, c, d, e, f, g, h}; partitions part = c; disktab_entry = getdiskbyname ("cmu81"); return disktab_entry->d_secsize; } return 512 ; }