home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-08-21 | 53.9 KB | 2,125 lines |
- Newsgroups: comp.sources.misc
- From: tlhouns@srv.pacbell.com (Lee Hounshell)
- Subject: v31i091: var - a C++ string class library, Part01/02
- Message-ID: <csm-v31i091=var.104945@sparky.IMD.Sterling.COM>
- X-Md4-Signature: c06ffbe54ada717d84c18d0bb446b631
- Date: Fri, 21 Aug 1992 15:50:16 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: tlhouns@srv.pacbell.com (Lee Hounshell)
- Posting-number: Volume 31, Issue 91
- Archive-name: var/part01
- Environment: C++
-
- This is "var", a C++ object library that is kinda like a "super-string" class.
- The var class does a pretty good job of offering a data object that assumes
- its "type" at run time, based on context of use. Rarely will you need to
- declare int's, or longs, or doubles or char[] or even string objects again!
- "Var" does it all (or at least tries to).
-
- + var will do base data types (eg: int, long, char *, float, string ...) + var will do arithmetic
- + var will do strings and operations on strings
- + var will do sub-strings and operations on sub-strings
- + var will intelligently "mix" operations between mixed types
- + var will do formatted output using the stream library
- + individual vars can be "staticly" typed, or they can assume
- type at runtime, based on context.
-
- To use this class, simply type make and a library file "libvar.a" will be
- created. This class has been used extensively here at Pacific Bell as a
- base class in development of our own internal C++ class libraries. I've
- even used "var" as the YYSTYPE type inside yacc/lex programs!!
-
- If there is sufficient interest in "var" I may post a few other "base" C++
- classes that I've developed.. such as an "associative array" class that uses
- a "var" to index another "var."
-
- If you like (or dislike) var, please drop me a line.
- Mail bug reports and comments to:
- tlhouns@srv.pacbell.com
-
- -Lee
- -------
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then feed it
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # The tool that generated this appeared in the comp.sources.unix newsgroup;
- # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
- # Contents: README LEGAL_NOTICE var.3++ var.C
- # Wrapped by kent@sparky on Fri Aug 21 10:47:44 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- echo If this archive is complete, you will see the following message:
- echo ' "shar: End of archive 1 (of 2)."'
- if test -f 'README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README'\"
- else
- echo shar: Extracting \"'README'\" \(1356 characters\)
- sed "s/^X//" >'README' <<'END_OF_FILE'
- X
- XThis is "var", a C++ object library that is kinda like a "super-string" class.
- XThe var class does a pretty good job of offering a data object that assumes
- Xits "type" at run time, based on context of use. Rarely will you need to
- Xdeclare int's, or longs, or doubles or char[] or even string objects!
- X"Var" does it all (or at least tries to).
- X
- X + var will do base data types (eg: int, long, char *, float, string ...)
- X + var will do arithmetic
- X + var will do strings and operations on strings
- X + var will do sub-strings and operations on sub-strings
- X + var will intelligently "mix" operations between mixed types
- X + var will do formatted output using the stream library
- X + individual vars can be "staticly" typed, or they can assume
- X type at runtime, based on context.
- X
- XTo use this class, simply type make and a library file "libvar.a" will be
- Xcreated. This class has been used extensively here at Pacific Bell as a
- Xbase class in development of our own internal C++ class libraries. I've
- Xeven used "var" as the YYSTYPE type inside yacc/lex programs!!
- X
- XIf there is sufficient interest in "var" I may post a few other "base" C++
- Xclasses that I've developed.. such as an "associative array" class that uses
- Xa "var" to index another "var."
- X
- XIf you like (or dislike) var, please drop me a line.
- XMail bug reports and comments to:
- Xtlhouns@srv.pacbell.com
- X
- X-Lee
- END_OF_FILE
- if test 1356 -ne `wc -c <'README'`; then
- echo shar: \"'README'\" unpacked with wrong size!
- fi
- # end of 'README'
- fi
- if test -f 'LEGAL_NOTICE' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'LEGAL_NOTICE'\"
- else
- echo shar: Extracting \"'LEGAL_NOTICE'\" \(1388 characters\)
- sed "s/^X//" >'LEGAL_NOTICE' <<'END_OF_FILE'
- X
- X Any use of this source code must include, in the user documentation
- X and internal comments to the code, and notices to the end user as
- X follows:
- X
- X Copyright (c) 1992 Lee Hounshell
- X
- X LEE HOUNSHELL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF
- X THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS"
- X WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. LEE HOUNSHELL
- X SEVERALLY AND INDIVIDUALLY, DISCLAIM ALL WARRANTIES WITH REGARD
- X TO THIS SOURCE CODE, INCLUDING ALL IMPLIED WARRANTIES OF
- X MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO
- X EVENT SHALL LEE HOUNSHELL BE LIABLE FOR ANY SPECIAL, INDIRECT,
- X INCIDENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER
- X RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- X OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- X OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE.
- X
- X Permission to use, copy, modify, and distribute this software
- X and its documentation for any purpose and without fee is hereby
- X granted, provided that the above copyright notice appear in all
- X copies and that both that copyright notice and this permission
- X notice appear in supporting documentation, and that the name of
- X Lee Hounshell not be used in advertising in publicity pertaining
- X to distribution of the software without specific, written prior
- X permission.
- X
- END_OF_FILE
- if test 1388 -ne `wc -c <'LEGAL_NOTICE'`; then
- echo shar: \"'LEGAL_NOTICE'\" unpacked with wrong size!
- fi
- # end of 'LEGAL_NOTICE'
- fi
- if test -f 'var.3++' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'var.3++'\"
- else
- echo shar: Extracting \"'var.3++'\" \(15188 characters\)
- sed "s/^X//" >'var.3++' <<'END_OF_FILE'
- X.po 6
- X.TH VAR 3++ "1/92" "Version 1.0" "Variable Base Type String Class Library"
- X
- X.SH CLASS
- XVAR \- Variable Base Type String Class Library
- X.SH SYNOPSIS
- X.B #include <var.H>
- X.PP
- X.nf
- X.ta.5i 1.0i 4.0i
- X\fB
- Xclass var {
- X
- X public:
- X // Constructors & Destructors
- X var(void); // constructor
- X var(const varsize &); // constructor
- X var(const char *); // constructor
- X var(const char); // constructor
- X var(const short); // constructor
- X var(const unsigned short); // constructor
- X var(const int); // constructor
- X var(const unsigned int); // constructor
- X var(const long); // constructor
- X var(const unsigned long); // constructor
- X var(const double); // constructor
- X var(const var &); // copy constructor
- X ~var(void); // destructor
- X
- X // Operators
- X var & operator = (const char *); // assignment
- X var & operator = (const var &); // assignment
- X char & operator [] (const int); // indexing
- X subvar & operator () (int, int) const; // substring
- X subvar & operator () (const int) const; // substring
- X friend ostream & operator << (ostream &, const var &); // output
- X friend istream & operator >> (istream &, var &); // input
- X friend class subvar; // substring
- X
- X // More Operators (used for arithmetic type extension)
- X var & operator = (const char); // assignment
- X var & operator = (const short); // assignment
- X var & operator = (const unsigned short); // assignment
- X var & operator = (const int); // assignment
- X var & operator = (const unsigned int); // assignment
- X var & operator = (const long); // assignment
- X var & operator = (const unsigned long); // assignment
- X var & operator = (const double); // assignment
- X
- X // Casting Operators
- X operator char * (void) const; // type conversion
- X operator double (void) const; // type conversion
- X
- X // Assignment Operators
- X var & operator ++ (void); // increment (pre-index only)
- X var & operator -- (void); // decrement (pre-index only)
- X var operator ! (void) const; // not
- X
- X var operator + (const var &) const; // addition OR concatenation
- X var operator - (const var &) const; // subtraction
- X var operator * (const var &) const; // multiplication
- X var operator / (const var &) const; // division
- X var operator % (const var &) const; // remainder
- X
- X var & operator += (const var &); // addition OR concatenation
- X var & operator -= (const var &); // subtraction
- X var & operator *= (const var &); // multiplication
- X var & operator /= (const var &); // division
- X var & operator %= (const var &); // remainder
- X
- X var & operator += (const char &); // addition OR concatenation
- X var & operator += (const char *); // addition OR concatenation
- X var & operator -= (const char *); // subtraction
- X var & operator *= (const char *); // multiplication
- X var & operator /= (const char *); // division
- X var & operator %= (const char *); // remainder
- X
- X var & operator += (const double); // addition OR concatenation
- X var & operator -= (const double); // subtraction
- X var & operator *= (const double); // multiplication
- X var & operator /= (const double); // division
- X var & operator %= (const double); // remainder
- X
- X friend var operator + (const char *, const var &); // addition OR concatenation
- X friend var operator - (const char *, const var &); // subtraction
- X friend var operator * (const char *, const var &); // multiplication
- X friend var operator / (const char *, const var &); // division
- X friend var operator % (const char *, const var &); // remainder
- X friend var operator + (const var &, const char *); // addition OR concatenation
- X friend var operator - (const var &, const char *); // subtraction
- X friend var operator * (const var &, const char *); // multiplication
- X friend var operator / (const var &, const char *); // division
- X friend var operator % (const var &, const char *); // remainder
- X
- X friend var operator + (const var &, const double); // addition OR concatenation
- X friend var operator - (const var &, const double); // subtraction
- X friend var operator * (const var &, const double); // multiplication
- X friend var operator / (const var &, const double); // division
- X friend var operator % (const var &, const double); // remainder
- X friend var operator + (const double, const var &); // addition OR concatenation
- X friend var operator - (const double, const var &); // subtraction
- X friend var operator * (const double, const var &); // multiplication
- X friend var operator / (const double, const var &); // division
- X friend var operator % (const double, const var &); // remainder
- X
- X // Equality Operators
- X int operator == (const var &) const; // equality
- X int operator != (const var &) const; // inequality
- X int operator < (const var &) const; // less than
- X int operator > (const var &) const; // greater than
- X int operator <= (const var &) const; // less than or equal
- X int operator >= (const var &) const; // greater than or equal
- X
- X friend int operator == (const var &, const char *); // equality
- X friend int operator != (const var &, const char *); // inequality
- X friend int operator < (const var &, const char *); // less than
- X friend int operator > (const var &, const char *); // greater than
- X friend int operator <= (const var &, const char *); // less than or equal
- X friend int operator >= (const var &, const char *); // greater than or equal
- X friend int operator == (const char *, const var &); // equality
- X friend int operator != (const char *, const var &); // inequality
- X friend int operator < (const char *, const var &); // less than
- X friend int operator > (const char *, const var &); // greater than
- X friend int operator <= (const char *, const var &); // less than or equal
- X friend int operator >= (const char *, const var &); // greater than or equal
- X
- X friend int operator == (const var &, const double); // equality
- X friend int operator != (const var &, const double); // inequality
- X friend int operator < (const var &, const double); // less than
- X friend int operator > (const var &, const double); // greater than
- X friend int operator <= (const var &, const double); // less than or equal
- X friend int operator >= (const var &, const double); // greater than or equal
- X friend int operator == (const double, const var &); // equality
- X friend int operator != (const double, const var &); // inequality
- X friend int operator < (const double, const var &); // less than
- X friend int operator > (const double, const var &); // greater than
- X friend int operator <= (const double, const var &); // less than or equal
- X friend int operator >= (const double, const var &); // greater than or equal
- X
- X // Custom Interface
- X void null(int); // "null" out string
- X void changesize(int); // change allocated memory
- X int length(void) const; // length of string
- X const char * vartype(void) const; // name of this var type
- X void change_type(const char *); // change var type
- X int is_string(void) const; // test var type
- X int is_double(void) const; // test var type
- X int is_long(void) const; // test var type
- X int strchr(const char) const; // strchr(char) index
- X int strrchr(const char) const; // strrchr(char) index
- X var & concat(const var &); // concatenation
- X var & format(const char *); // set output format
- X};
- X.fi
- X\fP
- X
- X.SH DESCRIPTION
- XClass \fBvar\fP represents a \fBstring\fP object class that also provides all
- Xthe traditional functionality of the C base types: char, int, long, float, double, and char*.
- X\fBVar\fP, is in many ways a "super-string" class.
- XThe var class does a pretty good job of offering a base data "container" object that can either
- Xassume its "type" at run time, based on context or remain a "fixed" type, always.
- X
- X.SS var will do
- X.TP 2
- X+
- Xall the base data types (eg: short, int, long, char *, float, double ...)
- X.TP 2
- X+
- Xstring types
- X.TP 2
- X+
- Xarithmetic
- X.TP 2
- X+
- Xstrings and operations on strings
- X.TP 2
- X+
- Xsub-strings and operations on sub-strings
- X.TP 2
- X+
- Xintelligent "mixing" of operations between mixed types
- X.TP 2
- X+
- Xformatted output using the stream library
- X
- X.SH PUBLIC CONSTRUCTORS
- X.SS var(void);
- XThis constructor is used to declare an "untyped" var object. Type is determined
- Xat run-time, based on context of use.
- X
- X.SS var(const varsize &);
- XThis constructor is used to declare an "string" var object, with preallocated memory.
- XThe object's type can change at run-time, based on context.
- X
- X.SS var(const char *);
- XThis constructor is used to declare a "string" object initialize from a "char *".
- XThe object's type can change at run-time, based on context.
- X
- X.SS var(const char);
- XThis constructor is used to declare an "numeric" var object, initialized from a char.
- XThe object's type can change at run-time, based on context.
- X
- X.SS var(const short);
- XThis constructor is used to declare an "numeric" var object, initialized from a short.
- XThe object's type is fixed and will not change at run-time.
- X
- X.SS var(const unsigned short);
- XThis constructor is used to declare an "numeric" var object, initialized from an unsigned short.
- XThe object's type is fixed and will not change at run-time.
- X
- X.SS var(const int);
- XThis constructor is used to declare an "numeric" var object, initialized from an int.
- XThe object's type is fixed and will not change at run-time.
- X
- X.SS var(const unsigned int);
- XThis constructor is used to declare an "numeric" var object, initialized from an unsigned int.
- XThe object's type is fixed and will not change at run-time.
- X
- X.SS var(const long);
- XThis constructor is used to declare an "numeric" var object, initialized from a long.
- XThe object's type is fixed and will not change at run-time.
- X
- X.SS var(const unsigned long);
- XThis constructor is used to declare an "numeric" var object, initialized from an unsigned long.
- XThe object's type is fixed and will not change at run-time.
- X
- X.SS var(const double);
- XThis constructor is used to declare an "numeric" var object, initialized from a double or float.
- XThe object's type is fixed and will not change at run-time.
- X
- X.SS var(const var &);
- XThis constructor is used to declare a var object, which is a copy of another var.
- XThe object assumes the characteristics of the initializing object.
- X
- X.SS ~var(void);
- XThe destructor returns all memory allocated by the object back to the OS.
- X
- X
- X.SH PUBLIC OPERATORS
- X.SS Arithmetic and Concatenation Operators
- XMost operators (+, -, /, *, %, +=, etc..) will operate as expected.
- XThe "+" and "+=" operators will either do addition or concatenation, as appropriate.
- Xif concatenation is required, then the \fB"var.concat(var)"\fP member function should
- Xbe used.
- X
- X.SS Relational Operators
- XThese also operate as expected. If "string" objects are compared, the comparison
- Xwill be as performed by \fBstrcmp(3)\fP.
- X
- X.SS The Indexing Operator []
- XYou can index a character from inside a \fBvar\fP by using
- Xthe \fB"char & operator [] (const int);"\fP operator.
- XA reference to the character is returned, which can be assigned to.
- XDo not assign the NULL character using this operator.
- XInstead call the member function \fB"null(index)"\fP.
- X
- X.SS Sub-strings
- XTwo operators are provide for substring operation. The
- Xfirst, \fB"subvar & operator () (int start, int length) const;"\fP
- Xwill extract a string starting at "start" for "length" characters.
- XThe second, \fB"subvar & operator () (const int start) const;"\fP will
- Xextract a string starting at "start" to the end of the string.
- X
- X.SS Type Casting
- XOnly two type casts are required by \fBvar\fP. The first converts
- Xthe object into a "char *". The second converts the object into a
- Xdouble. Implicit conversion between "char *" and "double" types
- Xwill be performed by your C++ compiler.
- X
- X.SS Formatted Input/Output
- XYou can usr \fBvar\fP with the io stream library. Object can be
- Xboth output and input using the ">>" and "<<" operators.
- XFor formatted output, be sure to set the object's "format template"
- Xprior to calling the ">>" operator. (see \fB"var & format(const char *);"\fP)
- X
- X.SH PUBLIC MEMBER FUNCTIONS
- X
- X.SS Truncating a string
- XThe \fB"void null(int index);"\fP function will truncate a \fBvar\fP
- Xobject, starting from the specified index postion.
- X
- X.SS Memory Allocation
- XThe \fB"void changesize(int newsize);"\fP can be used to increase
- Xallocated memory for a var. Memory can NOT be decreased. Allocated
- Xmemory is returned to the heap when an object goes out of scope.
- X
- X.SS Determining Var's Length
- XThe \fB"int length(void) const;"\fP function returns the "size" of a \fBvar\fP.
- X
- X.SS Determining Var's Type
- XThe \fB"const char * vartype(void) const;"\fP function returns the "type" of a \fBvar\fP.
- XPossible types are: "VAR_STRING", "VAR_LONG" and "VAR_DOUBLE".
- X
- X.SS Explititly Changing a Var's Type
- XThe \fB"void change_type(const char *newtype);"\fP function can be used
- Xto set an exact type. Valid values for "newtype" are "string", "short",
- X"unsigned short", "int", "unsigned int", "long", "unsigned long",
- X"float", and "double".
- X
- X.SS Testing a Var's Type
- XThree functions are provided that allow testing a \fBvar\fP type.
- XThey are as follows: \fB"int is_string(void) const;"\fP,
- X\fB"int is_double(void) const;"\fP, and \fB"int is_long(void) const;"\fP
- X
- X.SS Searching for a Character
- XTwo functions are provided that search a \fBvar\fP for a specified
- Xcharacter. Both return an offset. The first \fB"int strchr(const char) const;"\fP
- Xsearches forward. The second, \fB"int strrchr(const char) const;"\fP
- Xsearches backward.
- X
- X.SS Concatenation
- XConcatenation can be forced, regardless of type with the \fB"var & concat(const var &);"\fP
- Xfunction.
- X
- X.SS Setting the Output Format
- XThe \fB"var & format(const char *fmt);"\fP function will allow you to specify an
- Xoutput format. This format will remain in effect until changed. Printf()
- Xstyle output formats can be introduced anywhere in the format statment.
- XMultiple formateed output directives can appear in the same "fmt". Each
- Xdirective will receive a copy of the object. Automatic type conversion will
- Xoccur.
- X
- X
- X.SH AUTHOR
- XLee Hounshell - 1/92
- X
- X.SH EXAMPLE
- X.nf
- X#include <stdlib.h>
- X#include <stream.h>
- X#include <var.H>
- X
- Xmain ()
- X{
- X var value; // declare an "untyped" var
- X value = "hello world"; // initialize it
- X cout << value << endl; // output "hello world"
- X value = value(3, value.length() - 6); // substring example
- X cout << value << endl; // output "lo wo"
- X value = 35; // assignment of int
- X value += 42.375; // add 42.375 to present value
- X cout << value << endl; // output "77.375"
- X cout << value.format("formatted output example %05d of value") << endl;
- X cout << value.format("multiple outputs #1=%d, #2=%9.2f of value") << endl;
- X value.null(2); // truncate string
- X value += " sunset strip"; // concatenate a string
- X cout << value.format("%s") << endl; // output "77 sunset strip"
- X cout << value[3] << value[4] << value[5] << endl; // output "sun"
- X}
- X.fi
- X
- X.SH SUPERCLASSES
- Xnone.
- X
- X.SH SUBCLASSES
- Xnone
- X
- X.SH BUGS
- XAssignment of an array of vars to another array of vars
- Xmust currently be done one elemnt at a time.
- X
- END_OF_FILE
- if test 15188 -ne `wc -c <'var.3++'`; then
- echo shar: \"'var.3++'\" unpacked with wrong size!
- fi
- # end of 'var.3++'
- fi
- if test -f 'var.C' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'var.C'\"
- else
- echo shar: Extracting \"'var.C'\" \(30983 characters\)
- sed "s/^X//" >'var.C' <<'END_OF_FILE'
- X//
- X// NAME: var.C
- X//
- X// PURPOSE: C++ Generic "Universal Variable" library class
- X// AUTHOR: Lee Hounshell
- X//
- X
- X#include <stddef.h>
- X#include <stream.h>
- X#include <stdlib.h>
- X#include <ctype.h>
- X#include <string.h>
- X#include "var.H"
- X#include "Misc.H"
- X
- Xconst int VAR_PAD_SIZE = 128;
- Xconst int VAR_DEF_SIZE = 16;
- X
- Xconst short VAR_STRING = 0;
- Xconst short VAR_LONG = 1;
- Xconst short VAR_DOUBLE = 2;
- X
- Xchar * DEFAULT_STRING_FORMAT = "'%s'";
- Xchar * DEFAULT_INT_FORMAT = "%d";
- Xchar * DEFAULT_UINT_FORMAT = "%u";
- Xchar * DEFAULT_LONG_FORMAT = "%ld";
- Xchar * DEFAULT_ULONG_FORMAT = "%lu";
- Xchar * DEFAULT_DOUBLE_FORMAT = "%9.2f";
- X
- X// -----------------------------------------------------------------------------
- X
- Xconst var var::ctype = "var";
- Xint var::save_me = 1;
- X
- X
- Xconst var & var::type(void) const
- X{
- X return var::ctype;
- X}
- X
- X
- Xvarsize::varsize(int sz)
- X{
- X size = sz;
- X}
- X
- X
- Xvar::var(void)
- X{
- X fixed = 0;
- X is_numeric = VAR_STRING;
- X data_str_len = VAR_DEF_SIZE;
- X data_str_end = 0;
- X data_str = new char[data_str_len];
- X data_str[0] = 0;
- X format_str = DEFAULT_STRING_FORMAT;
- X}
- X
- X
- Xvar::var(const char *str)
- X{
- X fixed = 1;
- X is_numeric = VAR_STRING;
- X data_str_end = strlen(str);
- X data_str_len = data_str_end + VAR_DEF_SIZE;
- X data_str = new char[data_str_len];
- X strcpy(data_str, str);
- X format_str = DEFAULT_STRING_FORMAT;
- X}
- X
- X
- Xvar::var(const varsize &vsz)
- X{
- X fixed = 0;
- X is_numeric = VAR_STRING;
- X data_str_len = vsz.size + VAR_DEF_SIZE;
- X data_str_end = 0;
- X data_str = new char[data_str_len];
- X data_str[0] = 0;
- X format_str = DEFAULT_STRING_FORMAT;
- X}
- X
- X
- Xvar::var(const char ch)
- X{
- X fixed = 0;
- X is_numeric = VAR_STRING;
- X data_str_len = VAR_DEF_SIZE;
- X data_str_end = 1;
- X data_str = new char[data_str_len];
- X data_str[0] = ch;
- X data_str[1] = 0;
- X format_str = DEFAULT_STRING_FORMAT;
- X}
- X
- X
- Xvar::var(const short int_num)
- X{
- X fixed = 1;
- X is_numeric = VAR_LONG;
- X data_str_len = VAR_DEF_SIZE;
- X data_str = new char[data_str_len];
- X strcpy(data_str, itoa(int_num));
- X data_str_end = strlen(data_str);
- X format_str = DEFAULT_INT_FORMAT;
- X}
- X
- X
- Xvar::var(const unsigned short int_num)
- X{
- X fixed = 1;
- X is_numeric = VAR_LONG;
- X data_str_len = VAR_DEF_SIZE;
- X data_str = new char[data_str_len];
- X strcpy(data_str, itoa(int_num));
- X data_str_end = strlen(data_str);
- X format_str = DEFAULT_UINT_FORMAT;
- X}
- X
- X
- Xvar::var(const int int_num)
- X{
- X fixed = 1;
- X is_numeric = VAR_LONG;
- X data_str_len = VAR_DEF_SIZE;
- X data_str = new char[data_str_len];
- X strcpy(data_str, itoa(int_num));
- X data_str_end = strlen(data_str);
- X format_str = DEFAULT_INT_FORMAT;
- X}
- X
- X
- Xvar::var(const unsigned int int_num)
- X{
- X fixed = 1;
- X is_numeric = VAR_LONG;
- X data_str_len = VAR_DEF_SIZE;
- X data_str = new char[data_str_len];
- X strcpy(data_str, itoa(int_num));
- X data_str_end = strlen(data_str);
- X format_str = DEFAULT_UINT_FORMAT;
- X}
- X
- X
- Xvar::var(const long long_num)
- X{
- X fixed = 1;
- X is_numeric = VAR_LONG;
- X data_str_len = VAR_DEF_SIZE;
- X data_str = new char[data_str_len];
- X strcpy(data_str, ltoa(long_num));
- X data_str_end = strlen(data_str);
- X format_str = DEFAULT_LONG_FORMAT;
- X}
- X
- X
- Xvar::var(const unsigned long long_num)
- X{
- X fixed = 1;
- X is_numeric = VAR_LONG;
- X data_str_len = VAR_DEF_SIZE;
- X data_str = new char[data_str_len];
- X strcpy(data_str, ltoa(long_num));
- X data_str_end = strlen(data_str);
- X format_str = DEFAULT_ULONG_FORMAT;
- X}
- X
- X
- Xvar::var(const double double_num)
- X{
- X fixed = 1;
- X is_numeric = VAR_DOUBLE;
- X data_str_len = VAR_DEF_SIZE;
- X data_str = new char[data_str_len];
- X strcpy(data_str, dtoa(double_num));
- X data_str_end = strlen(data_str);
- X format_str = DEFAULT_DOUBLE_FORMAT;
- X}
- X
- X
- Xvar::var(const var &v)
- X{
- X fixed = v.fixed;
- X is_numeric = v.is_numeric;
- X if (v.data_str && v.data_str_end) {
- X data_str_len = v.data_str_end + VAR_DEF_SIZE;
- X data_str_end = v.data_str_end;
- X data_str = new char[data_str_len];
- X strcpy(data_str, v.data_str);
- X }
- X else {
- X data_str_len = VAR_DEF_SIZE;
- X data_str_end = 0;
- X data_str = new char[data_str_len];
- X data_str[0] = 0;
- X }
- X format_str = DEFAULT_STRING_FORMAT;
- X}
- X
- X
- Xvar::~var(void)
- X{
- X if (data_str) {
- X delete data_str;
- X }
- X if (format_str
- X && format_str != DEFAULT_STRING_FORMAT
- X && format_str != DEFAULT_INT_FORMAT
- X && format_str != DEFAULT_UINT_FORMAT
- X && format_str != DEFAULT_LONG_FORMAT
- X && format_str != DEFAULT_ULONG_FORMAT
- X && format_str != DEFAULT_DOUBLE_FORMAT) {
- X delete format_str;
- X }
- X}
- X
- X// -----------------------------------------------------------------------------
- X
- Xvar & var::operator = (const char *str)
- X{
- X if (fixed && is_numeric) {
- X if (is_numeric == VAR_DOUBLE) {
- X double d = atod((char *) str);
- X *this = d;
- X }
- X else {
- X long l = atol(str);
- X *this = l;
- X }
- X }
- X else {
- X int len = strlen(str) + 1;
- X if (data_str_len < len) {
- X delete data_str;
- X data_str_len = len;
- X data_str = new char[data_str_len];
- X }
- X data_str_end = len - 1;
- X strcpy(data_str, str);
- X if (!fixed) {
- X int str_is_numeric = numcheck(data_str);
- X is_numeric = str_is_numeric;
- X }
- X }
- X return *this;
- X}
- X
- X
- Xvar & var::operator = (const var &l)
- X{
- X if (this != &l) {
- X if (data_str_len <= l.data_str_end) {
- X delete data_str;
- X data_str_len = l.data_str_end + VAR_DEF_SIZE;
- X data_str = new char[data_str_len];
- X }
- X data_str_end = l.data_str_end;
- X strncpy(data_str, l.data_str, l.data_str_end);
- X data_str[data_str_end] = 0;
- X if (!fixed) {
- X is_numeric = numcheck(data_str);
- X }
- X //
- X // Note: the output "format" of a var variable is preserved
- X //
- X }
- X return *this;
- X}
- X
- X
- Xchar & var::operator [] (const int index)
- X{
- X static char error_ch;
- X if (index < 0) {
- X cerr << "ERROR: " << " - var[" << index << "] negative index used." << endl;
- X error_ch = 0;
- X return error_ch;
- X }
- X if (data_str_len <= index) {
- X // this is technically a program error, but I'll be nice and extend the string's length
- X data_str_len = index + VAR_PAD_SIZE;
- X data_str_end = index + 1;
- X char *buf = new char[data_str_len];
- X sprintf(buf, "%-*.*s", data_str_end, data_str_end, data_str);
- X delete data_str;
- X data_str = buf;
- X data_str[index] = 0;
- X cerr << "WARNING: " << " - var index '" << index << "' beyond current string boundary." << endl;
- X }
- X while (data_str_end < index) {
- X data_str[data_str_end++] = ' '; // pad to index with spaces if necessary
- X }
- X if (data_str_end == index) {
- X data_str[data_str_end] = 0; // the end of a string is ALWAYS 0
- X if ((data_str_end + 1) < data_str_len) {
- X data_str[++data_str_end] = 0; // the new end of string is also 0
- X }
- X }
- X return data_str[index];
- X}
- X
- X
- X// for substrings
- Xsubvar & var::operator () (const int offset) const
- X{
- X return operator () (offset, -1);
- X}
- X
- X
- X// for substrings
- Xsubvar & var::operator () (int offset, int length) const
- X{
- X static subvar _esi_subvar;
- X if (length < 0) {
- X length = data_str_end - offset;
- X }
- X char *substr = new char[length + 1];
- X strncpy(substr, data_str + offset, (int) length);
- X substr[length] = 0;
- X _esi_subvar.var::operator = (substr);
- X _esi_subvar.varptr = (var *) this;
- X _esi_subvar.offset = offset;
- X _esi_subvar.length = length;
- X delete substr;
- X return _esi_subvar;
- X}
- X
- X
- X// for syntax: var(offset, length) = var
- Xvar & subvar::operator = (const var &substr)
- X{
- X char *srcstr = varptr->data_str;
- X char *repstr = substr.data_str;
- X int replen = length;
- X if (substr.data_str_end < length) {
- X replen = substr.data_str_end;
- X }
- X int len = varptr->data_str_len;
- X char *newstr = new char[len];
- X strncpy(newstr, srcstr, offset); // data from string being replaced up to "offset"
- X if (replen) {
- X strncpy(newstr + offset, repstr, replen); // replacement string data
- X }
- X int newoffset = offset + replen;
- X if (newoffset < varptr->data_str_end) {
- X strcpy(newstr + newoffset, srcstr + offset + length);
- X }
- X else {
- X newstr[newoffset] = 0;
- X }
- X if (varptr->data_str) {
- X delete varptr->data_str;
- X }
- X varptr->data_str = newstr;
- X varptr->data_str_len = len;
- X varptr->data_str_end = strlen(newstr);
- X if (!varptr->fixed) {
- X varptr->is_numeric = numcheck(newstr);
- X }
- X return *varptr;
- X}
- X
- X// -----------------------------------------------------------------------------
- X
- Xvar & var::operator = (const char ch)
- X{
- X char buf[2];
- X buf[0] = ch;
- X buf[1] = 0;
- X *this = buf;
- X return *this;
- X}
- X
- X
- Xvar & var::operator = (const short int_num)
- X{
- X char *str = itoa(int_num);
- X int len = strlen(str);
- X if (data_str_len < len) {
- X delete data_str;
- X data_str_len = len + 1;
- X data_str = new char[data_str_len];
- X }
- X data_str_end = len;
- X strcpy(data_str, str);
- X if (!fixed) {
- X is_numeric = VAR_LONG;
- X }
- X return *this;
- X}
- X
- X
- Xvar & var::operator = (const unsigned short int_num)
- X{
- X char *str = itoa(int_num);
- X int len = strlen(str);
- X if (data_str_len < len) {
- X delete data_str;
- X data_str_len = len + 1;
- X data_str = new char[data_str_len];
- X }
- X data_str_end = len;
- X strcpy(data_str, str);
- X is_numeric = VAR_LONG;
- X return *this;
- X}
- X
- X
- Xvar & var::operator = (const int int_num)
- X{
- X char *str = itoa(int_num);
- X int len = strlen(str);
- X if (data_str_len < len) {
- X delete data_str;
- X data_str_len = len + 1;
- X data_str = new char[data_str_len];
- X }
- X data_str_end = len;
- X strcpy(data_str, str);
- X if (!fixed) {
- X is_numeric = VAR_LONG;
- X }
- X return *this;
- X}
- X
- X
- Xvar & var::operator = (const unsigned int int_num)
- X{
- X char *str = itoa(int_num);
- X int len = strlen(str);
- X if (data_str_len < len) {
- X delete data_str;
- X data_str_len = len + 1;
- X data_str = new char[data_str_len];
- X }
- X data_str_end = len;
- X strcpy(data_str, str);
- X if (!fixed) {
- X is_numeric = VAR_LONG;
- X }
- X return *this;
- X}
- X
- X
- Xvar & var::operator = (const long long_num)
- X{
- X char *str = ltoa(long_num);
- X int len = strlen(str);
- X if (data_str_len < len) {
- X delete data_str;
- X data_str_len = len + 1;
- X data_str = new char[data_str_len];
- X }
- X data_str_end = len;
- X strcpy(data_str, str);
- X if (!fixed) {
- X is_numeric = VAR_LONG;
- X }
- X return *this;
- X}
- X
- X
- Xvar & var::operator = (const unsigned long long_num)
- X{
- X char *str = ltoa(long_num);
- X int len = strlen(str);
- X if (data_str_len < len) {
- X delete data_str;
- X data_str_len = len + 1;
- X data_str = new char[data_str_len];
- X }
- X data_str_end = len;
- X strcpy(data_str, str);
- X if (!fixed) {
- X is_numeric = VAR_LONG;
- X }
- X return *this;
- X}
- X
- X
- Xvar & var::operator = (const double dbl_num)
- X{
- X char *str = dtoa(dbl_num);
- X int len = strlen(str);
- X if (data_str_len < len) {
- X delete data_str;
- X data_str_len = len + 1;
- X data_str = new char[data_str_len];
- X }
- X data_str_end = len;
- X strcpy(data_str, str);
- X if (!fixed) {
- X is_numeric = VAR_DOUBLE;
- X }
- X return *this;
- X}
- X
- X// -----------------------------------------------------------------------------
- X
- Xvar::operator char * (void) const
- X{
- X return data_str;
- X}
- X
- X
- Xvar::operator double (void) const
- X{
- X return atod(data_str);
- X}
- X
- X// -----------------------------------------------------------------------------
- X
- Xvar & var::operator ++ (void) // increment (pre-index only)
- X{
- X *this += 1;
- X return *this;
- X}
- X
- X
- Xvar & var::operator -- (void) // decrement (pre-index only)
- X{
- X *this -= 1;
- X return *this;
- X}
- X
- X
- Xvar var::operator ! (void) const // not
- X{
- X var not(1);
- X if ((int) *this) {
- X not = 0;
- X }
- X return not;
- X}
- X
- X// -----------------------------------------------------------------------------
- X
- Xvar var::operator + (const var & v) const // addition OR concatenation
- X{
- X var add;
- X if (is_numeric && v.is_numeric) {
- X // do math in the highest precision specified
- X int n_type = (is_numeric > v.is_numeric) ? is_numeric : v.is_numeric;
- X switch (n_type) {
- X case VAR_LONG:
- X add = (long) *this + (long) v;
- X break;
- X default:
- X // should be VAR_DOUBLE
- X add = (double) *this + (double) v;
- X break;
- X }
- X }
- X else {
- X // concatenate strings
- X delete add.data_str;
- X add.data_str_len = data_str_end + v.data_str_end + VAR_PAD_SIZE;
- X add.data_str_end = data_str_end + v.data_str_end;
- X add.data_str = new char[add.data_str_len];
- X strcpy(add.data_str, data_str);
- X strcpy((add.data_str) + data_str_end, v.data_str);
- X add.is_numeric = VAR_STRING;
- X }
- X return add;
- X}
- X
- X
- Xvar var::operator - (const var & v) const // subtraction
- X{
- X var sub;
- X // do math in the highest precision specified
- X int n_type = (is_numeric > v.is_numeric) ? is_numeric : v.is_numeric;
- X switch (n_type) {
- X case VAR_LONG:
- X sub = (long) *this - (long) v;
- X sub.is_numeric = VAR_LONG;
- X break;
- X default:
- X // should be VAR_DOUBLE
- X sub = (double) *this - (double) v;
- X break;
- X }
- X return sub;
- X}
- X
- X
- Xvar var::operator * (const var & v) const // multiplication
- X{
- X var times;
- X // do math in the highest precision specified
- X int n_type = (is_numeric > v.is_numeric) ? is_numeric : v.is_numeric;
- X switch (n_type) {
- X case VAR_LONG:
- X times = (long) *this * (long) v;
- X break;
- X default:
- X // should be VAR_DOUBLE
- X times = (double) *this * (double) v;
- X break;
- X }
- X return times;
- X}
- X
- X
- Xvar var::operator / (const var & v) const // division
- X{
- X var div;
- X // do math in the highest precision specified
- X int n_type = (is_numeric > v.is_numeric) ? is_numeric : v.is_numeric;
- X switch (n_type) {
- X case VAR_LONG:
- X div = (long) *this / (long) v;
- X break;
- X default:
- X // should be VAR_DOUBLE
- X div = (double) *this / (double) v;
- X break;
- X }
- X return div;
- X}
- X
- X
- Xvar var::operator % (const var & v) const // remainder
- X{
- X var mod;
- X // do math in the highest precision specified
- X int n_type = (is_numeric > v.is_numeric) ? is_numeric : v.is_numeric;
- X switch (n_type) {
- X case VAR_LONG:
- X mod = (long) *this % (long) v;
- X break;
- X default:
- X // should be VAR_DOUBLE
- X // really, I shouldn't allow this..
- X mod = (double) ((long) *this % (long) v);
- X break;
- X }
- X return mod;
- X}
- X
- X// -----------------------------------------------------------------------------
- X
- Xvar & var::operator += (const var & v)
- X{
- X if ((is_numeric == VAR_STRING) || (v.is_numeric == VAR_STRING)) {
- X concat(v);
- X }
- X else {
- X *this = (*this) + v;
- X }
- X return *this;
- X}
- X
- X
- Xvar & var::operator -= (const var & v)
- X{
- X *this = (*this) - v;
- X return *this;
- X}
- X
- X
- Xvar & var::operator *= (const var & v)
- X{
- X *this = (*this) * v;
- X return *this;
- X}
- X
- X
- Xvar & var::operator /= (const var & v)
- X{
- X *this = (*this) / v;
- X return *this;
- X}
- X
- X
- Xvar & var::operator %= (const var & v)
- X{
- X *this = (*this) % v;
- X return *this;
- X}
- X
- X// -----------------------------------------------------------------------------
- X
- Xvar & var::operator += (const char & ch)
- X{
- X var foo = ch;
- X *this += foo;
- X return *this;
- X}
- X
- Xvar & var::operator += (const char * v)
- X{
- X var foo = v;
- X *this += foo;
- X return *this;
- X}
- X
- X
- Xvar & var::operator -= (const char * v)
- X{
- X var foo = v;
- X *this -= foo;
- X return *this;
- X}
- X
- X
- Xvar & var::operator *= (const char * v)
- X{
- X var foo = v;
- X *this *= foo;
- X return *this;
- X}
- X
- X
- Xvar & var::operator /= (const char * v)
- X{
- X var foo = v;
- X *this /= foo;
- X return *this;
- X}
- X
- X
- Xvar & var::operator %= (const char * v)
- X{
- X var foo = v;
- X *this %= foo;
- X return *this;
- X}
- X
- X// -----------------------------------------------------------------------------
- X
- Xvar & var::operator += (const double v)
- X{
- X var foo = v;
- X *this += foo;
- X return *this;
- X}
- X
- X
- Xvar & var::operator -= (const double v)
- X{
- X var foo = v;
- X *this -= foo;
- X return *this;
- X}
- X
- X
- Xvar & var::operator *= (const double v)
- X{
- X var foo = v;
- X *this *= foo;
- X return *this;
- X}
- X
- X
- Xvar & var::operator /= (const double v)
- X{
- X var foo = v;
- X *this /= foo;
- X return *this;
- X}
- X
- X
- Xvar & var::operator %= (const double v)
- X{
- X var foo = v;
- X *this %= foo;
- X return *this;
- X}
- X
- X// -----------------------------------------------------------------------------
- X
- Xvar operator + (const char * s, const var & v)
- X{
- X var foo = s;
- X return foo + v;
- X}
- X
- X
- Xvar operator - (const char * s, const var & v)
- X{
- X var foo = s;
- X return foo - v;
- X}
- X
- X
- Xvar operator * (const char * s, const var & v)
- X{
- X var foo = s;
- X return foo * v;
- X}
- X
- X
- Xvar operator / (const char * s, const var & v)
- X{
- X var foo = s;
- X return foo / v;
- X}
- X
- X
- Xvar operator % (const char * s, const var & v)
- X{
- X var foo = s;
- X return foo % v;
- X}
- X
- X
- Xvar operator + (const var & v, const char * s)
- X{
- X var foo = s;
- X return v + foo;
- X}
- X
- X
- Xvar operator - (const var & v, const char * s)
- X{
- X var foo = s;
- X return v - foo;
- X}
- X
- X
- Xvar operator * (const var & v, const char * s)
- X{
- X var foo = s;
- X return v * foo;
- X}
- X
- X
- Xvar operator / (const var & v, const char * s)
- X{
- X var foo = s;
- X return v / foo;
- X}
- X
- X
- Xvar operator % (const var & v, const char * s)
- X{
- X var foo = s;
- X return v % foo;
- X}
- X
- X// -----------------------------------------------------------------------------
- X
- Xvar operator + (const var & v, const double d)
- X{
- X var foo = d;
- X return v + foo;
- X}
- X
- X
- Xvar operator - (const var & v, const double d)
- X{
- X var foo = d;
- X return v - foo;
- X}
- X
- X
- Xvar operator * (const var & v, const double d)
- X{
- X var foo = d;
- X return v * foo;
- X}
- X
- X
- Xvar operator / (const var & v, const double d)
- X{
- X var foo = d;
- X return v / foo;
- X}
- X
- X
- Xvar operator % (const var & v, const double d)
- X{
- X var foo = d;
- X return v % foo;
- X}
- X
- X
- Xvar operator + (const double d, const var & v)
- X{
- X var foo = d;
- X return foo + v;
- X}
- X
- X
- Xvar operator - (const double d, const var & v)
- X{
- X var foo = d;
- X return foo - v;
- X}
- X
- X
- Xvar operator * (const double d, const var & v)
- X{
- X var foo = d;
- X return foo * v;
- X}
- X
- X
- Xvar operator / (const double d, const var & v)
- X{
- X var foo = d;
- X return foo / v;
- X}
- X
- X
- Xvar operator % (const double d, const var & v)
- X{
- X var foo = d;
- X return foo % v;
- X}
- X
- X// -----------------------------------------------------------------------------
- X
- Xint var::operator == (const var & t) const // equality
- X{
- X if (is_numeric && t.is_numeric) {
- X if (is_numeric == VAR_LONG && t.is_numeric == VAR_LONG) {
- X return (long) (*this) == (long) t;
- X }
- X return (double) (*this) == (double) t;
- X }
- X else {
- X if (data_str_end && t.data_str_end) {
- X return !strcmp(data_str, t.data_str);
- X }
- X else {
- X return data_str_end == t.data_str_end;
- X }
- X }
- X}
- X
- X
- Xint var::operator != (const var & t) const // inequality
- X{
- X if (is_numeric && t.is_numeric) {
- X if (is_numeric == VAR_LONG && t.is_numeric == VAR_LONG) {
- X return (long) (*this) != (long) t;
- X }
- X return (double) (*this) != (double) t;
- X }
- X else {
- X if (data_str_end && t.data_str_end) {
- X return strcmp(data_str, t.data_str);
- X }
- X else {
- X return data_str_end != t.data_str_end;
- X }
- X }
- X}
- X
- X
- Xint var::operator < (const var & t) const // less than
- X{
- X if (is_numeric && t.is_numeric) {
- X if (is_numeric == VAR_LONG && t.is_numeric == VAR_LONG) {
- X return (long) (*this) < (long) t;
- X }
- X return (double) (*this) < (double) t;
- X }
- X else {
- X if (data_str_end && t.data_str_end) {
- X return (strcmp(data_str, t.data_str) < 0);
- X }
- X else {
- X return data_str_end < t.data_str_end;
- X }
- X }
- X}
- X
- X
- Xint var::operator > (const var & t) const // greater than
- X{
- X if (is_numeric && t.is_numeric) {
- X if (is_numeric == VAR_LONG && t.is_numeric == VAR_LONG) {
- X return (long) (*this) > (long) t;
- X }
- X return (double) (*this) > (double) t;
- X }
- X else {
- X if (data_str_end && t.data_str_end) {
- X return (strcmp(data_str, t.data_str) > 0);
- X }
- X else {
- X return data_str_end > t.data_str_end;
- X }
- X }
- X}
- X
- X
- Xint var::operator <= (const var & t) const // less than or equal
- X{
- X if (is_numeric && t.is_numeric) {
- X if (is_numeric == VAR_LONG && t.is_numeric == VAR_LONG) {
- X return (long) (*this) <= (long) t;
- X }
- X return (double) (*this) <= (double) t;
- X }
- X else {
- X if (data_str_end && t.data_str_end) {
- X return (strcmp(data_str, t.data_str) <= 0);
- X }
- X else {
- X return data_str_end <= t.data_str_end;
- X }
- X }
- X}
- X
- X
- Xint var::operator >= (const var & t) const // greater than or equal
- X{
- X if (is_numeric && t.is_numeric) {
- X if (is_numeric == VAR_LONG && t.is_numeric == VAR_LONG) {
- X return (long) (*this) >= (long) t;
- X }
- X return (double) (*this) >= (double) t;
- X }
- X else {
- X if (data_str_end && t.data_str_end) {
- X return (strcmp(data_str, t.data_str) >= 0);
- X }
- X else {
- X return data_str_end >= t.data_str_end;
- X }
- X }
- X}
- X
- X// -----------------------------------------------------------------------------
- X
- Xint operator == (const var & t, const char * s)
- X{
- X var foo = s;
- X return t == foo;
- X}
- X
- X
- Xint operator != (const var & t, const char * s)
- X{
- X var foo = s;
- X return t != foo;
- X}
- X
- X
- Xint operator < (const var & t, const char * s)
- X{
- X var foo = s;
- X return t < foo;
- X}
- X
- X
- Xint operator > (const var & t, const char * s)
- X{
- X var foo = s;
- X return t > foo;
- X}
- X
- X
- Xint operator <= (const var & t, const char * s)
- X{
- X var foo = s;
- X return t <= foo;
- X}
- X
- X
- Xint operator >= (const var & t, const char * s)
- X{
- X var foo = s;
- X return t >= foo;
- X}
- X
- X
- Xint operator == (const char * s, const var & t)
- X{
- X var foo = s;
- X return foo == t;
- X}
- X
- X
- Xint operator != (const char * s, const var & t)
- X{
- X var foo = s;
- X return foo != t;
- X}
- X
- X
- Xint operator < (const char * s, const var & t)
- X{
- X var foo = s;
- X return foo < t;
- X}
- X
- X
- Xint operator > (const char * s, const var & t)
- X{
- X var foo = s;
- X return foo > t;
- X}
- X
- X
- Xint operator <= (const char * s, const var & t)
- X{
- X var foo = s;
- X return foo <= t;
- X}
- X
- X
- Xint operator >= (const char * s, const var & t)
- X{
- X var foo = s;
- X return foo >= t;
- X}
- X
- X// -----------------------------------------------------------------------------
- X
- Xint operator == (const var & t, const double d)
- X{
- X return (double) t == d;
- X}
- X
- X
- Xint operator != (const var & t, const double d)
- X{
- X return (double) t != d;
- X}
- X
- X
- Xint operator < (const var & t, const double d)
- X{
- X return (double) t < d;
- X}
- X
- X
- Xint operator > (const var & t, const double d)
- X{
- X return (double) t > d;
- X}
- X
- X
- Xint operator <= (const var & t, const double d)
- X{
- X return (double) t <= d;
- X}
- X
- X
- Xint operator >= (const var & t, const double d)
- X{
- X return (double) t >= d;
- X}
- X
- X
- Xint operator == (const double d, const var & t)
- X{
- X return d == (double) t;
- X}
- X
- X
- Xint operator != (const double d, const var & t)
- X{
- X return d != (double) t;
- X}
- X
- X
- Xint operator < (const double d, const var & t)
- X{
- X return d < (double) t;
- X}
- X
- X
- Xint operator > (const double d, const var & t)
- X{
- X return d > (double) t;
- X}
- X
- X
- Xint operator <= (const double d, const var & t)
- X{
- X return d <= (double) t;
- X}
- X
- X
- Xint operator >= (const double d, const var & t)
- X{
- X return d >= (double) t;
- X}
- X
- X// -----------------------------------------------------------------------------
- X
- Xvoid var::null(int index)
- X{
- X if (index >= data_str_len) {
- X cerr << "WARNING: " << " - var::null(" << index << ") - the index out of range." << endl;
- X (*this)[index] = 0;
- X data_str_end = index;
- X }
- X else {
- X data_str[index] = 0;
- X data_str_end = index;
- X }
- X}
- X
- X
- Xvoid var::changesize(int newsize)
- X{
- X if (newsize > data_str_len) {
- X char *buf = new char[newsize];
- X if (data_str) {
- X strncpy(buf, data_str, data_str_end);
- X buf[data_str_end] = 0;
- X delete data_str;
- X }
- X else {
- X *buf = 0;
- X data_str_end = 0;
- X }
- X data_str_len = newsize;
- X data_str = buf;
- X }
- X}
- X
- X
- Xint var::length(void) const
- X{
- X return data_str_end;
- X}
- X
- X
- Xconst char * var::vartype(void) const
- X{
- X switch (is_numeric) {
- X case VAR_STRING:
- X return "VAR_STRING";
- X case VAR_LONG:
- X return "VAR_LONG";
- X case VAR_DOUBLE:
- X return "VAR_DOUBLE";
- X }
- X return "var type unknown";
- X}
- X
- X
- Xvoid var::change_type(const char *ntype)
- X{
- X if (ntype == NULL) {
- X return;
- X }
- X int index = strlen(ntype);
- X if (!index) {
- X return;
- X }
- X char *new_type = new char[index + 1];
- X if (ntype[0] == '(' && ntype[index - 1] == ')') {
- X strcpy(new_type, &ntype[1]);
- X index = strlen(new_type) - 1;
- X if (index <= 0) {
- X delete new_type;
- X return;
- X }
- X new_type[index] = 0; // drop parens
- X }
- X else {
- X strcpy(new_type, ntype);
- X }
- X if (new_type[index - 1] == ' ') {
- X new_type[index - 1] = 0;
- X }
- X fixed = 1;
- X if (!strcmp(new_type, "var")) {
- X is_numeric = numcheck((const char *) *this);
- X }
- X else if (!strcmp(new_type, "string")) {
- X is_numeric = VAR_STRING;
- X }
- X else if (!strcmp(new_type, "short")) {
- X is_numeric = VAR_LONG;
- X }
- X else if (!strcmp(new_type, "unsigned short")) {
- X is_numeric = VAR_LONG;
- X }
- X else if (!strcmp(new_type, "int")) {
- X is_numeric = VAR_LONG;
- X }
- X else if (!strcmp(new_type, "unsigned int")) {
- X is_numeric = VAR_LONG;
- X }
- X else if (!strcmp(new_type, "long")) {
- X is_numeric = VAR_LONG;
- X }
- X else if (!strcmp(new_type, "unsigned long")) {
- X is_numeric = VAR_LONG;
- X }
- X else if (!strcmp(new_type, "float")) {
- X is_numeric = VAR_DOUBLE;
- X }
- X else if (!strcmp(new_type, "double")) {
- X is_numeric = VAR_DOUBLE;
- X }
- X else {
- X cerr << "WARNING: " << " - change_type(" << new_type << ") - unrecognized type name." << endl;
- X }
- X delete new_type;
- X}
- X
- X
- Xint var::is_string(void) const
- X{
- X return is_numeric == VAR_STRING;
- X}
- X
- X
- Xint var::is_double(void) const
- X{
- X return is_numeric == VAR_DOUBLE;
- X}
- X
- X
- Xint var::is_long(void) const
- X{
- X return is_numeric == VAR_LONG;
- X}
- X
- X
- Xint var::strchr(const char ch) const
- X{
- X for (int i = 0; i < data_str_end; ++i) {
- X if (data_str[i] == ch) {
- X return i;
- X }
- X }
- X return -1;
- X}
- X
- X
- Xint var::strrchr(const char ch) const
- X{
- X for (int i = data_str_end - 1; i >= 0; --i) {
- X if (data_str[i] == ch) {
- X return i;
- X }
- X }
- X return -1;
- X}
- X
- X
- Xvar & var::concat(const var & str)
- X{
- X // concatenate strings
- X int new_data_str_end = data_str_end + str.data_str_end;
- X if (new_data_str_end >= data_str_len) {
- X var add;
- X add.data_str_len = data_str_len + str.data_str_len + VAR_PAD_SIZE;
- X add.data_str_end = new_data_str_end;
- X add.data_str = new char[add.data_str_len];
- X strcpy(add.data_str, data_str);
- X strcpy((add.data_str) + data_str_end, str.data_str);
- X *this = add;
- X }
- X else {
- X strcpy(data_str + data_str_end, str.data_str);
- X data_str_end += str.data_str_end;
- X }
- X return *this;
- X}
- X
- X
- Xvar & var::format(const char * fmt)
- X{
- X if (format_str
- X && format_str != DEFAULT_STRING_FORMAT
- X && format_str != DEFAULT_INT_FORMAT
- X && format_str != DEFAULT_UINT_FORMAT
- X && format_str != DEFAULT_LONG_FORMAT
- X && format_str != DEFAULT_ULONG_FORMAT
- X && format_str != DEFAULT_DOUBLE_FORMAT) {
- X delete format_str;
- X }
- X if (fmt) {
- X format_str = new char[strlen(fmt) + 1];
- X strcpy(format_str, fmt);
- X }
- X else {
- X format_str = NULL;
- X }
- X return *this;
- X}
- X
- X
- Xint var::numcheck(const char * str) const
- X{
- X if (!str || !*str) {
- X return VAR_STRING; // assume a string
- X }
- X char *ptr = (char *) str;
- X int nc = VAR_LONG; // assume a signed long
- X int decimal_yet = 0;
- X if (*ptr == '.' && *(ptr + 1)) {
- X nc = VAR_DOUBLE; // floating point number
- X decimal_yet = 1;
- X ++ptr;
- X }
- X else if (*ptr == '-' && *(ptr + 1)) {
- X // skip optional sign char
- X ++ptr;
- X }
- X while (*ptr) {
- X if (*ptr == '.' && !decimal_yet) {
- X decimal_yet = 1;
- X nc = VAR_DOUBLE; // assume a double
- X }
- X else if (!isdigit(*ptr)) {
- X return VAR_STRING; // nope.. got a string
- X }
- X ++ptr;
- X }
- X return nc;
- X}
- X
- X// -----------------------------------------------------------------------------
- X
- Xint var::save_it(const int save_flag)
- X{
- X int s = var::save_me;
- X var::save_me = save_flag;
- X return s;
- X}
- X
- X// -----------------------------------------------------------------------------
- X
- Xostream & operator << (ostream &out, const var &d)
- X{
- X d.print(out);
- X return out;
- X}
- X
- X
- Xvoid var::print(ostream &out) const
- X{
- X // NOTE: the "read()" function requires a newline to appear after the last quote.
- X // I assume that this newline was appropriately output by the var class user.
- X if (!format_str || (format_str && *format_str == 0)) {
- X out << "var OBJECT: {"
- X << Inc << "fixed = " << fixed
- X << Tab << "is_numeric = " << is_numeric
- X << Tab << "data_str_len = " << data_str_len
- X << Tab << "data_str_end = " << data_str_end
- X << Tab << "data_str = '" << data_str << "'"
- X << Tab << "format_str = '" << format_str << "'"
- X << Dec << "}" << endl;
- X }
- X else {
- X // we need to use the specified format string for output
- X int len = length() + 1;
- X char *outbuf = new char[2048];
- X char *fptr = format_str;
- X while (*fptr) {
- X if (*fptr != '%' && *fptr != '\\') {
- X out << *fptr;
- X ++fptr;
- X }
- X else if (*fptr == '\\') {
- X switch (*(fptr + 1)) {
- X case 'n':
- X cout << '\n';
- X break;
- X case 't':
- X cout << '\t';
- X break;
- X case 'v':
- X cout << '\v';
- X break;
- X case 'b':
- X cout << '\b';
- X break;
- X case 'r':
- X cout << '\r';
- X break;
- X case 'f':
- X cout << '\f';
- X break;
- X case 'a':
- X cout << '\007';
- X break;
- X case '\\':
- X cout << '\\';
- X break;
- X case '?':
- X cout << '\?';
- X break;
- X case '\'':
- X cout << '\'';
- X break;
- X case '\"':
- X cout << '\"';
- X break;
- X default:
- X cout << *(fptr + 1);
- X }
- X fptr += 2;
- X }
- X else {
- X // Hmmm.. we need to do some special formatting
- X // first extract this printf-style format string
- X char smallfmtstr[128];
- X char *smptr = smallfmtstr;
- X *smptr = 0;
- X if (*(fptr + 1) == '%') {
- X strcpy(outbuf, "%");
- X fptr += 2;
- X }
- X else {
- X while (*fptr) {
- X *smptr = *fptr++;
- X *(smptr + 1) = 0;
- X // integer
- X if (*smptr == 'd') {
- X sprintf(outbuf, smallfmtstr, (int) *this);
- X break;
- X }
- X // unsigned integer
- X if (*smptr == 'o' || *smptr == 'u' || *smptr == 'x' || *smptr == 'X') {
- X sprintf(outbuf, smallfmtstr, (unsigned int) *this);
- X break;
- X }
- X // float or double
- X if (*smptr == 'f' || *smptr == 'e' || *smptr == 'E' || *smptr == 'g' || *smptr == 'G') {
- X sprintf(outbuf, smallfmtstr, (double) *this);
- X break;
- X }
- X // character
- X if (*smptr == 'c') {
- X if (!strcmp(vartype(), "VAR_STRING")) {
- X const char *tmp = (const char *) (*this);
- X sprintf(outbuf, smallfmtstr, tmp[0]);
- X }
- X else {
- X sprintf(outbuf, smallfmtstr, (char) ((int) *this));
- X }
- X break;
- X }
- X // string
- X if (*smptr == 's') {
- X sprintf(outbuf, smallfmtstr, (const char *) *this);
- X break;
- X }
- X ++smptr;
- X }
- X }
- X out << outbuf;
- X }
- X }
- X out << flush;
- X delete outbuf;
- X }
- X}
- X
- X
- Xistream & operator >> (istream &in, var &d)
- X{
- X d.read(in);
- X return in;
- X}
- X
- X
- Xvoid var::read(istream &in)
- X{
- X // input the same format as was created by the output operator
- X char buf1[4096];
- X char buf2[4096];
- X if (!format_str || (format_str && *format_str == 0)) {
- X look_for(in, '{');
- X look_for(in, '=');
- X in >> fixed;
- X look_for(in, '=');
- X in >> is_numeric;
- X look_for(in, '=');
- X in >> data_str_len;
- X look_for(in, '=');
- X in >> data_str_end;
- X look_for(in, '=');
- X scan_string(in, buf1, sizeof(buf1));
- X look_for(in, '=');
- X scan_string(in, buf2, sizeof(buf2));
- X look_for(in, '}');
- X *this = buf1;
- X format(buf2);
- X }
- X else {
- X // LEE: need to add input/output formatting capabilities
- X }
- X}
- X
- END_OF_FILE
- if test 30983 -ne `wc -c <'var.C'`; then
- echo shar: \"'var.C'\" unpacked with wrong size!
- fi
- # end of 'var.C'
- fi
- echo shar: End of archive 1 \(of 2\).
- cp /dev/null ark1isdone
- MISSING=""
- for I in 1 2 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked both archives.
- rm -f ark[1-9]isdone
- else
- echo You still must unpack the following archives:
- echo " " ${MISSING}
- fi
- exit 0
- exit 0 # Just in case...
-